On Mon, 07 Jun 2010, Peter Palfrader wrote:

> just a quick heads up.
> 
> As it is the patch does not work correctly.
> 
> At the very least it requires s/geoip/geoip6/ in one line, but even then
> it does not yet work for me for v6.
> 
> To be continued,

Try this one instead.

- it uses get_code instead of get_name for ipv6, to get 'AT' instead of
  'Austria' just like it expects.  (GeoIP_country_name_by_ipnum_v6 vs.
  GeoIP_country_code_by_ipnum_v6).
- it does not segfault when the databases are not available, and
  properly logs if it needs databases but they aren't installed.
- I also moved the database pointers to function static variables
  instead of global statics.  I did that during debugging, but I think
  it should be fine.

patch is against the package in sid, not against bind in sid including
the patch previously submitted to this bug.

Cheers,
-- 
                           |  .''`.  ** Debian GNU/Linux **
      Peter Palfrader      | : :' :      The  universal
 http://www.palfrader.org/ | `. `'      Operating System
                           |   `-    http://www.debian.org/
diff -u bind9-9.7.0.dfsg.P1/lib/dns/acl.c bind9-9.7.0.dfsg.P1/lib/dns/acl.c
--- bind9-9.7.0.dfsg.P1/lib/dns/acl.c
+++ bind9-9.7.0.dfsg.P1/lib/dns/acl.c
@@ -29,14 +29,11 @@
 #include <isc/once.h>
 #include <isc/string.h>
 #include <isc/util.h>
+#include <dns/log.h>
 
 #include <dns/acl.h>
 #include <dns/iptable.h>
 
-#ifdef SUPPORT_GEOIP
-static GeoIP *geoip = NULL;
-#endif
-
 /*
  * Create a new ACL, including an IP table and an array with room
  * for 'n' ACL elements.  The elements are uninitialized and the
@@ -391,30 +388,65 @@
 	int indirectmatch;
 	isc_result_t result;
 
+	#ifdef SUPPORT_GEOIP
+	static GeoIP *geoip = NULL;
+	static isc_boolean_t geoip_init_tried = ISC_FALSE;
+	#ifdef GEOIP_V6
+	static GeoIP *geoip6 = NULL;
+	static isc_boolean_t geoip6_init_tried = ISC_FALSE;
+	#endif
+	#endif
+
 	switch (e->type) {
 #ifdef SUPPORT_GEOIP
 	case dns_aclelementtype_ipcountry:
 		/* Country match */
-		if (NULL == geoip) {
-			geoip = GeoIP_new(GEOIP_MEMORY_CACHE);
+		if (NULL == geoip && !geoip_init_tried) {
+			geoip_init_tried = ISC_TRUE;
+			if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) {
+				geoip = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_MEMORY_CACHE);
+				if (NULL == geoip)
+					isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+						      DNS_LOGMODULE_ACL, ISC_LOG_NOTICE,
+						      "Failed to open geoip database for ipv4");
+			} else {
+				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+					      DNS_LOGMODULE_ACL, ISC_LOG_NOTICE,
+					      "geoip database for ipv4 is not available");
+			}
 		}
-		if (NULL != geoip) {
-			const char *value = NULL;
+#ifdef GEOIP_V6
+		if (NULL == geoip6 && !geoip6_init_tried) {
+			geoip6_init_tried = ISC_TRUE;
+			if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION_V6)) {
+				geoip6 = GeoIP_open_type(GEOIP_COUNTRY_EDITION_V6, GEOIP_MEMORY_CACHE);
+				if (NULL == geoip6)
+					isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+						      DNS_LOGMODULE_ACL, ISC_LOG_NOTICE,
+						      "Failed to open geoip database for ipv6");
+			} else {
+				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+					      DNS_LOGMODULE_ACL, ISC_LOG_NOTICE,
+					      "geoip database for ipv6 is not available");
+			}
+		}
+#endif
+
+                const char *value = NULL;
 
-			if (reqaddr->family == AF_INET) {
-				value = GeoIP_country_code_by_addr(geoip,inet_ntoa(reqaddr->type.in));
+		if (reqaddr->family == AF_INET && geoip) {
+			value = GeoIP_country_code_by_addr(geoip,inet_ntoa(reqaddr->type.in));
 #ifdef GEOIP_V6
-			} else if (reqaddr->family == AF_INET6) {
-				value = GeoIP_country_name_by_ipnum_v6(geoip, (geoipv6_t)reqaddr->type.in6);
+		} else if (reqaddr->family == AF_INET6 && geoip6) {
+			value = GeoIP_country_code_by_ipnum_v6(geoip6, (geoipv6_t)reqaddr->type.in6);
 #endif
-			}
+		}
                 
-			if ((NULL != value) && (2 == strlen(value))) {
-				if ((e->country[0] == value[0]) && (e->country[1] == value[1])) {
-					return (ISC_TRUE);
-				}
+		if ((NULL != value) && (2 == strlen(value))) {
+			if ((e->country[0] == value[0]) && (e->country[1] == value[1])) {
+				return (ISC_TRUE);
 			}
-                }
+		}
 		return (ISC_FALSE);
 #endif
 

Reply via email to