]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Sec 1149] use setsockopt(SO_EXCLUSIVEADDRUSE) on Windows
authorDave Hart <hart@ntp.org>
Tue, 7 Apr 2009 09:14:58 +0000 (09:14 +0000)
committerDave Hart <hart@ntp.org>
Tue, 7 Apr 2009 09:14:58 +0000 (09:14 +0000)
bk: 49db1992GignEwCHB_Qqerf98vrOTQ

ChangeLog
ntpd/ntp_io.c
ports/winnt/libntp/libntp.vcproj

index 26053ea57d7682bc490529c0f47c70ca4ce2c8e6..572cb89bf690d9899243e920bd813157ec943a3b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,8 @@
+---
+* [Sec 1149] use SO_EXCLUSIVEADDRUSE on Windows
+---
 (4.2.4p7-RC1) 2009/03/30 Released by Harlan Stenn <stenn@ntp.org>
+
 * [Bug 1131] UDP sockets should not use SIGPOLL on Solaris.
 * build system email address cleanup
 * [Bug 774] parsesolaris.c does not compile under the new Solaris
index 5f09f72ad30e39c8b951258542169852a9ac4bf8..45bfde9bca32e5a83fd33f40208b82fbbcc4e35f 100644 (file)
@@ -94,7 +94,12 @@ extern const char *specific_interface;
 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) 
 #endif
 
-#endif
+/*
+ * Windows C runtime ioctl() can't deal properly with sockets, 
+ * map to ioctlsocket for this source file.
+ */
+#define ioctl(fd, opt, val)  ioctlsocket((fd), (opt), (u_long *)(val))
+#endif  /* SYS_WINNT */
 
 /*
  * We do asynchronous input using the SIGIO facility.  A number of
@@ -1503,6 +1508,24 @@ create_interface(
        return interface;
 }
 
+
+#ifdef SO_EXCLUSIVEADDRUSE
+static void
+set_excladdruse(int fd)
+{
+       int one = 1;
+       int failed;
+
+       failed = setsockopt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
+                           (char *)&one, sizeof(one));
+
+       if (failed)
+               netsyslog(LOG_ERR, 
+                         "setsockopt(%d, SO_EXCLUSIVEADDRUSE, on): %m", fd);
+}
+#endif  /* SO_EXCLUSIVEADDRUSE */
+
+
 /*
  * set_reuseaddr() - set/clear REUSEADDR on all sockets
  *                     NB possible hole - should we be doing this on broadcast
@@ -1512,6 +1535,8 @@ static void
 set_reuseaddr(int flag) {
        struct interface *interf;
 
+#ifndef SO_EXCLUSIVEADDRUSE
+
        for (interf = ISC_LIST_HEAD(inter_list);
             interf != NULL;
             interf = ISC_LIST_NEXT(interf, link)) {
@@ -1533,6 +1558,7 @@ set_reuseaddr(int flag) {
                        }
                }
        }
+#endif /* ! SO_EXCLUSIVEADDRUSE */
 }
 
 /*
@@ -2064,7 +2090,7 @@ io_multicast_add(
        }
        else
        {
-               delete_interface(interface);  /* re-use existing interface */
+               delete_interface(interface);  /* re-use existing interface */
                interface = NULL;
                if (addr.ss_family == AF_INET)
                        interface = wildipv4;
