Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream_geoip_module.c @ 7876:ffd362e87eb2 quic
Added more context to CONNECTION CLOSE frames.
Now it is possible to specify frame type that caused an error
and a human-readable reason phrase.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Fri, 22 May 2020 18:08:02 +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 } |