]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add GeoIP2 lookups to unit test
authorEvan Hunt <each@isc.org>
Sun, 23 Jun 2019 06:45:59 +0000 (23:45 -0700)
committerEvan Hunt <each@isc.org>
Tue, 2 Jul 2019 19:29:44 +0000 (12:29 -0700)
(cherry picked from commit 6399a70cb470427dfd5b66a92a2ae6210d3ae19f)
(cherry picked from commit 7468036226e53184d09cbc06977697fa7dee9b6e)

lib/dns/tests/geoip_test.c

index 9a57e9db8701cd108129fc5f222c5a51d3d96711..50922ea59559e534151ce866fc86c6cbf480f0fd 100644 (file)
 #if defined(HAVE_GEOIP2)
 #include <maxminddb.h>
 
-/* TODO GEOIP2 */
-#define TEST_GEOIP_DATA ""
-#elif defined(HAVE_GEOI2)
+/* Use GeoIP2 databases from the 'geoip2' system test */
+#define TEST_GEOIP_DATA "../../../bin/tests/system/geoip2/data"
+#elif defined(HAVE_GEOIP)
 #include <GeoIP.h>
 
-/* We use GeoIP databases from the 'geoip' system test */
+/* Use GeoIP databases from the 'geoip' system test */
 #define TEST_GEOIP_DATA "../../../bin/tests/system/geoip/data"
 #endif
 
@@ -71,12 +71,36 @@ _teardown(void **state) {
 static dns_geoip_databases_t geoip = DNS_GEOIP_DATABASE_INIT;
 #endif /* HAVE_GEOIP || HAVE_GEOIP2 */
 
-#ifdef HAVE_GEOIP
+#if defined(HAVE_GEOIP2)
+static MMDB_s geoip_country, geoip_city, geoip_as, geoip_isp, geoip_domain;
+
+static MMDB_s *
+open_geoip2(const char *dir, const char *dbfile, MMDB_s *mmdb) {
+       char pathbuf[PATH_MAX];
+       int ret;
+
+       snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dir, dbfile);
+       ret = MMDB_open(pathbuf, MMDB_MODE_MMAP, mmdb);
+       if (ret == MMDB_SUCCESS) {
+               return (mmdb);
+       }
+
+       return (NULL);
+}
+
+static void
+load_geoip(const char *dir) {
+       geoip.country = open_geoip2(dir, "GeoIP2-Country.mmdb",
+                                    &geoip_country);
+       geoip.city = open_geoip2(dir, "GeoIP2-City.mmdb", &geoip_city);
+       geoip.as = open_geoip2(dir, "GeoLite2-ASN.mmdb", &geoip_as);
+       geoip.isp = open_geoip2(dir, "GeoIP2-ISP.mmdb", &geoip_isp);
+       geoip.domain = open_geoip2(dir, "GeoIP2-Domain.mmdb", &geoip_domain);
+}
+#elif defined(HAVE_GEOIP)
 /*
- * Helper functions
- * (Mostly copied from bin/named/geoip.c)
+ * Helper functions (mostly copied from bin/named/geoip.c)
  */
