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