[nginx] Realip: port support in X-Real-IP and X-Forwarded-For.

Dmitry Volyntsev xeioex at nginx.com
Mon May 23 15:45:39 UTC 2016


details:   http://hg.nginx.org/nginx/rev/19db5a6bc34e
branches:  
changeset: 6564:19db5a6bc34e
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon May 23 18:44:23 2016 +0300
description:
Realip: port support in X-Real-IP and X-Forwarded-For.

Now, the module extracts optional port which may accompany an
IP address.  This custom extension is introduced, among other
things, in order to facilitate logging of original client ports.
Addresses with ports are expected to be in the RFC 3986 format,
that is, with IPv6 addresses in square brackets.  E.g.,
"X-Real-IP: [2001:0db8::1]:12345" sets client port ($remote_port)
to 12345.

diffstat:

 src/core/ngx_inet.c             |  79 +++++++++++++++++++++++++++++++++++++++++
 src/core/ngx_inet.h             |   2 +
 src/http/ngx_http_core_module.c |   4 +-
 3 files changed, 84 insertions(+), 1 deletions(-)

diffs (115 lines):

diff -r 26feae43987f -r 19db5a6bc34e src/core/ngx_inet.c
--- a/src/core/ngx_inet.c	Mon May 23 18:44:22 2016 +0300
+++ b/src/core/ngx_inet.c	Mon May 23 18:44:23 2016 +0300
@@ -526,6 +526,85 @@ ngx_parse_addr(ngx_pool_t *pool, ngx_add
 
 
 ngx_int_t
+ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
+    size_t len)
+{
+    u_char               *p, *last;
+    size_t                plen;
+    ngx_int_t             rc, port;
+    struct sockaddr_in   *sin;
+#if (NGX_HAVE_INET6)
+    struct sockaddr_in6  *sin6;
+#endif
+
+    rc = ngx_parse_addr(pool, addr, text, len);
+
+    if (rc != NGX_DECLINED) {
+        return rc;
+    }
+
+    last = text + len;
+
+#if (NGX_HAVE_INET6)
+    if (len && text[0] == '[') {
+
+        p = ngx_strlchr(text, last, ']');
+
+        if (p == NULL || p == last - 1 || *++p != ':') {
+            return NGX_DECLINED;
+        }
+
+        text++;
+        len -= 2;
+
+    } else
+#endif
+
+    {
+        p = ngx_strlchr(text, last, ':');
+
+        if (p == NULL) {
+            return NGX_DECLINED;
+        }
+    }
+
+    p++;
+    plen = last - p;
+
+    port = ngx_atoi(p, plen);
+
+    if (port < 1 || port > 65535) {
+        return NGX_DECLINED;
+    }
+
+    len -= plen + 1;
+
+    rc = ngx_parse_addr(pool, addr, text, len);
+
+    if (rc != NGX_OK) {
+        return rc;
+    }
+
+    switch (addr->sockaddr->sa_family) {
+
+#if (NGX_HAVE_INET6)
+    case AF_INET6:
+        sin6 = (struct sockaddr_in6 *) addr->sockaddr;
+        sin6->sin6_port = htons(port);
+        break;
+#endif
+
+    default: /* AF_INET */
+        sin = (struct sockaddr_in *) addr->sockaddr;
+        sin->sin_port = htons(port);
+        break;
+    }
+
+    return NGX_OK;
+}
+
+
+ngx_int_t
 ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
 {
     u_char  *p;
diff -r 26feae43987f -r 19db5a6bc34e src/core/ngx_inet.h
--- a/src/core/ngx_inet.h	Mon May 23 18:44:22 2016 +0300
+++ b/src/core/ngx_inet.h	Mon May 23 18:44:23 2016 +0300
@@ -115,6 +115,8 @@ size_t ngx_inet_ntop(int family, void *a
 ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);
 ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
     size_t len);
+ngx_int_t ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr,
+    u_char *text, size_t len);
 ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
 ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);
 ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
diff -r 26feae43987f -r 19db5a6bc34e src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c	Mon May 23 18:44:22 2016 +0300
+++ b/src/http/ngx_http_core_module.c	Mon May 23 18:44:23 2016 +0300
@@ -2910,7 +2910,9 @@ ngx_http_get_forwarded_addr_internal(ngx
             }
         }
 
-        if (ngx_parse_addr(r->pool, &paddr, p, xfflen - (p - xff)) != NGX_OK) {
+        if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff))
+            != NGX_OK)
+        {
             return NGX_DECLINED;
         }
 



More information about the nginx-devel mailing list