<div>Two files are affected &quot;ngx_inet.c&quot; and &quot;ngx_inet.h&quot;. I remove the original &quot;ngx_parse_inet_url&quot; and &quot;ngx_parse_inet6_url&quot; because they have many duplicated code and &quot;ngx_pare_inet_url&quot; this name won&#39;t describe what it does comprehensively (it may generate IPv6 too).</div>

<div><br></div><div>So I use &quot;ngx_parse_url&quot; to split the url to &quot;host&quot;, &quot;port&quot;, &quot;uri&quot; and create a function &quot;ngx_parse_host&quot; to convert host to IP address. Besides, I also change &quot;ngx_inet_resolve_host&quot; to make it accept IPv6.</div>

<div><br></div><div>At last I add a function &quot;ngx_inet_sock_addr&quot; to convert &quot;ipv4:port&quot; and &quot;[ipv6]:port&quot; to sockaddr_in and sockaddr_in6.</div><div><br></div><div>The following test has been done to verify the functionality of url parse (Here ip = ipv4 and ipv6).</div>

<div><br></div><div>1. only port   ==&gt; only accept IPv4</div><div>2. *:port ==&gt; same as 1</div><div>3. [::]:port ==&gt; accept both ipv4 and ipv6 if not set ipv6only=on</div><div>4. ip:port</div><div>5. ip:port/uri</div>

<div>6. ip:port/uri?arg</div><div>7: ip/uri?arg</div><div>8. text:port   (text url can be resolved to 1 IPv6 addr)</div><div>9. text:port   (text url can be resolved to many addr, some are IPv4 and some IPv6. The url-&gt;sockaddr always be the first IP address) </div>

<div><br></div><div><meta charset="utf-8">--------------------------------------------------------ngx_inet.c-------------------------------------------</div><div><br></div><div>--- nginx-0.9.3/src/core/ngx_inet.c<span style="white-space:pre-wrap">        </span>2009-12-07 07:13:46.000000000 -0800</div>

<div>+++ /home/speedfirst/p4/zimbra/main/ThirdParty/nginx/nginx-0.9-zimbra/src/core/ngx_inet.c<span style="white-space:pre-wrap">        </span>2011-02-28 02:17:31.187902103 -0800</div>
<div>@@ -9,8 +9,7 @@</div><div> </div><div> </div><div> static ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u);</div><div>-static ngx_int_t ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u);</div><div>


-static ngx_int_t ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u);</div><div>+static ngx_int_t ngx_parse_host(ngx_pool_t *pool, ngx_url_t *u);</div><div> </div><div> </div><div> in_addr_t</div><div>@@ -446,7 +445,6 @@</div>


<div>     }</div><div> }</div><div> </div><div>-</div><div> ngx_int_t</div><div> ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)</div><div> {</div><div>@@ -506,11 +504,18 @@</div><div>     return NGX_OK;</div>


<div> }</div><div> </div><div>-</div><div> ngx_int_t</div><div> ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)</div><div> {</div><div>-    u_char  *p;</div><div>+    u_char   *p, *host, *port, *last, *uri, *args;</div><div>


+    size_t    len;</div><div>+    ngx_int_t n;</div><div>+    struct sockaddr_in  *sin;</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div><div>+    struct sockaddr_in6 *sin6;</div><div>+    ngx_flag_t           ipv6 = 0;</div>


<div>+#endif</div><div> </div><div>     p = u-&gt;url.data;</div><div> </div><div>@@ -523,129 +528,44 @@</div><div>         return NGX_ERROR;</div><div>     }</div><div> </div><div>-    if (p[0] == &#39;[&#39;) {</div><div>


-        return ngx_parse_inet6_url(pool, u);</div><div>-    }</div><div>+    host = u-&gt;url.data;</div><div> </div><div>-    return ngx_parse_inet_url(pool, u);</div><div>-}</div><div>+    last = host + u-&gt;url.len;</div>


<div> </div><div>+    len = 0;</div><div> </div><div>-static ngx_int_t</div><div>-ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)</div><div>-{</div><div>-#if (NGX_HAVE_UNIX_DOMAIN)</div><div>-    u_char              *path, *uri, *last;</div>


<div>-    size_t               len;</div><div>-    struct sockaddr_un  *saun;</div><div>-</div><div>-    len = u-&gt;url.len;</div><div>-    path = u-&gt;url.data;</div><div>+#if (NGX_HAVE_INET6)</div><div>+    if (host[0] == &#39;[&#39;) {</div>


<div> </div><div>-    path += 5;</div><div>-    len -= 5;</div><div>+        ipv6 = 1;</div><div> </div><div>-    if (u-&gt;uri_part) {</div><div>+        host = u-&gt;url.data + 1;</div><div> </div><div>-        last = path + len;</div>


<div>-        uri = ngx_strlchr(path, last, &#39;:&#39;);</div><div>+        p = ngx_strlchr(host, last, &#39;]&#39;);</div><div> </div><div>-        if (uri) {</div><div>-            len = uri - path;</div><div>-            uri++;</div>


<div>-            u-&gt;uri.len = last - uri;</div><div>-            u-&gt;uri.data = uri;</div><div>+        if (p == NULL) {</div><div>+            u-&gt;err = &quot;invalid host&quot;;</div><div>+            return NGX_ERROR;</div>


<div>         }</div><div>-    }</div><div>-</div><div>-    if (len == 0) {</div><div>-        u-&gt;err = &quot;no path in the unix domain socket&quot;;</div><div>-        return NGX_ERROR;</div><div>-    }</div><div>-</div>


<div>-    u-&gt;host.len = len++;</div><div>-    u-&gt;host.data = path;</div><div>-</div><div>-    if (len &gt; sizeof(saun-&gt;sun_path)) {</div><div>-        u-&gt;err = &quot;too long path in the unix domain socket&quot;;</div>


<div>-        return NGX_ERROR;</div><div>-    }</div><div>-</div><div>-    u-&gt;socklen = sizeof(struct sockaddr_un);</div><div>-    saun = (struct sockaddr_un *) &amp;u-&gt;sockaddr;</div><div>-    saun-&gt;sun_family = AF_UNIX;</div>


<div>-    (void) ngx_cpystrn((u_char *) saun-&gt;sun_path, path, len);</div><div> </div><div>-    u-&gt;addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));</div><div>-    if (u-&gt;addrs == NULL) {</div><div>-        return NGX_ERROR;</div>


<div>-    }</div><div>+        u-&gt;family = AF_INET6;</div><div> </div><div>-    saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));</div><div>-    if (saun == NULL) {</div><div>-        return NGX_ERROR;</div><div>     }</div>


