]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 1191] ntpd fails on Win2000 - "Address already in use" after fix
authorDave Hart <hart@ntp.org>
Sun, 17 May 2009 08:59:06 +0000 (08:59 +0000)
committerDave Hart <hart@ntp.org>
Sun, 17 May 2009 08:59:06 +0000 (08:59 +0000)
for [Sec 1149].

bk: 4a0fd1daqa4sC0jBInI2CXiO6aA-Cw

ChangeLog
ntpd/ntp_io.c

index f098ab6273762a1d117b388228f1a701d99aca1c..741178c49f326816110807a01f88f18bc00ea2e0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
 ---
+
+* [Bug 1191] ntpd fails on Win2000 - "Address already in use" after fix
+  for [Sec 1149].
+
+---
 (4.2.4p7-RC7) 2009/05/12 Released by Harlan Stenn <stenn@ntp.org>
 
 * ntp.isc.org -> ntp.org cleanup.
index 102c22484d720e78121e6ab97f13d8a945cc6fe0..5cf9f1d858d4a47df891863e9013c1074126f8ca 100644 (file)
@@ -294,23 +294,29 @@ static inline int     read_refclock_packet        P((SOCKET, struct refclockio *, l_fp)
  * systems are not affected by this and work correctly.
  * See Microsoft Knowledge Base Article Q263823 for details of this.
  */
-isc_result_t
-connection_reset_fix(SOCKET fd) {
+void
+connection_reset_fix(
+       SOCKET fd,
+       struct sockaddr_storage *addr
+       )
+{
        DWORD dwBytesReturned = 0;
        BOOL  bNewBehavior = FALSE;
        DWORD status;
 
-       if(isc_win32os_majorversion() < 5)
-               return (ISC_R_SUCCESS); /*  NT 4.0 has no problem */
-
-       /* disable bad behavior using IOCTL: SIO_UDP_CONNRESET */
-       status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,
-                         sizeof(bNewBehavior), NULL, 0,
-                         &dwBytesReturned, NULL, NULL);
-       if (status != SOCKET_ERROR)
-               return (ISC_R_SUCCESS);
-       else
-               return (ISC_R_UNEXPECTED);
+       /*
+        * disable bad behavior using IOCTL: SIO_UDP_CONNRESET
+        * NT 4.0 has no problem
+        */
+       if (isc_win32os_majorversion() >= 5) {
+               status = WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior,
+                                 sizeof(bNewBehavior), NULL, 0,
+                                 &dwBytesReturned, NULL, NULL);
+               if (SOCKET_ERROR == status)
+                       netsyslog(LOG_ERR, "connection_reset_fix() "
+                                          "failed for address %s: %m", 
+                                          stoa(addr));
+       }
 }
 #endif
 
@@ -2317,9 +2323,8 @@ open_socket(
         * 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 */
@@ -2348,35 +2353,41 @@ open_socket(
                exit(1);
                /*NOTREACHED*/
        }
-#ifdef SYS_WINNT
-       if (connection_reset_fix(fd) != ISC_R_SUCCESS) {
-               netsyslog(LOG_ERR, "connection_reset_fix(fd) failed on address %s: %m",
-                       stoa(addr));
-       }
-#endif /* SYS_WINNT */
 
+#ifdef SYS_WINNT
+       connection_reset_fix(fd, addr);
+#endif
        /*
         * Fixup the file descriptor for some systems
         * See bug #530 for details of the issue.
         */
        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
+        * number on each interface according to turn_off_reuse.
+        * This is undesirable on Windows versions starting with
+        * Windows XP (numeric version 5.1).
         */
-       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
-                      turn_off_reuse ? (char *)&off : (char *)&on, sizeof(on)))
-       {
-               netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR %s on fails on address %s: %m",
-                       turn_off_reuse ? "off" : "on", stoa(addr));
-
-               closesocket(fd);
-
-               return INVALID_SOCKET;
-       }
-#else  /* SO_EXCLUSIVEADDRUSE defined */
+#ifdef SYS_WINNT
+       if (isc_win32os_versioncheck(5, 1, 0, 0) < 0)  /* before 5.1 */
+#endif
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+                              (char *)(turn_off_reuse 
+                                       ? &off 
+                                       : &on), 
+                              sizeof(on))) {
+
+                       netsyslog(LOG_ERR, "setsockopt SO_REUSEADDR %s"
+                                          " fails for address %s: %m",
+                                          turn_off_reuse 
+                                               ? "off" 
+                                               : "on", 
+                                          stoa(addr));
+                       closesocket(fd);
+                       return INVALID_SOCKET;
+               }
+#ifdef SO_EXCLUSIVEADDRUSE
        /*
         * setting SO_EXCLUSIVEADDRUSE on the wildcard we open
         * first will cause more specific binds to fail.