[PATCH] nginx support parse a URL to IPv6
Jiankuan Xing
jiankuan at zimbra.com
Tue Mar 1 05:32:40 MSK 2011
Hey, guys. I've implement a parse URL to IPv6 function which is discussed in "http://forum.nginx.org/read.php?2,177146,177190". I change "ngx_parse_url" and add an function "ngx_parse_host" to resolve a host (IP or text) to either IPv4 or IPv6 functions. And I change "ngx_inet_resolve_host" to let it accept IPv4/IPv6. Besides I add another function "ngx_inet_sock_addr" to parse string with format "ipv4:port" and "[ipv6]:port" to the addr structure. Seems I can't upload the attachment so I past them here. I've do the unit test to them. Hope you can take regression test and merge them to the nginx main branch.
If u wish, I can also past the unit test I write. The change is a big one so I recommend directly submit a source code. But as convention, here is the diff:
===============ngx_inet.c=====================
12,13c12
< 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_parse_host(ngx_pool_t *pool, ngx_url_t *u);
449d447
<
509d506
<
513c510,518
< u_char *p;
---
> 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;
> ngx_flag_t ipv6 = 0;
> #endif
526,528c531
< if (p[0] == '[') {
< return ngx_parse_inet6_url(pool, u);
< }
---
> host = u->url.data;
530,531c533
< return ngx_parse_inet_url(pool, u);
< }
---
> last = host + u->url.len;
532a535
> len = 0;
534,543c537,538
< static ngx_int_t
< ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
< {
< #if (NGX_HAVE_UNIX_DOMAIN)
< u_char *path, *uri, *last;
< size_t len;
< struct sockaddr_un *saun;
<
< len = u->url.len;
< path = u->url.data;
---
> #if (NGX_HAVE_INET6)
> if (host[0] == '[') {
545,546c540
< path += 5;
< len -= 5;
---
> ipv6 = 1;
548c542
< if (u->uri_part) {
---
> host = u->url.data + 1;
550,551c544
< last = path + len;
< uri = ngx_strlchr(path, last, ':');
---
> p = ngx_strlchr(host, last, ']');
553,557c546,548
< if (uri) {
< len = uri - path;
< uri++;
< u->uri.len = last - uri;
< u->uri.data = uri;
---
> if (p == NULL) {
> u->err = "invalid host";
> return NGX_ERROR;
559,577d549
< }
<
< if (len == 0) {
< u->err = "no path in the unix domain socket";
< return NGX_ERROR;
< }
<
< u->host.len = len++;
< u->host.data = path;
<
< if (len > sizeof(saun->sun_path)) {
< u->err = "too long path in the unix domain socket";
< 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);
579,582c551
< u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
< if (u->addrs == NULL) {
< return NGX_ERROR;
< }
---
> u->family = AF_INET6;
584,586d552
< saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
< if (saun == NULL) {
< return NGX_ERROR;
588,607d553
<
< u->family = AF_UNIX;
< u->naddrs = 1;
<
< saun->sun_family = AF_UNIX;
< (void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
<
< u->addrs[0].sockaddr = (struct sockaddr *) saun;
< u->addrs[0].socklen = sizeof(struct sockaddr_un);
< u->addrs[0].name.len = len + 4;
< u->addrs[0].name.data = u->url.data;
<
< return NGX_OK;
<
< #else
<
< u->err = "the unix domain sockets are not supported on this platform";
<
< return NGX_ERROR;
<
609,631d554
< }
<
<
< 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->socklen = sizeof(struct sockaddr_in);
< sin = (struct sockaddr_in *) &u->sockaddr;
< sin->sin_family = AF_INET;
<
< u->family = AF_INET;
<
< host = u->url.data;
<
< last = host + u->url.len;
<
< port = ngx_strlchr(host, last, ':');
633c556
< uri = ngx_strlchr(host, last, '/');
---
> port = ngx_strlchr(p, last, ':');
635c558
< args = ngx_strlchr(host, last, '?');
---
> uri = ngx_strlchr(p, last, '/');
637,639c560
< if (args) {
< if (uri == NULL) {
< uri = args;
---
> args = ngx_strlchr(p, last, '?');
641,643c562,563
< } else if (args < uri) {
< uri = args;
< }
---
> if (args && (uri == NULL || args < uri)) {
> uri = args;
648c568
< u->err = "invalid host";
---
> u->err = "invalid url to listen";
680,681d599
< sin->sin_port = htons((in_port_t) n);
<
688,692c606,607
< if (uri == NULL) {
<
< if (u->listen) {
<
< /* test value as port only */
---
> if (uri == NULL && u->listen) {
> /* test value as port only */
694c609
< n = ngx_atoi(host, last - host);
---
> n = ngx_atoi(u->url.data, u->url.len);
696,704c611,614
< if (n != NGX_ERROR) {
<
< if (n < 1 || n > 65536) {
< u->err = "invalid port";
< return NGX_ERROR;
< }
<
< u->port = (in_port_t) n;
< sin->sin_port = htons((in_port_t) n);
---
> if (n < 1 || n > 65536) {
> u->err = "invalid port";
> return NGX_ERROR;
> }
706,707c616,625
< u->port_text.len = last - host;
< u->port_text.data = host;
---
> u->family = AF_INET;
> u->port = (in_port_t) n;
> sin = (struct sockaddr_in *)u->sockaddr;
> sin->sin_family = AF_INET;
> sin->sin_addr.s_addr = INADDR_ANY;
> sin->sin_port = htons((in_port_t) n);
> u->port_text.len = len;
> u->port_text.data = port;
> u->socklen = sizeof (struct sockaddr_in);
> u->wildcard = 1;
709c627
< u->wildcard = 1;
---
> return NGX_OK;
711,713c629,630
< return NGX_OK;
< }
< }
---
> } else {
> u->no_port = 1;
714a632
> }
716c634,641
< u->no_port = 1;
---
> #if (NGX_HAVE_INET6)
> if (ipv6) {
> if (*(last - 1) == ']' && last > host) {
> last--;
> } else {
> u->err = "invalid host";
> return NGX_ERROR;
> }
717a643
> #endif
721,725d646
< if (len == 0) {
< u->err = "no host";
< return NGX_ERROR;
< }
<
727a649,654
> u->family = AF_INET;
> u->socklen = sizeof (struct sockaddr_in);
> u->wildcard = 1;
> sin = (struct sockaddr_in *)u->sockaddr;
> sin->sin_family = AF_INET;
> sin->sin_addr.s_addr = INADDR_ANY;
737,766c664,666
< if (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;
< }
<
< (void) ngx_cpystrn(p, host, len);
<
< h = gethostbyname((const char *) p);
<
< ngx_free(p);
<
< if (h == NULL || h->h_addr_list[0] == NULL) {
< u->err = "host not found";
< return NGX_ERROR;
< }
<
< sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[0]);
< }
<
< if (sin->sin_addr.s_addr == INADDR_ANY) {
< u->wildcard = 1;
< }
<
< } else {
< sin->sin_addr.s_addr = INADDR_ANY;
< u->wildcard = 1;
---
> if(u->host.len > 0 && ngx_parse_host(pool, u) == NGX_ERROR) {
> u->err = "invalid host";
> return NGX_ERROR;
771c671,683
< sin->sin_port = htons(u->default_port);
---
> }
>
> #if (NGX_HAVE_INET6)
> if (u->family == AF_INET6) {
> sin6 = (struct sockaddr_in6 *)u->sockaddr;
> sin6->sin6_port = htons (u->port);
>
> }
> else
> #endif
> {
> sin = (struct sockaddr_in *)u->sockaddr;
> sin->sin_port = htons (u->port);
787c699
< ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
---
> ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
789,803c701,704
< #if (NGX_HAVE_INET6)
< 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 (NGX_HAVE_UNIX_DOMAIN)
> u_char *path, *uri, *last;
> size_t len;
> struct sockaddr_un *saun;
805,808c706,707
< if (p == NULL) {
< u->err = "invalid host";
< return NGX_ERROR;
< }
---
> len = u->url.len;
> path = u->url.data;
810c709,710
< if (last - p) {
---
> path += 5;
> len -= 5;
812c712
< port = p + 1;
---
> if (u->uri_part) {
814c714,715
< uri = ngx_strlchr(port, last, '/');
---
> last = path + len;
> uri = ngx_strlchr(path, last, ':');
817,821c718,719
< if (u->listen || !u->uri_part) {
< u->err = "invalid host";
< return NGX_ERROR;
< }
<
---
> len = uri - path;
> uri++;
824a723
> }
826,851c725,727
< 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;
< }
---
> if (len == 0) {
> u->err = "no path in the unix domain socket";
> return NGX_ERROR;
854c730,731
< len = p - host;
---
> u->host.len = len++;
> u->host.data = path;
856,857c733,734
< if (len == 0) {
< u->err = "no host";
---
> if (len > sizeof(saun->sun_path)) {
> u->err = "too long path in the unix domain socket";
861,862c738,741
< u->host.len = len;
< u->host.data = host;
---
> 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);
864,865c743,744
< if (ngx_inet6_addr(host, len, sin6->sin6_addr.s6_addr) != NGX_OK) {
< u->err = "invalid IPv6 address";
---
> u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
> if (u->addrs == NULL) {
869,870c748,750
< if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
< u->wildcard = 1;
---
> saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
> if (saun == NULL) {
> return NGX_ERROR;
873c753,754
< u->family = AF_INET6;
---
> u->family = AF_UNIX;
> u->naddrs = 1;
875,877c756,757
< if (u->no_resolve) {
< return NGX_OK;
< }
---
> saun->sun_family = AF_UNIX;
> (void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
879,882c759,762
< if (u->no_port) {
< u->port = u->default_port;
< sin6->sin6_port = htons(u->default_port);
< }
---
> u->addrs[0].sockaddr = (struct sockaddr *) saun;
> u->addrs[0].socklen = sizeof(struct sockaddr_un);
> u->addrs[0].name.len = len + 4;
> u->addrs[0].name.data = u->url.data;
888c768
< u->err = "the INET6 sockets are not supported on this platform";
---
> u->err = "the unix domain sockets are not supported on this platform";
894a775,891
> static ngx_int_t
> ngx_parse_host(ngx_pool_t *pool, ngx_url_t *u) {
> u_char *p;
> ngx_uint_t family, n;
> in_addr_t inaddr;
> struct sockaddr_in *sin;
> struct addrinfo hints, *addrinfo;
>
> #if (NGX_HAVE_INET6)
> struct in6_addr inaddr6;
> struct sockaddr_in6 *sin6;
>
> if (u->family == AF_INET6) {
> /* u->family has been set to AF_INET6 means the host
> * to be parsed should be IPv6 address so no need to parse
> * it as IPv4 or resolve host
> */
> ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));
> if (ngx_inet6_addr(u->host.data, u->host.len, inaddr6.s6_addr) == NGX_OK) {
> family = AF_INET6;
> goto done;
> } else {
> u->err = "invalid host";
> return NGX_ERROR;
> }
> }
> #endif
>
> inaddr = ngx_inet_addr(u->host.data, u->host.len);
>
> if (inaddr != INADDR_NONE) {
> family = AF_INET;
>
> #if (NGX_HAVE_INET6)
> } else if (ngx_inet6_addr(u->host.data, u->host.len, inaddr6.s6_addr) == NGX_OK) {
> family = AF_INET6;
>
> #endif
> } else {
> /* resolve the IP address through host name
> only the first IP address will be used */
> p = ngx_alloc(u->host.len + 1, pool->log);
> if (p == NULL) {
> return NGX_ERROR;
> }
> ngx_cpystrn(p, u->host.data, u->host.len + 1);
>
> ngx_memzero (&hints, sizeof (struct addrinfo));
>
> if (u->listen) {
> hints.ai_flags = AI_PASSIVE;
> } else {
> hints.ai_flags = AI_CANONNAME;
> }
>
> hints.ai_protocol = IPPROTO_TCP;
>
> n = getaddrinfo((const char *) p,
> NULL, &hints, &addrinfo);
>
> ngx_free (p);
>
> if (n != NGX_OK) {
> u->err = "error in host resolve";
> return NGX_ERROR;
> }
>
> if (addrinfo->ai_family == AF_INET) {
> family = AF_INET;
> inaddr = ((struct sockaddr_in *) addrinfo->ai_addr)->sin_addr.s_addr;
>
> #if (NGX_HAVE_INET6)
> } else if (addrinfo->ai_family == AF_INET6) {
> family = AF_INET6;
> inaddr6 = ((struct sockaddr_in6 *) addrinfo->ai_addr)->sin6_addr;
>
> #endif
> } else {
> u->err = "unknown address family";
> return NGX_ERROR;
> }
> }
>
> #if (NGX_HAVE_INET6)
> done:
> #endif
>
> switch (family) {
>
> #if (NGX_HAVE_INET6)
> case AF_INET6:
> sin6 = (struct sockaddr_in6 *) u->sockaddr;
> sin6->sin6_family = AF_INET6;
> u->family = AF_INET6;
> u->socklen = sizeof (struct sockaddr_in6);
> ngx_memcpy(sin6->sin6_addr.s6_addr, inaddr6.s6_addr, 16);
>
> if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
> u->wildcard = 1;
> }
> break;
> #endif
>
> default: /* AF_INET */
> sin = (struct sockaddr_in *) u->sockaddr;
> sin->sin_family = AF_INET;
> u->family = AF_INET;
> u->socklen = sizeof (struct sockaddr_in);
> sin->sin_addr.s_addr = inaddr;
> if (sin->sin_addr.s_addr == INADDR_ANY) {
> u->wildcard = 1;
> }
> break;
> }
>
> return NGX_OK;
> }
902,904c899,901
< in_addr_t in_addr;
< ngx_uint_t i;
< struct hostent *h;
---
> in_addr_t inaddr;
> ngx_uint_t i, n;
> struct addrinfo hints, *addrinfo, *item;
907c904,913
< /* AF_INET only */
---
> #if (NGX_HAVE_INET6)
> struct in6_addr inaddr6;
> struct sockaddr_in6 *sin6;
>
> /*
> * prevent MSVC8 waring:
> * potentially uninitialized local variable 'inaddr6' used
> */
> ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));
> #endif
911c917
< in_addr = ngx_inet_addr(u->host.data, u->host.len);
---
> inaddr = ngx_inet_addr(u->host.data, u->host.len);
913,915c919,923
< if (in_addr == INADDR_NONE) {
< host = ngx_alloc(u->host.len + 1, pool->log);
< if (host == NULL) {
---
> if (inaddr != INADDR_NONE) {
> /* MP: ngx_shared_palloc() */
>
> u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
> if (u->addrs == NULL) {
919c927,930
< (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
---
> sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
> if (sin == NULL) {
> return NGX_ERROR;
> }
921c932
< h = gethostbyname((char *) host);
---
> u->naddrs = 1;
923c934,936
< ngx_free(host);
---
> sin->sin_family = AF_INET;
> sin->sin_port = port;
> sin->sin_addr.s_addr = inaddr;
925,926c938,942
< if (h == NULL || h->h_addr_list[0] == NULL) {
< u->err = "host not found";
---
> 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) {
930,931c946,948
< if (u->one_addr == 0) {
< for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
---
> u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
> &u->host, ntohs(port)) - p;
> u->addrs[0].name.data = p;
933,934c950,957
< } else {
< i = 1;
---
> return NGX_OK;
> }
>
> #if (NGX_HAVE_INET6)
> if(ngx_inet6_addr(u->host.data, u->host.len, inaddr6.s6_addr) == NGX_OK) {
> u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
> if (u->addrs == NULL) {
> return NGX_ERROR;
937c960,963
< /* MP: ngx_shared_palloc() */
---
> sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));
> if (sin6 == NULL) {
> return NGX_ERROR;
> }
939,940c965,974
< u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
< if (u->addrs == NULL) {
---
> u->naddrs = 1;
>
> sin6->sin6_family = AF_INET6;
> sin6->sin6_port = port;
> ngx_memcpy(sin6->sin6_addr.s6_addr, inaddr6.s6_addr, 16);
> 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) {
944c978,1007
< u->naddrs = i;
---
> u->addrs[0].name.len = ngx_sprintf(p, "[%V]:%d",
> &u->host, ntohs(port)) - p;
> u->addrs[0].name.data = p;
>
> return NGX_OK;
> }
> #endif
>
> /* resolve all the IP address for this host */
> host = ngx_alloc(u->host.len + 1, pool->log);
> if (host == NULL) {
> return NGX_ERROR;
> }
> ngx_cpystrn(host, u->host.data, u->host.len + 1);
>
> ngx_memzero (&hints, sizeof (struct addrinfo));
>
> /* if the address is for listen, it won't enter this reslove function */
> hints.ai_flags = AI_CANONNAME;
> hints.ai_protocol = IPPROTO_TCP;
>
> n = getaddrinfo((const char *) host,
> NULL, &hints, &addrinfo);
>
> ngx_free (host);
>
> if (n != NGX_OK) {
> u->err = "error in host resolve";
> return NGX_ERROR;
> }
946c1009
< for (i = 0; h->h_addr_list[i] != NULL; i++) {
---
> i = 0;
947a1011,1030
> if (u->one_addr == 0) {
> item = addrinfo;
> for (i = 0; item != NULL; i++, item = item->ai_next) { /* void */ }
>
> } else {
> i = 1;
> }
>
> /* MP: ngx_shared_palloc() */
>
> u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
> if (u->addrs == NULL) {
> return NGX_ERROR;
> }
>
> u->naddrs = i;
>
> for (i = 0; i < u->naddrs; i++, addrinfo = addrinfo->ai_next) {
>
> if (addrinfo->ai_family == AF_INET) {
955,956c1038,1039
< sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
<
---
> inaddr = ((struct sockaddr_in *) addrinfo->ai_addr)->sin_addr.s_addr;
> sin->sin_addr.s_addr = inaddr;
960a1044,1052
> p = ngx_pnalloc(pool, len);
> if (p == NULL) {
> return NGX_ERROR;
> }
>
> len = ngx_sock_ntop((struct sockaddr *) sin, p, len, sin->sin_port);
>
> u->addrs[i].name.len = len;
> u->addrs[i].name.data = p;
961a1054,1068
> #if (NGX_HAVE_INET6)
> } else if (addrinfo->ai_family == AF_INET6) {
> sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));
> if (sin6 == NULL) {
> return NGX_ERROR;
> }
>
> sin6->sin6_family = AF_INET6;
> sin6->sin6_port = port;
> inaddr6 = ((struct sockaddr_in6 *) addrinfo->ai_addr)->sin6_addr;
> ngx_memcpy(sin6->sin6_addr.s6_addr, inaddr6.s6_addr, 16);
> u->addrs[i].sockaddr = (struct sockaddr *) sin6;
> u->addrs[i].socklen = sizeof(struct sockaddr_in6);
>
> len = NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1;
967c1074
< len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
---
> len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, sin6->sin6_port);
970a1078,1081
> #endif
> } else {
> u->err = "unknown address family";
> return NGX_ERROR;
971a1083
> }
973c1085,1086
< } else {
---
> return NGX_OK;
> }
975c1088,1093
< /* MP: ngx_shared_palloc() */
---
> ngx_int_t
> ngx_inet_sock_addr (u_char * p, size_t len, struct sockaddr * sockaddr)
> {
> u_char *port, *last;
> ngx_int_t n;
> struct sockaddr_in *sin;
977,978c1095,1116
< u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
< if (u->addrs == NULL) {
---
> #if (NGX_HAVE_INET6)
> struct sockaddr_in6 *sin6;
> u_char *q;
> #endif
>
> if (len == 0) {
> return NGX_ERROR;
> }
>
> last = p + len;
>
> port = NULL;
>
> #if (NGX_HAVE_INET6)
>
> if (*p == '[') {
>
> p++;
>
> q = ngx_strlchr(p, last, ']');
>
> if (q == NULL) {
982,983c1120,1122
< sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
< if (sin == NULL) {
---
> if (q < last - 2 && *(q + 1) == ':') {
> port = q + 2;
> } else {
987c1126,1152
< u->naddrs = 1;
---
> sin6 = (struct sockaddr_in6 *)sockaddr;
>
> sin6->sin6_family = AF_INET6;
>
> if (ngx_inet6_addr(p, q - p, sin6->sin6_addr.s6_addr) == NGX_ERROR) {
> return NGX_ERROR;
> }
>
> n = ngx_atoi(port, last - port);
>
> if (n == NGX_ERROR || n < 1 || n > 65535) {
> return NGX_ERROR;
> }
>
> sin6->sin6_port = htons(n);
>
> }
> else
> #endif
> {
> port = ngx_strlchr(p, last, ':');
>
> if (port == NULL) {
> return NGX_ERROR;
> }
>
> sin = (struct sockaddr_in *)sockaddr;
990,991d1154
< sin->sin_port = port;
< sin->sin_addr.s_addr = in_addr;
993,994c1156
< u->addrs[0].sockaddr = (struct sockaddr *) sin;
< u->addrs[0].socklen = sizeof(struct sockaddr_in);
---
> sin->sin_addr.s_addr = ngx_inet_addr (p, port - p);
996,997c1158
< p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
< if (p == NULL) {
---
> if (sin->sin_addr.s_addr == INADDR_NONE) {
1001,1003c1162,1171
< u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
< &u->host, ntohs(port)) - p;
< u->addrs[0].name.data = p;
---
> port++;
>
> n = ngx_atoi(port, last - port);
>
> if (n == NGX_ERROR || n < 1 || n > 65535) {
> return NGX_ERROR;
> }
>
> sin->sin_port = htons(n);
>
===============ngx_inet.h=====================
110a111,112
> ngx_int_t ngx_inet_sock_addr (u_char * p, size_t len,
> struct sockaddr * sockaddr);
--
Jiankuan Xing ~~
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://nginx.org/pipermail/nginx-devel/attachments/20110228/7b06324f/attachment-0001.html>
More information about the nginx-devel
mailing list