Author: rjung
Date: Sun Feb  8 14:28:10 2015
New Revision: 1658173

URL: http://svn.apache.org/r1658173
Log:
BZ 57536: AJP: Allow to configure connection
source address. This should only be used on
multi-homed hosts.
The feature is experimental. 

Modified:
    tomcat/jk/trunk/native/common/jk_ajp12_worker.c
    tomcat/jk/trunk/native/common/jk_ajp_common.c
    tomcat/jk/trunk/native/common/jk_ajp_common.h
    tomcat/jk/trunk/native/common/jk_connect.c
    tomcat/jk/trunk/native/common/jk_connect.h
    tomcat/jk/trunk/native/common/jk_status.c
    tomcat/jk/trunk/native/common/jk_util.c
    tomcat/jk/trunk/native/common/jk_util.h
    tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
    tomcat/jk/trunk/xdocs/reference/workers.xml

Modified: tomcat/jk/trunk/native/common/jk_ajp12_worker.c
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp12_worker.c?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_ajp12_worker.c (original)
+++ tomcat/jk/trunk/native/common/jk_ajp12_worker.c Sun Feb  8 14:28:10 2015
@@ -41,6 +41,7 @@
 struct ajp12_worker
 {
     jk_sockaddr_t worker_inet_addr;
+    jk_sockaddr_t worker_source_inet_addr;
     unsigned connect_retry_attempts;
     char *name;
     jk_worker_t worker;
@@ -127,6 +128,9 @@ static int JK_METHOD service(jk_endpoint
          attempt++) {
         p->sd =
             jk_open_socket(&p->worker->worker_inet_addr,
+                           p->worker->worker_source_inet_addr.ipaddr_ptr != 
NULL ?
+                               &p->worker->worker_source_inet_addr :
+                               NULL,
                            JK_FALSE, 0, 0, 0, l);
 
         jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::service, sd = %d",
@@ -187,19 +191,34 @@ static int JK_METHOD validate(jk_worker_
                                         p->name,
                                         AJP_DEF_HOST);
 
+        const char *source = jk_get_worker_host(props,
+                                                p->name,
+                                                "");
+
         jk_log(l, JK_LOG_DEBUG,
-               "In jk_worker_t::validate for worker %s contact is %s:%d",
+               "In jk_worker_t::validate for worker %s target is %s:%d",
                p->name, host, port);
 
         if (host) {
-            if (jk_resolve(host, port, &p->worker_inet_addr, we->pool, 
JK_FALSE, l)) {
-                return JK_TRUE;
+            if (!jk_resolve(host, port, &p->worker_inet_addr, we->pool, 
JK_FALSE, l)) {
+                jk_log(l, JK_LOG_ERROR,
+                       "In jk_worker_t::validate, host '%s:%d' resolve failed",
+                       host, port);
+                return JK_FALSE;
             }
+        } else {
             jk_log(l, JK_LOG_ERROR,
-                   "In jk_worker_t::validate, resolve failed");
+                   "In jk_worker_t::validate, Error no host name given");
+            return JK_FALSE;
+        }
+        if (source && *source) {
+            if (!jk_resolve(source, 0, &p->worker_source_inet_addr, we->pool, 
JK_FALSE, l)) {
+                p->worker_source_inet_addr.ipaddr_ptr = NULL;
+                jk_log(l, JK_LOG_WARNING,
+                       "In jk_worker_t::validate, source addr '%s' resolve 
failed - ignored",
+                       source);
+            }
         }
-        jk_log(l, JK_LOG_ERROR, "In jk_worker_t::validate, Error %s %d",
-               host, port);
     }
     else {
         jk_log(l, JK_LOG_ERROR,

Modified: tomcat/jk/trunk/native/common/jk_ajp_common.c
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp_common.c?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_ajp_common.c (original)
+++ tomcat/jk/trunk/native/common/jk_ajp_common.c Sun Feb  8 14:28:10 2015
@@ -1040,6 +1040,9 @@ int ajp_connect_to_endpoint(ajp_endpoint
 
     ae->last_errno = 0;
     ae->sd = jk_open_socket(&ae->worker->worker_inet_addr,
+                            ae->worker->worker_source_inet_addr.ipaddr_ptr != 
NULL ?
+                                &ae->worker->worker_source_inet_addr :
+                                NULL,
                             ae->worker->keepalive,
                             ae->worker->socket_timeout,
                             ae->worker->socket_connect_timeout,
@@ -2830,12 +2833,18 @@ int ajp_validate(jk_worker_t *pThis,
         }
         strncpy(p->host, tmp, JK_SHM_STR_SIZ);
         p->prefer_ipv6 = jk_get_worker_prefer_ipv6(props, p->name, JK_FALSE);
+        tmp = jk_get_worker_source(props, p->name, "");
+        if (jk_check_attribute_length("source address", tmp, l) == JK_FALSE) {
+            JK_TRACE_EXIT(l);
+            return JK_FALSE;
+        }
+        strncpy(p->source, tmp, JK_SHM_STR_SIZ);
         if (p->s->h.sequence == 0) {
             /* Initial setup.
              */
             if (JK_IS_DEBUG_LEVEL(l))
                 jk_log(l, JK_LOG_DEBUG,
-                       "worker %s contact is '%s:%d'",
+                       "worker %s target is '%s:%d'",
                        p->name, p->host, p->port);
             if (p->port > 0) {
                 if (!jk_resolve(p->host, p->port, &p->worker_inet_addr,
@@ -2850,6 +2859,15 @@ int ajp_validate(jk_worker_t *pThis,
                                p->name);
                 }
             }
+            if (p->source && *p->source) {
+                if (!jk_resolve(p->source, 0, &p->worker_source_inet_addr,
+                                we->pool, p->prefer_ipv6, l)) {
+                    p->worker_source_inet_addr.ipaddr_ptr = NULL;
+                    jk_log(l, JK_LOG_WARNING,
+                           "worker %s can't resolve source address '%s'",
+                           p->name, p->source);
+                }
+            }
             p->addr_sequence    = 0;
             p->s->addr_sequence = 0;
             p->s->last_maintain_time = time(NULL);

Modified: tomcat/jk/trunk/native/common/jk_ajp_common.h
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp_common.h?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_ajp_common.h (original)
+++ tomcat/jk/trunk/native/common/jk_ajp_common.h Sun Feb  8 14:28:10 2015
@@ -299,9 +299,11 @@ struct ajp_worker
     JK_CRIT_SEC cs;
 
     jk_sockaddr_t worker_inet_addr;    /* Contains host and port */
+    jk_sockaddr_t worker_source_inet_addr; /* Contains source ip */
     unsigned connect_retry_attempts;
     char host[JK_SHM_STR_SIZ];
     int port;
+    char source[JK_SHM_STR_SIZ];
     int addr_sequence;  /* Whether the address is resolved */
     int maintain_time;
     int prefer_ipv6;

Modified: tomcat/jk/trunk/native/common/jk_connect.c
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_connect.c?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_connect.c (original)
+++ tomcat/jk/trunk/native/common/jk_connect.c Sun Feb  8 14:28:10 2015
@@ -163,6 +163,7 @@ static int sononblock(jk_sock_t sd)
 /** Non-blocking socket connect
  * @param sd       socket to connect
  * @param addr     address to connect to
+ * @param source   optional source address
  * @param timeout  connect timeout in seconds
  *                 (<=0: no timeout=blocking)
  * @param l        logger
@@ -171,12 +172,22 @@ static int sononblock(jk_sock_t sd)
  *                               during blocking connect
  *                 0: success
  */
-static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, int timeout, 
jk_logger_t *l)
+static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, jk_sockaddr_t *source,
+                      int timeout, jk_logger_t *l)
 {
     int rc;
+    char buf[64];
 
     JK_TRACE_ENTER(l);
 
+    if (source != NULL) {
+        if (bind(sd, (const struct sockaddr *)&source->sa.sin, source->salen)) 
{
+            JK_GET_SOCKET_ERRNO();
+            jk_log(l, JK_LOG_ERROR,
+                   "error during source bind on socket %d [%s] (errno=%d)",
+                   sd, jk_dump_hinfo(source, buf, sizeof(buf)), errno);
+        }
+    }
     if (timeout <= 0) {
         rc = connect(sd, (const struct sockaddr *)&addr->sa.sin, addr->salen);
         JK_TRACE_EXIT(l);
@@ -237,18 +248,29 @@ static int nb_connect(jk_sock_t sd, jk_s
 /** Non-blocking socket connect
  * @param sd       socket to connect
  * @param addr     address to connect to
+ * @param source   optional source address
  * @param timeout  connect timeout in seconds
  *                 (<=0: no timeout=blocking)
  * @param l        logger
  * @return         -1: some kind of error occured
  *                 0: success
  */
-static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, int timeout, 
jk_logger_t *l)
+static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, jk_sockaddr_t *source,
+                      int timeout, jk_logger_t *l)
 {
     int rc = 0;
+    char buf[64];
 
     JK_TRACE_ENTER(l);
 
+    if (source != NULL) {
+        if (bind(sd, (const struct sockaddr *)&source->sa.sin, source->salen)) 
{
+            JK_GET_SOCKET_ERRNO();
+            jk_log(l, JK_LOG_ERROR,
+                   "error during source bind on socket %d [%s] (errno=%d)",
+                   sd, jk_dump_hinfo(source, buf, sizeof(buf)), errno);
+        }
+    }
     if (timeout > 0) {
         if (sononblock(sd)) {
             JK_TRACE_EXIT(l);
@@ -301,17 +323,28 @@ static int nb_connect(jk_sock_t sd, jk_s
 /** Non-blocking socket connect
  * @param sd       socket to connect
  * @param addr     address to connect to
+ * @param source   optional source address
  * @param timeout  connect timeout in seconds (ignored!)
  * @param l        logger
  * @return         -1: some kind of error occured
  *                 0: success
  */
-static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, int timeout, 
jk_logger_t *l)
+static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, jk_sockaddr_t *source,
+                      int timeout, jk_logger_t *l)
 {
     int rc;
+    char buf[64];
 
     JK_TRACE_ENTER(l);
 
+    if (source != NULL) {
+        if (bind(sd, (const struct sockaddr *)&source->sa.sin, source->salen)) 
{
+            JK_GET_SOCKET_ERRNO();
+            jk_log(l, JK_LOG_ERROR,
+                   "error during source bind on socket %d [%s] (errno=%d)",
+                   sd, jk_dump_hinfo(source, buf, sizeof(buf)), errno);
+        }
+    }
     rc = connect(sd, (const struct sockaddr *)&addr->sa.sin, addr->salen);
     JK_TRACE_EXIT(l);
     return rc;
@@ -580,7 +613,8 @@ int jk_resolve(const char *host, int por
  *                  created socket: success
  * @remark          Cares about errno
  */
-jk_sock_t jk_open_socket(jk_sockaddr_t *addr, int keepalive,
+jk_sock_t jk_open_socket(jk_sockaddr_t *addr, jk_sockaddr_t *source,
+                         int keepalive,
                          int timeout, int connect_timeout,
                          int sock_buf, jk_logger_t *l)
 {
@@ -767,11 +801,11 @@ jk_sock_t jk_open_socket(jk_sockaddr_t *
                 jk_dump_hinfo(addr, buf, sizeof(buf)));
 
 /* Need more infos for BSD 4.4 and Unix 98 defines, for now only
-iSeries when Unix98 is required at compil time */
+iSeries when Unix98 is required at compile time */
 #if (_XOPEN_SOURCE >= 520) && defined(AS400)
     ((struct sockaddr *)addr)->sa.sin.sa_len = sizeof(struct sockaddr_in);
 #endif
-    ret = nb_connect(sd, addr, connect_timeout, l);
+    ret = nb_connect(sd, addr, source, connect_timeout, l);
 #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__))
     if (JK_IS_SOCKET_ERROR(ret)) {
         JK_GET_SOCKET_ERRNO();

Modified: tomcat/jk/trunk/native/common/jk_connect.h
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_connect.h?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_connect.h (original)
+++ tomcat/jk/trunk/native/common/jk_connect.h Sun Feb  8 14:28:10 2015
@@ -43,7 +43,8 @@ void jk_clone_sockaddr(jk_sockaddr_t *ou
 int jk_resolve(const char *host, int port, jk_sockaddr_t *rc, void *pool,
                int prefer_ipv6, jk_logger_t *l);
 
-jk_sock_t jk_open_socket(jk_sockaddr_t *addr, int keepalive,
+jk_sock_t jk_open_socket(jk_sockaddr_t *addr, jk_sockaddr_t *source,
+                         int keepalive,
                          int timeout, int connect_timeout,
                          int sock_buf, jk_logger_t *l);
 

Modified: tomcat/jk/trunk/native/common/jk_status.c
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_status.c?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_status.c (original)
+++ tomcat/jk/trunk/native/common/jk_status.c Sun Feb  8 14:28:10 2015
@@ -155,6 +155,7 @@
 #define JK_STATUS_ARG_AJP_TEXT_HOST_STR    "Hostname"
 #define JK_STATUS_ARG_AJP_TEXT_PORT        "Port"
 #define JK_STATUS_ARG_AJP_TEXT_ADDR_STR    "Address:Port"
+#define JK_STATUS_ARG_AJP_TEXT_SOURCE_STR  "Source"
 
 #define JK_STATUS_ARG_AJP_HEAD_CACHE_TO    "Connection<br/>Pool Timeout"
 #define JK_STATUS_ARG_AJP_HEAD_PING_TO     "Ping<br/>Timeout"
@@ -170,6 +171,7 @@
 #define JK_STATUS_ARG_AJP_HEAD_HOST_STR    "Hostname"
 #define JK_STATUS_ARG_AJP_HEAD_PORT        "Port"
 #define JK_STATUS_ARG_AJP_HEAD_ADDR_STR    "Address:Port"
+#define JK_STATUS_ARG_AJP_HEAD_SOURCE_STR  "Source"
 
 #define JK_STATUS_CMD_UNKNOWN              (0)
 #define JK_STATUS_CMD_LIST                 (1)
@@ -274,6 +276,7 @@
                                            "<th>Type</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_HOST_STR "</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_ADDR_STR "</th>" \
+                                           "<th>" 
JK_STATUS_ARG_AJP_HEAD_SOURCE_STR "</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_CACHE_TO "</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_CONNECT_TO "</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_PREPOST_TO "</th>" \
@@ -287,6 +290,7 @@
                                            "<td>%s</td>" \
                                            "<td>%s</td>" \
                                            "<td>%s</td>" \
+                                           "<td>%s</td>" \
                                            "<td>%d</td>" \
                                            "<td>%d</td>" \
                                            "<td>%d</td>" \
@@ -379,6 +383,7 @@
                                            "<th>Name</th><th>Type</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_HOST_STR "</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_ADDR_STR "</th>" \
+                                           "<th>" 
JK_STATUS_ARG_AJP_HEAD_SOURCE_STR "</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_CACHE_TO "</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_CONNECT_TO "</th>" \
                                            "<th>" 
JK_STATUS_ARG_AJP_HEAD_PREPOST_TO "</th>" \
@@ -393,6 +398,7 @@
                                            "<td>%s</td>" \
                                            "<td>%s</td>" \
                                            "<td>%s</td>" \
+                                           "<td>%s</td>" \
                                            "<td>%d</td>" \
                                            "<td>%d</td>" \
                                            "<td>%d</td>" \
@@ -1799,6 +1805,7 @@ static void display_worker_ajp_conf_deta
                   status_worker_type(type),
                   aw->host,
                   dump_ajp_addr(aw, buf, sizeof(buf)),
+                  aw->source && *aw->source ? aw->source : "undefined",
                   aw->cache_timeout,
                   aw->connect_timeout,
                   aw->prepost_timeout,
@@ -1812,6 +1819,7 @@ static void display_worker_ajp_conf_deta
                   status_worker_type(type),
                   aw->host,
                   dump_ajp_addr(aw, buf, sizeof(buf)),
+                  aw->source && *aw->source ? aw->source : "undefined",
                   aw->cache_timeout,
                   aw->connect_timeout,
                   aw->prepost_timeout,
@@ -1960,6 +1968,7 @@ static void display_worker_ajp_details(j
         jk_print_xml_att_string(s, l, off+2, "host", aw->host);
         jk_print_xml_att_int(s, l, off+2, "port", aw->port);
         jk_print_xml_att_string(s, l, off+2, "address", dump_ajp_addr(aw, buf, 
sizeof(buf)));
+        jk_print_xml_att_string(s, l, off+2, "source", aw->source && 
*aw->source ? aw->source : "undefined");
         jk_print_xml_att_int(s, l, off+2, "connection_pool_timeout", 
aw->cache_timeout);
         jk_print_xml_att_int(s, l, off+2, "ping_timeout", aw->ping_timeout);
         jk_print_xml_att_int(s, l, off+2, "connect_timeout", 
aw->connect_timeout);
@@ -2029,6 +2038,7 @@ static void display_worker_ajp_details(j
         jk_printf(s, l, " host=%s", aw->host);
         jk_printf(s, l, " port=%d", aw->port);
         jk_printf(s, l, " address=%s", dump_ajp_addr(aw, buf, sizeof(buf)));
+        jk_printf(s, l, " source=%s", aw->source && *aw->source ? aw->source : 
"undefined");
         jk_printf(s, l, " connection_pool_timeout=%d", aw->cache_timeout);
         jk_printf(s, l, " ping_timeout=%d", aw->ping_timeout);
         jk_printf(s, l, " connect_timeout=%d", aw->connect_timeout);
@@ -2095,6 +2105,7 @@ static void display_worker_ajp_details(j
         jk_print_prop_att_string(s, l, w, ajp_name, "host", aw->host);
         jk_print_prop_att_int(s, l, w, ajp_name, "port", aw->port);
         jk_print_prop_att_string(s, l, w, ajp_name, "address", 
dump_ajp_addr(aw, buf, sizeof(buf)));
+        jk_print_prop_att_string(s, l, w, ajp_name, "source", aw->source && 
*aw->source ? aw->source : "undefined");
         jk_print_prop_att_int(s, l, w, ajp_name, "connection_pool_timeout", 
aw->cache_timeout);
         jk_print_prop_att_int(s, l, w, ajp_name, "ping_timeout", 
aw->ping_timeout);
         jk_print_prop_att_int(s, l, w, ajp_name, "connect_timeout", 
aw->connect_timeout);

Modified: tomcat/jk/trunk/native/common/jk_util.c
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_util.c?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_util.c (original)
+++ tomcat/jk/trunk/native/common/jk_util.c Sun Feb  8 14:28:10 2015
@@ -45,6 +45,7 @@
 #define NATIVE_LIB_OF_WORKER        "native_lib"
 #define REFERENCE_OF_WORKER         "reference"
 #define HOST_OF_WORKER              "host"
+#define SOURCE_OF_WORKER            "source"
 #define PORT_OF_WORKER              "port"
 #define TYPE_OF_WORKER              "type"
 #define CACHE_OF_WORKER_DEPRECATED  "cachesize"
@@ -183,6 +184,7 @@ static const char *unique_properties[] =
     SECRET_OF_WORKER,
     REFERENCE_OF_WORKER,
     HOST_OF_WORKER,
+    SOURCE_OF_WORKER,
     PORT_OF_WORKER,
     TYPE_OF_WORKER,
     CACHE_OF_WORKER_DEPRECATED,
@@ -279,6 +281,7 @@ static const char *supported_properties[
     NATIVE_LIB_OF_WORKER,
     REFERENCE_OF_WORKER,
     HOST_OF_WORKER,
+    SOURCE_OF_WORKER,
     PORT_OF_WORKER,
     TYPE_OF_WORKER,
     CACHE_OF_WORKER_DEPRECATED,
@@ -906,6 +909,19 @@ const char *jk_get_worker_host(jk_map_t
 
     return jk_map_get_string(m, buf, def);
 }
+
+const char *jk_get_worker_source(jk_map_t *m, const char *wname, const char 
*def)
+{
+    char buf[PARAM_BUFFER_SIZE];
+
+    if (!m || !wname) {
+        return NULL;
+    }
+
+    MAKE_WORKER_PARAM(SOURCE_OF_WORKER);
+
+    return jk_map_get_string(m, buf, def);
+}
 
 int jk_get_worker_port(jk_map_t *m, const char *wname, int def)
 {

Modified: tomcat/jk/trunk/native/common/jk_util.h
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_util.h?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_util.h (original)
+++ tomcat/jk/trunk/native/common/jk_util.h Sun Feb  8 14:28:10 2015
@@ -63,6 +63,8 @@ int jk_check_attribute_length(const char
     
 const char *jk_get_worker_host(jk_map_t *m, const char *wname, const char 
*def);
 
+const char *jk_get_worker_source(jk_map_t *m, const char *wname, const char 
*def);
+
 const char *jk_get_worker_type(jk_map_t *m, const char *wname);
 
 int jk_get_worker_port(jk_map_t *m, const char *wname, int def);

Modified: tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml (original)
+++ tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Sun Feb  8 14:28:10 2015
@@ -210,6 +210,11 @@
         "no usable connection found, will create a new one". Tone done
         from info log level to debug for the common case. (rjung)
       </fix>
+      <add>
+        <bug>57536</bug>: AJP: Allow to configure connection source address.
+        This should only be used on multi-homed hosts. The feature is
+        experimental. (rjung)
+      </add>
     </changelog>
   </subsection>
 </section>

Modified: tomcat/jk/trunk/xdocs/reference/workers.xml
URL: 
http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/reference/workers.xml?rev=1658173&r1=1658172&r2=1658173&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/reference/workers.xml (original)
+++ tomcat/jk/trunk/xdocs/reference/workers.xml Sun Feb  8 14:28:10 2015
@@ -253,6 +253,14 @@ The default value depends on the worker
 <b>8009</b>, while for ajp14 type of worker that value is <b>8011</b>.
 </directive>
 
+<directive name="source" default="" required="false">
+Name or IP address used for the connection source (outgoing address).
+It should only be used on multi-homed hosts.
+<p>
+This feature is experimental and has been added in <b>jk 1.2.41</b>.
+</p>
+</directive>
+
 <directive name="socket_timeout" default="0" required="false">
 Socket timeout in seconds used for the communication channel between JK and 
remote host.
 If the remote host does not respond inside the timeout specified, JK will 
generate an error,



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

Reply via email to