From 7640e72a319905446456ed4892e25989da72c263 Mon Sep 17 00:00:00 2001 From: Lukas Tribus Date: Mon, 3 Mar 2014 21:10:51 +0100 Subject: [PATCH] MINOR: set IP_FREEBIND on IPv6 sockets in transparent mode Lets set IP_FREEBIND on IPv6 sockets as well, this works since Linux 3.3 and doesn't require CAP_NET_ADMIN privileges (IPV6_TRANSPARENT does). This allows unprivileged users to bind to non-local IPv6 addresses, which can be useful when setting up the listening sockets or when connecting to backend servers with a specific, non-local source IPv6 address (at that point we usually dropped root privileges already). --- src/proto_tcp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 11f63310b..2b12ef8e8 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -160,6 +160,9 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so #if defined(IPV6_TRANSPARENT) || (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0) #endif +#if defined(IP_FREEBIND) + || (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0) +#endif #if defined(IPV6_BINDANY) || (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == 0) #endif @@ -787,6 +790,9 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) #if defined(IPV6_TRANSPARENT) && (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == -1) #endif +#if defined(IP_FREEBIND) + && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1) +#endif #if defined(IPV6_BINDANY) && (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == -1) #endif