diff --git a/src/client.c b/src/client.c
index b60b86f..2931490 100644
--- a/src/client.c
+++ b/src/client.c
@@ -84,6 +84,8 @@ CLI *alloc_client_session(SERVICE_OPTIONS *opt, int rfd, int wfd) {
     c->opt=opt;
     c->local_rfd.fd=rfd;
     c->local_wfd.fd=wfd;
+    if (c->opt->option.sendproxy)
+        c->sendproxy = 1;
     return c;
 }
 
@@ -559,6 +561,73 @@ static void transfer(CLI *c) {
             }
         }
 
+       if (c->sendproxy && !c->ssl_ptr) {
+               int cfd;
+               struct sockaddr_storage local_addr;
+               struct sockaddr_storage peer_addr;
+               u_char family = AF_UNSPEC;
+
+               cfd = SSL_get_fd(c->ssl);
+               if (cfd != -1) {
+                       size_t namelen;
+
+                       namelen = sizeof(local_addr);
+                       if (!getsockname(cfd, (struct sockaddr *)&local_addr, &namelen)) {
+                               namelen = sizeof(peer_addr);
+                               if (!getpeername(cfd, (struct sockaddr *)&peer_addr, &namelen))
+                                       family = peer_addr.ss_family;
+                       }
+               }
+
+               if (family == AF_INET) {
+
+                       if (BUFFSIZE >= 11) {
+                               memcpy(c->ssl_buff, "PROXY TCP4 ", 11);
+                               c->ssl_ptr += 11;
+                       }
+
+                       if (inet_ntop(peer_addr.ss_family, &((struct sockaddr_in*)&peer_addr)->sin_addr, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr)) {
+                               c->ssl_ptr += strlen(c->ssl_buff+c->ssl_ptr);
+                       }
+                       if (c->ssl_ptr != BUFFSIZE) {
+                               c->ssl_buff[c->ssl_ptr] = ' ';
+                               c->ssl_ptr++;
+                       }
+                       if (inet_ntop(local_addr.ss_family, &((struct sockaddr_in*)&local_addr)->sin_addr, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr)) {
+                               c->ssl_ptr += strlen(c->ssl_buff+c->ssl_ptr);
+                       }
+                       c->ssl_ptr += snprintf(c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr, " %u %u\r\n", ntohs(((struct sockaddr_in*)&peer_addr)->sin_port), ntohs(((struct sockaddr_in*)&local_addr)->sin_port));
+               }
+#if defined(USE_IPv6) && !defined(USE_WIN32)                   
+               else if (family == AF_INET6) {
+
+                       if (BUFFSIZE >= 11) {
+                                memcpy(c->ssl_buff, "PROXY TCP6 ", 11);
+                                c->ssl_ptr += 11;
+                        }
+
+                        if (inet_ntop(peer_addr.ss_family, &((struct sockaddr_in6*)&peer_addr)->sin6_addr, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr)) {
+                                c->ssl_ptr += strlen(c->ssl_buff+c->ssl_ptr);
+                        }
+                        if (c->ssl_ptr != BUFFSIZE) {
+                                c->ssl_buff[c->ssl_ptr] = ' ';
+                                c->ssl_ptr++;
+                        }
+                        if (inet_ntop(local_addr.ss_family, &((struct sockaddr_in6*)&local_addr)->sin6_addr, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr)) {
+                                c->ssl_ptr += strlen(c->ssl_buff+c->ssl_ptr);
+                        }
+                        c->ssl_ptr += snprintf(c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr, " %u %u\r\n", ntohs(((struct sockaddr_in6*)&peer_addr)->sin6_port), ntohs(((struct sockaddr_in6*)&local_addr)->sin6_port));
+               }
+#endif
+               else {
+                       if (BUFFSIZE >= 15) {
+                                memcpy(c->ssl_buff, "PROXY UNKNOWN\r\n ", 15);
+                                c->ssl_ptr += 15;
+                        }
+               }
+               c->sendproxy = 0;
+       }
+
         /****************************** write to socket */
         if(sock_open_wr && sock_can_wr) {
             num=writesocket(c->sock_wfd->fd, c->ssl_buff, c->ssl_ptr);
diff --git a/src/options.c b/src/options.c
index 174550f..1216738 100644
--- a/src/options.c
+++ b/src/options.c
@@ -830,6 +830,29 @@ static char *parse_service_option(CMD cmd, SERVICE_OPTIONS *section,
     }
 #endif
 
+    /* sendproxy */
+    switch(cmd) {
+    case CMD_INIT:
+        section->option.sendproxy=0;
+        break;
+    case CMD_EXEC:
+        if(strcasecmp(opt, "sendproxy"))
+            break;
+        if(!strcasecmp(arg, "yes"))
+            section->option.sendproxy=1;
+        else if(!strcasecmp(arg, "no"))
+            section->option.sendproxy=0;
+        else
+            return "argument should be either 'yes' or 'no'";
+        return NULL; /* OK */
+    case CMD_DEFAULT:
+        break;
+    case CMD_HELP:
+        s_log(LOG_NOTICE, "%-15s = yes|no append proxy prefix",
+            "sendproxy");
+        break;
+    }
+
     /* exec */
     switch(cmd) {
     case CMD_INIT:
diff --git a/src/prototypes.h b/src/prototypes.h
index ad6aed5..2cf4c21 100644
--- a/src/prototypes.h
+++ b/src/prototypes.h
@@ -184,6 +184,7 @@ typedef struct service_options_struct {
         unsigned int sessiond:1;
         unsigned int program:1;         /* endpoint: exec */
         unsigned int sni:1;             /* endpoint: sni */
+	unsigned int sendproxy:1;
 #ifndef USE_WIN32
         unsigned int pty:1;
         unsigned int transparent_src:1;
@@ -373,6 +374,7 @@ typedef struct {
     /* data for transfer() function */
     char sock_buff[BUFFSIZE]; /* socket read buffer */
     char ssl_buff[BUFFSIZE]; /* SSL read buffer */
+    int sendproxy;
     int sock_ptr, ssl_ptr; /* index of first unused byte in buffer */
     FD *sock_rfd, *sock_wfd; /* read and write socket descriptors */
     FD *ssl_rfd, *ssl_wfd; /* read and write SSL descriptors */
