]>
Commit | Line | Data |
---|---|---|
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 | }; |