aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_inet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ngx_inet.c')
-rw-r--r--src/core/ngx_inet.c340
1 files changed, 129 insertions, 211 deletions
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index db48b93c1..d935fbb67 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -12,6 +12,8 @@
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_inet6_url(ngx_pool_t *pool, ngx_url_t *u);
+static ngx_int_t ngx_inet_add_addr(ngx_pool_t *pool, ngx_url_t *u,
+ struct sockaddr *sockaddr, socklen_t socklen, ngx_uint_t total);
in_addr_t
@@ -780,13 +782,10 @@ 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 sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
+ u_char *host, *port, *last, *uri, *args;
+ size_t len;
+ ngx_int_t n;
+ struct sockaddr_in *sin;
u->socklen = sizeof(struct sockaddr_in);
sin = (struct sockaddr_in *) &u->sockaddr;
@@ -864,13 +863,15 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
u->port = (in_port_t) n;
sin->sin_port = htons((in_port_t) n);
+ sin->sin_addr.s_addr = INADDR_ANY;
u->port_text.len = last - host;
u->port_text.data = host;
u->wildcard = 1;
- return NGX_OK;
+ return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr,
+ u->socklen, 1);
}
}
}
@@ -893,7 +894,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
if (u->listen && len == 1 && *host == '*') {
sin->sin_addr.s_addr = INADDR_ANY;
u->wildcard = 1;
- return NGX_OK;
+ return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);
}
sin->sin_addr.s_addr = ngx_inet_addr(host, len);
@@ -904,33 +905,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
u->wildcard = 1;
}
- u->naddrs = 1;
-
- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NGX_ERROR;
- }
-
- 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;
- }
-
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, u->port) - p;
- u->addrs[0].name.data = p;
-
- return NGX_OK;
+ return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);
}
if (u->no_resolve) {
@@ -944,29 +919,7 @@ ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
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;
- }
+ u->wildcard = ngx_inet_wildcard(&u->sockaddr.sockaddr);
return NGX_OK;
}
@@ -1061,33 +1014,8 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
}
u->family = AF_INET6;
- u->naddrs = 1;
- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));
- if (sin6 == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(sin6, &u->sockaddr, sizeof(struct sockaddr_in6));
-
- u->addrs[0].sockaddr = (struct sockaddr *) sin6;
- u->addrs[0].socklen = sizeof(struct sockaddr_in6);
-
- p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, u->port) - p;
- u->addrs[0].name.data = p;
-
- return NGX_OK;
+ return ngx_inet_add_addr(pool, u, &u->sockaddr.sockaddr, u->socklen, 1);
#else
@@ -1104,15 +1032,9 @@ ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
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);
+ u_char *host;
+ ngx_uint_t n;
+ struct addrinfo hints, *res, *rp;
host = ngx_alloc(u->host.len + 1, pool->log);
if (host == NULL) {
@@ -1136,7 +1058,7 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
ngx_free(host);
- for (i = 0, rp = res; rp != NULL; rp = rp->ai_next) {
+ for (n = 0, rp = res; rp != NULL; rp = rp->ai_next) {
switch (rp->ai_family) {
@@ -1148,25 +1070,16 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
continue;
}
- i++;
+ n++;
}
- if (i == 0) {
+ if (n == 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) {
@@ -1175,31 +1088,11 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
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) {
+ if (ngx_inet_add_addr(pool, u, rp->ai_addr, rp->ai_addrlen, n)
+ != NGX_OK)
+ {
goto failed;
}
-
- len = ngx_sock_ntop((struct sockaddr *) sin, rp->ai_addrlen, 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) {
@@ -1208,32 +1101,11 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
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) {
+ if (ngx_inet_add_addr(pool, u, rp->ai_addr, rp->ai_addrlen, n)
+ != NGX_OK)
+ {
goto failed;
}
-
- len = ngx_sock_ntop((struct sockaddr *) sin6, rp->ai_addrlen, p,
- len, 1);
-
- u->addrs[i].name.len = len;
- u->addrs[i].name.data = p;
-
- i++;
}
freeaddrinfo(res);
@@ -1250,21 +1122,19 @@ failed:
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;
- in_addr_t in_addr;
- ngx_uint_t i;
+ u_char *host;
+ ngx_uint_t i, n;
struct hostent *h;
- struct sockaddr_in *sin;
+ struct sockaddr_in sin;
/* AF_INET only */
- port = htons(u->port);
+ ngx_memzero(&sin, sizeof(struct sockaddr_in));
- in_addr = ngx_inet_addr(u->host.data, u->host.len);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = ngx_inet_addr(u->host.data, u->host.len);
- if (in_addr == INADDR_NONE) {
+ if (sin.sin_addr.s_addr == INADDR_NONE) {
host = ngx_alloc(u->host.len + 1, pool->log);
if (host == NULL) {
return NGX_ERROR;
@@ -1281,83 +1151,94 @@ ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
return NGX_ERROR;
}
- for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
+ for (n = 0; h->h_addr_list[n] != NULL; n++) { /* void */ }
/* MP: ngx_shared_palloc() */
- u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
+ for (i = 0; i < n; i++) {
+ sin.sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
- u->naddrs = i;
-
- for (i = 0; i < u->naddrs; i++) {
-
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
+ if (ngx_inet_add_addr(pool, u, (struct sockaddr *) &sin,
+ sizeof(struct sockaddr_in), n)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
+ }
- sin->sin_family = AF_INET;
- sin->sin_port = port;
- sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
-
- u->addrs[i].sockaddr = (struct sockaddr *) sin;
- u->addrs[i].socklen = sizeof(struct sockaddr_in);
+ } else {
- len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+ /* MP: ngx_shared_palloc() */
- p = ngx_pnalloc(pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
+ if (ngx_inet_add_addr(pool, u, (struct sockaddr *) &sin,
+ sizeof(struct sockaddr_in), 1)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+ }
- len = ngx_sock_ntop((struct sockaddr *) sin,
- sizeof(struct sockaddr_in), p, len, 1);
+ return NGX_OK;
+}
- u->addrs[i].name.len = len;
- u->addrs[i].name.data = p;
- }
+#endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */
- } else {
- /* MP: ngx_shared_palloc() */
+static ngx_int_t
+ngx_inet_add_addr(ngx_pool_t *pool, ngx_url_t *u, struct sockaddr *sockaddr,
+ socklen_t socklen, ngx_uint_t total)
+{
+ u_char *p;
+ size_t len;
+ ngx_addr_t *addr;
+ struct sockaddr *sa;
- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
+ if (u->addrs == NULL) {
+ u->addrs = ngx_palloc(pool, total * sizeof(ngx_addr_t));
if (u->addrs == NULL) {
return NGX_ERROR;
}
+ }
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NGX_ERROR;
- }
+ sa = ngx_pcalloc(pool, socklen);
+ if (sa == NULL) {
+ return NGX_ERROR;
+ }
- u->naddrs = 1;
+ ngx_memcpy(sa, sockaddr, socklen);
- sin->sin_family = AF_INET;
- sin->sin_port = port;
- sin->sin_addr.s_addr = in_addr;
+ ngx_inet_set_port(sa, u->port);
- u->addrs[0].sockaddr = (struct sockaddr *) sin;
- u->addrs[0].socklen = sizeof(struct sockaddr_in);
+ switch (sa->sa_family) {
- p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
+#if (NGX_HAVE_INET6)
+ case AF_INET6:
+ len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65536") - 1;
+ break;
+#endif
+
+ default: /* AF_INET */
+ len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
+ }
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, ntohs(port)) - p;
- u->addrs[0].name.data = p;
+ p = ngx_pnalloc(pool, len);
+ if (p == NULL) {
+ return NGX_ERROR;
}
+ len = ngx_sock_ntop(sa, socklen, p, len, 1);
+
+ addr = &u->addrs[u->naddrs++];
+
+ addr->sockaddr = sa;
+ addr->socklen = socklen;
+
+ addr->name.len = len;
+ addr->name.data = p;
+
return NGX_OK;
}
-#endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */
-
ngx_int_t
ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
@@ -1495,3 +1376,40 @@ ngx_inet_set_port(struct sockaddr *sa, in_port_t port)
break;
}
}
+
+
+ngx_uint_t
+ngx_inet_wildcard(struct sockaddr *sa)
+{
+ struct sockaddr_in *sin;
+#if (NGX_HAVE_INET6)
+ struct sockaddr_in6 *sin6;
+#endif
+
+ switch (sa->sa_family) {
+
+ case AF_INET:
+ sin = (struct sockaddr_in *) sa;
+
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ return 1;
+ }
+
+ break;
+
+#if (NGX_HAVE_INET6)
+
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) sa;
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ return 1;
+ }
+
+ break;
+
+#endif
+ }
+
+ return 0;
+}