~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/http/modules/ngx_http_geoip_module.c

Version: ~ [ nginx-1.4.1 ] ~ [ nginx-1.5.0 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  * Copyright (C) Nginx, Inc.
  5  */
  6 
  7 
  8 #include <ngx_config.h>
  9 #include <ngx_core.h>
 10 #include <ngx_http.h>
 11 
 12 #include <GeoIP.h>
 13 #include <GeoIPCity.h>
 14 
 15 
 16 #define NGX_GEOIP_COUNTRY_CODE   0
 17 #define NGX_GEOIP_COUNTRY_CODE3  1
 18 #define NGX_GEOIP_COUNTRY_NAME   2
 19 
 20 
 21 typedef struct {
 22     GeoIP        *country;
 23     GeoIP        *org;
 24     GeoIP        *city;
 25     ngx_array_t  *proxies;    /* array of ngx_cidr_t */
 26     ngx_flag_t    proxy_recursive;
 27 #if (NGX_HAVE_GEOIP_V6)
 28     unsigned      country_v6:1;
 29     unsigned      org_v6:1;
 30     unsigned      city_v6:1;
 31 #endif
 32 } ngx_http_geoip_conf_t;
 33 
 34 
 35 typedef struct {
 36     ngx_str_t    *name;
 37     uintptr_t     data;
 38 } ngx_http_geoip_var_t;
 39 
 40 
 41 typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *,
 42     u_long addr);
 43 
 44 
 45 ngx_http_geoip_variable_handler_pt ngx_http_geoip_country_functions[] = {
 46     GeoIP_country_code_by_ipnum,
 47     GeoIP_country_code3_by_ipnum,
 48     GeoIP_country_name_by_ipnum,
 49 };
 50 
 51 
 52 #if (NGX_HAVE_GEOIP_V6)
 53 
 54 typedef const char *(*ngx_http_geoip_variable_handler_v6_pt)(GeoIP *,
 55     geoipv6_t addr);
 56 
 57 
 58 ngx_http_geoip_variable_handler_v6_pt ngx_http_geoip_country_v6_functions[] = {
 59     GeoIP_country_code_by_ipnum_v6,
 60     GeoIP_country_code3_by_ipnum_v6,
 61     GeoIP_country_name_by_ipnum_v6,
 62 };
 63 
 64 #endif
 65 
 66 
 67 static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
 68     ngx_http_variable_value_t *v, uintptr_t data);
 69 static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r,
 70     ngx_http_variable_value_t *v, uintptr_t data);
 71 static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r,
 72     ngx_http_variable_value_t *v, uintptr_t data);
 73 static ngx_int_t ngx_http_geoip_region_name_variable(ngx_http_request_t *r,
 74     ngx_http_variable_value_t *v, uintptr_t data);
 75 static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
 76     ngx_http_variable_value_t *v, uintptr_t data);
 77 static ngx_int_t ngx_http_geoip_city_int_variable(ngx_http_request_t *r,
 78     ngx_http_variable_value_t *v, uintptr_t data);
 79 static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r);
 80 
 81 static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
 82 static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
 83 static char *ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf);
 84 static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
 85     void *conf);
 86 static char *ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd,
 87     void *conf);
 88 static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
 89     void *conf);
 90 static char *ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd,
 91     void *conf);
 92 static ngx_int_t ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
 93     ngx_cidr_t *cidr);
 94 static void ngx_http_geoip_cleanup(void *data);
 95 
 96 
 97 static ngx_command_t  ngx_http_geoip_commands[] = {
 98 
 99     { ngx_string("geoip_country"),
100       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12,
101       ngx_http_geoip_country,
102       NGX_HTTP_MAIN_CONF_OFFSET,
103       0,
104       NULL },
105 
106     { ngx_string("geoip_org"),
107       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12,
108       ngx_http_geoip_org,
109       NGX_HTTP_MAIN_CONF_OFFSET,
110       0,
111       NULL },
112 
113     { ngx_string("geoip_city"),
114       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12,
115       ngx_http_geoip_city,
116       NGX_HTTP_MAIN_CONF_OFFSET,
117       0,
118       NULL },
119 
120     { ngx_string("geoip_proxy"),
121       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
122       ngx_http_geoip_proxy,
123       NGX_HTTP_MAIN_CONF_OFFSET,
124       0,
125       NULL },
126 
127     { ngx_string("geoip_proxy_recursive"),
128       NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
129       ngx_conf_set_flag_slot,
130       NGX_HTTP_MAIN_CONF_OFFSET,
131       offsetof(ngx_http_geoip_conf_t, proxy_recursive),
132       NULL },
133 
134       ngx_null_command
135 };
136 
137 
138 static ngx_http_module_t  ngx_http_geoip_module_ctx = {
139     ngx_http_geoip_add_variables,          /* preconfiguration */
140     NULL,                                  /* postconfiguration */
141 
142     ngx_http_geoip_create_conf,            /* create main configuration */
143     ngx_http_geoip_init_conf,              /* init main configuration */
144 
145     NULL,                                  /* create server configuration */
146     NULL,                                  /* merge server configuration */
147 
148     NULL,                                  /* create location configuration */
149     NULL                                   /* merge location configuration */
150 };
151 
152 
153 ngx_module_t  ngx_http_geoip_module = {
154     NGX_MODULE_V1,
155     &ngx_http_geoip_module_ctx,            /* module context */
156     ngx_http_geoip_commands,               /* module directives */
157     NGX_HTTP_MODULE,                       /* module type */
158     NULL,                                  /* init master */
159     NULL,                                  /* init module */
160     NULL,                                  /* init process */
161     NULL,                                  /* init thread */
162     NULL,                                  /* exit thread */
163     NULL,                                  /* exit process */
164     NULL,                                  /* exit master */
165     NGX_MODULE_V1_PADDING
166 };
167 
168 
169 static ngx_http_variable_t  ngx_http_geoip_vars[] = {
170 
171     { ngx_string("geoip_country_code"), NULL,
172       ngx_http_geoip_country_variable,
173       NGX_GEOIP_COUNTRY_CODE, 0, 0 },
174 
175     { ngx_string("geoip_country_code3"), NULL,
176       ngx_http_geoip_country_variable,
177       NGX_GEOIP_COUNTRY_CODE3, 0, 0 },
178 
179     { ngx_string("geoip_country_name"), NULL,
180       ngx_http_geoip_country_variable,
181       NGX_GEOIP_COUNTRY_NAME, 0, 0 },
182 
183     { ngx_string("geoip_org"), NULL,
184       ngx_http_geoip_org_variable,
185       0, 0, 0 },
186 
187     { ngx_string("geoip_city_continent_code"), NULL,
188       ngx_http_geoip_city_variable,
189       offsetof(GeoIPRecord, continent_code), 0, 0 },
190 
191     { ngx_string("geoip_city_country_code"), NULL,
192       ngx_http_geoip_city_variable,
193       offsetof(GeoIPRecord, country_code), 0, 0 },
194 
195     { ngx_string("geoip_city_country_code3"), NULL,
196       ngx_http_geoip_city_variable,
197       offsetof(GeoIPRecord, country_code3), 0, 0 },
198 
199     { ngx_string("geoip_city_country_name"), NULL,
200       ngx_http_geoip_city_variable,
201       offsetof(GeoIPRecord, country_name), 0, 0 },
202 
203     { ngx_string("geoip_region"), NULL,
204       ngx_http_geoip_city_variable,
205       offsetof(GeoIPRecord, region), 0, 0 },
206 
207     { ngx_string("geoip_region_name"), NULL,
208       ngx_http_geoip_region_name_variable,
209       0, 0, 0 },
210 
211     { ngx_string("geoip_city"), NULL,
212       ngx_http_geoip_city_variable,
213       offsetof(GeoIPRecord, city), 0, 0 },
214 
215     { ngx_string("geoip_postal_code"), NULL,
216       ngx_http_geoip_city_variable,
217       offsetof(GeoIPRecord, postal_code), 0, 0 },
218 
219     { ngx_string("geoip_latitude"), NULL,
220       ngx_http_geoip_city_float_variable,
221       offsetof(GeoIPRecord, latitude), 0, 0 },
222 
223     { ngx_string("geoip_longitude"), NULL,
224       ngx_http_geoip_city_float_variable,
225       offsetof(GeoIPRecord, longitude), 0, 0 },
226 
227     { ngx_string("geoip_dma_code"), NULL,
228       ngx_http_geoip_city_int_variable,
229       offsetof(GeoIPRecord, dma_code), 0, 0 },
230 
231     { ngx_string("geoip_area_code"), NULL,
232       ngx_http_geoip_city_int_variable,
233       offsetof(GeoIPRecord, area_code), 0, 0 },
234 
235     { ngx_null_string, NULL, NULL, 0, 0, 0 }
236 };
237 
238 
239 static u_long
240 ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
241 {
242     ngx_addr_t           addr;
243     ngx_array_t         *xfwd;
244     struct sockaddr_in  *sin;
245 
246     addr.sockaddr = r->connection->sockaddr;
247     addr.socklen = r->connection->socklen;
248     /* addr.name = r->connection->addr_text; */
249 
250     xfwd = &r->headers_in.x_forwarded_for;
251 
252     if (xfwd->nelts > 0 && gcf->proxies != NULL) {
253         (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
254                                            gcf->proxies, gcf->proxy_recursive);
255     }
256 
257 #if (NGX_HAVE_INET6)
258 
259     if (addr.sockaddr->sa_family == AF_INET6) {
260         u_char           *p;
261         in_addr_t         inaddr;
262         struct in6_addr  *inaddr6;
263 
264         inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
265 
266         if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
267             p = inaddr6->s6_addr;
268 
269             inaddr = p[12] << 24;
270             inaddr += p[13] << 16;
271             inaddr += p[14] << 8;
272             inaddr += p[15];
273 
274             return inaddr;
275         }
276     }
277 
278 #endif
279 
280     if (addr.sockaddr->sa_family != AF_INET) {
281         return INADDR_NONE;
282     }
283 
284     sin = (struct sockaddr_in *) addr.sockaddr;
285     return ntohl(sin->sin_addr.s_addr);
286 }
287 
288 
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_array_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->nelts > 0 && gcf->proxies != NULL) {
308         (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
309                                            gcf->proxies, gcf->proxy_recursive);
310     }
311 
312     switch (addr.sockaddr->sa_family) {
313 
314     case AF_INET:
315         /* Produce IPv4-mapped IPv6 address. */
316         sin = (struct sockaddr_in *) addr.sockaddr;
317         addr4 = ntohl(sin->sin_addr.s_addr);
318 
319         ngx_memzero(&addr6, sizeof(struct in6_addr));
320         addr6.s6_addr[10] = 0xff;
321         addr6.s6_addr[11] = 0xff;
322         addr6.s6_addr[12] = addr4 >> 24;
323         addr6.s6_addr[13] = addr4 >> 16;
324         addr6.s6_addr[14] = addr4 >> 8;
325         addr6.s6_addr[15] = addr4;
326         return addr6;
327 
328     case AF_INET6:
329         sin6 = (struct sockaddr_in6 *) addr.sockaddr;
330         return sin6->sin6_addr;
331 
332     default:
333         return in6addr_any;
334     }
335 }
336 
337 #endif
338 
339 
340 static ngx_int_t
341 ngx_http_geoip_country_variable(ngx_http_request_t *r,
342     ngx_http_variable_value_t *v, uintptr_t data)
343 {
344     ngx_http_geoip_variable_handler_pt     handler =
345         ngx_http_geoip_country_functions[data];
346 #if (NGX_HAVE_GEOIP_V6)
347     ngx_http_geoip_variable_handler_v6_pt  handler_v6 =
348         ngx_http_geoip_country_v6_functions[data];
349 #endif
350 
351     const char             *val;
352     ngx_http_geoip_conf_t  *gcf;
353 
354     gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
355 
356     if (gcf->country == NULL) {
357         goto not_found;
358     }
359 
360 #if (NGX_HAVE_GEOIP_V6)
361     val = gcf->country_v6
362               ? handler_v6(gcf->country, ngx_http_geoip_addr_v6(r, gcf))
363               : handler(gcf->country, ngx_http_geoip_addr(r, gcf));
364 #else
365     val = handler(gcf->country, ngx_http_geoip_addr(r, gcf));
366 #endif
367 
368     if (val == NULL) {
369         goto not_found;
370     }
371 
372     v->len = ngx_strlen(val);
373     v->valid = 1;
374     v->no_cacheable = 0;
375     v->not_found = 0;
376     v->data = (u_char *) val;
377 
378     return NGX_OK;
379 
380 not_found:
381 
382     v->not_found = 1;
383 
384     return NGX_OK;
385 }
386 
387 
388 static ngx_int_t
389 ngx_http_geoip_org_variable(ngx_http_request_t *r,
390     ngx_http_variable_value_t *v, uintptr_t data)
391 {
392     size_t                  len;
393     char                   *val;
394     ngx_http_geoip_conf_t  *gcf;
395 
396     gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
397 
398     if (gcf->org == NULL) {
399         goto not_found;
400     }
401 
402 #if (NGX_HAVE_GEOIP_V6)
403     val = gcf->org_v6
404               ? GeoIP_name_by_ipnum_v6(gcf->org,
405                                        ngx_http_geoip_addr_v6(r, gcf))
406               : GeoIP_name_by_ipnum(gcf->org,
407                                     ngx_http_geoip_addr(r, gcf));
408 #else
409     val = GeoIP_name_by_ipnum(gcf->org, ngx_http_geoip_addr(r, gcf));
410 #endif
411 
412     if (val == NULL) {
413         goto not_found;
414     }
415 
416     len = ngx_strlen(val);
417     v->data = ngx_pnalloc(r->pool, len);
418     if (v->data == NULL) {
419         ngx_free(val);
420         return NGX_ERROR;
421     }
422 
423     ngx_memcpy(v->data, val, len);
424 
425     v->len = len;
426     v->valid = 1;
427     v->no_cacheable = 0;
428     v->not_found = 0;
429 
430     ngx_free(val);
431 
432     return NGX_OK;
433 
434 not_found:
435 
436     v->not_found = 1;
437 
438     return NGX_OK;
439 }
440 
441 
442 static ngx_int_t
443 ngx_http_geoip_city_variable(ngx_http_request_t *r,
444     ngx_http_variable_value_t *v, uintptr_t data)
445 {
446     char         *val;
447     size_t        len;
448     GeoIPRecord  *gr;
449 
450     gr = ngx_http_geoip_get_city_record(r);
451     if (gr == NULL) {
452         goto not_found;
453     }
454 
455     val = *(char **) ((char *) gr + data);
456     if (val == NULL) {
457         goto no_value;
458     }
459 
460     len = ngx_strlen(val);
461     v->data = ngx_pnalloc(r->pool, len);
462     if (v->data == NULL) {
463         GeoIPRecord_delete(gr);
464         return NGX_ERROR;
465     }
466 
467     ngx_memcpy(v->data, val, len);
468 
469     v->len = len;
470     v->valid = 1;
471     v->no_cacheable = 0;
472     v->not_found = 0;
473 
474     GeoIPRecord_delete(gr);
475 
476     return NGX_OK;
477 
478 no_value:
479 
480     GeoIPRecord_delete(gr);
481 
482 not_found:
483 
484     v->not_found = 1;
485 
486     return NGX_OK;
487 }
488 
489 
490 static ngx_int_t
491 ngx_http_geoip_region_name_variable(ngx_http_request_t *r,
492     ngx_http_variable_value_t *v, uintptr_t data)
493 {
494     size_t        len;
495     const char   *val;
496     GeoIPRecord  *gr;
497 
498     gr = ngx_http_geoip_get_city_record(r);
499     if (gr == NULL) {
500         goto not_found;
501     }
502 
503     val = GeoIP_region_name_by_code(gr->country_code, gr->region);
504 
505     GeoIPRecord_delete(gr);
506 
507     if (val == NULL) {
508         goto not_found;
509     }
510 
511     len = ngx_strlen(val);
512     v->data = ngx_pnalloc(r->pool, len);
513     if (v->data == NULL) {
514         return NGX_ERROR;
515     }
516 
517     ngx_memcpy(v->data, val, len);
518 
519     v->len = len;
520     v->valid = 1;
521     v->no_cacheable = 0;
522     v->not_found = 0;
523 
524     return NGX_OK;
525 
526 not_found:
527 
528     v->not_found = 1;
529 
530     return NGX_OK;
531 }
532 
533 
534 static ngx_int_t
535 ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
536     ngx_http_variable_value_t *v, uintptr_t data)
537 {
538     float         val;
539     GeoIPRecord  *gr;
540 
541     gr = ngx_http_geoip_get_city_record(r);
542     if (gr == NULL) {
543         v->not_found = 1;
544         return NGX_OK;
545     }
546 
547     v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN + 5);
548     if (v->data == NULL) {
549         GeoIPRecord_delete(gr);
550         return NGX_ERROR;
551     }
552 
553     val = *(float *) ((char *) gr + data);
554 
555     v->len = ngx_sprintf(v->data, "%.4f", val) - v->data;
556 
557     GeoIPRecord_delete(gr);
558 
559     return NGX_OK;
560 }
561 
562 
563 static ngx_int_t
564 ngx_http_geoip_city_int_variable(ngx_http_request_t *r,
565     ngx_http_variable_value_t *v, uintptr_t data)
566 {
567     int           val;
568     GeoIPRecord  *gr;
569 
570     gr = ngx_http_geoip_get_city_record(r);
571     if (gr == NULL) {
572         v->not_found = 1;
573         return NGX_OK;
574     }
575 
576     v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN);
577     if (v->data == NULL) {
578         GeoIPRecord_delete(gr);
579         return NGX_ERROR;
580     }
581 
582     val = *(int *) ((char *) gr + data);
583 
584     v->len = ngx_sprintf(v->data, "%d", val) - v->data;
585 
586     GeoIPRecord_delete(gr);
587 
588     return NGX_OK;
589 }
590 
591 
592 static GeoIPRecord *
593 ngx_http_geoip_get_city_record(ngx_http_request_t *r)
594 {
595     ngx_http_geoip_conf_t  *gcf;
596 
597     gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
598 
599     if (gcf->city) {
600 #if (NGX_HAVE_GEOIP_V6)
601         return gcf->city_v6
602                    ? GeoIP_record_by_ipnum_v6(gcf->city,
603                                               ngx_http_geoip_addr_v6(r, gcf))
604                    : GeoIP_record_by_ipnum(gcf->city,
605                                            ngx_http_geoip_addr(r, gcf));
606 #else
607         return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
608 #endif
609     }
610 
611     return NULL;
612 }
613 
614 
615 static ngx_int_t
616 ngx_http_geoip_add_variables(ngx_conf_t *cf)
617 {
618     ngx_http_variable_t  *var, *v;
619 
620     for (v = ngx_http_geoip_vars; v->name.len; v++) {
621         var = ngx_http_add_variable(cf, &v->name, v->flags);
622         if (var == NULL) {
623             return NGX_ERROR;
624         }
625 
626         var->get_handler = v->get_handler;
627         var->data = v->data;
628     }
629 
630     return NGX_OK;
631 }
632 
633 
634 static void *
635 ngx_http_geoip_create_conf(ngx_conf_t *cf)
636 {
637     ngx_pool_cleanup_t     *cln;
638     ngx_http_geoip_conf_t  *conf;
639 
640     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_geoip_conf_t));
641     if (conf == NULL) {
642         return NULL;
643     }
644 
645     conf->proxy_recursive = NGX_CONF_UNSET;
646 
647     cln = ngx_pool_cleanup_add(cf->pool, 0);
648     if (cln == NULL) {
649         return NULL;
650     }
651 
652     cln->handler = ngx_http_geoip_cleanup;
653     cln->data = conf;
654 
655     return conf;
656 }
657 
658 
659 static char *
660 ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf)
661 {
662     ngx_http_geoip_conf_t  *gcf = conf;
663 
664     ngx_conf_init_value(gcf->proxy_recursive, 0);
665 
666     return NGX_CONF_OK;
667 }
668 
669 
670 static char *
671 ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
672 {
673     ngx_http_geoip_conf_t  *gcf = conf;
674 
675     ngx_str_t  *value;
676 
677     if (gcf->country) {
678         return "is duplicate";
679     }
680 
681     value = cf->args->elts;
682 
683     gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
684 
685     if (gcf->country == NULL) {
686         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
687                            "GeoIP_open(\"%V\") failed", &value[1]);
688 
689         return NGX_CONF_ERROR;
690     }
691 
692     if (cf->args->nelts == 3) {
693         if (ngx_strcmp(value[2].data, "utf8") == 0) {
694             GeoIP_set_charset (gcf->country, GEOIP_CHARSET_UTF8);
695 
696         } else {
697             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
698                                "invalid parameter \"%V\"", &value[2]);
699             return NGX_CONF_ERROR;
700         }
701     }
702 
703     switch (gcf->country->databaseType) {
704 
705     case GEOIP_COUNTRY_EDITION:
706 
707         return NGX_CONF_OK;
708 
709 #if (NGX_HAVE_GEOIP_V6)
710     case GEOIP_COUNTRY_EDITION_V6:
711 
712         gcf->country_v6 = 1;
713         return NGX_CONF_OK;
714 #endif
715 
716     default:
717         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
718                            "invalid GeoIP database \"%V\" type:%d",
719                            &value[1], gcf->country->databaseType);
720         return NGX_CONF_ERROR;
721     }
722 }
723 
724 
725 static char *
726 ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
727 {
728     ngx_http_geoip_conf_t  *gcf = conf;
729 
730     ngx_str_t  *value;
731 
732     if (gcf->org) {
733         return "is duplicate";
734     }
735 
736     value = cf->args->elts;
737 
738     gcf->org = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
739 
740     if (gcf->org == NULL) {
741         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
742                            "GeoIP_open(\"%V\") failed", &value[1]);
743 
744         return NGX_CONF_ERROR;
745     }
746 
747     if (cf->args->nelts == 3) {
748         if (ngx_strcmp(value[2].data, "utf8") == 0) {
749             GeoIP_set_charset (gcf->org, GEOIP_CHARSET_UTF8);
750 
751         } else {
752             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
753                                "invalid parameter \"%V\"", &value[2]);
754             return NGX_CONF_ERROR;
755         }
756     }
757 
758     switch (gcf->org->databaseType) {
759 
760     case GEOIP_ISP_EDITION:
761     case GEOIP_ORG_EDITION:
762     case GEOIP_DOMAIN_EDITION:
763     case GEOIP_ASNUM_EDITION:
764 
765         return NGX_CONF_OK;
766 
767 #if (NGX_HAVE_GEOIP_V6)
768     case GEOIP_ISP_EDITION_V6:
769     case GEOIP_ORG_EDITION_V6:
770     case GEOIP_DOMAIN_EDITION_V6:
771     case GEOIP_ASNUM_EDITION_V6:
772 
773         gcf->org_v6 = 1;
774         return NGX_CONF_OK;
775 #endif
776 
777     default:
778         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
779                            "invalid GeoIP database \"%V\" type:%d",
780                            &value[1], gcf->org->databaseType);
781         return NGX_CONF_ERROR;
782     }
783 }
784 
785 
786 static char *
787 ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
788 {
789     ngx_http_geoip_conf_t  *gcf = conf;
790 
791     ngx_str_t  *value;
792 
793     if (gcf->city) {
794         return "is duplicate";
795     }
796 
797     value = cf->args->elts;
798 
799     gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
800 
801     if (gcf->city == NULL) {
802         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
803                            "GeoIP_open(\"%V\") failed", &value[1]);
804 
805         return NGX_CONF_ERROR;
806     }
807 
808     if (cf->args->nelts == 3) {
809         if (ngx_strcmp(value[2].data, "utf8") == 0) {
810             GeoIP_set_charset (gcf->city, GEOIP_CHARSET_UTF8);
811 
812         } else {
813             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
814                                "invalid parameter \"%V\"", &value[2]);
815             return NGX_CONF_ERROR;
816         }
817     }
818 
819     switch (gcf->city->databaseType) {
820 
821     case GEOIP_CITY_EDITION_REV0:
822     case GEOIP_CITY_EDITION_REV1:
823 
824         return NGX_CONF_OK;
825 
826 #if (NGX_HAVE_GEOIP_V6)
827     case GEOIP_CITY_EDITION_REV0_V6:
828     case GEOIP_CITY_EDITION_REV1_V6:
829 
830         gcf->city_v6 = 1;
831         return NGX_CONF_OK;
832 #endif
833 
834     default:
835         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
836                            "invalid GeoIP City database \"%V\" type:%d",
837                            &value[1], gcf->city->databaseType);
838         return NGX_CONF_ERROR;
839     }
840 }
841 
842 
843 static char *
844 ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
845 {
846     ngx_http_geoip_conf_t  *gcf = conf;
847 
848     ngx_str_t   *value;
849     ngx_cidr_t  cidr, *c;
850 
851     value = cf->args->elts;
852 
853     if (ngx_http_geoip_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
854         return NGX_CONF_ERROR;
855     }
856 
857     if (gcf->proxies == NULL) {
858         gcf->proxies = ngx_array_create(cf->pool, 4, sizeof(ngx_cidr_t));
859         if (gcf->proxies == NULL) {
860             return NGX_CONF_ERROR;
861         }
862     }
863 
864     c = ngx_array_push(gcf->proxies);
865     if (c == NULL) {
866         return NGX_CONF_ERROR;
867     }
868 
869     *c = cidr;
870 
871     return NGX_CONF_OK;
872 }
873 
874 static ngx_int_t
875 ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
876 {
877     ngx_int_t  rc;
878 
879     if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
880         cidr->family = AF_INET;
881         cidr->u.in.addr = 0xffffffff;
882         cidr->u.in.mask = 0xffffffff;
883 
884         return NGX_OK;
885     }
886 
887     rc = ngx_ptocidr(net, cidr);
888 
889     if (rc == NGX_ERROR) {
890         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
891         return NGX_ERROR;
892     }
893 
894     if (rc == NGX_DONE) {
895         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
896                            "low address bits of %V are meaningless", net);
897     }
898 
899     return NGX_OK;
900 }
901 
902 
903 static void
904 ngx_http_geoip_cleanup(void *data)
905 {
906     ngx_http_geoip_conf_t  *gcf = data;
907 
908     if (gcf->country) {
909         GeoIP_delete(gcf->country);
910     }
911 
912     if (gcf->org) {
913         GeoIP_delete(gcf->org);
914     }
915 
916     if (gcf->city) {
917         GeoIP_delete(gcf->city);
918     }
919 }
920 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.