summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2017-11-01 12:09:27 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2017-11-01 12:09:27 +0000
commitb0e1a44e4ff8d234f5e37f000b556ffcdbb5a040 (patch)
tree3290a0b1197b0db7c32f226ed1f810dfa8d2af44
parent0b3000073334476af026627df3d909389472aaaf (diff)
Make ip-transparent option work by using SO_BINDANY.
OK jca, benno
-rw-r--r--usr.sbin/unbound/doc/unbound.conf.5.in3
-rw-r--r--usr.sbin/unbound/services/listen_dnsport.c26
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 &&