Mercurial > hg > nginx
comparison src/http/modules/ngx_http_geoip_module.c @ 3919:0dceaa117e0d
support IPv4 mapped to IPv6 in geoip module
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 16 May 2011 13:50:58 +0000 |
parents | e3645e338937 |
children | d620f497c50f |
comparison
equal
deleted
inserted
replaced
3918:eccd0b66a4ab | 3919:0dceaa117e0d |
---|---|
178 | 178 |
179 { ngx_null_string, NULL, NULL, 0, 0, 0 } | 179 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
180 }; | 180 }; |
181 | 181 |
182 | 182 |
183 static u_long | |
184 ngx_http_geoip_addr(ngx_http_request_t *r) | |
185 { | |
186 struct sockaddr_in *sin; | |
187 #if (NGX_HAVE_INET6) | |
188 u_char *p; | |
189 u_long addr; | |
190 struct sockaddr_in6 *sin6; | |
191 #endif | |
192 | |
193 switch (r->connection->sockaddr->sa_family) { | |
194 | |
195 case AF_INET: | |
196 sin = (struct sockaddr_in *) r->connection->sockaddr; | |
197 return ntohl(sin->sin_addr.s_addr); | |
198 | |
199 #if (NGX_HAVE_INET6) | |
200 | |
201 case AF_INET6: | |
202 sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; | |
203 | |
204 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { | |
205 p = sin6->sin6_addr.s6_addr; | |
206 addr = p[12] << 24; | |
207 addr += p[13] << 16; | |
208 addr += p[14] << 8; | |
209 addr += p[15]; | |
210 | |
211 return addr; | |
212 } | |
213 | |
214 #endif | |
215 } | |
216 | |
217 return INADDR_NONE; | |
218 } | |
219 | |
220 | |
183 static ngx_int_t | 221 static ngx_int_t |
184 ngx_http_geoip_country_variable(ngx_http_request_t *r, | 222 ngx_http_geoip_country_variable(ngx_http_request_t *r, |
185 ngx_http_variable_value_t *v, uintptr_t data) | 223 ngx_http_variable_value_t *v, uintptr_t data) |
186 { | 224 { |
187 ngx_http_geoip_variable_handler_pt handler = | 225 ngx_http_geoip_variable_handler_pt handler = |
188 (ngx_http_geoip_variable_handler_pt) data; | 226 (ngx_http_geoip_variable_handler_pt) data; |
189 | 227 |
190 u_long addr; | |
191 const char *val; | 228 const char *val; |
192 struct sockaddr_in *sin; | |
193 ngx_http_geoip_conf_t *gcf; | 229 ngx_http_geoip_conf_t *gcf; |
194 | 230 |
195 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); | 231 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); |
196 | 232 |
197 if (gcf->country == NULL) { | 233 if (gcf->country == NULL) { |
198 goto not_found; | 234 goto not_found; |
199 } | 235 } |
200 | 236 |
201 if (r->connection->sockaddr->sa_family != AF_INET) { | 237 val = handler(gcf->country, ngx_http_geoip_addr(r)); |
202 goto not_found; | |
203 } | |
204 | |
205 sin = (struct sockaddr_in *) r->connection->sockaddr; | |
206 addr = ntohl(sin->sin_addr.s_addr); | |
207 | |
208 val = handler(gcf->country, addr); | |
209 | 238 |
210 if (val == NULL) { | 239 if (val == NULL) { |
211 goto not_found; | 240 goto not_found; |
212 } | 241 } |
213 | 242 |
232 ngx_http_variable_value_t *v, uintptr_t data) | 261 ngx_http_variable_value_t *v, uintptr_t data) |
233 { | 262 { |
234 ngx_http_geoip_variable_handler_pt handler = | 263 ngx_http_geoip_variable_handler_pt handler = |
235 (ngx_http_geoip_variable_handler_pt) data; | 264 (ngx_http_geoip_variable_handler_pt) data; |
236 | 265 |
237 u_long addr; | |
238 const char *val; | 266 const char *val; |
239 struct sockaddr_in *sin; | |
240 ngx_http_geoip_conf_t *gcf; | 267 ngx_http_geoip_conf_t *gcf; |
241 | 268 |
242 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); | 269 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); |
243 | 270 |
244 if (gcf->org == NULL) { | 271 if (gcf->org == NULL) { |
245 goto not_found; | 272 goto not_found; |
246 } | 273 } |
247 | 274 |
248 if (r->connection->sockaddr->sa_family != AF_INET) { | 275 val = handler(gcf->org, ngx_http_geoip_addr(r)); |
249 goto not_found; | |
250 } | |
251 | |
252 sin = (struct sockaddr_in *) r->connection->sockaddr; | |
253 addr = ntohl(sin->sin_addr.s_addr); | |
254 | |
255 val = handler(gcf->org, addr); | |
256 | 276 |
257 if (val == NULL) { | 277 if (val == NULL) { |
258 goto not_found; | 278 goto not_found; |
259 } | 279 } |
260 | 280 |
425 | 445 |
426 | 446 |
427 static GeoIPRecord * | 447 static GeoIPRecord * |
428 ngx_http_geoip_get_city_record(ngx_http_request_t *r) | 448 ngx_http_geoip_get_city_record(ngx_http_request_t *r) |
429 { | 449 { |
430 u_long addr; | |
431 struct sockaddr_in *sin; | |
432 ngx_http_geoip_conf_t *gcf; | 450 ngx_http_geoip_conf_t *gcf; |
433 | 451 |
434 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); | 452 gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); |
435 | 453 |
436 if (gcf->city && r->connection->sockaddr->sa_family == AF_INET) { | 454 if (gcf->city) { |
437 | 455 return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r)); |
438 sin = (struct sockaddr_in *) r->connection->sockaddr; | |
439 addr = ntohl(sin->sin_addr.s_addr); | |
440 | |
441 return GeoIP_record_by_ipnum(gcf->city, addr); | |
442 } | 456 } |
443 | 457 |
444 return NULL; | 458 return NULL; |
445 } | 459 } |
446 | 460 |