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