20
ngx_array_t *proxies; /* array of ngx_cidr_t */
21
ngx_flag_t proxy_recursive;
20
22
} ngx_http_geoip_conf_t;
26
28
} ngx_http_geoip_var_t;
29
31
typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
33
static u_long ngx_http_geoip_addr(ngx_http_request_t *r,
34
ngx_http_geoip_conf_t *gcf);
31
35
static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
32
36
ngx_http_variable_value_t *v, uintptr_t data);
33
37
static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r,
45
49
static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
46
50
static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
51
static char *ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf);
47
52
static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
49
54
static char *ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd,
51
56
static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
58
static char *ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd,
60
static ngx_int_t ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
53
62
static void ngx_http_geoip_cleanup(void *data);
88
{ ngx_string("geoip_proxy"),
89
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
91
NGX_HTTP_MAIN_CONF_OFFSET,
95
{ ngx_string("geoip_proxy_recursive"),
96
NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
97
ngx_conf_set_flag_slot,
98
NGX_HTTP_MAIN_CONF_OFFSET,
99
offsetof(ngx_http_geoip_conf_t, proxy_recursive),
85
108
NULL, /* postconfiguration */
87
110
ngx_http_geoip_create_conf, /* create main configuration */
88
NULL, /* init main configuration */
111
ngx_http_geoip_init_conf, /* init main configuration */
90
113
NULL, /* create server configuration */
91
114
NULL, /* merge server configuration */
185
ngx_http_geoip_addr(ngx_http_request_t *r)
208
ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
187
struct sockaddr_in *sin;
191
struct sockaddr_in6 *sin6;
194
switch (r->connection->sockaddr->sa_family) {
197
sin = (struct sockaddr_in *) r->connection->sockaddr;
198
return ntohl(sin->sin_addr.s_addr);
203
sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
205
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
206
p = sin6->sin6_addr.s6_addr;
211
ngx_table_elt_t *xfwd;
212
struct sockaddr_in *sin;
214
addr.sockaddr = r->connection->sockaddr;
215
addr.socklen = r->connection->socklen;
216
/* addr.name = r->connection->addr_text; */
218
xfwd = r->headers_in.x_forwarded_for;
220
if (xfwd != NULL && gcf->proxies != NULL) {
221
(void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
222
xfwd->value.len, gcf->proxies,
223
gcf->proxy_recursive);
228
if (addr.sockaddr->sa_family == AF_INET6) {
229
struct in6_addr *inaddr6;
231
inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
233
if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
234
return ntohl(*(in_addr_t *) &inaddr6->s6_addr[12]);
240
if (addr.sockaddr->sa_family != AF_INET) {
244
sin = (struct sockaddr_in *) addr.sockaddr;
245
return ntohl(sin->sin_addr.s_addr);
453
480
gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
456
return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r));
483
return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
535
ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf)
537
ngx_http_geoip_conf_t *gcf = conf;
539
ngx_conf_init_value(gcf->proxy_recursive, 0);
506
546
ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
508
548
ngx_http_geoip_conf_t *gcf = conf;
696
ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
698
ngx_http_geoip_conf_t *gcf = conf;
703
value = cf->args->elts;
705
if (ngx_http_geoip_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
706
return NGX_CONF_ERROR;
709
if (gcf->proxies == NULL) {
710
gcf->proxies = ngx_array_create(cf->pool, 4, sizeof(ngx_cidr_t));
711
if (gcf->proxies == NULL) {
712
return NGX_CONF_ERROR;
716
c = ngx_array_push(gcf->proxies);
718
return NGX_CONF_ERROR;
727
ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
731
if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
732
cidr->family = AF_INET;
733
cidr->u.in.addr = 0xffffffff;
734
cidr->u.in.mask = 0xffffffff;
739
rc = ngx_ptocidr(net, cidr);
741
if (rc == NGX_ERROR) {
742
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
746
if (rc == NGX_DONE) {
747
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
748
"low address bits of %V are meaningless", net);
656
756
ngx_http_geoip_cleanup(void *data)