-static dns_geoip_databases_t geoip = { NULL };
 
 static void
 init_geoip_db(void **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback,
@@ -156,8 +180,8 @@ load_geoip(const char *dir) {
 }
 
 static bool
-do_lookup_string(const char *addr, uint8_t *scope,
-                dns_geoip_subtype_t subtype, const char *string)
+do_lookup_int(const char *addr, uint8_t *scope,
+             dns_geoip_subtype_t subtype, int id)
 {
        dns_geoip_elem_t elt;
        struct in_addr in4;
@@ -167,21 +191,24 @@ do_lookup_string(const char *addr, uint8_t *scope,
        isc_netaddr_fromin(&na, &in4);
 
        elt.subtype = subtype;
-       strlcpy(elt.as_string, string, sizeof(elt.as_string));
+       elt.as_int = id;
 
        return (dns_geoip_match(&na, scope, &geoip, &elt));
 }
 
+#endif /* HAVE_GEOIP */
+
+#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2)
 static bool
-do_lookup_string_v6(const char *addr, uint8_t *scope,
-                   dns_geoip_subtype_t subtype, const char *string)
+do_lookup_string(const char *addr, uint8_t *scope,
+                dns_geoip_subtype_t subtype, const char *string)
 {
        dns_geoip_elem_t elt;
-       struct in6_addr in6;
+       struct in_addr in4;
        isc_netaddr_t na;
 
-       inet_pton(AF_INET6, addr, &in6);
-       isc_netaddr_fromin6(&na, &in6);
+       inet_pton(AF_INET, addr, &in4);
+       isc_netaddr_fromin(&na, &in4);
 
        elt.subtype = subtype;
        strlcpy(elt.as_string, string, sizeof(elt.as_string));
@@ -190,18 +217,18 @@ do_lookup_string_v6(const char *addr, uint8_t *scope,
 }
 
 static bool
-do_lookup_int(const char *addr, uint8_t *scope,
-             dns_geoip_subtype_t subtype, int id)
+do_lookup_string_v6(const char *addr, uint8_t *scope,
+                   dns_geoip_subtype_t subtype, const char *string)
 {
        dns_geoip_elem_t elt;
-       struct in_addr in4;
+       struct in6_addr in6;
        isc_netaddr_t na;
 
-       inet_pton(AF_INET, addr, &in4);
-       isc_netaddr_fromin(&na, &in4);
+       inet_pton(AF_INET6, addr, &in6);
+       isc_netaddr_fromin6(&na, &in6);
 
        elt.subtype = subtype;
-       elt.as_int = id;
+       strlcpy(elt.as_string, string, sizeof(elt.as_string));
 
        return (dns_geoip_match(&na, scope, &geoip, &elt));
 }
@@ -217,20 +244,21 @@ country(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
+#ifdef HAVE_GEOIP2
+       if (geoip.country == NULL) {
+               skip();
+       }
+#else /* HAVE_GEOIP */
        if (geoip.country_v4 == NULL) {
                skip();
        }
+#endif /* HAVE_GEOIP */
 
        match = do_lookup_string("10.53.0.1", &scope,
                                 dns_geoip_country_code, "AU");
        assert_true(match);
        assert_int_equal(scope, 32);
 
-       match = do_lookup_string("10.53.0.1", &scope,
-                                dns_geoip_country_code3, "AUS");
-       assert_true(match);
-       assert_int_equal(scope, 32);
-
        match = do_lookup_string("10.53.0.1", &scope,
                                 dns_geoip_country_name, "Australia");
        assert_true(match);
@@ -258,20 +286,21 @@ country_v6(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
+#ifdef HAVE_GEOIP2
+       if (geoip.country == NULL) {
+               skip();
+       }
+#else /* HAVE_GEOIP */
        if (geoip.country_v6 == NULL) {
                skip();
        }
+#endif /* HAVE_GEOIP */
 
        match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", &scope,
                                    dns_geoip_country_code, "AU");
        assert_true(match);
        assert_int_equal(scope, 128);
 
-       match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", &scope,
-                                   dns_geoip_country_code3, "AUS");
-       assert_true(match);
-       assert_int_equal(scope, 128);
-
        match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", &scope,
                                    dns_geoip_country_name, "Australia");
        assert_true(match);
@@ -288,9 +317,15 @@ city(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
+#ifdef HAVE_GEOIP2
+       if (geoip.city == NULL) {
+               skip();
+       }
+#else /* HAVE_GEOIP */
        if (geoip.city_v4 == NULL) {
                skip();
        }
+#endif /* HAVE_GEOIP */
 
        match = do_lookup_string("10.53.0.1", NULL,
                                 dns_geoip_city_continentcode, "NA");
@@ -300,10 +335,6 @@ city(void **state) {
                                 dns_geoip_city_countrycode, "US");
        assert_true(match);
 
-       match = do_lookup_string("10.53.0.1", NULL,
-                                dns_geoip_city_countrycode3, "USA");
-       assert_true(match);
-
        match = do_lookup_string("10.53.0.1", NULL,
                                 dns_geoip_city_countryname, "United States");
        assert_true(match);
@@ -324,11 +355,13 @@ city(void **state) {
                                 dns_geoip_city_postalcode, "94063");
        assert_true(match);
 
+#ifdef HAVE_GEOIP
        match = do_lookup_int("10.53.0.1", NULL, dns_geoip_city_areacode, 650);
        assert_true(match);
 
        match = do_lookup_int("10.53.0.1", NULL, dns_geoip_city_metrocode, 807);
        assert_true(match);
+#endif
 }
 
 /* GeoIP city (ipv6) matching */
@@ -341,9 +374,15 @@ city_v6(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
+#ifdef HAVE_GEOIP2
+       if (geoip.city == NULL) {
+               skip();
+       }
+#else /* HAVE_GEOIP */
        if (geoip.city_v6 == NULL) {
                skip();
        }
+#endif /* HAVE_GEOIP */
 
        match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
                                    dns_geoip_city_continentcode, "NA");
@@ -353,10 +392,6 @@ city_v6(void **state) {
                                    dns_geoip_city_countrycode, "US");
        assert_true(match);
 
-       match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
-                                   dns_geoip_city_countrycode3, "USA");
-       assert_true(match);
-
        match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
                                    dns_geoip_city_countryname,
                                    "United States");
@@ -379,10 +414,9 @@ city_v6(void **state) {
        assert_true(match);
 }
 
