From: Willy Tarreau Date: Fri, 16 Dec 2011 20:25:11 +0000 (+0100) Subject: BUG: proto_tcp: don't try to bind to a foreign address if sin_family is unknown X-Git-Tag: v1.5-dev8~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dc1e98905154d883dd1d5d357183f37ce202a7e;p=thirdparty%2Fhaproxy.git BUG: proto_tcp: don't try to bind to a foreign address if sin_family is unknown This is 1.5-specific. It causes issues with transparent source binding involving hdr_ip. We must not try to bind() to a foreign address when the family is not set, and we must set the family when an address is set. --- diff --git a/src/backend.c b/src/backend.c index 248bf1e5a1..6a12cf4c58 100644 --- a/src/backend.c +++ b/src/backend.c @@ -881,6 +881,7 @@ static void assign_tproxy_address(struct session *s) case SRV_TPROXY_DYN: if (srv->bind_hdr_occ) { /* bind to the IP in a header */ + ((struct sockaddr_in *)&s->req->cons->addr.from)->sin_family = AF_INET; ((struct sockaddr_in *)&s->req->cons->addr.from)->sin_port = 0; ((struct sockaddr_in *)&s->req->cons->addr.from)->sin_addr.s_addr = htonl(get_ip_from_hdr2(&s->txn.req, @@ -907,6 +908,7 @@ static void assign_tproxy_address(struct session *s) case PR_O_TPXY_DYN: if (s->be->bind_hdr_occ) { /* bind to the IP in a header */ + ((struct sockaddr_in *)&s->req->cons->addr.from)->sin_family = AF_INET; ((struct sockaddr_in *)&s->req->cons->addr.from)->sin_port = 0; ((struct sockaddr_in *)&s->req->cons->addr.from)->sin_addr.s_addr = htonl(get_ip_from_hdr2(&s->txn.req, diff --git a/src/proto_tcp.c b/src/proto_tcp.c index ecef63f85b..caeb539317 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -146,6 +146,9 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so if (flags & 2) ((struct sockaddr_in6 *)&bind_addr)->sin6_port = ((struct sockaddr_in6 *)remote)->sin6_port; break; + default: + /* we don't want to try to bind to an unknown address family */ + foreign_ok = 0; } }