]> git.pld-linux.org Git - packages/bind.git/blame - bind-geoip.patch
geoip patch requires --with-geoip=yes configure
[packages/bind.git] / bind-geoip.patch
CommitLineData
c259b5d4
ER
1--- version.orig 2012-09-26 17:35:19.000000000 -0700
2+++ version 2012-10-09 17:38:10.000000000 -0700
3@@ -7,4 +7,4 @@
4 MINORVER=9
5 PATCHVER=2
6 RELEASETYPE=
7-RELEASEVER=
8+RELEASEVER=-geoip-1.3
9--- bin/named/geoip.c.orig 2012-10-09 17:38:10.000000000 -0700
10+++ bin/named/geoip.c 2012-10-09 17:38:10.000000000 -0700
11@@ -0,0 +1,254 @@
12+#ifdef HAVE_GEOIP
13+
14+#include <named/log.h>
15+#include <isc/geoip.h>
16+
17+void
18+geoip_init()
19+{
20+#ifdef _WIN32
21+ GeoIPOptions geoip_method = GEOIP_STANDARD ;
22+#else
23+ GeoIPOptions geoip_method = GEOIP_MMAP_CACHE ;
24+#endif
25+ char *geoip_db_info ;
26+
27+ /* COUNTRY DB */
28+
29+ if ( ns_g_geoip_countryDB )
30+ GeoIP_delete( ns_g_geoip_countryDB );
31+
32+ if ( GeoIP_db_avail( GEOIP_COUNTRY_EDITION ) ) {
33+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
34+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
35+ "Initializing GeoIP Country DB");
36+ if ( !( ns_g_geoip_countryDB = GeoIP_open_type( GEOIP_COUNTRY_EDITION, geoip_method ) ) )
37+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
38+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
39+ "Failed to initialize GeoIP Country DB! "
40+ "geoip_countryDB_ matches will silently fail.");
41+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_countryDB) ))
42+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
43+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
44+ geoip_db_info);
45+ } else
46+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
47+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
48+ "GeoIP Country DB not available");
49+
50+ /* CITY DB */
51+
52+ if ( ns_g_geoip_cityDB )
53+ GeoIP_delete( ns_g_geoip_cityDB );
54+
55+ if ( GeoIP_db_avail( GEOIP_CITY_EDITION_REV1 ) ) {
56+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
57+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
58+ "Initializing GeoIP City DB Revision 1");
59+ if ( !( ns_g_geoip_cityDB = GeoIP_open_type( GEOIP_CITY_EDITION_REV1, geoip_method ) ) )
60+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
61+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
62+ "Failed to initialize GeoIP City DB Revision 1! "
63+ "geoip_cityDB_ matches will silently fail.");
64+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_cityDB) ))
65+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
66+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
67+ geoip_db_info);
68+ } else if ( GeoIP_db_avail( GEOIP_CITY_EDITION_REV0 ) ) {
69+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
70+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
71+ "Initializing GeoIP City DB Revision 0");
72+ if ( !( ns_g_geoip_cityDB = GeoIP_open_type( GEOIP_CITY_EDITION_REV0, geoip_method ) ) )
73+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
74+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
75+ "Failed to initialize GeoIP City DB Revision 0! "
76+ "geoip_cityDB_ matches will silently fail.");
77+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_cityDB) ))
78+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
79+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
80+ geoip_db_info);
81+ } else
82+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
83+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
84+ "GeoIP City DB Revision 0 or 1 not available");
85+
86+ /* REGION DB */
87+
88+ if ( ns_g_geoip_regionDB )
89+ GeoIP_delete( ns_g_geoip_regionDB );
90+
91+ if ( GeoIP_db_avail( GEOIP_REGION_EDITION_REV1 ) ) {
92+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
93+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
94+ "Initializing GeoIP Region DB Revision 1");
95+ if ( !( ns_g_geoip_regionDB = GeoIP_open_type( GEOIP_REGION_EDITION_REV1, geoip_method ) ) )
96+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
97+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
98+ "Failed to initialize GeoIP Region DB Revision 1! "
99+ "geoip_regionDB_ matches will silently fail.");
100+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_regionDB) ))
101+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
102+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
103+ geoip_db_info);
104+ } else if ( GeoIP_db_avail( GEOIP_REGION_EDITION_REV0 ) ) {
105+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
106+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
107+ "Initializing GeoIP Region DB Revision 0");
108+ if ( !( ns_g_geoip_regionDB = GeoIP_open_type( GEOIP_REGION_EDITION_REV0, geoip_method ) ) )
109+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
110+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
111+ "Failed to initialize GeoIP Region DB Revision 0! "
112+ "geoip_regionDB_ matches will silently fail.");
113+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_regionDB) ))
114+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
115+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
116+ geoip_db_info);
117+ } else
118+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
119+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
120+ "GeoIP Region DB Revision 0 or 1 not available");
121+
122+ /* ISP DB */
123+
124+ if ( ns_g_geoip_ispDB )
125+ GeoIP_delete( ns_g_geoip_ispDB );
126+
127+ if ( GeoIP_db_avail( GEOIP_ISP_EDITION ) ) {
128+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
129+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
130+ "Initializing GeoIP ISP DB");
131+ if ( !( ns_g_geoip_ispDB = GeoIP_open_type( GEOIP_ISP_EDITION, geoip_method ) ) )
132+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
133+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
134+ "Failed to initialize GeoIP ISP DB! "
135+ "geoip_ispDB_ matches will silently fail.");
136+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_ispDB) ))
137+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
138+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
139+ geoip_db_info);
140+ } else
141+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
142+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
143+ "GeoIP ISP DB not available");
144+
145+ /* ORGANIZATION DB */
146+
147+ if ( ns_g_geoip_orgDB )
148+ GeoIP_delete( ns_g_geoip_orgDB );
149+
150+ if ( GeoIP_db_avail( GEOIP_ORG_EDITION ) ) {
151+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
152+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
153+ "Initializing GeoIP Organization DB");
154+ if ( !( ns_g_geoip_orgDB = GeoIP_open_type( GEOIP_ORG_EDITION, geoip_method ) ) )
155+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
156+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
157+ "Failed to initialize GeoIP Organization DB! "
158+ "geoip_orgDB_ matches will silently fail.");
159+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_orgDB) ))
160+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
161+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
162+ geoip_db_info);
163+ } else
164+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
165+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
166+ "GeoIP Organization DB not available");
167+
168+ /* AS DB */
169+
170+ if ( ns_g_geoip_asDB )
171+ GeoIP_delete( ns_g_geoip_asDB );
172+
173+ if ( GeoIP_db_avail( GEOIP_ASNUM_EDITION ) ) {
174+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
175+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
176+ "Initializing GeoIP AS DB");
177+ if ( !( ns_g_geoip_asDB = GeoIP_open_type( GEOIP_ASNUM_EDITION, geoip_method ) ) )
178+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
179+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
180+ "Failed to initialize GeoIP AS DB! "
181+ "geoip_asDB_ matches will silently fail.");
182+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_asDB) ))
183+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
184+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
185+ geoip_db_info);
186+ } else
187+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
188+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
189+ "GeoIP AS DB not available");
190+
191+ /* NETSPEED DB */
192+
193+ if ( ns_g_geoip_netspeedDB )
194+ GeoIP_delete( ns_g_geoip_netspeedDB );
195+
196+ if ( GeoIP_db_avail( GEOIP_NETSPEED_EDITION ) ) {
197+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
198+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
199+ "Initializing GeoIP NetSpeed DB");
200+ if ( !( ns_g_geoip_netspeedDB = GeoIP_open_type( GEOIP_NETSPEED_EDITION, geoip_method ) ) )
201+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
202+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
203+ "Failed to initialize GeoIP NetSpeed DB! "
204+ "geoip_netspeedDB_ matches will silently fail.");
205+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_netspeedDB) ))
206+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
207+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
208+ geoip_db_info);
209+ } else
210+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
211+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
212+ "GeoIP NetSpeed DB not available");
213+
214+ /* DOMAIN DB */
215+
216+ if ( ns_g_geoip_domainDB )
217+ GeoIP_delete( ns_g_geoip_domainDB );
218+
219+ if ( GeoIP_db_avail( GEOIP_DOMAIN_EDITION ) ) {
220+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
221+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
222+ "Initializing GeoIP Domain DB");
223+ if ( !( ns_g_geoip_domainDB = GeoIP_open_type( GEOIP_DOMAIN_EDITION, geoip_method ) ) )
224+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
225+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
226+ "Failed to initialize GeoIP Domain DB! "
227+ "geoip_domainDB_ matches will silently fail.");
228+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_domainDB) ))
229+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
230+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
231+ geoip_db_info);
232+ } else
233+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
234+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
235+ "GeoIP Domain DB not available");
236+
237+#ifdef HAVE_GEOIP_V6
238+
239+ /* COUNTRY DB IPv6 */
240+
241+ if ( ns_g_geoip_countryDB_v6 )
242+ GeoIP_delete( ns_g_geoip_countryDB_v6 );
243+
244+ if ( GeoIP_db_avail( GEOIP_COUNTRY_EDITION_V6 ) ) {
245+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
246+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
247+ "Initializing GeoIP Country DB IPv6");
248+ if ( !( ns_g_geoip_countryDB_v6 = GeoIP_open_type( GEOIP_COUNTRY_EDITION_V6, geoip_method ) ) )
249+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
250+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
251+ "Failed to initialize GeoIP Country DB IPv6! "
252+ "geoip_countryDB_ matches will silently fail on IPv6 addresses.");
253+ if (( geoip_db_info = GeoIP_database_info(ns_g_geoip_countryDB_v6) ))
254+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
255+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
256+ geoip_db_info);
257+ } else
258+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
259+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
260+ "GeoIP Country DB IPv6 not available");
261+
262+#endif /* HAVE_GEOIP_V6 */
263+} /* geoip_init() */
264+
265+#endif /* HAVE_GEOIP */
266--- bin/named/Makefile.in.orig 2012-09-26 17:35:19.000000000 -0700
267+++ bin/named/Makefile.in 2012-10-09 17:38:10.000000000 -0700
268@@ -87,6 +87,7 @@
269 zoneconf.@O@ \
270 lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \
271 lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ \
272+ geoip.@O@ \
273 ${DLZDRIVER_OBJS} ${DBDRIVER_OBJS}
274
275 UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@
276@@ -101,6 +102,7 @@
277 zoneconf.c \
278 lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \
279 lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c \
280+ geoip.c \
281 ${DLZDRIVER_SRCS} ${DBDRIVER_SRCS}
282
283 MANPAGES = named.8 lwresd.8 named.conf.5
50390d1a
ER
284--- bin/named/server.c 2013-09-05 08:09:08.000000000 +0300
285+++ bin/named/server.c 2013-10-25 15:34:56.010749111 +0300
c259b5d4
ER
286@@ -52,6 +52,9 @@
287 #include <isc/timer.h>
288 #include <isc/util.h>
289 #include <isc/xml.h>
290+#ifdef HAVE_GEOIP
291+#include <isc/geoip.h>
292+#endif /* HAVE_GEOIP */
293
294 #include <isccfg/namedconf.h>
295
50390d1a
ER
296@@ -4859,6 +4862,21 @@
297 return (n);
c259b5d4
ER
298 }
299
300+#ifdef HAVE_GEOIP
301+static isc_result_t
302+load_geoip(ns_server_t *server) {
303+ isc_result_t result;
304+
305+ result = isc_task_beginexclusive(server->task);
306+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
307+
308+ geoip_init();
309+
310+ isc_task_endexclusive(server->task);
311+ return (result);
312+}
313+#endif /* HAVE_GEOIP */
314+
315 static isc_result_t
50390d1a
ER
316 load_configuration(const char *filename, ns_server_t *server,
317 isc_boolean_t first_time)
318@@ -5983,6 +6001,11 @@
c259b5d4
ER
319 isc_hash_init();
320
50390d1a 321 CHECKFATAL(load_zones(server, ISC_TRUE), "loading zones");
c259b5d4
ER
322+
323+#ifdef HAVE_GEOIP
324+ /* Load GeoIP DBs */
325+ CHECKFATAL(load_geoip(server), "loading GeoIP");
326+#endif /* HAVE_GEOIP */
327 }
328
329 void
50390d1a 330@@ -6430,6 +6453,20 @@
c259b5d4
ER
331 "reloading zones failed: %s",
332 isc_result_totext(result));
333
334+#ifdef HAVE_GEOIP
335+ /* Reload GeoIP DBs */
336+ result = load_geoip(server);
337+ if (result == ISC_R_SUCCESS)
338+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
339+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
340+ "reloading GeoIP succeeded");
341+ else
342+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
343+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
344+ "reloading GeoIP failed: %s",
345+ isc_result_totext(result));
346+#endif /* HAVE_GEOIP */
347+
348 cleanup:
349 return (result);
350 }
351--- configure.orig 2012-09-26 17:35:19.000000000 -0700
352+++ configure 2012-10-09 17:38:10.000000000 -0700
353@@ -533,6 +533,10 @@
354 ## M4sh Initialization. ##
355 ## -------------------- ##
356
357+touch configure.in
358+echo "ERROR: Please run autoconf to enable GeoIP support"
359+exit 1
360+
361 # Be more Bourne compatible
362 DUALCASE=1; export DUALCASE # for MKS sh
363 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
364--- configure.in.orig 2012-09-26 17:35:19.000000000 -0700
365+++ configure.in 2012-10-09 17:38:10.000000000 -0700
366@@ -938,6 +938,78 @@
367 esac
368 AC_SUBST(PKCS11_PROVIDER)
369
370+AC_ARG_WITH(geoip,
371+[ --with-geoip=PATH Specify path for GeoIP support],
372+ use_geoip="$withval", use_geoip="no")
373+
374+case "$use_geoip" in
375+ no)
376+ AC_MSG_CHECKING([for GeoIP support])
377+ AC_MSG_RESULT([disabled])
378+ ;;
379+ *)
380+ if test "$use_geoip" != "yes"
381+ then
382+ if test -d "$use_geoip" -o -L "$use_geoip"
383+ then
384+ CFLAGS="$CFLAGS -I$use_geoip/include"
385+ CPPFLAGS="$CPPFLAGS -I$use_geoip/include"
386+ LIBS="$LIBS -L$use_geoip/lib -Wl,-rpath=$use_geoip/lib"
387+ else
388+ AC_MSG_ERROR([GeoIP path $use_geoip does not exist])
389+ fi
390+ fi
391+ AC_CHECK_HEADER(GeoIP.h, [],
392+ [AC_MSG_ERROR([GeoIP header file not found])]
393+ )
394+ AC_SEARCH_LIBS(GeoIP_open, GeoIP, [],
395+ [AC_MSG_ERROR([GeoIP library not found])]
396+ )
397+ AC_SEARCH_LIBS(fabsf, m, [],
398+ [AC_MSG_ERROR([Math library not found])]
399+ )
400+ CFLAGS="${CFLAGS} -DHAVE_GEOIP"
401+ AC_MSG_CHECKING([for GeoIP support])
402+ AC_MSG_RESULT([yes])
403+
404+ AC_MSG_CHECKING([for GeoIP IPv6 support])
405+ AC_COMPILE_IFELSE(
406+ AC_LANG_PROGRAM([[
407+ #include <GeoIP.h>
408+ #include <netinet/in.h>
409+ ]], [[
410+ struct in6_addr in6;
411+
412+ GeoIP_country_name_by_ipnum_v6(NULL, in6);
413+ ]]),
414+ [
415+ AC_MSG_RESULT([yes])
416+ CFLAGS="${CFLAGS} -DHAVE_GEOIP_V6"
417+ CPPFLAGS="${CPPFLAGS} -DHAVE_GEOIP_V6"
418+ ],
419+ [AC_MSG_RESULT([no])]
420+ )
421+ ;;
422+esac
423+
424+AC_MSG_CHECKING(for GeoIP debugging)
425+AC_ARG_WITH(geoip-debug,
426+[ --with-geoip-debug Enable GeoIP debugging messages],
427+ use_geoip_debug="$withval", use_geoip_debug="no")
428+
429+case "$use_geoip_debug" in
430+ no)
431+ AC_MSG_RESULT([disabled])
432+ ;;
433+ yes)
434+ AC_MSG_RESULT([yes])
435+ CFLAGS="${CFLAGS} -DDEBUG_GEOIP"
436+ ;;
437+ *)
438+ AC_MSG_ERROR([--with-geoip-debug requires yes or no])
439+ ;;
440+esac
441+
442 AC_MSG_CHECKING(for GSSAPI library)
443 AC_ARG_WITH(gssapi,
444 [ --with-gssapi=PATH Specify path for system-supplied GSSAPI [[default=yes]]],
445--- lib/isccfg/aclconf.c.orig 2012-09-26 17:35:19.000000000 -0700
446+++ lib/isccfg/aclconf.c 2012-10-09 17:38:10.000000000 -0700
447@@ -31,6 +31,11 @@
448 #include <dns/fixedname.h>
449 #include <dns/log.h>
450
451+#ifdef HAVE_GEOIP
452+#include <stdlib.h>
453+#include <math.h>
454+#endif /* HAVE_GEOIP */
455+
456 #define LOOP_MAGIC ISC_MAGIC('L','O','O','P')
457
458 isc_result_t
459@@ -249,6 +254,12 @@
460 if (strcasecmp(name, "localhost") == 0 ||
461 strcasecmp(name, "localnets") == 0) {
462 n++;
463+#ifdef HAVE_GEOIP
464+ /* country_ for backwards compatibility with geodns */
465+ } else if (strncasecmp(name, "country_", 8) == 0 ||
466+ strncasecmp(name, "geoip_", 6) == 0) {
467+ n++;
468+#endif /* HAVE_GEOIP */
469 } else if (strcasecmp(name, "any") != 0 &&
470 strcasecmp(name, "none") != 0) {
471 result = get_acl_def(cctx, name, &cacl);
472@@ -441,6 +452,336 @@
473 de->negative = !neg;
474 } else
475 continue;
476+#ifdef HAVE_GEOIP
477+ } else if (strncasecmp(name, "country_", 8) == 0) {
478+ if (strlen(name+8) == 2) {
479+ de->geoip_countryDB.subtype = geoip_countryDB_country_code ;
480+ strncpy( de->geoip_countryDB.country_code, name+8, 2 );
481+ } else {
482+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
483+ "unrecognized GeoIP Country DB ACL: %s", name );
484+ result = ISC_R_FAILURE;
485+ goto cleanup;
486+ }
487+ de->type = dns_aclelementtype_geoip_countryDB;
488+ de->negative = neg;
489+ } /* country_XX (backwards compatibility) */
490+ else if (strncasecmp(name, "geoip_countryDB_", 16) == 0) {
491+ const char *noff = name+16 ;
492+
493+ if ((strncasecmp(noff, "country_", 8) == 0) && (strlen(noff+8) == 2)) {
494+ de->geoip_countryDB.subtype = geoip_countryDB_country_code ;
495+ strncpy( de->geoip_countryDB.country_code, noff+8, 2 );
496+ } else if ((strncasecmp(noff, "country3_", 9) == 0) && (strlen(noff+9) == 3)) {
497+ de->geoip_countryDB.subtype = geoip_countryDB_country_code3 ;
498+ strncpy( de->geoip_countryDB.country_code3, noff+9, 3 );
499+ } else if (strncasecmp(noff, "country_name_", 13) == 0) {
500+ unsigned int c ;
501+
502+ de->geoip_countryDB.subtype = geoip_countryDB_country_name ;
503+ strncpy( de->geoip_countryDB.country_name, noff+13, 255 );
504+ de->geoip_countryDB.country_name[255] = '\0' ;
505+ for ( c=0 ; c < strlen(de->geoip_countryDB.country_name) ; c++ )
506+ if ( de->geoip_countryDB.country_name[c] == '_' )
507+ de->geoip_countryDB.country_name[c] = ' ';
508+ else if ( de->geoip_countryDB.country_name[c] == '|' )
509+ de->geoip_countryDB.country_name[c] = '/';
510+ } else {
511+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
512+ "unrecognized GeoIP Country DB ACL: %s", name );
513+ result = ISC_R_FAILURE;
514+ goto cleanup;
515+ }
516+ de->type = dns_aclelementtype_geoip_countryDB;
517+ de->negative = neg;
518+ } /* geoip_countryDB_ */
519+ else if (strncasecmp(name, "geoip_cityDB_", 13) == 0) {
520+ const char *noff = name+13 ;
521+ int match ;
522+ float flowt[4] ;
523+ char radius_type[2+1] ;
524+
525+ if ((strncasecmp(noff, "country_", 8) == 0) && (strlen(noff+8) == 2)) {
526+ de->geoip_cityDB.subtype = geoip_cityDB_country_code ;
527+ strncpy( de->geoip_cityDB.country_code, noff+8, 2 );
528+ } else if ((strncasecmp(noff, "country3_", 9) == 0) && (strlen(noff+9) == 3)) {
529+ de->geoip_cityDB.subtype = geoip_cityDB_country_code3 ;
530+ strncpy( de->geoip_cityDB.country_code3, noff+9, 3 );
531+ } else if ((strncasecmp(noff, "region_", 7) == 0) && (strlen(noff+7) == 2)) {
532+ de->geoip_cityDB.subtype = geoip_cityDB_region ;
533+ strncpy( de->geoip_cityDB.region, noff+7, 2 );
534+ } else if (strncasecmp(noff, "regionname_", 11) == 0) {
535+ unsigned int c ;
536+
537+ de->geoip_cityDB.subtype = geoip_cityDB_region_name ;
538+ strncpy( de->geoip_cityDB.region_name, noff+11, 255 );
539+ de->geoip_cityDB.region_name[255] = '\0' ;
540+ for ( c=0 ; c < strlen(de->geoip_cityDB.region_name) ; c++ )
541+ if ( de->geoip_cityDB.region_name[c] == '_' )
542+ de->geoip_cityDB.region_name[c] = ' ';
543+ else if ( de->geoip_cityDB.region_name[c] == '|' )
544+ de->geoip_cityDB.region_name[c] = '/';
545+ } else if (strncasecmp(noff, "city_", 5) == 0) {
546+ unsigned int c ;
547+
548+ de->geoip_cityDB.subtype = geoip_cityDB_city ;
549+ strncpy( de->geoip_cityDB.city, noff+5, 255 );
550+ de->geoip_cityDB.city[255] = '\0' ;
551+ for ( c=0 ; c < strlen(de->geoip_cityDB.city) ; c++ )
552+ if ( de->geoip_cityDB.city[c] == '_' )
553+ de->geoip_cityDB.city[c] = ' ';
554+ else if ( de->geoip_cityDB.city[c] == '|' )
555+ de->geoip_cityDB.city[c] = '/';
556+ } else if ((strncasecmp(noff, "postal_", 7) == 0) && (strlen(noff+7) <= 6)) {
557+ de->geoip_cityDB.subtype = geoip_cityDB_postal_code ;
558+ strncpy( de->geoip_cityDB.postal_code, noff+7, 6 );
559+ de->geoip_cityDB.postal_code[6] = '\0' ;
560+ } else if (( match = sscanf(noff, "lat_%f_lat_%f_lon_%f_lon_%f", &flowt[0], &flowt[1], &flowt[2], &flowt[3]) ) == 4 ) {
561+ if ( fabsf(flowt[0]) >= 90 || fabsf(flowt[1]) >= 90
562+ || fabsf(flowt[2]) >= 180 || fabsf(flowt[3]) >= 180 ) {
563+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
564+ "GeoIP ACL includes invalid lat,lat,lon,lon: %f,%f,%f,%f", flowt[0], flowt[1], flowt[2], flowt[3] );
565+ result = ISC_R_FAILURE;
566+ goto cleanup;
567+ }
568+
569+ if ( flowt[0] == flowt[1] || flowt[2] == flowt[3] ) {
570+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
571+ "GeoIP ACL includes invariant lat vs. lat or lon vs. lon: %f,%f %f,%f", flowt[0], flowt[1], flowt[2], flowt[3] );
572+ result = ISC_R_FAILURE;
573+ goto cleanup;
574+ }
575+
576+ de->geoip_cityDB.subtype = geoip_cityDB_range ;
577+ de->geoip_cityDB.lat[0] = flowt[0] ;
578+ de->geoip_cityDB.lat[1] = flowt[1] ;
579+ de->geoip_cityDB.lon[0] = flowt[2] ;
580+ de->geoip_cityDB.lon[1] = flowt[3] ;
581+ } else if (( match = sscanf(noff, "lat_%f_lat_%f", &flowt[0], &flowt[1]) ) == 2 ) {
582+ if ( flowt[0] == flowt[1] ) {
583+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
584+ "GeoIP ACL includes invariant lat vs. lat: %f,%f", flowt[0], flowt[1] );
585+ result = ISC_R_FAILURE;
586+ goto cleanup;
587+ }
588+
589+ de->geoip_cityDB.subtype = geoip_cityDB_range ;
590+ de->geoip_cityDB.lat[0] = flowt[0] ;
591+ de->geoip_cityDB.lat[1] = flowt[1] ;
592+ de->geoip_cityDB.lon[0] = 0.0 ;
593+ de->geoip_cityDB.lon[1] = 0.0 ;
594+ } else if (( match = sscanf(noff, "lon_%f_lon_%f", &flowt[0], &flowt[1]) ) == 2 ) {
595+ if ( flowt[0] == flowt[1] ) {
596+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
597+ "GeoIP ACL includes invariant lon vs. lon: %f,%f", flowt[0], flowt[1] );
598+ result = ISC_R_FAILURE;
599+ goto cleanup;
600+ }
601+
602+ de->geoip_cityDB.subtype = geoip_cityDB_range ;
603+ de->geoip_cityDB.lon[0] = flowt[0] ;
604+ de->geoip_cityDB.lon[1] = flowt[1] ;
605+ de->geoip_cityDB.lat[0] = 0.0 ;
606+ de->geoip_cityDB.lat[1] = 0.0 ;
607+ } else if (( match = sscanf(noff, "lat_%f_lon_%f_radius_%f%2s", &flowt[0], &flowt[1], &flowt[2], radius_type) ) == 4 ) {
608+ float de2ra = acos(-1)/180 ;
609+ float factor = fabsf( cos( flowt[0] * de2ra ) );
610+
611+ if ( fabsf(flowt[0]) >= 90 || fabsf(flowt[1]) >= 180 ) {
612+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
613+ "GeoIP ACL includes invalid lat,lon: %f,%f", flowt[0], flowt[1] );
614+ result = ISC_R_FAILURE;
615+ goto cleanup;
616+ }
617+
618+ if ( flowt[2] <= 0 ) {
619+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
620+ "GeoIP ACL includes invalid radius value: %f", flowt[2] );
621+ result = ISC_R_FAILURE;
622+ goto cleanup;
623+ }
624+
625+ if ( strncasecmp( radius_type, "mi", 2 ) == 0 ) {
626+ static float earth_radius_mi = 3958.761 ;
627+ float mi_de = earth_radius_mi * de2ra ;
628+
629+ de->geoip_cityDB.radius[0] = ( flowt[2] / mi_de );
630+ de->geoip_cityDB.radius[1] = ( flowt[2] / mi_de ) * factor ;
631+ }
632+ else if ( strncasecmp( radius_type, "km", 2 ) == 0 ) {
633+ static float earth_radius_km = 6371.009 ;
634+ float km_de = earth_radius_km * de2ra ;
635+
636+ de->geoip_cityDB.radius[0] = ( flowt[2] / km_de );
637+ de->geoip_cityDB.radius[1] = ( flowt[2] / km_de ) * factor ;
638+ }
639+ else if ( strncasecmp( radius_type, "de", 2 ) == 0 ) {
640+ de->geoip_cityDB.radius[0] = flowt[2] ;
641+ de->geoip_cityDB.radius[1] = flowt[2] ;
642+ }
643+ else {
644+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
645+ "unrecognized GeoIP ACL (need mi, km, or de): %s", name );
646+ result = ISC_R_FAILURE;
647+ goto cleanup;
648+ }
649+ de->geoip_cityDB.subtype = geoip_cityDB_radius ;
650+ de->geoip_cityDB.lat[0] = flowt[0] ;
651+ de->geoip_cityDB.lon[0] = flowt[1] ;
652+ de->geoip_cityDB.lat[1] = 0.0 ;
653+ de->geoip_cityDB.lon[1] = 0.0 ;
654+ } else if (strncasecmp(noff, "metro_", 6) == 0) {
655+ de->geoip_cityDB.subtype = geoip_cityDB_metro_code ;
656+ de->geoip_cityDB.metro_code = atoi( noff+6 );
657+ } else if (strncasecmp(noff, "area_", 5) == 0) {
658+ de->geoip_cityDB.subtype = geoip_cityDB_area_code ;
659+ de->geoip_cityDB.area_code = atoi( noff+5 );
660+ } else if ((strncasecmp(noff, "continent_", 10) == 0) && (strlen(noff+10) == 2)) {
661+ de->geoip_cityDB.subtype = geoip_cityDB_continent_code ;
662+ strncpy( de->geoip_cityDB.continent_code, noff+10, 2 );
663+ } else if (strncasecmp(noff, "timezone_", 9) == 0) {
664+ unsigned int c ;
665+
666+ de->geoip_cityDB.subtype = geoip_cityDB_timezone_code ;
667+ strncpy( de->geoip_cityDB.timezone_code, noff+9, 255 );
668+ de->geoip_cityDB.timezone_code[255] = '\0';
669+ for ( c=0 ; c < strlen(de->geoip_cityDB.timezone_code) ; c++ )
670+ if ( de->geoip_cityDB.timezone_code[c] == '_' )
671+ de->geoip_cityDB.timezone_code[c] = ' ';
672+ else if ( de->geoip_cityDB.timezone_code[c] == '|' )
673+ de->geoip_cityDB.timezone_code[c] = '/';
674+ } else {
675+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
676+ "unrecognized GeoIP City DB ACL: %s", name );
677+ result = ISC_R_FAILURE;
678+ goto cleanup;
679+ }
680+ de->type = dns_aclelementtype_geoip_cityDB;
681+ de->negative = neg;
682+ } /* geoip_cityDB_ */
683+ else if (strncasecmp(name, "geoip_regionDB_", 15) == 0) {
684+ const char *noff = name+15 ;
685+
686+ if ((strncasecmp(noff, "country_", 8) == 0) && (strlen(noff+8) == 2)) {
687+ de->geoip_regionDB.subtype = geoip_regionDB_country_code ;
688+ strncpy( de->geoip_regionDB.country_code, noff+8, 2 );
689+ } else if ((strncasecmp(noff, "region_", 7) == 0) && (strlen(noff+7) == 2)) {
690+ de->geoip_regionDB.subtype = geoip_regionDB_region ;
691+ strncpy( de->geoip_regionDB.region, noff+7, 2 );
692+ } else {
693+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
694+ "unrecognized GeoIP Region DB ACL: %s", name );
695+ result = ISC_R_FAILURE;
696+ goto cleanup;
697+ }
698+ de->type = dns_aclelementtype_geoip_regionDB;
699+ de->negative = neg;
700+ } /* geoip_regionDB_ */
701+ else if (strncasecmp(name, "geoip_ispDB_", 12) == 0) {
702+ const char *noff = name+12 ;
703+
704+ if (strncasecmp(noff, "name_", 5) == 0) {
705+ unsigned int c ;
706+
707+ de->geoip_ispDB.subtype = geoip_ispDB_name ;
708+ strncpy( de->geoip_ispDB.name, noff+5, 50 );
709+ de->geoip_ispDB.name[50] = '\0';
710+ for ( c=0 ; c < strlen(de->geoip_ispDB.name) ; c++ )
711+ if ( de->geoip_ispDB.name[c] == '_' )
712+ de->geoip_ispDB.name[c] = ' ';
713+ } else {
714+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
715+ "unrecognized GeoIP ISP DB ACL: %s", name );
716+ result = ISC_R_FAILURE;
717+ goto cleanup;
718+ }
719+ de->type = dns_aclelementtype_geoip_ispDB;
720+ de->negative = neg;
721+ } /* geoip_ispDB_ */
722+ else if (strncasecmp(name, "geoip_orgDB_", 12) == 0) {
723+ const char *noff = name+12 ;
724+
725+ if (strncasecmp(noff, "name_", 5) == 0) {
726+ unsigned int c ;
727+
728+ de->geoip_orgDB.subtype = geoip_orgDB_name ;
729+ strncpy( de->geoip_orgDB.name, noff+5, 50 );
730+ de->geoip_orgDB.name[50] = '\0';
731+ for ( c=0 ; c < strlen(de->geoip_orgDB.name) ; c++ )
732+ if ( de->geoip_orgDB.name[c] == '_' )
733+ de->geoip_orgDB.name[c] = ' ';
734+ else if ( de->geoip_orgDB.name[c] == '|' )
735+ de->geoip_orgDB.name[c] = '/';
736+ } else {
737+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
738+ "unrecognized GeoIP Organization DB ACL: %s", name );
739+ result = ISC_R_FAILURE;
740+ goto cleanup;
741+ }
742+ de->type = dns_aclelementtype_geoip_orgDB;
743+ de->negative = neg;
744+ } /* geoip_orgDB_ */
745+ else if (strncasecmp(name, "geoip_asDB_", 11) == 0) {
746+ const char *noff = name+11 ;
747+
748+ if (strncasecmp(noff, "org_", 4) == 0) {
749+ unsigned int c ;
750+
751+ de->geoip_asDB.subtype = geoip_asDB_org ;
752+ strncpy( de->geoip_asDB.org, noff+4, 50 );
753+ de->geoip_asDB.org[50] = '\0';
754+ for ( c=0 ; c < strlen(de->geoip_asDB.org) ; c++ )
755+ if ( de->geoip_asDB.org[c] == '_' )
756+ de->geoip_asDB.org[c] = ' ';
757+ else if ( de->geoip_asDB.org[c] == '|' )
758+ de->geoip_asDB.org[c] = '/';
759+ } else {
760+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
761+ "unrecognized GeoIP AS DB ACL: %s", name );
762+ result = ISC_R_FAILURE;
763+ goto cleanup;
764+ }
765+ de->type = dns_aclelementtype_geoip_asDB;
766+ de->negative = neg;
767+ } /* geoip_asDB_ */
768+ else if (strncasecmp(name, "geoip_netspeedDB_", 17) == 0) {
769+ const char *noff = name+17 ;
770+
771+ if (strncasecmp(noff, "id_", 3) == 0) {
772+ de->geoip_netspeedDB.subtype = geoip_netspeedDB_id ;
773+ de->geoip_netspeedDB.id = atoi( noff+3 );
774+ } else {
775+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
776+ "unrecognized GeoIP NetSpeed DB ACL: %s", name );
777+ result = ISC_R_FAILURE;
778+ goto cleanup;
779+ }
780+ de->type = dns_aclelementtype_geoip_netspeedDB;
781+ de->negative = neg;
782+ } /* geoip_netspeedDB_ */
783+ else if (strncasecmp(name, "geoip_domainDB_", 15) == 0) {
784+ const char *noff = name+15 ;
785+
786+ if (strncasecmp(noff, "name_", 5) == 0) {
787+ unsigned int c ;
788+
789+ de->geoip_domainDB.subtype = geoip_domainDB_name ;
790+ strncpy( de->geoip_domainDB.name, noff+5, 255 );
791+ de->geoip_domainDB.name[255] = '\0';
792+ for ( c=0 ; c < strlen(de->geoip_domainDB.name) ; c++ )
793+ if ( de->geoip_domainDB.name[c] == '_' )
794+ de->geoip_domainDB.name[c] = ' ';
795+ else if ( de->geoip_domainDB.name[c] == '|' )
796+ de->geoip_domainDB.name[c] = '/';
797+ } else {
798+ cfg_obj_log(ce, lctx, ISC_LOG_ERROR,
799+ "unrecognized GeoIP Domain DB ACL: %s", name );
800+ result = ISC_R_FAILURE;
801+ goto cleanup;
802+ }
803+ de->type = dns_aclelementtype_geoip_domainDB;
804+ de->negative = neg;
805+#endif /* HAVE_GEOIP */
806 } else if (strcasecmp(name, "localhost") == 0) {
807 de->type = dns_aclelementtype_localhost;
808 de->negative = neg;
809--- lib/isc/include/isc/geoip.h.orig 2012-10-09 17:38:10.000000000 -0700
810+++ lib/isc/include/isc/geoip.h 2012-10-09 17:38:10.000000000 -0700
811@@ -0,0 +1,25 @@
812+#ifdef HAVE_GEOIP
813+#ifndef _GEOIP_H
814+#define _GEOIP_H
815+
816+#include <GeoIP.h>
817+#include <GeoIPCity.h>
818+
819+void geoip_init( void );
820+
821+extern GeoIP * ns_g_geoip_countryDB ; /* 1 */
822+extern GeoIP * ns_g_geoip_cityDB ; /* 2&6 */
823+extern GeoIP * ns_g_geoip_regionDB ; /* 3&7 */
824+extern GeoIP * ns_g_geoip_ispDB ; /* 4 */
825+extern GeoIP * ns_g_geoip_orgDB ; /* 5 */
826+/* proxyDB doesn't apply in a DNS context * 8 */
827+extern GeoIP * ns_g_geoip_asDB ; /* 9 */
828+extern GeoIP * ns_g_geoip_netspeedDB ; /* 10 */
829+extern GeoIP * ns_g_geoip_domainDB ; /* 11 */
830+#ifdef HAVE_GEOIP_V6
831+extern GeoIP * ns_g_geoip_countryDB_v6 ; /* 12 */
832+#endif
833+
834+#endif /* !_GEOIP_H */
835+#endif /* HAVE_GEOIP */
836+
837--- lib/dns/acl.c.orig 2012-09-26 17:35:19.000000000 -0700
838+++ lib/dns/acl.c 2012-10-09 17:38:10.000000000 -0700
839@@ -29,6 +29,72 @@
840 #include <dns/acl.h>
841 #include <dns/iptable.h>
842
843+#ifdef HAVE_GEOIP
844+#include <isc/thread.h>
845+#include <math.h>
846+#include <netinet/in.h>
847+#include <dns/log.h>
848+#include <GeoIP.h>
849+#include <GeoIPCity.h>
850+#include <isc/geoip.h>
851+
852+GeoIP * ns_g_geoip_countryDB = (GeoIP *)NULL ;
853+GeoIP * ns_g_geoip_cityDB = (GeoIP *)NULL ;
854+GeoIP * ns_g_geoip_regionDB = (GeoIP *)NULL ;
855+GeoIP * ns_g_geoip_ispDB = (GeoIP *)NULL ;
856+GeoIP * ns_g_geoip_orgDB = (GeoIP *)NULL ;
857+GeoIP * ns_g_geoip_asDB = (GeoIP *)NULL ;
858+GeoIP * ns_g_geoip_netspeedDB = (GeoIP *)NULL ;
859+GeoIP * ns_g_geoip_domainDB = (GeoIP *)NULL ;
860+#ifdef HAVE_GEOIP_V6
861+GeoIP * ns_g_geoip_countryDB_v6 = (GeoIP *)NULL ;
862+#endif
863+
864+#ifdef ISC_PLATFORM_USETHREADS
865+/* CITY IPNUM v4 */
866+static isc_once_t prev_cityDB_ipnum_once = ISC_ONCE_INIT;
867+static isc_thread_key_t prev_cityDB_ipnum ;
868+static void
869+initialize_prev_cityDB_ipnum( void ) {
870+ RUNTIME_CHECK(isc_thread_key_create( &prev_cityDB_ipnum, (void *)NULL) == ISC_R_SUCCESS);
871+}
872+static uint32_t
873+get_prev_cityDB_ipnum() {
874+ uint32_t *preval = (uint32_t *)isc_thread_key_getspecific( prev_cityDB_ipnum );
875+ if ( preval )
876+ return *preval ;
877+ return 0 ;
878+}
879+static void
880+set_prev_cityDB_ipnum( const uint32_t in_ipnum ) {
881+ uint32_t *preval = (uint32_t *)isc_thread_key_getspecific( prev_cityDB_ipnum );
882+ if ( preval )
883+ free(preval);
884+ if (( preval = (uint32_t *)malloc( sizeof(uint32_t) ) ))
885+ *preval = in_ipnum ;
886+ isc_thread_key_setspecific( prev_cityDB_ipnum, preval );
887+}
888+/* CITY RECORD */
889+static isc_once_t prev_cityDB_record_once = ISC_ONCE_INIT;
890+static isc_thread_key_t prev_cityDB_record ;
891+static void
892+initialize_prev_cityDB_record( void ) {
893+ RUNTIME_CHECK(isc_thread_key_create( &prev_cityDB_record, (void *)NULL) == ISC_R_SUCCESS);
894+}
895+static GeoIPRecord *
896+get_prev_cityDB_record() {
897+ return (GeoIPRecord *)isc_thread_key_getspecific( prev_cityDB_record );
898+}
899+static void
900+set_prev_cityDB_record( GeoIPRecord *in_record ) {
901+ GeoIPRecord *preval = get_prev_cityDB_record();
902+ if ( preval )
903+ GeoIPRecord_delete( preval );
904+ isc_thread_key_setspecific(prev_cityDB_record, in_record);
905+}
906+#endif /* ISC_PLATFORM_USETHREADS */
907+#endif /* HAVE_GEOIP */
908+
909 /*
910 * Create a new ACL, including an IP table and an array with room
911 * for 'n' ACL elements. The elements are uninitialized and the
912@@ -375,6 +441,43 @@
913 dns_acl_t *inner = NULL;
914 int indirectmatch;
915 isc_result_t result;
916+#ifdef HAVE_GEOIP
917+ uint32_t ipnum = 0;
918+#ifdef HAVE_GEOIP_V6
919+ const geoipv6_t *ipnum6 = NULL;
920+#ifdef DEBUG_GEOIP
921+ /* Use longest address type to size the buffer */
922+ char ipstr[INET6_ADDRSTRLEN+1] = "";
923+#endif
924+#else /* HAVE_GEOIP_V6 */
925+#ifdef DEBUG_GEOIP
926+ char ipstr[INET_ADDRSTRLEN+1] = "";
927+#endif
928+#endif /* HAVE_GEOIP_V6 */
929+
930+ switch ( reqaddr->family ) {
931+ case AF_INET:
932+ ipnum = ntohl(reqaddr->type.in.s_addr);
933+#ifdef DEBUG_GEOIP
934+ inet_ntop(AF_INET, &reqaddr->type.in, ipstr, INET_ADDRSTRLEN);
935+#endif
936+ break;
937+#ifdef HAVE_GEOIP_V6
938+ case AF_INET6:
939+ ipnum6 = &reqaddr->type.in6;
940+#ifdef DEBUG_GEOIP
941+ inet_ntop(AF_INET6, &reqaddr->type.in6, ipstr, INET6_ADDRSTRLEN);
942+#endif
943+ break;
944+#endif
945+ }
946+ if ( !ipnum )
947+ return(ISC_FALSE);
948+#ifdef HAVE_GEOIP_V6
949+ if ( !ipnum && !ipnum6 )
950+ return(ISC_FALSE);
951+#endif
952+#endif /* HAVE_GEOIP */
953
954 switch (e->type) {
955 case dns_aclelementtype_keyname:
956@@ -391,6 +494,477 @@
957 inner = e->nestedacl;
958 break;
959
960+#ifdef HAVE_GEOIP
961+ /* GeoIPRecord lookups are only performed if the previous lookup was
962+ * with a different IP address than the current.
963+ *
964+ * This allows only a single GeoIPRecord lookup per query for an entire
965+ * configuration pass, instead of a GeoIPRecord lookup for each and
966+ * every instance of a geoip_* ACL. Because of this, CityDB /may/ scale
967+ * more nicely than other DBs.
968+ *
969+ * The mechanism consists of simple statics (prev_ipnum, prev_record)
970+ * for non-threaded operation, and an unspeakably painful TLS mechanism
971+ * for threaded operation.
972+ */
973+ case dns_aclelementtype_geoip_countryDB: {
974+ short int georesult = 0 ;
975+ const char *result = (const char *)NULL ;
976+
977+ if ( ( ipnum && !ns_g_geoip_countryDB )
978+#ifdef HAVE_GEOIP_V6
979+ || ( ipnum6 && !ns_g_geoip_countryDB_v6 )
980+#endif
981+ )
982+ return(ISC_FALSE);
983+
984+ switch ( e->geoip_countryDB.subtype ) {
985+ case geoip_countryDB_country_code:
986+ if ( ipnum )
987+ result = GeoIP_country_code_by_ipnum( ns_g_geoip_countryDB, ipnum );
988+#ifdef HAVE_GEOIP_V6
989+ else if ( ipnum6 )
990+ result = GeoIP_country_code_by_ipnum_v6( ns_g_geoip_countryDB_v6, *ipnum6 );
991+#endif
992+ if ( result )
993+ georesult = ( strncasecmp( e->geoip_countryDB.country_code, result, 2 ) == 0 );
994+#ifdef DEBUG_GEOIP
995+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
996+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
997+ "client %s: geoip_countryDB_country_code compared result \"%s\" to rule \"%s\", got %d neg %d",
998+ ipstr,
999+ result, e->geoip_countryDB.country_code,
1000+ georesult, e->negative);
1001+#endif
1002+ break;
1003+ case geoip_countryDB_country_code3:
1004+ if ( ipnum )
1005+ result = GeoIP_country_code3_by_ipnum( ns_g_geoip_countryDB, ipnum );
1006+#ifdef HAVE_GEOIP_V6
1007+ else if ( ipnum6 )
1008+ result = GeoIP_country_code3_by_ipnum_v6( ns_g_geoip_countryDB_v6, *ipnum6 );
1009+#endif
1010+ if ( result )
1011+ georesult = ( strncasecmp( e->geoip_countryDB.country_code3, result, 3 ) == 0 );
1012+#ifdef DEBUG_GEOIP
1013+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1014+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1015+ "client %s: geoip_countryDB_country_code3 compared result \"%s\" to rule \"%s\", got %d neg %d",
1016+ ipstr,
1017+ result, e->geoip_countryDB.country_code3,
1018+ georesult, e->negative);
1019+#endif
1020+ break;
1021+ case geoip_countryDB_country_name:
1022+ if ( ipnum )
1023+ result = GeoIP_country_name_by_ipnum( ns_g_geoip_countryDB, ipnum );
1024+#ifdef HAVE_GEOIP_V6
1025+ else if ( ipnum6 )
1026+ result = GeoIP_country_name_by_ipnum_v6( ns_g_geoip_countryDB_v6, *ipnum6 );
1027+#endif
1028+ if ( result )
1029+ georesult = ( strcasecmp( e->geoip_countryDB.country_name, result ) == 0 );
1030+#ifdef DEBUG_GEOIP
1031+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1032+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1033+ "client %s: geoip_countryDB_country_name compared result \"%s\" to rule \"%s\", got %d neg %d",
1034+ ipstr,
1035+ result, e->geoip_countryDB.country_name,
1036+ georesult, e->negative);
1037+#endif
1038+ break;
1039+ default:
1040+ break;
1041+ } /* switch */
1042+ return( georesult ? ISC_TRUE : ISC_FALSE );
1043+ } /* case geoip_countryDB */
1044+
1045+ case dns_aclelementtype_geoip_cityDB: {
1046+ short int georesult = 0 ;
1047+ const char *scratch = (const char *)NULL;
1048+ GeoIPRecord *record = (GeoIPRecord *)NULL ;
1049+#ifdef ISC_PLATFORM_USETHREADS
1050+ uint32_t prev_cityDB_ipnum = get_prev_cityDB_ipnum();
1051+
1052+ GeoIPRecord *prev_cityDB_record = (GeoIPRecord *)NULL ;
1053+
1054+ RUNTIME_CHECK(
1055+ isc_once_do(&prev_cityDB_ipnum_once, initialize_prev_cityDB_ipnum) == ISC_R_SUCCESS
1056+ );
1057+ RUNTIME_CHECK(
1058+ isc_once_do(&prev_cityDB_record_once, initialize_prev_cityDB_record) == ISC_R_SUCCESS
1059+ );
1060+
1061+ prev_cityDB_record = get_prev_cityDB_record();
1062+#else
1063+ static uint32_t prev_cityDB_ipnum = 0 ;
1064+ static void *prev_cityDB_record ;
1065+#endif
1066+
1067+ if ( !ipnum || !ns_g_geoip_cityDB )
1068+ return( ISC_FALSE );
1069+
1070+ if ( prev_cityDB_ipnum == ipnum )
1071+ record = prev_cityDB_record ;
1072+ else {
1073+ record = GeoIP_record_by_ipnum( ns_g_geoip_cityDB, ipnum );
1074+#ifdef ISC_PLATFORM_USETHREADS
1075+ set_prev_cityDB_record( record );
1076+ set_prev_cityDB_ipnum( ipnum );
1077+#else
1078+ prev_cityDB_record = record ;
1079+ prev_cityDB_ipnum = ipnum ;
1080+#endif
1081+ }
1082+
1083+ if ( record ) {
1084+ switch ( e->geoip_cityDB.subtype ) {
1085+ case geoip_cityDB_country_code:
1086+ if ( record->country_code )
1087+ georesult = ( strncasecmp( e->geoip_cityDB.country_code, record->country_code, 2 ) == 0 );
1088+#ifdef DEBUG_GEOIP
1089+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1090+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1091+ "client %s: geoip_cityDB_country_code compared result \"%s\" to rule \"%s\", got %d neg %d",
1092+ ipstr,
1093+ record->country_code, e->geoip_cityDB.country_code,
1094+ georesult, e->negative);
1095+#endif
1096+ break;
1097+ case geoip_cityDB_country_code3:
1098+ if ( record->country_code3 )
1099+ georesult = ( strncasecmp( e->geoip_cityDB.country_code3, record->country_code3, 3 ) == 0 );
1100+#ifdef DEBUG_GEOIP
1101+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1102+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1103+ "client %s: geoip_cityDB_country_code3 compared result \"%s\" to rule \"%s\", got %d neg %d",
1104+ ipstr,
1105+ record->country_code3, e->geoip_cityDB.country_code3,
1106+ georesult, e->negative);
1107+#endif
1108+ break;
1109+ case geoip_cityDB_region:
1110+ if ( record->region )
1111+ georesult = ( strncasecmp( e->geoip_cityDB.region, record->region, 2 ) == 0 );
1112+#ifdef DEBUG_GEOIP
1113+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1114+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1115+ "client %s: geoip_cityDB_region compared result \"%s\" to rule \"%s\", got %d neg %d",
1116+ ipstr,
1117+ record->region, e->geoip_cityDB.region,
1118+ georesult, e->negative);
1119+#endif
1120+ break;
1121+ case geoip_cityDB_region_name:
1122+ if ( record->country_code && record->region
1123+ && ( scratch = GeoIP_region_name_by_code(record->country_code,record->region) ) )
1124+ georesult = ( strcasecmp( e->geoip_cityDB.region_name, scratch ) == 0 );
1125+#ifdef DEBUG_GEOIP
1126+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1127+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1128+ "client %s: geoip_cityDB_regionname compared result \"%s\" to rule \"%s\", got %d neg %d",
1129+ ipstr,
1130+ scratch, e->geoip_cityDB.region_name,
1131+ georesult, e->negative);
1132+#endif
1133+ break;
1134+ case geoip_cityDB_city:
1135+ if ( record->city )
1136+ georesult = ( strcasecmp( e->geoip_cityDB.city, record->city ) == 0 );
1137+#ifdef DEBUG_GEOIP
1138+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1139+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1140+ "client %s: geoip_cityDB_city compared result \"%s\" to rule \"%s\", got %d neg %d",
1141+ ipstr,
1142+ record->city, e->geoip_cityDB.city,
1143+ georesult, e->negative);
1144+#endif
1145+ break;
1146+ case geoip_cityDB_postal_code:
1147+ if ( record->postal_code )
1148+ georesult = ( strcasecmp( e->geoip_cityDB.postal_code, record->postal_code ) == 0 );
1149+#ifdef DEBUG_GEOIP
1150+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1151+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1152+ "client %s: geoip_cityDB_postal compared result \"%s\" to rule \"%s\", got %d neg %d",
1153+ ipstr,
1154+ record->postal_code, e->geoip_cityDB.postal_code,
1155+ georesult, e->negative);
1156+#endif
1157+ break;
1158+ case geoip_cityDB_range: {
1159+ short int lat = -1 ;
1160+ short int lon = -1 ;
1161+ if ( e->geoip_cityDB.lat[0] || e->geoip_cityDB.lat[1] )
1162+ lat = ( e->geoip_cityDB.lat[0] <= record->latitude && record->latitude <= e->geoip_cityDB.lat[1] );
1163+ if ( e->geoip_cityDB.lon[0] || e->geoip_cityDB.lon[1] )
1164+ lon = ( e->geoip_cityDB.lon[0] <= record->longitude && record->longitude <= e->geoip_cityDB.lon[1] );
1165+ georesult = ( lat && lon );
1166+#ifdef DEBUG_GEOIP
1167+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1168+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1169+ "client %s: geoip_cityDB_range compared result %f,%f to rule %f->%f,%f->%f; got %d neg %d",
1170+ ipstr,
1171+ record->latitude, record->longitude,
1172+ e->geoip_cityDB.lat[0], e->geoip_cityDB.lat[1],
1173+ e->geoip_cityDB.lon[0], e->geoip_cityDB.lon[1],
1174+ georesult, e->negative);
1175+#endif
1176+ break;
1177+ }
1178+ case geoip_cityDB_radius:
1179+ georesult = (( pow((record->latitude-e->geoip_cityDB.lat[0])/e->geoip_cityDB.radius[0],2) + pow((record->longitude-e->geoip_cityDB.lon[0])/e->geoip_cityDB.radius[1],2) ) <= 1 );
1180+#ifdef DEBUG_GEOIP
1181+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1182+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1183+ "client %s: geoip_cityDB_radius compared result %f,%f to rule %f->%f %fx%f; got %d neg %d",
1184+ ipstr,
1185+ record->latitude, record->longitude,
1186+ e->geoip_cityDB.lat[0], e->geoip_cityDB.lon[0],
1187+ e->geoip_cityDB.radius[0], e->geoip_cityDB.radius[1],
1188+ georesult, e->negative);
1189+#endif
1190+ break;
1191+ case geoip_cityDB_metro_code:
1192+ georesult = ( e->geoip_cityDB.metro_code == record->metro_code );
1193+#ifdef DEBUG_GEOIP
1194+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1195+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1196+ "client %s: geoip_cityDB_metro compared result %d to rule %d, got %d neg %d",
1197+ ipstr,
1198+ record->metro_code, e->geoip_cityDB.metro_code,
1199+ georesult, e->negative);
1200+#endif
1201+ break;
1202+ case geoip_cityDB_area_code:
1203+ georesult = ( e->geoip_cityDB.area_code == record->area_code );
1204+#ifdef DEBUG_GEOIP
1205+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1206+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1207+ "client %s: geoip_cityDB_area compared result %d to rule %d, got %d neg %d",
1208+ ipstr,
1209+ record->area_code, e->geoip_cityDB.area_code,
1210+ georesult, e->negative);
1211+#endif
1212+ break;
1213+ case geoip_cityDB_continent_code:
1214+ if ( record->continent_code )
1215+ georesult = ( strncasecmp( e->geoip_cityDB.continent_code, record->continent_code, 2 ) == 0 );
1216+#ifdef DEBUG_GEOIP
1217+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1218+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1219+ "client %s: geoip_cityDB_continent compared result \"%s\" to rule \"%s\", got %d neg %d",
1220+ ipstr,
1221+ record->continent_code, e->geoip_cityDB.continent_code,
1222+ georesult, e->negative);
1223+#endif
1224+ break;
1225+ case geoip_cityDB_timezone_code:
1226+ if ( record->country_code && record->region
1227+ && ( scratch = GeoIP_time_zone_by_country_and_region( record->country_code, record->region ) ) )
1228+ georesult = ( strcasecmp( e->geoip_cityDB.timezone_code, scratch ) == 0 );
1229+#ifdef DEBUG_GEOIP
1230+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1231+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1232+ "client %s: geoip_cityDB_timezone compared result \"%s\" to rule \"%s\", got %d neg %d",
1233+ ipstr,
1234+ scratch, e->geoip_cityDB.timezone_code,
1235+ georesult, e->negative);
1236+#endif
1237+ break;
1238+ default:
1239+ break;
1240+ } /* switch */
1241+ } /* if record */
1242+#ifdef DEBUG_GEOIP
1243+ else
1244+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1245+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1246+ "client %s: geoip_cityDB found no record",
1247+ ipstr);
1248+#endif
1249+ return( georesult ? ISC_TRUE : ISC_FALSE );
1250+ } /* case geoip_cityDB */
1251+
1252+ case dns_aclelementtype_geoip_regionDB: {
1253+ short int georesult = 0 ;
1254+ const GeoIPRegion *record = (const GeoIPRegion *)NULL ;
1255+
1256+ if ( !ipnum || !ns_g_geoip_regionDB )
1257+ return(ISC_FALSE);
1258+
1259+ if (( record = GeoIP_region_by_ipnum( ns_g_geoip_regionDB, ipnum) )) {
1260+ switch ( e->geoip_regionDB.subtype ) {
1261+ case geoip_regionDB_country_code:
1262+ if ( record->country_code )
1263+ georesult = ( strncasecmp( e->geoip_regionDB.country_code, record->country_code, 3 ) == 0 );
1264+#ifdef DEBUG_GEOIP
1265+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1266+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1267+ "client %s: geoip_regionDB_name compared result \"%s\" to rule \"%s\", got %d neg %d",
1268+ ipstr,
1269+ record->country_code, e->geoip_regionDB.country_code,
1270+ georesult, e->negative);
1271+#endif
1272+ break;
1273+ case geoip_regionDB_region:
1274+ if ( record->region && *record->region )
1275+ georesult = ( strncasecmp( e->geoip_regionDB.region, record->region, 3 ) == 0 );
1276+#ifdef DEBUG_GEOIP
1277+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1278+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1279+ "client %s: geoip_regionDB_name compared result \"%s\" to rule \"%s\", got %d neg %d",
1280+ ipstr,
1281+ record->region, e->geoip_regionDB.region,
1282+ georesult, e->negative);
1283+#endif
1284+ break;
1285+ default:
1286+ break;
1287+ } /* switch */
1288+ } /* if record */
1289+#ifdef DEBUG_GEOIP
1290+ else
1291+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1292+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1293+ "client %s: geoip_regionDB found no record",
1294+ ipstr);
1295+#endif
1296+ return( georesult ? ISC_TRUE : ISC_FALSE );
1297+ } /* case geoip_regionDB */
1298+
1299+ case dns_aclelementtype_geoip_ispDB: {
1300+ short int georesult = 0 ;
1301+ const char *result = (const char *)NULL ;
1302+
1303+ if ( !ipnum || !ns_g_geoip_ispDB )
1304+ return(ISC_FALSE);
1305+
1306+ switch ( e->geoip_ispDB.subtype ) {
1307+ case geoip_ispDB_name:
1308+ if (( result = GeoIP_name_by_ipnum( ns_g_geoip_ispDB, ipnum ) ))
1309+ georesult = ( strcasecmp( e->geoip_ispDB.name, result ) == 0 );
1310+#ifdef DEBUG_GEOIP
1311+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1312+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1313+ "client %s: geoip_ispDB_name compared result \"%s\" to rule \"%s\", got %d neg %d",
1314+ ipstr,
1315+ result, e->geoip_ispDB.name,
1316+ georesult, e->negative);
1317+#endif
1318+ break;
1319+ default:
1320+ break;
1321+ } /* switch */
1322+ return( georesult ? ISC_TRUE : ISC_FALSE );
1323+ } /* case geoip_ispDB */
1324+
1325+ case dns_aclelementtype_geoip_orgDB: {
1326+ short int georesult = 0 ;
1327+ const char *result = (const char *)NULL ;
1328+
1329+ if ( !ipnum || !ns_g_geoip_orgDB )
1330+ return(ISC_FALSE);
1331+
1332+ switch ( e->geoip_orgDB.subtype ) {
1333+ case geoip_orgDB_name:
1334+ if (( result = GeoIP_name_by_ipnum( ns_g_geoip_orgDB, ipnum ) ))
1335+ georesult = ( strcasecmp( e->geoip_orgDB.name, result ) == 0 );
1336+#ifdef DEBUG_GEOIP
1337+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1338+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1339+ "client %s: geoip_orgDB_name compared result \"%s\" to rule \"%s\", got %d neg %d",
1340+ ipstr,
1341+ result, e->geoip_orgDB.name,
1342+ georesult, e->negative);
1343+#endif
1344+ break;
1345+ default:
1346+ break;
1347+ } /* switch */
1348+ return( georesult ? ISC_TRUE : ISC_FALSE );
1349+ } /* case geoip_orgDB */
1350+
1351+ case dns_aclelementtype_geoip_asDB: {
1352+ short int georesult = 0 ;
1353+ const char *result = (const char *)NULL ;
1354+
1355+ if ( !ipnum || !ns_g_geoip_asDB )
1356+ return(ISC_FALSE);
1357+
1358+ switch ( e->geoip_asDB.subtype ) {
1359+ case geoip_asDB_org:
1360+ if (( result = GeoIP_org_by_ipnum( ns_g_geoip_asDB, ipnum ) ))
1361+ georesult = ( strcasecmp( e->geoip_asDB.org, result ) == 0 );
1362+#ifdef DEBUG_GEOIP
1363+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1364+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1365+ "client %s: geoip_asDB_org compared result \"%s\" to rule \"%s\", got %d neg %d",
1366+ ipstr,
1367+ result, e->geoip_asDB.org,
1368+ georesult, e->negative);
1369+#endif
1370+ break;
1371+ default:
1372+ break;
1373+ } /* switch */
1374+ return( georesult ? ISC_TRUE : ISC_FALSE );
1375+ } /* case geoip_asDB */
1376+
1377+ case dns_aclelementtype_geoip_netspeedDB: {
1378+ short int georesult = 0 ;
1379+ short int result = -1 ;
1380+
1381+ if ( !ipnum || !ns_g_geoip_netspeedDB )
1382+ return( ISC_FALSE );
1383+
1384+ switch ( e->geoip_netspeedDB.subtype ) {
1385+ case geoip_netspeedDB_id:
1386+ result = GeoIP_id_by_ipnum( ns_g_geoip_netspeedDB, ipnum );
1387+ georesult = ( e->geoip_netspeedDB.id == result );
1388+#ifdef DEBUG_GEOIP
1389+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1390+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1391+ "client %s: geoip_netspeedDB_id compared result %d to rule %d, got %d neg %d",
1392+ ipstr,
1393+ result, e->geoip_netspeedDB.id,
1394+ georesult, e->negative);
1395+#endif
1396+ break;
1397+ default:
1398+ break;
1399+ } /* switch */
1400+ return( georesult ? ISC_TRUE : ISC_FALSE );
1401+ } /* case geoip_netspeedDB */
1402+
1403+ case dns_aclelementtype_geoip_domainDB: {
1404+ short int georesult = 0 ;
1405+ const char *result = (const char *)NULL ;
1406+
1407+ if ( !ipnum || !ns_g_geoip_domainDB )
1408+ return(ISC_FALSE);
1409+
1410+ switch ( e->geoip_domainDB.subtype ) {
1411+ case geoip_domainDB_name:
1412+ if (( result = GeoIP_name_by_ipnum( ns_g_geoip_domainDB, ipnum ) ))
1413+ georesult = ( strcasecmp( e->geoip_domainDB.name, result ) == 0 );
1414+#ifdef DEBUG_GEOIP
1415+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY,
1416+ DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
1417+ "client %s: geoip_domainDB_name compared result \"%s\" to rule \"%s\", got %d neg %d",
1418+ ipstr,
1419+ result, e->geoip_domainDB.name,
1420+ georesult, e->negative);
1421+#endif
1422+ break;
1423+ default:
1424+ break;
1425+ } /* switch */
1426+ return( georesult ? ISC_TRUE : ISC_FALSE );
1427+ } /* case geoip_domainDB */
1428+
1429+#endif /* HAVE_GEOIP */
1430+
1431 case dns_aclelementtype_localhost:
1432 if (env == NULL || env->localhost == NULL)
1433 return (ISC_FALSE);
1434--- lib/dns/include/dns/acl.h.orig 2012-09-26 17:35:19.000000000 -0700
1435+++ lib/dns/include/dns/acl.h 2012-10-09 17:38:10.000000000 -0700
1436@@ -52,8 +52,139 @@
1437 dns_aclelementtype_nestedacl,
1438 dns_aclelementtype_localhost,
1439 dns_aclelementtype_localnets,
1440+#ifdef HAVE_GEOIP
1441+ dns_aclelementtype_geoip_countryDB,
1442+ dns_aclelementtype_geoip_cityDB,
1443+ dns_aclelementtype_geoip_regionDB,
1444+ dns_aclelementtype_geoip_ispDB,
1445+ dns_aclelementtype_geoip_orgDB,
1446+ dns_aclelementtype_geoip_asDB,
1447+ dns_aclelementtype_geoip_netspeedDB,
1448+ dns_aclelementtype_geoip_domainDB,
1449+#endif /* HAVE_GEOIP */
1450 dns_aclelementtype_any
1451-} dns_aclelemettype_t;
1452+} dns_aclelementtype_t;
1453+
1454+#ifdef HAVE_GEOIP
1455+
1456+/* COUNTRY DB */
1457+
1458+typedef enum {
1459+ geoip_countryDB_country_code,
1460+ geoip_countryDB_country_code3,
1461+ geoip_countryDB_country_name,
1462+} dns_geoip_subtype_countryDB_t ;
1463+
1464+typedef struct dns_geoip_countryDB {
1465+ dns_geoip_subtype_countryDB_t subtype ;
1466+ char country_code[2] ;
1467+ char country_code3[3] ;
1468+ char country_name[256] ; /* \0 padded */
1469+} dns_geoip_countryDB_t;
1470+
1471+/* CITY DB */
1472+
1473+typedef enum {
1474+ geoip_cityDB_country_code,
1475+ geoip_cityDB_country_code3,
1476+ geoip_cityDB_region,
1477+ geoip_cityDB_region_name,
1478+ geoip_cityDB_city,
1479+ geoip_cityDB_postal_code,
1480+ geoip_cityDB_range,
1481+ geoip_cityDB_radius,
1482+ geoip_cityDB_metro_code,
1483+ geoip_cityDB_area_code,
1484+ geoip_cityDB_continent_code,
1485+ geoip_cityDB_timezone_code,
1486+} dns_geoip_subtype_cityDB_t ;
1487+
1488+typedef struct dns_geoip_cityDB {
1489+ dns_geoip_subtype_cityDB_t subtype ;
1490+ char country_code[2] ;
1491+ char country_code3[3] ;
1492+ char region[2] ;
1493+ char region_name[256] ; /* \0 padded */
1494+ char city[256] ; /* \0 padded */
1495+ char postal_code[7] ; /* \0 padded */
1496+ float lat[2] ;
1497+ float lon[2] ;
1498+ float radius[2] ;
1499+ int metro_code ;
1500+ int area_code ;
1501+ char continent_code[2] ;
1502+ char timezone_code[256] ; /* \0 padded */
1503+} dns_geoip_cityDB_t;
1504+
1505+/* REGION DB */
1506+
1507+typedef enum {
1508+ geoip_regionDB_country_code,
1509+ geoip_regionDB_region,
1510+} dns_geoip_subtype_regionDB_t ;
1511+
1512+typedef struct dns_geoip_regionDB {
1513+ dns_geoip_subtype_regionDB_t subtype ;
1514+ char country_code[2] ;
1515+ char region[2] ;
1516+} dns_geoip_regionDB_t;
1517+
1518+/* ISP DB */
1519+
1520+typedef enum {
1521+ geoip_ispDB_name,
1522+} dns_geoip_subtype_ispDB_t ;
1523+
1524+typedef struct dns_geoip_ispDB {
1525+ dns_geoip_subtype_ispDB_t subtype ;
1526+ char name[51] ; /* \0 padded */
1527+} dns_geoip_ispDB_t;
1528+
1529+/* ORG DB */
1530+
1531+typedef enum {
1532+ geoip_orgDB_name,
1533+} dns_geoip_subtype_orgDB_t ;
1534+
1535+typedef struct dns_geoip_orgDB {
1536+ dns_geoip_subtype_orgDB_t subtype ;
1537+ char name[51] ; /* \0 padded */
1538+} dns_geoip_orgDB_t;
1539+
1540+/* AS DB */
1541+
1542+typedef enum {
1543+ geoip_asDB_org,
1544+} dns_geoip_subtype_asDB_t ;
1545+
1546+typedef struct dns_geoip_asDB {
1547+ dns_geoip_subtype_asDB_t subtype ;
1548+ char org[51] ; /* \0 padded */
1549+} dns_geoip_asDB_t;
1550+
1551+/* NETSPEED DB */
1552+
1553+typedef enum {
1554+ geoip_netspeedDB_id,
1555+} dns_geoip_subtype_netspeedDB_t ;
1556+
1557+typedef struct dns_geoip_netspeedDB {
1558+ dns_geoip_subtype_netspeedDB_t subtype ;
1559+ short int id ;
1560+} dns_geoip_netspeedDB_t;
1561+
1562+/* DOMAIN DB */
1563+
1564+typedef enum {
1565+ geoip_domainDB_name,
1566+} dns_geoip_subtype_domainDB_t ;
1567+
1568+typedef struct dns_geoip_domainDB {
1569+ dns_geoip_subtype_domainDB_t subtype ;
1570+ char name[256] ; /* \0 padded */
1571+} dns_geoip_domainDB_t;
1572+
1573+#endif /* HAVE_GEOIP */
1574
1575 typedef struct dns_aclipprefix dns_aclipprefix_t;
1576
1577@@ -63,9 +194,19 @@
1578 };
1579
1580 struct dns_aclelement {
1581- dns_aclelemettype_t type;
1582+ dns_aclelementtype_t type;
1583 isc_boolean_t negative;
1584 dns_name_t keyname;
1585+#ifdef HAVE_GEOIP
1586+ dns_geoip_countryDB_t geoip_countryDB;
1587+ dns_geoip_cityDB_t geoip_cityDB;
1588+ dns_geoip_regionDB_t geoip_regionDB;
1589+ dns_geoip_ispDB_t geoip_ispDB;
1590+ dns_geoip_orgDB_t geoip_orgDB;
1591+ dns_geoip_asDB_t geoip_asDB;
1592+ dns_geoip_netspeedDB_t geoip_netspeedDB;
1593+ dns_geoip_domainDB_t geoip_domainDB;
1594+#endif /* HAVE_GEOIP */
1595 dns_acl_t *nestedacl;
1596 int node_num;
1597 };
This page took 0.313633 seconds and 4 git commands to generate.