-
-/* GeoIP region matching */
+/* GeoIP asnum matching */
 static void
-region(void **state) {
+asnum(void **state) {
        bool match;
 
        UNUSED(state);
@@ -390,31 +424,19 @@ region(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
-       if (geoip.region == NULL) {
+       if (geoip.as == NULL) {
                skip();
        }
 
-       match = do_lookup_string("10.53.0.1", NULL,
-                                dns_geoip_region_code, "CA");
-       assert_true(match);
 
-       match = do_lookup_string("10.53.0.1", NULL,
-                                dns_geoip_region_name, "California");
-       assert_true(match);
-
-       match = do_lookup_string("10.53.0.1", NULL,
-                                dns_geoip_region_countrycode, "US");
+       match = do_lookup_string("10.53.0.3", NULL,
+                                dns_geoip_as_asnum, "AS100003");
        assert_true(match);
 }
 
-/*
- * GeoIP best-database matching
- * (With no specified databse and a city database available, answers
- * should come from city database.  With city database unavailable, region
- * database.  Region database unavailable, country database.)
- */
+/* GeoIP isp matching */
 static void
-best(void **state) {
+isp(void **state) {
        bool match;
 
        UNUSED(state);
@@ -422,69 +444,18 @@ best(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
-       if (geoip.region == NULL) {
+       if (geoip.isp == NULL) {
                skip();
        }
 
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countrycode, "US");
-       assert_true(match);
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countrycode3, "USA");
-       assert_true(match);
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countryname, "United States");
-       assert_true(match);
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_regionname, "Virginia");
-       assert_true(match);
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_region, "VA");
-       assert_true(match);
-
-       GeoIP_delete(geoip.city_v4);
-       geoip.city_v4 = NULL;
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countrycode, "AU");
-       assert_true(match);
-
-       /*
-        * Note, region doesn't support code3 or countryname, so
-        * the next two would be answered from the country database instead
-        */
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countrycode3, "CAN");
-       assert_true(match);
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countryname, "Canada");
-       assert_true(match);
-
-       GeoIP_delete(geoip.region);
-       geoip.region = NULL;
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countrycode, "CA");
-       assert_true(match);
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countrycode3, "CAN");
-       assert_true(match);
-
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_countryname, "Canada");
+       match = do_lookup_string("10.53.0.1", NULL, dns_geoip_isp_name,
+                                "One Systems, Inc.");
        assert_true(match);
 }
 
-
-/* GeoIP asnum matching */
+/* GeoIP org matching */
 static void
