It is useless and time-consuming to call get_original_dst() when the proxy is not in transparent mode : 10:30:12.784822 accept(3, {sa_family=AF_INET, sin_port=htons(32788), sin_addr=inet_addr("10.0.3.2")}, [16]) = 5 <0.000026> 10:30:12.784933 fcntl64(5, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 <0.000008> 10:30:12.784980 setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 0 <0.000010> 10:30:12.785035 getsockopt(5, SOL_IP, 0x50 /* IP_??? */, 0xb0c93478, 0xb0c93460) = -1 ENOPROTOOPT (Protocol not available) <0.000015> 10:30:12.785107 getsockname(5, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("10.0.3.1")}, [16]) = 0 <0.000011> 10:30:12.785207 write(2, "accepting from 0x806e9c8 => 1 co"..., 60) = 60 <0.000016> --- hapoxy-1.1.32/haproxy.c Sun Oct 9 11:32:39 2005 +++ ./haproxy.c Sun Oct 9 11:54:25 2005 @@ -1592,7 +1592,7 @@ /* some prototypes */ static int maintain_proxies(void); -/* this either returns the sockname or the original destination address. Code +/* This either returns the sockname or the original destination address. Code * inspired from Patrick Schaaf's example of nf_getsockname() implementation. */ static int get_original_dst(int fd, struct sockaddr_in *sa, socklen_t *salen) { @@ -1723,7 +1723,8 @@ struct sockaddr_in sockname; socklen_t namelen = sizeof(sockname); - if (get_original_dst(s->cli_fd, (struct sockaddr_in *)&sockname, &namelen) == -1) + if (!(s->proxy->options & PR_O_TRANSP) || + get_original_dst(s->cli_fd, (struct sockaddr_in *)&sockname, &namelen) == -1) getsockname(s->cli_fd, (struct sockaddr *)&sockname, &namelen); s->srv_addr.sin_port = htons(ntohs(s->srv_addr.sin_port) + ntohs(sockname.sin_port)); } @@ -2499,7 +2500,8 @@ socklen_t namelen = sizeof(sockname); unsigned char *pn, *sn; - if (get_original_dst(cfd, (struct sockaddr_in *)&sockname, &namelen) == -1) + if (!(s->proxy->options & PR_O_TRANSP) || + get_original_dst(cfd, (struct sockaddr_in *)&sockname, &namelen) == -1) getsockname(cfd, (struct sockaddr *)&sockname, &namelen); sn = (unsigned char *)&sockname.sin_addr; pn = (unsigned char *)&s->cli_addr.sin_addr; @@ -2523,7 +2525,8 @@ unsigned char *pn, *sn; int len; - if (get_original_dst(cfd, (struct sockaddr_in *)&sockname, &namelen) == -1) + if (!(s->proxy->options & PR_O_TRANSP) || + get_original_dst(cfd, (struct sockaddr_in *)&sockname, &namelen) == -1) getsockname(cfd, (struct sockaddr *)&sockname, &namelen); sn = (unsigned char *)&sockname.sin_addr; pn = (unsigned char *)&s->cli_addr.sin_addr;