00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020
00021 #include <isc/util.h>
00022
00023 #include <isc/mem.h>
00024 #include <isc/once.h>
00025 #include <isc/string.h>
00026
00027 #include <dns/acl.h>
00028 #include <dns/geoip.h>
00029
00030 #include <isc/thread.h>
00031 #include <math.h>
00032 #ifndef WIN32
00033 #include <netinet/in.h>
00034 #else
00035 #ifndef _WINSOCKAPI_
00036 #define _WINSOCKAPI_
00037 #endif
00038 #include <winsock2.h>
00039 #endif
00040 #include <dns/log.h>
00041
00042 #ifdef HAVE_GEOIP
00043 #include <GeoIP.h>
00044 #include <GeoIPCity.h>
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 typedef struct geoip_state {
00071 isc_uint16_t subtype;
00072 unsigned int family;
00073 isc_uint32_t ipnum;
00074 geoipv6_t ipnum6;
00075 isc_uint8_t scope;
00076 GeoIPRecord *record;
00077 GeoIPRegion *region;
00078 const char *text;
00079 char *name;
00080 int id;
00081 isc_mem_t *mctx;
00082 } geoip_state_t;
00083
00084 #ifdef ISC_PLATFORM_USETHREADS
00085 static isc_mutex_t key_mutex;
00086 static isc_boolean_t state_key_initialized = ISC_FALSE;
00087 static isc_thread_key_t state_key;
00088 static isc_once_t mutex_once = ISC_ONCE_INIT;
00089 static isc_mem_t *state_mctx = NULL;
00090
00091 static void
00092 key_mutex_init(void) {
00093 RUNTIME_CHECK(isc_mutex_init(&key_mutex) == ISC_R_SUCCESS);
00094 }
00095
00096 static void
00097 free_state(void *arg) {
00098 geoip_state_t *state = arg;
00099 if (state != NULL && state->record != NULL)
00100 GeoIPRecord_delete(state->record);
00101 if (state != NULL)
00102 isc_mem_putanddetach(&state->mctx,
00103 state, sizeof(geoip_state_t));
00104 isc_thread_key_setspecific(state_key, NULL);
00105 }
00106
00107 static isc_result_t
00108 state_key_init(void) {
00109 isc_result_t result;
00110
00111 result = isc_once_do(&mutex_once, key_mutex_init);
00112 if (result != ISC_R_SUCCESS)
00113 return (result);
00114
00115 if (!state_key_initialized) {
00116 LOCK(&key_mutex);
00117 if (!state_key_initialized) {
00118 int ret;
00119
00120 if (state_mctx == NULL)
00121 result = isc_mem_create2(0, 0, &state_mctx, 0);
00122 if (result != ISC_R_SUCCESS)
00123 goto unlock;
00124 isc_mem_setname(state_mctx, "geoip_state", NULL);
00125 isc_mem_setdestroycheck(state_mctx, ISC_FALSE);
00126
00127 ret = isc_thread_key_create(&state_key, free_state);
00128 if (ret == 0)
00129 state_key_initialized = ISC_TRUE;
00130 else
00131 result = ISC_R_FAILURE;
00132 }
00133 unlock:
00134 UNLOCK(&key_mutex);
00135 }
00136
00137 return (result);
00138 }
00139 #else
00140 static geoip_state_t saved_state;
00141 #endif
00142
00143 static void
00144 clean_state(geoip_state_t *state) {
00145 if (state == NULL)
00146 return;
00147
00148 if (state->record != NULL) {
00149 GeoIPRecord_delete(state->record);
00150 state->record = NULL;
00151 }
00152 if (state->region != NULL) {
00153 GeoIPRegion_delete(state->region);
00154 state->region = NULL;
00155 }
00156 if (state->name != NULL) {
00157 free (state->name);
00158 state->name = NULL;
00159 }
00160 state->ipnum = 0;
00161 state->text = NULL;
00162 state->id = 0;
00163 }
00164
00165 static isc_result_t
00166 set_state(unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6,
00167 isc_uint8_t scope, dns_geoip_subtype_t subtype, GeoIPRecord *record,
00168 GeoIPRegion *region, char *name, const char *text, int id)
00169 {
00170 geoip_state_t *state = NULL;
00171 #ifdef ISC_PLATFORM_USETHREADS
00172 isc_result_t result;
00173
00174 result = state_key_init();
00175 if (result != ISC_R_SUCCESS)
00176 return (result);
00177
00178 state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
00179 if (state == NULL) {
00180 state = (geoip_state_t *) isc_mem_get(state_mctx,
00181 sizeof(geoip_state_t));
00182 if (state == NULL)
00183 return (ISC_R_NOMEMORY);
00184 memset(state, 0, sizeof(*state));
00185
00186 result = isc_thread_key_setspecific(state_key, state);
00187 if (result != ISC_R_SUCCESS) {
00188 isc_mem_put(state_mctx, state, sizeof(geoip_state_t));
00189 return (result);
00190 }
00191
00192 isc_mem_attach(state_mctx, &state->mctx);
00193 } else
00194 clean_state(state);
00195 #else
00196 state = &saved_state;
00197 clean_state(state);
00198 #endif
00199
00200 if (family == AF_INET)
00201 state->ipnum = ipnum;
00202 else
00203 state->ipnum6 = *ipnum6;
00204
00205 state->family = family;
00206 state->subtype = subtype;
00207 state->scope = scope;
00208 state->record = record;
00209 state->region = region;
00210 state->name = name;
00211 state->text = text;
00212 state->id = id;
00213
00214 return (ISC_R_SUCCESS);
00215 }
00216
00217 static geoip_state_t *
00218 get_state_for(unsigned int family, isc_uint32_t ipnum,
00219 const geoipv6_t *ipnum6)
00220 {
00221 geoip_state_t *state;
00222
00223 #ifdef ISC_PLATFORM_USETHREADS
00224 isc_result_t result;
00225
00226 result = state_key_init();
00227 if (result != ISC_R_SUCCESS)
00228 return (NULL);
00229
00230 state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
00231 if (state == NULL)
00232 return (NULL);
00233 #else
00234 state = &saved_state;
00235 #endif
00236
00237 if (state->family == family &&
00238 ((state->family == AF_INET && state->ipnum == ipnum) ||
00239 (state->family == AF_INET6 && ipnum6 != NULL &&
00240 memcmp(state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0)))
00241 return (state);
00242
00243 return (NULL);
00244 }
00245
00246
00247
00248
00249
00250
00251 static const char *
00252 country_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
00253 unsigned int family,
00254 isc_uint32_t ipnum, const geoipv6_t *ipnum6,
00255 isc_uint8_t *scope)
00256 {
00257 geoip_state_t *prev_state = NULL;
00258 const char *text = NULL;
00259 GeoIPLookup gl;
00260
00261 REQUIRE(db != NULL);
00262
00263 #ifndef HAVE_GEOIP_V6
00264
00265 if (family == AF_INET6)
00266 return (NULL);
00267 #endif
00268
00269 prev_state = get_state_for(family, ipnum, ipnum6);
00270 if (prev_state != NULL && prev_state->subtype == subtype) {
00271 text = prev_state->text;
00272 if (scope != NULL)
00273 *scope = prev_state->scope;
00274 }
00275
00276 if (text == NULL) {
00277 switch (subtype) {
00278 case dns_geoip_country_code:
00279 if (family == AF_INET)
00280 text = GeoIP_country_code_by_ipnum_gl(db,
00281 ipnum, &gl);
00282 #ifdef HAVE_GEOIP_V6
00283 else
00284 text = GeoIP_country_code_by_ipnum_v6_gl(db,
00285 *ipnum6, &gl);
00286 #endif
00287 break;
00288 case dns_geoip_country_code3:
00289 if (family == AF_INET)
00290 text = GeoIP_country_code3_by_ipnum_gl(db,
00291 ipnum, &gl);
00292 #ifdef HAVE_GEOIP_V6
00293 else
00294 text = GeoIP_country_code3_by_ipnum_v6_gl(db,
00295 *ipnum6, &gl);
00296 #endif
00297 break;
00298 case dns_geoip_country_name:
00299 if (family == AF_INET)
00300 text = GeoIP_country_name_by_ipnum_gl(db,
00301 ipnum, &gl);
00302 #ifdef HAVE_GEOIP_V6
00303 else
00304 text = GeoIP_country_name_by_ipnum_v6_gl(db,
00305 *ipnum6, &gl);
00306 #endif
00307 break;
00308 default:
00309 INSIST(0);
00310 }
00311
00312 if (text == NULL)
00313 return (NULL);
00314
00315 if (scope != NULL)
00316 *scope = gl.netmask;
00317
00318 set_state(family, ipnum, ipnum6, gl.netmask, subtype,
00319 NULL, NULL, NULL, text, 0);
00320 }
00321
00322 return (text);
00323 }
00324
00325 static char *
00326 city_string(GeoIPRecord *record, dns_geoip_subtype_t subtype, int *maxlen) {
00327 const char *s;
00328 char *deconst;
00329
00330 REQUIRE(record != NULL);
00331 REQUIRE(maxlen != NULL);
00332
00333
00334 switch (subtype) {
00335 case dns_geoip_city_countrycode:
00336 case dns_geoip_city_region:
00337 case dns_geoip_city_continentcode:
00338 *maxlen = 2;
00339 break;
00340
00341 case dns_geoip_city_countrycode3:
00342 *maxlen = 3;
00343 break;
00344
00345 default:
00346
00347 *maxlen = 255;
00348 }
00349
00350 switch (subtype) {
00351 case dns_geoip_city_countrycode:
00352 return (record->country_code);
00353 case dns_geoip_city_countrycode3:
00354 return (record->country_code3);
00355 case dns_geoip_city_countryname:
00356 return (record->country_name);
00357 case dns_geoip_city_region:
00358 return (record->region);
00359 case dns_geoip_city_regionname:
00360 s = GeoIP_region_name_by_code(record->country_code,
00361 record->region);
00362 DE_CONST(s, deconst);
00363 return (deconst);
00364 case dns_geoip_city_name:
00365 return (record->city);
00366 case dns_geoip_city_postalcode:
00367 return (record->postal_code);
00368 case dns_geoip_city_continentcode:
00369 return (record->continent_code);
00370 case dns_geoip_city_timezonecode:
00371 s = GeoIP_time_zone_by_country_and_region(record->country_code,
00372 record->region);
00373 DE_CONST(s, deconst);
00374 return (deconst);
00375 default:
00376 INSIST(0);
00377 }
00378 }
00379
00380 static isc_boolean_t
00381 is_city(dns_geoip_subtype_t subtype) {
00382 switch (subtype) {
00383 case dns_geoip_city_countrycode:
00384 case dns_geoip_city_countrycode3:
00385 case dns_geoip_city_countryname:
00386 case dns_geoip_city_region:
00387 case dns_geoip_city_regionname:
00388 case dns_geoip_city_name:
00389 case dns_geoip_city_postalcode:
00390 case dns_geoip_city_continentcode:
00391 case dns_geoip_city_timezonecode:
00392 case dns_geoip_city_metrocode:
00393 case dns_geoip_city_areacode:
00394 return (ISC_TRUE);
00395 default:
00396 return (ISC_FALSE);
00397 }
00398 }
00399
00400
00401
00402
00403
00404
00405 static GeoIPRecord *
00406 city_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
00407 unsigned int family, isc_uint32_t ipnum,
00408 const geoipv6_t *ipnum6,
00409 isc_uint8_t *scope)
00410 {
00411 GeoIPRecord *record = NULL;
00412 geoip_state_t *prev_state = NULL;
00413
00414 REQUIRE(db != NULL);
00415
00416 #ifndef HAVE_GEOIP_V6
00417
00418 if (family == AF_INET6)
00419 return (NULL);
00420 #endif
00421
00422 prev_state = get_state_for(family, ipnum, ipnum6);
00423 if (prev_state != NULL && is_city(prev_state->subtype)) {
00424 record = prev_state->record;
00425 if (scope != NULL)
00426 *scope = record->netmask;
00427 }
00428
00429 if (record == NULL) {
00430 if (family == AF_INET)
00431 record = GeoIP_record_by_ipnum(db, ipnum);
00432 #ifdef HAVE_GEOIP_V6
00433 else
00434 record = GeoIP_record_by_ipnum_v6(db, *ipnum6);
00435 #endif
00436 if (record == NULL)
00437 return (NULL);
00438
00439 if (scope != NULL)
00440 *scope = record->netmask;
00441
00442 set_state(family, ipnum, ipnum6, record->netmask, subtype,
00443 record, NULL, NULL, NULL, 0);
00444 }
00445
00446 return (record);
00447 }
00448
00449 static char * region_string(GeoIPRegion *region, dns_geoip_subtype_t subtype, int *maxlen) {
00450 const char *s;
00451 char *deconst;
00452
00453 REQUIRE(region != NULL);
00454 REQUIRE(maxlen != NULL);
00455
00456 switch (subtype) {
00457 case dns_geoip_region_countrycode:
00458 *maxlen = 2;
00459 return (region->country_code);
00460 case dns_geoip_region_code:
00461 *maxlen = 2;
00462 return (region->region);
00463 case dns_geoip_region_name:
00464 *maxlen = 255;
00465 s = GeoIP_region_name_by_code(region->country_code,
00466 region->region);
00467 DE_CONST(s, deconst);
00468 return (deconst);
00469 default:
00470 INSIST(0);
00471 }
00472 }
00473
00474 static isc_boolean_t
00475 is_region(dns_geoip_subtype_t subtype) {
00476 switch (subtype) {
00477 case dns_geoip_region_countrycode:
00478 case dns_geoip_region_code:
00479 return (ISC_TRUE);
00480 default:
00481 return (ISC_FALSE);
00482 }
00483 }
00484
00485
00486
00487
00488
00489
00490 static GeoIPRegion *
00491 region_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
00492 isc_uint32_t ipnum, isc_uint8_t *scope)
00493 {
00494 GeoIPRegion *region = NULL;
00495 geoip_state_t *prev_state = NULL;
00496 GeoIPLookup gl;
00497
00498 REQUIRE(db != NULL);
00499
00500 prev_state = get_state_for(AF_INET, ipnum, NULL);
00501 if (prev_state != NULL && is_region(prev_state->subtype)) {
00502 region = prev_state->region;
00503 if (scope != NULL)
00504 *scope = prev_state->scope;
00505 }
00506
00507 if (region == NULL) {
00508 region = GeoIP_region_by_ipnum_gl(db, ipnum, &gl);
00509 if (region == NULL)
00510 return (NULL);
00511
00512 if (scope != NULL)
00513 *scope = gl.netmask;
00514
00515 set_state(AF_INET, ipnum, NULL, gl.netmask,
00516 subtype, NULL, region, NULL, NULL, 0);
00517 }
00518
00519 return (region);
00520 }
00521
00522
00523
00524
00525
00526
00527 static char *
00528 name_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
00529 isc_uint32_t ipnum, isc_uint8_t *scope)
00530 {
00531 char *name = NULL;
00532 geoip_state_t *prev_state = NULL;
00533 GeoIPLookup gl;
00534
00535 REQUIRE(db != NULL);
00536
00537 prev_state = get_state_for(AF_INET, ipnum, NULL);
00538 if (prev_state != NULL && prev_state->subtype == subtype) {
00539 name = prev_state->name;
00540 if (scope != NULL)
00541 *scope = prev_state->scope;
00542 }
00543
00544 if (name == NULL) {
00545 name = GeoIP_name_by_ipnum_gl(db, ipnum, &gl);
00546 if (name == NULL)
00547 return (NULL);
00548
00549 if (scope != NULL)
00550 *scope = gl.netmask;
00551
00552 set_state(AF_INET, ipnum, NULL, gl.netmask,
00553 subtype, NULL, NULL, name, NULL, 0);
00554 }
00555
00556 return (name);
00557 }
00558
00559
00560
00561
00562
00563
00564 static int
00565 netspeed_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
00566 isc_uint32_t ipnum, isc_uint8_t *scope)
00567 {
00568 geoip_state_t *prev_state = NULL;
00569 isc_boolean_t found = ISC_FALSE;
00570 GeoIPLookup gl;
00571 int id = -1;
00572
00573 REQUIRE(db != NULL);
00574
00575 prev_state = get_state_for(AF_INET, ipnum, NULL);
00576 if (prev_state != NULL && prev_state->subtype == subtype) {
00577 id = prev_state->id;
00578 if (scope != NULL)
00579 *scope = prev_state->scope;
00580 found = ISC_TRUE;
00581 }
00582
00583 if (!found) {
00584 id = GeoIP_id_by_ipnum_gl(db, ipnum, &gl);
00585 if (id == 0)
00586 return (0);
00587
00588 if (scope != NULL)
00589 *scope = gl.netmask;
00590
00591 set_state(AF_INET, ipnum, NULL, gl.netmask,
00592 subtype, NULL, NULL, NULL, NULL, id);
00593 }
00594
00595 return (id);
00596 }
00597 #endif
00598
00599 #define DB46(addr, geoip, name) \
00600 ((addr->family == AF_INET) ? (geoip->name##_v4) : (geoip->name##_v6))
00601
00602 #ifdef HAVE_GEOIP
00603
00604
00605
00606 static dns_geoip_subtype_t
00607 fix_subtype(const isc_netaddr_t *reqaddr, const dns_geoip_databases_t *geoip,
00608 dns_geoip_subtype_t subtype)
00609 {
00610 dns_geoip_subtype_t ret = subtype;
00611
00612 switch (subtype) {
00613 case dns_geoip_countrycode:
00614 if (DB46(reqaddr, geoip, city) != NULL)
00615 ret = dns_geoip_city_countrycode;
00616 else if (reqaddr->family == AF_INET && geoip->region != NULL)
00617 ret = dns_geoip_region_countrycode;
00618 else if (DB46(reqaddr, geoip, country) != NULL)
00619 ret = dns_geoip_country_code;
00620 break;
00621 case dns_geoip_countrycode3:
00622 if (DB46(reqaddr, geoip, city) != NULL)
00623 ret = dns_geoip_city_countrycode3;
00624 else if (DB46(reqaddr, geoip, country) != NULL)
00625 ret = dns_geoip_country_code3;
00626 break;
00627 case dns_geoip_countryname:
00628 if (DB46(reqaddr, geoip, city) != NULL)
00629 ret = dns_geoip_city_countryname;
00630 else if (DB46(reqaddr, geoip, country) != NULL)
00631 ret = dns_geoip_country_name;
00632 break;
00633 case dns_geoip_region:
00634 if (DB46(reqaddr, geoip, city) != NULL)
00635 ret = dns_geoip_city_region;
00636 else if (reqaddr->family == AF_INET && geoip->region != NULL)
00637 ret = dns_geoip_region_code;
00638 break;
00639 case dns_geoip_regionname:
00640 if (DB46(reqaddr, geoip, city) != NULL)
00641 ret = dns_geoip_city_regionname;
00642 else if (reqaddr->family == AF_INET && geoip->region != NULL)
00643 ret = dns_geoip_region_name;
00644 break;
00645 default:
00646 break;
00647 }
00648
00649 return (ret);
00650 }
00651 #endif
00652
00653 isc_boolean_t
00654 dns_geoip_match(const isc_netaddr_t *reqaddr, isc_uint8_t *scope,
00655 const dns_geoip_databases_t *geoip,
00656 const dns_geoip_elem_t *elt)
00657 {
00658 #ifndef HAVE_GEOIP
00659 UNUSED(reqaddr);
00660 UNUSED(geoip);
00661 UNUSED(elt);
00662
00663 return (ISC_FALSE);
00664 #else
00665 GeoIP *db;
00666 GeoIPRecord *record;
00667 GeoIPRegion *region;
00668 dns_geoip_subtype_t subtype;
00669 isc_uint32_t ipnum = 0;
00670 int maxlen = 0, id, family;
00671 const char *cs;
00672 char *s;
00673 #ifdef HAVE_GEOIP_V6
00674 const geoipv6_t *ipnum6 = NULL;
00675 #else
00676 const void *ipnum6 = NULL;
00677 #endif
00678
00679 INSIST(geoip != NULL);
00680
00681 family = reqaddr->family;
00682 switch (family) {
00683 case AF_INET:
00684 ipnum = ntohl(reqaddr->type.in.s_addr);
00685 break;
00686 case AF_INET6:
00687 #ifdef HAVE_GEOIP_V6
00688 ipnum6 = &reqaddr->type.in6;
00689 break;
00690 #else
00691 return (ISC_FALSE);
00692 #endif
00693 default:
00694 return (ISC_FALSE);
00695 }
00696
00697 subtype = fix_subtype(reqaddr, geoip, elt->subtype);
00698
00699 switch (subtype) {
00700 case dns_geoip_country_code:
00701 maxlen = 2;
00702 goto getcountry;
00703
00704 case dns_geoip_country_code3:
00705 maxlen = 3;
00706 goto getcountry;
00707
00708 case dns_geoip_country_name:
00709 maxlen = 255;
00710 getcountry:
00711 db = DB46(reqaddr, geoip, country);
00712 if (db == NULL)
00713 return (ISC_FALSE);
00714
00715 INSIST(elt->as_string != NULL);
00716
00717 cs = country_lookup(db, subtype, family, ipnum, ipnum6, scope);
00718 if (cs != NULL && strncasecmp(elt->as_string, cs, maxlen) == 0)
00719 return (ISC_TRUE);
00720 break;
00721
00722 case dns_geoip_city_countrycode:
00723 case dns_geoip_city_countrycode3:
00724 case dns_geoip_city_countryname:
00725 case dns_geoip_city_region:
00726 case dns_geoip_city_regionname:
00727 case dns_geoip_city_name:
00728 case dns_geoip_city_postalcode:
00729 case dns_geoip_city_continentcode:
00730 case dns_geoip_city_timezonecode:
00731 INSIST(elt->as_string != NULL);
00732
00733 db = DB46(reqaddr, geoip, city);
00734 if (db == NULL)
00735 return (ISC_FALSE);
00736
00737 record = city_lookup(db, subtype, family,
00738 ipnum, ipnum6, scope);
00739 if (record == NULL)
00740 break;
00741
00742 s = city_string(record, subtype, &maxlen);
00743 INSIST(maxlen != 0);
00744 if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0)
00745 return (ISC_TRUE);
00746 break;
00747
00748 case dns_geoip_city_metrocode:
00749 db = DB46(reqaddr, geoip, city);
00750 if (db == NULL)
00751 return (ISC_FALSE);
00752
00753 record = city_lookup(db, subtype, family,
00754 ipnum, ipnum6, scope);
00755 if (record == NULL)
00756 break;
00757
00758 if (elt->as_int == record->metro_code)
00759 return (ISC_TRUE);
00760 break;
00761
00762 case dns_geoip_city_areacode:
00763 db = DB46(reqaddr, geoip, city);
00764 if (db == NULL)
00765 return (ISC_FALSE);
00766
00767 record = city_lookup(db, subtype, family,
00768 ipnum, ipnum6, scope);
00769 if (record == NULL)
00770 break;
00771
00772 if (elt->as_int == record->area_code)
00773 return (ISC_TRUE);
00774 break;
00775
00776 case dns_geoip_region_countrycode:
00777 case dns_geoip_region_code:
00778 case dns_geoip_region_name:
00779 case dns_geoip_region:
00780 if (geoip->region == NULL)
00781 return (ISC_FALSE);
00782
00783 INSIST(elt->as_string != NULL);
00784
00785
00786 if (family == AF_INET6)
00787 return (ISC_FALSE);
00788
00789 region = region_lookup(geoip->region, subtype, ipnum, scope);
00790 if (region == NULL)
00791 break;
00792
00793 s = region_string(region, subtype, &maxlen);
00794 INSIST(maxlen != 0);
00795 if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0)
00796 return (ISC_TRUE);
00797 break;
00798
00799 case dns_geoip_isp_name:
00800 db = geoip->isp;
00801 goto getname;
00802
00803 case dns_geoip_org_name:
00804 db = geoip->org;
00805 goto getname;
00806
00807 case dns_geoip_as_asnum:
00808 db = geoip->as;
00809 goto getname;
00810
00811 case dns_geoip_domain_name:
00812 db = geoip->domain;
00813
00814 getname:
00815 if (db == NULL)
00816 return (ISC_FALSE);
00817
00818 INSIST(elt->as_string != NULL);
00819
00820 if (family == AF_INET6)
00821 return (ISC_FALSE);
00822
00823 s = name_lookup(db, subtype, ipnum, scope);
00824 if (s != NULL) {
00825 size_t l;
00826 if (strcasecmp(elt->as_string, s) == 0)
00827 return (ISC_TRUE);
00828 if (subtype != dns_geoip_as_asnum)
00829 break;
00830
00831
00832
00833 l = strlen(elt->as_string);
00834 if (l > 0U && strchr(elt->as_string, ' ') == NULL &&
00835 strncasecmp(elt->as_string, s, l) == 0 &&
00836 s[l] == ' ')
00837 return (ISC_TRUE);
00838 }
00839 break;
00840
00841 case dns_geoip_netspeed_id:
00842 INSIST(geoip->netspeed != NULL);
00843
00844
00845 if (family == AF_INET6)
00846 return (ISC_FALSE);
00847
00848 id = netspeed_lookup(geoip->netspeed, subtype, ipnum, scope);
00849 if (id == elt->as_int)
00850 return (ISC_TRUE);
00851 break;
00852
00853 case dns_geoip_countrycode:
00854 case dns_geoip_countrycode3:
00855 case dns_geoip_countryname:
00856 case dns_geoip_regionname:
00857
00858
00859
00860
00861 break;
00862
00863 default:
00864 INSIST(0);
00865 }
00866
00867 return (ISC_FALSE);
00868 #endif
00869 }
00870
00871 void
00872 dns_geoip_shutdown(void) {
00873 #ifdef HAVE_GEOIP
00874 GeoIP_cleanup();
00875 #ifdef ISC_PLATFORM_USETHREADS
00876 if (state_mctx != NULL)
00877 isc_mem_detach(&state_mctx);
00878 #endif
00879 #else
00880 return;
00881 #endif
00882 }