Mercurial > hg > nginx
comparison src/http/modules/ngx_http_realip_module.c @ 6997:df1a62c83b1b
Realip: allow hostnames in set_real_ip_from (ticket #1180).
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Mon, 15 May 2017 17:17:01 +0300 |
parents | cecf415643d7 |
children | 2a288909abc6 |
comparison
equal
deleted
inserted
replaced
6996:72188d1bcab5 | 6997:df1a62c83b1b |
---|---|
315 static char * | 315 static char * |
316 ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 316 ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
317 { | 317 { |
318 ngx_http_realip_loc_conf_t *rlcf = conf; | 318 ngx_http_realip_loc_conf_t *rlcf = conf; |
319 | 319 |
320 ngx_int_t rc; | 320 ngx_int_t rc; |
321 ngx_str_t *value; | 321 ngx_str_t *value; |
322 ngx_cidr_t *cidr; | 322 ngx_url_t u; |
323 ngx_cidr_t c, *cidr; | |
324 ngx_uint_t i; | |
325 struct sockaddr_in *sin; | |
326 #if (NGX_HAVE_INET6) | |
327 struct sockaddr_in6 *sin6; | |
328 #endif | |
323 | 329 |
324 value = cf->args->elts; | 330 value = cf->args->elts; |
325 | 331 |
326 if (rlcf->from == NULL) { | 332 if (rlcf->from == NULL) { |
327 rlcf->from = ngx_array_create(cf->pool, 2, | 333 rlcf->from = ngx_array_create(cf->pool, 2, |
329 if (rlcf->from == NULL) { | 335 if (rlcf->from == NULL) { |
330 return NGX_CONF_ERROR; | 336 return NGX_CONF_ERROR; |
331 } | 337 } |
332 } | 338 } |
333 | 339 |
334 cidr = ngx_array_push(rlcf->from); | 340 #if (NGX_HAVE_UNIX_DOMAIN) |
341 | |
342 if (ngx_strcmp(value[1].data, "unix:") == 0) { | |
343 cidr = ngx_array_push(rlcf->from); | |
344 if (cidr == NULL) { | |
345 return NGX_CONF_ERROR; | |
346 } | |
347 | |
348 cidr->family = AF_UNIX; | |
349 return NGX_CONF_OK; | |
350 } | |
351 | |
352 #endif | |
353 | |
354 rc = ngx_ptocidr(&value[1], &c); | |
355 | |
356 if (rc != NGX_ERROR) { | |
357 if (rc == NGX_DONE) { | |
358 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | |
359 "low address bits of %V are meaningless", | |
360 &value[1]); | |
361 } | |
362 | |
363 cidr = ngx_array_push(rlcf->from); | |
364 if (cidr == NULL) { | |
365 return NGX_CONF_ERROR; | |
366 } | |
367 | |
368 *cidr = c; | |
369 | |
370 return NGX_CONF_OK; | |
371 } | |
372 | |
373 ngx_memzero(&u, sizeof(ngx_url_t)); | |
374 u.host = value[1]; | |
375 | |
376 if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { | |
377 if (u.err) { | |
378 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
379 "%s in set_real_ip_from \"%V\"", | |
380 u.err, &u.host); | |
381 } | |
382 | |
383 return NGX_CONF_ERROR; | |
384 } | |
385 | |
386 cidr = ngx_array_push_n(rlcf->from, u.naddrs); | |
335 if (cidr == NULL) { | 387 if (cidr == NULL) { |
336 return NGX_CONF_ERROR; | 388 return NGX_CONF_ERROR; |
337 } | 389 } |
338 | 390 |
339 #if (NGX_HAVE_UNIX_DOMAIN) | 391 ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t)); |
340 | 392 |
341 if (ngx_strcmp(value[1].data, "unix:") == 0) { | 393 for (i = 0; i < u.naddrs; i++) { |
342 cidr->family = AF_UNIX; | 394 cidr[i].family = u.addrs[i].sockaddr->sa_family; |
343 return NGX_CONF_OK; | 395 |
344 } | 396 switch (cidr[i].family) { |
345 | 397 |
398 #if (NGX_HAVE_INET6) | |
399 case AF_INET6: | |
400 sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr; | |
401 cidr[i].u.in6.addr = sin6->sin6_addr; | |
402 ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16); | |
403 break; | |
346 #endif | 404 #endif |
347 | 405 |
348 rc = ngx_ptocidr(&value[1], cidr); | 406 default: /* AF_INET */ |
349 | 407 sin = (struct sockaddr_in *) u.addrs[i].sockaddr; |
350 if (rc == NGX_ERROR) { | 408 cidr[i].u.in.addr = sin->sin_addr.s_addr; |
351 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", | 409 cidr[i].u.in.mask = 0xffffffff; |
352 &value[1]); | 410 break; |
353 return NGX_CONF_ERROR; | 411 } |
354 } | |
355 | |
356 if (rc == NGX_DONE) { | |
357 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | |
358 "low address bits of %V are meaningless", &value[1]); | |
359 } | 412 } |
360 | 413 |
361 return NGX_CONF_OK; | 414 return NGX_CONF_OK; |
362 } | 415 } |
363 | 416 |