Mercurial > hg > nginx-mail
diff src/mail/ngx_mail_core_module.c @ 570:9773720b845e
Merge with 0.8.16.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 26 Sep 2009 01:25:07 +0400 |
parents | 1e91f9968443 f39b9e29530d |
children |
line wrap: on
line diff
--- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -120,20 +120,20 @@ ngx_mail_core_create_main_conf(ngx_conf_ cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t)); if (cmcf == NULL) { - return NGX_CONF_ERROR; + return NULL; } if (ngx_array_init(&cmcf->servers, cf->pool, 4, sizeof(ngx_mail_core_srv_conf_t *)) != NGX_OK) { - return NGX_CONF_ERROR; + return NULL; } if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) != NGX_OK) { - return NGX_CONF_ERROR; + return NULL; } return cmcf; @@ -274,19 +274,24 @@ ngx_mail_core_server(ngx_conf_t *cf, ngx } -/* AF_INET only */ - static char * ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_mail_core_srv_conf_t *cscf = conf; + size_t len, off; + in_port_t port; ngx_str_t *value; ngx_url_t u; ngx_uint_t i, m; - ngx_mail_listen_t *imls; + struct sockaddr *sa; + ngx_mail_listen_t *ls; ngx_mail_module_t *module; + struct sockaddr_in *sin; ngx_mail_core_main_conf_t *cmcf; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif value = cf->args->elts; @@ -305,18 +310,42 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx return NGX_CONF_ERROR; } - if (u.family != AF_INET) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "listen supports IPv4 only"); - return NGX_CONF_ERROR; - } - cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); - imls = cmcf->listen.elts; + ls = cmcf->listen.elts; for (i = 0; i < cmcf->listen.nelts; i++) { - if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) { + sa = (struct sockaddr *) ls[i].sockaddr; + + if (sa->sa_family != u.family) { + continue; + } + + switch (sa->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + off = offsetof(struct sockaddr_in6, sin6_addr); + len = 16; + sin6 = (struct sockaddr_in6 *) sa; + port = sin6->sin6_port; + break; +#endif + + default: /* AF_INET */ + off = offsetof(struct sockaddr_in, sin_addr); + len = 4; + sin = (struct sockaddr_in *) sa; + port = sin->sin_port; + break; + } + + if (ngx_memcmp(ls[i].sockaddr + off, u.sockaddr + off, len) != 0) { + continue; + } + + if (port != u.port) { continue; } @@ -325,17 +354,18 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx return NGX_CONF_ERROR; } - imls = ngx_array_push(&cmcf->listen); - if (imls == NULL) { + ls = ngx_array_push(&cmcf->listen); + if (ls == NULL) { return NGX_CONF_ERROR; } - ngx_memzero(imls, sizeof(ngx_mail_listen_t)); + ngx_memzero(ls, sizeof(ngx_mail_listen_t)); + + ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen); - imls->addr = u.addr.in_addr; - imls->port = u.port; - imls->family = u.family; - imls->ctx = cf->ctx; + ls->socklen = u.socklen; + ls->wildcard = u.wildcard; + ls->ctx = cf->ctx; for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_MAIL_MODULE) { @@ -359,13 +389,54 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx for (i = 2; i < cf->args->nelts; i++) { if (ngx_strcmp(value[i].data, "bind") == 0) { - imls->bind = 1; + ls->bind = 1; continue; } + if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { +#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) + struct sockaddr *sa; + u_char buf[NGX_SOCKADDR_STRLEN]; + + sa = (struct sockaddr *) ls->sockaddr; + + if (sa->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 = 2; + + } 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 { + len = ngx_sock_ntop(sa, buf, NGX_SOCKADDR_STRLEN, 1); + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "ipv6only is not supported " + "on addr \"%*s\", ignored", len, buf); + } + + continue; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "bind ipv6only is not supported " + "on this platform"); + return NGX_CONF_ERROR; +#endif + } + if (ngx_strcmp(value[i].data, "ssl") == 0) { #if (NGX_MAIL_SSL) - imls->ssl = 1; + ls->ssl = 1; continue; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,