Dear developers.

I made the mod_jk patch to support ipv6 between mod_jk and Tomcat.
The detection of getaddrinfo() and implementation of jk_resolve()
referred to APR.

This patch was tested in the following environments (Do not compile in
other OS's).
1.RHEL4/5 with Apache 2.x
 Link-Local address cannot be used.

2.Windows XP Pro with IIS 5.1
 isapi_redirector.dll was constructed by VS 2005 Express + PSDK.
 when constructing the isapi_redirector.dll,  '/D "HAVE_IPV6"' and
'/D "HAVE_GETADDRINFO"' were specified.

My best regards.
Index: mod_jk/native/iis/jk_isapi_plugin.c
===================================================================
--- mod_jk/native/iis/jk_isapi_plugin.c (revision 598096)
+++ mod_jk/native/iis/jk_isapi_plugin.c (working copy)
@@ -27,10 +27,6 @@
 // This define is needed to include wincrypt,h, needed to get client 
certificates
 #define _WIN32_WINNT 0x0400
 
-#include <httpext.h>
-#include <httpfilt.h>
-#include <wininet.h>
-
 #include "jk_global.h"
 #include "jk_url.h"
 #include "jk_util.h"
@@ -43,6 +39,10 @@
 #include "jk_ajp13.h"
 #include "pcre.h"
 
+#include <httpext.h>
+#include <httpfilt.h>
+#include <wininet.h>
+
 #ifndef POSIX_MALLOC_THRESHOLD
 #define POSIX_MALLOC_THRESHOLD (10)
 #endif
Index: mod_jk/native/configure.in
===================================================================
--- mod_jk/native/configure.in  (revision 598096)
+++ mod_jk/native/configure.in  (working copy)
@@ -263,6 +263,44 @@
 AC_SUBST(uint64_t_hex_fmt) 
 AC_SUBST(pid_t_fmt) 
 
+dnl check for getaddrinfo.
+AC_DEFUN([JK_CHECK_WORKING_GETADDRINFO],[
+  AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
+  AC_TRY_RUN( [
+#include <netdb.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int main(void) {
+    struct addrinfo hints, *ai;
+    int error;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    error = getaddrinfo("127.0.0.1", NULL, &hints, &ai);
+    if (error) {
+        exit(1);
+    }
+    if (ai->ai_addr->sa_family != AF_INET) {
+        exit(1);
+    }
+    exit(0);
+}
+],[
+  ac_cv_working_getaddrinfo="yes"
+],[
+  ac_cv_working_getaddrinfo="no"
+],[
+  ac_cv_working_getaddrinfo="yes"
+])])
+if test "$ac_cv_working_getaddrinfo" = "yes"; then
+  AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if getaddrinfo exists and works well 
enough for APR])
+fi
+])
+JK_CHECK_WORKING_GETADDRINFO
+
 dnl check for snprintf and vsnprintf.
 AC_CHECK_FUNC(snprintf, AC_DEFINE(HAVE_SNPRINTF,1,[Have snprintf()]))
 AC_CHECK_FUNC(vsnprintf, AC_DEFINE(HAVE_VSNPRINTF,1,[Have vsnprintf()]))
Index: mod_jk/native/common/jk_ajp_common.c
===================================================================
--- mod_jk/native/common/jk_ajp_common.c        (revision 598096)
+++ mod_jk/native/common/jk_ajp_common.c        (working copy)
@@ -852,7 +852,7 @@
 
 int ajp_connect_to_endpoint(ajp_endpoint_t * ae, jk_logger_t *l)
 {
-    char buf[32];
+    char buf[JK_DUMP_BUF];
     int rc = JK_TRUE;
 
     JK_TRACE_ENTER(l);
Index: mod_jk/native/common/jk_ajp_common.h
===================================================================
--- mod_jk/native/common/jk_ajp_common.h        (revision 598096)
+++ mod_jk/native/common/jk_ajp_common.h        (working copy)
@@ -232,7 +232,7 @@
 
 struct ajp_worker
 {
-    struct sockaddr_in worker_inet_addr;    /* Contains host and port */
+    struct jk_sockaddr_in worker_inet_addr;    /* Contains host and port */
     unsigned connect_retry_attempts;
     const char *name;
     const char *host;
Index: mod_jk/native/common/jk_connect.c
===================================================================
--- mod_jk/native/common/jk_connect.c   (revision 598096)
+++ mod_jk/native/common/jk_connect.c   (working copy)
@@ -35,7 +35,6 @@
 #include "apr_errno.h"
 #include "apr_general.h"
 #include "apr_pools.h"
-static apr_pool_t *jk_apr_pool = NULL;
 #endif
 
 #ifdef HAVE_SYS_FILIO_H
@@ -117,15 +116,15 @@
 
 #if defined (WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
 /* WIN32 implementation */
-static int nb_connect(jk_sock_t sock, struct sockaddr *addr, int timeout)
+static int nb_connect(jk_sock_t sock, struct jk_sockaddr_in *addr, int timeout)
 {
     int rc;
     if (timeout <= 0)
-        return connect(sock, addr, sizeof(struct sockaddr_in));
+        return connect(sock, (const struct sockaddr *)&addr->sa.sin, 
addr->salen);
 
     if ((rc = sononblock(sock)))
         return -1;
-    if (connect(sock, addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
+    if (connect(sock, (const struct sockaddr *)&addr->sa.sin, addr->salen) == 
SOCKET_ERROR) {
         struct timeval tv;
         fd_set wfdset, efdset;
 
@@ -167,7 +166,7 @@
 
 #elif !defined(NETWARE)
 /* POSIX implementation */
-static int nb_connect(jk_sock_t sock, struct sockaddr *addr, int timeout)
+static int nb_connect(jk_sock_t sock, struct jk_sockaddr_in *addr, int timeout)
 {
     int rc = 0;
 
@@ -176,7 +175,7 @@
             return -1;
     }
     do {
-        rc = connect(sock, addr, sizeof(struct sockaddr_in));
+         rc = connect(sock, (const struct sockaddr *)&addr->sa.sin, 
addr->salen);
     } while (rc == -1 && errno == EINTR);
 
     if ((rc == -1) && (errno == EINPROGRESS || errno == EALREADY)
@@ -216,9 +215,9 @@
 }
 #else
 /* NETWARE implementation - blocking for now */
-static int nb_connect(jk_sock_t sock, struct sockaddr *addr, int timeout)
+static int nb_connect(jk_sock_t sock, struct jk_sockaddr_in *addr, int timeout)
 {
-    return connect(sock, addr, sizeof(struct sockaddr_in));
+    return connect(sock, (const struct sockaddr *)&addr->sa.sin, addr->salen);
 }
 #endif
 
@@ -245,16 +244,35 @@
 
 /** resolve the host IP */
 
-int jk_resolve(const char *host, int port, struct sockaddr_in *rc)
+int jk_resolve(const char *host, int port, struct jk_sockaddr_in *rc)
 {
-    int x;
-    struct in_addr laddr;
+    int ret = JK_FALSE;
+#ifdef HAVE_GETADDRINFO
+    struct addrinfo hints, *res;
 
-    memset(rc, 0, sizeof(struct sockaddr_in));
+    memset(rc, 0, sizeof(struct jk_sockaddr_in));
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_family = AF_UNSPEC;
 
-    rc->sin_port = htons((short)port);
-    rc->sin_family = AF_INET;
+    if (getaddrinfo(host, NULL, &hints, &res) == 0) {
+        rc->family = res->ai_family;
+        rc->salen = res->ai_addrlen;
+        memcpy(&(rc->sa), res->ai_addr, res->ai_addrlen);
+        rc->sa.sin.sin_port = htons((short)port);
 
+        freeaddrinfo(res);
+        ret = JK_TRUE;
+    }
+#else  /* HAVE_GETADDR_INFO */
+    int x;
+    struct in_addr laddr;
+
+    memset(rc, 0, sizeof(struct jk_sockaddr_in));
+    rc->family = rc->sa.sin.sin_family = AF_INET;
+    rc->salen = sizeof(struct sockaddr_in);
+    rc->sa.sin.sin_port = htons((short)port);
+ 
     /* Check if we only have digits in the string */
     for (x = 0; host[x] != '\0'; x++) {
         if (!isdigit((int)(host[x])) && host[x] != '.') {
@@ -265,67 +283,34 @@
     /* If we found also characters we shoud make name to IP resolution */
     if (host[x] != '\0') {
 
-#ifdef HAVE_APR
-        apr_sockaddr_t *remote_sa, *temp_sa;
-        char *remote_ipaddr;
-
-        if (!jk_apr_pool) {
-            if (apr_pool_create(&jk_apr_pool, NULL) != APR_SUCCESS)
-                return JK_FALSE;
-        }
-        if (apr_sockaddr_info_get
-            (&remote_sa, host, APR_UNSPEC, (apr_port_t) port, 0, jk_apr_pool)
-            != APR_SUCCESS)
-            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;
-        else
-            return JK_FALSE;
-
-        apr_sockaddr_ip_get(&remote_ipaddr, remote_sa);
-
-        laddr.s_addr = jk_inet_addr(remote_ipaddr);
-
-#else /* HAVE_APR */
-
-        /* 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);
 #else
         struct hostent *hoste = gethostbyname(host);
 #endif
-        if (!hoste) {
-            return JK_FALSE;
+        if (hoste) {
+            laddr = *((struct in_addr *)hoste->h_addr_list[0]);
+            ret = JK_TRUE;
         }
-
-        laddr = *((struct in_addr *)hoste->h_addr_list[0]);
-
-#endif /* HAVE_APR */
     }
     else {
         /* If we found only digits we use inet_addr() */
         laddr.s_addr = jk_inet_addr(host);
+        ret = JK_TRUE;
     }
-    memcpy(&(rc->sin_addr), &laddr, sizeof(laddr));
+    if ( ret == JK_TRUE )
+        memcpy(&(rc->sa.sin.sin_addr), &laddr, sizeof(laddr));
 
-    return JK_TRUE;
+#endif /* HAVE_GETADDR_INFO */
+    return ret;
 }
 
 /** connect to Tomcat */
 
-jk_sock_t jk_open_socket(struct sockaddr_in *addr, int keepalive,
+jk_sock_t jk_open_socket(struct jk_sockaddr_in *addr, int keepalive,
                          int timeout, int sock_buf, jk_logger_t *l)
 {
-    char buf[32];
+    char buf[JK_DUMP_BUF];
     jk_sock_t sock;
     int set = 1;
     int ret = 0;
@@ -335,7 +320,7 @@
 
     JK_TRACE_ENTER(l);
 
-    sock = socket(AF_INET, SOCK_STREAM, 0);
+    sock = socket(addr->family, SOCK_STREAM, 0);
     if (!IS_VALID_SOCKET(sock)) {
         JK_GET_SOCKET_ERRNO();
         jk_log(l, JK_LOG_ERROR,
@@ -456,12 +441,13 @@
                 "trying to connect socket %d to %s", sock,
                 jk_dump_hinfo(addr, buf));
 
+
 /* Need more infos for BSD 4.4 and Unix 98 defines, for now only
 iSeries when Unix98 is required at compil time */
 #if (_XOPEN_SOURCE >= 520) && defined(AS400)
-    ((struct sockaddr *)addr)->sa_len = sizeof(struct sockaddr_in);
+    ((struct sockaddr)(addr->sa.sin)).sa_len = addr->salen;
 #endif
-    ret = nb_connect(sock, (struct sockaddr *)addr, timeout);
+    ret = nb_connect(sock, addr, timeout);
 #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
     if (ret == SOCKET_ERROR) {
         errno = WSAGetLastError() - WSABASEERR;
@@ -641,14 +627,24 @@
  * dump a sockaddr_in in A.B.C.D:P in ASCII buffer
  *
  */
-char *jk_dump_hinfo(struct sockaddr_in *saddr, char *buf)
+char *jk_dump_hinfo(struct jk_sockaddr_in *saddr, char *buf)
 {
-    unsigned long laddr = (unsigned long)htonl(saddr->sin_addr.s_addr);
-    unsigned short lport = (unsigned short)htons(saddr->sin_port);
+    unsigned short lport = (unsigned short)htons(saddr->sa.sin.sin_port);
+    if (saddr->family == AF_INET) {
+        unsigned long laddr = (unsigned 
long)htonl(saddr->sa.sin.sin_addr.s_addr);
 
-    sprintf(buf, "%d.%d.%d.%d:%d",
-            (int)(laddr >> 24), (int)((laddr >> 16) & 0xff),
-            (int)((laddr >> 8) & 0xff), (int)(laddr & 0xff), (int)lport);
+        sprintf(buf, "%d.%d.%d.%d:%d",
+                (int)(laddr >> 24), (int)((laddr >> 16) & 0xff),
+                (int)((laddr >> 8) & 0xff), (int)(laddr & 0xff), (int)lport);
+#ifdef HAVE_IPV6
+    } else {
+        unsigned short *laddr = (unsigned short *)&(saddr->sa.sin6.sin6_addr);
+               sprintf(buf, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d",
+                htons(*laddr), htons(*(laddr+1)), htons(*(laddr+2)),
+                htons(*(laddr+3)), htons(*(laddr+4)), htons(*(laddr+5)),
+                htons(*(laddr+6)), htons(*(laddr+7)), (int)lport);
+#endif /* HAVE_IPV6 */
+    }
 
     return buf;
 }
Index: mod_jk/native/common/jk_connect.h
===================================================================
--- mod_jk/native/common/jk_connect.h   (revision 598096)
+++ mod_jk/native/common/jk_connect.h   (working copy)
@@ -39,9 +39,9 @@
 #define JK_SOCKET_EOF      (-2)
 #define JK_SOCKET_ERROR    (-3)
 
-int jk_resolve(const char *host, int port, struct sockaddr_in *rc);
+int jk_resolve(const char *host, int port, struct jk_sockaddr_in *rc);
 
-jk_sock_t jk_open_socket(struct sockaddr_in *addr, int keepalive,
+jk_sock_t jk_open_socket(struct jk_sockaddr_in *addr, int keepalive,
                          int timeout, int sock_buf, jk_logger_t *l);
 
 int jk_close_socket(jk_sock_t s);
@@ -52,11 +52,10 @@
 
 int jk_tcp_socket_recvfull(jk_sock_t sd, unsigned char *b, int len);
 
-char *jk_dump_hinfo(struct sockaddr_in *saddr, char *buf);
+char *jk_dump_hinfo(struct jk_sockaddr_in *saddr, char *buf);
 
 int jk_is_socket_connected(jk_sock_t sd);
 
-
 /***
  * i5/OS V5R4 need ASCII<->EBCDIC translation for inet_addr() call
  */
Index: mod_jk/native/common/jk_ajp12_worker.c
===================================================================
--- mod_jk/native/common/jk_ajp12_worker.c      (revision 598096)
+++ mod_jk/native/common/jk_ajp12_worker.c      (working copy)
@@ -40,7 +40,7 @@
 
 struct ajp12_worker
 {
-    struct sockaddr_in worker_inet_addr;
+    struct jk_sockaddr_in worker_inet_addr;
     unsigned connect_retry_attempts;
     char *name;
     jk_worker_t worker;
Index: mod_jk/native/common/jk_status.c
===================================================================
--- mod_jk/native/common/jk_status.c    (revision 598096)
+++ mod_jk/native/common/jk_status.c    (working copy)
@@ -1343,7 +1343,7 @@
                               lb_worker_t *lb,
                               jk_logger_t *l)
 {
-    char buf[32];
+    char buf[JK_DUMP_BUF];
     char buf_rd[32];
     char buf_wr[32];
     int cmd;
@@ -1754,7 +1754,7 @@
                                ajp_worker_t *aw,
                                jk_logger_t *l)
 {
-    char buf[32];
+    char buf[JK_DUMP_BUF];
     int cmd;
     int mime;
     int single = 0;
Index: mod_jk/native/common/jk_global.h
===================================================================
--- mod_jk/native/common/jk_global.h    (revision 598096)
+++ mod_jk/native/common/jk_global.h    (working copy)
@@ -371,6 +371,23 @@
 #define strcasecmp(a,b) apr_strnatcasecmp(a,b)
 #endif
 
+#ifdef HAVE_APR
+#define HAVE_IPV6 APR_HAVE_IPV6
+#endif
+
+#define JK_DUMP_BUF 48
+
+struct jk_sockaddr_in {
+    unsigned short int family;
+    int salen;
+    union {
+        struct sockaddr_in sin;
+#ifdef HAVE_IPV6
+        struct sockaddr_in6 sin6;
+#endif /* HAVE_IPV6 */
+    } sa;
+};
+
 #ifdef __cplusplus
 }
 #endif                          /* __cplusplus */
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to