<div>-</div><div>-    u-&gt;family = AF_UNIX;</div><div>-    u-&gt;naddrs = 1;</div><div>-</div><div>-    saun-&gt;sun_family = AF_UNIX;</div><div>-    (void) ngx_cpystrn((u_char *) saun-&gt;sun_path, path, len);</div><div>


-</div><div>-    u-&gt;addrs[0].sockaddr = (struct sockaddr *) saun;</div><div>-    u-&gt;addrs[0].socklen = sizeof(struct sockaddr_un);</div><div>-    u-&gt;addrs[0].name.len = len + 4;</div><div>-    u-&gt;addrs[0].name.data = u-&gt;url.data;</div>


<div>-</div><div>-    return NGX_OK;</div><div>-</div><div>-#else</div><div>-</div><div>-    u-&gt;err = &quot;the unix domain sockets are not supported on this platform&quot;;</div><div>-</div><div>-    return NGX_ERROR;</div>


<div>-</div><div> #endif</div><div>-}</div><div>-</div><div>-</div><div>-static ngx_int_t</div><div>-ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)</div><div>-{</div><div>-    u_char              *p, *host, *port, *last, *uri, *args;</div>


<div>-    size_t               len;</div><div>-    ngx_int_t            n;</div><div>-    struct hostent      *h;</div><div>-    struct sockaddr_in  *sin;</div><div>-</div><div>-    u-&gt;socklen = sizeof(struct sockaddr_in);</div>


<div>-    sin = (struct sockaddr_in *) &amp;u-&gt;sockaddr;</div><div>-    sin-&gt;sin_family = AF_INET;</div><div>-</div><div>-    u-&gt;family = AF_INET;</div><div>-</div><div>-    host = u-&gt;url.data;</div><div>-</div>


<div>-    last = host + u-&gt;url.len;</div><div>-</div><div>-    port = ngx_strlchr(host, last, &#39;:&#39;);</div><div> </div><div>-    uri = ngx_strlchr(host, last, &#39;/&#39;);</div><div>+    port = ngx_strlchr(p, last, &#39;:&#39;);</div>


<div> </div><div>-    args = ngx_strlchr(host, last, &#39;?&#39;);</div><div>+    uri = ngx_strlchr(p, last, &#39;/&#39;);</div><div> </div><div>-    if (args) {</div><div>-        if (uri == NULL) {</div><div>-            uri = args;</div>


<div>+    args = ngx_strlchr(p, last, &#39;?&#39;);</div><div> </div><div>-        } else if (args &lt; uri) {</div><div>-            uri = args;</div><div>-        }</div><div>+    if (args &amp;&amp; (uri == NULL || args &lt; uri)) {</div>


<div>+        uri = args;</div><div>     }</div><div> </div><div>     if (uri) {</div><div>         if (u-&gt;listen || !u-&gt;uri_part) {</div><div>-            u-&gt;err = &quot;invalid host&quot;;</div><div>+            u-&gt;err = &quot;invalid url to listen&quot;;</div>


<div>             return NGX_ERROR;</div><div>         }</div><div> </div><div>@@ -677,54 +597,61 @@</div><div>         }</div><div> </div><div>         u-&gt;port = (in_port_t) n;</div><div>-        sin-&gt;sin_port = htons((in_port_t) n);</div>


<div>-</div><div>         u-&gt;port_text.len = len;</div><div>         u-&gt;port_text.data = port;</div><div> </div><div>         last = port - 1;</div><div> </div><div>     } else {</div><div>-        if (uri == NULL) {</div>


<div>-</div><div>-            if (u-&gt;listen) {</div><div>-</div><div>-                /* test value as port only */</div><div>+        if (uri == NULL &amp;&amp; u-&gt;listen) {</div><div>+            /* test value as port only */</div>


<div> </div><div>-                n = ngx_atoi(host, last - host);</div><div>+            n = ngx_atoi(u-&gt;url.data, u-&gt;url.len);</div><div> </div><div>-                if (n != NGX_ERROR) {</div><div>-</div><div>-                    if (n &lt; 1 || n &gt; 65536) {</div>


<div>-                        u-&gt;err = &quot;invalid port&quot;;</div><div>-                        return NGX_ERROR;</div><div>-                    }</div><div>-</div><div>-                    u-&gt;port = (in_port_t) n;</div>


<div>-                    sin-&gt;sin_port = htons((in_port_t) n);</div><div>+            if (n &lt; 1 || n &gt; 65536) {</div><div>+                u-&gt;err = &quot;invalid port&quot;;</div><div>+                return NGX_ERROR;</div>


<div>+            }</div><div> </div><div>-                    u-&gt;port_text.len = last - host;</div><div>-                    u-&gt;port_text.data = host;</div><div>+            u-&gt;family = AF_INET;</div><div>+            u-&gt;port = (in_port_t) n;</div>


<div>+            sin = (struct sockaddr_in *)u-&gt;sockaddr;</div><div>+            sin-&gt;sin_family = AF_INET;</div><div>+            sin-&gt;sin_addr.s_addr = INADDR_ANY;</div><div>+            sin-&gt;sin_port = htons((in_port_t) n);</div>


<div>+            u-&gt;port_text.len = len;</div><div>+            u-&gt;port_text.data = port;</div><div>+            u-&gt;socklen = sizeof (struct sockaddr_in);</div><div>+            u-&gt;wildcard = 1;</div><div> </div>


<div>-                    u-&gt;wildcard = 1;</div><div>+            return NGX_OK;</div><div> </div><div>-                    return NGX_OK;</div><div>-                }</div><div>-            }</div><div>+        } else {</div>


<div>+            u-&gt;no_port = 1;</div><div>         }</div><div>+    }</div><div> </div><div>-        u-&gt;no_port = 1;</div><div>+#if (NGX_HAVE_INET6)</div><div>+    if (ipv6) {</div><div>+        if (*(last - 1) == &#39;]&#39; &amp;&amp; last &gt; host) {</div>


<div>+            last--;</div><div>+        } else {</div><div>+            u-&gt;err = &quot;invalid host&quot;;</div><div>+            return NGX_ERROR;</div><div>+        }</div><div>     }</div><div>+#endif</div><div>


 </div><div>     len = last - host;</div><div> </div><div>-    if (len == 0) {</div><div>-        u-&gt;err = &quot;no host&quot;;</div><div>-        return NGX_ERROR;</div><div>-    }</div><div>-</div><div>     if (len == 1 &amp;&amp; *host == &#39;*&#39;) {</div>


<div>         len = 0;</div><div>+        u-&gt;family = AF_INET;</div><div>+        u-&gt;socklen = sizeof (struct sockaddr_in);</div><div>+        u-&gt;wildcard = 1;</div><div>+        sin = (struct sockaddr_in *)u-&gt;sockaddr;</div>


<div>+        sin-&gt;sin_family = AF_INET;</div><div>+        sin-&gt;sin_addr.s_addr = INADDR_ANY;</div><div>     }</div><div> </div><div>     u-&gt;host.len = len;</div><div>@@ -734,41 +661,26 @@</div><div>         return NGX_OK;</div>


