Author: mturk
Date: Fri Sep  6 09:55:32 2013
New Revision: 1520524

URL: http://svn.apache.org/r1520524
Log:
IPV6 support - should work with APR only for now. Still need to implement for 
non httpd connectors

Modified:
    tomcat/jk/trunk/native/common/jk_connect.c

Modified: tomcat/jk/trunk/native/common/jk_connect.c
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_connect.c?rev=1520524&r1=1520523&r2=1520524&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_connect.c (original)
+++ tomcat/jk/trunk/native/common/jk_connect.c Fri Sep  6 09:55:32 2013
@@ -339,31 +339,21 @@ in_addr_t jk_inet_addr(const char * addr
 int jk_resolve(const char *host, int port, jk_sockaddr_t *saddr,
                void *pool, int prefer_ipv6, jk_logger_t *l)
 {
-    int x;
-    struct in_addr laddr4;
-    struct sockaddr_in *rc4;
+    int family = AF_INET;
+    struct in_addr iaddr;
 
     JK_TRACE_ENTER(l);
 
     memset(saddr, 0, sizeof(jk_sockaddr_t));
+    if (*host >= '0' && *host <= '9' && strspn(host, "0123456789.") == 
strlen(host)) {
 
-    rc4 = &saddr->sa.sin;
-    rc4->sin_port   = htons((short)port);
-    rc4->sin_family = AF_INET;
-
-    /* Check if we only have digits in the string */
-    for (x = 0; host[x] != '\0'; x++) {
-        if (!jk_isdigit(host[x]) && host[x] != '.') {
-            break;
-        }
+        /* If we found only digits we use inet_addr() */
+        iaddr.s_addr = jk_inet_addr(host);
+        memcpy(&(saddr->sa.sin.sin_addr), &iaddr, sizeof(struct in_addr));
     }
-
-    /* If we found also characters we should make name to IP resolution */
-    if (host[x] != '\0') {
-
+    else {
 #ifdef HAVE_APR
         apr_sockaddr_t *remote_sa, *temp_sa;
-        char *remote_ipaddr;
 
         if (!jk_apr_pool) {
             if (apr_pool_create(&jk_apr_pool, (apr_pool_t *)pool) != 
APR_SUCCESS) {
@@ -372,66 +362,94 @@ int jk_resolve(const char *host, int por
             }
         }
         apr_pool_clear(jk_apr_pool);
-        if (apr_sockaddr_info_get
-            (&remote_sa, host, APR_UNSPEC, (apr_port_t) port, 0, jk_apr_pool)
-            != APR_SUCCESS) {
+        if (apr_sockaddr_info_get(&remote_sa, host, APR_UNSPEC, 
(apr_port_t)port,
+                                  0, jk_apr_pool) != APR_SUCCESS) {
             JK_TRACE_EXIT(l);
             return JK_FALSE;
         }
 
-        /* Since we are only handling AF_INET (IPV4) address (in_addr_t) */
-        /* make sure we find one of those.                               */
-        temp_sa = remote_sa;
-        while ((NULL != temp_sa) && (AF_INET != temp_sa->family))
-            temp_sa = temp_sa->next;
-
-        /* if temp_sa is set, we have a valid address otherwise, just return */
-        if (NULL != temp_sa) {
-            remote_sa = temp_sa;
+        /* Check if we have multiple address matches
+         */
+        if (remote_sa->next) {
+            /* Since we are only handling AF_INET (IPV4) address (in_addr_t) */
+            /* make sure we find one of those.                               */
+            temp_sa = remote_sa;
+#if APR_HAVE_IPV6
+            if (prefer_ipv6) {
+                while ((NULL != temp_sa) && (AF_INET6 != temp_sa->family))
+                    temp_sa = temp_sa->next;
+            }
+#endif
+            if (NULL != temp_sa) {
+                remote_sa = temp_sa;
+            }
+            else {
+                while ((NULL != temp_sa) && (AF_INET != temp_sa->family))
+                    temp_sa = temp_sa->next;
+            }
+            /* if temp_sa is set, we have a valid address otherwise, just 
return */
+            if (NULL != temp_sa) {
+                remote_sa = temp_sa;
+            }
+            else {
+                JK_TRACE_EXIT(l);
+                return JK_FALSE;
+            }
         }
+        if (remote_sa->family == AF_INET) {
+            saddr->sa.sin = remote_sa->sa.sin;
+            family = AF_INET;
+        }
+#if APR_HAVE_IPV6
         else {
-            JK_TRACE_EXIT(l);
-            return JK_FALSE;
+            saddr->sa.sin6 = remote_sa->sa.sin6;
+            family = AF_INET6;
         }
-
-        apr_sockaddr_ip_get(&remote_ipaddr, remote_sa);
-
-        laddr4.s_addr = jk_inet_addr(remote_ipaddr);
-
+#endif
 #else /* HAVE_APR */
+        /* Without APR go the classic way.
+         */
+
+        struct hostent *hoste;
+        /* TODO:
+         * Check for numeric IPV6 addresses
+         */
 
         /* XXX : WARNING : We should really use gethostbyname_r in 
multi-threaded env */
         /* Fortunatly when APR is available, ie under Apache 2.0, we use it */
 #if defined(NETWARE) && !defined(__NOVELL_LIBC__)
-        struct hostent *hoste = gethostbyname((char*)host);
+        hoste = gethostbyname((char*)host);
 #else
-        struct hostent *hoste = gethostbyname(host);
+        hoste = gethostbyname(host);
 #endif
         if (!hoste) {
             JK_TRACE_EXIT(l);
             return JK_FALSE;
         }
-
-        laddr4 = *((struct in_addr *)hoste->h_addr_list[0]);
+        iaddr = *((struct in_addr *)hoste->h_addr_list[0]);
+        memcpy(&(saddr->sa.sin.sin_addr), &iaddr, sizeof(struct in_addr));
 
 #endif /* HAVE_APR */
     }
+
+    if (family == AF_INET) {
+        saddr->ipaddr_ptr = &(saddr->sa.sin.sin_addr);
+        saddr->ipaddr_len = (int)sizeof(struct in_addr);
+        saddr->salen      = (int)sizeof(struct sockaddr_in);
+    }
+#if APR_HAVE_IPV6
     else {
-        /* If we found only digits we use inet_addr() */
-        laddr4.s_addr = jk_inet_addr(host);
+        saddr->ipaddr_ptr = &(saddr->sa.sin6.sin6_addr);
+        saddr->ipaddr_len = (int)sizeof(struct in6_addr);
+        saddr->salen      = (int)sizeof(struct sockaddr_in6);
     }
-    /* TODO:
-     * This will depend on IPV4/IPV6 resolving
-     * and prefer_ipv6
-     */
-    saddr->ipaddr_ptr = &rc4->sin_addr;
-    saddr->ipaddr_len = (int)sizeof(struct in_addr);
-    saddr->salen      = (int)sizeof(struct sockaddr_in);
-    saddr->port       = port;
-    saddr->host       = host;
-    saddr->family     = rc4->sin_family;
-
-    memcpy(saddr->ipaddr_ptr, &laddr4, saddr->ipaddr_len);
+#endif
+    saddr->sa.sin.sin_family = family;
+    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
+    saddr->sa.sin.sin_port = htons(port);
+    saddr->port   = port;
+    saddr->host   = host;
+    saddr->family = family;
 
     JK_TRACE_EXIT(l);
     return JK_TRUE;



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to