]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] fix a problem with libgeoip 1.5 and higher
authorEvan Hunt <each@isc.org>
Thu, 23 Jan 2014 20:46:02 +0000 (12:46 -0800)
committerEvan Hunt <each@isc.org>
Thu, 23 Jan 2014 20:46:02 +0000 (12:46 -0800)
3715. [bug] The region and city databases could fail to
initialize when using some versions of libGeoIP,
causing assertion failures when named was
configured to use them. [RT #35427]

CHANGES
bin/named/geoip.c
lib/dns/geoip.c
lib/dns/tests/geoip_test.c

diff --git a/CHANGES b/CHANGES
index c681eb28a413a8de884f80b0bb2d3fae9be0869c..697a4002a2c526b5ebaedef4d62da73ec0e06226 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+3715.  [bug]           The region and city databases could fail to
+                       initialize when using some versions of libGeoIP,
+                       causing assertion failures when named was
+                       configured to use them. [RT #35427]
+
 3714.  [test]          System tests that need to test for cryptography
                        support before running can now use a common
                        "testcrypto.sh" script to do so. [RT #35213]
index 6f27da53d839f3ec36cdb72c176d593020b1f849..83fe825b054a9286c235900881a7be370ca813b0 100644 (file)
@@ -31,7 +31,7 @@ static dns_geoip_databases_t geoip_table = {
 };
 
 static void
-init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
+init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback,
              GeoIPOptions method, const char *name)
 {
        char *info;
@@ -49,22 +49,22 @@ init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
        if (! GeoIP_db_avail(edition)) {
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
                        NS_LOGMODULE_SERVER, ISC_LOG_INFO,
-                       "GeoIP %s DB not available", name);
-               return;
+                       "GeoIP %s (type %d) DB not available", name, edition);
+               goto fail;
        }
 
        isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
                NS_LOGMODULE_SERVER, ISC_LOG_INFO,
-               "initializing GeoIP %s DB", name);
+               "initializing GeoIP %s (type %d) DB", name, edition);
 
        db = GeoIP_open_type(edition, method);
        if (db == NULL) {
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
                        NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
-                       "failed to initialize GeoIP %s DB; "
-                       "geoip matches using this database will fail",
-                       name);
-               return;
+                       "failed to initialize GeoIP %s (type %d) DB%s",
+                       name, edition, fallback == 0
+                        ? "geoip matches using this database will fail" : "");
+               goto fail;
        }
 
        info = GeoIP_database_info(db);
@@ -74,18 +74,11 @@ init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
                              "%s", info);
 
        *dbp = db;
-}
+       return;
+ fail:
+       if (fallback != 0)
+               init_geoip_db(dbp, fallback, 0, method, name);
 
-static GeoIPDBTypes
-choose_rev(GeoIPDBTypes primary, GeoIPDBTypes secondary, const char *name) {
-       if (GeoIP_db_avail(primary))
-               return (primary);
-       if (GeoIP_db_avail(secondary))
-               return (secondary);
-       isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
-               NS_LOGMODULE_SERVER, ISC_LOG_INFO,
-               "GeoIP %s DB: neither revision available", name);
-       return (0);
 }
 #endif /* HAVE_GEOIP */
 
@@ -124,41 +117,32 @@ ns_geoip_load(char *dir) {
                GeoIP_setup_custom_directory(dir);
        }
 
-       init_geoip_db(&ns_g_geoip->country_v4, GEOIP_COUNTRY_EDITION,
+       init_geoip_db(&ns_g_geoip->country_v4, GEOIP_COUNTRY_EDITION, 0,
                      method, "Country (IPv4)");
 #ifdef HAVE_GEOIP_V6
-       init_geoip_db(&ns_g_geoip->country_v6, GEOIP_COUNTRY_EDITION_V6,
+       init_geoip_db(&ns_g_geoip->country_v6, GEOIP_COUNTRY_EDITION_V6, 0,
                      method, "Country (IPv6)");
 #endif
 
-       edition = choose_rev(GEOIP_CITY_EDITION_REV0,
-                            GEOIP_CITY_EDITION_REV1, "City (IPv4)");
-       if (edition != 0)
-               init_geoip_db(&ns_g_geoip->city_v4, edition,
-                             method, "City (IPv4)");
+       init_geoip_db(&ns_g_geoip->city_v4, GEOIP_CITY_EDITION_REV1,
+                     GEOIP_CITY_EDITION_REV0, method, "City (IPv4)");
 #if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6)
-       edition = choose_rev(GEOIP_CITY_EDITION_REV0_V6,
-                            GEOIP_CITY_EDITION_REV1_V6, "City (IPv6)");
-       if (edition != 0)
-               init_geoip_db(&ns_g_geoip->city_v6, edition,
-                             method, "City (IPv6)");
+       init_geoip_db(&ns_g_geoip->city_v6, GEOIP_CITY_EDITION_REV1_V6,
+                     GEOIP_CITY_EDITION_REV0_V6, method, "City (IPv6)");
 #endif
 
+       init_geoip_db(&ns_g_geoip->region, GEOIP_REGION_EDITION_REV1,
+                     GEOIP_REGION_EDITION_REV0, method, "Region");
 
-       edition = choose_rev(GEOIP_REGION_EDITION_REV0,
-                            GEOIP_REGION_EDITION_REV1, "Region");
-       if (edition != 0)
-               init_geoip_db(&ns_g_geoip->region, edition, method, "Region");
-
-       init_geoip_db(&ns_g_geoip->isp, GEOIP_ISP_EDITION,
+       init_geoip_db(&ns_g_geoip->isp, GEOIP_ISP_EDITION, 0,
                      method, "ISP");
-       init_geoip_db(&ns_g_geoip->org, GEOIP_ORG_EDITION,
+       init_geoip_db(&ns_g_geoip->org, GEOIP_ORG_EDITION, 0,
                      method, "Org");
-       init_geoip_db(&ns_g_geoip->as, GEOIP_ASNUM_EDITION,
+       init_geoip_db(&ns_g_geoip->as, GEOIP_ASNUM_EDITION, 0,
                      method, "AS");
-       init_geoip_db(&ns_g_geoip->domain, GEOIP_DOMAIN_EDITION,
+       init_geoip_db(&ns_g_geoip->domain, GEOIP_DOMAIN_EDITION, 0,
                      method, "Domain");
-       init_geoip_db(&ns_g_geoip->netspeed, GEOIP_NETSPEED_EDITION,
+       init_geoip_db(&ns_g_geoip->netspeed, GEOIP_NETSPEED_EDITION, 0,
                      method, "NetSpeed");
 #endif /* HAVE_GEOIP */
 }
index 753d2b6e68c665a068151cebe368a27a4b43a350..1f55962cbfa18dec85880057d956aed086a747f4 100644 (file)
@@ -655,8 +655,11 @@ dns_geoip_match(const isc_netaddr_t *reqaddr,
                maxlen = 255;
  getcountry:
                db = DB46(reqaddr, geoip, country);
-               INSIST(db != NULL);
+               if (db == NULL)
+                       return (ISC_FALSE);
+
                INSIST(elt->as_string != NULL);
+
                cs = country_lookup(db, subtype, reqaddr->family,
                                    ipnum, ipnum6);
                if (cs != NULL && strncasecmp(elt->as_string, cs, maxlen) == 0)
@@ -675,6 +678,9 @@ dns_geoip_match(const isc_netaddr_t *reqaddr,
                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)
@@ -688,6 +694,9 @@ dns_geoip_match(const isc_netaddr_t *reqaddr,
 
        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)
@@ -699,6 +708,9 @@ dns_geoip_match(const isc_netaddr_t *reqaddr,
 
        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)
@@ -711,7 +723,10 @@ dns_geoip_match(const isc_netaddr_t *reqaddr,
        case dns_geoip_region_countrycode:
        case dns_geoip_region_code:
        case dns_geoip_region_name:
-               INSIST(geoip->region != NULL);
+       case dns_geoip_region:
+               if (geoip->region == NULL)
+                       return (ISC_FALSE);
+
                INSIST(elt->as_string != NULL);
 
                /* Region DB is not supported for IPv6 */
@@ -744,7 +759,9 @@ dns_geoip_match(const isc_netaddr_t *reqaddr,
                db = geoip->domain;
 
  getname:
-               INSIST(db != NULL);
+               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)
index 48110375b36d0a4fc9fca4568f0644987378d81c..74fcbc45982d0099d22ddce2e653df282d8581e1 100644 (file)
@@ -45,7 +45,7 @@ static dns_geoip_databases_t geoip = {
 };
 
 static void
-init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
+init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback,
              GeoIPOptions method, const char *name)
 {
        char *info;
@@ -61,18 +61,22 @@ init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
        }
 
        if (! GeoIP_db_avail(edition)) {
-               fprintf(stderr, "GeoIP %s DB not available\n", name);
-               return;
+               fprintf(stderr, "GeoIP %s (type %d) DB not available\n",
+                       name, edition);
+               goto fail;
        }
 
-       fprintf(stderr, "initializing GeoIP %s DB\n", name);
+       fprintf(stderr, "initializing GeoIP %s (type %d) DB\n",
+               name, edition);
 
        db = GeoIP_open_type(edition, method);
        if (db == NULL) {
-               fprintf(stderr, "failed to initialize GeoIP %s DB; "
-                               "geoip matches using this database will fail\n",
-                               name);
-               return;
+               fprintf(stderr,
+                       "failed to initialize GeoIP %s (type %d) DB%s\n",
+                       name, edition, fallback == 0
+                        ? "; geoip matches using this database will fail"
+                        : "");
+               goto fail;
        }
 
        info = GeoIP_database_info(db);
@@ -80,22 +84,16 @@ init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
                fprintf(stderr, "%s\n", info);
 
        *dbp = db;
-}
+       return;
 
-static GeoIPDBTypes
-choose_rev(GeoIPDBTypes primary, GeoIPDBTypes secondary, const char *name) {
-       if (GeoIP_db_avail(primary))
-               return (primary);
-       if (GeoIP_db_avail(secondary))
-               return (secondary);
-       fprintf(stderr, "GeoIP %s DB: neither revision available\n", name);
-       return (0);
+ fail:
+       if (fallback != 0)
+               init_geoip_db(dbp, fallback, 0, method, name);
 }
 
 static void
 load_geoip(const char *dir) {
        GeoIPOptions method;
-       GeoIPDBTypes edition;
 
 #ifdef _WIN32
        method = GEOIP_STANDARD;
@@ -109,38 +107,31 @@ load_geoip(const char *dir) {
                GeoIP_setup_custom_directory(p);
        }
 
-       init_geoip_db(&geoip.country_v4, GEOIP_COUNTRY_EDITION,
+       init_geoip_db(&geoip.country_v4, GEOIP_COUNTRY_EDITION, 0,
                      method, "Country (IPv4)");
 #ifdef HAVE_GEOIP_V6
-       init_geoip_db(&geoip.country_v6, GEOIP_COUNTRY_EDITION_V6,
+       init_geoip_db(&geoip.country_v6, GEOIP_COUNTRY_EDITION_V6, 0,
                      method, "Country (IPv6)");
 #endif
 
-       edition = choose_rev(GEOIP_CITY_EDITION_REV0,
-                            GEOIP_CITY_EDITION_REV1, "City (IPv4)");
-       if (edition != 0)
-               init_geoip_db(&geoip.city_v4, edition, method, "City (IPv4)");
+       init_geoip_db(&geoip.city_v4, GEOIP_CITY_EDITION_REV1,
+                     GEOIP_CITY_EDITION_REV0, method, "City (IPv4)");
 #if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6)
-       edition = choose_rev(GEOIP_CITY_EDITION_REV0_V6,
-                            GEOIP_CITY_EDITION_REV1_V6, "City (IPv6)");
-       if (edition != 0)
-               init_geoip_db(&geoip.city_v6, edition, method, "City (IPv6)");
+       init_geoip_db(&geoip.city_v6, GEOIP_CITY_EDITION_REV1_V6,
+                     GEOIP_CITY_EDITION_REV0_V6, method, "City (IPv6)");
 #endif
 
-       edition = choose_rev(GEOIP_REGION_EDITION_REV0,
-                            GEOIP_REGION_EDITION_REV1, "Region");
-       if (edition != 0)
-               init_geoip_db(&geoip.region, edition, method, "Region");
-
-       init_geoip_db(&geoip.isp, GEOIP_ISP_EDITION,
+       init_geoip_db(&geoip.region, GEOIP_REGION_EDITION_REV1,
+                     GEOIP_REGION_EDITION_REV0, method, "Region");
+       init_geoip_db(&geoip.isp, GEOIP_ISP_EDITION, 0,
                      method, "ISP");
-       init_geoip_db(&geoip.org, GEOIP_ORG_EDITION,
+       init_geoip_db(&geoip.org, GEOIP_ORG_EDITION, 0,
                      method, "Org");
-       init_geoip_db(&geoip.as, GEOIP_ASNUM_EDITION,
+       init_geoip_db(&geoip.as, GEOIP_ASNUM_EDITION, 0,
                      method, "AS");
-       init_geoip_db(&geoip.domain, GEOIP_DOMAIN_EDITION,
+       init_geoip_db(&geoip.domain, GEOIP_DOMAIN_EDITION, 0,
                      method, "Domain");
-       init_geoip_db(&geoip.netspeed, GEOIP_NETSPEED_EDITION,
+       init_geoip_db(&geoip.netspeed, GEOIP_NETSPEED_EDITION, 0,
                      method, "NetSpeed");
 }