[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