]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2146. [cleanup] Silence Linux's spurious "obsolete setsockopt
authorMark Andrews <marka@isc.org>
Mon, 26 Feb 2007 01:45:09 +0000 (01:45 +0000)
committerMark Andrews <marka@isc.org>
Mon, 26 Feb 2007 01:45:09 +0000 (01:45 +0000)
                        SO_BSDCOMPAT" message. [RT #16641]

CHANGES
lib/isc/unix/socket.c

diff --git a/CHANGES b/CHANGES
index d2e97854a0b34bc59355dadcd16c0e4d298b6a1c..aebe8de6bea19ff57a9ee079eec4c5013cf1825f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2146.  [cleanup]       Silence Linux's spurious "obsolete setsockopt
+                       SO_BSDCOMPAT" message. [RT #16641]
+
 2145.  [bug]           Check DS/DLV digest lengths for known digests.
                        [RT #16622]
 
index f95e3c8f75d4104a4e87bca38a472a1ab0249b4e..7c161aa1c835f363be33ab1d0ca94ed289140dfc 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.207.2.19.2.26 2006/05/19 02:53:36 marka Exp $ */
+/* $Id: socket.c,v 1.207.2.19.2.27 2007/02/26 01:45:09 marka Exp $ */
 
 #include <config.h>
 
@@ -42,6 +42,7 @@
 #include <isc/msgs.h>
 #include <isc/mutex.h>
 #include <isc/net.h>
+#include <isc/once.h>
 #include <isc/platform.h>
 #include <isc/print.h>
 #include <isc/region.h>
 #include "socket_p.h"
 #endif /* ISC_PLATFORM_USETHREADS */
 
+#if defined(SO_BSDCOMPAT) && defined(__linux__)
+#include <sys/utsname.h>
+#endif
+
 /*
  * Some systems define the socket length argument as an int, some as size_t,
  * some as socklen_t.  This is here so it can be easily changed if needed.
@@ -1368,7 +1373,45 @@ free_socket(isc_socket_t **socketp) {
        *socketp = NULL;
 }
 
+#ifdef SO_BSDCOMPAT
 /*
+ * This really should not be necessary to do.  Having to workout
+ * which kernel version we are on at run time so that we don't cause
+ * the kernel to issue a warning about us using a deprecated socket option.
+ * Such warnings should *never* be on by default in production kernels.
+ *
+ * We can't do this a build time because executables are moved between
+ * machines and hence kernels.
+ *
+ * We can't just not set SO_BSDCOMAT because some kernels require it.
+ */
+
+static isc_once_t         bsdcompat_once = ISC_ONCE_INIT;
+isc_boolean_t bsdcompat = ISC_TRUE;
+
+static void
+clear_bsdcompat(void) {
+#ifdef __linux__
+        struct utsname buf;
+        char *endp;
+        long int major;
+        long int minor;
+
+        uname(&buf);    /* Can only fail if buf is bad in Linux. */
+
+        /* Paranoia in parsing can be increased, but we trust uname(). */
+        major = strtol(buf.release, &endp, 10);
+        if (*endp == '.') {
+               minor = strtol(endp+1, &endp, 10);
+               if ((major > 2) || ((major == 2) && (minor >= 4))) {
+                       bsdcompat = ISC_FALSE;
+               }
+        }
+#endif /* __linux __ */
+}
+#endif
+
+/*%
  * Create a new 'type' socket managed by 'manager'.  Events
  * will be posted to 'task' and when dispatched 'action' will be
  * called with 'arg' as the arg value.  The new socket is returned
@@ -1468,8 +1511,10 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
        }
 
 #ifdef SO_BSDCOMPAT
-       if (setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT,
-                      (void *)&on, sizeof(on)) < 0) {
+       RUNTIME_CHECK(isc_once_do(&bsdcompat_once,
+                                 clear_bsdcompat) == ISC_R_SUCCESS);
+       if (bsdcompat && setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT,
+                                   (void *)&on, sizeof(on)) < 0) {
                isc__strerror(errno, strbuf, sizeof(strbuf));
                UNEXPECTED_ERROR(__FILE__, __LINE__,
                                 "setsockopt(%d, SO_BSDCOMPAT) %s: %s",