--- /config.c
+++ /config.c
@@ -81,6 +81,9 @@
 static regex_t  ClientCert, AddHeader, DisableProto, SSLAllowClientRenegotiation, SSLHonorCipherOrder, Ciphers;
 static regex_t  CAlist, VerifyList, CRLlist, NoHTTPS11, Grace, Include, ConnTO, IgnoreCase, HTTPS;
 static regex_t  Disabled, Threads, CNName, Anonymise, ECDHCurve;
+#ifdef TPROXY_ENABLE
+static regex_t  TProxy;
+#endif

 static regmatch_t   matches[5];

@@ -250,6 +250,9 @@
     res->url = NULL;
     res->next = NULL;
     has_addr = has_port = 0;
+#ifdef TPROXY_ENABLE
+    res->tp_enabled = 0;
+#endif
     pthread_mutex_init(&res->mut, NULL);
     while(conf_fgets(lin, MAXBUF)) {
         if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
@@ -415,6 +415,10 @@
             if((res->addr.ai_family == AF_INET || res->addr.ai_family == AF_INET6) && !has_port)
                 conf_err("BackEnd missing Port - aborted");
             return res;
+#ifdef TPROXY_ENABLE
+        } else if(!regexec(&TProxy, lin, 4, matches, 0)) {
+           if (enable_tproxy && have_tproxy) res->tp_enabled = atoi(lin + matches[1].rm_so);
+#endif
         } else {
             conf_err("unknown directive");
         }
@@ -1282,6 +1282,13 @@
 #endif
             }
             return res;
+#ifdef TPROXY_ENABLE
+        } else if(!regexec(&TProxy, lin, 4, matches, 0)) {
+           if (have_tproxy)
+                enable_tproxy = atoi(lin + matches[1].rm_so);
+           else
+               enable_tproxy = 0;
+#endif
         } else {
             conf_err("unknown directive");
         }
