Welcome! Log In Create A New Profile

Advanced

[nginx] Multiple addresses in "listen".

Roman Arutyunyan
March 21, 2019 07:10AM
details: https://hg.nginx.org/nginx/rev/4f9b72a229c1
branches:
changeset: 7478:4f9b72a229c1
user: Roman Arutyunyan <arut@nginx.com>
date: Fri Mar 15 15:45:56 2019 +0300
description:
Multiple addresses in "listen".

Previously only one address was used by the listen directive handler even if
host name resolved to multiple addresses. Now a separate listening socket is
created for each address.

diffstat:

src/core/ngx_inet.c | 354 +++++++++++++----------------------
src/core/ngx_inet.h | 1 +
src/http/ngx_http.c | 34 +-
src/http/ngx_http_core_module.c | 81 ++++---
src/http/ngx_http_core_module.h | 5 +-
src/mail/ngx_mail.c | 42 +---
src/mail/ngx_mail.h | 3 +-
src/mail/ngx_mail_core_module.c | 83 +++----
src/stream/ngx_stream.c | 42 +---
src/stream/ngx_stream.h | 3 +-
src/stream/ngx_stream_core_module.c | 75 +++----
11 files changed, 286 insertions(+), 437 deletions(-)

diffs (truncated from 1286 to 1000 lines):

diff -r c74904a17021 -r 4f9b72a229c1 src/core/ngx_inet.c
--- a/src/core/ngx_inet.c Sat Mar 09 03:03:56 2019 +0300
+++ b/src/core/ngx_inet.c Fri Mar 15 15:45:56 2019 +0300
@@ -12,6 +12,8 @@
static ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u);
static ngx_int_t ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u);
static ngx_int_t ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u);
+static ngx_int_t ngx_inet_add_addr(ngx_pool_t *pool, ngx_url_t *u,
+ struct sockaddr *sockaddr, socklen_t socklen, ngx_uint_t total);


in_addr_t
@@ -780,13 +782,10 @@ 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 *p, *host, *port, *last, *uri, *args;
- size_t len;
- ngx_int_t n;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
+ u_char *host, *port, *last, *uri, *args;
+ size_t len;
+ ngx_int_t n;
+ struct sockaddr_in *sin;

u->socklen = sizeof(struct sockaddr_in);
sin = (struct sockaddr_in *) &u->sockaddr;
@@ -864,13 +863,15 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx

u->port = (in_port_t) n;
sin->sin_port = htons((in_port_t) n);
+ sin->sin_addr.s_addr = INADDR_ANY;

u->port_text.len = last - host;
u->port_text.data = host;

u->wildcard = 1;

- return NGX_OK;
+ return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr,
+ u->socklen, 1);
}
}
}
@@ -893,7 +894,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx
if (u->listen && len == 1 && *host == '*') {
sin->sin_addr.s_addr = INADDR_ANY;
u->wildcard = 1;
- return NGX_OK;
+ return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);
}

sin->sin_addr.s_addr = ngx_inet_addr(host, len);
@@ -904,33 +905,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx
u->wildcard = 1;
}

- u->naddrs = 1;
-
- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(sin, &u->sockaddr, sizeof(struct sockaddr_in));
-
- u->addrs[0].sockaddr = (struct sockaddr *) sin;
- u->addrs[0].socklen = sizeof(struct sockaddr_in);
-
- p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, u->port) - p;
- u->addrs[0].name.data = p;
-
- return NGX_OK;
+ return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);
}

if (u->no_resolve) {
@@ -944,29 +919,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx
u->family = u->addrs[0].sockaddr->sa_family;
u->socklen = u->addrs[0].socklen;
ngx_memcpy(&u->sockaddr, u->addrs[0].sockaddr, u->addrs[0].socklen);
-
- switch (u->family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) &u->sockaddr;
-
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- u->wildcard = 1;
- }
-
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) &u->sockaddr;
-
- if (sin->sin_addr.s_addr == INADDR_ANY) {
- u->wildcard = 1;
- }
-
- break;
- }
+ u->wildcard = ngx_inet_wildcard(&u->sockaddr.sockaddr);

return NGX_OK;
}
@@ -1061,33 +1014,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ng
}

u->family = AF_INET6;
- u->naddrs = 1;

- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));
- if (sin6 == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(sin6, &u->sockaddr, sizeof(struct sockaddr_in6));
-
- u->addrs[0].sockaddr = (struct sockaddr *) sin6;
- u->addrs[0].socklen = sizeof(struct sockaddr_in6);
-
- p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, u->port) - p;
- u->addrs[0].name.data = p;
-
- return NGX_OK;
+ return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);

#else

@@ -1104,15 +1032,9 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ng
ngx_int_t
ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
{
- u_char *p, *host;
- size_t len;
- in_port_t port;
- ngx_uint_t i;
- struct addrinfo hints, *res, *rp;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
-
- port = htons(u->port);
+ u_char *host;
+ ngx_uint_t n;
+ struct addrinfo hints, *res, *rp;

host = ngx_alloc(u->host.len + 1, pool->log);
if (host == NULL) {
@@ -1136,7 +1058,7 @@ ngx_inet_resolve_host(ngx_pool_t *pool,

ngx_free(host);

- for (i = 0, rp = res; rp != NULL; rp = rp->ai_next) {
+ for (n = 0, rp = res; rp != NULL; rp = rp->ai_next) {

switch (rp->ai_family) {

@@ -1148,25 +1070,16 @@ ngx_inet_resolve_host(ngx_pool_t *pool,
continue;
}

- i++;
+ n++;
}

- if (i == 0) {
+ if (n == 0) {
u->err = "host not found";
goto failed;
}

/* MP: ngx_shared_palloc() */

- u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- goto failed;
- }
-
- u->naddrs = i;
-
- i = 0;
-
/* AF_INET addresses first */

for (rp = res; rp != NULL; rp = rp->ai_next) {
@@ -1175,31 +1088,11 @@ ngx_inet_resolve_host(ngx_pool_t *pool,
continue;
}

- sin = ngx_pcalloc(pool, rp->ai_addrlen);
- if (sin == NULL) {
+ if (ngx_inet_add_addr(pool, u, rp->ai_addr, rp->ai_addrlen, n)
+ != NGX_OK)
+ {
goto failed;
}
-
- ngx_memcpy(sin, rp->ai_addr, rp->ai_addrlen);
-
- sin->sin_port = port;
-
- u->addrs[i].sockaddr = (struct sockaddr *) sin;
- u->addrs[i].socklen = rp->ai_addrlen;
-
- len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
-
- p = ngx_pnalloc(pool, len);
- if (p == NULL) {
- goto failed;
- }
-
- len = ngx_sock_ntop((struct sockaddr *) sin, rp->ai_addrlen, p, len, 1);
-
- u->addrs[i].name.len = len;
- u->addrs[i].name.data = p;
-
- i++;
}

for (rp = res; rp != NULL; rp = rp->ai_next) {
@@ -1208,32 +1101,11 @@ ngx_inet_resolve_host(ngx_pool_t *pool,
continue;
}

- sin6 = ngx_pcalloc(pool, rp->ai_addrlen);
- if (sin6 == NULL) {
+ if (ngx_inet_add_addr(pool, u, rp->ai_addr, rp->ai_addrlen, n)
+ != NGX_OK)
+ {
goto failed;
}
-
- ngx_memcpy(sin6, rp->ai_addr, rp->ai_addrlen);
-
- sin6->sin6_port = port;
-
- u->addrs[i].sockaddr = (struct sockaddr *) sin6;
- u->addrs[i].socklen = rp->ai_addrlen;
-
- len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
-
- p = ngx_pnalloc(pool, len);
- if (p == NULL) {
- goto failed;
- }
-
- len = ngx_sock_ntop((struct sockaddr *) sin6, rp->ai_addrlen, p,
- len, 1);
-
- u->addrs[i].name.len = len;
- u->addrs[i].name.data = p;
-
- i++;
}

freeaddrinfo(res);
@@ -1250,21 +1122,19 @@ failed:
ngx_int_t
ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
{
- u_char *p, *host;
- size_t len;
- in_port_t port;
- in_addr_t in_addr;
- ngx_uint_t i;
+ u_char *host;
+ ngx_uint_t i, n;
struct hostent *h;
- struct sockaddr_in *sin;
+ struct sockaddr_in sin;

/* AF_INET only */

- port = htons(u->port);
+ ngx_memzero(&sin, sizeof(struct sockaddr_in));

- in_addr = ngx_inet_addr(u->host.data, u->host.len);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = ngx_inet_addr(u->host.data, u->host.len);

- if (in_addr == INADDR_NONE) {
+ if (sin.sin_addr.s_addr == INADDR_NONE) {
host = ngx_alloc(u->host.len + 1, pool->log);
if (host == NULL) {
return NGX_ERROR;
@@ -1281,76 +1151,31 @@ ngx_inet_resolve_host(ngx_pool_t *pool,
return NGX_ERROR;
}

- for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
+ for (n = 0; h->h_addr_list[n] != NULL; n++) { /* void */ }

/* MP: ngx_shared_palloc() */

- u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
+ for (i = 0; i < n; i++) {
+ sin.sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);

- u->naddrs = i;
-
- for (i = 0; i < u->naddrs; i++) {
-
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
+ if (ngx_inet_add_addr(pool, u, (struct sockaddr *) &sin,
+ sizeof(struct sockaddr_in), n)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
-
- sin->sin_family = AF_INET;
- sin->sin_port = port;
- sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
-
- u->addrs[i].sockaddr = (struct sockaddr *) sin;
- u->addrs[i].socklen = sizeof(struct sockaddr_in);
-
- len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
-
- p = ngx_pnalloc(pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- len = ngx_sock_ntop((struct sockaddr *) sin,
- sizeof(struct sockaddr_in), p, len, 1);
-
- u->addrs[i].name.len = len;
- u->addrs[i].name.data = p;
}

} else {

/* MP: ngx_shared_palloc() */

- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
+ if (ngx_inet_add_addr(pool, u, (struct sockaddr *) &sin,
+ sizeof(struct sockaddr_in), 1)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
-
- u->naddrs = 1;
-
- sin->sin_family = AF_INET;
- sin->sin_port = port;
- sin->sin_addr.s_addr = in_addr;
-
- u->addrs[0].sockaddr = (struct sockaddr *) sin;
- u->addrs[0].socklen = sizeof(struct sockaddr_in);
-
- p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, ntohs(port)) - p;
- u->addrs[0].name.data = p;
}

return NGX_OK;
@@ -1359,6 +1184,62 @@ ngx_inet_resolve_host(ngx_pool_t *pool,
#endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */


+static ngx_int_t
+ngx_inet_add_addr(ngx_pool_t *pool, ngx_url_t *u, struct sockaddr *sockaddr,
+ socklen_t socklen, ngx_uint_t total)
+{
+ u_char *p;
+ size_t len;
+ ngx_addr_t *addr;
+ struct sockaddr *sa;
+
+ if (u->addrs == NULL) {
+ u->addrs = ngx_palloc(pool, total * sizeof(ngx_addr_t));
+ if (u->addrs == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ sa = ngx_pcalloc(pool, socklen);
+ if (sa == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(sa, sockaddr, socklen);
+
+ ngx_inet_set_port(sa, u->port);
+
+ switch (sa->sa_family) {
+
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65536") - 1;
+ break;
+#endif
+
+ default: /* AF_INET */
+ len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+ }
+
+ p = ngx_pnalloc(pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ len = ngx_sock_ntop(sa, socklen, p, len, 1);
+
+ addr = &u->addrs[u->naddrs++];
+
+ addr->sockaddr = sa;
+ addr->socklen = socklen;
+
+ addr->name.len = len;
+ addr->name.data = p;
+
+ return NGX_OK;
+}
+
+
ngx_int_t
ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port)
@@ -1495,3 +1376,40 @@ ngx_inet_set_port(struct sockaddr *sa, i
break;
}
}
+
+
+ngx_uint_t
+ngx_inet_wildcard(struct sockaddr *sa)
+{
+ struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
+
+ switch (sa->sa_family) {
+
+ case AF_INET:
+ sin = (struct sockaddr_in *) sa;
+
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ return 1;
+ }
+
+ break;
+
+#if (NGX_HAVE_INET6)
+
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) sa;
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ return 1;
+ }
+
+ break;
+
+#endif
+ }
+
+ return 0;
+}
diff -r c74904a17021 -r 4f9b72a229c1 src/core/ngx_inet.h
--- a/src/core/ngx_inet.h Sat Mar 09 03:03:56 2019 +0300
+++ b/src/core/ngx_inet.h Fri Mar 15 15:45:56 2019 +0300
@@ -125,6 +125,7 @@ ngx_int_t ngx_cmp_sockaddr(struct sockad
struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port);
in_port_t ngx_inet_get_port(struct sockaddr *sa);
void ngx_inet_set_port(struct sockaddr *sa, in_port_t port);
+ngx_uint_t ngx_inet_wildcard(struct sockaddr *sa);


#endif /* _NGX_INET_H_INCLUDED_ */
diff -r c74904a17021 -r 4f9b72a229c1 src/http/ngx_http.c
--- a/src/http/ngx_http.c Sat Mar 09 03:03:56 2019 +0300
+++ b/src/http/ngx_http.c Fri Mar 15 15:45:56 2019 +0300
@@ -1157,7 +1157,7 @@ ngx_http_add_listen(ngx_conf_t *cf, ngx_
}
}

- sa = &lsopt->sockaddr.sockaddr;
+ sa = lsopt->sockaddr;
p = ngx_inet_get_port(sa);

port = cmcf->ports->elts;
@@ -1209,8 +1209,8 @@ ngx_http_add_addresses(ngx_conf_t *cf, n

for (i = 0; i < port->addrs.nelts; i++) {

- if (ngx_cmp_sockaddr(&lsopt->sockaddr.sockaddr, lsopt->socklen,
- &addr[i].opt.sockaddr.sockaddr,
+ if (ngx_cmp_sockaddr(lsopt->sockaddr, lsopt->socklen,
+ addr[i].opt.sockaddr,
addr[i].opt.socklen, 0)
!= NGX_OK)
{
@@ -1239,7 +1239,8 @@ ngx_http_add_addresses(ngx_conf_t *cf, n

if (addr[i].opt.set) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate listen options for %s", addr[i].opt.addr);
+ "duplicate listen options for %V",
+ &addr[i].opt.addr_text);
return NGX_ERROR;
}

@@ -1252,7 +1253,8 @@ ngx_http_add_addresses(ngx_conf_t *cf, n

if (default_server) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "a duplicate default server for %s", addr[i].opt.addr);
+ "a duplicate default server for %V",
+ &addr[i].opt.addr_text);
return NGX_ERROR;
}

@@ -1305,8 +1307,8 @@ ngx_http_add_address(ngx_conf_t *cf, ngx
if (lsopt->http2 && lsopt->ssl) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"nginx was built with OpenSSL that lacks ALPN "
- "and NPN support, HTTP/2 is not enabled for %s",
- lsopt->addr);
+ "and NPN support, HTTP/2 is not enabled for %V",
+ &lsopt->addr_text);
}

#endif
@@ -1354,7 +1356,8 @@ ngx_http_add_server(ngx_conf_t *cf, ngx_
for (i = 0; i < addr->servers.nelts; i++) {
if (server[i] == cscf) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "a duplicate listen %s", addr->opt.addr);
+ "a duplicate listen %V",
+ &addr->opt.addr_text);
return NGX_ERROR;
}
}
@@ -1471,15 +1474,15 @@ ngx_http_server_names(ngx_conf_t *cf, ng

if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "invalid server name or wildcard \"%V\" on %s",
- &name[n].name, addr->opt.addr);
+ "invalid server name or wildcard \"%V\" on %V",
+ &name[n].name, &addr->opt.addr_text);
return NGX_ERROR;
}

if (rc == NGX_BUSY) {
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
- "conflicting server name \"%V\" on %s, ignored",
- &name[n].name, addr->opt.addr);
+ "conflicting server name \"%V\" on %V, ignored",
+ &name[n].name, &addr->opt.addr_text);
}
}
}
@@ -1700,8 +1703,7 @@ ngx_http_add_listening(ngx_conf_t *cf, n
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t *cscf;

- ls = ngx_create_listening(cf, &addr->opt.sockaddr.sockaddr,
- addr->opt.socklen);
+ ls = ngx_create_listening(cf, addr->opt.sockaddr, addr->opt.socklen);
if (ls == NULL) {
return NULL;
}
@@ -1791,7 +1793,7 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h

for (i = 0; i < hport->naddrs; i++) {

- sin = &addr[i].opt.sockaddr.sockaddr_in;
+ sin = (struct sockaddr_in *) addr[i].opt.sockaddr;
addrs[i].addr = sin->sin_addr.s_addr;
addrs[i].conf.default_server = addr[i].default_server;
#if (NGX_HTTP_SSL)
@@ -1856,7 +1858,7 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_

for (i = 0; i < hport->naddrs; i++) {

- sin6 = &addr[i].opt.sockaddr.sockaddr_in6;
+ sin6 = (struct sockaddr_in6 *) addr[i].opt.sockaddr;
addrs6[i].addr6 = sin6->sin6_addr;
addrs6[i].conf.default_server = addr[i].default_server;
#if (NGX_HTTP_SSL)
diff -r c74904a17021 -r 4f9b72a229c1 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Sat Mar 09 03:03:56 2019 +0300
+++ b/src/http/ngx_http_core_module.c Fri Mar 15 15:45:56 2019 +0300
@@ -2715,6 +2715,8 @@ ngx_http_core_server(ngx_conf_t *cf, ngx
{
char *rv;
void *mconf;
+ size_t len;
+ u_char *p;
ngx_uint_t i;
ngx_conf_t pcf;
ngx_http_module_t *module;
@@ -2802,7 +2804,14 @@ ngx_http_core_server(ngx_conf_t *cf, ngx
if (rv == NGX_CONF_OK && !cscf->listen) {
ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));

- sin = &lsopt.sockaddr.sockaddr_in;
+ p = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ lsopt.sockaddr = (struct sockaddr *) p;
+
+ sin = (struct sockaddr_in *) p;

sin->sin_family = AF_INET;
#if (NGX_WIN32)
@@ -2825,8 +2834,16 @@ ngx_http_core_server(ngx_conf_t *cf, ngx
#endif
lsopt.wildcard = 1;

- (void) ngx_sock_ntop(&lsopt.sockaddr.sockaddr, lsopt.socklen,
- lsopt.addr, NGX_SOCKADDR_STRLEN, 1);
+ len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+
+ p = ngx_pnalloc(cf->pool, len);
+ if (p == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ lsopt.addr_text.data = p;
+ lsopt.addr_text.len = ngx_sock_ntop(lsopt.sockaddr, lsopt.socklen, p,
+ len, 1);

if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
return NGX_CONF_ERROR;
@@ -3779,9 +3796,6 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx

ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));

- ngx_memcpy(&lsopt.sockaddr.sockaddr, &u.sockaddr, u.socklen);
-
- lsopt.socklen = u.socklen;
lsopt.backlog = NGX_LISTEN_BACKLOG;
lsopt.rcvbuf = -1;
lsopt.sndbuf = -1;
@@ -3791,14 +3805,10 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
#if (NGX_HAVE_TCP_FASTOPEN)
lsopt.fastopen = -1;
#endif
- lsopt.wildcard = u.wildcard;
#if (NGX_HAVE_INET6)
lsopt.ipv6only = 1;
#endif

- (void) ngx_sock_ntop(&lsopt.sockaddr.sockaddr, lsopt.socklen, lsopt.addr,
- NGX_SOCKADDR_STRLEN, 1);
-
for (n = 2; n < cf->args->nelts; n++) {

if (ngx_strcmp(value[n].data, "default_server") == 0
@@ -3923,34 +3933,22 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx

if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- struct sockaddr *sa;
-
- sa = &lsopt.sockaddr.sockaddr;
-
- if (sa->sa_family == AF_INET6) {
-
- if (ngx_strcmp(&value[n].data[10], "n") == 0) {
- lsopt.ipv6only = 1;
-
- } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
- lsopt.ipv6only = 0;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid ipv6only flags \"%s\"",
- &value[n].data[9]);
- return NGX_CONF_ERROR;
- }
-
- lsopt.set = 1;
- lsopt.bind = 1;
+ if (ngx_strcmp(&value[n].data[10], "n") == 0) {
+ lsopt.ipv6only = 1;
+
+ } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
+ lsopt.ipv6only = 0;

} else {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "ipv6only is not supported "
- "on addr \"%s\", ignored", lsopt.addr);
+ "invalid ipv6only flags \"%s\"",
+ &value[n].data[9]);
+ return NGX_CONF_ERROR;
}

+ lsopt.set = 1;
+ lsopt.bind = 1;
+
continue;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -4106,11 +4104,18 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
return NGX_CONF_ERROR;
}

- if (ngx_http_add_listen(cf, cscf, &lsopt) == NGX_OK) {
- return NGX_CONF_OK;
- }
-
- return NGX_CONF_ERROR;
+ for (n = 0; n < u.naddrs; n++) {
+ lsopt.sockaddr = u.addrs[n].sockaddr;
+ lsopt.socklen = u.addrs[n].socklen;
+ lsopt.addr_text = u.addrs[n].name;
+ lsopt.wildcard = ngx_inet_wildcard(lsopt.sockaddr);
+
+ if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ return NGX_CONF_OK;
}


diff -r c74904a17021 -r 4f9b72a229c1 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Sat Mar 09 03:03:56 2019 +0300
+++ b/src/http/ngx_http_core_module.h Fri Mar 15 15:45:56 2019 +0300
@@ -65,8 +65,9 @@ typedef struct ngx_http_core_loc_conf_s


typedef struct {
- ngx_sockaddr_t sockaddr;
+ struct sockaddr *sockaddr;
socklen_t socklen;
+ ngx_str_t addr_text;

unsigned set:1;
unsigned default_server:1;
@@ -100,8 +101,6 @@ typedef struct {
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
char *accept_filter;
#endif
-
- u_char addr[NGX_SOCKADDR_STRLEN + 1];
} ngx_http_listen_opt_t;


diff -r c74904a17021 -r 4f9b72a229c1 src/mail/ngx_mail.c
--- a/src/mail/ngx_mail.c Sat Mar 09 03:03:56 2019 +0300
+++ b/src/mail/ngx_mail.c Fri Mar 15 15:45:56 2019 +0300
@@ -231,7 +231,7 @@ ngx_mail_add_ports(ngx_conf_t *cf, ngx_a
ngx_mail_conf_port_t *port;
ngx_mail_conf_addr_t *addr;

- sa = &listen->sockaddr.sockaddr;
+ sa = listen->sockaddr;
p = ngx_inet_get_port(sa);

port = ports->elts;
@@ -316,7 +316,7 @@ ngx_mail_optimize_servers(ngx_conf_t *cf
continue;
}

- ls = ngx_create_listening(cf, &addr[i].opt.sockaddr.sockaddr,
+ ls = ngx_create_listening(cf, addr[i].opt.sockaddr,
addr[i].opt.socklen);
if (ls == NULL) {
return NGX_CONF_ERROR;
@@ -384,12 +384,9 @@ static ngx_int_t
ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport,
ngx_mail_conf_addr_t *addr)
{
- u_char *p;
- size_t len;
ngx_uint_t i;
ngx_mail_in_addr_t *addrs;
struct sockaddr_in *sin;
- u_char buf[NGX_SOCKADDR_STRLEN];

mport->addrs = ngx_pcalloc(cf->pool,
mport->naddrs * sizeof(ngx_mail_in_addr_t));
@@ -401,26 +398,14 @@ ngx_mail_add_addrs(ngx_conf_t *cf, ngx_m

for (i = 0; i < mport->naddrs; i++) {

- sin = &addr[i].opt.sockaddr.sockaddr_in;
+ sin = (struct sockaddr_in *) addr[i].opt.sockaddr;
addrs[i].addr = sin->sin_addr.s_addr;

addrs[i].conf.ctx = addr[i].opt.ctx;
#if (NGX_MAIL_SSL)
addrs[i].conf.ssl = addr[i].opt.ssl;
#endif
-
- len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen,
- buf, NGX_SOCKADDR_STRLEN, 1);
-
- p = ngx_pnalloc(cf->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(p, buf, len);
-
- addrs[i].conf.addr_text.len = len;
- addrs[i].conf.addr_text.data = p;
+ addrs[i].conf.addr_text = addr[i].opt.addr_text;
}

return NGX_OK;
@@ -433,12 +418,9 @@ static ngx_int_t
ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport,
ngx_mail_conf_addr_t *addr)
{
- u_char *p;
- size_t len;
ngx_uint_t i;
ngx_mail_in6_addr_t *addrs6;
struct sockaddr_in6 *sin6;
- u_char buf[NGX_SOCKADDR_STRLEN];

mport->addrs = ngx_pcalloc(cf->pool,
mport->naddrs * sizeof(ngx_mail_in6_addr_t));
@@ -450,26 +432,14 @@ ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_

for (i = 0; i < mport->naddrs; i++) {

- sin6 = &addr[i].opt.sockaddr.sockaddr_in6;
+ sin6 = (struct sockaddr_in6 *) addr[i].opt.sockaddr;
addrs6[i].addr6 = sin6->sin6_addr;

addrs6[i].conf.ctx = addr[i].opt.ctx;
#if (NGX_MAIL_SSL)
addrs6[i].conf.ssl = addr[i].opt.ssl;
#endif
-
- len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen,
- buf, NGX_SOCKADDR_STRLEN, 1);
-
- p = ngx_pnalloc(cf->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(p, buf, len);
-
- addrs6[i].conf.addr_text.len = len;
- addrs6[i].conf.addr_text.data = p;
+ addrs6[i].conf.addr_text = addr[i].opt.addr_text;
}

return NGX_OK;
diff -r c74904a17021 -r 4f9b72a229c1 src/mail/ngx_mail.h
--- a/src/mail/ngx_mail.h Sat Mar 09 03:03:56 2019 +0300
+++ b/src/mail/ngx_mail.h Fri Mar 15 15:45:56 2019 +0300
@@ -27,8 +27,9 @@ typedef struct {


typedef struct {
- ngx_sockaddr_t sockaddr;
+ struct sockaddr *sockaddr;
socklen_t socklen;
+ ngx_str_t addr_text;

/* server ctx */
ngx_mail_conf_ctx_t *ctx;
diff -r c74904a17021 -r 4f9b72a229c1 src/mail/ngx_mail_core_module.c
--- a/src/mail/ngx_mail_core_module.c Sat Mar 09 03:03:56 2019 +0300
+++ b/src/mail/ngx_mail_core_module.c Fri Mar 15 15:45:56 2019 +0300
@@ -297,8 +297,8 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx

ngx_str_t *value, size;
ngx_url_t u;
- ngx_uint_t i, m;
- ngx_mail_listen_t *ls;
+ ngx_uint_t i, n, m;
+ ngx_mail_listen_t *ls, *als;
ngx_mail_module_t *module;
ngx_mail_core_main_conf_t *cmcf;

@@ -323,36 +323,16 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx

cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);

- ls = cmcf->listen.elts;
-
- for (i = 0; i < cmcf->listen.nelts; i++) {
-
- if (ngx_cmp_sockaddr(&ls[i].sockaddr.sockaddr, ls[i].socklen,
- (struct sockaddr *) &u.sockaddr, u.socklen, 1)
- != NGX_OK)
- {
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate \"%V\" address and port pair", &u.url);
- return NGX_CONF_ERROR;
- }
-
- ls = ngx_array_push(&cmcf->listen);
+ ls = ngx_array_push_n(&cmcf->listen, u.naddrs);
if (ls == NULL) {
return NGX_CONF_ERROR;
}

ngx_memzero(ls, sizeof(ngx_mail_listen_t));

- ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen);
-
- ls->socklen = u.socklen;
ls->backlog = NGX_LISTEN_BACKLOG;
ls->rcvbuf = -1;
ls->sndbuf = -1;
- ls->wildcard = u.wildcard;
ls->ctx = cf->ctx;

#if (NGX_HAVE_INET6)
@@ -434,35 +414,20 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx

if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- size_t len;
- u_char buf[NGX_SOCKADDR_STRLEN];
-
- if (ls->sockaddr.sockaddr.sa_family == AF_INET6) {
-
- if (ngx_strcmp(&value[i].data[10], "n") == 0) {
- ls->ipv6only = 1;
+ if (ngx_strcmp(&value[i].data[10], "n") == 0) {
+ ls->ipv6only = 1;

- } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
- ls->ipv6only = 0;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid ipv6only flags \"%s\"",
- &value[i].data[9]);
- return NGX_CONF_ERROR;
- }
-
- ls->bind = 1;
+ } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
+ ls->ipv6only = 0;

} else {
- len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf,
- NGX_SOCKADDR_STRLEN, 1);
-
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "ipv6only is not supported "
- "on addr \"%*s\", ignored", len, buf);
+ "invalid ipv6only flags \"%s\"",
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] Multiple addresses in "listen".

Roman Arutyunyan 259 March 21, 2019 07:10AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 160
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready