mirror of
https://github.com/nginx/nginx.git
synced 2024-12-04 13:59:00 +08:00
a prelimiary IPv6 support, HTTP listen
This commit is contained in:
parent
a883361c47
commit
a35eaccdec
@ -43,6 +43,8 @@ EVENT_AIO=NO
|
|||||||
|
|
||||||
USE_THREADS=NO
|
USE_THREADS=NO
|
||||||
|
|
||||||
|
NGX_IPV6=NO
|
||||||
|
|
||||||
HTTP=YES
|
HTTP=YES
|
||||||
|
|
||||||
NGX_HTTP_LOG_PATH=
|
NGX_HTTP_LOG_PATH=
|
||||||
@ -160,6 +162,8 @@ do
|
|||||||
#--with-threads=*) USE_THREADS="$value" ;;
|
#--with-threads=*) USE_THREADS="$value" ;;
|
||||||
#--with-threads) USE_THREADS="pthreads" ;;
|
#--with-threads) USE_THREADS="pthreads" ;;
|
||||||
|
|
||||||
|
--with-ipv6) NGX_IPV6=YES ;;
|
||||||
|
|
||||||
--without-http) HTTP=NO ;;
|
--without-http) HTTP=NO ;;
|
||||||
--http-log-path=*) NGX_HTTP_LOG_PATH="$value" ;;
|
--http-log-path=*) NGX_HTTP_LOG_PATH="$value" ;;
|
||||||
--http-client-body-temp-path=*) NGX_HTTP_CLIENT_TEMP_PATH="$value" ;;
|
--http-client-body-temp-path=*) NGX_HTTP_CLIENT_TEMP_PATH="$value" ;;
|
||||||
@ -285,6 +289,8 @@ cat << END
|
|||||||
--with-poll_module enable poll module
|
--with-poll_module enable poll module
|
||||||
--without-poll_module disable poll module
|
--without-poll_module disable poll module
|
||||||
|
|
||||||
|
--with-ipv6 enable ipv6 support
|
||||||
|
|
||||||
--with-http_ssl_module enable ngx_http_ssl_module
|
--with-http_ssl_module enable ngx_http_ssl_module
|
||||||
--with-http_realip_module enable ngx_http_realip_module
|
--with-http_realip_module enable ngx_http_realip_module
|
||||||
--with-http_addition_module enable ngx_http_addition_module
|
--with-http_addition_module enable ngx_http_addition_module
|
||||||
|
15
auto/unix
15
auto/unix
@ -64,6 +64,21 @@ ngx_param=NGX_TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
|
|||||||
# syscalls, libc calls and some features
|
# syscalls, libc calls and some features
|
||||||
|
|
||||||
|
|
||||||
|
if [ $NGX_IPV6 = YES ]; then
|
||||||
|
ngx_feature="AF_INET6"
|
||||||
|
ngx_feature_name="NGX_HAVE_INET6"
|
||||||
|
ngx_feature_run=no
|
||||||
|
ngx_feature_incs="#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>"
|
||||||
|
ngx_feature_path=
|
||||||
|
ngx_feature_libs=
|
||||||
|
ngx_feature_test="struct sockaddr_in6 sin6;
|
||||||
|
sin6.sin6_family = AF_INET6;"
|
||||||
|
. auto/feature
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
ngx_feature="setproctitle()"
|
ngx_feature="setproctitle()"
|
||||||
ngx_feature_name="NGX_HAVE_SETPROCTITLE"
|
ngx_feature_name="NGX_HAVE_SETPROCTITLE"
|
||||||
ngx_feature_run=no
|
ngx_feature_run=no
|
||||||
|
@ -52,7 +52,6 @@ ngx_listening_inet_stream_socket(ngx_conf_t *cf, in_addr_t addr, in_port_t port)
|
|||||||
ls->type = SOCK_STREAM;
|
ls->type = SOCK_STREAM;
|
||||||
ls->sockaddr = (struct sockaddr *) sin;
|
ls->sockaddr = (struct sockaddr *) sin;
|
||||||
ls->socklen = sizeof(struct sockaddr_in);
|
ls->socklen = sizeof(struct sockaddr_in);
|
||||||
ls->addr = offsetof(struct sockaddr_in, sin_addr);
|
|
||||||
ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
|
ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
|
||||||
|
|
||||||
return ls;
|
return ls;
|
||||||
@ -65,7 +64,6 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
|
|||||||
size_t len;
|
size_t len;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_listening_t *ls;
|
ngx_listening_t *ls;
|
||||||
struct sockaddr_in *sin;
|
|
||||||
socklen_t olen;
|
socklen_t olen;
|
||||||
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
|
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
|
||||||
ngx_err_t err;
|
ngx_err_t err;
|
||||||
@ -94,33 +92,39 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sin = (struct sockaddr_in *) ls[i].sockaddr;
|
switch (ls[i].sockaddr->sa_family) {
|
||||||
|
|
||||||
if (sin->sin_family != AF_INET) {
|
#if (NGX_HAVE_INET6)
|
||||||
|
case AF_INET6:
|
||||||
|
ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case AF_INET:
|
||||||
|
ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
|
ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
|
||||||
"the inherited socket #%d has "
|
"the inherited socket #%d has "
|
||||||
"unsupported family", ls[i].fd);
|
"an unsupported protocol family", ls[i].fd);
|
||||||
ls[i].ignore = 1;
|
ls[i].ignore = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
|
len = ls[i].addr_text_max_len + sizeof(":65535") - 1;
|
||||||
|
|
||||||
ls[i].addr_text.data = ngx_pnalloc(cycle->pool,
|
ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
|
||||||
NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1);
|
|
||||||
if (ls[i].addr_text.data == NULL) {
|
if (ls[i].addr_text.data == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ngx_sock_ntop(ls[i].sockaddr, ls[i].addr_text.data,
|
len = ngx_sock_ntop(ls[i].sockaddr, ls[i].addr_text.data, len, 1);
|
||||||
NGX_INET_ADDRSTRLEN);
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ls[i].addr_text.len = ngx_sprintf(ls[i].addr_text.data + len, ":%d",
|
ls[i].addr_text.len = len;
|
||||||
ntohs(sin->sin_port))
|
|
||||||
- ls[i].addr_text.data;
|
|
||||||
|
|
||||||
ls[i].backlog = NGX_LISTEN_BACKLOG;
|
ls[i].backlog = NGX_LISTEN_BACKLOG;
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ struct ngx_listening_s {
|
|||||||
|
|
||||||
struct sockaddr *sockaddr;
|
struct sockaddr *sockaddr;
|
||||||
socklen_t socklen; /* size of sockaddr */
|
socklen_t socklen; /* size of sockaddr */
|
||||||
size_t addr; /* offset to address in sockaddr */
|
|
||||||
size_t addr_text_max_len;
|
size_t addr_text_max_len;
|
||||||
ngx_str_t addr_text;
|
ngx_str_t addr_text;
|
||||||
|
|
||||||
@ -123,10 +122,8 @@ struct ngx_connection_s {
|
|||||||
ngx_ssl_connection_t *ssl;
|
ngx_ssl_connection_t *ssl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (NGX_HAVE_IOCP)
|
|
||||||
struct sockaddr *local_sockaddr;
|
struct sockaddr *local_sockaddr;
|
||||||
socklen_t local_socklen;
|
socklen_t local_socklen;
|
||||||
#endif
|
|
||||||
|
|
||||||
ngx_buf_t *buffer;
|
ngx_buf_t *buffer;
|
||||||
|
|
||||||
|
@ -876,23 +876,47 @@ ngx_destroy_cycle_pools(ngx_conf_t *conf)
|
|||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2)
|
ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2)
|
||||||
{
|
{
|
||||||
struct sockaddr_in *sin1, *sin2;
|
struct sockaddr_in *sin1, *sin2;
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
struct sockaddr_in6 *sin61, *sin62;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* AF_INET only */
|
if (sa1->sa_family != sa2->sa_family) {
|
||||||
|
|
||||||
if (sa1->sa_family != AF_INET || sa2->sa_family != AF_INET) {
|
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
sin1 = (struct sockaddr_in *) sa1;
|
switch (sa1->sa_family) {
|
||||||
sin2 = (struct sockaddr_in *) sa2;
|
|
||||||
|
|
||||||
if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
|
#if (NGX_HAVE_INET6)
|
||||||
return NGX_DECLINED;
|
case AF_INET6:
|
||||||
}
|
sin61 = (struct sockaddr_in6 *) sa1;
|
||||||
|
sin62 = (struct sockaddr_in6 *) sa2;
|
||||||
|
|
||||||
if (sin1->sin_port != sin2->sin_port) {
|
if (sin61->sin6_port != sin61->sin6_port) {
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_memcmp(&sin61->sin6_addr, &sin62->sin6_addr, 16) != 0) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: /* AF_INET */
|
||||||
|
|
||||||
|
sin1 = (struct sockaddr_in *) sa1;
|
||||||
|
sin2 = (struct sockaddr_in *) sa2;
|
||||||
|
|
||||||
|
if (sin1->sin_port != sin2->sin_port) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
static size_t ngx_inet6_ntop(u_char *p, u_char *text, size_t len);
|
||||||
|
#endif
|
||||||
static ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u);
|
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_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);
|
||||||
|
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
in_addr_t
|
in_addr_t
|
||||||
ngx_inet_addr(u_char *text, size_t len)
|
ngx_inet_addr(u_char *text, size_t len)
|
||||||
{
|
{
|
||||||
@ -57,25 +59,58 @@ ngx_inet_addr(u_char *text, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len)
|
ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
size_t n;
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sa->sa_family == AF_INET) {
|
switch (sa->sa_family) {
|
||||||
|
|
||||||
|
case AF_INET:
|
||||||
|
|
||||||
sin = (struct sockaddr_in *) sa;
|
sin = (struct sockaddr_in *) sa;
|
||||||
p = (u_char *) &sin->sin_addr;
|
p = (u_char *) &sin->sin_addr;
|
||||||
|
|
||||||
return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
|
if (port) {
|
||||||
p[0], p[1], p[2], p[3])
|
p = ngx_snprintf(text, len, "%ud.%ud.%ud.%ud:%d",
|
||||||
- text;
|
p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
|
||||||
}
|
} else {
|
||||||
|
p = ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
|
||||||
|
p[0], p[1], p[2], p[3]);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return (p - text);
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
|
||||||
|
sin6 = (struct sockaddr_in6 *) sa;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
if (port) {
|
||||||
|
text[n++] = '[';
|
||||||
|
}
|
||||||
|
|
||||||
|
n = ngx_inet6_ntop((u_char *) &sin6->sin6_addr, &text[n], len);
|
||||||
|
|
||||||
|
if (port) {
|
||||||
|
n = ngx_sprintf(&text[1 + n], "]:%d",
|
||||||
|
ntohs(sin6->sin6_port)) - text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -84,18 +119,109 @@ ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
|
|||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
|
|
||||||
if (family == AF_INET) {
|
switch (family) {
|
||||||
|
|
||||||
p = (u_char *) addr;
|
case AF_INET:
|
||||||
|
|
||||||
|
p = addr;
|
||||||
|
|
||||||
return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
|
return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
|
||||||
p[0], p[1], p[2], p[3])
|
p[0], p[1], p[2], p[3])
|
||||||
- text;
|
- text;
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
return ngx_inet6_ntop(addr, text, len);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
ngx_inet6_ntop(u_char *p, u_char *text, size_t len)
|
||||||
|
{
|
||||||
|
u_char *dst;
|
||||||
|
size_t max, n;
|
||||||
|
ngx_uint_t i, zero, last;
|
||||||
|
|
||||||
|
if (len < NGX_INET6_ADDRSTRLEN) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
zero = (ngx_uint_t) -1;
|
||||||
|
last = (ngx_uint_t) -1;
|
||||||
|
max = 1;
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i += 2) {
|
||||||
|
|
||||||
|
if (p[i] || p[i + 1]) {
|
||||||
|
|
||||||
|
if (max < n) {
|
||||||
|
zero = last;
|
||||||
|
max = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n++ == 0) {
|
||||||
|
last = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max < n) {
|
||||||
|
zero = last;
|
||||||
|
max = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = text;
|
||||||
|
n = 16;
|
||||||
|
|
||||||
|
if (zero == 0) {
|
||||||
|
|
||||||
|
if ((max == 5 && p[10] == 0xff && p[11] == 0xff)
|
||||||
|
|| (max == 6)
|
||||||
|
|| (max == 7 && p[14] != 0 && p[15] != 1))
|
||||||
|
{
|
||||||
|
n = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst++ = ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i += 2) {
|
||||||
|
|
||||||
|
if (i == zero) {
|
||||||
|
*dst++ = ':';
|
||||||
|
i += (max - 1) * 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = ngx_sprintf(dst, "%uxi", p[i] * 256 + p[i + 1]);
|
||||||
|
|
||||||
|
if (i < 14) {
|
||||||
|
*dst++ = ':';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 12) {
|
||||||
|
dst = ngx_sprintf(dst, "%ud.%ud.%ud.%ud", p[12], p[13], p[14], p[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst - text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* AF_INET only */
|
/* AF_INET only */
|
||||||
|
|
||||||
@ -171,6 +297,10 @@ ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p[0] == '[') {
|
||||||
|
return ngx_parse_inet6_url(pool, u);
|
||||||
|
}
|
||||||
|
|
||||||
return ngx_parse_inet_url(pool, u);
|
return ngx_parse_inet_url(pool, u);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,13 +339,17 @@ ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
|
|
||||||
u->host.len = len++;
|
u->host.len = len++;
|
||||||
u->host.data = path;
|
u->host.data = path;
|
||||||
u->family = AF_UNIX;
|
|
||||||
|
|
||||||
if (len > sizeof(saun->sun_path)) {
|
if (len > sizeof(saun->sun_path)) {
|
||||||
u->err = "too long path in the unix domain socket";
|
u->err = "too long path in the unix domain socket";
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u->socklen = sizeof(struct sockaddr_un);
|
||||||
|
saun = (struct sockaddr_un *) &u->sockaddr;
|
||||||
|
saun->sun_family = AF_UNIX;
|
||||||
|
(void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
|
||||||
|
|
||||||
u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
|
u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
|
||||||
if (u->addrs == NULL) {
|
if (u->addrs == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
@ -226,6 +360,7 @@ ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u->family = AF_UNIX;
|
||||||
u->naddrs = 1;
|
u->naddrs = 1;
|
||||||
|
|
||||||
saun->sun_family = AF_UNIX;
|
saun->sun_family = AF_UNIX;
|
||||||
@ -251,10 +386,15 @@ ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
||||||
{
|
{
|
||||||
u_char *p, *host, *port, *last, *uri, *args;
|
u_char *p, *host, *port, *last, *uri, *args;
|
||||||
size_t len;
|
size_t len;
|
||||||
ngx_int_t n;
|
ngx_int_t n;
|
||||||
struct hostent *h;
|
struct hostent *h;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
|
u->socklen = sizeof(struct sockaddr_in);
|
||||||
|
sin = (struct sockaddr_in *) &u->sockaddr;
|
||||||
|
sin->sin_family = AF_INET;
|
||||||
|
|
||||||
u->family = AF_INET;
|
u->family = AF_INET;
|
||||||
|
|
||||||
@ -311,6 +451,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
}
|
}
|
||||||
|
|
||||||
u->port = (in_port_t) n;
|
u->port = (in_port_t) n;
|
||||||
|
sin->sin_port = htons((in_port_t) n);
|
||||||
|
|
||||||
u->port_text.len = len;
|
u->port_text.len = len;
|
||||||
u->port_text.data = port;
|
u->port_text.data = port;
|
||||||
@ -334,10 +475,13 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
}
|
}
|
||||||
|
|
||||||
u->port = (in_port_t) n;
|
u->port = (in_port_t) n;
|
||||||
|
sin->sin_port = htons((in_port_t) n);
|
||||||
|
|
||||||
u->port_text.len = last - host;
|
u->port_text.len = last - host;
|
||||||
u->port_text.data = host;
|
u->port_text.data = host;
|
||||||
|
|
||||||
|
u->wildcard = 1;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,8 +518,9 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
(void) ngx_cpystrn(p, host, len);
|
(void) ngx_cpystrn(p, host, len);
|
||||||
|
|
||||||
u->addr.in_addr = inet_addr((const char *) p);
|
u->addr.in_addr = inet_addr((const char *) p);
|
||||||
|
sin->sin_addr.s_addr = inet_addr((const char *) p);
|
||||||
|
|
||||||
if (u->addr.in_addr == INADDR_NONE) {
|
if (sin->sin_addr.s_addr == INADDR_NONE) {
|
||||||
h = gethostbyname((const char *) p);
|
h = gethostbyname((const char *) p);
|
||||||
|
|
||||||
if (h == NULL || h->h_addr_list[0] == NULL) {
|
if (h == NULL || h->h_addr_list[0] == NULL) {
|
||||||
@ -385,16 +530,24 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
}
|
}
|
||||||
|
|
||||||
u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
|
u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
|
||||||
|
sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sin->sin_addr.s_addr == INADDR_ANY) {
|
||||||
|
u->wildcard = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_free(p);
|
ngx_free(p);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
u->addr.in_addr = INADDR_ANY;
|
u->addr.in_addr = INADDR_ANY;
|
||||||
|
sin->sin_addr.s_addr = INADDR_ANY;
|
||||||
|
u->wildcard = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->no_port) {
|
if (u->no_port) {
|
||||||
u->port = u->default_port;
|
u->port = u->default_port;
|
||||||
|
sin->sin_port = htons(u->default_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->listen) {
|
if (u->listen) {
|
||||||
@ -409,11 +562,134 @@ 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)
|
||||||
|
{
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
int rc;
|
||||||
|
u_char *p, *host, *port, *last, *uri;
|
||||||
|
size_t len;
|
||||||
|
ngx_int_t n;
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
|
||||||
|
u->socklen = sizeof(struct sockaddr_in6);
|
||||||
|
sin6 = (struct sockaddr_in6 *) &u->sockaddr;
|
||||||
|
sin6->sin6_family = AF_INET6;
|
||||||
|
|
||||||
|
host = u->url.data + 1;
|
||||||
|
|
||||||
|
last = u->url.data + u->url.len;
|
||||||
|
|
||||||
|
p = ngx_strlchr(host, last, ']');
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
u->err = "invalid host";
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last - p) {
|
||||||
|
|
||||||
|
port = p + 1;
|
||||||
|
|
||||||
|
uri = ngx_strlchr(port, last, '/');
|
||||||
|
|
||||||
|
if (uri) {
|
||||||
|
if (u->listen || !u->uri_part) {
|
||||||
|
u->err = "invalid host";
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->uri.len = last - uri;
|
||||||
|
u->uri.data = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*port == ':') {
|
||||||
|
port++;
|
||||||
|
|
||||||
|
len = last - port;
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
u->err = "invalid port";
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = ngx_atoi(port, len);
|
||||||
|
|
||||||
|
if (n < 1 || n > 65536) {
|
||||||
|
u->err = "invalid port";
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->port = (in_port_t) n;
|
||||||
|
sin6->sin6_port = htons((in_port_t) n);
|
||||||
|
|
||||||
|
u->port_text.len = len;
|
||||||
|
u->port_text.data = port;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
u->no_port = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = p - host;
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
u->err = "no host";
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->host.len = len++;
|
||||||
|
u->host.data = host;
|
||||||
|
|
||||||
|
p = ngx_alloc(len, pool->log);
|
||||||
|
if (p == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) ngx_cpystrn(p, host, len);
|
||||||
|
|
||||||
|
rc = inet_pton(AF_INET6, (const char *) p, &sin6->sin6_addr);
|
||||||
|
|
||||||
|
ngx_free(p);
|
||||||
|
|
||||||
|
if (rc == 0) {
|
||||||
|
u->err = "invalid IPv6 address";
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||||
|
u->wildcard = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->family = AF_INET6;
|
||||||
|
|
||||||
|
if (u->no_resolve) {
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->no_port) {
|
||||||
|
u->port = u->default_port;
|
||||||
|
sin6->sin6_port = htons(u->default_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
u->err = "the INET6 sockets are not supported on this platform";
|
||||||
|
|
||||||
|
return NGX_ERROR;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
|
ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
|
||||||
{
|
{
|
||||||
u_char *p, *host;
|
u_char *p, *host;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
in_port_t port;
|
||||||
in_addr_t in_addr;
|
in_addr_t in_addr;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
struct hostent *h;
|
struct hostent *h;
|
||||||
@ -428,6 +704,9 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
|
|
||||||
/* AF_INET only */
|
/* AF_INET only */
|
||||||
|
|
||||||
|
sin = (struct sockaddr_in *) &u->sockaddr;
|
||||||
|
port = sin->sin_port;
|
||||||
|
|
||||||
in_addr = inet_addr((char *) host);
|
in_addr = inet_addr((char *) host);
|
||||||
|
|
||||||
if (in_addr == INADDR_NONE) {
|
if (in_addr == INADDR_NONE) {
|
||||||
@ -464,22 +743,22 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
sin->sin_port = htons(u->port);
|
sin->sin_port = port;
|
||||||
sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
|
sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
|
||||||
|
|
||||||
u->addrs[i].sockaddr = (struct sockaddr *) sin;
|
u->addrs[i].sockaddr = (struct sockaddr *) sin;
|
||||||
u->addrs[i].socklen = sizeof(struct sockaddr_in);
|
u->addrs[i].socklen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
|
len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
|
||||||
|
|
||||||
p = ngx_pnalloc(pool, len);
|
p = ngx_pnalloc(pool, len);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ngx_sock_ntop((struct sockaddr *) sin, p, len);
|
len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
|
||||||
|
|
||||||
u->addrs[i].name.len = ngx_sprintf(&p[len], ":%d", u->port) - p;
|
u->addrs[i].name.len = len;
|
||||||
u->addrs[i].name.data = p;
|
u->addrs[i].name.data = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,18 +781,19 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
|
|||||||
u->naddrs = 1;
|
u->naddrs = 1;
|
||||||
|
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
sin->sin_port = htons(u->port);
|
sin->sin_port = port;
|
||||||
sin->sin_addr.s_addr = in_addr;
|
sin->sin_addr.s_addr = in_addr;
|
||||||
|
|
||||||
u->addrs[0].sockaddr = (struct sockaddr *) sin;
|
u->addrs[0].sockaddr = (struct sockaddr *) sin;
|
||||||
u->addrs[0].socklen = sizeof(struct sockaddr_in);
|
u->addrs[0].socklen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
p = ngx_pnalloc(pool, u->host.len + sizeof(":65536") - 1);
|
p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->addrs[0].name.len = ngx_sprintf(p, "%V:%d", &u->host, u->port) - p;
|
u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
|
||||||
|
&u->host, ntohs(port)) - p;
|
||||||
u->addrs[0].name.data = p;
|
u->addrs[0].name.data = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,25 @@
|
|||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
|
|
||||||
|
|
||||||
#define NGX_INET_ADDRSTRLEN (sizeof("255.255.255.255") - 1)
|
#define NGX_INET_ADDRSTRLEN (sizeof("255.255.255.255") - 1)
|
||||||
|
#define NGX_INET6_ADDRSTRLEN \
|
||||||
|
(sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") - 1)
|
||||||
|
|
||||||
|
#define NGX_SOCKADDR_STRLEN (NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: autoconfigure NGX_SOCKADDRLEN as
|
||||||
|
* sizeof(struct sockaddr_storage)
|
||||||
|
* sizeof(struct sockaddr_in6)
|
||||||
|
* sizeof(struct sockaddr_in)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
#define NGX_SOCKADDRLEN sizeof(struct sockaddr_in6)
|
||||||
|
#else
|
||||||
|
#define NGX_SOCKADDRLEN sizeof(struct sockaddr_in)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -49,9 +67,13 @@ typedef struct {
|
|||||||
unsigned one_addr:1;
|
unsigned one_addr:1;
|
||||||
|
|
||||||
unsigned no_port:1;
|
unsigned no_port:1;
|
||||||
|
unsigned wildcard:1;
|
||||||
|
|
||||||
ngx_url_addr_t addr;
|
ngx_url_addr_t addr;
|
||||||
|
|
||||||
|
socklen_t socklen;
|
||||||
|
u_char sockaddr[NGX_SOCKADDRLEN];
|
||||||
|
|
||||||
ngx_peer_addr_t *addrs;
|
ngx_peer_addr_t *addrs;
|
||||||
ngx_uint_t naddrs;
|
ngx_uint_t naddrs;
|
||||||
|
|
||||||
@ -60,7 +82,8 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
in_addr_t ngx_inet_addr(u_char *text, size_t len);
|
in_addr_t ngx_inet_addr(u_char *text, size_t len);
|
||||||
size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len);
|
size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len,
|
||||||
|
ngx_uint_t port);
|
||||||
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
|
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
|
||||||
ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
|
ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
|
||||||
ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
|
ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
|
||||||
|
@ -9,10 +9,6 @@
|
|||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
|
|
||||||
|
|
||||||
/* the buffer size is enough to hold "struct sockaddr_un" */
|
|
||||||
#define NGX_SOCKLEN 512
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
|
static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
|
||||||
static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
|
static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
|
||||||
static void ngx_close_accepted_connection(ngx_connection_t *c);
|
static void ngx_close_accepted_connection(ngx_connection_t *c);
|
||||||
@ -29,7 +25,7 @@ ngx_event_accept(ngx_event_t *ev)
|
|||||||
ngx_listening_t *ls;
|
ngx_listening_t *ls;
|
||||||
ngx_connection_t *c, *lc;
|
ngx_connection_t *c, *lc;
|
||||||
ngx_event_conf_t *ecf;
|
ngx_event_conf_t *ecf;
|
||||||
char sa[NGX_SOCKLEN];
|
u_char sa[NGX_SOCKADDRLEN];
|
||||||
|
|
||||||
ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
|
ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
|
||||||
|
|
||||||
@ -48,7 +44,7 @@ ngx_event_accept(ngx_event_t *ev)
|
|||||||
"accept on %V, ready: %d", &ls->addr_text, ev->available);
|
"accept on %V, ready: %d", &ls->addr_text, ev->available);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
socklen = NGX_SOCKLEN;
|
socklen = NGX_SOCKADDRLEN;
|
||||||
|
|
||||||
s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
|
s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
|
||||||
|
|
||||||
@ -153,8 +149,10 @@ ngx_event_accept(ngx_event_t *ev)
|
|||||||
c->log = log;
|
c->log = log;
|
||||||
c->pool->log = log;
|
c->pool->log = log;
|
||||||
|
|
||||||
c->listening = ls;
|
|
||||||
c->socklen = socklen;
|
c->socklen = socklen;
|
||||||
|
c->listening = ls;
|
||||||
|
c->local_sockaddr = ls->sockaddr;
|
||||||
|
c->local_socklen = ls->socklen;
|
||||||
|
|
||||||
c->unexpected_eof = 1;
|
c->unexpected_eof = 1;
|
||||||
|
|
||||||
@ -208,7 +206,7 @@ ngx_event_accept(ngx_event_t *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->addr_text.data,
|
c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->addr_text.data,
|
||||||
ls->addr_text_max_len);
|
ls->addr_text_max_len, 0);
|
||||||
if (c->addr_text.len == 0) {
|
if (c->addr_text.len == 0) {
|
||||||
ngx_close_accepted_connection(c);
|
ngx_close_accepted_connection(c);
|
||||||
return;
|
return;
|
||||||
|
@ -66,7 +66,7 @@ ngx_event_acceptex(ngx_event_t *rev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->addr_text.data,
|
c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->addr_text.data,
|
||||||
c->listening->addr_text_max_len);
|
c->listening->addr_text_max_len, 0);
|
||||||
if (c->addr_text.len == 0) {
|
if (c->addr_text.len == 0) {
|
||||||
/* TODO: close socket */
|
/* TODO: close socket */
|
||||||
return;
|
return;
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
#include <ngx_http.h>
|
#include <ngx_http.h>
|
||||||
|
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_addr_t mask;
|
in_addr_t mask;
|
||||||
in_addr_t addr;
|
in_addr_t addr;
|
||||||
@ -103,6 +101,10 @@ ngx_http_access_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
/* AF_INET only */
|
/* AF_INET only */
|
||||||
|
|
||||||
|
if (r->connection->sockaddr->sa_family != AF_INET) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||||
|
|
||||||
rule = alcf->rules->elts;
|
rule = alcf->rules->elts;
|
||||||
|
@ -175,6 +175,10 @@ ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
|
|||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
"http geo started: %V", &r->connection->addr_text);
|
"http geo started: %V", &r->connection->addr_text);
|
||||||
|
|
||||||
|
if (r->connection->sockaddr->sa_family != AF_INET) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||||
return ntohl(sin->sin_addr.s_addr);
|
return ntohl(sin->sin_addr.s_addr);
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
#define NGX_HTTP_REALIP_HEADER 2
|
#define NGX_HTTP_REALIP_HEADER 2
|
||||||
|
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_addr_t mask;
|
in_addr_t mask;
|
||||||
in_addr_t addr;
|
in_addr_t addr;
|
||||||
@ -209,6 +207,10 @@ found:
|
|||||||
|
|
||||||
/* AF_INET only */
|
/* AF_INET only */
|
||||||
|
|
||||||
|
if (r->connection->sockaddr->sa_family != AF_INET) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
sin = (struct sockaddr_in *) c->sockaddr;
|
sin = (struct sockaddr_in *) c->sockaddr;
|
||||||
|
|
||||||
from = rlcf->from->elts;
|
from = rlcf->from->elts;
|
||||||
|
@ -15,7 +15,6 @@ typedef struct {
|
|||||||
|
|
||||||
ngx_uint_t hash;
|
ngx_uint_t hash;
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
u_char addr[3];
|
u_char addr[3];
|
||||||
|
|
||||||
u_char tries;
|
u_char tries;
|
||||||
@ -111,11 +110,20 @@ ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
|
|||||||
r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
|
r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
|
||||||
|
|
||||||
/* AF_INET only */
|
/* AF_INET only */
|
||||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
|
||||||
p = (u_char *) &sin->sin_addr.s_addr;
|
if (r->connection->sockaddr->sa_family == AF_INET) {
|
||||||
iphp->addr[0] = p[0];
|
|
||||||
iphp->addr[1] = p[1];
|
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||||
iphp->addr[2] = p[2];
|
p = (u_char *) &sin->sin_addr.s_addr;
|
||||||
|
iphp->addr[0] = p[0];
|
||||||
|
iphp->addr[1] = p[1];
|
||||||
|
iphp->addr[2] = p[2];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
iphp->addr[0] = 0;
|
||||||
|
iphp->addr[1] = 0;
|
||||||
|
iphp->addr[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
iphp->hash = 89;
|
iphp->hash = 89;
|
||||||
iphp->tries = 0;
|
iphp->tries = 0;
|
||||||
|
@ -20,16 +20,16 @@ static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf,
|
|||||||
static ngx_int_t ngx_http_init_server_lists(ngx_conf_t *cf,
|
static ngx_int_t ngx_http_init_server_lists(ngx_conf_t *cf,
|
||||||
ngx_array_t *servers, ngx_array_t *in_ports);
|
ngx_array_t *servers, ngx_array_t *in_ports);
|
||||||
static ngx_int_t ngx_http_add_ports(ngx_conf_t *cf,
|
static ngx_int_t ngx_http_add_ports(ngx_conf_t *cf,
|
||||||
ngx_http_core_srv_conf_t *cscf, ngx_array_t *in_ports,
|
ngx_http_core_srv_conf_t *cscf, ngx_array_t *ports,
|
||||||
ngx_http_listen_t *listen);
|
ngx_http_listen_t *listen);
|
||||||
static ngx_int_t ngx_http_add_addresses(ngx_conf_t *cf,
|
static ngx_int_t ngx_http_add_addresses(ngx_conf_t *cf,
|
||||||
ngx_http_core_srv_conf_t *cscf, ngx_http_conf_in_port_t *in_port,
|
ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
|
||||||
ngx_http_listen_t *listen);
|
ngx_http_listen_t *listen);
|
||||||
static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
|
static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
|
||||||
ngx_http_core_srv_conf_t *cscf, ngx_http_conf_in_port_t *in_port,
|
ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
|
||||||
ngx_http_listen_t *listen);
|
ngx_http_listen_t *listen);
|
||||||
static ngx_int_t ngx_http_add_names(ngx_conf_t *cf,
|
static ngx_int_t ngx_http_add_names(ngx_conf_t *cf,
|
||||||
ngx_http_core_srv_conf_t *cscf, ngx_http_conf_in_addr_t *in_addr);
|
ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr);
|
||||||
|
|
||||||
static char *ngx_http_merge_locations(ngx_conf_t *cf,
|
static char *ngx_http_merge_locations(ngx_conf_t *cf,
|
||||||
ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module,
|
ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module,
|
||||||
@ -49,15 +49,23 @@ static ngx_http_location_tree_node_t *
|
|||||||
size_t prefix);
|
size_t prefix);
|
||||||
|
|
||||||
static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf,
|
static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf,
|
||||||
ngx_http_core_main_conf_t *cmcf, ngx_array_t *in_ports);
|
ngx_http_core_main_conf_t *cmcf, ngx_array_t *ports);
|
||||||
static ngx_int_t ngx_http_server_names(ngx_conf_t *cf,
|
static ngx_int_t ngx_http_server_names(ngx_conf_t *cf,
|
||||||
ngx_http_core_main_conf_t *cmcf, ngx_http_conf_in_addr_t *in_addr);
|
ngx_http_core_main_conf_t *cmcf, ngx_http_conf_addr_t *addr);
|
||||||
static ngx_int_t ngx_http_cmp_conf_in_addrs(const void *one, const void *two);
|
static ngx_int_t ngx_http_cmp_conf_addrs(const void *one, const void *two);
|
||||||
static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
|
static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
|
||||||
const void *two);
|
const void *two);
|
||||||
|
|
||||||
static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf,
|
static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf,
|
||||||
ngx_http_conf_in_port_t *in_port);
|
ngx_http_conf_port_t *port);
|
||||||
|
static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf,
|
||||||
|
ngx_http_conf_addr_t *addr);
|
||||||
|
static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
|
||||||
|
ngx_http_conf_addr_t *addr);
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
static ngx_int_t ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
|
||||||
|
ngx_http_conf_addr_t *addr);
|
||||||
|
#endif
|
||||||
|
|
||||||
ngx_uint_t ngx_http_max_module;
|
ngx_uint_t ngx_http_max_module;
|
||||||
|
|
||||||
@ -359,8 +367,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
* to find quickly the server core module configuration at run-time
|
* to find quickly the server core module configuration at run-time
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
if (ngx_http_init_server_lists(cf, &cmcf->servers, &in_ports) != NGX_OK) {
|
if (ngx_http_init_server_lists(cf, &cmcf->servers, &in_ports) != NGX_OK) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
@ -368,8 +374,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
/* optimize the lists of ports, addresses and server names */
|
/* optimize the lists of ports, addresses and server names */
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
if (ngx_http_optimize_servers(cf, cmcf, &in_ports) != NGX_OK) {
|
if (ngx_http_optimize_servers(cf, cmcf, &in_ports) != NGX_OK) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
@ -1107,14 +1111,13 @@ inclusive:
|
|||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers,
|
ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers,
|
||||||
ngx_array_t *in_ports)
|
ngx_array_t *ports)
|
||||||
{
|
{
|
||||||
ngx_uint_t s, i;
|
ngx_uint_t s, i;
|
||||||
ngx_http_listen_t *listen;
|
ngx_http_listen_t *listen;
|
||||||
ngx_http_core_srv_conf_t **cscfp;
|
ngx_http_core_srv_conf_t **cscfp;
|
||||||
|
|
||||||
if (ngx_array_init(in_ports, cf->temp_pool, 2,
|
if (ngx_array_init(ports, cf->temp_pool, 2, sizeof(ngx_http_conf_port_t))
|
||||||
sizeof(ngx_http_conf_in_port_t))
|
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
@ -1130,11 +1133,7 @@ ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers,
|
|||||||
listen = cscfp[s]->listen.elts;
|
listen = cscfp[s]->listen.elts;
|
||||||
for (i = 0; i < cscfp[s]->listen.nelts; i++) {
|
for (i = 0; i < cscfp[s]->listen.nelts; i++) {
|
||||||
|
|
||||||
/* AF_INET only */
|
if (ngx_http_add_ports(cf, cscfp[s], ports, &listen[i]) != NGX_OK) {
|
||||||
|
|
||||||
if (ngx_http_add_ports(cf, cscfp[s], in_ports, &listen[i])
|
|
||||||
!= NGX_OK)
|
|
||||||
{
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1144,70 +1143,116 @@ ngx_http_init_server_lists(ngx_conf_t *cf, ngx_array_t *servers,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_add_ports(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
ngx_http_add_ports(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||||
ngx_array_t *in_ports, ngx_http_listen_t *listen)
|
ngx_array_t *ports, ngx_http_listen_t *listen)
|
||||||
{
|
{
|
||||||
|
in_port_t p;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_http_conf_in_port_t *in_port;
|
struct sockaddr *sa;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
ngx_http_conf_port_t *port;
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
|
||||||
in_port = in_ports->elts;
|
sa = (struct sockaddr *) &listen->sockaddr;
|
||||||
for (i = 0; i < in_ports->nelts; i++) {
|
|
||||||
|
|
||||||
if (listen->port != in_port[i].port) {
|
switch (sa->sa_family) {
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
case AF_INET6:
|
||||||
|
sin6 = (struct sockaddr_in6 *) sa;
|
||||||
|
p = sin6->sin6_port;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: /* AF_INET */
|
||||||
|
sin = (struct sockaddr_in *) sa;
|
||||||
|
p = sin->sin_port;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
port = ports->elts;
|
||||||
|
for (i = 0; i < ports->nelts; i++) {
|
||||||
|
|
||||||
|
if (p != port[i].port || sa->sa_family != port[i].family) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a port is already in the in_port list */
|
/* a port is already in the in_port list */
|
||||||
|
|
||||||
return ngx_http_add_addresses(cf, cscf, &in_port[i], listen);
|
return ngx_http_add_addresses(cf, cscf, &port[i], listen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a port to the in_port list */
|
/* add a port to the in_port list */
|
||||||
|
|
||||||
in_port = ngx_array_push(in_ports);
|
port = ngx_array_push(ports);
|
||||||
if (in_port == NULL) {
|
if (port == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_port->port = listen->port;
|
port->family = sa->sa_family;
|
||||||
in_port->addrs.elts = NULL;
|
port->port = p;
|
||||||
|
port->addrs.elts = NULL;
|
||||||
|
|
||||||
return ngx_http_add_address(cf, cscf, in_port, listen);
|
return ngx_http_add_address(cf, cscf, port, listen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||||
ngx_http_conf_in_port_t *in_port, ngx_http_listen_t *listen)
|
ngx_http_conf_port_t *port, ngx_http_listen_t *listen)
|
||||||
{
|
{
|
||||||
ngx_uint_t i;
|
u_char *p;
|
||||||
ngx_http_conf_in_addr_t *in_addr;
|
size_t len, off;
|
||||||
|
ngx_uint_t i;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
ngx_http_conf_addr_t *addr;
|
||||||
|
|
||||||
in_addr = in_port->addrs.elts;
|
/*
|
||||||
|
* we can not compare whole sockaddr struct's as kernel
|
||||||
|
* may fill some fields in inherited sockaddr struct's
|
||||||
|
*/
|
||||||
|
|
||||||
for (i = 0; i < in_port->addrs.nelts; i++) {
|
sa = (struct sockaddr *) &listen->sockaddr;
|
||||||
|
|
||||||
if (listen->addr != in_addr[i].addr) {
|
switch (sa->sa_family) {
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
case AF_INET6:
|
||||||
|
off = offsetof(struct sockaddr_in6, sin6_addr);
|
||||||
|
len = 16;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: /* AF_INET */
|
||||||
|
off = offsetof(struct sockaddr_in, sin_addr);
|
||||||
|
len = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = listen->sockaddr + off;
|
||||||
|
|
||||||
|
addr = port->addrs.elts;
|
||||||
|
|
||||||
|
for (i = 0; i < port->addrs.nelts; i++) {
|
||||||
|
|
||||||
|
if (ngx_memcmp(p, (u_char *) addr[i].sockaddr + off, len) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the address is already in the address list */
|
/* the address is already in the address list */
|
||||||
|
|
||||||
if (ngx_http_add_names(cf, cscf, &in_addr[i]) != NGX_OK) {
|
if (ngx_http_add_names(cf, cscf, &addr[i]) != NGX_OK) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* check the duplicate "default" server for this address:port */
|
||||||
* check the duplicate "default" server
|
|
||||||
* for this address:port
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (listen->conf.default_server) {
|
if (listen->conf.default_server) {
|
||||||
|
|
||||||
if (in_addr[i].default_server) {
|
if (addr[i].default_server) {
|
||||||
ngx_log_error(NGX_LOG_ERR, cf->log, 0,
|
ngx_log_error(NGX_LOG_ERR, cf->log, 0,
|
||||||
"the duplicate default server in %s:%ui",
|
"the duplicate default server in %s:%ui",
|
||||||
listen->file_name, listen->line);
|
listen->file_name, listen->line);
|
||||||
@ -1215,23 +1260,20 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_addr[i].core_srv_conf = cscf;
|
addr[i].core_srv_conf = cscf;
|
||||||
in_addr[i].default_server = 1;
|
addr[i].default_server = 1;
|
||||||
#if (NGX_HTTP_SSL)
|
#if (NGX_HTTP_SSL)
|
||||||
in_addr[i].ssl = listen->conf.ssl;
|
addr[i].ssl = listen->conf.ssl;
|
||||||
#endif
|
#endif
|
||||||
in_addr[i].listen_conf = &listen->conf;
|
addr[i].listen_conf = &listen->conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* add the address to the addresses list that bound to this port */
|
||||||
* add the address to the addresses list that
|
|
||||||
* bound to this port
|
|
||||||
*/
|
|
||||||
|
|
||||||
return ngx_http_add_address(cf, cscf, in_port, listen);
|
return ngx_http_add_address(cf, cscf, port, listen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1242,60 +1284,62 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
|||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||||
ngx_http_conf_in_port_t *in_port, ngx_http_listen_t *listen)
|
ngx_http_conf_port_t *port, ngx_http_listen_t *listen)
|
||||||
{
|
{
|
||||||
ngx_http_conf_in_addr_t *in_addr;
|
ngx_http_conf_addr_t *addr;
|
||||||
|
|
||||||
if (in_port->addrs.elts == NULL) {
|
if (port->addrs.elts == NULL) {
|
||||||
if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4,
|
if (ngx_array_init(&port->addrs, cf->temp_pool, 4,
|
||||||
sizeof(ngx_http_conf_in_addr_t))
|
sizeof(ngx_http_conf_addr_t))
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in_addr = ngx_array_push(&in_port->addrs);
|
addr = ngx_array_push(&port->addrs);
|
||||||
if (in_addr == NULL) {
|
if (addr == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_addr->addr = listen->addr;
|
addr->sockaddr = (struct sockaddr *) &listen->sockaddr;
|
||||||
in_addr->hash.buckets = NULL;
|
addr->socklen = listen->socklen;
|
||||||
in_addr->hash.size = 0;
|
addr->hash.buckets = NULL;
|
||||||
in_addr->wc_head = NULL;
|
addr->hash.size = 0;
|
||||||
in_addr->wc_tail = NULL;
|
addr->wc_head = NULL;
|
||||||
in_addr->names.elts = NULL;
|
addr->wc_tail = NULL;
|
||||||
|
addr->names.elts = NULL;
|
||||||
#if (NGX_PCRE)
|
#if (NGX_PCRE)
|
||||||
in_addr->nregex = 0;
|
addr->nregex = 0;
|
||||||
in_addr->regex = NULL;
|
addr->regex = NULL;
|
||||||
#endif
|
#endif
|
||||||
in_addr->core_srv_conf = cscf;
|
addr->core_srv_conf = cscf;
|
||||||
in_addr->default_server = listen->conf.default_server;
|
addr->default_server = listen->conf.default_server;
|
||||||
in_addr->bind = listen->conf.bind;
|
addr->bind = listen->conf.bind;
|
||||||
|
addr->wildcard = listen->conf.wildcard;
|
||||||
#if (NGX_HTTP_SSL)
|
#if (NGX_HTTP_SSL)
|
||||||
in_addr->ssl = listen->conf.ssl;
|
addr->ssl = listen->conf.ssl;
|
||||||
#endif
|
#endif
|
||||||
in_addr->listen_conf = &listen->conf;
|
addr->listen_conf = &listen->conf;
|
||||||
|
|
||||||
return ngx_http_add_names(cf, cscf, in_addr);
|
return ngx_http_add_names(cf, cscf, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add the server names and the server core module
|
* add the server names and the server core module
|
||||||
* configurations to the address:port (in_addr)
|
* configurations to the address:port
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||||
ngx_http_conf_in_addr_t *in_addr)
|
ngx_http_conf_addr_t *addr)
|
||||||
{
|
{
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_http_server_name_t *server_names, *name;
|
ngx_http_server_name_t *server_names, *name;
|
||||||
|
|
||||||
if (in_addr->names.elts == NULL) {
|
if (addr->names.elts == NULL) {
|
||||||
if (ngx_array_init(&in_addr->names, cf->temp_pool, 4,
|
if (ngx_array_init(&addr->names, cf->temp_pool, 4,
|
||||||
sizeof(ngx_http_server_name_t))
|
sizeof(ngx_http_server_name_t))
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
@ -1313,7 +1357,7 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
|||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||||
"name: %V", &server_names[i].name);
|
"name: %V", &server_names[i].name);
|
||||||
|
|
||||||
name = ngx_array_push(&in_addr->names);
|
name = ngx_array_push(&addr->names);
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -1327,35 +1371,35 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
|||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
||||||
ngx_array_t *in_ports)
|
ngx_array_t *ports)
|
||||||
{
|
{
|
||||||
ngx_uint_t s, p, a;
|
ngx_uint_t s, p, a;
|
||||||
|
ngx_http_conf_port_t *port;
|
||||||
|
ngx_http_conf_addr_t *addr;
|
||||||
ngx_http_server_name_t *name;
|
ngx_http_server_name_t *name;
|
||||||
ngx_http_conf_in_port_t *in_port;
|
|
||||||
ngx_http_conf_in_addr_t *in_addr;
|
|
||||||
|
|
||||||
in_port = in_ports->elts;
|
port = ports->elts;
|
||||||
for (p = 0; p < in_ports->nelts; p++) {
|
for (p = 0; p < ports->nelts; p++) {
|
||||||
|
|
||||||
ngx_sort(in_port[p].addrs.elts, (size_t) in_port[p].addrs.nelts,
|
ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
|
||||||
sizeof(ngx_http_conf_in_addr_t), ngx_http_cmp_conf_in_addrs);
|
sizeof(ngx_http_conf_addr_t), ngx_http_cmp_conf_addrs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check whether all name-based servers have the same
|
* check whether all name-based servers have the same
|
||||||
* configuraiton as a default server for given address:port
|
* configuraiton as a default server for given address:port
|
||||||
*/
|
*/
|
||||||
|
|
||||||
in_addr = in_port[p].addrs.elts;
|
addr = port[p].addrs.elts;
|
||||||
for (a = 0; a < in_port[p].addrs.nelts; a++) {
|
for (a = 0; a < port[p].addrs.nelts; a++) {
|
||||||
|
|
||||||
name = in_addr[a].names.elts;
|
name = addr[a].names.elts;
|
||||||
for (s = 0; s < in_addr[a].names.nelts; s++) {
|
for (s = 0; s < addr[a].names.nelts; s++) {
|
||||||
|
|
||||||
if (in_addr[a].core_srv_conf == name[s].core_srv_conf) {
|
if (addr[a].core_srv_conf == name[s].core_srv_conf) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_http_server_names(cf, cmcf, &in_addr[a]) != NGX_OK) {
|
if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1363,7 +1407,7 @@ ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_http_init_listening(cf, &in_port[p]) != NGX_OK) {
|
if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1374,7 +1418,7 @@ ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
||||||
ngx_http_conf_in_addr_t *in_addr)
|
ngx_http_conf_addr_t *addr)
|
||||||
{
|
{
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_uint_t s;
|
ngx_uint_t s;
|
||||||
@ -1400,9 +1444,9 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = in_addr->names.elts;
|
name = addr->names.elts;
|
||||||
|
|
||||||
for (s = 0; s < in_addr->names.nelts; s++) {
|
for (s = 0; s < addr->names.nelts; s++) {
|
||||||
|
|
||||||
#if (NGX_PCRE)
|
#if (NGX_PCRE)
|
||||||
if (name[s].regex) {
|
if (name[s].regex) {
|
||||||
@ -1421,14 +1465,14 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
if (rc == NGX_DECLINED) {
|
if (rc == NGX_DECLINED) {
|
||||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||||
"invalid server name or wildcard \"%V\" on %s",
|
"invalid server name or wildcard \"%V\" on %s",
|
||||||
&name[s].name, in_addr->listen_conf->addr);
|
&name[s].name, addr->listen_conf->addr);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == NGX_BUSY) {
|
if (rc == NGX_BUSY) {
|
||||||
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
|
||||||
"conflicting server name \"%V\" on %s, ignored",
|
"conflicting server name \"%V\" on %s, ignored",
|
||||||
&name[s].name, in_addr->listen_conf->addr);
|
&name[s].name, addr->listen_conf->addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1439,7 +1483,7 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
hash.pool = cf->pool;
|
hash.pool = cf->pool;
|
||||||
|
|
||||||
if (ha.keys.nelts) {
|
if (ha.keys.nelts) {
|
||||||
hash.hash = &in_addr->hash;
|
hash.hash = &addr->hash;
|
||||||
hash.temp_pool = NULL;
|
hash.temp_pool = NULL;
|
||||||
|
|
||||||
if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) {
|
if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) {
|
||||||
@ -1462,7 +1506,7 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_addr->wc_head = (ngx_hash_wildcard_t *) hash.hash;
|
addr->wc_head = (ngx_hash_wildcard_t *) hash.hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ha.dns_wc_tail.nelts) {
|
if (ha.dns_wc_tail.nelts) {
|
||||||
@ -1480,7 +1524,7 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash;
|
addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_destroy_pool(ha.temp_pool);
|
ngx_destroy_pool(ha.temp_pool);
|
||||||
@ -1491,16 +1535,15 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_addr->nregex = regex;
|
addr->nregex = regex;
|
||||||
in_addr->regex = ngx_palloc(cf->pool,
|
addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t));
|
||||||
regex * sizeof(ngx_http_server_name_t));
|
if (addr->regex == NULL) {
|
||||||
if (in_addr->regex == NULL) {
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, s = 0; s < in_addr->names.nelts; s++) {
|
for (i = 0, s = 0; s < addr->names.nelts; s++) {
|
||||||
if (name[s].regex) {
|
if (name[s].regex) {
|
||||||
in_addr->regex[i++] = name[s];
|
addr->regex[i++] = name[s];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1517,15 +1560,15 @@ failed:
|
|||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_cmp_conf_in_addrs(const void *one, const void *two)
|
ngx_http_cmp_conf_addrs(const void *one, const void *two)
|
||||||
{
|
{
|
||||||
ngx_http_conf_in_addr_t *first, *second;
|
ngx_http_conf_addr_t *first, *second;
|
||||||
|
|
||||||
first = (ngx_http_conf_in_addr_t *) one;
|
first = (ngx_http_conf_addr_t *) one;
|
||||||
second = (ngx_http_conf_in_addr_t *) two;
|
second = (ngx_http_conf_addr_t *) two;
|
||||||
|
|
||||||
if (first->addr == INADDR_ANY) {
|
if (first->wildcard) {
|
||||||
/* the INADDR_ANY must be the last resort, shift it to the end */
|
/* a wildcard address must be the last resort, shift it to the end */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1558,171 +1601,302 @@ ngx_http_cmp_dns_wildcards(const void *one, const void *two)
|
|||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port)
|
ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port)
|
||||||
{
|
{
|
||||||
ngx_uint_t i, a, last, bind_all, done;
|
ngx_uint_t i, a, last, bind_wildcard;
|
||||||
ngx_listening_t *ls;
|
ngx_listening_t *ls;
|
||||||
ngx_http_in_port_t *hip;
|
ngx_http_port_t *hport;
|
||||||
ngx_http_conf_in_addr_t *in_addr;
|
ngx_http_conf_addr_t *addr;
|
||||||
ngx_http_virtual_names_t *vn;
|
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
|
||||||
|
|
||||||
in_addr = in_port->addrs.elts;
|
addr = port->addrs.elts;
|
||||||
last = in_port->addrs.nelts;
|
last = port->addrs.nelts;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if there is a binding to a "*:port" then we need to bind()
|
* If there is a binding to an "*:port" then we need to bind() to
|
||||||
* to the "*:port" only and ignore other bindings
|
* the "*:port" only and ignore other implicit bindings. The bindings
|
||||||
|
* have been already sorted: explicit bindings are on the start, then
|
||||||
|
* implicit bindings go, and wildcard binding is in the end.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (in_addr[last - 1].addr == INADDR_ANY) {
|
if (addr[last - 1].wildcard) {
|
||||||
in_addr[last - 1].bind = 1;
|
addr[last - 1].bind = 1;
|
||||||
bind_all = 0;
|
bind_wildcard = 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bind_all = 1;
|
bind_wildcard = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
a = 0;
|
a = 0;
|
||||||
|
|
||||||
while (a < last) {
|
while (a < last) {
|
||||||
|
|
||||||
if (!bind_all && !in_addr[a].bind) {
|
if (bind_wildcard && !addr[a].bind) {
|
||||||
a++;
|
a++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr,
|
ls = ngx_http_add_listening(cf, &addr[a]);
|
||||||
in_port->port);
|
|
||||||
if (ls == NULL) {
|
if (ls == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ls->addr_ntop = 1;
|
hport = ngx_pcalloc(cf->pool, sizeof(ngx_http_port_t));
|
||||||
|
if (hport == NULL) {
|
||||||
ls->handler = ngx_http_init_connection;
|
|
||||||
|
|
||||||
cscf = in_addr[a].core_srv_conf;
|
|
||||||
ls->pool_size = cscf->connection_pool_size;
|
|
||||||
ls->post_accept_timeout = cscf->client_header_timeout;
|
|
||||||
|
|
||||||
clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
|
|
||||||
|
|
||||||
ls->log = *clcf->err_log;
|
|
||||||
ls->log.data = &ls->addr_text;
|
|
||||||
ls->log.handler = ngx_accept_log_error;
|
|
||||||
|
|
||||||
#if (NGX_WIN32)
|
|
||||||
{
|
|
||||||
ngx_iocp_conf_t *iocpcf;
|
|
||||||
|
|
||||||
iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
|
|
||||||
if (iocpcf->acceptex_read) {
|
|
||||||
ls->post_accept_buffer_size = cscf->client_header_buffer_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ls->backlog = in_addr[a].listen_conf->backlog;
|
|
||||||
ls->rcvbuf = in_addr[a].listen_conf->rcvbuf;
|
|
||||||
ls->sndbuf = in_addr[a].listen_conf->sndbuf;
|
|
||||||
|
|
||||||
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
|
|
||||||
ls->accept_filter = in_addr[a].listen_conf->accept_filter;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
|
|
||||||
ls->deferred_accept = in_addr[a].listen_conf->deferred_accept;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hip = ngx_palloc(cf->pool, sizeof(ngx_http_in_port_t));
|
|
||||||
if (hip == NULL) {
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
hip->port = in_port->port;
|
ls->servers = hport;
|
||||||
|
|
||||||
hip->port_text.data = ngx_pnalloc(cf->pool, 7);
|
hport->port = ntohs(port->port);
|
||||||
if (hip->port_text.data == NULL) {
|
|
||||||
return NGX_ERROR;
|
for (i = ls->addr_text.len - 1; i; i--) {
|
||||||
|
|
||||||
|
if (ls->addr_text.data[i] == ':') {
|
||||||
|
hport->port_text.len = ls->addr_text.len - i;
|
||||||
|
hport->port_text.data = &ls->addr_text.data[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ls->servers = hip;
|
if (a == last - 1) {
|
||||||
|
hport->naddrs = last;
|
||||||
hip->port_text.len = ngx_sprintf(hip->port_text.data, ":%d", hip->port)
|
|
||||||
- hip->port_text.data;
|
|
||||||
|
|
||||||
in_addr = in_port->addrs.elts;
|
|
||||||
|
|
||||||
if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) {
|
|
||||||
hip->naddrs = 1;
|
|
||||||
done = 0;
|
|
||||||
|
|
||||||
} else if (in_port->addrs.nelts > 1
|
|
||||||
&& in_addr[last - 1].addr == INADDR_ANY)
|
|
||||||
{
|
|
||||||
hip->naddrs = last;
|
|
||||||
done = 1;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
hip->naddrs = 1;
|
hport->naddrs = 1;
|
||||||
done = 0;
|
a = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hip->addrs = ngx_pcalloc(cf->pool,
|
switch (ls->sockaddr->sa_family) {
|
||||||
hip->naddrs * sizeof(ngx_http_in_addr_t));
|
|
||||||
if (hip->addrs == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < hip->naddrs; i++) {
|
#if (NGX_HAVE_INET6)
|
||||||
hip->addrs[i].addr = in_addr[i].addr;
|
case AF_INET6:
|
||||||
hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf;
|
if (ngx_http_add_addrs6(cf, hport, addr) != NGX_OK) {
|
||||||
|
|
||||||
#if (NGX_HTTP_SSL)
|
|
||||||
hip->addrs[i].ssl = in_addr[i].ssl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (in_addr[i].hash.buckets == NULL
|
|
||||||
&& (in_addr[i].wc_head == NULL
|
|
||||||
|| in_addr[i].wc_head->hash.buckets == NULL)
|
|
||||||
&& (in_addr[i].wc_head == NULL
|
|
||||||
|| in_addr[i].wc_head->hash.buckets == NULL))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
|
|
||||||
if (vn == NULL) {
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
hip->addrs[i].virtual_names = vn;
|
break;
|
||||||
|
|
||||||
vn->names.hash = in_addr[i].hash;
|
|
||||||
vn->names.wc_head = in_addr[i].wc_head;
|
|
||||||
vn->names.wc_tail = in_addr[i].wc_tail;
|
|
||||||
#if (NGX_PCRE)
|
|
||||||
vn->nregex = in_addr[i].nregex;
|
|
||||||
vn->regex = in_addr[i].regex;
|
|
||||||
#endif
|
#endif
|
||||||
|
default: /* AF_INET */
|
||||||
|
if (ngx_http_add_addrs(cf, hport, addr) != NGX_OK) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (done) {
|
addr++;
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_addr++;
|
|
||||||
in_port->addrs.elts = in_addr;
|
|
||||||
last--;
|
last--;
|
||||||
|
|
||||||
a = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_listening_t *
|
||||||
|
ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
|
||||||
|
{
|
||||||
|
ngx_listening_t *ls;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
|
u_char text[NGX_SOCKADDR_STRLEN];
|
||||||
|
|
||||||
|
ls = ngx_array_push(&cf->cycle->listening);
|
||||||
|
if (ls == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memzero(ls, sizeof(ngx_listening_t));
|
||||||
|
|
||||||
|
sa = ngx_palloc(cf->pool, addr->socklen);
|
||||||
|
if (sa == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memcpy(sa, addr->sockaddr, addr->socklen);
|
||||||
|
|
||||||
|
ls->sockaddr = sa;
|
||||||
|
ls->socklen = addr->socklen;
|
||||||
|
|
||||||
|
ls->addr_text.len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1);
|
||||||
|
|
||||||
|
ls->addr_text.data = ngx_pnalloc(cf->pool, ls->addr_text.len);
|
||||||
|
if (ls->addr_text.data == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memcpy(ls->addr_text.data, text, ls->addr_text.len);
|
||||||
|
|
||||||
|
ls->fd = (ngx_socket_t) -1;
|
||||||
|
ls->type = SOCK_STREAM;
|
||||||
|
|
||||||
|
switch (ls->sockaddr->sa_family) {
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
case AF_INET6:
|
||||||
|
ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case AF_INET:
|
||||||
|
ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ls->addr_text_max_len = NGX_SOCKADDR_STRLEN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ls->addr_ntop = 1;
|
||||||
|
|
||||||
|
ls->handler = ngx_http_init_connection;
|
||||||
|
|
||||||
|
cscf = addr->core_srv_conf;
|
||||||
|
ls->pool_size = cscf->connection_pool_size;
|
||||||
|
ls->post_accept_timeout = cscf->client_header_timeout;
|
||||||
|
|
||||||
|
clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
|
||||||
|
|
||||||
|
ls->log = *clcf->err_log;
|
||||||
|
ls->log.data = &ls->addr_text;
|
||||||
|
ls->log.handler = ngx_accept_log_error;
|
||||||
|
|
||||||
|
#if (NGX_WIN32)
|
||||||
|
{
|
||||||
|
ngx_iocp_conf_t *iocpcf;
|
||||||
|
|
||||||
|
iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
|
||||||
|
if (iocpcf->acceptex_read) {
|
||||||
|
ls->post_accept_buffer_size = cscf->client_header_buffer_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ls->backlog = addr->listen_conf->backlog;
|
||||||
|
ls->rcvbuf = addr->listen_conf->rcvbuf;
|
||||||
|
ls->sndbuf = addr->listen_conf->sndbuf;
|
||||||
|
|
||||||
|
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
|
||||||
|
ls->accept_filter = addr->listen_conf->accept_filter;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
|
||||||
|
ls->deferred_accept = addr->listen_conf->deferred_accept;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
|
||||||
|
ngx_http_conf_addr_t *addr)
|
||||||
|
{
|
||||||
|
ngx_uint_t i;
|
||||||
|
ngx_http_in_addr_t *addrs;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
ngx_http_virtual_names_t *vn;
|
||||||
|
|
||||||
|
hport->addrs = ngx_pcalloc(cf->pool,
|
||||||
|
hport->naddrs * sizeof(ngx_http_in_addr_t));
|
||||||
|
if (hport->addrs == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
addrs = hport->addrs;
|
||||||
|
|
||||||
|
for (i = 0; i < hport->naddrs; i++) {
|
||||||
|
|
||||||
|
sin = (struct sockaddr_in *) addr[i].sockaddr;
|
||||||
|
addrs[i].addr = sin->sin_addr.s_addr;
|
||||||
|
addrs[i].conf.core_srv_conf = addr[i].core_srv_conf;
|
||||||
|
#if (NGX_HTTP_SSL)
|
||||||
|
addrs[i].conf.ssl = addr[i].ssl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (addr[i].hash.buckets == NULL
|
||||||
|
&& (addr[i].wc_head == NULL
|
||||||
|
|| addr[i].wc_head->hash.buckets == NULL)
|
||||||
|
&& (addr[i].wc_head == NULL
|
||||||
|
|| addr[i].wc_head->hash.buckets == NULL))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
|
||||||
|
if (vn == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
addrs[i].conf.virtual_names = vn;
|
||||||
|
|
||||||
|
vn->names.hash = addr[i].hash;
|
||||||
|
vn->names.wc_head = addr[i].wc_head;
|
||||||
|
vn->names.wc_tail = addr[i].wc_tail;
|
||||||
|
#if (NGX_PCRE)
|
||||||
|
vn->nregex = addr[i].nregex;
|
||||||
|
vn->regex = addr[i].regex;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
|
||||||
|
ngx_http_conf_addr_t *addr)
|
||||||
|
{
|
||||||
|
ngx_uint_t i;
|
||||||
|
ngx_http_in6_addr_t *addrs6;
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
ngx_http_virtual_names_t *vn;
|
||||||
|
|
||||||
|
hport->addrs = ngx_pcalloc(cf->pool,
|
||||||
|
hport->naddrs * sizeof(ngx_http_in6_addr_t));
|
||||||
|
if (hport->addrs == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
addrs6 = hport->addrs;
|
||||||
|
|
||||||
|
for (i = 0; i < hport->naddrs; i++) {
|
||||||
|
|
||||||
|
sin6 = (struct sockaddr_in6 *) addr[i].sockaddr;
|
||||||
|
addrs6[i].addr6 = sin6->sin6_addr;
|
||||||
|
addrs6[i].conf.core_srv_conf = addr[i].core_srv_conf;
|
||||||
|
#if (NGX_HTTP_SSL)
|
||||||
|
addrs6[i].conf.ssl = addr[i].ssl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (addr[i].hash.buckets == NULL
|
||||||
|
&& (addr[i].wc_head == NULL
|
||||||
|
|| addr[i].wc_head->hash.buckets == NULL)
|
||||||
|
&& (addr[i].wc_head == NULL
|
||||||
|
|| addr[i].wc_head->hash.buckets == NULL))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
|
||||||
|
if (vn == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
addrs6[i].conf.virtual_names = vn;
|
||||||
|
|
||||||
|
vn->names.hash = addr[i].hash;
|
||||||
|
vn->names.wc_head = addr[i].wc_head;
|
||||||
|
vn->names.wc_tail = addr[i].wc_tail;
|
||||||
|
#if (NGX_PCRE)
|
||||||
|
vn->nregex = addr[i].nregex;
|
||||||
|
vn->regex = addr[i].regex;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
{
|
{
|
||||||
|
@ -1776,32 +1776,37 @@ ngx_http_server_addr(ngx_http_request_t *r, ngx_str_t *s)
|
|||||||
{
|
{
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in *sin;
|
||||||
|
u_char sa[NGX_SOCKADDRLEN];
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
c = r->connection;
|
c = r->connection;
|
||||||
|
|
||||||
if (r->in_addr == 0) {
|
if (c->local_sockaddr == NULL) {
|
||||||
len = sizeof(struct sockaddr_in);
|
|
||||||
if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) {
|
len = NGX_SOCKADDRLEN;
|
||||||
|
|
||||||
|
if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) {
|
||||||
ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
|
ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
r->in_addr = sin.sin_addr.s_addr;
|
c->local_sockaddr = ngx_palloc(r->connection->pool, len);
|
||||||
|
if (c->local_sockaddr == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
c->local_socklen = len;
|
||||||
sin.sin_family = c->sockaddr->sa_family;
|
ngx_memcpy(c->local_sockaddr, &sa, len);
|
||||||
sin.sin_addr.s_addr = r->in_addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sin = (struct sockaddr_in *) c->local_sockaddr;
|
||||||
|
r->in_addr = sin->sin_addr.s_addr;
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->len = ngx_sock_ntop((struct sockaddr *) &sin, s->data,
|
s->len = ngx_sock_ntop(c->local_sockaddr, s->data, s->len, 0);
|
||||||
NGX_INET_ADDRSTRLEN);
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -2729,7 +2734,8 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
|
|||||||
* conf->client_large_buffers.num = 0;
|
* conf->client_large_buffers.num = 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t))
|
if (ngx_array_init(&cscf->listen, cf->temp_pool, 4,
|
||||||
|
sizeof(ngx_http_listen_t))
|
||||||
== NGX_ERROR)
|
== NGX_ERROR)
|
||||||
{
|
{
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
@ -2761,6 +2767,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
ngx_http_core_srv_conf_t *conf = child;
|
ngx_http_core_srv_conf_t *conf = child;
|
||||||
|
|
||||||
ngx_http_listen_t *ls;
|
ngx_http_listen_t *ls;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
ngx_http_server_name_t *sn;
|
ngx_http_server_name_t *sn;
|
||||||
|
|
||||||
/* TODO: it does not merge, it inits only */
|
/* TODO: it does not merge, it inits only */
|
||||||
@ -2773,14 +2780,15 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
|
|
||||||
ngx_memzero(ls, sizeof(ngx_http_listen_t));
|
ngx_memzero(ls, sizeof(ngx_http_listen_t));
|
||||||
|
|
||||||
ls->addr = INADDR_ANY;
|
sin = (struct sockaddr_in *) &ls->sockaddr;
|
||||||
|
|
||||||
|
sin->sin_family = AF_INET;
|
||||||
#if (NGX_WIN32)
|
#if (NGX_WIN32)
|
||||||
ls->port = 80;
|
sin->sin_port = htons(80);
|
||||||
#else
|
#else
|
||||||
/* STUB: getuid() should be cached */
|
sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
|
||||||
ls->port = (getuid() == 0) ? 80 : 8000;
|
|
||||||
#endif
|
#endif
|
||||||
ls->family = AF_INET;
|
sin->sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
ls->conf.backlog = NGX_LISTEN_BACKLOG;
|
ls->conf.backlog = NGX_LISTEN_BACKLOG;
|
||||||
ls->conf.rcvbuf = -1;
|
ls->conf.rcvbuf = -1;
|
||||||
@ -3159,8 +3167,6 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* AF_INET only */
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
{
|
{
|
||||||
@ -3201,17 +3207,18 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
ngx_memzero(ls, sizeof(ngx_http_listen_t));
|
ngx_memzero(ls, sizeof(ngx_http_listen_t));
|
||||||
|
|
||||||
ls->family = u.family;
|
ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen);
|
||||||
ls->addr = u.addr.in_addr;
|
|
||||||
ls->port = u.port;
|
ls->socklen = u.socklen;
|
||||||
ls->file_name = cf->conf_file->file.name.data;
|
ls->file_name = cf->conf_file->file.name.data;
|
||||||
ls->line = cf->conf_file->line;
|
ls->line = cf->conf_file->line;
|
||||||
ls->conf.backlog = NGX_LISTEN_BACKLOG;
|
ls->conf.backlog = NGX_LISTEN_BACKLOG;
|
||||||
ls->conf.rcvbuf = -1;
|
ls->conf.rcvbuf = -1;
|
||||||
ls->conf.sndbuf = -1;
|
ls->conf.sndbuf = -1;
|
||||||
|
ls->conf.wildcard = u.wildcard;
|
||||||
|
|
||||||
n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, NGX_INET_ADDRSTRLEN);
|
(void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
|
||||||
ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port);
|
NGX_SOCKADDR_STRLEN, 1);
|
||||||
|
|
||||||
if (cf->args->nelts == 2) {
|
if (cf->args->nelts == 2) {
|
||||||
return NGX_CONF_OK;
|
return NGX_CONF_OK;
|
||||||
|
@ -40,6 +40,7 @@ typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t;
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned default_server:1;
|
unsigned default_server:1;
|
||||||
unsigned bind:1;
|
unsigned bind:1;
|
||||||
|
unsigned wildcard:1;
|
||||||
#if (NGX_HTTP_SSL)
|
#if (NGX_HTTP_SSL)
|
||||||
unsigned ssl:1;
|
unsigned ssl:1;
|
||||||
#endif
|
#endif
|
||||||
@ -55,15 +56,13 @@ typedef struct {
|
|||||||
ngx_uint_t deferred_accept;
|
ngx_uint_t deferred_accept;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u_char addr[NGX_INET_ADDRSTRLEN + sizeof(":65535")];
|
u_char addr[NGX_SOCKADDR_STRLEN + 1];
|
||||||
|
|
||||||
} ngx_http_listen_conf_t;
|
} ngx_http_listen_conf_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_addr_t addr;
|
u_char sockaddr[NGX_SOCKADDRLEN];
|
||||||
in_port_t port;
|
socklen_t socklen;
|
||||||
int family;
|
|
||||||
|
|
||||||
u_char *file_name;
|
u_char *file_name;
|
||||||
ngx_uint_t line;
|
ngx_uint_t line;
|
||||||
@ -173,8 +172,6 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_addr_t addr;
|
|
||||||
|
|
||||||
/* the default server configuration for this address:port */
|
/* the default server configuration for this address:port */
|
||||||
ngx_http_core_srv_conf_t *core_srv_conf;
|
ngx_http_core_srv_conf_t *core_srv_conf;
|
||||||
|
|
||||||
@ -183,25 +180,45 @@ typedef struct {
|
|||||||
#if (NGX_HTTP_SSL)
|
#if (NGX_HTTP_SSL)
|
||||||
ngx_uint_t ssl; /* unsigned ssl:1; */
|
ngx_uint_t ssl; /* unsigned ssl:1; */
|
||||||
#endif
|
#endif
|
||||||
|
} ngx_http_addr_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
in_addr_t addr;
|
||||||
|
ngx_http_addr_conf_t conf;
|
||||||
} ngx_http_in_addr_t;
|
} ngx_http_in_addr_t;
|
||||||
|
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct in6_addr addr6;
|
||||||
|
ngx_http_addr_conf_t conf;
|
||||||
|
} ngx_http_in6_addr_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_port_t port;
|
in_port_t port;
|
||||||
ngx_str_t port_text;
|
ngx_str_t port_text;
|
||||||
ngx_http_in_addr_t *addrs;
|
|
||||||
|
/* ngx_http_in_addr_t or ngx_http_in6_addr_t */
|
||||||
|
void *addrs;
|
||||||
ngx_uint_t naddrs;
|
ngx_uint_t naddrs;
|
||||||
} ngx_http_in_port_t;
|
} ngx_http_port_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
ngx_int_t family;
|
||||||
in_port_t port;
|
in_port_t port;
|
||||||
ngx_array_t addrs; /* array of ngx_http_conf_in_addr_t */
|
ngx_array_t addrs; /* array of ngx_http_conf_addr_t */
|
||||||
} ngx_http_conf_in_port_t;
|
} ngx_http_conf_port_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
in_addr_t addr;
|
struct sockaddr *sockaddr;
|
||||||
|
socklen_t socklen;
|
||||||
|
|
||||||
ngx_hash_t hash;
|
ngx_hash_t hash;
|
||||||
ngx_hash_wildcard_t *wc_head;
|
ngx_hash_wildcard_t *wc_head;
|
||||||
@ -219,12 +236,13 @@ typedef struct {
|
|||||||
|
|
||||||
unsigned default_server:1;
|
unsigned default_server:1;
|
||||||
unsigned bind:1;
|
unsigned bind:1;
|
||||||
|
unsigned wildcard:1;
|
||||||
#if (NGX_HTTP_SSL)
|
#if (NGX_HTTP_SSL)
|
||||||
unsigned ssl:1;
|
unsigned ssl:1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ngx_http_listen_conf_t *listen_conf;
|
ngx_http_listen_conf_t *listen_conf;
|
||||||
} ngx_http_conf_in_addr_t;
|
} ngx_http_conf_addr_t;
|
||||||
|
|
||||||
|
|
||||||
struct ngx_http_server_name_s {
|
struct ngx_http_server_name_s {
|
||||||
|
@ -161,8 +161,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||||||
ngx_table_elt_t *header;
|
ngx_table_elt_t *header;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
/* AF_INET only */
|
u_char addr[NGX_SOCKADDR_STRLEN];
|
||||||
u_char addr[NGX_INET_ADDRSTRLEN];
|
|
||||||
|
|
||||||
r->header_sent = 1;
|
r->header_sent = 1;
|
||||||
|
|
||||||
@ -290,6 +289,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||||||
host = r->headers_in.server;
|
host = r->headers_in.server;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
host.len = NGX_SOCKADDR_STRLEN;
|
||||||
host.data = addr;
|
host.data = addr;
|
||||||
|
|
||||||
if (ngx_http_server_addr(r, &host) != NGX_OK) {
|
if (ngx_http_server_addr(r, &host) != NGX_OK) {
|
||||||
|
@ -232,13 +232,19 @@ ngx_http_init_request(ngx_event_t *rev)
|
|||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
ngx_http_in_port_t *hip;
|
struct sockaddr_in *sin;
|
||||||
ngx_http_in_addr_t *hia;
|
ngx_http_port_t *port;
|
||||||
|
ngx_http_in_addr_t *addr;
|
||||||
ngx_http_log_ctx_t *ctx;
|
ngx_http_log_ctx_t *ctx;
|
||||||
|
ngx_http_addr_conf_t *addr_conf;
|
||||||
ngx_http_connection_t *hc;
|
ngx_http_connection_t *hc;
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
ngx_http_core_main_conf_t *cmcf;
|
ngx_http_core_main_conf_t *cmcf;
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
ngx_http_in6_addr_t *addr6;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (NGX_STAT_STUB)
|
#if (NGX_STAT_STUB)
|
||||||
ngx_atomic_fetch_add(ngx_stat_reading, -1);
|
ngx_atomic_fetch_add(ngx_stat_reading, -1);
|
||||||
@ -292,58 +298,90 @@ ngx_http_init_request(ngx_event_t *rev)
|
|||||||
|
|
||||||
/* find the server configuration for the address:port */
|
/* find the server configuration for the address:port */
|
||||||
|
|
||||||
/* AF_INET only */
|
port = c->listening->servers;
|
||||||
|
|
||||||
hip = c->listening->servers;
|
r->port = port->port;
|
||||||
hia = hip->addrs;
|
r->port_text = &port->port_text;
|
||||||
|
|
||||||
r->port = hip->port;
|
|
||||||
r->port_text = &hip->port_text;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
r->connection = c;
|
r->connection = c;
|
||||||
|
|
||||||
if (hip->naddrs > 1) {
|
if (port->naddrs > 1) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are several addresses on this port and one of them
|
* there are several addresses on this port and one of them
|
||||||
* is the "*:port" wildcard so getsockname() is needed to determine
|
* is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
|
||||||
* the server address.
|
* is required to determine a server address
|
||||||
*
|
|
||||||
* AcceptEx() already has given this address.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if (NGX_WIN32)
|
c->local_sockaddr = NULL;
|
||||||
if (c->local_sockaddr) {
|
|
||||||
r->in_addr =
|
|
||||||
((struct sockaddr_in *) c->local_sockaddr)->sin_addr.s_addr;
|
|
||||||
|
|
||||||
} else
|
if (ngx_http_server_addr(r, NULL) != NGX_OK) {
|
||||||
#endif
|
ngx_http_close_connection(c);
|
||||||
{
|
return;
|
||||||
if (ngx_http_server_addr(r, NULL) != NGX_OK) {
|
|
||||||
ngx_http_close_connection(c);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the last address is "*" */
|
switch (c->local_sockaddr->sa_family) {
|
||||||
|
|
||||||
for ( /* void */ ; i < hip->naddrs - 1; i++) {
|
#if (NGX_HAVE_INET6)
|
||||||
if (hia[i].addr == r->in_addr) {
|
case AF_INET6:
|
||||||
break;
|
sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
|
||||||
|
|
||||||
|
addr6 = (ngx_http_in6_addr_t *) port->addrs;
|
||||||
|
|
||||||
|
/* the last address is "*" */
|
||||||
|
|
||||||
|
for (i = 0; i < port->naddrs - 1; i++) {
|
||||||
|
if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addr_conf = &addr6[i].conf;
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: /* AF_INET */
|
||||||
|
sin = (struct sockaddr_in *) c->local_sockaddr;
|
||||||
|
|
||||||
|
addr = port->addrs;
|
||||||
|
|
||||||
|
/* the last address is "*" */
|
||||||
|
|
||||||
|
for (i = 0; i < port->naddrs - 1; i++) {
|
||||||
|
if (addr[i].addr == sin->sin_addr.s_addr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_conf = &addr[i].conf;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
r->in_addr = hia[0].addr;
|
|
||||||
|
switch (c->local_sockaddr->sa_family) {
|
||||||
|
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
case AF_INET6:
|
||||||
|
addr6 = (ngx_http_in6_addr_t *) port->addrs;
|
||||||
|
addr_conf = &addr6[0].conf;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: /* AF_INET */
|
||||||
|
addr = port->addrs;
|
||||||
|
addr_conf = &addr[0].conf;
|
||||||
|
r->in_addr = addr[0].addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r->virtual_names = hia[i].virtual_names;
|
r->virtual_names = addr_conf->virtual_names;
|
||||||
|
|
||||||
/* the default server configuration for the address:port */
|
/* the default server configuration for the address:port */
|
||||||
cscf = hia[i].core_srv_conf;
|
cscf = addr_conf->core_srv_conf;
|
||||||
|
|
||||||
r->main_conf = cscf->ctx->main_conf;
|
r->main_conf = cscf->ctx->main_conf;
|
||||||
r->srv_conf = cscf->ctx->srv_conf;
|
r->srv_conf = cscf->ctx->srv_conf;
|
||||||
@ -357,13 +395,13 @@ ngx_http_init_request(ngx_event_t *rev)
|
|||||||
ngx_http_ssl_srv_conf_t *sscf;
|
ngx_http_ssl_srv_conf_t *sscf;
|
||||||
|
|
||||||
sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
|
sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
|
||||||
if (sscf->enable || hia[i].ssl) {
|
if (sscf->enable || addr_conf->ssl) {
|
||||||
|
|
||||||
if (c->ssl == NULL) {
|
if (c->ssl == NULL) {
|
||||||
|
|
||||||
c->log->action = "SSL handshaking";
|
c->log->action = "SSL handshaking";
|
||||||
|
|
||||||
if (hia[i].ssl && sscf->ssl.ctx == NULL) {
|
if (addr_conf->ssl && sscf->ssl.ctx == NULL) {
|
||||||
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
||||||
"no \"ssl_certificate\" is defined "
|
"no \"ssl_certificate\" is defined "
|
||||||
"in server listening on SSL port");
|
"in server listening on SSL port");
|
||||||
|
@ -828,17 +828,37 @@ static ngx_int_t
|
|||||||
ngx_http_variable_binary_remote_addr(ngx_http_request_t *r,
|
ngx_http_variable_binary_remote_addr(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
ngx_http_variable_value_t *v, uintptr_t data)
|
||||||
{
|
{
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* AF_INET only */
|
switch (r->connection->sockaddr->sa_family) {
|
||||||
|
|
||||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
#if (NGX_HAVE_INET6)
|
||||||
|
case AF_INET6:
|
||||||
|
sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
|
||||||
|
|
||||||
v->len = sizeof(in_addr_t);
|
v->len = sizeof(struct in6_addr);
|
||||||
v->valid = 1;
|
v->valid = 1;
|
||||||
v->no_cacheable = 0;
|
v->no_cacheable = 0;
|
||||||
v->not_found = 0;
|
v->not_found = 0;
|
||||||
v->data = (u_char *) &sin->sin_addr.s_addr;
|
v->data = (u_char *) &sin6->sin6_addr;
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: /* AF_INET */
|
||||||
|
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||||
|
|
||||||
|
v->len = sizeof(in_addr_t);
|
||||||
|
v->valid = 1;
|
||||||
|
v->no_cacheable = 0;
|
||||||
|
v->not_found = 0;
|
||||||
|
v->data = (u_char *) &sin->sin_addr;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -862,8 +882,11 @@ static ngx_int_t
|
|||||||
ngx_http_variable_remote_port(ngx_http_request_t *r,
|
ngx_http_variable_remote_port(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
ngx_http_variable_value_t *v, uintptr_t data)
|
||||||
{
|
{
|
||||||
ngx_uint_t port;
|
ngx_uint_t port;
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
#if (NGX_HAVE_INET6)
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
|
||||||
v->len = 0;
|
v->len = 0;
|
||||||
v->valid = 1;
|
v->valid = 1;
|
||||||
@ -875,16 +898,23 @@ ngx_http_variable_remote_port(ngx_http_request_t *r,
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AF_INET only */
|
switch (r->connection->sockaddr->sa_family) {
|
||||||
|
|
||||||
if (r->connection->sockaddr->sa_family == AF_INET) {
|
#if (NGX_HAVE_INET6)
|
||||||
|
case AF_INET6:
|
||||||
|
sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
|
||||||
|
port = ntohs(sin6->sin6_port);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default: /* AF_INET */
|
||||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||||
|
|
||||||
port = ntohs(sin->sin_port);
|
port = ntohs(sin->sin_port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (port > 0 && port < 65536) {
|
if (port > 0 && port < 65536) {
|
||||||
v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
|
v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@ -896,16 +926,22 @@ ngx_http_variable_server_addr(ngx_http_request_t *r,
|
|||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
ngx_http_variable_value_t *v, uintptr_t data)
|
||||||
{
|
{
|
||||||
ngx_str_t s;
|
ngx_str_t s;
|
||||||
|
u_char addr[NGX_SOCKADDR_STRLEN];
|
||||||
|
|
||||||
s.data = ngx_pnalloc(r->pool, NGX_INET_ADDRSTRLEN);
|
s.len = NGX_SOCKADDR_STRLEN;
|
||||||
if (s.data == NULL) {
|
s.data = addr;
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_http_server_addr(r, &s) != NGX_OK) {
|
if (ngx_http_server_addr(r, &s) != NGX_OK) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.data = ngx_pnalloc(r->pool, s.len);
|
||||||
|
if (s.data == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memcpy(s.data, addr, s.len);
|
||||||
|
|
||||||
v->len = s.len;
|
v->len = s.len;
|
||||||
v->valid = 1;
|
v->valid = 1;
|
||||||
v->no_cacheable = 0;
|
v->no_cacheable = 0;
|
||||||
|
@ -305,6 +305,11 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
return NGX_CONF_ERROR;
|
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);
|
cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
|
||||||
|
|
||||||
imls = cmcf->listen.elts;
|
imls = cmcf->listen.elts;
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h> /* ipv6 */
|
||||||
#include <mswsock.h>
|
#include <mswsock.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include <stddef.h> /* offsetof() */
|
#include <stddef.h> /* offsetof() */
|
||||||
|
Loading…
Reference in New Issue
Block a user