@@ -2233,12 +2259,7 @@ static void init_nonblocking_io(SOCKET fd)
 #elif defined(FIONBIO)
        {
                int on = 1;
-# if defined(SYS_WINNT)
-
-               if (ioctlsocket(fd,FIONBIO,(u_long *) &on) == SOCKET_ERROR)
-# else
                if (ioctl(fd,FIONBIO,&on) < 0)
-# endif
                {
                        netsyslog(LOG_ERR, "ioctl(FIONBIO) fails on fd #%d: %m",
                                fd);
@@ -2273,8 +2294,14 @@ open_socket(
 {
        int errval;
        SOCKET fd;
-       int on = 1, off = 0;    /* int is OK for REUSEADR per */
-                               /* http://www.kohala.com/start/mcast.api.txt */
+       /*
+        * int is OK for REUSEADR per 
+        * http://www.kohala.com/start/mcast.api.txt
+        */
+       int on = 1;
+#ifndef SO_EXCLUSIVEADDRUSE
+       int off = 0;
+#endif
 #if defined(IPTOS_LOWDELAY) && defined(IPPROTO_IP) && defined(IP_TOS)
        int tos;
 #endif /* IPTOS_LOWDELAY && IPPROTO_IP && IP_TOS */
@@ -2283,26 +2310,21 @@ open_socket(
                return (INVALID_SOCKET);
 
        /* create a datagram (UDP) socket */
+       fd = socket(addr->ss_family, SOCK_DGRAM, 0);
+       if (INVALID_SOCKET == fd) {
 #ifndef SYS_WINNT
-       if (  (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) < 0) {
                errval = errno;
 #else
-       if (  (fd = socket(addr->ss_family, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
                errval = WSAGetLastError();
 #endif
-               if(addr->ss_family == AF_INET)
-                       netsyslog(LOG_ERR, "socket(AF_INET, SOCK_DGRAM, 0) failed on address %s: %m",
-                               stoa(addr));
-               else if(addr->ss_family == AF_INET6)
-                       netsyslog(LOG_ERR, "socket(AF_INET6, SOCK_DGRAM, 0) failed on address %s: %m",
-                               stoa(addr));
-#ifndef SYS_WINNT
-               if (errval == EPROTONOSUPPORT || errval == EAFNOSUPPORT ||
+               netsyslog(LOG_ERR, 
+                         "socket(AF_INET%s, SOCK_DGRAM, 0) failed on address %s: %m",
+                         (addr->ss_family == AF_INET6) ? "6" : "",
+                         stoa(addr));
+
+               if (errval == EPROTONOSUPPORT || 
+                   errval == EAFNOSUPPORT ||
                    errval == EPFNOSUPPORT)
-#else
-               if (errval == WSAEPROTONOSUPPORT || errval == WSAEAFNOSUPPORT ||
-                   errval == WSAEPFNOSUPPORT)
-#endif
                        return (INVALID_SOCKET);
                msyslog(LOG_ERR, "unexpected error code %d (not PROTONOSUPPORT|AFNOSUPPORT|FPNOSUPPORT) - exiting", errval);
                exit(1);
@@ -2321,6 +2343,7 @@ open_socket(
         */
        fd = move_fd(fd);
 
+#ifndef SO_EXCLUSIVEADDRUSE
        /*
         * set SO_REUSEADDR since we will be binding the same port
         * number on each interface according to flag
@@ -2335,6 +2358,14 @@ open_socket(
 
                return INVALID_SOCKET;
        }
+#else  /* SO_EXCLUSIVEADDRUSE defined */
+       /*
+        * setting SO_EXCLUSIVEADDRUSE on the wildcard we open
+        * first will cause more specific binds to fail.
+        */
+       if (!(interf->flags & INT_WILDCARD))
+               set_excladdruse(fd);
+#endif
 
        /*
         * IPv4 specific options go here
@@ -2412,22 +2443,24 @@ open_socket(
                        ) {
                        if (addr->ss_family == AF_INET)
                                netsyslog(LOG_ERR,
-                                         "bind() fd %d, family %d, port %d, addr %s, in_classd=%d flags=0x%x fails: %m",
-                                         fd, addr->ss_family, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
+                                         "bind() fd %d, family AF_INET, port %d, addr %s, in_classd=%d flags=0x%x fails: %m",
+                                         fd, (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
                                          stoa(addr),
-                                         IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), flags);
+                                         IN_CLASSD(ntohl(((struct sockaddr_in*)addr)->sin_addr.s_addr)), 
+                                         flags);
 #ifdef INCLUDE_IPV6_SUPPORT
                        else if (addr->ss_family == AF_INET6)
-                               netsyslog(LOG_ERR,
-                                         "bind() fd %d, family %d, port %d, scope %d, addr %s, in6_is_addr_multicast=%d flags=0x%x fails: %m",
-                                         fd, addr->ss_family, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port),
+                               netsyslog(LOG_ERR,
+                                         "bind() fd %d, family AF_INET6, port %d, scope %d, addr %s, mcast=%d flags=0x%x fails: %m",
+                                         fd, (int)ntohs(((struct sockaddr_in6*)addr)->sin6_port),
 # ifdef ISC_PLATFORM_HAVESCOPEID
                                          ((struct sockaddr_in6*)addr)->sin6_scope_id
 # else
                                          -1
 # endif
                                          , stoa(addr),
-                                         IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), flags);
+                                         IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)addr)->sin6_addr), 
+                                         flags);
 #endif
                }
 
@@ -2458,7 +2491,7 @@ open_socket(
                   addr->ss_family,
                   (int)ntohs(((struct sockaddr_in*)addr)->sin_port),
                   stoa(addr),
-                   flags));
+                  interf->flags));
 
        init_nonblocking_io(fd);
        
index eb80867769b868009233c7c03f4a51af8ec17fe4..6a115348b630a6c57306b3245521d5d67fc01c0e 100644 (file)
                                RelativePath="..\..\..\include\ntp_control.h"
                                >
                        </File>
+                       <File
+                               RelativePath="..\..\..\include\ntp_debug.h"
+                               >
+                       </File>
                        <File
                                RelativePath="..\..\..\include\ntp_fp.h"
                                >