]> git.pld-linux.org Git - packages/bind.git/blob - bind-geoip.patch
- root.zone update
[packages/bind.git] / bind-geoip.patch
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
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
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  
288 @@ -4859,6 +4862,21 @@
289         return (n);
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
308  load_configuration(const char *filename, ns_server_t *server,
309                    isc_boolean_t first_time)
310 @@ -5983,6 +6001,11 @@
311         isc_hash_init();
312  
313         CHECKFATAL(load_zones(server, ISC_TRUE), "loading zones");
314 +
315 +#ifdef HAVE_GEOIP
316 +       /* Load GeoIP DBs */
317 +       CHECKFATAL(load_geoip(server), "loading GeoIP");
318 +#endif /* HAVE_GEOIP */
319  }
320  
321  void
322 @@ -6430,6 +6453,20 @@
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.421211 seconds and 3 git commands to generate.