1 /* $NetBSD: geoip.c,v 1.1.1.6 2015/07/08 15:38:01 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC") 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /*! \file */ 20 21 #include <config.h> 22 23 #include <isc/util.h> 24 25 #include <isc/mem.h> 26 #include <isc/once.h> 27 #include <isc/string.h> 28 29 #include <dns/acl.h> 30 #include <dns/geoip.h> 31 32 #include <isc/thread.h> 33 #include <math.h> 34 #ifndef WIN32 35 #include <netinet/in.h> 36 #else 37 #ifndef _WINSOCKAPI_ 38 #define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ 39 #endif 40 #include <winsock2.h> 41 #endif /* WIN32 */ 42 #include <dns/log.h> 43 44 #ifdef HAVE_GEOIP 45 #include <GeoIP.h> 46 #include <GeoIPCity.h> 47 48 /* 49 * This structure preserves state from the previous GeoIP lookup, 50 * so that successive lookups for the same data from the same IP 51 * address will not require repeated calls into the GeoIP library 52 * to look up data in the database. This should improve performance 53 * somewhat. 54 * 55 * For lookups in the City and Region databases, we preserve pointers 56 * to the GeoIPRecord and GeoIPregion structures; these will need to be 57 * freed by GeoIPRecord_delete() and GeoIPRegion_delete(). 58 * 59 * for lookups in ISP, AS, Org and Domain we prserve a pointer to 60 * the returned name; these must be freed by free(). 61 * 62 * For lookups in Country we preserve a pointer to the text of 63 * the country code, name, etc (we use a different pointer for this 64 * than for the names returned by Org, ISP, etc, because those need 65 * to be freed but country lookups do not). 66 * 67 * For lookups in Netspeed we preserve the returned ID. 68 * 69 * XXX: Currently this mechanism is only used for IPv4 lookups; the 70 * family and addr6 fields are to be used IPv6 is added. 71 */ 72 typedef struct geoip_state { 73 isc_uint16_t subtype; 74 unsigned int family; 75 isc_uint32_t ipnum; 76 geoipv6_t ipnum6; 77 GeoIPRecord *record; 78 GeoIPRegion *region; 79 const char *text; 80 char *name; 81 int id; 82 isc_mem_t *mctx; 83 } geoip_state_t; 84 85 #ifdef ISC_PLATFORM_USETHREADS 86 static isc_mutex_t key_mutex; 87 static isc_boolean_t state_key_initialized = ISC_FALSE; 88 static isc_thread_key_t state_key; 89 static isc_once_t mutex_once = ISC_ONCE_INIT; 90 static isc_mem_t *state_mctx = NULL; 91 92 static void 93 key_mutex_init(void) { 94 RUNTIME_CHECK(isc_mutex_init(&key_mutex) == ISC_R_SUCCESS); 95 } 96 97 static void 98 free_state(void *arg) { 99 geoip_state_t *state = arg; 100 if (state != NULL && state->record != NULL) 101 GeoIPRecord_delete(state->record); 102 if (state != NULL) 103 isc_mem_putanddetach(&state->mctx, 104 state, sizeof(geoip_state_t)); 105 isc_thread_key_setspecific(state_key, NULL); 106 } 107 108 static isc_result_t 109 state_key_init(void) { 110 isc_result_t result; 111 112 result = isc_once_do(&mutex_once, key_mutex_init); 113 if (result != ISC_R_SUCCESS) 114 return (result); 115 116 if (!state_key_initialized) { 117 LOCK(&key_mutex); 118 if (!state_key_initialized) { 119 int ret; 120 121 if (state_mctx == NULL) 122 result = isc_mem_create2(0, 0, &state_mctx, 0); 123 if (result != ISC_R_SUCCESS) 124 goto unlock; 125 isc_mem_setname(state_mctx, "geoip_state", NULL); 126 isc_mem_setdestroycheck(state_mctx, ISC_FALSE); 127 128 ret = isc_thread_key_create(&state_key, free_state); 129 if (ret == 0) 130 state_key_initialized = ISC_TRUE; 131 else 132 result = ISC_R_FAILURE; 133 } 134 unlock: 135 UNLOCK(&key_mutex); 136 } 137 138 return (result); 139 } 140 #else 141 geoip_state_t prev_state; 142 #endif 143 144 static void 145 clean_state(geoip_state_t *state) { 146 if (state == NULL) 147 return; 148 149 if (state->record != NULL) { 150 GeoIPRecord_delete(state->record); 151 state->record = NULL; 152 } 153 if (state->region != NULL) { 154 GeoIPRegion_delete(state->region); 155 state->region = NULL; 156 } 157 if (state->name != NULL) { 158 free (state->name); 159 state->name = NULL; 160 } 161 state->ipnum = 0; 162 state->text = NULL; 163 state->id = 0; 164 } 165 166 static isc_result_t 167 set_state(unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6, 168 dns_geoip_subtype_t subtype, GeoIPRecord *record, 169 GeoIPRegion *region, char *name, const char *text, int id) 170 { 171 geoip_state_t *state = NULL; 172 173 #ifdef ISC_PLATFORM_USETHREADS 174 isc_result_t result; 175 176 result = state_key_init(); 177 if (result != ISC_R_SUCCESS) 178 return (result); 179 180 state = (geoip_state_t *) isc_thread_key_getspecific(state_key); 181 if (state == NULL) { 182 state = (geoip_state_t *) isc_mem_get(state_mctx, 183 sizeof(geoip_state_t)); 184 if (state == NULL) 185 return (ISC_R_NOMEMORY); 186 memset(state, 0, sizeof(*state)); 187 188 result = isc_thread_key_setspecific(state_key, state); 189 if (result != ISC_R_SUCCESS) { 190 isc_mem_put(state_mctx, state, sizeof(geoip_state_t)); 191 return (result); 192 } 193 194 isc_mem_attach(state_mctx, &state->mctx); 195 } else 196 clean_state(state); 197 #else 198 state = &prev_state; 199 clean_state(state); 200 #endif 201 202 if (family == AF_INET) 203 state->ipnum = ipnum; 204 else 205 state->ipnum6 = *ipnum6; 206 207 state->family = family; 208 state->subtype = subtype; 209 state->record = record; 210 state->region = region; 211 state->name = name; 212 state->text = text; 213 state->id = id; 214 215 return (ISC_R_SUCCESS); 216 } 217 218 static geoip_state_t * 219 get_state_for(unsigned int family, isc_uint32_t ipnum, 220 const geoipv6_t *ipnum6) 221 { 222 geoip_state_t *state; 223 224 #ifdef ISC_PLATFORM_USETHREADS 225 isc_result_t result; 226 227 result = state_key_init(); 228 if (result != ISC_R_SUCCESS) 229 return (NULL); 230 231 state = (geoip_state_t *) isc_thread_key_getspecific(state_key); 232 if (state == NULL) 233 return (NULL); 234 #else 235 state = &prev_state; 236 #endif 237 238 if (state->family == family && 239 ((state->family == AF_INET && state->ipnum == ipnum) || 240 (state->family == AF_INET6 && ipnum6 != NULL && 241 memcmp(state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0))) 242 return (state); 243 244 return (NULL); 245 } 246 247 /* 248 * Country lookups are performed if the previous lookup was from a 249 * different IP address than the current, or was for a search of a 250 * different subtype. 251 */ 252 static const char * 253 country_lookup(GeoIP *db, dns_geoip_subtype_t subtype, 254 unsigned int family, 255 isc_uint32_t ipnum, const geoipv6_t *ipnum6) 256 { 257 geoip_state_t *prev_state = NULL; 258 const char *text = NULL; 259 260 REQUIRE(db != NULL); 261 262 #ifndef HAVE_GEOIP_V6 263 /* no IPv6 support? give up now */ 264 if (family == AF_INET6) 265 return (NULL); 266 #endif 267 268 prev_state = get_state_for(family, ipnum, ipnum6); 269 if (prev_state != NULL && prev_state->subtype == subtype) 270 text = prev_state->text; 271 272 if (text == NULL) { 273 switch (subtype) { 274 case dns_geoip_country_code: 275 if (family == AF_INET) 276 text = GeoIP_country_code_by_ipnum(db, ipnum); 277 #ifdef HAVE_GEOIP_V6 278 else 279 text = GeoIP_country_code_by_ipnum_v6(db, 280 *ipnum6); 281 #endif 282 break; 283 case dns_geoip_country_code3: 284 if (family == AF_INET) 285 text = GeoIP_country_code3_by_ipnum(db, ipnum); 286 #ifdef HAVE_GEOIP_V6 287 else 288 text = GeoIP_country_code3_by_ipnum_v6(db, 289 *ipnum6); 290 #endif 291 break; 292 case dns_geoip_country_name: 293 if (family == AF_INET) 294 text = GeoIP_country_name_by_ipnum(db, ipnum); 295 #ifdef HAVE_GEOIP_V6 296 else 297 text = GeoIP_country_name_by_ipnum_v6(db, 298 *ipnum6); 299 #endif 300 break; 301 default: 302 INSIST(0); 303 } 304 305 set_state(family, ipnum, ipnum6, subtype, 306 NULL, NULL, NULL, text, 0); 307 } 308 309 return (text); 310 } 311 312 static char * 313 city_string(GeoIPRecord *record, dns_geoip_subtype_t subtype, int *maxlen) { 314 const char *s; 315 char *deconst; 316 317 REQUIRE(record != NULL); 318 REQUIRE(maxlen != NULL); 319 320 /* Set '*maxlen' to the maximum length of this subtype, if any */ 321 switch (subtype) { 322 case dns_geoip_city_countrycode: 323 case dns_geoip_city_region: 324 case dns_geoip_city_continentcode: 325 *maxlen = 2; 326 break; 327 328 case dns_geoip_city_countrycode3: 329 *maxlen = 3; 330 break; 331 332 default: 333 /* No fixed length; just use strcasecmp() for comparison */ 334 *maxlen = 255; 335 } 336 337 switch (subtype) { 338 case dns_geoip_city_countrycode: 339 return (record->country_code); 340 case dns_geoip_city_countrycode3: 341 return (record->country_code3); 342 case dns_geoip_city_countryname: 343 return (record->country_name); 344 case dns_geoip_city_region: 345 return (record->region); 346 case dns_geoip_city_regionname: 347 s = GeoIP_region_name_by_code(record->country_code, 348 record->region); 349 DE_CONST(s, deconst); 350 return (deconst); 351 case dns_geoip_city_name: 352 return (record->city); 353 case dns_geoip_city_postalcode: 354 return (record->postal_code); 355 case dns_geoip_city_continentcode: 356 return (record->continent_code); 357 case dns_geoip_city_timezonecode: 358 s = GeoIP_time_zone_by_country_and_region(record->country_code, 359 record->region); 360 DE_CONST(s, deconst); 361 return (deconst); 362 default: 363 INSIST(0); 364 } 365 } 366 367 static isc_boolean_t 368 is_city(dns_geoip_subtype_t subtype) { 369 switch (subtype) { 370 case dns_geoip_city_countrycode: 371 case dns_geoip_city_countrycode3: 372 case dns_geoip_city_countryname: 373 case dns_geoip_city_region: 374 case dns_geoip_city_regionname: 375 case dns_geoip_city_name: 376 case dns_geoip_city_postalcode: 377 case dns_geoip_city_continentcode: 378 case dns_geoip_city_timezonecode: 379 case dns_geoip_city_metrocode: 380 case dns_geoip_city_areacode: 381 return (ISC_TRUE); 382 default: 383 return (ISC_FALSE); 384 } 385 } 386 387 /* 388 * GeoIPRecord lookups are performed if the previous lookup was 389 * from a different IP address than the current, or was for a search 390 * outside the City database. 391 */ 392 static GeoIPRecord * 393 city_lookup(GeoIP *db, dns_geoip_subtype_t subtype, 394 unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6) 395 { 396 GeoIPRecord *record = NULL; 397 geoip_state_t *prev_state = NULL; 398 399 REQUIRE(db != NULL); 400 401 #ifndef HAVE_GEOIP_V6 402 /* no IPv6 support? give up now */ 403 if (family == AF_INET6) 404 return (NULL); 405 #endif 406 407 prev_state = get_state_for(family, ipnum, ipnum6); 408 if (prev_state != NULL && is_city(prev_state->subtype)) 409 record = prev_state->record; 410 411 if (record == NULL) { 412 if (family == AF_INET) 413 record = GeoIP_record_by_ipnum(db, ipnum); 414 #ifdef HAVE_GEOIP_V6 415 else 416 record = GeoIP_record_by_ipnum_v6(db, *ipnum6); 417 #endif 418 if (record == NULL) 419 return (NULL); 420 421 set_state(family, ipnum, ipnum6, subtype, 422 record, NULL, NULL, NULL, 0); 423 } 424 425 return (record); 426 } 427 428 static char * 429 region_string(GeoIPRegion *region, dns_geoip_subtype_t subtype, int *maxlen) { 430 const char *s; 431 char *deconst; 432 433 REQUIRE(region != NULL); 434 REQUIRE(maxlen != NULL); 435 436 switch (subtype) { 437 case dns_geoip_region_countrycode: 438 *maxlen = 2; 439 return (region->country_code); 440 case dns_geoip_region_code: 441 *maxlen = 2; 442 return (region->region); 443 case dns_geoip_region_name: 444 *maxlen = 255; 445 s = GeoIP_region_name_by_code(region->country_code, 446 region->region); 447 DE_CONST(s, deconst); 448 return (deconst); 449 default: 450 INSIST(0); 451 } 452 } 453 454 static isc_boolean_t 455 is_region(dns_geoip_subtype_t subtype) { 456 switch (subtype) { 457 case dns_geoip_region_countrycode: 458 case dns_geoip_region_code: 459 return (ISC_TRUE); 460 default: 461 return (ISC_FALSE); 462 } 463 } 464 465 /* 466 * GeoIPRegion lookups are performed if the previous lookup was 467 * from a different IP address than the current, or was for a search 468 * outside the Region database. 469 */ 470 static GeoIPRegion * 471 region_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) { 472 GeoIPRegion *region = NULL; 473 geoip_state_t *prev_state = NULL; 474 475 REQUIRE(db != NULL); 476 477 prev_state = get_state_for(AF_INET, ipnum, NULL); 478 if (prev_state != NULL && is_region(prev_state->subtype)) 479 region = prev_state->region; 480 481 if (region == NULL) { 482 region = GeoIP_region_by_ipnum(db, ipnum); 483 if (region == NULL) 484 return (NULL); 485 486 set_state(AF_INET, ipnum, NULL, 487 subtype, NULL, region, NULL, NULL, 0); 488 } 489 490 return (region); 491 } 492 493 /* 494 * ISP, Organization, AS Number and Domain lookups are performed if 495 * the previous lookup was from a different IP address than the current, 496 * or was for a search of a different subtype. 497 */ 498 static char * 499 name_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) { 500 char *name = NULL; 501 geoip_state_t *prev_state = NULL; 502 503 REQUIRE(db != NULL); 504 505 prev_state = get_state_for(AF_INET, ipnum, NULL); 506 if (prev_state != NULL && prev_state->subtype == subtype) 507 name = prev_state->name; 508 509 if (name == NULL) { 510 name = GeoIP_name_by_ipnum(db, ipnum); 511 if (name == NULL) 512 return (NULL); 513 514 set_state(AF_INET, ipnum, NULL, 515 subtype, NULL, NULL, name, NULL, 0); 516 } 517 518 return (name); 519 } 520 521 /* 522 * Netspeed lookups are performed if the previous lookup was from a 523 * different IP address than the current, or was for a search of a 524 * different subtype. 525 */ 526 static int 527 netspeed_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) { 528 geoip_state_t *prev_state = NULL; 529 isc_boolean_t found = ISC_FALSE; 530 int id = -1; 531 532 REQUIRE(db != NULL); 533 534 prev_state = get_state_for(AF_INET, ipnum, NULL); 535 if (prev_state != NULL && prev_state->subtype == subtype) { 536 id = prev_state->id; 537 found = ISC_TRUE; 538 } 539 540 if (!found) { 541 id = GeoIP_id_by_ipnum(db, ipnum); 542 set_state(AF_INET, ipnum, NULL, 543 subtype, NULL, NULL, NULL, NULL, id); 544 } 545 546 return (id); 547 } 548 #endif /* HAVE_GEOIP */ 549 550 #define DB46(addr, geoip, name) \ 551 ((addr->family == AF_INET) ? (geoip->name##_v4) : (geoip->name##_v6)) 552 553 #ifdef HAVE_GEOIP 554 /* 555 * Find the best database to answer a generic subtype 556 */ 557 static dns_geoip_subtype_t 558 fix_subtype(const isc_netaddr_t *reqaddr, const dns_geoip_databases_t *geoip, 559 dns_geoip_subtype_t subtype) 560 { 561 dns_geoip_subtype_t ret = subtype; 562 563 switch (subtype) { 564 case dns_geoip_countrycode: 565 if (DB46(reqaddr, geoip, city) != NULL) 566 ret = dns_geoip_city_countrycode; 567 else if (reqaddr->family == AF_INET && geoip->region != NULL) 568 ret = dns_geoip_region_countrycode; 569 else if (DB46(reqaddr, geoip, country) != NULL) 570 ret = dns_geoip_country_code; 571 break; 572 case dns_geoip_countrycode3: 573 if (DB46(reqaddr, geoip, city) != NULL) 574 ret = dns_geoip_city_countrycode3; 575 else if (DB46(reqaddr, geoip, country) != NULL) 576 ret = dns_geoip_country_code3; 577 break; 578 case dns_geoip_countryname: 579 if (DB46(reqaddr, geoip, city) != NULL) 580 ret = dns_geoip_city_countryname; 581 else if (DB46(reqaddr, geoip, country) != NULL) 582 ret = dns_geoip_country_name; 583 break; 584 case dns_geoip_region: 585 if (DB46(reqaddr, geoip, city) != NULL) 586 ret = dns_geoip_city_region; 587 else if (reqaddr->family == AF_INET && geoip->region != NULL) 588 ret = dns_geoip_region_code; 589 break; 590 case dns_geoip_regionname: 591 if (DB46(reqaddr, geoip, city) != NULL) 592 ret = dns_geoip_city_regionname; 593 else if (reqaddr->family == AF_INET && geoip->region != NULL) 594 ret = dns_geoip_region_name; 595 break; 596 default: 597 break; 598 } 599 600 return (ret); 601 } 602 #endif /* HAVE_GEOIP */ 603 604 isc_boolean_t 605 dns_geoip_match(const isc_netaddr_t *reqaddr, 606 const dns_geoip_databases_t *geoip, 607 const dns_geoip_elem_t *elt) 608 { 609 #ifndef HAVE_GEOIP 610 UNUSED(reqaddr); 611 UNUSED(geoip); 612 UNUSED(elt); 613 614 return (ISC_FALSE); 615 #else 616 GeoIP *db; 617 GeoIPRecord *record; 618 GeoIPRegion *region; 619 dns_geoip_subtype_t subtype; 620 isc_uint32_t ipnum = 0; 621 int maxlen = 0, id, family; 622 const char *cs; 623 char *s; 624 #ifdef HAVE_GEOIP_V6 625 const geoipv6_t *ipnum6 = NULL; 626 #else 627 const void *ipnum6 = NULL; 628 #endif 629 630 INSIST(geoip != NULL); 631 632 family = reqaddr->family; 633 switch (family) { 634 case AF_INET: 635 ipnum = ntohl(reqaddr->type.in.s_addr); 636 break; 637 case AF_INET6: 638 #ifdef HAVE_GEOIP_V6 639 ipnum6 = &reqaddr->type.in6; 640 break; 641 #else 642 return (ISC_FALSE); 643 #endif 644 default: 645 return (ISC_FALSE); 646 } 647 648 subtype = fix_subtype(reqaddr, geoip, elt->subtype); 649 650 switch (subtype) { 651 case dns_geoip_country_code: 652 maxlen = 2; 653 goto getcountry; 654 655 case dns_geoip_country_code3: 656 maxlen = 3; 657 goto getcountry; 658 659 case dns_geoip_country_name: 660 maxlen = 255; 661 getcountry: 662 db = DB46(reqaddr, geoip, country); 663 if (db == NULL) 664 return (ISC_FALSE); 665 666 INSIST(elt->as_string != NULL); 667 668 cs = country_lookup(db, subtype, family, ipnum, ipnum6); 669 if (cs != NULL && strncasecmp(elt->as_string, cs, maxlen) == 0) 670 return (ISC_TRUE); 671 break; 672 673 case dns_geoip_city_countrycode: 674 case dns_geoip_city_countrycode3: 675 case dns_geoip_city_countryname: 676 case dns_geoip_city_region: 677 case dns_geoip_city_regionname: 678 case dns_geoip_city_name: 679 case dns_geoip_city_postalcode: 680 case dns_geoip_city_continentcode: 681 case dns_geoip_city_timezonecode: 682 INSIST(elt->as_string != NULL); 683 684 db = DB46(reqaddr, geoip, city); 685 if (db == NULL) 686 return (ISC_FALSE); 687 688 record = city_lookup(db, subtype, family, ipnum, ipnum6); 689 if (record == NULL) 690 break; 691 692 s = city_string(record, subtype, &maxlen); 693 INSIST(maxlen != 0); 694 if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0) 695 return (ISC_TRUE); 696 break; 697 698 case dns_geoip_city_metrocode: 699 db = DB46(reqaddr, geoip, city); 700 if (db == NULL) 701 return (ISC_FALSE); 702 703 record = city_lookup(db, subtype, family, ipnum, ipnum6); 704 if (record == NULL) 705 break; 706 707 if (elt->as_int == record->metro_code) 708 return (ISC_TRUE); 709 break; 710 711 case dns_geoip_city_areacode: 712 db = DB46(reqaddr, geoip, city); 713 if (db == NULL) 714 return (ISC_FALSE); 715 716 record = city_lookup(db, subtype, family, ipnum, ipnum6); 717 if (record == NULL) 718 break; 719 720 if (elt->as_int == record->area_code) 721 return (ISC_TRUE); 722 break; 723 724 case dns_geoip_region_countrycode: 725 case dns_geoip_region_code: 726 case dns_geoip_region_name: 727 case dns_geoip_region: 728 if (geoip->region == NULL) 729 return (ISC_FALSE); 730 731 INSIST(elt->as_string != NULL); 732 733 /* Region DB is not supported for IPv6 */ 734 if (family == AF_INET6) 735 return (ISC_FALSE); 736 737 region = region_lookup(geoip->region, subtype, ipnum); 738 if (region == NULL) 739 break; 740 741 s = region_string(region, subtype, &maxlen); 742 INSIST(maxlen != 0); 743 if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0) 744 return (ISC_TRUE); 745 break; 746 747 case dns_geoip_isp_name: 748 db = geoip->isp; 749 goto getname; 750 751 case dns_geoip_org_name: 752 db = geoip->org; 753 goto getname; 754 755 case dns_geoip_as_asnum: 756 db = geoip->as; 757 goto getname; 758 759 case dns_geoip_domain_name: 760 db = geoip->domain; 761 762 getname: 763 if (db == NULL) 764 return (ISC_FALSE); 765 766 INSIST(elt->as_string != NULL); 767 /* ISP, Org, AS, and Domain are not supported for IPv6 */ 768 if (family == AF_INET6) 769 return (ISC_FALSE); 770 771 s = name_lookup(db, subtype, ipnum); 772 if (s != NULL) { 773 size_t l; 774 if (strcasecmp(elt->as_string, s) == 0) 775 return (ISC_TRUE); 776 if (subtype != dns_geoip_as_asnum) 777 break; 778 /* 779 * Just check if the ASNNNN value matches. 780 */ 781 l = strlen(elt->as_string); 782 if (l > 0U && strchr(elt->as_string, ' ') == NULL && 783 strncasecmp(elt->as_string, s, l) == 0 && 784 s[l] == ' ') 785 return (ISC_TRUE); 786 } 787 break; 788 789 case dns_geoip_netspeed_id: 790 INSIST(geoip->netspeed != NULL); 791 792 /* Netspeed DB is not supported for IPv6 */ 793 if (family == AF_INET6) 794 return (ISC_FALSE); 795 796 id = netspeed_lookup(geoip->netspeed, subtype, ipnum); 797 if (id == elt->as_int) 798 return (ISC_TRUE); 799 break; 800 801 case dns_geoip_countrycode: 802 case dns_geoip_countrycode3: 803 case dns_geoip_countryname: 804 case dns_geoip_regionname: 805 /* 806 * If these were not remapped by fix_subtype(), 807 * the database was unavailable. Always return false. 808 */ 809 break; 810 811 default: 812 INSIST(0); 813 } 814 815 return (ISC_FALSE); 816 #endif 817 } 818 819 void 820 dns_geoip_shutdown(void) { 821 #ifdef HAVE_GEOIP 822 GeoIP_cleanup(); 823 #ifdef ISC_PLATFORM_USETHREADS 824 if (state_mctx != NULL) 825 isc_mem_detach(&state_mctx); 826 #endif 827 #else 828 return; 829 #endif 830 } 831