[nginx] Realip: allow hostnames in set_real_ip_from (ticket #1180).

Ruslan Ermilov ru at nginx.com
Mon May 15 14:21:18 UTC 2017


details:   http://hg.nginx.org/nginx/rev/df1a62c83b1b
branches:  
changeset: 6997:df1a62c83b1b
user:      Ruslan Ermilov <ru at nginx.com>
date:      Mon May 15 17:17:01 2017 +0300
description:
Realip: allow hostnames in set_real_ip_from (ticket #1180).

diffstat:

 src/http/modules/ngx_http_realip_module.c |  83 +++++++++++++++++++++++++-----
 src/stream/ngx_stream_realip_module.c     |  83 +++++++++++++++++++++++++-----
 2 files changed, 136 insertions(+), 30 deletions(-)

diffs (226 lines):

diff -r 72188d1bcab5 -r df1a62c83b1b src/http/modules/ngx_http_realip_module.c
--- a/src/http/modules/ngx_http_realip_module.c	Mon May 15 17:16:32 2017 +0300
+++ b/src/http/modules/ngx_http_realip_module.c	Mon May 15 17:17:01 2017 +0300
@@ -317,9 +317,15 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx
 {
     ngx_http_realip_loc_conf_t *rlcf = 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;
 
@@ -331,31 +337,78 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx
         }
     }
 
-    cidr = ngx_array_push(rlcf->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(rlcf->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) {
-        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
-                           &value[1]);
+    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(rlcf->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);
+        }
+
         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(rlcf->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;
diff -r 72188d1bcab5 -r df1a62c83b1b src/stream/ngx_stream_realip_module.c
--- a/src/stream/ngx_stream_realip_module.c	Mon May 15 17:16:32 2017 +0300
+++ b/src/stream/ngx_stream_realip_module.c	Mon May 15 17:17:01 2017 +0300
@@ -178,9 +178,15 @@ ngx_stream_realip_from(ngx_conf_t *cf, n
 {
     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, n
         }
     }
 
-    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) {
-        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
-                           &value[1]);
+    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);
+        }
+
         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;


More information about the nginx-devel mailing list