geoip.c revision 83f69fcd6ef72c9e2ebcb025b66a2ee74176becd
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley/*
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * Copyright (C) 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley *
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * Permission to use, copy, modify, and/or distribute this software for any
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * purpose with or without fee is hereby granted, provided that the above
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * copyright notice and this permission notice appear in all copies.
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley *
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * PERFORMANCE OF THIS SOFTWARE.
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley */
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley/*! \file */
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <config.h>
9695ae1c24b168996e3a267855dc754971ccb32cBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <isc/util.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <isc/mem.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/once.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <isc/string.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <dns/acl.h>
9695ae1c24b168996e3a267855dc754971ccb32cBob Halley#include <dns/geoip.h>
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <isc/thread.h>
1c776a2909632bc755f3fddd3b53addd792ab4d0Brian Wellington#include <math.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#ifndef WIN32
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <netinet/in.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#ifndef _WINSOCKAPI_
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#endif
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <winsock2.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#endif /* WIN32 */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <dns/log.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#ifdef HAVE_GEOIP
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#include <GeoIP.h>
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#include <GeoIPCity.h>
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington/*
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * This structure preserves state from the previous GeoIP lookup,
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * so that successive lookups for the same data from the same IP
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * address will not require repeated calls into the GeoIP library
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * to look up data in the database. This should improve performance
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * somwhat.
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington *
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * For lookups in the City and Region databases, we preserve pointers
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * to the GeoIPRecord and GeoIPregion structures; these will need to be
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * freed by GeoIPRecord_delete() and GeoIPRegion_delete().
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington *
e419f613d8591885df608cb73065921be07dd12eBob Halley * for lookups in ISP, AS, Org and Domain we prserve a pointer to
e419f613d8591885df608cb73065921be07dd12eBob Halley * the returned name; these must be freed by free().
e419f613d8591885df608cb73065921be07dd12eBob Halley *
e419f613d8591885df608cb73065921be07dd12eBob Halley * For lookups in Country we preserve a pointer to the text of
e419f613d8591885df608cb73065921be07dd12eBob Halley * the country code, name, etc (we use a different pointer for this
e419f613d8591885df608cb73065921be07dd12eBob Halley * than for the names returned by Org, ISP, etc, because those need
e419f613d8591885df608cb73065921be07dd12eBob Halley * to be freed but country lookups do not).
e419f613d8591885df608cb73065921be07dd12eBob Halley *
e419f613d8591885df608cb73065921be07dd12eBob Halley * For lookups in Netspeed we preserve the returned ID.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * XXX: Currently this mechanism is only used for IPv4 lookups; the
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * family and addr6 fields are to be used IPv6 is added.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleytypedef struct geoip_state {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington isc_uint16_t subtype;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington unsigned int family;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington isc_uint32_t ipnum;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington geoipv6_t ipnum6;
e419f613d8591885df608cb73065921be07dd12eBob Halley GeoIPRecord *record;
e419f613d8591885df608cb73065921be07dd12eBob Halley GeoIPRegion *region;
e419f613d8591885df608cb73065921be07dd12eBob Halley const char *text;
e419f613d8591885df608cb73065921be07dd12eBob Halley char *name;
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley int id;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_mem_t *mctx;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley} geoip_state_t;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#ifdef ISC_PLATFORM_USETHREADS
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic isc_mutex_t key_mutex;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic isc_boolean_t state_key_initialized = ISC_FALSE;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic isc_thread_key_t state_key;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic isc_once_t mutex_once = ISC_ONCE_INIT;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic isc_mem_t *state_mctx = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic void
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleykey_mutex_init(void) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley RUNTIME_CHECK(isc_mutex_init(&key_mutex) == ISC_R_SUCCESS);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic void
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleyfree_state(void *arg) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley geoip_state_t *state = arg;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (state != NULL && state->record != NULL)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley GeoIPRecord_delete(state->record);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (state != NULL)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_mem_putanddetach(&state->mctx,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley state, sizeof(geoip_state_t));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_thread_key_setspecific(state_key, NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic isc_result_t
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystate_key_init(void) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_result_t result;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = isc_once_do(&mutex_once, key_mutex_init);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (result != ISC_R_SUCCESS)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (result);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (!state_key_initialized) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley LOCK(&key_mutex);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (!state_key_initialized) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley int ret;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (state_mctx == NULL)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = isc_mem_create2(0, 0, &state_mctx, 0);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (result != ISC_R_SUCCESS)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley goto unlock;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_mem_setname(state_mctx, "geoip_state", NULL);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington isc_mem_setdestroycheck(state_mctx, ISC_FALSE);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington ret = isc_thread_key_create(&state_key, free_state);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (ret == 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley state_key_initialized = ISC_TRUE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = ISC_R_FAILURE;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington }
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington unlock:
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington UNLOCK(&key_mutex);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington }
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (result);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington}
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#else
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtongeoip_state_t prev_state;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#endif
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic void
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonclean_state(geoip_state_t *state) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (state == NULL)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (state->record != NULL)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington GeoIPRecord_delete(state->record);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (state->region != NULL)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington GeoIPRegion_delete(state->region);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (state->name != NULL)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington free (state->name);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington state->ipnum = 0;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington state->text = NULL;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington state->id = 0;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington}
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic isc_result_t
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonset_state(unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6,
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington dns_geoip_subtype_t subtype, GeoIPRecord *record,
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington GeoIPRegion *region, char *name, const char *text, int id)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington{
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington isc_result_t result;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington geoip_state_t *state = NULL;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington#ifdef ISC_PLATFORM_USETHREADS
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington result = state_key_init();
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if (result != ISC_R_SUCCESS)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington return (result);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if (state == NULL) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington state = (geoip_state_t *) isc_mem_get(state_mctx,
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington sizeof(geoip_state_t));
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if (state == NULL)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington return (ISC_R_NOMEMORY);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington memset(state, 0, sizeof(*state));
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington result = isc_thread_key_setspecific(state_key, state);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if (result != ISC_R_SUCCESS) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington isc_mem_put(state_mctx, state, sizeof(geoip_state_t));
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington return (result);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington }
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington isc_mem_attach(state_mctx, &state->mctx);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington } else
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington clean_state(state);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington#else
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington state = &prev_state;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if (state->ipnum != ipnum)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington clean_state(state);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#endif
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (family == AF_INET)
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson state->ipnum = ipnum;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson else
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson state->ipnum6 = *ipnum6;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson state->family = family;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson state->subtype = subtype;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson state->record = record;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley state->region = region;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley state->name = name;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley state->text = text;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley state->id = id;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (ISC_R_SUCCESS);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic geoip_state_t *
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleyget_state() {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#ifdef ISC_PLATFORM_USETHREADS
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_result_t result;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley geoip_state_t *state;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley result = state_key_init();
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (result != ISC_R_SUCCESS)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (state);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (&prev_state);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#endif
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley/*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Country lookups are performed if the previous lookup was from a
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * different IP address than the current, or was for a search of a
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * different subtype.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic const char *
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleycountry_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley unsigned int family,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_uint32_t ipnum, const geoipv6_t *ipnum6)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley{
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley geoip_state_t *prev_state = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley const char *text = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(db != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#ifndef HAVE_GEOIP_V6
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /* no IPv6 support? give up now */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (family == AF_INET6)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#endif
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley prev_state = get_state();
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (prev_state != NULL &&
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley prev_state->subtype == subtype &&
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ((prev_state->family == AF_INET && prev_state->ipnum == ipnum) ||
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley (prev_state->family == AF_INET6 &&
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley memcmp(prev_state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0)))
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley text = prev_state->text;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (text == NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley switch (subtype) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_country_code:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (family == AF_INET)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley text = GeoIP_country_code_by_ipnum(db, ipnum);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#ifdef HAVE_GEOIP_V6
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley text = GeoIP_country_code_by_ipnum_v6(db,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *ipnum6);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#endif
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_country_code3:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (family == AF_INET)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley text = GeoIP_country_code3_by_ipnum(db, ipnum);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#ifdef HAVE_GEOIP_V6
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley text = GeoIP_country_code3_by_ipnum_v6(db,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *ipnum6);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#endif
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_country_name:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (family == AF_INET)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley text = GeoIP_country_name_by_ipnum(db, ipnum);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#ifdef HAVE_GEOIP_V6
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley text = GeoIP_country_name_by_ipnum_v6(db,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *ipnum6);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#endif
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley default:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley INSIST(0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley set_state(family, ipnum, ipnum6, subtype,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley NULL, NULL, NULL, text, 0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (text);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic char *
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleycity_string(GeoIPRecord *record, dns_geoip_subtype_t subtype, int *maxlen) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley const char *s;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley char *deconst;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(record != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(maxlen != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /* Set '*maxlen' to the maximum length of this subtype, if any */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley switch (subtype) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_countrycode:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_region:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_continentcode:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *maxlen = 2;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_countrycode3:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *maxlen = 3;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley break;
1854401d34e3cdaec6d167e82655c0448ed92a92Bob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley default:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /* No fixed length; just use strcasecmp() for comparison */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *maxlen = 255;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley switch (subtype) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_countrycode:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (record->country_code);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_countrycode3:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (record->country_code3);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_countryname:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (record->country_name);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_region:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (record->region);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_regionname:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley s = GeoIP_region_name_by_code(record->country_code,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley record->region);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley DE_CONST(s, deconst);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (deconst);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_name:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (record->city);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_postalcode:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (record->postal_code);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_continentcode:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (record->continent_code);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_timezonecode:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley s = GeoIP_time_zone_by_country_and_region(record->country_code,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley record->region);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley DE_CONST(s, deconst);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (deconst);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley default:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley INSIST(0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtonstatic isc_boolean_t
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtonis_city(dns_geoip_subtype_t subtype) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington switch (subtype) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_countrycode:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_countrycode3:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_countryname:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_region:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_regionname:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_name:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_postalcode:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_continentcode:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_timezonecode:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_metrocode:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington case dns_geoip_city_areacode:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington return (ISC_TRUE);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington default:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington return (ISC_FALSE);
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington }
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington}
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington/*
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington * GeoIPRecord lookups are performed if the previous lookup was
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington * from a different IP address than the current, or was for a search
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington * outside the City database.
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington */
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtonstatic GeoIPRecord *
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtoncity_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington{
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley GeoIPRecord *record = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley geoip_state_t *prev_state = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(db != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#ifndef HAVE_GEOIP_V6
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /* no IPv6 support? give up now */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (family == AF_INET6)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#endif
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley prev_state = get_state();
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (prev_state != NULL &&
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley is_city(prev_state->subtype) &&
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ((prev_state->family == AF_INET && prev_state->ipnum == ipnum) ||
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley (prev_state->family == AF_INET6 &&
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley memcmp(prev_state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0)))
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley record = prev_state->record;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (record == NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (family == AF_INET)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington record = GeoIP_record_by_ipnum(db, ipnum);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#ifdef HAVE_GEOIP_V6
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington else
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington record = GeoIP_record_by_ipnum_v6(db, *ipnum6);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington#endif
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (record == NULL)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (NULL);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington set_state(family, ipnum, ipnum6, subtype,
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington record, NULL, NULL, NULL, 0);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington }
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (record);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington}
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonstatic char *
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellingtonregion_string(GeoIPRegion *region, dns_geoip_subtype_t subtype, int *maxlen) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington const char *s;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington char *deconst;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington REQUIRE(region != NULL);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington REQUIRE(maxlen != NULL);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington switch (subtype) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington case dns_geoip_region_countrycode:
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington *maxlen = 2;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (region->country_code);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_region_code:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *maxlen = 2;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (region->region);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_region_name:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *maxlen = 255;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley s = GeoIP_region_name_by_code(region->country_code,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley region->region);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley DE_CONST(s, deconst);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (deconst);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley default:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley INSIST(0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic isc_boolean_t
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleyis_region(dns_geoip_subtype_t subtype) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley switch (subtype) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_region_countrycode:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_region_code:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (ISC_TRUE);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley default:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (ISC_FALSE);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley/*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * GeoIPRegion lookups are performed if the previous lookup was
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * from a different IP address than the current, or was for a search
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * outside the Region database.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafssonstatic GeoIPRegion *
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafssonregion_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) {
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson GeoIPRegion *region = NULL;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson geoip_state_t *prev_state = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(db != NULL);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson prev_state = get_state();
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson if (prev_state != NULL && prev_state->ipnum == ipnum &&
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson is_region(prev_state->subtype))
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley region = prev_state->region;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (region == NULL) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington region = GeoIP_region_by_ipnum(db, ipnum);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (region == NULL)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley set_state(AF_INET, ipnum, NULL,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley subtype, NULL, region, NULL, NULL, 0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (region);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington/*
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson * ISP, Organization, AS Number and Domain lookups are performed if
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson * the previous lookup was from a different IP address than the current,
0a3e2e1d590dac7fb011e72bd3a4982c179d8e68Brian Wellington * or was for a search of a different subtype.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic char *
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleyname_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley char *name = NULL;
0a3e2e1d590dac7fb011e72bd3a4982c179d8e68Brian Wellington geoip_state_t *prev_state = NULL;
0a3e2e1d590dac7fb011e72bd3a4982c179d8e68Brian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington REQUIRE(db != NULL);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington prev_state = get_state();
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (prev_state != NULL && prev_state->ipnum == ipnum &&
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington prev_state->subtype == subtype)
0a3e2e1d590dac7fb011e72bd3a4982c179d8e68Brian Wellington name = prev_state->name;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson if (name == NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley name = GeoIP_name_by_ipnum(db, ipnum);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (name == NULL)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (NULL);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington set_state(AF_INET, ipnum, NULL,
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington subtype, NULL, NULL, name, NULL, 0);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (name);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington}
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington/*
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * Netspeed lookups are performed if the previous lookup was from a
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * different IP address than the current, or was for a search of a
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * different subtype.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic int
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleynetspeed_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley geoip_state_t *prev_state = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_boolean_t found = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley int id = -1;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(db != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley prev_state = get_state();
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (prev_state != NULL && prev_state->ipnum == ipnum &&
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff prev_state->subtype == subtype) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley id = prev_state->id;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley found = ISC_TRUE;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (!found) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley id = GeoIP_id_by_ipnum(db, ipnum);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley set_state(AF_INET, ipnum, NULL,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley subtype, NULL, NULL, NULL, NULL, id);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley }
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley return (id);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley}
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley#endif /* HAVE_GEOIP */
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley#define DB46(addr, geoip, name) \
e419f613d8591885df608cb73065921be07dd12eBob Halley ((addr->family == AF_INET) ? (geoip->name##_v4) : (geoip->name##_v6))
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley#ifdef HAVE_GEOIP
e419f613d8591885df608cb73065921be07dd12eBob Halley/*
e419f613d8591885df608cb73065921be07dd12eBob Halley * Find the best database to answer a generic subtype
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley */
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halleystatic dns_geoip_subtype_t
e419f613d8591885df608cb73065921be07dd12eBob Halleyfix_subtype(const isc_netaddr_t *reqaddr, const dns_geoip_databases_t *geoip,
e419f613d8591885df608cb73065921be07dd12eBob Halley dns_geoip_subtype_t subtype)
e419f613d8591885df608cb73065921be07dd12eBob Halley{
e419f613d8591885df608cb73065921be07dd12eBob Halley dns_geoip_subtype_t ret = subtype;
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley switch (subtype) {
62a84c4a27033bb0e7316256964a6950b1e230bdAndreas Gustafsson case dns_geoip_countrycode:
e419f613d8591885df608cb73065921be07dd12eBob Halley if (DB46(reqaddr, geoip, city) != NULL)
e419f613d8591885df608cb73065921be07dd12eBob Halley ret = dns_geoip_city_countrycode;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington else if (reqaddr->family == AF_INET && geoip->region != NULL)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington ret = dns_geoip_region_countrycode;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington else if (DB46(reqaddr, geoip, country) != NULL)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington ret = dns_geoip_country_code;
e419f613d8591885df608cb73065921be07dd12eBob Halley break;
e419f613d8591885df608cb73065921be07dd12eBob Halley case dns_geoip_countrycode3:
e419f613d8591885df608cb73065921be07dd12eBob Halley if (DB46(reqaddr, geoip, city) != NULL)
e419f613d8591885df608cb73065921be07dd12eBob Halley ret = dns_geoip_city_countrycode3;
e419f613d8591885df608cb73065921be07dd12eBob Halley else if (DB46(reqaddr, geoip, country) != NULL)
e419f613d8591885df608cb73065921be07dd12eBob Halley ret = dns_geoip_country_code3;
e419f613d8591885df608cb73065921be07dd12eBob Halley break;
e419f613d8591885df608cb73065921be07dd12eBob Halley case dns_geoip_countryname:
e419f613d8591885df608cb73065921be07dd12eBob Halley if (DB46(reqaddr, geoip, city) != NULL)
e419f613d8591885df608cb73065921be07dd12eBob Halley ret = dns_geoip_city_countryname;
e419f613d8591885df608cb73065921be07dd12eBob Halley else if (DB46(reqaddr, geoip, country) != NULL)
e419f613d8591885df608cb73065921be07dd12eBob Halley ret = dns_geoip_country_name;
e419f613d8591885df608cb73065921be07dd12eBob Halley break;
e419f613d8591885df608cb73065921be07dd12eBob Halley case dns_geoip_region:
e419f613d8591885df608cb73065921be07dd12eBob Halley if (DB46(reqaddr, geoip, city) != NULL)
e419f613d8591885df608cb73065921be07dd12eBob Halley ret = dns_geoip_city_region;
e419f613d8591885df608cb73065921be07dd12eBob Halley else if (reqaddr->family == AF_INET && geoip->region != NULL)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ret = dns_geoip_region_code;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_regionname:
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington if (DB46(reqaddr, geoip, city) != NULL)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington ret = dns_geoip_city_regionname;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington else if (reqaddr->family == AF_INET && geoip->region != NULL)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington ret = dns_geoip_region_name;
e419f613d8591885df608cb73065921be07dd12eBob Halley break;
e419f613d8591885df608cb73065921be07dd12eBob Halley default:
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (ret);
e419f613d8591885df608cb73065921be07dd12eBob Halley}
e419f613d8591885df608cb73065921be07dd12eBob Halley#endif /* HAVE_GEOIP */
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halleyisc_boolean_t
e419f613d8591885df608cb73065921be07dd12eBob Halleydns_geoip_match(const isc_netaddr_t *reqaddr,
e419f613d8591885df608cb73065921be07dd12eBob Halley const dns_geoip_databases_t *geoip,
e419f613d8591885df608cb73065921be07dd12eBob Halley const dns_geoip_elem_t *elt)
e419f613d8591885df608cb73065921be07dd12eBob Halley{
e419f613d8591885df608cb73065921be07dd12eBob Halley#ifndef HAVE_GEOIP
e419f613d8591885df608cb73065921be07dd12eBob Halley UNUSED(reqaddr);
e419f613d8591885df608cb73065921be07dd12eBob Halley UNUSED(geoip);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley UNUSED(elt);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley return (ISC_FALSE);
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley#else
e419f613d8591885df608cb73065921be07dd12eBob Halley GeoIP *db;
e419f613d8591885df608cb73065921be07dd12eBob Halley GeoIPRecord *record;
e419f613d8591885df608cb73065921be07dd12eBob Halley GeoIPRegion *region;
e419f613d8591885df608cb73065921be07dd12eBob Halley dns_geoip_subtype_t subtype;
e419f613d8591885df608cb73065921be07dd12eBob Halley isc_uint32_t ipnum = 0;
e419f613d8591885df608cb73065921be07dd12eBob Halley int maxlen = 0, id;
e419f613d8591885df608cb73065921be07dd12eBob Halley const char *cs;
e419f613d8591885df608cb73065921be07dd12eBob Halley char *s;
e419f613d8591885df608cb73065921be07dd12eBob Halley#ifdef HAVE_GEOIP_V6
e419f613d8591885df608cb73065921be07dd12eBob Halley const geoipv6_t *ipnum6 = NULL;
e419f613d8591885df608cb73065921be07dd12eBob Halley#else
e419f613d8591885df608cb73065921be07dd12eBob Halley const void *ipnum6 = NULL;
e419f613d8591885df608cb73065921be07dd12eBob Halley#endif
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley INSIST(geoip != NULL);
e419f613d8591885df608cb73065921be07dd12eBob Halley
e419f613d8591885df608cb73065921be07dd12eBob Halley switch (reqaddr->family) {
e419f613d8591885df608cb73065921be07dd12eBob Halley case AF_INET:
e419f613d8591885df608cb73065921be07dd12eBob Halley ipnum = ntohl(reqaddr->type.in.s_addr);
e419f613d8591885df608cb73065921be07dd12eBob Halley break;
1872808932603066d401d3de97db11af8ffee78aAndreas Gustafsson case AF_INET6:
e419f613d8591885df608cb73065921be07dd12eBob Halley#ifdef HAVE_GEOIP_V6
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ipnum6 = &reqaddr->type.in6;
e419f613d8591885df608cb73065921be07dd12eBob Halley break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#else
e419f613d8591885df608cb73065921be07dd12eBob Halley return (ISC_FALSE);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#endif
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley default:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (ISC_FALSE);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
e419f613d8591885df608cb73065921be07dd12eBob Halley
1872808932603066d401d3de97db11af8ffee78aAndreas Gustafsson subtype = fix_subtype(reqaddr, geoip, elt->subtype);
e419f613d8591885df608cb73065921be07dd12eBob Halley
1872808932603066d401d3de97db11af8ffee78aAndreas Gustafsson switch (subtype) {
1872808932603066d401d3de97db11af8ffee78aAndreas Gustafsson case dns_geoip_country_code:
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley maxlen = 2;
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley goto getcountry;
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley case dns_geoip_country_code3:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley maxlen = 3;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley goto getcountry;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_country_name:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley maxlen = 255;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley getcountry:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley db = DB46(reqaddr, geoip, country);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (db == NULL)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (ISC_FALSE);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley INSIST(elt->as_string != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley cs = country_lookup(db, subtype, reqaddr->family,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ipnum, ipnum6);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (cs != NULL && strncasecmp(elt->as_string, cs, maxlen) == 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (ISC_TRUE);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley break;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_countrycode:
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case dns_geoip_city_countrycode3:
e419f613d8591885df608cb73065921be07dd12eBob Halley case dns_geoip_city_countryname:
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley case dns_geoip_city_region:
case dns_geoip_city_regionname:
case dns_geoip_city_name:
case dns_geoip_city_postalcode:
case dns_geoip_city_continentcode:
case dns_geoip_city_timezonecode:
INSIST(elt->as_string != NULL);
db = DB46(reqaddr, geoip, city);
if (db == NULL)
return (ISC_FALSE);
record = city_lookup(db, subtype,
reqaddr->family, ipnum, ipnum6);
if (record == NULL)
break;
s = city_string(record, subtype, &maxlen);
INSIST(maxlen != 0);
if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0)
return (ISC_TRUE);
break;
case dns_geoip_city_metrocode:
db = DB46(reqaddr, geoip, city);
if (db == NULL)
return (ISC_FALSE);
record = city_lookup(db, subtype,
reqaddr->family, ipnum, ipnum6);
if (record == NULL)
break;
if (elt->as_int == record->metro_code)
return (ISC_TRUE);
break;
case dns_geoip_city_areacode:
db = DB46(reqaddr, geoip, city);
if (db == NULL)
return (ISC_FALSE);
record = city_lookup(db, subtype,
reqaddr->family, ipnum, ipnum6);
if (record == NULL)
break;
if (elt->as_int == record->area_code)
return (ISC_TRUE);
break;
case dns_geoip_region_countrycode:
case dns_geoip_region_code:
case dns_geoip_region_name:
case dns_geoip_region:
if (geoip->region == NULL)
return (ISC_FALSE);
INSIST(elt->as_string != NULL);
/* Region DB is not supported for IPv6 */
if (reqaddr->family == AF_INET6)
return (ISC_FALSE);
region = region_lookup(geoip->region, subtype, ipnum);
if (region == NULL)
break;
s = region_string(region, subtype, &maxlen);
INSIST(maxlen != 0);
if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0)
return (ISC_TRUE);
break;
case dns_geoip_isp_name:
db = geoip->isp;
goto getname;
case dns_geoip_org_name:
db = geoip->org;
goto getname;
case dns_geoip_as_asnum:
db = geoip->as;
goto getname;
case dns_geoip_domain_name:
db = geoip->domain;
getname:
if (db == NULL)
return (ISC_FALSE);
INSIST(elt->as_string != NULL);
/* ISP, Org, AS, and Domain are not supported for IPv6 */
if (reqaddr->family == AF_INET6)
return (ISC_FALSE);
s = name_lookup(db, subtype, ipnum);
if (s != NULL && strcasecmp(elt->as_string, s) == 0)
return (ISC_TRUE);
break;
case dns_geoip_netspeed_id:
INSIST(geoip->netspeed != NULL);
/* Netspeed DB is not supported for IPv6 */
if (reqaddr->family == AF_INET6)
return (ISC_FALSE);
id = netspeed_lookup(geoip->netspeed, subtype, ipnum);
if (id == elt->as_int)
return (ISC_TRUE);
break;
default:
INSIST(0);
}
return (ISC_FALSE);
#endif
}
void
dns_geoip_shutdown(void) {
#if defined(HAVE_GEOIP) && defined(ISC_PLATFORM_USETHREADS)
if (state_mctx != NULL)
isc_mem_detach(&state_mctx);
#else
return;
#endif
}