Maintained by: NLnet Labs

make ip-transparent option work on OpenBSD

Florian Obser
Wed Nov 1 14:38:32 CET 2017


OpenBSD supports SO_BINDANY socket option from BSD/OS since 2008.

Thanks,
Florian

Index: doc/unbound.conf.5.in
===================================================================
--- doc/unbound.conf.5.in	(revision 4391)
+++ doc/unbound.conf.5.in	(working copy)
@@ -293,7 +293,8 @@
 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
Index: services/listen_dnsport.c
===================================================================
--- services/listen_dnsport.c	(revision 4391)
+++ services/listen_dnsport.c	(working copy)
@@ -167,7 +167,7 @@
 	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 @@
 #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 @@
 			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 @@
 	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 @@
 #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 @@
 		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 &&

-- 
I'm not entirely sure you are real.