From: Dave Hart Date: Tue, 7 Apr 2009 09:14:58 +0000 (+0000) Subject: [Sec 1149] use setsockopt(SO_EXCLUSIVEADDRUSE) on Windows X-Git-Tag: NTP_4_2_4P7_RC2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=992d6e1849498b7637374e7f6637c89dc7c74a57;p=thirdparty%2Fntp.git [Sec 1149] use setsockopt(SO_EXCLUSIVEADDRUSE) on Windows bk: 49db1992GignEwCHB_Qqerf98vrOTQ --- diff --git a/ChangeLog b/ChangeLog index 26053ea57..572cb89bf 100644 --- 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 + * [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 diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index 5f09f72ad..45bfde9bc 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -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); diff --git a/ports/winnt/libntp/libntp.vcproj b/ports/winnt/libntp/libntp.vcproj index eb8086776..6a115348b 100644 --- a/ports/winnt/libntp/libntp.vcproj +++ b/ports/winnt/libntp/libntp.vcproj @@ -2078,6 +2078,10 @@ RelativePath="..\..\..\include\ntp_control.h" > + +