Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream_geoip_module.c @ 8531:41f4bd4c51f1
Disabled control characters and space in header names.
Control characters (0x00-0x1f, 0x7f), space, and colon were never allowed in
header names. The only somewhat valid use is header continuation which nginx
never supported and which is explicitly obsolete by RFC 7230.
Previously, such headers were considered invalid and were ignored by default
(as per ignore_invalid_headers directive). With this change, such headers
are unconditionally rejected.
It is expected to make nginx more resilient to various attacks, in particular,
with ignore_invalid_headers switched off (which is inherently unsecure, though
nevertheless sometimes used in the wild).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 28 Jun 2021 18:01:18 +0300 |
parents | 2a288909abc6 |
children |
rev | line source |
---|---|
2985 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
2985 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
6630 | 10 #include <ngx_stream.h> |
2985 | 11 |
12 #include <GeoIP.h> | |
13 #include <GeoIPCity.h> | |
14 | |
15 | |
5015 | 16 #define NGX_GEOIP_COUNTRY_CODE 0 |
17 #define NGX_GEOIP_COUNTRY_CODE3 1 | |
18 #define NGX_GEOIP_COUNTRY_NAME 2 | |
19 | |
20 | |
2985 | 21 typedef struct { |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
22 GeoIP *country; |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
23 GeoIP *org; |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
24 GeoIP *city; |
5015 | 25 #if (NGX_HAVE_GEOIP_V6) |
26 unsigned country_v6:1; | |
27 unsigned org_v6:1; | |
28 unsigned city_v6:1; | |
29 #endif | |
6630 | 30 } ngx_stream_geoip_conf_t; |
2985 | 31 |
32 | |
33 typedef struct { | |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
34 ngx_str_t *name; |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
35 uintptr_t data; |
6630 | 36 } ngx_stream_geoip_var_t; |
2985 | 37 |
38 | |
6630 | 39 typedef const char *(*ngx_stream_geoip_variable_handler_pt)(GeoIP *, |
5015 | 40 u_long addr); |
41 | |
42 | |
6630 | 43 ngx_stream_geoip_variable_handler_pt ngx_stream_geoip_country_functions[] = { |
5015 | 44 GeoIP_country_code_by_ipnum, |
45 GeoIP_country_code3_by_ipnum, | |
46 GeoIP_country_name_by_ipnum, | |
47 }; | |
48 | |
49 | |
50 #if (NGX_HAVE_GEOIP_V6) | |
2985 | 51 |
6630 | 52 typedef const char *(*ngx_stream_geoip_variable_handler_v6_pt)(GeoIP *, |
5015 | 53 geoipv6_t addr); |
54 | |
55 | |
6630 | 56 ngx_stream_geoip_variable_handler_v6_pt |
57 ngx_stream_geoip_country_v6_functions[] = | |
58 { | |
5015 | 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 | |
6630 | 67 static ngx_int_t ngx_stream_geoip_country_variable(ngx_stream_session_t *s, |
68 ngx_stream_variable_value_t *v, uintptr_t data); | |
69 static ngx_int_t ngx_stream_geoip_org_variable(ngx_stream_session_t *s, | |
70 ngx_stream_variable_value_t *v, uintptr_t data); | |
71 static ngx_int_t ngx_stream_geoip_city_variable(ngx_stream_session_t *s, | |
72 ngx_stream_variable_value_t *v, uintptr_t data); | |
73 static ngx_int_t ngx_stream_geoip_region_name_variable(ngx_stream_session_t *s, | |
74 ngx_stream_variable_value_t *v, uintptr_t data); | |
75 static ngx_int_t ngx_stream_geoip_city_float_variable(ngx_stream_session_t *s, | |
76 ngx_stream_variable_value_t *v, uintptr_t data); | |
77 static ngx_int_t ngx_stream_geoip_city_int_variable(ngx_stream_session_t *s, | |
78 ngx_stream_variable_value_t *v, uintptr_t data); | |
79 static GeoIPRecord *ngx_stream_geoip_get_city_record(ngx_stream_session_t *s); | |
2985 | 80 |
6630 | 81 static ngx_int_t ngx_stream_geoip_add_variables(ngx_conf_t *cf); |
82 static void *ngx_stream_geoip_create_conf(ngx_conf_t *cf); | |
83 static char *ngx_stream_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, | |
3915 | 84 void *conf); |
6630 | 85 static char *ngx_stream_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
86 void *conf); |
6630 | 87 static char *ngx_stream_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, |
88 void *conf); | |
89 static void ngx_stream_geoip_cleanup(void *data); | |
2985 | 90 |
91 | |
6630 | 92 static ngx_command_t ngx_stream_geoip_commands[] = { |
2985 | 93 |
94 { ngx_string("geoip_country"), | |
6630 | 95 NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12, |
96 ngx_stream_geoip_country, | |
97 NGX_STREAM_MAIN_CONF_OFFSET, | |
2985 | 98 0, |
99 NULL }, | |
100 | |
3915 | 101 { ngx_string("geoip_org"), |
6630 | 102 NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12, |
103 ngx_stream_geoip_org, | |
104 NGX_STREAM_MAIN_CONF_OFFSET, | |
3915 | 105 0, |
106 NULL }, | |
107 | |
2985 | 108 { ngx_string("geoip_city"), |
6630 | 109 NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE12, |
110 ngx_stream_geoip_city, | |
111 NGX_STREAM_MAIN_CONF_OFFSET, | |
2985 | 112 0, |
113 NULL }, | |
114 | |
115 ngx_null_command | |
116 }; | |
117 | |
118 | |
6630 | 119 static ngx_stream_module_t ngx_stream_geoip_module_ctx = { |
120 ngx_stream_geoip_add_variables, /* preconfiguration */ | |
2985 | 121 NULL, /* postconfiguration */ |
122 | |
6630 | 123 ngx_stream_geoip_create_conf, /* create main configuration */ |
124 NULL, /* init main configuration */ | |
2985 | 125 |
126 NULL, /* create server configuration */ | |
6630 | 127 NULL /* merge server configuration */ |
2985 | 128 }; |
129 | |
130 | |
6630 | 131 ngx_module_t ngx_stream_geoip_module = { |
2985 | 132 NGX_MODULE_V1, |
6630 | 133 &ngx_stream_geoip_module_ctx, /* module context */ |
134 ngx_stream_geoip_commands, /* module directives */ | |
135 NGX_STREAM_MODULE, /* module type */ | |
2985 | 136 NULL, /* init master */ |
137 NULL, /* init module */ | |
138 NULL, /* init process */ | |
139 NULL, /* init thread */ | |
140 NULL, /* exit thread */ | |
141 NULL, /* exit process */ | |
142 NULL, /* exit master */ | |
143 NGX_MODULE_V1_PADDING | |
144 }; | |
145 | |
146 | |
6630 | 147 static ngx_stream_variable_t ngx_stream_geoip_vars[] = { |
2985 | 148 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
149 { ngx_string("geoip_country_code"), NULL, |
6630 | 150 ngx_stream_geoip_country_variable, |
5015 | 151 NGX_GEOIP_COUNTRY_CODE, 0, 0 }, |
2985 | 152 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
153 { ngx_string("geoip_country_code3"), NULL, |
6630 | 154 ngx_stream_geoip_country_variable, |
5015 | 155 NGX_GEOIP_COUNTRY_CODE3, 0, 0 }, |
2985 | 156 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
157 { ngx_string("geoip_country_name"), NULL, |
6630 | 158 ngx_stream_geoip_country_variable, |
5015 | 159 NGX_GEOIP_COUNTRY_NAME, 0, 0 }, |
2985 | 160 |
3915 | 161 { ngx_string("geoip_org"), NULL, |
6630 | 162 ngx_stream_geoip_org_variable, |
5015 | 163 0, 0, 0 }, |
3915 | 164 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
165 { ngx_string("geoip_city_continent_code"), NULL, |
6630 | 166 ngx_stream_geoip_city_variable, |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
167 offsetof(GeoIPRecord, continent_code), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
168 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
169 { ngx_string("geoip_city_country_code"), NULL, |
6630 | 170 ngx_stream_geoip_city_variable, |
2985 | 171 offsetof(GeoIPRecord, country_code), 0, 0 }, |
172 | |
173 { ngx_string("geoip_city_country_code3"), NULL, | |
6630 | 174 ngx_stream_geoip_city_variable, |
2985 | 175 offsetof(GeoIPRecord, country_code3), 0, 0 }, |
176 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
177 { ngx_string("geoip_city_country_name"), NULL, |
6630 | 178 ngx_stream_geoip_city_variable, |
2985 | 179 offsetof(GeoIPRecord, country_name), 0, 0 }, |
180 | |
181 { ngx_string("geoip_region"), NULL, | |
6630 | 182 ngx_stream_geoip_city_variable, |
2985 | 183 offsetof(GeoIPRecord, region), 0, 0 }, |
184 | |
3737 | 185 { ngx_string("geoip_region_name"), NULL, |
6630 | 186 ngx_stream_geoip_region_name_variable, |
3737 | 187 0, 0, 0 }, |
188 | |
2985 | 189 { ngx_string("geoip_city"), NULL, |
6630 | 190 ngx_stream_geoip_city_variable, |
2985 | 191 offsetof(GeoIPRecord, city), 0, 0 }, |
192 | |
193 { ngx_string("geoip_postal_code"), NULL, | |
6630 | 194 ngx_stream_geoip_city_variable, |
2985 | 195 offsetof(GeoIPRecord, postal_code), 0, 0 }, |
196 | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
197 { ngx_string("geoip_latitude"), NULL, |
6630 | 198 ngx_stream_geoip_city_float_variable, |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
199 offsetof(GeoIPRecord, latitude), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
200 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
201 { ngx_string("geoip_longitude"), NULL, |
6630 | 202 ngx_stream_geoip_city_float_variable, |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
203 offsetof(GeoIPRecord, longitude), 0, 0 }, |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
204 |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
205 { ngx_string("geoip_dma_code"), NULL, |
6630 | 206 ngx_stream_geoip_city_int_variable, |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
207 offsetof(GeoIPRecord, dma_code), 0, 0 }, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
208 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
209 { ngx_string("geoip_area_code"), NULL, |
6630 | 210 ngx_stream_geoip_city_int_variable, |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
211 offsetof(GeoIPRecord, area_code), 0, 0 }, |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
212 |
7077
2a288909abc6
Variables: macros for null variables.
Ruslan Ermilov <ru@nginx.com>
parents:
6630
diff
changeset
|
213 ngx_stream_null_variable |
2985 | 214 }; |
215 | |
216 | |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
217 static u_long |
6630 | 218 ngx_stream_geoip_addr(ngx_stream_session_t *s, ngx_stream_geoip_conf_t *gcf) |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
219 { |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
220 ngx_addr_t addr; |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
221 struct sockaddr_in *sin; |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
222 |
6630 | 223 addr.sockaddr = s->connection->sockaddr; |
224 addr.socklen = s->connection->socklen; | |
225 /* addr.name = s->connection->addr_text; */ | |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
226 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
227 #if (NGX_HAVE_INET6) |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
228 |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
229 if (addr.sockaddr->sa_family == AF_INET6) { |
4828
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
230 u_char *p; |
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
231 in_addr_t inaddr; |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
232 struct in6_addr *inaddr6; |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
233 |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
234 inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr; |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
235 |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
236 if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { |
4828
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
237 p = inaddr6->s6_addr; |
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
238 |
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
239 inaddr = p[12] << 24; |
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
240 inaddr += p[13] << 16; |
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
241 inaddr += p[14] << 8; |
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
242 inaddr += p[15]; |
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
243 |
f57154322e0e
Fixed strict aliasing bugs when dealing with IPv4-mapped IPv6 addresses
Ruslan Ermilov <ru@nginx.com>
parents:
4649
diff
changeset
|
244 return inaddr; |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
245 } |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
246 } |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
247 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
248 #endif |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
249 |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
250 if (addr.sockaddr->sa_family != AF_INET) { |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
251 return INADDR_NONE; |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
252 } |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
253 |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
254 sin = (struct sockaddr_in *) addr.sockaddr; |
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
255 return ntohl(sin->sin_addr.s_addr); |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
256 } |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
257 |
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
258 |
5015 | 259 #if (NGX_HAVE_GEOIP_V6) |
260 | |
261 static geoipv6_t | |
6630 | 262 ngx_stream_geoip_addr_v6(ngx_stream_session_t *s, ngx_stream_geoip_conf_t *gcf) |
5015 | 263 { |
264 ngx_addr_t addr; | |
265 in_addr_t addr4; | |
266 struct in6_addr addr6; | |
267 struct sockaddr_in *sin; | |
268 struct sockaddr_in6 *sin6; | |
269 | |
6630 | 270 addr.sockaddr = s->connection->sockaddr; |
271 addr.socklen = s->connection->socklen; | |
272 /* addr.name = s->connection->addr_text; */ | |
5015 | 273 |
274 switch (addr.sockaddr->sa_family) { | |
275 | |
276 case AF_INET: | |
277 /* Produce IPv4-mapped IPv6 address. */ | |
278 sin = (struct sockaddr_in *) addr.sockaddr; | |
279 addr4 = ntohl(sin->sin_addr.s_addr); | |
280 | |
281 ngx_memzero(&addr6, sizeof(struct in6_addr)); | |
282 addr6.s6_addr[10] = 0xff; | |
283 addr6.s6_addr[11] = 0xff; | |
284 addr6.s6_addr[12] = addr4 >> 24; | |
285 addr6.s6_addr[13] = addr4 >> 16; | |
286 addr6.s6_addr[14] = addr4 >> 8; | |
287 addr6.s6_addr[15] = addr4; | |
288 return addr6; | |
289 | |
290 case AF_INET6: | |
291 sin6 = (struct sockaddr_in6 *) addr.sockaddr; | |
292 return sin6->sin6_addr; | |
293 | |
294 default: | |
295 return in6addr_any; | |
296 } | |
297 } | |
298 | |
299 #endif | |
300 | |
301 | |
2985 | 302 static ngx_int_t |
6630 | 303 ngx_stream_geoip_country_variable(ngx_stream_session_t *s, |
304 ngx_stream_variable_value_t *v, uintptr_t data) | |
2985 | 305 { |
6630 | 306 ngx_stream_geoip_variable_handler_pt handler = |
307 ngx_stream_geoip_country_functions[data]; | |
5015 | 308 #if (NGX_HAVE_GEOIP_V6) |
6630 | 309 ngx_stream_geoip_variable_handler_v6_pt handler_v6 = |
310 ngx_stream_geoip_country_v6_functions[data]; | |
5015 | 311 #endif |
2985 | 312 |
6630 | 313 const char *val; |
314 ngx_stream_geoip_conf_t *gcf; | |
2985 | 315 |
6630 | 316 gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module); |
2985 | 317 |
318 if (gcf->country == NULL) { | |
319 goto not_found; | |
320 } | |
321 | |
5015 | 322 #if (NGX_HAVE_GEOIP_V6) |
323 val = gcf->country_v6 | |
6630 | 324 ? handler_v6(gcf->country, ngx_stream_geoip_addr_v6(s, gcf)) |
325 : handler(gcf->country, ngx_stream_geoip_addr(s, gcf)); | |
5015 | 326 #else |
6630 | 327 val = handler(gcf->country, ngx_stream_geoip_addr(s, gcf)); |
5015 | 328 #endif |
2985 | 329 |
330 if (val == NULL) { | |
331 goto not_found; | |
332 } | |
333 | |
334 v->len = ngx_strlen(val); | |
335 v->valid = 1; | |
336 v->no_cacheable = 0; | |
337 v->not_found = 0; | |
338 v->data = (u_char *) val; | |
339 | |
340 return NGX_OK; | |
341 | |
342 not_found: | |
343 | |
344 v->not_found = 1; | |
345 | |
346 return NGX_OK; | |
347 } | |
348 | |
349 | |
350 static ngx_int_t | |
6630 | 351 ngx_stream_geoip_org_variable(ngx_stream_session_t *s, |
352 ngx_stream_variable_value_t *v, uintptr_t data) | |
3915 | 353 { |
6630 | 354 size_t len; |
355 char *val; | |
356 ngx_stream_geoip_conf_t *gcf; | |
3915 | 357 |
6630 | 358 gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module); |
3915 | 359 |
360 if (gcf->org == NULL) { | |
361 goto not_found; | |
362 } | |
363 | |
5015 | 364 #if (NGX_HAVE_GEOIP_V6) |
365 val = gcf->org_v6 | |
366 ? GeoIP_name_by_ipnum_v6(gcf->org, | |
6630 | 367 ngx_stream_geoip_addr_v6(s, gcf)) |
5015 | 368 : GeoIP_name_by_ipnum(gcf->org, |
6630 | 369 ngx_stream_geoip_addr(s, gcf)); |
5015 | 370 #else |
6630 | 371 val = GeoIP_name_by_ipnum(gcf->org, ngx_stream_geoip_addr(s, gcf)); |
5015 | 372 #endif |
3915 | 373 |
374 if (val == NULL) { | |
375 goto not_found; | |
376 } | |
377 | |
4647
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
378 len = ngx_strlen(val); |
6630 | 379 v->data = ngx_pnalloc(s->connection->pool, len); |
4647
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
380 if (v->data == NULL) { |
4649
95d93f7e6fa2
geoip: got rid of ugly casts when calling ngx_free().
Ruslan Ermilov <ru@nginx.com>
parents:
4648
diff
changeset
|
381 ngx_free(val); |
4647
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
382 return NGX_ERROR; |
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
383 } |
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
384 |
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
385 ngx_memcpy(v->data, val, len); |
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
386 |
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
387 v->len = len; |
3915 | 388 v->valid = 1; |
389 v->no_cacheable = 0; | |
390 v->not_found = 0; | |
4647
a321eadcb16c
Fixed memory leak if $geoip_org variable was used.
Ruslan Ermilov <ru@nginx.com>
parents:
4627
diff
changeset
|
391 |
4649
95d93f7e6fa2
geoip: got rid of ugly casts when calling ngx_free().
Ruslan Ermilov <ru@nginx.com>
parents:
4648
diff
changeset
|
392 ngx_free(val); |
3915 | 393 |
394 return NGX_OK; | |
395 | |
396 not_found: | |
397 | |
398 v->not_found = 1; | |
399 | |
400 return NGX_OK; | |
401 } | |
402 | |
403 | |
404 static ngx_int_t | |
6630 | 405 ngx_stream_geoip_city_variable(ngx_stream_session_t *s, |
406 ngx_stream_variable_value_t *v, uintptr_t data) | |
2985 | 407 { |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
408 char *val; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
409 size_t len; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
410 GeoIPRecord *gr; |
2985 | 411 |
6630 | 412 gr = ngx_stream_geoip_get_city_record(s); |
2985 | 413 if (gr == NULL) { |
414 goto not_found; | |
415 } | |
416 | |
417 val = *(char **) ((char *) gr + data); | |
418 if (val == NULL) { | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
419 goto no_value; |
2985 | 420 } |
421 | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
422 len = ngx_strlen(val); |
6630 | 423 v->data = ngx_pnalloc(s->connection->pool, len); |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
424 if (v->data == NULL) { |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
425 GeoIPRecord_delete(gr); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
426 return NGX_ERROR; |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
427 } |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
428 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
429 ngx_memcpy(v->data, val, len); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
430 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
431 v->len = len; |
2985 | 432 v->valid = 1; |
433 v->no_cacheable = 0; | |
434 v->not_found = 0; | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
435 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
436 GeoIPRecord_delete(gr); |
2985 | 437 |
438 return NGX_OK; | |
439 | |
3031
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
440 no_value: |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
441 |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
442 GeoIPRecord_delete(gr); |
98a8336c5b7c
fix memory leak if GeoIP City database was used
Igor Sysoev <igor@sysoev.ru>
parents:
2985
diff
changeset
|
443 |
2985 | 444 not_found: |
445 | |
446 v->not_found = 1; | |
447 | |
448 return NGX_OK; | |
449 } | |
450 | |
451 | |
452 static ngx_int_t | |
6630 | 453 ngx_stream_geoip_region_name_variable(ngx_stream_session_t *s, |
454 ngx_stream_variable_value_t *v, uintptr_t data) | |
3737 | 455 { |
456 size_t len; | |
457 const char *val; | |
458 GeoIPRecord *gr; | |
459 | |
6630 | 460 gr = ngx_stream_geoip_get_city_record(s); |
3737 | 461 if (gr == NULL) { |
462 goto not_found; | |
463 } | |
464 | |
465 val = GeoIP_region_name_by_code(gr->country_code, gr->region); | |
3742
01691af60f94
we can free GeoIPRecord just after GeoIP_region_name_by_code(),
Igor Sysoev <igor@sysoev.ru>
parents:
3741
diff
changeset
|
466 |
01691af60f94
we can free GeoIPRecord just after GeoIP_region_name_by_code(),
Igor Sysoev <igor@sysoev.ru>
parents:
3741
diff
changeset
|
467 GeoIPRecord_delete(gr); |
01691af60f94
we can free GeoIPRecord just after GeoIP_region_name_by_code(),
Igor Sysoev <igor@sysoev.ru>
parents:
3741
diff
changeset
|
468 |
3741
0f9b2d285bfc
fix segfault, the bug has been introduced in r3738
Igor Sysoev <igor@sysoev.ru>
parents:
3737
diff
changeset
|
469 if (val == NULL) { |
3742
01691af60f94
we can free GeoIPRecord just after GeoIP_region_name_by_code(),
Igor Sysoev <igor@sysoev.ru>
parents:
3741
diff
changeset
|
470 goto not_found; |
3741
0f9b2d285bfc
fix segfault, the bug has been introduced in r3738
Igor Sysoev <igor@sysoev.ru>
parents:
3737
diff
changeset
|
471 } |
3737 | 472 |
473 len = ngx_strlen(val); | |
6630 | 474 v->data = ngx_pnalloc(s->connection->pool, len); |
3737 | 475 if (v->data == NULL) { |
476 return NGX_ERROR; | |
477 } | |
478 | |
479 ngx_memcpy(v->data, val, len); | |
480 | |
481 v->len = len; | |
482 v->valid = 1; | |
483 v->no_cacheable = 0; | |
484 v->not_found = 0; | |
485 | |
486 return NGX_OK; | |
487 | |
488 not_found: | |
489 | |
490 v->not_found = 1; | |
491 | |
492 return NGX_OK; | |
493 } | |
494 | |
495 | |
496 static ngx_int_t | |
6630 | 497 ngx_stream_geoip_city_float_variable(ngx_stream_session_t *s, |
498 ngx_stream_variable_value_t *v, uintptr_t data) | |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
499 { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
500 float val; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
501 GeoIPRecord *gr; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
502 |
6630 | 503 gr = ngx_stream_geoip_get_city_record(s); |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
504 if (gr == NULL) { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
505 v->not_found = 1; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
506 return NGX_OK; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
507 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
508 |
6630 | 509 v->data = ngx_pnalloc(s->connection->pool, NGX_INT64_LEN + 5); |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
510 if (v->data == NULL) { |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
511 GeoIPRecord_delete(gr); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
512 return NGX_ERROR; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
513 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
514 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
515 val = *(float *) ((char *) gr + data); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
516 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
517 v->len = ngx_sprintf(v->data, "%.4f", val) - v->data; |
5773
494c2c2a0247
GeoIP: not all variable fields were initialized.
Yichun Zhang <agentzh@gmail.com>
parents:
5758
diff
changeset
|
518 v->valid = 1; |
494c2c2a0247
GeoIP: not all variable fields were initialized.
Yichun Zhang <agentzh@gmail.com>
parents:
5758
diff
changeset
|
519 v->no_cacheable = 0; |
494c2c2a0247
GeoIP: not all variable fields were initialized.
Yichun Zhang <agentzh@gmail.com>
parents:
5758
diff
changeset
|
520 v->not_found = 0; |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
521 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
522 GeoIPRecord_delete(gr); |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
523 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
524 return NGX_OK; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
525 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
526 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
527 |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
528 static ngx_int_t |
6630 | 529 ngx_stream_geoip_city_int_variable(ngx_stream_session_t *s, |
530 ngx_stream_variable_value_t *v, uintptr_t data) | |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
531 { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
532 int val; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
533 GeoIPRecord *gr; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
534 |
6630 | 535 gr = ngx_stream_geoip_get_city_record(s); |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
536 if (gr == NULL) { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
537 v->not_found = 1; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
538 return NGX_OK; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
539 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
540 |
6630 | 541 v->data = ngx_pnalloc(s->connection->pool, NGX_INT64_LEN); |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
542 if (v->data == NULL) { |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
543 GeoIPRecord_delete(gr); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
544 return NGX_ERROR; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
545 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
546 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
547 val = *(int *) ((char *) gr + data); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
548 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
549 v->len = ngx_sprintf(v->data, "%d", val) - v->data; |
5773
494c2c2a0247
GeoIP: not all variable fields were initialized.
Yichun Zhang <agentzh@gmail.com>
parents:
5758
diff
changeset
|
550 v->valid = 1; |
494c2c2a0247
GeoIP: not all variable fields were initialized.
Yichun Zhang <agentzh@gmail.com>
parents:
5758
diff
changeset
|
551 v->no_cacheable = 0; |
494c2c2a0247
GeoIP: not all variable fields were initialized.
Yichun Zhang <agentzh@gmail.com>
parents:
5758
diff
changeset
|
552 v->not_found = 0; |
3736
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
553 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
554 GeoIPRecord_delete(gr); |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
555 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
556 return NGX_OK; |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
557 } |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
558 |
257785918797
$geoip_dma_code and $geoip_area_code
Igor Sysoev <igor@sysoev.ru>
parents:
3398
diff
changeset
|
559 |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
560 static GeoIPRecord * |
6630 | 561 ngx_stream_geoip_get_city_record(ngx_stream_session_t *s) |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
562 { |
6630 | 563 ngx_stream_geoip_conf_t *gcf; |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
564 |
6630 | 565 gcf = ngx_stream_get_module_main_conf(s, ngx_stream_geoip_module); |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
566 |
3919
0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
Igor Sysoev <igor@sysoev.ru>
parents:
3915
diff
changeset
|
567 if (gcf->city) { |
5015 | 568 #if (NGX_HAVE_GEOIP_V6) |
569 return gcf->city_v6 | |
570 ? GeoIP_record_by_ipnum_v6(gcf->city, | |
6630 | 571 ngx_stream_geoip_addr_v6(s, gcf)) |
5015 | 572 : GeoIP_record_by_ipnum(gcf->city, |
6630 | 573 ngx_stream_geoip_addr(s, gcf)); |
5015 | 574 #else |
6630 | 575 return GeoIP_record_by_ipnum(gcf->city, ngx_stream_geoip_addr(s, gcf)); |
5015 | 576 #endif |
3398
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
577 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
578 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
579 return NULL; |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
580 } |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
581 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
582 |
236634d2b603
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
Igor Sysoev <igor@sysoev.ru>
parents:
3031
diff
changeset
|
583 static ngx_int_t |
6630 | 584 ngx_stream_geoip_add_variables(ngx_conf_t *cf) |
2985 | 585 { |
6630 | 586 ngx_stream_variable_t *var, *v; |
2985 | 587 |
6630 | 588 for (v = ngx_stream_geoip_vars; v->name.len; v++) { |
589 var = ngx_stream_add_variable(cf, &v->name, v->flags); | |
2985 | 590 if (var == NULL) { |
591 return NGX_ERROR; | |
592 } | |
593 | |
594 var->get_handler = v->get_handler; | |
595 var->data = v->data; | |
596 } | |
597 | |
598 return NGX_OK; | |
599 } | |
600 | |
601 | |
602 static void * | |
6630 | 603 ngx_stream_geoip_create_conf(ngx_conf_t *cf) |
2985 | 604 { |
6630 | 605 ngx_pool_cleanup_t *cln; |
606 ngx_stream_geoip_conf_t *conf; | |
2985 | 607 |
6630 | 608 conf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_geoip_conf_t)); |
2985 | 609 if (conf == NULL) { |
610 return NULL; | |
611 } | |
612 | |
613 cln = ngx_pool_cleanup_add(cf->pool, 0); | |
614 if (cln == NULL) { | |
615 return NULL; | |
616 } | |
617 | |
6630 | 618 cln->handler = ngx_stream_geoip_cleanup; |
2985 | 619 cln->data = conf; |
620 | |
621 return conf; | |
622 } | |
623 | |
624 | |
625 static char * | |
6630 | 626 ngx_stream_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
627 { |
6630 | 628 ngx_stream_geoip_conf_t *gcf = conf; |
2985 | 629 |
630 ngx_str_t *value; | |
631 | |
632 if (gcf->country) { | |
633 return "is duplicate"; | |
634 } | |
635 | |
636 value = cf->args->elts; | |
637 | |
638 gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); | |
639 | |
640 if (gcf->country == NULL) { | |
641 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3914 | 642 "GeoIP_open(\"%V\") failed", &value[1]); |
2985 | 643 |
644 return NGX_CONF_ERROR; | |
645 } | |
646 | |
3859
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
647 if (cf->args->nelts == 3) { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
648 if (ngx_strcmp(value[2].data, "utf8") == 0) { |
5758
f3df4e420ae7
Style: remove whitespace between function name and parentheses.
Piotr Sikora <piotr@cloudflare.com>
parents:
5084
diff
changeset
|
649 GeoIP_set_charset(gcf->country, GEOIP_CHARSET_UTF8); |
3859
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
650 |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
651 } else { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
652 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
653 "invalid parameter \"%V\"", &value[2]); |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
654 return NGX_CONF_ERROR; |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
655 } |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
656 } |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
657 |
2985 | 658 switch (gcf->country->databaseType) { |
659 | |
660 case GEOIP_COUNTRY_EDITION: | |
661 | |
662 return NGX_CONF_OK; | |
663 | |
5015 | 664 #if (NGX_HAVE_GEOIP_V6) |
665 case GEOIP_COUNTRY_EDITION_V6: | |
666 | |
667 gcf->country_v6 = 1; | |
668 return NGX_CONF_OK; | |
669 #endif | |
670 | |
2985 | 671 default: |
672 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
673 "invalid GeoIP database \"%V\" type:%d", | |
674 &value[1], gcf->country->databaseType); | |
675 return NGX_CONF_ERROR; | |
676 } | |
677 } | |
678 | |
679 | |
680 static char * | |
6630 | 681 ngx_stream_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
3915 | 682 { |
6630 | 683 ngx_stream_geoip_conf_t *gcf = conf; |
3915 | 684 |
685 ngx_str_t *value; | |
686 | |
687 if (gcf->org) { | |
688 return "is duplicate"; | |
689 } | |
690 | |
691 value = cf->args->elts; | |
692 | |
693 gcf->org = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); | |
694 | |
695 if (gcf->org == NULL) { | |
696 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
697 "GeoIP_open(\"%V\") failed", &value[1]); | |
698 | |
699 return NGX_CONF_ERROR; | |
700 } | |
701 | |
702 if (cf->args->nelts == 3) { | |
703 if (ngx_strcmp(value[2].data, "utf8") == 0) { | |
5758
f3df4e420ae7
Style: remove whitespace between function name and parentheses.
Piotr Sikora <piotr@cloudflare.com>
parents:
5084
diff
changeset
|
704 GeoIP_set_charset(gcf->org, GEOIP_CHARSET_UTF8); |
3915 | 705 |
706 } else { | |
707 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
708 "invalid parameter \"%V\"", &value[2]); | |
709 return NGX_CONF_ERROR; | |
710 } | |
711 } | |
712 | |
713 switch (gcf->org->databaseType) { | |
714 | |
715 case GEOIP_ISP_EDITION: | |
716 case GEOIP_ORG_EDITION: | |
717 case GEOIP_DOMAIN_EDITION: | |
718 case GEOIP_ASNUM_EDITION: | |
719 | |
720 return NGX_CONF_OK; | |
721 | |
5015 | 722 #if (NGX_HAVE_GEOIP_V6) |
723 case GEOIP_ISP_EDITION_V6: | |
724 case GEOIP_ORG_EDITION_V6: | |
725 case GEOIP_DOMAIN_EDITION_V6: | |
726 case GEOIP_ASNUM_EDITION_V6: | |
727 | |
728 gcf->org_v6 = 1; | |
729 return NGX_CONF_OK; | |
730 #endif | |
731 | |
3915 | 732 default: |
733 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
734 "invalid GeoIP database \"%V\" type:%d", | |
735 &value[1], gcf->org->databaseType); | |
736 return NGX_CONF_ERROR; | |
737 } | |
738 } | |
739 | |
740 | |
741 static char * | |
6630 | 742 ngx_stream_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
2985 | 743 { |
6630 | 744 ngx_stream_geoip_conf_t *gcf = conf; |
2985 | 745 |
746 ngx_str_t *value; | |
747 | |
748 if (gcf->city) { | |
749 return "is duplicate"; | |
750 } | |
751 | |
752 value = cf->args->elts; | |
753 | |
754 gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE); | |
755 | |
756 if (gcf->city == NULL) { | |
757 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3914 | 758 "GeoIP_open(\"%V\") failed", &value[1]); |
2985 | 759 |
760 return NGX_CONF_ERROR; | |
761 } | |
762 | |
3859
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
763 if (cf->args->nelts == 3) { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
764 if (ngx_strcmp(value[2].data, "utf8") == 0) { |
5758
f3df4e420ae7
Style: remove whitespace between function name and parentheses.
Piotr Sikora <piotr@cloudflare.com>
parents:
5084
diff
changeset
|
765 GeoIP_set_charset(gcf->city, GEOIP_CHARSET_UTF8); |
3859
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
766 |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
767 } else { |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
768 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
769 "invalid parameter \"%V\"", &value[2]); |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
770 return NGX_CONF_ERROR; |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
771 } |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
772 } |
30d4d6187316
utf8 parameter of geoip_country and geoip_city
Igor Sysoev <igor@sysoev.ru>
parents:
3742
diff
changeset
|
773 |
2985 | 774 switch (gcf->city->databaseType) { |
775 | |
776 case GEOIP_CITY_EDITION_REV0: | |
777 case GEOIP_CITY_EDITION_REV1: | |
778 | |
779 return NGX_CONF_OK; | |
780 | |
5015 | 781 #if (NGX_HAVE_GEOIP_V6) |
782 case GEOIP_CITY_EDITION_REV0_V6: | |
783 case GEOIP_CITY_EDITION_REV1_V6: | |
784 | |
785 gcf->city_v6 = 1; | |
786 return NGX_CONF_OK; | |
787 #endif | |
788 | |
2985 | 789 default: |
790 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
791 "invalid GeoIP City database \"%V\" type:%d", | |
792 &value[1], gcf->city->databaseType); | |
793 return NGX_CONF_ERROR; | |
794 } | |
795 } | |
796 | |
797 | |
6630 | 798 static void |
799 ngx_stream_geoip_cleanup(void *data) | |
4627
3152e4c371d7
geoip: trusted proxies support and partial IPv6 support.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
800 { |
6630 | 801 ngx_stream_geoip_conf_t *gcf = data; |
2985 | 802 |
803 if (gcf->country) { | |
804 GeoIP_delete(gcf->country); | |
805 } | |
806 | |
3915 | 807 if (gcf->org) { |
808 GeoIP_delete(gcf->org); | |
809 } | |
810 | |
2985 | 811 if (gcf->city) { |
812 GeoIP_delete(gcf->city); | |
813 } | |
814 } |