diff -uNr httpd-2.2.9/config.nice httpd-2.2.9-tproxy/config.nice
--- httpd-2.2.9/config.nice	1970-01-01 09:00:00.000000000 +0900
+++ httpd-2.2.9-tproxy/config.nice	2009-11-11 16:51:43.000000000 +0900
@@ -0,0 +1,13 @@
+#! /bin/sh
+#
+# Created by configure
+
+CPPFLAGS="-I/usr/src/kernels/linux-2.6.21.7/include"; export CPPFLAGS
+"./configure" \
+"--prefix=/usr/local/waf" \
+"--enable-so" \
+"--enable-unique_id" \
+"--with-mpm=worker" \
+"--enable-mods-shared=proxy proxy_http proxy_balancer cache disk_cache mem_cache headers deflate rewrite ssl" \
+"CPPFLAGS=-I/usr/src/kernels/linux-2.6.21.7/include" \
+"$@"
diff -uNr httpd-2.2.9/modules/proxy/mod_proxy.c httpd-2.2.9-tproxy/modules/proxy/mod_proxy.c
--- httpd-2.2.9/modules/proxy/mod_proxy.c	2008-05-29 06:11:24.000000000 +0900
+++ httpd-2.2.9-tproxy/modules/proxy/mod_proxy.c	2009-11-11 16:17:46.000000000 +0900
@@ -1870,6 +1870,18 @@
     return NULL;
 }
 
+static const char *
+set_tproxy(cmd_parms *parms, void *dummy, int flag)
+{
+    proxy_server_conf *psf =
+	ap_get_module_config(parms->server->module_config, &proxy_module);
+
+    psf->tproxy = flag;
+    psf->tproxy_set = 1;
+
+    return NULL;
+}
+
 static void ap_add_per_proxy_conf(server_rec *s, ap_conf_vector_t *dir_config)
 {
     proxy_server_conf *sconf = ap_get_module_config(s->module_config,
@@ -2082,6 +2094,8 @@
      "A balancer or worker name with list of params"),
     AP_INIT_TAKE1("ProxyFtpDirCharset", set_ftp_directory_charset, NULL,
      RSRC_CONF|ACCESS_CONF, "Define the character set for proxied FTP listings"),
+    AP_INIT_FLAG("ProxyTProxy", set_tproxy, NULL, RSRC_CONF,
+     "on if the proxy should use client IP to connect to the origin server"),
     {NULL}
 };
 
diff -uNr httpd-2.2.9/modules/proxy/mod_proxy.h httpd-2.2.9-tproxy/modules/proxy/mod_proxy.h
--- httpd-2.2.9/modules/proxy/mod_proxy.h	2008-05-29 06:24:04.000000000 +0900
+++ httpd-2.2.9-tproxy/modules/proxy/mod_proxy.h	2009-11-11 16:19:18.000000000 +0900
@@ -193,6 +193,9 @@
     } proxy_status;             /* Status display options */
     char proxy_status_set;
     apr_pool_t *pool;           /* Pool used for allocating this struct */
+    int tproxy;                 /* true if tproxy is enabled */
+    char tproxy_set;
+
 } proxy_server_conf;
 
 
@@ -711,6 +714,7 @@
  * @param conn    acquired connection
  * @param worker  connection worker
  * @param s       current server record
+ * @param remote_addr  client addr
  * @return        OK or HTTP_XXX error
  * @note In case the socket already exists for conn, just check the link
  * status.
@@ -718,7 +722,8 @@
 PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
                                             proxy_conn_rec *conn,
                                             proxy_worker *worker,
-                                            server_rec *s);
+                                            server_rec *s,
+					    apr_sockaddr_t *remote_addr);
 /**
  * Make a connection record for backend connection
  * @param proxy_function calling proxy scheme (http, ajp, ...)
diff -uNr httpd-2.2.9/modules/proxy/mod_proxy_ajp.c httpd-2.2.9-tproxy/modules/proxy/mod_proxy_ajp.c
--- httpd-2.2.9/modules/proxy/mod_proxy_ajp.c	2008-06-05 21:46:43.000000000 +0900
+++ httpd-2.2.9-tproxy/modules/proxy/mod_proxy_ajp.c	2009-11-11 16:19:56.000000000 +0900
@@ -605,11 +605,11 @@
         goto cleanup;
 
     /* Step Two: Make the Connection */
