[nginx] Listen port ranges.
Roman Arutyunyan
arut at nginx.com
Thu Mar 21 11:09:58 UTC 2019
details: https://hg.nginx.org/nginx/rev/d9c3917c7f90
branches:
changeset: 7480:d9c3917c7f90
user: Roman Arutyunyan <arut at nginx.com>
date: Wed Mar 06 20:46:09 2019 +0300
description:
Listen port ranges.
A range is specified with a dash. For each port in a range a separate listen
socket is created.
Examples:
listen 8080-9000;
listen example.com:80-88;
diffstat:
src/core/ngx_inet.c | 147 +++++++++++++++++++++++++++++++++++++++++----------
src/core/ngx_inet.h | 1 +
2 files changed, 119 insertions(+), 29 deletions(-)
diffs (262 lines):
diff -r 8be88b22fe81 -r d9c3917c7f90 src/core/ngx_inet.c
--- a/src/core/ngx_inet.c Wed Mar 20 20:31:59 2019 +0300
+++ b/src/core/ngx_inet.c Wed Mar 06 20:46:09 2019 +0300
@@ -782,7 +782,7 @@ ngx_parse_unix_domain_url(ngx_pool_t *po
static ngx_int_t
ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
{
- u_char *host, *port, *last, *uri, *args;
+ u_char *host, *port, *last, *uri, *args, *dash;
size_t len;
ngx_int_t n;
struct sockaddr_in *sin;
@@ -830,6 +830,25 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx
len = last - port;
+ if (u->listen) {
+ dash = ngx_strlchr(port, last, '-');
+
+ if (dash) {
+ dash++;
+
+ n = ngx_atoi(dash, last - dash);
+
+ if (n < 1 || n > 65535) {
+ u->err = "invalid port";
+ return NGX_ERROR;
+ }
+
+ u->last_port = (in_port_t) n;
+
+ len = dash - port - 1;
+ }
+ }
+
n = ngx_atoi(port, len);
if (n < 1 || n > 65535) {
@@ -837,10 +856,15 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx
return NGX_ERROR;
}
+ if (u->last_port && n > u->last_port) {
+ u->err = "invalid port range";
+ return NGX_ERROR;
+ }
+
u->port = (in_port_t) n;
sin->sin_port = htons((in_port_t) n);
- u->port_text.len = len;
+ u->port_text.len = last - port;
u->port_text.data = port;
last = port - 1;
@@ -852,15 +876,47 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx
/* test value as port only */
- n = ngx_atoi(host, last - host);
+ len = last - host;
+
+ dash = ngx_strlchr(host, last, '-');
+
+ if (dash) {
+ dash++;
+
+ n = ngx_atoi(dash, last - dash);
+
+ if (n == NGX_ERROR) {
+ goto no_port;
+ }
+
+ if (n < 1 || n > 65535) {
+ u->err = "invalid port";
+
+ } else {
+ u->last_port = (in_port_t) n;
+ }
+
+ len = dash - host - 1;
+ }
+
+ n = ngx_atoi(host, len);
if (n != NGX_ERROR) {
+ if (u->err) {
+ return NGX_ERROR;
+ }
+
if (n < 1 || n > 65535) {
u->err = "invalid port";
return NGX_ERROR;
}
+ if (u->last_port && n > u->last_port) {
+ u->err = "invalid port range";
+ return NGX_ERROR;
+ }
+
u->port = (in_port_t) n;
sin->sin_port = htons((in_port_t) n);
sin->sin_addr.s_addr = INADDR_ANY;
@@ -876,9 +932,13 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx
}
}
+no_port:
+
+ u->err = NULL;
u->no_port = 1;
u->port = u->default_port;
sin->sin_port = htons(u->default_port);
+ u->last_port = 0;
}
len = last - host;
@@ -929,7 +989,7 @@ static ngx_int_t
ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
{
#if (NGX_HAVE_INET6)
- u_char *p, *host, *port, *last, *uri;
+ u_char *p, *host, *port, *last, *uri, *dash;
size_t len;
ngx_int_t n;
struct sockaddr_in6 *sin6;
@@ -975,6 +1035,25 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ng
len = last - port;
+ if (u->listen) {
+ dash = ngx_strlchr(port, last, '-');
+
+ if (dash) {
+ dash++;
+
+ n = ngx_atoi(dash, last - dash);
+
+ if (n < 1 || n > 65535) {
+ u->err = "invalid port";
+ return NGX_ERROR;
+ }
+
+ u->last_port = (in_port_t) n;
+
+ len = dash - port - 1;
+ }
+ }
+
n = ngx_atoi(port, len);
if (n < 1 || n > 65535) {
@@ -982,10 +1061,15 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ng
return NGX_ERROR;
}
+ if (u->last_port && n > u->last_port) {
+ u->err = "invalid port range";
+ return NGX_ERROR;
+ }
+
u->port = (in_port_t) n;
sin6->sin6_port = htons((in_port_t) n);
- u->port_text.len = len;
+ u->port_text.len = last - port;
u->port_text.data = port;
} else {
@@ -1181,51 +1265,56 @@ ngx_inet_add_addr(ngx_pool_t *pool, ngx_
{
u_char *p;
size_t len;
+ ngx_uint_t i, nports;
ngx_addr_t *addr;
struct sockaddr *sa;
+ nports = u->last_port ? u->last_port - u->port + 1 : 1;
+
if (u->addrs == NULL) {
- u->addrs = ngx_palloc(pool, total * sizeof(ngx_addr_t));
+ u->addrs = ngx_palloc(pool, total * nports * sizeof(ngx_addr_t));
if (u->addrs == NULL) {
return NGX_ERROR;
}
}
- sa = ngx_pcalloc(pool, socklen);
- if (sa == NULL) {
- return NGX_ERROR;
- }
+ for (i = 0; i < nports; i++) {
+ sa = ngx_pcalloc(pool, socklen);
+ if (sa == NULL) {
+ return NGX_ERROR;
+ }
- ngx_memcpy(sa, sockaddr, socklen);
+ ngx_memcpy(sa, sockaddr, socklen);
- ngx_inet_set_port(sa, u->port);
+ ngx_inet_set_port(sa, u->port + i);
- switch (sa->sa_family) {
+ switch (sa->sa_family) {
#if (NGX_HAVE_INET6)
- case AF_INET6:
- len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65536") - 1;
- break;
+ case AF_INET6:
+ len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65536") - 1;
+ break;
#endif
- default: /* AF_INET */
- len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
- }
+ default: /* AF_INET */
+ len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+ }
- p = ngx_pnalloc(pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
+ p = ngx_pnalloc(pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
- len = ngx_sock_ntop(sa, socklen, p, len, 1);
+ len = ngx_sock_ntop(sa, socklen, p, len, 1);
- addr = &u->addrs[u->naddrs++];
+ addr = &u->addrs[u->naddrs++];
- addr->sockaddr = sa;
- addr->socklen = socklen;
+ addr->sockaddr = sa;
+ addr->socklen = socklen;
- addr->name.len = len;
- addr->name.data = p;
+ addr->name.len = len;
+ addr->name.data = p;
+ }
return NGX_OK;
}
diff -r 8be88b22fe81 -r d9c3917c7f90 src/core/ngx_inet.h
--- a/src/core/ngx_inet.h Wed Mar 20 20:31:59 2019 +0300
+++ b/src/core/ngx_inet.h Wed Mar 06 20:46:09 2019 +0300
@@ -86,6 +86,7 @@ typedef struct {
in_port_t port;
in_port_t default_port;
+ in_port_t last_port;
int family;
unsigned listen:1;
More information about the nginx-devel
mailing list