<div>     }</div><div> </div><div>-    if (len) {</div><div>-        sin-&gt;sin_addr.s_addr = ngx_inet_addr(host, len);</div><div>-</div><div>-        if (sin-&gt;sin_addr.s_addr == INADDR_NONE) {</div><div>-            p = ngx_alloc(++len, pool-&gt;log);</div>


<div>-            if (p == NULL) {</div><div>-                return NGX_ERROR;</div><div>-            }</div><div>-</div><div>-            (void) ngx_cpystrn(p, host, len);</div><div>-</div><div>-            h = gethostbyname((const char *) p);</div>


<div>-</div><div>-            ngx_free(p);</div><div>-</div><div>-            if (h == NULL || h-&gt;h_addr_list[0] == NULL) {</div><div>-                u-&gt;err = &quot;host not found&quot;;</div><div>-                return NGX_ERROR;</div>


<div>-            }</div><div>-</div><div>-            sin-&gt;sin_addr.s_addr = *(in_addr_t *) (h-&gt;h_addr_list[0]);</div><div>-        }</div><div>-</div><div>-        if (sin-&gt;sin_addr.s_addr == INADDR_ANY) {</div>


<div>-            u-&gt;wildcard = 1;</div><div>-        }</div><div>-</div><div>-    } else {</div><div>-        sin-&gt;sin_addr.s_addr = INADDR_ANY;</div><div>-        u-&gt;wildcard = 1;</div><div>+    if(u-&gt;host.len &gt; 0 &amp;&amp; ngx_parse_host(pool, u) == NGX_ERROR) {</div>


<div>+        u-&gt;err = &quot;invalid host&quot;;</div><div>+        return NGX_ERROR;</div><div>     }</div><div> </div><div>     if (u-&gt;no_port) {</div><div>         u-&gt;port = u-&gt;default_port;</div><div>-        sin-&gt;sin_port = htons(u-&gt;default_port);</div>


<div>+    }</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div><div>+    if (u-&gt;family == AF_INET6) {</div><div>+        sin6 = (struct sockaddr_in6 *)u-&gt;sockaddr;</div><div>+        sin6-&gt;sin6_port = htons (u-&gt;port);</div>


<div>+</div><div>+    }</div><div>+    else</div><div>+#endif</div><div>+    {</div><div>+        sin = (struct sockaddr_in *)u-&gt;sockaddr;</div><div>+        sin-&gt;sin_port = htons (u-&gt;port);</div><div>     }</div>


<div> </div><div>     if (u-&gt;listen) {</div><div>@@ -784,114 +696,199 @@</div><div> </div><div> </div><div> static ngx_int_t</div><div>-ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)</div><div>+ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)</div>


<div> {</div><div>-#if (NGX_HAVE_INET6)</div><div>-    u_char               *p, *host, *port, *last, *uri;</div><div>-    size_t                len;</div><div>-    ngx_int_t             n;</div><div>-    struct sockaddr_in6  *sin6;</div>


<div>-</div><div>-    u-&gt;socklen = sizeof(struct sockaddr_in6);</div><div>-    sin6 = (struct sockaddr_in6 *) &amp;u-&gt;sockaddr;</div><div>-    sin6-&gt;sin6_family = AF_INET6;</div><div>-</div><div>-    host = u-&gt;url.data + 1;</div>


<div>-</div><div>-    last = u-&gt;url.data + u-&gt;url.len;</div><div>-</div><div>-    p = ngx_strlchr(host, last, &#39;]&#39;);</div><div>+#if (NGX_HAVE_UNIX_DOMAIN)</div><div>+    u_char              *path, *uri, *last;</div>


<div>+    size_t               len;</div><div>+    struct sockaddr_un  *saun;</div><div> </div><div>-    if (p == NULL) {</div><div>-        u-&gt;err = &quot;invalid host&quot;;</div><div>-        return NGX_ERROR;</div>


<div>-    }</div><div>+    len = u-&gt;url.len;</div><div>+    path = u-&gt;url.data;</div><div> </div><div>-    if (last - p) {</div><div>+    path += 5;</div><div>+    len -= 5;</div><div> </div><div>-        port = p + 1;</div>


<div>+    if (u-&gt;uri_part) {</div><div> </div><div>-        uri = ngx_strlchr(port, last, &#39;/&#39;);</div><div>+        last = path + len;</div><div>+        uri = ngx_strlchr(path, last, &#39;:&#39;);</div><div> </div>


<div>         if (uri) {</div><div>-            if (u-&gt;listen || !u-&gt;uri_part) {</div><div>-                u-&gt;err = &quot;invalid host&quot;;</div><div>-                return NGX_ERROR;</div><div>-            }</div>


<div>-</div><div>+            len = uri - path;</div><div>+            uri++;</div><div>             u-&gt;uri.len = last - uri;</div><div>             u-&gt;uri.data = uri;</div><div>         }</div><div>+    }</div><div>


 </div><div>-        if (*port == &#39;:&#39;) {</div><div>-            port++;</div><div>-</div><div>-            len = last - port;</div><div>-</div><div>-            if (len == 0) {</div><div>-                u-&gt;err = &quot;invalid port&quot;;</div>


<div>-                return NGX_ERROR;</div><div>-            }</div><div>-</div><div>-            n = ngx_atoi(port, len);</div><div>-</div><div>-            if (n &lt; 1 || n &gt; 65536) {</div><div>-                u-&gt;err = &quot;invalid port&quot;;</div>


<div>-                return NGX_ERROR;</div><div>-            }</div><div>-</div><div>-            u-&gt;port = (in_port_t) n;</div><div>-            sin6-&gt;sin6_port = htons((in_port_t) n);</div><div>-</div><div>-            u-&gt;port_text.len = len;</div>


<div>-            u-&gt;port_text.data = port;</div><div>-</div><div>-        } else {</div><div>-            u-&gt;no_port = 1;</div><div>-        }</div><div>+    if (len == 0) {</div><div>+        u-&gt;err = &quot;no path in the unix domain socket&quot;;</div>


<div>+        return NGX_ERROR;</div><div>     }</div><div> </div><div>-    len = p - host;</div><div>+    u-&gt;host.len = len++;</div><div>+    u-&gt;host.data = path;</div><div> </div><div>-    if (len == 0) {</div><div>


-        u-&gt;err = &quot;no host&quot;;</div><div>+    if (len &gt; sizeof(saun-&gt;sun_path)) {</div><div>+        u-&gt;err = &quot;too long path in the unix domain socket&quot;;</div><div>         return NGX_ERROR;</div>


<div>     }</div><div> </div><div>-    u-&gt;host.len = len;</div><div>-    u-&gt;host.data = host;</div><div>+    u-&gt;socklen = sizeof(struct sockaddr_un);</div><div>+    saun = (struct sockaddr_un *) &amp;u-&gt;sockaddr;</div>


<div>+    saun-&gt;sun_family = AF_UNIX;</div><div>+    (void) ngx_cpystrn((u_char *) saun-&gt;sun_path, path, len);</div><div> </div><div>-    if (ngx_inet6_addr(host, len, sin6-&gt;sin6_addr.s6_addr) != NGX_OK) {</div>

<div>
-        u-&gt;err = &quot;invalid IPv6 address&quot;;</div><div>+    u-&gt;addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));</div><div>+    if (u-&gt;addrs == NULL) {</div><div>         return NGX_ERROR;</div><div>     }</div>


<div> </div><div>-    if (IN6_IS_ADDR_UNSPECIFIED(&amp;sin6-&gt;sin6_addr)) {</div><div>-        u-&gt;wildcard = 1;</div><div>+    saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));</div><div>+    if (saun == NULL) {</div>


<div>+        return NGX_ERROR;</div><div>     }</div><div> </div><div>-    u-&gt;family = AF_INET6;</div><div>+    u-&gt;family = AF_UNIX;</div><div>+    u-&gt;naddrs = 1;</div><div> </div><div>-    if (u-&gt;no_resolve) {</div>


<div>-        return NGX_OK;</div><div>-    }</div><div>+    saun-&gt;sun_family = AF_UNIX;</div><div>+    (void) ngx_cpystrn((u_char *) saun-&gt;sun_path, path, len);</div><div> </div><div>-    if (u-&gt;no_port) {</div>


<div>-        u-&gt;port = u-&gt;default_port;</div><div>-        sin6-&gt;sin6_port = htons(u-&gt;default_port);</div><div>-    }</div><div>+    u-&gt;addrs[0].sockaddr = (struct sockaddr *) saun;</div><div>+    u-&gt;addrs[0].socklen = sizeof(struct sockaddr_un);</div>


<div>+    u-&gt;addrs[0].name.len = len + 4;</div><div>+    u-&gt;addrs[0].name.data = u-&gt;url.data;</div><div> </div><div>     return NGX_OK;</div><div> </div><div> #else</div><div> </div><div>-    u-&gt;err = &quot;the INET6 sockets are not supported on this platform&quot;;</div>


<div>+    u-&gt;err = &quot;the unix domain sockets are not supported on this platform&quot;;</div><div> </div><div>     return NGX_ERROR;</div><div> </div><div> #endif</div><div> }</div><div> </div><div>+static ngx_int_t</div>


<div>+ngx_parse_host(ngx_pool_t *pool, ngx_url_t *u) {</div><div>+    u_char                *p;</div><div>+    ngx_uint_t            family, n;</div><div>+    in_addr_t             inaddr;</div><div>+    struct sockaddr_in   *sin;</div>


<div>+    struct addrinfo       hints, *addrinfo;</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div><div>+    struct in6_addr       inaddr6;</div><div>+    struct sockaddr_in6  *sin6;</div><div>+</div><div>+   if (u-&gt;family == AF_INET6) {</div>


<div>+       /* u-&gt;family has been set to AF_INET6 means the host</div><div>+        * to be parsed should be IPv6 address so no need to parse</div><div>+        * it as IPv4 or resolve host</div><div>+        */</div>


<div>+       ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));</div><div>+       if (ngx_inet6_addr(u-&gt;host.data, u-&gt;host.len, inaddr6.s6_addr) == NGX_OK) {</div><div>+           family = AF_INET6;</div><div>+           goto done;</div>


<div>+       } else {</div><div>+           u-&gt;err = &quot;invalid host&quot;;</div><div>+           return NGX_ERROR;</div><div>+       }</div><div>+   }</div><div>+#endif</div><div>+</div><div>+   inaddr = ngx_inet_addr(u-&gt;host.data, u-&gt;host.len);</div>


<div>+</div><div>+   if (inaddr != INADDR_NONE) {</div><div>+       family = AF_INET;</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div><div>+   } else if (ngx_inet6_addr(u-&gt;host.data, u-&gt;host.len, inaddr6.s6_addr) == NGX_OK) {</div>


<div>+       family = AF_INET6;</div><div>+</div><div>+#endif</div><div>+   } else {</div><div>+       /* resolve the IP address through host name</div><div>+          only the first IP address will be used   */</div><div>


+       p = ngx_alloc(u-&gt;host.len + 1, pool-&gt;log);</div><div>+       if (p == NULL) {</div><div>+          return NGX_ERROR;</div><div>+       }</div><div>+       ngx_cpystrn(p, u-&gt;host.data, u-&gt;host.len + 1);</div>


<div>+</div><div>+       ngx_memzero (&amp;hints, sizeof (struct addrinfo));</div><div>+</div><div>+       if (u-&gt;listen) {</div><div>+           hints.ai_flags = AI_PASSIVE;</div><div>+       } else {</div><div>+           hints.ai_flags = AI_CANONNAME;</div>


<div>+       }</div><div>+</div><div>+       hints.ai_protocol = IPPROTO_TCP;</div><div>+</div><div>+       n = getaddrinfo((const char *) p,</div><div>+               NULL, &amp;hints, &amp;addrinfo);</div><div>+</div><div>


+       ngx_free (p);</div><div>+</div><div>+       if (n != NGX_OK) {</div><div>+           u-&gt;err = &quot;error in host resolve&quot;;</div><div>+           return NGX_ERROR;</div><div>+       }</div><div>+</div><div>


+       if (addrinfo-&gt;ai_family == AF_INET) {</div><div>+           family = AF_INET;</div><div>+           inaddr = ((struct sockaddr_in *) addrinfo-&gt;ai_addr)-&gt;sin_addr.s_addr;</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div>


<div>+       } else if (addrinfo-&gt;ai_family == AF_INET6) {</div><div>+           family = AF_INET6;</div><div>+           inaddr6 = ((struct sockaddr_in6 *) addrinfo-&gt;ai_addr)-&gt;sin6_addr;</div><div>+</div><div>+#endif</div>


<div>+       } else {</div><div>+           u-&gt;err = &quot;unknown address family&quot;;</div><div>+           return NGX_ERROR;</div><div>+       }</div><div>+   }</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div><div>


+   done:</div><div>+#endif</div><div>+</div><div>+   switch (family) {</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div><div>+   case AF_INET6:</div><div>+       sin6 = (struct sockaddr_in6 *) u-&gt;sockaddr;</div><div>

+       sin6-&gt;sin6_family = AF_INET6;</div>
<div>+       u-&gt;family = AF_INET6;</div><div>+       u-&gt;socklen = sizeof (struct sockaddr_in6);</div><div>+       ngx_memcpy(sin6-&gt;sin6_addr.s6_addr, inaddr6.s6_addr, 16);</div><div>+</div><div>+       if (IN6_IS_ADDR_UNSPECIFIED(&amp;sin6-&gt;sin6_addr)) {</div>


<div>+           u-&gt;wildcard = 1;</div><div>+       }</div><div>+       break;</div><div>+#endif</div><div>+</div><div>+   default: /* AF_INET */</div><div>+       sin = (struct sockaddr_in *) u-&gt;sockaddr;</div><div>


+       sin-&gt;sin_family = AF_INET;</div><div>+       u-&gt;family = AF_INET;</div><div>+       u-&gt;socklen = sizeof (struct sockaddr_in);</div><div>+       sin-&gt;sin_addr.s_addr = inaddr;</div><div>+       if (sin-&gt;sin_addr.s_addr == INADDR_ANY) {</div>


<div>+           u-&gt;wildcard = 1;</div><div>+       }</div><div>+       break;</div><div>+   }</div><div>+</div><div>+   return NGX_OK;</div><div>+}</div><div> </div><div> ngx_int_t</div><div> ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)</div>


<div>@@ -899,52 +896,138 @@</div><div>     u_char              *p, *host;</div><div>     size_t               len;</div><div>     in_port_t            port;</div><div>-    in_addr_t            in_addr;</div><div>-    ngx_uint_t           i;</div>


<div>-    struct hostent      *h;</div><div>+    in_addr_t            inaddr;</div><div>+    ngx_uint_t           i, n;</div><div>+    struct addrinfo      hints, *addrinfo, *item;</div><div>     struct sockaddr_in  *sin;</div>


<div> </div><div>-    /* AF_INET only */</div><div>+#if (NGX_HAVE_INET6)</div><div>+    struct in6_addr      inaddr6;</div><div>+    struct sockaddr_in6 *sin6;</div><div>+</div><div>+    /*</div><div>+     * prevent MSVC8 waring:</div>


<div>+     *    potentially uninitialized local variable &#39;inaddr6&#39; used</div><div>+     */</div><div>+    ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));</div><div>+#endif</div><div> </div><div>     port = htons(u-&gt;port);</div>


<div> </div><div>-    in_addr = ngx_inet_addr(u-&gt;host.data, u-&gt;host.len);</div><div>+    inaddr = ngx_inet_addr(u-&gt;host.data, u-&gt;host.len);</div><div> </div><div>-    if (in_addr == INADDR_NONE) {</div><div>-        host = ngx_alloc(u-&gt;host.len + 1, pool-&gt;log);</div>


<div>-        if (host == NULL) {</div><div>+    if (inaddr != INADDR_NONE) {</div><div>+        /* MP: ngx_shared_palloc() */</div><div>+</div><div>+        u-&gt;addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));</div><div>


+        if (u-&gt;addrs == NULL) {</div><div>             return NGX_ERROR;</div><div>         }</div><div> </div><div>-        (void) ngx_cpystrn(host, u-&gt;host.data, u-&gt;host.len + 1);</div><div>+        sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));</div>


<div>+        if (sin == NULL) {</div><div>+            return NGX_ERROR;</div><div>+        }</div><div> </div><div>-        h = gethostbyname((char *) host);</div><div>+        u-&gt;naddrs = 1;</div><div> </div><div>-        ngx_free(host);</div>


<div>+        sin-&gt;sin_family = AF_INET;</div><div>+        sin-&gt;sin_port = port;</div><div>+        sin-&gt;sin_addr.s_addr = inaddr;</div><div> </div><div>-        if (h == NULL || h-&gt;h_addr_list[0] == NULL) {</div>


<div>-            u-&gt;err = &quot;host not found&quot;;</div><div>+        u-&gt;addrs[0].sockaddr = (struct sockaddr *) sin;</div><div>+        u-&gt;addrs[0].socklen = sizeof(struct sockaddr_in);</div><div>+</div><div>


+        p = ngx_pnalloc(pool, u-&gt;host.len + sizeof(&quot;:65535&quot;) - 1);</div><div>+        if (p == NULL) {</div><div>             return NGX_ERROR;</div><div>         }</div><div> </div><div>-        if (u-&gt;one_addr == 0) {</div>


<div>-            for (i = 0; h-&gt;h_addr_list[i] != NULL; i++) { /* void */ }</div><div>+        u-&gt;addrs[0].name.len = ngx_sprintf(p, &quot;%V:%d&quot;,</div><div>+                                           &amp;u-&gt;host, ntohs(port)) - p;</div>


<div>+        u-&gt;addrs[0].name.data = p;</div><div> </div><div>-        } else {</div><div>-            i = 1;</div><div>+        return NGX_OK;</div><div>+    }</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div><div>+    if(ngx_inet6_addr(u-&gt;host.data, u-&gt;host.len, inaddr6.s6_addr) == NGX_OK) {</div>


<div>+        u-&gt;addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));</div><div>+        if (u-&gt;addrs == NULL) {</div><div>+            return NGX_ERROR;</div><div>         }</div><div> </div><div>-        /* MP: ngx_shared_palloc() */</div>


<div>+        sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));</div><div>+        if (sin6 == NULL) {</div><div>+            return NGX_ERROR;</div><div>+        }</div><div> </div><div>-        u-&gt;addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));</div>


<div>-        if (u-&gt;addrs == NULL) {</div><div>+        u-&gt;naddrs = 1;</div><div>+</div><div>+        sin6-&gt;sin6_family = AF_INET6;</div><div>+        sin6-&gt;sin6_port = port;</div><div>+        ngx_memcpy(sin6-&gt;sin6_addr.s6_addr, inaddr6.s6_addr, 16);</div>


<div>+        u-&gt;addrs[0].sockaddr = (struct sockaddr *) sin6;</div><div>+        u-&gt;addrs[0].socklen = sizeof(struct sockaddr_in6);</div><div>+</div><div>+        p = ngx_pnalloc(pool, u-&gt;host.len + sizeof(&quot;:65535&quot;) - 1);</div>


<div>+        if (p == NULL) {</div><div>             return NGX_ERROR;</div><div>         }</div><div> </div><div>-        u-&gt;naddrs = i;</div><div>+        u-&gt;addrs[0].name.len = ngx_sprintf(p, &quot;[%V]:%d&quot;,</div>


<div>+                                           &amp;u-&gt;host, ntohs(port)) - p;</div><div>+        u-&gt;addrs[0].name.data = p;</div><div>+</div><div>+        return NGX_OK;</div><div>+    }</div><div>+#endif</div><div>