-    if (ap_proxy_connect_backend(scheme, backend, worker, r->server)) {
-        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
-                     "proxy: AJP: failed to make connection to backend: %s",
-                     backend->hostname);
-        status = HTTP_SERVICE_UNAVAILABLE;
+    if (ap_proxy_connect_backend(scheme, backend, worker, r->server, r->connection->remote_addr)) {
+	ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+		     "proxy: AJP: failed to make connection to backend: %s",
+		     backend->hostname);
+	status = HTTP_SERVICE_UNAVAILABLE;
         goto cleanup;
     }
 
diff -uNr httpd-2.2.9/modules/proxy/mod_proxy_ftp.c httpd-2.2.9-tproxy/modules/proxy/mod_proxy_ftp.c
--- httpd-2.2.9/modules/proxy/mod_proxy_ftp.c	2008-05-18 04:42:03.000000000 +0900
+++ httpd-2.2.9-tproxy/modules/proxy/mod_proxy_ftp.c	2009-11-11 16:21:11.000000000 +0900
@@ -973,11 +973,11 @@
      */
 
 
-    if (ap_proxy_connect_backend("FTP", backend, worker, r->server)) {
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                     "proxy: FTP: an error occurred creating a new connection to %pI (%s)",
-                     connect_addr, connectname);
-        proxy_ftp_cleanup(r, backend);
+    if (ap_proxy_connect_backend("FTP", backend, worker, r->server, c->remote_addr)) {
+	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+		     "proxy: FTP: an error occurred creating a new connection to %pI (%s)",
+		     connect_addr, connectname);
+	proxy_ftp_cleanup(r, backend);
         return HTTP_SERVICE_UNAVAILABLE;
     }
 
diff -uNr httpd-2.2.9/modules/proxy/mod_proxy_http.c httpd-2.2.9-tproxy/modules/proxy/mod_proxy_http.c
--- httpd-2.2.9/modules/proxy/mod_proxy_http.c	2008-06-11 03:49:19.000000000 +0900
+++ httpd-2.2.9-tproxy/modules/proxy/mod_proxy_http.c	2009-11-11 16:22:03.000000000 +0900
@@ -1929,7 +1929,7 @@
         goto cleanup;
 
     /* Step Two: Make the Connection */
-    if (ap_proxy_connect_backend(proxy_function, backend, worker, r->server)) {
+     if (ap_proxy_connect_backend(proxy_function, backend, worker, r->server, c->remote_addr)) {
         if (r->proxyreq == PROXYREQ_PROXY)
             status = HTTP_NOT_FOUND;
         else
diff -uNr httpd-2.2.9/modules/proxy/proxy_util.c httpd-2.2.9-tproxy/modules/proxy/proxy_util.c
--- httpd-2.2.9/modules/proxy/proxy_util.c	2008-05-29 06:11:24.000000000 +0900
+++ httpd-2.2.9-tproxy/modules/proxy/proxy_util.c	2009-11-11 16:24:06.000000000 +0900
@@ -2269,7 +2269,8 @@
 PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
                                             proxy_conn_rec *conn,
                                             proxy_worker *worker,
-                                            server_rec *s)
+                                            server_rec *s,
+					    apr_sockaddr_t *remote_addr)
 {
     apr_status_t rv;
     int connected = 0;
@@ -2342,8 +2343,23 @@
                 ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                              "apr_socket_opt_set(SO_KEEPALIVE): Failed to set"
                              " Keepalive");
-            }
-        }
+	    }
+	}
+
+	/* TProxy support */
+	if (conf->tproxy) {
+	    if ((rv = apr_socket_opt_set(newsock, APR_IP_TRANSPARENT, 1)) != APR_SUCCESS) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+			     "apr_socket_opt_set(APR_IP_TRANSPARENT): Failed to set");
+	    }
+
+	    if ((rv = apr_socket_bind(newsock, remote_addr)) != APR_SUCCESS) {
+		ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+			     "proxy: error binding to socket %pI", remote_addr);
+		return HTTP_INTERNAL_SERVER_ERROR;
+	    }
+	}
+
         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                      "proxy: %s: fam %d socket created to connect to %s",
                      proxy_function, backend_addr->family, worker->hostname);
