Mercurial > hg > nginx
diff src/mail/ngx_mail_core_module.c @ 7478:4f9b72a229c1
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.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Fri, 15 Mar 2019 15:45:56 +0300 |
parents | 7f955d3b9a0d |
children | 12ea1de7d87c |
line wrap: on
line diff
--- 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_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 @@ 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 @@ 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\"", + &value[i].data[9]); + return NGX_CONF_ERROR; } + ls->bind = 1; continue; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -588,6 +553,32 @@ return NGX_CONF_ERROR; } + als = cmcf->listen.elts; + + for (n = 0; n < u.naddrs; n++) { + ls[n] = ls[0]; + + 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); + + for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) { + + 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; }