-asnum(void **state) {
+org(void **state) {
        bool match;
 
        UNUSED(state);
@@ -492,19 +463,24 @@ asnum(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
+#ifdef HAVE_GEOIP2
        if (geoip.as == NULL) {
                skip();
        }
+#else /* HAVE_GEOIP */
+       if (geoip.org == NULL) {
+               skip();
+       }
+#endif /* HAVE_GEOIP */
 
-
-       match = do_lookup_string("10.53.0.3", NULL, dns_geoip_as_asnum,
-                                "AS100003 Three Network Labs");
+       match = do_lookup_string("10.53.0.2", NULL, dns_geoip_org_name,
+                                "Two Technology Ltd.");
        assert_true(match);
 }
 
-/* GeoIP isp matching */
+/* GeoIP domain matching */
 static void
-isp(void **state) {
+domain(void **state) {
        bool match;
 
        UNUSED(state);
@@ -512,18 +488,20 @@ isp(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
-       if (geoip.isp == NULL) {
+       if (geoip.domain == NULL) {
                skip();
        }
 
-       match = do_lookup_string("10.53.0.1", NULL, dns_geoip_isp_name,
-                                "One Systems, Inc.");
+       match = do_lookup_string("10.53.0.5", NULL,
+                                dns_geoip_domain_name, "five.es");
        assert_true(match);
 }
+#endif /* HAVE_GEOIP || HAVE_GEOIP2 */
 
-/* GeoIP org matching */
+#ifdef HAVE_GEOIP
+/* GeoIP region matching */
 static void
-org(void **state) {
+region(void **state) {
        bool match;
 
        UNUSED(state);
@@ -531,18 +509,26 @@ org(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
-       if (geoip.org == NULL) {
+       if (geoip.region == NULL) {
                skip();
        }
 
-       match = do_lookup_string("10.53.0.2", NULL, dns_geoip_org_name,
-                                "Two Technology Ltd.");
+       match = do_lookup_string("10.53.0.1", NULL,
+                                dns_geoip_region_code, "CA");
+       assert_true(match);
+
+       match = do_lookup_string("10.53.0.1", NULL,
+                                dns_geoip_region_name, "California");
+       assert_true(match);
+
+       match = do_lookup_string("10.53.0.1", NULL,
+                                dns_geoip_region_countrycode, "US");
        assert_true(match);
 }
 
-/* GeoIP domain matching */
+/* GeoIP netspeed matching */
 static void
-domain(void **state) {
+netspeed(void **state) {
        bool match;
 
        UNUSED(state);
@@ -550,18 +536,31 @@ domain(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
-       if (geoip.domain == NULL) {
+       if (geoip.netspeed == NULL) {
                skip();
        }
 
-       match = do_lookup_string("10.53.0.4", NULL,
-                                dns_geoip_domain_name, "four.com");
+       match = do_lookup_int("10.53.0.1", NULL, dns_geoip_netspeed_id, 0);
+       assert_true(match);
+
+       match = do_lookup_int("10.53.0.2", NULL, dns_geoip_netspeed_id, 1);
+       assert_true(match);
+
+       match = do_lookup_int("10.53.0.3", NULL, dns_geoip_netspeed_id, 2);
+       assert_true(match);
+
+       match = do_lookup_int("10.53.0.4", NULL, dns_geoip_netspeed_id, 3);
        assert_true(match);
 }
 
-/* GeoIP netspeed matching */
+/*
+ * GeoIP best-database matching
+ * (With no specified databse and a city database available, answers
+ * should come from city database.  With city database unavailable, region
+ * database.  Region database unavailable, country database.)
+ */
 static void
-netspeed(void **state) {
+best(void **state) {
        bool match;
 
        UNUSED(state);
@@ -569,47 +568,88 @@ netspeed(void **state) {
        /* Use databases from the geoip system test */
        load_geoip(TEST_GEOIP_DATA);
 
-       if (geoip.netspeed == NULL) {
+       if (geoip.region == NULL) {
                skip();
        }
 
-       match = do_lookup_int("10.53.0.1", NULL, dns_geoip_netspeed_id, 0);
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countrycode, "US");
        assert_true(match);
 
-       match = do_lookup_int("10.53.0.2", NULL, dns_geoip_netspeed_id, 1);
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countrycode3, "USA");
        assert_true(match);
 
-       match = do_lookup_int("10.53.0.3", NULL, dns_geoip_netspeed_id, 2);
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countryname, "United States");
        assert_true(match);
 
-       match = do_lookup_int("10.53.0.4", NULL, dns_geoip_netspeed_id, 3);
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_regionname, "Virginia");
+       assert_true(match);
+
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_region, "VA");
+       assert_true(match);
+
+       GeoIP_delete(geoip.city_v4);
+       geoip.city_v4 = NULL;
+
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countrycode, "AU");
+       assert_true(match);
+
+       /*
+        * Note, region doesn't support code3 or countryname, so
+        * the next two would be answered from the country database instead
+        */
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countrycode3, "CAN");
+       assert_true(match);
+
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countryname, "Canada");
+       assert_true(match);
+
+       GeoIP_delete(geoip.region);
+       geoip.region = NULL;
+
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countrycode, "CA");
+       assert_true(match);
+
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countrycode3, "CAN");
+       assert_true(match);
+
+       match = do_lookup_string("10.53.0.4", NULL,
+                                dns_geoip_countryname, "Canada");
        assert_true(match);
 }
 #endif /* HAVE_GEOIP */
 
 int
 main(void) {
-#if defined(HAVE_GEOIP2)
-       /* TODO GEOIP2 */
-       print_message("1..0 # Skip geoip2 tests not complete\n");
-#elif defined(HAVE_GEOIP)
+#if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2)
        const struct CMUnitTest tests[] = {
                cmocka_unit_test_setup_teardown(country, _setup, _teardown),
                cmocka_unit_test_setup_teardown(country_v6, _setup, _teardown),
                cmocka_unit_test_setup_teardown(city, _setup, _teardown),
                cmocka_unit_test_setup_teardown(city_v6, _setup, _teardown),
-               cmocka_unit_test_setup_teardown(region, _setup, _teardown),
-               cmocka_unit_test_setup_teardown(best, _setup, _teardown),
                cmocka_unit_test_setup_teardown(asnum, _setup, _teardown),
                cmocka_unit_test_setup_teardown(isp, _setup, _teardown),
                cmocka_unit_test_setup_teardown(org, _setup, _teardown),
                cmocka_unit_test_setup_teardown(domain, _setup, _teardown),
+#ifdef HAVE_GEOIP
+               cmocka_unit_test_setup_teardown(region, _setup, _teardown),
                cmocka_unit_test_setup_teardown(netspeed, _setup, _teardown),
+               cmocka_unit_test_setup_teardown(best, _setup, _teardown),
+#endif /* HAVE_GEOIP */
        };
 
        return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final));
 #else
-       print_message("1..0 # Skip geoip not enabled\n");
+       print_message("1..0 # Skip GeoIP not enabled\n");
 #endif
 }