Ticket #44: nginx-realip-ipv6.patch
| File nginx-realip-ipv6.patch, 4.5 KB (added by , 15 years ago) |
|---|
-
src/http/modules/ngx_http_realip_module.c
19 19 in_addr_t addr; 20 20 } ngx_http_realip_from_t; 21 21 22 #if (NGX_HAVE_INET6) 23 typedef struct { 24 struct in6_addr mask; 25 struct in6_addr addr; 26 } ngx_http_realip_from6_t; 27 #endif 22 28 23 29 typedef struct { 24 30 ngx_array_t *from; /* array of ngx_http_realip_from_t */ 31 #if (NGX_HAVE_INET6) 32 ngx_array_t *from6; /* array of ngx_http_realip_from6_t */ 33 #endif 25 34 ngx_uint_t type; 26 35 ngx_uint_t hash; 27 36 ngx_str_t header; … … 117 126 ngx_http_realip_ctx_t *ctx; 118 127 ngx_http_realip_from_t *from; 119 128 ngx_http_realip_loc_conf_t *rlcf; 129 #if (NGX_HAVE_INET6) 130 ngx_uint_t n; 131 struct sockaddr_in6 *sin6; 132 ngx_http_realip_from6_t *from6; 133 #endif 120 134 121 135 ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module); 122 136 … … 209 223 210 224 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip); 211 225 212 /* AF_INET only */213 214 226 if (c->sockaddr->sa_family == AF_INET) { 215 227 sin = (struct sockaddr_in *) c->sockaddr; 216 228 … … 227 239 } 228 240 } 229 241 242 #if (NGX_HAVE_INET6) 243 if (c->sockaddr->sa_family == AF_INET6) { 244 sin6 = (struct sockaddr_in6 *) c->sockaddr; 245 246 from6 = rlcf->from6->elts; 247 for (i = 0; i < rlcf->from6->nelts; i++) { 248 for (n = 0; n < 16; n++) { 249 if ((sin6->sin6_addr.s6_addr[n] & from6[i].mask.s6_addr[n]) != from6[i].addr.s6_addr[n]) { 250 goto next; 251 } 252 } 253 254 return ngx_http_realip_set_addr(r, ip, len); 255 256 next: 257 continue; 258 } 259 } 260 #endif 261 230 262 #if (NGX_HAVE_UNIX_DOMAIN) 231 263 232 264 if (c->sockaddr->sa_family == AF_UNIX && rlcf->unixsock) { … … 317 349 ngx_str_t *value; 318 350 ngx_cidr_t cidr; 319 351 ngx_http_realip_from_t *from; 352 #if (NGX_HAVE_INET6) 353 ngx_http_realip_from6_t *from6; 354 #endif 320 355 321 356 value = cf->args->elts; 322 357 … … 328 363 } 329 364 330 365 #endif 331 332 if (rlcf->from == NULL) { 333 rlcf->from = ngx_array_create(cf->pool, 2, 334 sizeof(ngx_http_realip_from_t)); 335 if (rlcf->from == NULL) { 336 return NGX_CONF_ERROR; 337 } 338 } 339 340 from = ngx_array_push(rlcf->from); 341 if (from == NULL) { 342 return NGX_CONF_ERROR; 343 } 344 366 345 367 rc = ngx_ptocidr(&value[1], &cidr); 346 368 347 369 if (rc == NGX_ERROR) { … … 350 372 return NGX_CONF_ERROR; 351 373 } 352 374 375 #if !(NGX_HAVE_INET6) 353 376 if (cidr.family != AF_INET) { 354 377 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 355 378 "\"set_real_ip_from\" supports IPv4 only"); 356 379 return NGX_CONF_ERROR; 357 380 } 381 #endif 358 382 359 383 if (rc == NGX_DONE) { 360 384 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, 361 385 "low address bits of %V are meaningless", &value[1]); 362 386 } 363 387 364 from->mask = cidr.u.in.mask; 365 from->addr = cidr.u.in.addr; 388 switch (cidr.family) { 389 #if (NGX_HAVE_INET6) 390 case AF_INET6: 391 if (rlcf->from6 == NULL) { 392 rlcf->from6 = ngx_array_create(cf->pool, 2, 393 sizeof(ngx_http_realip_from6_t)); 394 if (rlcf->from6 == NULL) { 395 return NGX_CONF_ERROR; 396 } 397 } 366 398 399 from6 = ngx_array_push(rlcf->from6); 400 if (from6 == NULL) { 401 return NGX_CONF_ERROR; 402 } 403 404 from6->addr = cidr.u.in6.addr; 405 from6->mask = cidr.u.in6.mask; 406 break; 407 #endif 408 409 default: /* AF_INET */ 410 if (rlcf->from == NULL) { 411 rlcf->from = ngx_array_create(cf->pool, 2, 412 sizeof(ngx_http_realip_from_t)); 413 if (rlcf->from == NULL) { 414 return NGX_CONF_ERROR; 415 } 416 } 417 418 from = ngx_array_push(rlcf->from); 419 if (from == NULL) { 420 return NGX_CONF_ERROR; 421 } 422 423 from->addr = cidr.u.in.addr; 424 from->mask = cidr.u.in.mask; 425 } 426 367 427 return NGX_CONF_OK; 368 428 } 369 429 … … 432 492 conf->from = prev->from; 433 493 } 434 494 495 #if (NGX_HAVE_INET6) 496 if (conf->from6 == NULL) { 497 conf->from6 = prev->from6; 498 } 499 #endif 500 435 501 #if (NGX_HAVE_UNIX_DOMAIN) 436 502 if (conf->unixsock == 2) { 437 503 conf->unixsock = (prev->unixsock == 2) ? 0 : prev->unixsock;
