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/mail | |
| parent | 59c34b67952c2ebee6760ca3115ba19e65060b58 (diff) | |
| download | nginx-4e17b93eb6787e99a4023f20f8c391284f86bbf3.tar.gz nginx-4e17b93eb6787e99a4023f20f8c391284f86bbf3.tar.bz2 | |
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/mail')
| -rw-r--r-- | src/mail/ngx_mail.c | 42 | ||||
| -rw-r--r-- | src/mail/ngx_mail.h | 3 | ||||
| -rw-r--r-- | src/mail/ngx_mail_core_module.c | 83 |
3 files changed, 45 insertions, 83 deletions
diff --git a/src/mail/ngx_mail.c b/src/mail/ngx_mail.c index 5fd5fa00c..f17c2ccc3 100644 --- a/src/mail/ngx_mail.c +++ b/src/mail/ngx_mail.c @@ -231,7 +231,7 @@ ngx_mail_add_ports(ngx_conf_t *cf, ngx_array_t *ports, 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, ngx_array_t *ports) 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_mail_port_t *mport, 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_mail_port_t *mport, 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 --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h index 6ecfefc98..d904f25f1 100644 --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -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 --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c index dd4e9802b..e16d70238 100644 --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -297,8 +297,8 @@ ngx_mail_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, 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_command_t *cmd, void *conf) 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_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, @@ -588,6 +553,32 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 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; } |
