aboutsummaryrefslogtreecommitdiff
path: root/src/stream/ngx_stream_realip_module.c
diff options
context:
space:
mode:
authorRuslan Ermilov <ru@nginx.com>2017-05-15 17:17:01 +0300
committerRuslan Ermilov <ru@nginx.com>2017-05-15 17:17:01 +0300
commita464d07f0a3fd8afd37ce7135e7c678e3604a30c (patch)
treee5914f33886671c3acb1caf52fc278fe7a45a7db /src/stream/ngx_stream_realip_module.c
parentb313bc4bd3a61fe8bf9fccbf14ef75ddbd25160b (diff)
downloadnginx-a464d07f0a3fd8afd37ce7135e7c678e3604a30c.tar.gz
nginx-a464d07f0a3fd8afd37ce7135e7c678e3604a30c.zip
Realip: allow hostnames in set_real_ip_from (ticket #1180).
Diffstat (limited to 'src/stream/ngx_stream_realip_module.c')
-rw-r--r--src/stream/ngx_stream_realip_module.c83
1 files changed, 68 insertions, 15 deletions
diff --git a/src/stream/ngx_stream_realip_module.c b/src/stream/ngx_stream_realip_module.c
index 0740431e3..1266605ce 100644
--- a/src/stream/ngx_stream_realip_module.c
+++ b/src/stream/ngx_stream_realip_module.c
@@ -178,9 +178,15 @@ ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_stream_realip_srv_conf_t *rscf = conf;
- ngx_int_t rc;
- ngx_str_t *value;
- ngx_cidr_t *cidr;
+ ngx_int_t rc;
+ ngx_str_t *value;
+ ngx_url_t u;
+ ngx_cidr_t c, *cidr;
+ ngx_uint_t i;
+ struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
value = cf->args->elts;
@@ -192,31 +198,78 @@ ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
- cidr = ngx_array_push(rscf->from);
- if (cidr == NULL) {
- return NGX_CONF_ERROR;
- }
-
#if (NGX_HAVE_UNIX_DOMAIN)
if (ngx_strcmp(value[1].data, "unix:") == 0) {
+ cidr = ngx_array_push(rscf->from);
+ if (cidr == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
cidr->family = AF_UNIX;
return NGX_CONF_OK;
}
#endif
- rc = ngx_ptocidr(&value[1], cidr);
+ rc = ngx_ptocidr(&value[1], &c);
+
+ if (rc != NGX_ERROR) {
+ if (rc == NGX_DONE) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "low address bits of %V are meaningless",
+ &value[1]);
+ }
+
+ cidr = ngx_array_push(rscf->from);
+ if (cidr == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *cidr = c;
+
+ return NGX_CONF_OK;
+ }
+
+ ngx_memzero(&u, sizeof(ngx_url_t));
+ u.host = value[1];
+
+ if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
+ if (u.err) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "%s in set_real_ip_from \"%V\"",
+ u.err, &u.host);
+ }
- if (rc == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
- &value[1]);
return NGX_CONF_ERROR;
}
- if (rc == NGX_DONE) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "low address bits of %V are meaningless", &value[1]);
+ cidr = ngx_array_push_n(rscf->from, u.naddrs);
+ if (cidr == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
+
+ for (i = 0; i < u.naddrs; i++) {
+ cidr[i].family = u.addrs[i].sockaddr->sa_family;
+
+ switch (cidr[i].family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
+ cidr[i].u.in6.addr = sin6->sin6_addr;
+ ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
+ break;
+#endif
+
+ default: /* AF_INET */
+ sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
+ cidr[i].u.in.addr = sin->sin_addr.s_addr;
+ cidr[i].u.in.mask = 0xffffffff;
+ break;
+ }
}
return NGX_CONF_OK;