diff options
author | Dmitry Volyntsev <xeioex@nginx.com> | 2016-05-23 18:44:23 +0300 |
---|---|---|
committer | Dmitry Volyntsev <xeioex@nginx.com> | 2016-05-23 18:44:23 +0300 |
commit | 06176bce918ea25bce8e4cc3adcc0e692bf1eac6 (patch) | |
tree | c1d9c513f560eb0b78a2a9f9d7c6fa78f5174bfe /src/core/ngx_inet.c | |
parent | 19140c8c4f7f16747df4a7e3bf4299a6a8d75a81 (diff) | |
download | nginx-06176bce918ea25bce8e4cc3adcc0e692bf1eac6.tar.gz nginx-06176bce918ea25bce8e4cc3adcc0e692bf1eac6.zip |
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 (limited to 'src/core/ngx_inet.c')
-rw-r--r-- | src/core/ngx_inet.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index 12bf9f81a..b5c57b7a4 100644 --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -526,6 +526,85 @@ 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) +{ + 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; |