diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2017-11-01 12:09:27 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2017-11-01 12:09:27 +0000 |
commit | b0e1a44e4ff8d234f5e37f000b556ffcdbb5a040 (patch) | |
tree | 3290a0b1197b0db7c32f226ed1f810dfa8d2af44 | |
parent | 0b3000073334476af026627df3d909389472aaaf (diff) |
Make ip-transparent option work by using SO_BINDANY.
OK jca, benno
-rw-r--r-- | usr.sbin/unbound/doc/unbound.conf.5.in | 3 | ||||
-rw-r--r-- | usr.sbin/unbound/services/listen_dnsport.c | 26 |
2 files changed, 22 insertions, 7 deletions
diff --git a/usr.sbin/unbound/doc/unbound.conf.5.in b/usr.sbin/unbound/doc/unbound.conf.5.in index 153e4a2f921..fcad8017d73 100644 --- a/usr.sbin/unbound/doc/unbound.conf.5.in +++ b/usr.sbin/unbound/doc/unbound.conf.5.in @@ -257,7 +257,8 @@ are going to exist later on, with host failover configuration. This is a lot like interface\-automatic, but that one services all interfaces and with this option you can select which (future) interfaces unbound provides service on. This option needs unbound to be started with root -permissions on some systems. The option uses IP_BINDANY on FreeBSD systems. +permissions on some systems. The option uses IP_BINDANY on FreeBSD systems +and SO_BINDANY on OpenBSD systems. .TP .B ip\-freebind: \fI<yes or no> If yes, then use IP_FREEBIND socket option on sockets where unbound diff --git a/usr.sbin/unbound/services/listen_dnsport.c b/usr.sbin/unbound/services/listen_dnsport.c index 3b53676d0e0..d099ca9449b 100644 --- a/usr.sbin/unbound/services/listen_dnsport.c +++ b/usr.sbin/unbound/services/listen_dnsport.c @@ -167,7 +167,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr, int freebind, int use_systemd) { int s; -#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) +#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined (SO_BINDANY) int on=1; #endif #ifdef IPV6_MTU @@ -182,7 +182,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr, #ifndef IPV6_V6ONLY (void)v6only; #endif -#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY) +#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY) && !defined(SO_BINDANY) (void)transparent; #endif #if !defined(IP_FREEBIND) @@ -281,7 +281,14 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr, log_warn("setsockopt(.. IP%s_BINDANY ..) failed: %s", (family==AF_INET6?"V6":""), strerror(errno)); } -#endif /* IP_TRANSPARENT || IP_BINDANY */ +#elif defined(SO_BINDANY) + if (transparent && + setsockopt(s, SOL_SOCKET, SO_BINDANY, (void*)&on, + (socklen_t)sizeof(on)) < 0) { + log_warn("setsockopt(.. SO_BINDANY ..) failed: %s", + strerror(errno)); + } +#endif /* IP_TRANSPARENT || IP_BINDANY || SO_BINDANY */ } #ifdef IP_FREEBIND if(freebind && @@ -592,7 +599,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto, int* reuseport, int transparent, int mss, int freebind, int use_systemd) { int s; -#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) +#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY) int on = 1; #endif #ifdef HAVE_SYSTEMD @@ -601,7 +608,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto, #ifdef USE_TCP_FASTOPEN int qlen; #endif -#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY) +#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY) && !defined(SO_BINDANY) (void)transparent; #endif #if !defined(IP_FREEBIND) @@ -736,7 +743,14 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto, log_warn("setsockopt(.. IP%s_BINDANY ..) failed: %s", (addr->ai_family==AF_INET6?"V6":""), strerror(errno)); } -#endif /* IP_TRANSPARENT || IP_BINDANY */ +#elif defined(SO_BINDANY) + if (transparent && + setsockopt(s, SOL_SOCKET, SO_BINDANY, (void*)&on, (socklen_t) + sizeof(on)) < 0) { + log_warn("setsockopt(.. SO_BINDANY ..) failed: %s", + strerror(errno)); + } +#endif /* IP_TRANSPARENT || IP_BINDANY || SO_BINDANY */ if( #ifdef HAVE_SYSTEMD !got_fd_from_systemd && |