Klaus Demo nginx / 431111e
Merge of r5014, r5015, r5016, r5030: geoip ipv6 support. *) Configure: fixed style of include directories. *) Configure: fixed GeoIP library detection. *) GeoIP: IPv6 support. When using IPv6 databases, IPv4 addresses are looked up as IPv4-mapped IPv6 addresses. Mostly based on a patch by Gregor Kališnik (ticket #250). *) GeoIP: removed pseudo-support of "proxy" and "netspeed" databases. Maxim Dounin 9 years ago
3 changed file(s) with 164 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
55 ngx_feature="GeoIP library"
66 ngx_feature_name=
77 ngx_feature_run=no
8 ngx_feature_incs=
8 ngx_feature_incs="#include <GeoIP.h>"
99 ngx_feature_path=
1010 ngx_feature_libs="-lGeoIP"
1111 ngx_feature_test="GeoIP_open(NULL, 0)"
1717 # FreeBSD port
1818
1919 ngx_feature="GeoIP library in /usr/local/"
20 ngx_feature_path="/usr/local/include"
2021
2122 if [ $NGX_RPATH = YES ]; then
2223 ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP"
3334 # NetBSD port
3435
3536 ngx_feature="GeoIP library in /usr/pkg/"
36 ngx_feature_path="/usr/pkg/include/"
37 ngx_feature_path="/usr/pkg/include"
3738
3839 if [ $NGX_RPATH = YES ]; then
3940 ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP"
6364
6465
6566 if [ $ngx_found = yes ]; then
67
68 CORE_INCS="$CORE_INCS $ngx_feature_path"
6669 CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
70
71 if [ $NGX_IPV6 = YES ]; then
72 ngx_feature="GeoIP IPv6 support"
73 ngx_feature_name="NGX_HAVE_GEOIP_V6"
74 ngx_feature_run=no
75 ngx_feature_incs="#include <stdio.h>
76 #include <GeoIP.h>"
77 #ngx_feature_path=
78 #ngx_feature_libs=
79 ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);"
80 . auto/feature
81 fi
6782
6883 else
6984
3434 # NetBSD port
3535
3636 ngx_feature="GD library in /usr/pkg/"
37 ngx_feature_path="/usr/pkg/include/"
37 ngx_feature_path="/usr/pkg/include"
3838
3939 if [ $NGX_RPATH = YES ]; then
4040 ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lgd"
1010
1111 #include <GeoIP.h>
1212 #include <GeoIPCity.h>
13
14
15 #define NGX_GEOIP_COUNTRY_CODE 0
16 #define NGX_GEOIP_COUNTRY_CODE3 1
17 #define NGX_GEOIP_COUNTRY_NAME 2
1318
1419
1520 typedef struct {
1823 GeoIP *city;
1924 ngx_array_t *proxies; /* array of ngx_cidr_t */
2025 ngx_flag_t proxy_recursive;
26 #if (NGX_HAVE_GEOIP_V6)
27 unsigned country_v6:1;
28 unsigned org_v6:1;
29 unsigned city_v6:1;
30 #endif
2131 } ngx_http_geoip_conf_t;
2232
2333
2737 } ngx_http_geoip_var_t;
2838
2939
30 typedef char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
31
32 static u_long ngx_http_geoip_addr(ngx_http_request_t *r,
33 ngx_http_geoip_conf_t *gcf);
40 typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *,
41 u_long addr);
42
43
44 ngx_http_geoip_variable_handler_pt ngx_http_geoip_country_functions[] = {
45 GeoIP_country_code_by_ipnum,
46 GeoIP_country_code3_by_ipnum,
47 GeoIP_country_name_by_ipnum,
48 };
49
50
51 #if (NGX_HAVE_GEOIP_V6)
52
53 typedef const char *(*ngx_http_geoip_variable_handler_v6_pt)(GeoIP *,
54 geoipv6_t addr);
55
56
57 ngx_http_geoip_variable_handler_v6_pt ngx_http_geoip_country_v6_functions[] = {
58 GeoIP_country_code_by_ipnum_v6,
59 GeoIP_country_code3_by_ipnum_v6,
60 GeoIP_country_name_by_ipnum_v6,
61 };
62
63 #endif
64
65
3466 static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
3567 ngx_http_variable_value_t *v, uintptr_t data);
3668 static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r,
137169
138170 { ngx_string("geoip_country_code"), NULL,
139171 ngx_http_geoip_country_variable,
140 (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 },
172 NGX_GEOIP_COUNTRY_CODE, 0, 0 },
141173
142174 { ngx_string("geoip_country_code3"), NULL,
143175 ngx_http_geoip_country_variable,
144 (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 },
176 NGX_GEOIP_COUNTRY_CODE3, 0, 0 },
145177
146178 { ngx_string("geoip_country_name"), NULL,
147179 ngx_http_geoip_country_variable,
148 (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 },
180 NGX_GEOIP_COUNTRY_NAME, 0, 0 },
149181
150182 { ngx_string("geoip_org"), NULL,
151183 ngx_http_geoip_org_variable,
152 (uintptr_t) GeoIP_name_by_ipnum, 0, 0 },
184 0, 0, 0 },
153185
154186 { ngx_string("geoip_city_continent_code"), NULL,
155187 ngx_http_geoip_city_variable,
254286 }
255287
256288
289 #if (NGX_HAVE_GEOIP_V6)
290
291 static geoipv6_t
292 ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
293 {
294 ngx_addr_t addr;
295 ngx_table_elt_t *xfwd;
296 in_addr_t addr4;
297 struct in6_addr addr6;
298 struct sockaddr_in *sin;
299 struct sockaddr_in6 *sin6;
300
301 addr.sockaddr = r->connection->sockaddr;
302 addr.socklen = r->connection->socklen;
303 /* addr.name = r->connection->addr_text; */
304
305 xfwd = r->headers_in.x_forwarded_for;
306
307 if (xfwd != NULL && gcf->proxies != NULL) {
308 (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
309 xfwd->value.len, gcf->proxies,
310 gcf->proxy_recursive);
311 }
312
313 switch (addr.sockaddr->sa_family) {
314
315 case AF_INET:
316 /* Produce IPv4-mapped IPv6 address. */
317 sin = (struct sockaddr_in *) addr.sockaddr;
318 addr4 = ntohl(sin->sin_addr.s_addr);
319
320 ngx_memzero(&addr6, sizeof(struct in6_addr));
321 addr6.s6_addr[10] = 0xff;
322 addr6.s6_addr[11] = 0xff;
323 addr6.s6_addr[12] = addr4 >> 24;
324 addr6.s6_addr[13] = addr4 >> 16;
325 addr6.s6_addr[14] = addr4 >> 8;
326 addr6.s6_addr[15] = addr4;
327 return addr6;
328
329 case AF_INET6:
330 sin6 = (struct sockaddr_in6 *) addr.sockaddr;
331 return sin6->sin6_addr;
332
333 default:
334 return in6addr_any;
335 }
336 }
337
338 #endif
339
340
257341 static ngx_int_t
258342 ngx_http_geoip_country_variable(ngx_http_request_t *r,
259343 ngx_http_variable_value_t *v, uintptr_t data)
260344 {
261 ngx_http_geoip_variable_handler_pt handler =
262 (ngx_http_geoip_variable_handler_pt) data;
345 ngx_http_geoip_variable_handler_pt handler =
346 ngx_http_geoip_country_functions[data];
347 #if (NGX_HAVE_GEOIP_V6)
348 ngx_http_geoip_variable_handler_v6_pt handler_v6 =
349 ngx_http_geoip_country_v6_functions[data];
350 #endif
263351
264352 const char *val;
265353 ngx_http_geoip_conf_t *gcf;
270358 goto not_found;
271359 }
272360
361 #if (NGX_HAVE_GEOIP_V6)
362 val = gcf->country_v6
363 ? handler_v6(gcf->country, ngx_http_geoip_addr_v6(r, gcf))
364 : handler(gcf->country, ngx_http_geoip_addr(r, gcf));
365 #else
273366 val = handler(gcf->country, ngx_http_geoip_addr(r, gcf));
367 #endif
274368
275369 if (val == NULL) {
276370 goto not_found;
296390 ngx_http_geoip_org_variable(ngx_http_request_t *r,
297391 ngx_http_variable_value_t *v, uintptr_t data)
298392 {
299 ngx_http_geoip_variable_handler_pt handler =
300 (ngx_http_geoip_variable_handler_pt) data;
301
302393 size_t len;
303394 char *val;
304395 ngx_http_geoip_conf_t *gcf;
309400 goto not_found;
310401 }
311402
312 val = handler(gcf->org, ngx_http_geoip_addr(r, gcf));
403 #if (NGX_HAVE_GEOIP_V6)
404 val = gcf->org_v6
405 ? GeoIP_name_by_ipnum_v6(gcf->org,
406 ngx_http_geoip_addr_v6(r, gcf))
407 : GeoIP_name_by_ipnum(gcf->org,
408 ngx_http_geoip_addr(r, gcf));
409 #else
410 val = GeoIP_name_by_ipnum(gcf->org, ngx_http_geoip_addr(r, gcf));
411 #endif
313412
314413 if (val == NULL) {
315414 goto not_found;
499598 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
500599
501600 if (gcf->city) {
601 #if (NGX_HAVE_GEOIP_V6)
602 return gcf->city_v6
603 ? GeoIP_record_by_ipnum_v6(gcf->city,
604 ngx_http_geoip_addr_v6(r, gcf))
605 : GeoIP_record_by_ipnum(gcf->city,
606 ngx_http_geoip_addr(r, gcf));
607 #else
502608 return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
609 #endif
503610 }
504611
505612 return NULL;
597704 switch (gcf->country->databaseType) {
598705
599706 case GEOIP_COUNTRY_EDITION:
600 case GEOIP_PROXY_EDITION:
601 case GEOIP_NETSPEED_EDITION:
602707
603708 return NGX_CONF_OK;
709
710 #if (NGX_HAVE_GEOIP_V6)
711 case GEOIP_COUNTRY_EDITION_V6:
712
713 gcf->country_v6 = 1;
714 return NGX_CONF_OK;
715 #endif
604716
605717 default:
606718 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
653765
654766 return NGX_CONF_OK;
655767
768 #if (NGX_HAVE_GEOIP_V6)
769 case GEOIP_ISP_EDITION_V6:
770 case GEOIP_ORG_EDITION_V6:
771 case GEOIP_DOMAIN_EDITION_V6:
772 case GEOIP_ASNUM_EDITION_V6:
773
774 gcf->org_v6 = 1;
775 return NGX_CONF_OK;
776 #endif
777
656778 default:
657779 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
658780 "invalid GeoIP database \"%V\" type:%d",
702824
703825 return NGX_CONF_OK;
704826
827 #if (NGX_HAVE_GEOIP_V6)
828 case GEOIP_CITY_EDITION_REV0_V6:
829 case GEOIP_CITY_EDITION_REV1_V6:
830
831 gcf->city_v6 = 1;
832 return NGX_CONF_OK;
833 #endif
834
705835 default:
706836 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
707837 "invalid GeoIP City database \"%V\" type:%d",