[nginx] svn commit: r4972 - in trunk: auto src/core src/mail src/os/win32
ru at nginx.com
ru at nginx.com
Mon Dec 17 12:08:54 UTC 2012
Author: ru
Date: 2012-12-17 12:08:53 +0000 (Mon, 17 Dec 2012)
New Revision: 4972
URL: http://trac.nginx.org/nginx/changeset/4972/nginx
Log:
Implemented IPv6 support for URLs specified using domain names.
This includes "debug_connection", upstreams, "proxy_pass", etc.
(ticket #92)
To preserve compatibility, "listen" specified with a domain name
selects the first IPv4 address, if available. If not available,
the first IPv6 address will be used (ticket #186).
Modified:
trunk/auto/unix
trunk/src/core/ngx_inet.c
trunk/src/core/ngx_inet.h
trunk/src/mail/ngx_mail_auth_http_module.c
trunk/src/os/win32/ngx_win32_config.h
Modified: trunk/auto/unix
===================================================================
--- trunk/auto/unix 2012-12-17 09:44:46 UTC (rev 4971)
+++ trunk/auto/unix 2012-12-17 12:08:53 UTC (rev 4972)
@@ -778,3 +778,17 @@
openat(AT_FDCWD, \".\", O_RDONLY|O_NOFOLLOW);
fstatat(AT_FDCWD, \".\", &sb, AT_SYMLINK_NOFOLLOW);"
. auto/feature
+
+
+ngx_feature="getaddrinfo()"
+ngx_feature_name="NGX_HAVE_GETADDRINFO"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netdb.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test='struct addrinfo *res;
+ if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1;
+ freeaddrinfo(res)'
+. auto/feature
Modified: trunk/src/core/ngx_inet.c
===================================================================
--- trunk/src/core/ngx_inet.c 2012-12-17 09:44:46 UTC (rev 4971)
+++ trunk/src/core/ngx_inet.c 2012-12-17 12:08:53 UTC (rev 4972)
@@ -611,11 +611,13 @@
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;
@@ -728,41 +730,79 @@
return NGX_OK;
}
- if (u->no_resolve) {
- return NGX_OK;
- }
-
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) {
+ if (sin->sin_addr.s_addr != INADDR_NONE) {
+
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ u->wildcard = 1;
+ }
+
+ u->naddrs = 1;
+
+ u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
+ if (u->addrs == NULL) {
return NGX_ERROR;
}
- (void) ngx_cpystrn(p, host, len);
+ sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
+ if (sin == NULL) {
+ return NGX_ERROR;
+ }
- h = gethostbyname((const char *) p);
+ ngx_memcpy(sin, u->sockaddr, sizeof(struct sockaddr_in));
- ngx_free(p);
+ u->addrs[0].sockaddr = (struct sockaddr *) sin;
+ u->addrs[0].socklen = sizeof(struct sockaddr_in);
- if (h == NULL || h->h_addr_list[0] == NULL) {
- u->err = "host not found";
+ p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
+ if (p == NULL) {
return NGX_ERROR;
}
- sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[0]);
- }
+ u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
+ &u->host, u->port) - p;
+ u->addrs[0].name.data = p;
- if (sin->sin_addr.s_addr == INADDR_ANY) {
- u->wildcard = 1;
+ 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;
}
@@ -894,9 +934,153 @@
}
+#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)
+{
u_char *p, *host;
size_t len;
in_port_t port;
@@ -928,13 +1112,8 @@
return NGX_ERROR;
}
- if (u->one_addr == 0) {
- for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
+ for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
- } else {
- i = 1;
- }
-
/* MP: ngx_shared_palloc() */
u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
@@ -1006,3 +1185,5 @@
return NGX_OK;
}
+
+#endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */
Modified: trunk/src/core/ngx_inet.h
===================================================================
--- trunk/src/core/ngx_inet.h 2012-12-17 09:44:46 UTC (rev 4971)
+++ trunk/src/core/ngx_inet.h 2012-12-17 12:08:53 UTC (rev 4972)
@@ -87,7 +87,7 @@
unsigned listen:1;
unsigned uri_part:1;
unsigned no_resolve:1;
- unsigned one_addr:1;
+ unsigned one_addr:1; /* compatibility */
unsigned no_port:1;
unsigned wildcard:1;
Modified: trunk/src/mail/ngx_mail_auth_http_module.c
===================================================================
--- trunk/src/mail/ngx_mail_auth_http_module.c 2012-12-17 09:44:46 UTC (rev 4971)
+++ trunk/src/mail/ngx_mail_auth_http_module.c 2012-12-17 12:08:53 UTC (rev 4972)
@@ -1388,7 +1388,6 @@
u.url = value[1];
u.default_port = 80;
u.uri_part = 1;
- u.one_addr = 1;
if (ngx_strncmp(u.url.data, "http://", 7) == 0) {
u.url.len -= 7;
Modified: trunk/src/os/win32/ngx_win32_config.h
===================================================================
--- trunk/src/os/win32/ngx_win32_config.h 2012-12-17 09:44:46 UTC (rev 4971)
+++ trunk/src/os/win32/ngx_win32_config.h 2012-12-17 12:08:53 UTC (rev 4972)
@@ -182,6 +182,7 @@
#define NGX_HAVE_SO_SNDLOWAT 0
#endif
+#define NGX_HAVE_GETADDRINFO 1
#define ngx_random rand
#define ngx_debug_init()
More information about the nginx-devel
mailing list