+</div><div>+    /* resolve all the IP address for this host */</div><div>+    host = ngx_alloc(u-&gt;host.len + 1, pool-&gt;log);</div><div>+    if (host == NULL) {</div><div>+        return NGX_ERROR;</div><div>+    }</div>


<div>+    ngx_cpystrn(host, u-&gt;host.data, u-&gt;host.len + 1);</div><div>+</div><div>+    ngx_memzero (&amp;hints, sizeof (struct addrinfo));</div><div>+</div><div>+    /* if the address is for listen, it won&#39;t enter this reslove function */</div>


<div>+    hints.ai_flags = AI_CANONNAME;</div><div>+    hints.ai_protocol = IPPROTO_TCP;</div><div>+</div><div>+    n = getaddrinfo((const char *) host,</div><div>+          NULL, &amp;hints, &amp;addrinfo);</div><div>+</div>


<div>+    ngx_free (host);</div><div>+</div><div>+    if (n != NGX_OK) {</div><div>+      u-&gt;err = &quot;error in host resolve&quot;;</div><div>+      return NGX_ERROR;</div><div>+    }</div><div> </div><div>-        for (i = 0; h-&gt;h_addr_list[i] != NULL; i++) {</div>


<div>+    i = 0;</div><div> </div><div>+    if (u-&gt;one_addr == 0) {</div><div>+        item = addrinfo;</div><div>+        for (i = 0; item != NULL; i++, item = item-&gt;ai_next) { /* void */ }</div><div>+</div><div>+    } else {</div>


<div>+        i = 1;</div><div>+    }</div><div>+</div><div>+    /* MP: ngx_shared_palloc() */</div><div>+</div><div>+    u-&gt;addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));</div><div>+    if (u-&gt;addrs == NULL) {</div>


<div>+        return NGX_ERROR;</div><div>+    }</div><div>+</div><div>+    u-&gt;naddrs = i;</div><div>+</div><div>+    for (i = 0; i &lt; u-&gt;naddrs; i++, addrinfo = addrinfo-&gt;ai_next) {</div><div>+</div><div>+        if (addrinfo-&gt;ai_family == AF_INET) {</div>


<div>             sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));</div><div>             if (sin == NULL) {</div><div>                 return NGX_ERROR;</div><div>@@ -952,55 +1035,140 @@</div><div> </div><div>             sin-&gt;sin_family = AF_INET;</div>


<div>             sin-&gt;sin_port = port;</div><div>-            sin-&gt;sin_addr.s_addr = *(in_addr_t *) (h-&gt;h_addr_list[i]);</div><div>-</div><div>+            inaddr = ((struct sockaddr_in *) addrinfo-&gt;ai_addr)-&gt;sin_addr.s_addr;</div>


<div>+            sin-&gt;sin_addr.s_addr = inaddr;</div><div>             u-&gt;addrs[i].sockaddr = (struct sockaddr *) sin;</div><div>             u-&gt;addrs[i].socklen = sizeof(struct sockaddr_in);</div><div> </div><div>


             len = NGX_INET_ADDRSTRLEN + sizeof(&quot;:65535&quot;) - 1;</div><div>+            p = ngx_pnalloc(pool, len);</div><div>+            if (p == NULL) {</div><div>+                return NGX_ERROR;</div><div>+            }</div>


<div>+</div><div>+            len = ngx_sock_ntop((struct sockaddr *) sin, p, len, sin-&gt;sin_port);</div><div>+</div><div>+            u-&gt;addrs[i].name.len = len;</div><div>+            u-&gt;addrs[i].name.data = p;</div>


<div> </div><div>+#if (NGX_HAVE_INET6)</div><div>+        } else if (addrinfo-&gt;ai_family == AF_INET6) {</div><div>+            sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));</div><div>+            if (sin6 == NULL) {</div>


<div>+                return NGX_ERROR;</div><div>+            }</div><div>+</div><div>+            sin6-&gt;sin6_family = AF_INET6;</div><div>+            sin6-&gt;sin6_port = port;</div><div>+            inaddr6 = ((struct sockaddr_in6 *) addrinfo-&gt;ai_addr)-&gt;sin6_addr;</div>


<div>+            ngx_memcpy(sin6-&gt;sin6_addr.s6_addr, inaddr6.s6_addr, 16);</div><div>+            u-&gt;addrs[i].sockaddr = (struct sockaddr *) sin6;</div><div>+            u-&gt;addrs[i].socklen = sizeof(struct sockaddr_in6);</div>


<div>+</div><div>+            len = NGX_INET6_ADDRSTRLEN + sizeof(&quot;:65535&quot;) - 1;</div><div>             p = ngx_pnalloc(pool, len);</div><div>             if (p == NULL) {</div><div>                 return NGX_ERROR;</div>


<div>             }</div><div> </div><div>-            len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);</div><div>+            len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, sin6-&gt;sin6_port);</div><div>

 </div>