@@ -1492,6 +1492,9 @@
     || regcomp(&VerifyList, "^[ \t]*VerifyList[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&CRLlist, "^[ \t]*CRLlist[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&NoHTTPS11, "^[ \t]*NoHTTPS11[ \t]+([0-2])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+#ifdef TPROXY_ENABLE
+    || regcomp(&TProxy, "^[ \t]*TProxy[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+#endif
     || regcomp(&Include, "^[ \t]*Include[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&ConnTO, "^[ \t]*ConnTO[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
     || regcomp(&IgnoreCase, "^[ \t]*IgnoreCase[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
@@ -1662,6 +1662,9 @@
     regfree(&VerifyList);
     regfree(&CRLlist);
     regfree(&NoHTTPS11);
+#ifdef TPROXY_ENABLE
+    regfree(&TProxy);
+#endif
     regfree(&Include);
     regfree(&ConnTO);
     regfree(&IgnoreCase);

--- /http.c
+++ /http.c
@@ -855,7 +855,12 @@
                 clean_all();
                 return;
             }
-            if(connect_nb(sock, &backend->addr, backend->conn_to) < 0) {
+
+#ifdef TPROXY_ENABLE
+           if(connect_nb(sock, &backend->addr, backend->to, backend->tp_enabled ? &from_host : NULL) < 0) {
+#else
+           if(connect_nb(sock, &backend->addr, backend->to) < 0) {
+#endif
                 str_be(buf, MAXBUF - 1, backend);
                 logmsg(LOG_WARNING, "(%lx) backend %s connect: %s", pthread_self(), buf, strerror(errno));
                 shutdown(sock, 2);
diff -urN Makefile.in Makefile.in
--- Makefile.in
+++ Makefile.in
@@ -25,18 +25,9 @@

 CC=@PTHREAD_CC@

-C_TPROXY=
-
-TPROXY=0
-
-ifeq (${TPROXY}, 1)
-       $(if $(findstring "@target_os@", "linux-gnu"),,$(error TPROXY can be used just with Linux))
-       C_TPROXY=-DTPROXY_ENABLE
-endif
-
 CFLAGS=-DF_CONF=\"@sysconfdir@/pound.cfg\" -DVERSION=\"@PACKAGE_VERSION@\" -DC_SSL=\"@C_SSL@\" -DC_T_RSA=\"@C_T_RSA@\" \
        -DC_DH_LEN=\"@C_DH_LEN@\" -DC_MAXBUF=\"@C_MAXBUF@\" -DC_OWNER=\"@C_OWNER@\" -DC_GROUP=\"@C_GROUP@\" \
-    -DC_SUPER=\"@C_SUPER@\" -DC_CERT1L=\"@C_CERT1L@\" @CFLAGS@ @PTHREAD_CFLAGS@ @CPPFLAGS@ ${C_TPROXY}
+    -DC_SUPER=\"@C_SUPER@\" -DC_CERT1L=\"@C_CERT1L@\" @CFLAGS@ @PTHREAD_CFLAGS@ @CPPFLAGS@
 LIBS=@LIBS@ @PTHREAD_LIBS@

 prefix=@prefix@
diff -urN pound.h pound.h
--- pound.h
+++ pound.h
@@ -241,6 +241,14 @@
 #define const
 #endif

+#ifdef TPROXY_ENABLE
+#include <sys/prctl.h>
+#include <linux/capability.h>
+#ifndef IP_TRANSPARENT
+#define IP_TRANSPARENT 19
+#endif
+#endif
+
 #ifdef  HAVE_LONG_LONG_INT
 #define LONG    long long
 #define L0      0LL
@@ -275,6 +275,11 @@
             grace,              /* grace period before shutdown */
             control_sock;       /* control socket */

+#ifdef TPROXY_ENABLE
+extern int  have_tproxy,       /* is tproxy available */
+           enable_tproxy;      /* is tproxy enabled */
+#endif
+
 extern regex_t  HEADER,     /* Allowed header */
                 CHUNK_HEAD, /* chunk header line */
                 RESP_SKIP,  /* responses for which we skip response */
@@ -320,6 +320,9 @@
     int                 to;         /* read/write time-out */
     int                 conn_to;    /* connection time-out */
     struct addrinfo     ha_addr;    /* HA address/port */
+#ifdef TPROXY_ENABLE
+    int                        tp_enabled; /* TProxy is enabled */
+#endif
     char                *url;       /* for redirectors */
     int                 redir_req;  /* the redirect should include the request path */
     SSL_CTX             *ctx;       /* CTX for SSL connections */
@@ -579,7 +579,12 @@
  * Non-blocking version of connect(2). Does the same as connect(2) but
  * ensures it will time-out after a much shorter time period CONN_TO.
  */
+#ifdef TPROXY_ENABLE
+extern int  detect_tproxy(void);
+extern int  connect_nb(const int, const struct addrinfo *, const int, const struct addrinfo *);
+#else
 extern int  connect_nb(const int, const struct addrinfo *, const int);
+#endif

 /*
  * Parse arguments/config file

diff -urN svc.c svc.c
--- svc.c
+++ svc.c
@@ -372,6 +372,40 @@
     return res - kp_res;
 }

+#ifdef TPROXY_ENABLE
+/*
+ * detect_tproxy
+ * check for TPROXY
+ *
+ * Thanks to Loadbalancer.org, Inc. especially to Malcolm Turnbull for sponsorship
+ * Thanks to Sianet Business Hosting especially to Rodrigo L. L. Jorge for sponsorship
+ *
+ */
+int
+detect_tproxy(void)
+{
+    int sock, tp_val;
+
+    tp_val = 1;
+
+    sock = socket(AF_INET, SOCK_STREAM, 0);
+    if (sock < 0) {
+        logmsg(LOG_WARNING, "detect_tproxy(): socket SOCK_STREAM failed: %s", strerror(errno));
+        return 1;
+    }
+    if (setsockopt(sock, SOL_IP, IP_TRANSPARENT, &tp_val, sizeof(tp_val)) < 0) {
+        logmsg(LOG_INFO, "detect_tproxy(): tproxy is not available");
+        close(sock);
+        return 1;
+    }
+
+    close(sock);
+    logmsg(LOG_INFO, "detect_tproxy(): tproxy is is detected");
+
+    return 0;
+}
+#endif
+
 /*
  * Parse a header
  * return a code and possibly content in the arg
@@ -922,12 +922,26 @@
  * Non-blocking connect(). Does the same as connect(2) but ensures
  * it will time-out after a much shorter time period SERVER_TO
  */
+#ifdef TPROXY_ENABLE
 int
-connect_nb(const int sockfd, const struct addrinfo *serv_addr, const int to)
-{
+connect_nb(const int sockfd, const struct addrinfo *serv_addr, const int to, const struct addrinfo *tp_addr) {
+#else
+int
+connect_nb(const int sockfd, const struct addrinfo *serv_addr, const int to) {
+#endif
     int             flags, res, error;
     socklen_t       len;
     struct pollfd   p;
+#ifdef TPROXY_ENABLE
+    int tp_val = 1;
+    struct sockaddr_in in;
+#endif
+
+    if (! serv_addr->ai_addr)
+    {
+       logmsg(LOG_ERR, "cconnect_nb: wrong serv_addr->ai_addr");
+       return -1;
+    }

     if((flags = fcntl(sockfd, F_GETFL, 0)) < 0) {
         logmsg(LOG_WARNING, "(%lx) connect_nb: fcntl GETFL failed: %s", pthread_self(), strerror(errno));
@@ -937,6 +937,24 @@
         logmsg(LOG_WARNING, "(%lx) connect_nb: fcntl SETFL failed: %s", pthread_self(), strerror(errno));
         return -1;
     }
+
+#ifdef TPROXY_ENABLE
+    if (tp_addr) {
+       memcpy(&in, tp_addr->ai_addr, sizeof(in));
+       in.sin_port = 0;
+       if (setsockopt(sockfd, SOL_IP, IP_TRANSPARENT, &tp_val, sizeof(tp_val)) < 0) {
+           logmsg(LOG_ERR, "(%lx) connect_nb: cannot set TProxy IP_TRANSPARENT socket option. Error: %d, %s.", pthread_self(),
+                            error, strerror(error));
+           return -1;
+       }
+
+       if (bind(sockfd, (struct sockaddr *) &in, sizeof(in)) < 0) {
+           logmsg(LOG_ERR, "(%lx) connect_nb: cannot bind to TProxy IP. Error: %d, %s.", pthread_self(),
+                            error, strerror(error));
+           return -1;
+       }
+    }
+#endif

     error = 0;
     if((res = connect(sockfd, serv_addr->ai_addr, serv_addr->ai_addrlen)) < 0)
@@ -1036,7 +1036,12 @@
         default:
             continue;
         }
-        if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0) {
+#ifdef TPROXY_ENABLE
+        if(connect_nb(sock, &be->ha_addr, be->conn_to, NULL) != 0)
+#else
+        if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0)
+#endif
+       {
             kill_be(svc, be, BE_KILL);
             str_be(buf, MAXBUF - 1, be);
             logmsg(LOG_NOTICE, "BackEnd %s is dead (HA)", buf);
@@ -1072,7 +1072,12 @@
         default:
             continue;
         }
-        if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0) {
+#ifdef TPROXY_ENABLE
+        if(connect_nb(sock, &be->ha_addr, be->conn_to, NULL) != 0)
+#else
+        if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0)
+#endif
+       {
             kill_be(svc, be, BE_KILL);
             str_be(buf, MAXBUF - 1, be);
             logmsg(LOG_NOTICE, "BackEnd %s is dead (HA)", buf);
@@ -1127,7 +1127,12 @@
                 }
                 addr = &be->ha_addr;
             }
-            if(connect_nb(sock, addr, be->conn_to) == 0) {
+#ifdef TPROXY_ENABLE
+           if(connect_nb(sock, addr, be->conn_to, NULL) == 0)
+#else
+           if(connect_nb(sock, addr, be->conn_to) == 0)
+#endif
+           {
                 be->resurrect = 1;
                 modified = 1;
             }
@@ -1196,7 +1196,12 @@
                 }
                 addr = &be->ha_addr;
             }
-            if(connect_nb(sock, addr, be->conn_to) == 0) {
+#ifdef TPROXY_ENABLE
+           if(connect_nb(sock, addr, be->conn_to, NULL) != 0)
+#else
+            if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0)
+#endif
+           {
                 be->resurrect = 1;
                 modified = 1;
             }