diff options
author | Roman Arutyunyan <arut@nginx.com> | 2019-03-15 15:45:56 +0300 |
---|---|---|
committer | Roman Arutyunyan <arut@nginx.com> | 2019-03-15 15:45:56 +0300 |
commit | 4e17b93eb6787e99a4023f20f8c391284f86bbf3 (patch) | |
tree | df9c59da4e3e13dff0c7d48cec7bf0ca76d2e9cb /src/stream/ngx_stream_core_module.c | |
parent | 59c34b67952c2ebee6760ca3115ba19e65060b58 (diff) | |
download | nginx-4e17b93eb6787e99a4023f20f8c391284f86bbf3.tar.gz nginx-4e17b93eb6787e99a4023f20f8c391284f86bbf3.zip |
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 (limited to 'src/stream/ngx_stream_core_module.c')
-rw-r--r-- | src/stream/ngx_stream_core_module.c | 75 |
1 files changed, 33 insertions, 42 deletions
diff --git a/src/stream/ngx_stream_core_module.c b/src/stream/ngx_stream_core_module.c index 3c4027b77..9b6afe974 100644 --- a/src/stream/ngx_stream_core_module.c +++ b/src/stream/ngx_stream_core_module.c @@ -577,7 +577,7 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_str_t *value, size; ngx_url_t u; - ngx_uint_t i, backlog; + ngx_uint_t i, n, backlog; ngx_stream_listen_t *ls, *als; ngx_stream_core_main_conf_t *cmcf; @@ -602,21 +602,17 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - 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_stream_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->type = SOCK_STREAM; - ls->wildcard = u.wildcard; ls->ctx = cf->ctx; #if (NGX_HAVE_INET6) @@ -688,35 +684,20 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 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; - - } 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; - } + if (ngx_strcmp(&value[i].data[10], "n") == 0) { + ls->ipv6only = 1; - 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\"", + &value[i].data[9]); + return NGX_CONF_ERROR; } + ls->bind = 1; continue; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -882,21 +863,31 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) als = cmcf->listen.elts; - for (i = 0; i < cmcf->listen.nelts - 1; i++) { - if (ls->type != als[i].type) { - continue; - } + for (n = 0; n < u.naddrs; n++) { + ls[n] = ls[0]; - if (ngx_cmp_sockaddr(&als[i].sockaddr.sockaddr, als[i].socklen, - &ls->sockaddr.sockaddr, ls->socklen, 1) - != NGX_OK) - { - continue; - } + ls[n].sockaddr = u.addrs[n].sockaddr; + ls[n].socklen = u.addrs[n].socklen; + ls[n].addr_text = u.addrs[n].name; + ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr); - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate \"%V\" address and port pair", &u.url); - return NGX_CONF_ERROR; + for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) { + if (ls[n].type != als[i].type) { + continue; + } + + if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen, + ls[n].sockaddr, ls[n].socklen, 1) + != NGX_OK) + { + continue; + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "duplicate \"%V\" address and port pair", + &ls[n].addr_text); + return NGX_CONF_ERROR; + } } return NGX_CONF_OK; |