<div>             u-&gt;addrs[i].name.len = len;</div><div>             u-&gt;addrs[i].name.data = p;</div><div>+#endif</div><div>+        } else {</div><div>+            u-&gt;err = &quot;unknown address family&quot;;</div>


<div>+            return NGX_ERROR;</div><div>         }</div><div>+    }</div><div> </div><div>-    } else {</div><div>+    return NGX_OK;</div><div>+}</div><div> </div><div>-        /* MP: ngx_shared_palloc() */</div><div>


+ngx_int_t</div><div>+ngx_inet_sock_addr (u_char * p, size_t len, struct sockaddr * sockaddr)</div><div>+{</div><div>+    u_char               *port, *last;</div><div>+    ngx_int_t             n;</div><div>+    struct sockaddr_in   *sin;</div>


<div> </div><div>-        u-&gt;addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));</div><div>-        if (u-&gt;addrs == NULL) {</div><div>+#if (NGX_HAVE_INET6)</div><div>+    struct sockaddr_in6  *sin6;</div><div>+    u_char               *q;</div>


<div>+#endif</div><div>+</div><div>+    if (len == 0) {</div><div>+        return NGX_ERROR;</div><div>+    }</div><div>+</div><div>+    last = p + len;</div><div>+</div><div>+    port = NULL;</div><div>+</div><div>+#if (NGX_HAVE_INET6)</div>


<div>+</div><div>+    if (*p == &#39;[&#39;) {</div><div>+</div><div>+        p++;</div><div>+</div><div>+        q = ngx_strlchr(p, last, &#39;]&#39;);</div><div>+</div><div>+        if (q == NULL) {</div><div>             return NGX_ERROR;</div>


<div>         }</div><div> </div><div>-        sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));</div><div>-        if (sin == NULL) {</div><div>+        if (q &lt; last - 2 &amp;&amp; *(q + 1) == &#39;:&#39;) {</div>

<div>
+            port = q + 2;</div><div>+        } else {</div><div>             return NGX_ERROR;</div><div>         }</div><div> </div><div>-        u-&gt;naddrs = 1;</div><div>+        sin6 = (struct sockaddr_in6 *)sockaddr;</div>


<div>+</div><div>+        sin6-&gt;sin6_family = AF_INET6;</div><div>+</div><div>+        if (ngx_inet6_addr(p, q - p, sin6-&gt;sin6_addr.s6_addr) == NGX_ERROR) {</div><div>+            return NGX_ERROR;</div><div>+        }</div>


<div>+</div><div>+        n = ngx_atoi(port, last - port);</div><div>+</div><div>+        if (n == NGX_ERROR || n &lt; 1 || n &gt; 65535) {</div><div>+            return NGX_ERROR;</div><div>+        }</div><div>+</div><div>


+        sin6-&gt;sin6_port = htons(n);</div><div>+</div><div>+    }</div><div>+    else</div><div>+#endif</div><div>+    {</div><div>+        port = ngx_strlchr(p, last, &#39;:&#39;);</div><div>+</div><div>+        if (port == NULL) {</div>


<div>+            return NGX_ERROR;</div><div>+        }</div><div>+</div><div>+        sin = (struct sockaddr_in *)sockaddr;</div><div> </div><div>         sin-&gt;sin_family = AF_INET;</div><div>-        sin-&gt;sin_port = port;</div>


<div>-        sin-&gt;sin_addr.s_addr = in_addr;</div><div> </div><div>-        u-&gt;addrs[0].sockaddr = (struct sockaddr *) sin;</div><div>-        u-&gt;addrs[0].socklen = sizeof(struct sockaddr_in);</div><div>+        sin-&gt;sin_addr.s_addr = ngx_inet_addr (p, port - p);</div>


<div> </div><div>-        p = ngx_pnalloc(pool, u-&gt;host.len + sizeof(&quot;:65535&quot;) - 1);</div><div>-        if (p == NULL) {</div><div>+        if (sin-&gt;sin_addr.s_addr == INADDR_NONE) {</div><div>             return NGX_ERROR;</div>


<div>         }</div><div> </div><div>-        u-&gt;addrs[0].name.len = ngx_sprintf(p, &quot;%V:%d&quot;,</div><div>-                                           &amp;u-&gt;host, ntohs(port)) - p;</div><div>-        u-&gt;addrs[0].name.data = p;</div>


<div>+        port++;</div><div>+</div><div>+        n = ngx_atoi(port, last - port);</div><div>+</div><div>+        if (n == NGX_ERROR || n &lt; 1 || n &gt; 65535) {</div><div>+            return NGX_ERROR;</div><div>+        }</div>


<div>+</div><div>+        sin-&gt;sin_port = htons(n);</div><div>+</div><div>     }</div><div> </div><div>     return NGX_OK;</div><div>--------------------------------------------------------ngx_inet.h-------------------------------------------</div>


<div><br></div><div><div>--- nginx-0.9.3/src/core/ngx_inet.h<span style="white-space:pre-wrap">        </span>2009-11-03 04:44:55.000000000 -0800</div><div>+++ /home/speedfirst/p4/zimbra/main/ThirdParty/nginx/nginx-0.9-zimbra/src/core/ngx_inet.h<span style="white-space:pre-wrap">        </span>2011-02-25 01:45:37.133302528 -0800</div>


<div>@@ -108,6 +108,8 @@</div><div> #endif</div><div> size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len,</div><div>     ngx_uint_t port);</div><div>+ngx_int_t ngx_inet_sock_addr (u_char * p, size_t len,</div>


<div>+    struct sockaddr * sockaddr);</div><div> size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);</div><div> ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);</div><div> ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,</div>


</div>