diff -uNr httpd-2.2.9/os/unix/unixd.c httpd-2.2.9-tproxy/os/unix/unixd.c
--- httpd-2.2.9/os/unix/unixd.c	2006-07-12 12:38:44.000000000 +0900
+++ httpd-2.2.9-tproxy/os/unix/unixd.c	2009-11-11 16:40:52.000000000 +0900
@@ -49,8 +49,10 @@
 #endif
 #ifdef HAVE_SYS_PRCTL_H
 #include <sys/prctl.h>
+#include <sys/capability.h>
 #endif
 
+
 unixd_config_rec unixd_config;
 
 /* Set group privileges.
@@ -60,6 +62,36 @@
  * with different sets of groups for each.
  */
 
+void
+keep_capabilities(void)
+{
+    if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
+	ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, "prctl Failed");
+    }
+}
+
+static void
+set_capabilities(int capability)
+{
+    cap_user_header_t head = (cap_user_header_t) calloc(1, sizeof(*head));
+    cap_user_data_t cap = (cap_user_data_t) calloc(1, sizeof(*cap));
+
+    head->version = _LINUX_CAPABILITY_VERSION;
+    head->pid = 0;
+    cap->effective = (1 << capability);
+    cap->inheritable = cap->effective;
+    cap->permitted = cap->effective;
+
+    if (capset(head, cap) != 0) {
+	ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, "capset Failed");
+    }
+
+    free(head);
+    free(cap);
+}
+
+
+
 static int set_group_privs(void)
 {
     if (!geteuid()) {
@@ -117,6 +149,7 @@
     if (set_group_privs()) {
         return -1;
     }
+    keep_capabilities();
 #ifdef MPE
     /* Only try to switch if we're running as MANAGER.SYS */
     if (geteuid() == 1 && unixd_config.user_id > 1) {
@@ -142,6 +175,10 @@
                     (long) unixd_config.user_id);
         return -1;
     }
+
+    /* Needed for tproxy */
+    set_capabilities(CAP_NET_ADMIN);
+
 #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
     /* this applies to Linux 2.4+ */
 #ifdef AP_MPM_WANT_SET_COREDUMPDIR
Binary files httpd-2.2.9/server/mpm/prefork/.libs/libprefork.a and httpd-2.2.9-tproxy/server/mpm/prefork/.libs/libprefork.a differ
diff -uNr httpd-2.2.9/server/mpm/prefork/.libs/libprefork.la httpd-2.2.9-tproxy/server/mpm/prefork/.libs/libprefork.la
--- httpd-2.2.9/server/mpm/prefork/.libs/libprefork.la	1970-01-01 09:00:00.000000000 +0900
+++ httpd-2.2.9-tproxy/server/mpm/prefork/.libs/libprefork.la	2009-11-13 15:03:40.928426797 +0900
@@ -0,0 +1,41 @@
+# libprefork.la - a libtool library file
+# Generated by ltmain.sh (GNU libtool) 2.2.6
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libprefork.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=' -pthread'
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libprefork.
+current=
+age=
+revision=
+
+# Is this an already installed library?
+installed=no
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir=''
Binary files httpd-2.2.9/server/mpm/prefork/.libs/prefork.o and httpd-2.2.9-tproxy/server/mpm/prefork/.libs/prefork.o differ
diff -uNr httpd-2.2.9/server/mpm/prefork/Makefile httpd-2.2.9-tproxy/server/mpm/prefork/Makefile
--- httpd-2.2.9/server/mpm/prefork/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ httpd-2.2.9-tproxy/server/mpm/prefork/Makefile	2009-11-13 15:04:01.836551463 +0900
@@ -0,0 +1,10 @@
+top_srcdir   = /root/httpd-2.2.9-tproxy
+top_builddir = /root/httpd-2.2.9-tproxy
+srcdir       = /root/httpd-2.2.9-tproxy/server/mpm/prefork
+builddir     = /root/httpd-2.2.9-tproxy/server/mpm/prefork
+VPATH        = /root/httpd-2.2.9-tproxy/server/mpm/prefork
+
+LTLIBRARY_NAME    = libprefork.la
+LTLIBRARY_SOURCES = prefork.c
+
+include $(top_srcdir)/build/ltlib.mk
diff -uNr httpd-2.2.9/server/mpm/prefork/libprefork.la httpd-2.2.9-tproxy/server/mpm/prefork/libprefork.la
--- httpd-2.2.9/server/mpm/prefork/libprefork.la	1970-01-01 09:00:00.000000000 +0900
+++ httpd-2.2.9-tproxy/server/mpm/prefork/libprefork.la	2009-11-13 15:03:40.928426797 +0900
@@ -0,0 +1,41 @@
+# libprefork.la - a libtool library file
+# Generated by ltmain.sh (GNU libtool) 2.2.6
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname=''
+
+# Names of this library.
+library_names=''
+
+# The name of the static archive.
+old_library='libprefork.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=' -pthread'
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libprefork.
+current=
+age=
+revision=
+
+# Is this an already installed library?
+installed=no
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir=''
diff -uNr httpd-2.2.9/server/mpm/prefork/prefork.lo httpd-2.2.9-tproxy/server/mpm/prefork/prefork.lo
--- httpd-2.2.9/server/mpm/prefork/prefork.lo	1970-01-01 09:00:00.000000000 +0900
+++ httpd-2.2.9-tproxy/server/mpm/prefork/prefork.lo	2009-11-13 15:03:40.873301427 +0900
@@ -0,0 +1,12 @@
+# prefork.lo - a libtool object file
+# Generated by ltmain.sh (GNU libtool) 2.2.6
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object='.libs/prefork.o'
+
+# Name of the non-PIC object
+non_pic_object='prefork.o'
+
Binary files httpd-2.2.9/server/mpm/prefork/prefork.o and httpd-2.2.9-tproxy/server/mpm/prefork/prefork.o differ
diff -uNr httpd-2.2.9/srclib/apr/include/apr_network_io.h httpd-2.2.9-tproxy/srclib/apr/include/apr_network_io.h
--- httpd-2.2.9/srclib/apr/include/apr_network_io.h	2007-12-15 13:10:38.000000000 +0900
+++ httpd-2.2.9-tproxy/srclib/apr/include/apr_network_io.h	2009-11-11 16:41:32.000000000 +0900
@@ -65,6 +65,7 @@
 #define APR_SO_DEBUG         4    /**< Debug */
 #define APR_SO_NONBLOCK      8    /**< Non-blocking IO */
 #define APR_SO_REUSEADDR     16   /**< Reuse addresses */
+#define APR_IP_TRANSPARENT   32   /**< TProxy support */
 #define APR_SO_SNDBUF        64   /**< Send buffer */
 #define APR_SO_RCVBUF        128  /**< Receive buffer */
 #define APR_SO_DISCONNECTED  256  /**< Disconnected */
diff -uNr httpd-2.2.9/srclib/apr/network_io/unix/sockopt.c httpd-2.2.9-tproxy/srclib/apr/network_io/unix/sockopt.c
--- httpd-2.2.9/srclib/apr/network_io/unix/sockopt.c	2006-08-03 19:55:31.000000000 +0900
+++ httpd-2.2.9-tproxy/srclib/apr/network_io/unix/sockopt.c	2009-11-11 16:42:57.000000000 +0900
@@ -17,6 +17,7 @@
 #include "apr_arch_networkio.h"
 #include "apr_strings.h"
 
+#define IP_TRANSPARENT 19
 
 static apr_status_t soblock(int sd)
 {
@@ -318,6 +319,15 @@
         return APR_ENOTIMPL;
 #endif
         break;
+    case APR_IP_TRANSPARENT:
+#ifdef IP_TRANSPARENT
+	if (setsockopt(sock->socketdes, SOL_IP, IP_TRANSPARENT, (void *)&one, sizeof(int)) == -1) {
+	    return errno;
+	}
+#else
+	return APR_ENOTIMPL;
+#endif
+	break;
     default:
         return APR_EINVAL;
     }
