diff options
| author | 2013-06-01 16:12:54 +0000 | |
|---|---|---|
| committer | 2013-06-01 16:12:54 +0000 | |
| commit | d8dc9a5250771aed5ee92cbc434097082ef103f1 (patch) | |
| tree | 1d1294b5132ddb61207c9fcb594f00810c3fdb69 /usr.sbin/nginx/src/core/ngx_inet.c | |
| parent | As found by kurt, there's a twisty race between exit1 and fork1 (diff) | |
| download | wireguard-openbsd-d8dc9a5250771aed5ee92cbc434097082ef103f1.tar.xz wireguard-openbsd-d8dc9a5250771aed5ee92cbc434097082ef103f1.zip | |
update to nginx-1.4.1 and enable the SPDY module by default
Diffstat (limited to 'usr.sbin/nginx/src/core/ngx_inet.c')
| -rw-r--r-- | usr.sbin/nginx/src/core/ngx_inet.c | 267 |
1 files changed, 219 insertions, 48 deletions
diff --git a/usr.sbin/nginx/src/core/ngx_inet.c b/usr.sbin/nginx/src/core/ngx_inet.c index a4acc8ca5c4..7757ab7d905 100644 --- a/usr.sbin/nginx/src/core/ngx_inet.c +++ b/usr.sbin/nginx/src/core/ngx_inet.c @@ -611,11 +611,13 @@ 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) { - u_char *p, *host, *port, *last, *uri, *args; - size_t len; - ngx_int_t n; - struct hostent *h; - struct sockaddr_in *sin; + u_char *p, *host, *port, *last, *uri, *args; + size_t len; + ngx_int_t n; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif u->socklen = sizeof(struct sockaddr_in); sin = (struct sockaddr_in *) &u->sockaddr; @@ -705,6 +707,8 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u) } u->no_port = 1; + u->port = u->default_port; + sin->sin_port = htons(u->default_port); } len = last - host; @@ -714,59 +718,88 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u) return NGX_ERROR; } - if (len == 1 && *host == '*') { - len = 0; - } - u->host.len = len; u->host.data = host; - if (u->no_resolve) { + if (u->listen && len == 1 && *host == '*') { + sin->sin_addr.s_addr = INADDR_ANY; + u->wildcard = 1; return NGX_OK; } - if (len) { - sin->sin_addr.s_addr = ngx_inet_addr(host, len); + sin->sin_addr.s_addr = ngx_inet_addr(host, len); - if (sin->sin_addr.s_addr == INADDR_NONE) { - p = ngx_alloc(++len, pool->log); - if (p == NULL) { - return NGX_ERROR; - } + if (sin->sin_addr.s_addr != INADDR_NONE) { - (void) ngx_cpystrn(p, host, len); - - h = gethostbyname((const char *) p); + if (sin->sin_addr.s_addr == INADDR_ANY) { + u->wildcard = 1; + } - ngx_free(p); + u->naddrs = 1; - if (h == NULL || h->h_addr_list[0] == NULL) { - u->err = "host not found"; - return NGX_ERROR; - } + u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t)); + if (u->addrs == NULL) { + return NGX_ERROR; + } - sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[0]); + sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in)); + if (sin == NULL) { + return NGX_ERROR; } - if (sin->sin_addr.s_addr == INADDR_ANY) { - u->wildcard = 1; + ngx_memcpy(sin, u->sockaddr, sizeof(struct sockaddr_in)); + + u->addrs[0].sockaddr = (struct sockaddr *) sin; + u->addrs[0].socklen = sizeof(struct sockaddr_in); + + p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1); + if (p == NULL) { + return NGX_ERROR; } - } else { - sin->sin_addr.s_addr = INADDR_ANY; - u->wildcard = 1; - } + u->addrs[0].name.len = ngx_sprintf(p, "%V:%d", + &u->host, u->port) - p; + u->addrs[0].name.data = p; - if (u->no_port) { - u->port = u->default_port; - sin->sin_port = htons(u->default_port); + return NGX_OK; } - if (u->listen) { + if (u->no_resolve) { return NGX_OK; } - return ngx_inet_resolve_host(pool, u); + if (ngx_inet_resolve_host(pool, u) != NGX_OK) { + return NGX_ERROR; + } + + u->family = u->addrs[0].sockaddr->sa_family; + u->socklen = u->addrs[0].socklen; + ngx_memcpy(u->sockaddr, u->addrs[0].sockaddr, u->addrs[0].socklen); + + switch (u->family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) &u->sockaddr; + + if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { + u->wildcard = 1; + } + + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) &u->sockaddr; + + if (sin->sin_addr.s_addr == INADDR_ANY) { + u->wildcard = 1; + } + + break; + } + + return NGX_OK; } @@ -832,6 +865,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u) } else { u->no_port = 1; + u->port = u->default_port; + sin6->sin6_port = htons(u->default_port); } } @@ -854,11 +889,6 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u) u->wildcard = 1; } - if (u->no_port) { - u->port = u->default_port; - sin6->sin6_port = htons(u->default_port); - } - u->family = AF_INET6; u->naddrs = 1; @@ -898,6 +928,150 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u) } +#if (NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6) + +ngx_int_t +ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u) +{ + u_char *p, *host; + size_t len; + in_port_t port; + ngx_uint_t i; + struct addrinfo hints, *res, *rp; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + port = htons(u->port); + + host = ngx_alloc(u->host.len + 1, pool->log); + if (host == NULL) { + return NGX_ERROR; + } + + (void) ngx_cpystrn(host, u->host.data, u->host.len + 1); + + ngx_memzero(&hints, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if (getaddrinfo((char *) host, NULL, &hints, &res) != 0) { + u->err = "host not found"; + ngx_free(host); + return NGX_ERROR; + } + + ngx_free(host); + + for (i = 0, rp = res; rp != NULL; rp = rp->ai_next) { + + switch (rp->ai_family) { + + case AF_INET: + case AF_INET6: + break; + + default: + continue; + } + + i++; + } + + if (i == 0) { + u->err = "host not found"; + goto failed; + } + + /* MP: ngx_shared_palloc() */ + + u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t)); + if (u->addrs == NULL) { + goto failed; + } + + u->naddrs = i; + + i = 0; + + /* AF_INET addresses first */ + + for (rp = res; rp != NULL; rp = rp->ai_next) { + + if (rp->ai_family != AF_INET) { + continue; + } + + sin = ngx_pcalloc(pool, rp->ai_addrlen); + if (sin == NULL) { + goto failed; + } + + ngx_memcpy(sin, rp->ai_addr, rp->ai_addrlen); + + sin->sin_port = port; + + u->addrs[i].sockaddr = (struct sockaddr *) sin; + u->addrs[i].socklen = rp->ai_addrlen; + + len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1; + + p = ngx_pnalloc(pool, len); + if (p == NULL) { + goto failed; + } + + len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1); + + u->addrs[i].name.len = len; + u->addrs[i].name.data = p; + + i++; + } + + for (rp = res; rp != NULL; rp = rp->ai_next) { + + if (rp->ai_family != AF_INET6) { + continue; + } + + sin6 = ngx_pcalloc(pool, rp->ai_addrlen); + if (sin6 == NULL) { + goto failed; + } + + ngx_memcpy(sin6, rp->ai_addr, rp->ai_addrlen); + + sin6->sin6_port = port; + + u->addrs[i].sockaddr = (struct sockaddr *) sin6; + u->addrs[i].socklen = rp->ai_addrlen; + + len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1; + + p = ngx_pnalloc(pool, len); + if (p == NULL) { + goto failed; + } + + len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, 1); + + u->addrs[i].name.len = len; + u->addrs[i].name.data = p; + + i++; + } + + freeaddrinfo(res); + return NGX_OK; + +failed: + + freeaddrinfo(res); + return NGX_ERROR; +} + +#else /* !NGX_HAVE_GETADDRINFO || !NGX_HAVE_INET6 */ + ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u) { @@ -932,12 +1106,7 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u) return NGX_ERROR; } - if (u->one_addr == 0) { - for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ } - - } else { - i = 1; - } + for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ } /* MP: ngx_shared_palloc() */ @@ -1010,3 +1179,5 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u) return NGX_OK; } + +#endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */ |
