From: Dave Hart Date: Fri, 8 May 2009 15:34:46 +0000 (+0000) Subject: Do not exceed FD_SETSIZE in ntp_intres.c X-Git-Tag: NTP_4_2_4P7_RC7~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5d737f4a3d738019f22df0f7b701b63ddb34409;p=thirdparty%2Fntp.git Do not exceed FD_SETSIZE in ntp_intres.c --- ntp_intres.c: typo --- ntp_intres.c: missing comma typo --- ntp_intres.c: typo bk: 4a045116_F1LbEo0bHS3DmPFgjZduA --- diff --git a/ntpd/ntp_intres.c b/ntpd/ntp_intres.c index ffa7e14d1..b698facf2 100644 --- a/ntpd/ntp_intres.c +++ b/ntpd/ntp_intres.c @@ -479,7 +479,7 @@ findhostaddr( if (entry->ce_name) { DPRINTF(2, ("findhostaddr: Resolving <%s>\n", - entry->ce_name); + entry->ce_name)); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; @@ -531,7 +531,7 @@ findhostaddr( case EAI_FAIL: again = 1; - break + break; case EAI_AGAIN: again = 1; @@ -542,22 +542,22 @@ findhostaddr( #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) case EAI_NODATA: #endif - msyslog(LOG_ERR, "host name not found %s%s: %s", - (EAI_NONAME == error) ? "EAI_NONAME" : "EAI_NODATA", + msyslog(LOG_ERR, "host name not found%s%s: %s", + (EAI_NONAME == error) ? "" : " EAI_NODATA", (eai_again_seen) ? " (permanent)" : "", entry->ce_name); again = !eai_again_seen; break; #ifdef EAI_SYSTEM - case EAI_SYSTEM + case EAI_SYSTEM: /* * EAI_SYSTEM means the real error is in errno. We should be more * discriminating about which errno values require retrying, but * this matches existing behavior. */ again = 1; - DPRINTF(1, ("intres: EAI_SYSTEM errno %d (%s) means try again, right?\n" + DPRINTF(1, ("intres: EAI_SYSTEM errno %d (%s) means try again, right?\n", errno, strerror(errno))); break; #endif @@ -577,12 +577,14 @@ findhostaddr( static void openntp(void) { - struct addrinfo hints; - struct addrinfo *addrResult; - const char *localhost = "127.0.0.1"; /* Use IPv6 loopback */ + const char *localhost = "127.0.0.1"; /* Use IPv4 loopback */ + struct addrinfo hints; + struct addrinfo *addr; + u_long on; + int err; if (sockfd != INVALID_SOCKET) - return; + return; memset(&hints, 0, sizeof(hints)); @@ -590,52 +592,81 @@ openntp(void) * For now only bother with IPv4 */ hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; - if (getaddrinfo(localhost, "ntp", &hints, &addrResult)!=0) { - msyslog(LOG_ERR, "getaddrinfo failed: %m"); + + err = getaddrinfo(localhost, "ntp", &hints, &addr); + + if (err) { +#ifdef EAI_SYSTEM + if (EAI_SYSTEM == err) + msyslog(LOG_ERR, "getaddrinfo(%s) failed: %m", + localhost); + else +#endif + msyslog(LOG_ERR, "getaddrinfo(%s) failed: %s", + localhost, gai_strerror(err)); resolver_exit(1); } - sockfd = socket(addrResult->ai_family, addrResult->ai_socktype, 0); - if (sockfd == -1) { + sockfd = socket(addr->ai_family, addr->ai_socktype, 0); + + if (INVALID_SOCKET == sockfd) { msyslog(LOG_ERR, "socket() failed: %m"); resolver_exit(1); } +#ifndef SYS_WINNT + /* + * On Windows only the count of sockets must be less than + * FD_SETSIZE. On Unix each descriptor's value must be less + * than FD_SETSIZE, as fd_set is a bit array. + */ + if (sockfd >= FD_SETSIZE) { + msyslog(LOG_ERR, "socket fd %d too large, FD_SETSIZE %d", + (int)sockfd, FD_SETSIZE); + resolver_exit(1); + } + /* * Make the socket non-blocking. We'll wait with select() + * Unix: fcntl(O_NONBLOCK) or fcntl(FNDELAY) */ -#ifndef SYS_WINNT -#if defined(O_NONBLOCK) +# ifdef O_NONBLOCK if (fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) { msyslog(LOG_ERR, "fcntl(O_NONBLOCK) failed: %m"); resolver_exit(1); } -#else -#if defined(FNDELAY) +# else +# ifdef FNDELAY if (fcntl(sockfd, F_SETFL, FNDELAY) == -1) { msyslog(LOG_ERR, "fcntl(FNDELAY) failed: %m"); resolver_exit(1); } -#else -# include "Bletch: NEED NON BLOCKING IO" -#endif /* FNDDELAY */ -#endif /* O_NONBLOCK */ -#else /* SYS_WINNT */ - { - int on = 1; - if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) { - msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m"); - resolver_exit(1); /* Windows NT - set socket in non-blocking mode */ - } +# else +# include "Bletch: NEED NON BLOCKING IO" +# endif /* FNDDELAY */ +# endif /* O_NONBLOCK */ + (void)on; /* quiet unused warning */ +#else /* !SYS_WINNT above */ + /* + * Make the socket non-blocking. We'll wait with select() + * Windows: ioctlsocket(FIONBIO) + */ + on = 1; + err = ioctlsocket(sockfd, FIONBIO, &on); + if (SOCKET_ERROR == err) { + msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m"); + resolver_exit(1); } #endif /* SYS_WINNT */ - if (connect(sockfd, addrResult->ai_addr, addrResult->ai_addrlen) == -1) { + + err = connect(sockfd, addr->ai_addr, addr->ai_addrlen); + if (SOCKET_ERROR == err) { msyslog(LOG_ERR, "openntp: connect() failed: %m"); resolver_exit(1); } - freeaddrinfo(addrResult); + + freeaddrinfo(addr); } @@ -662,7 +693,7 @@ request( checkparent(); /* make sure our guy is still running */ if (sockfd == INVALID_SOCKET) - openntp(); + openntp(); #ifdef SYS_WINNT hReadWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL); diff --git a/ntpd/ntp_request.c b/ntpd/ntp_request.c index b1bc99d6f..2af0f0bce 100644 --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -496,10 +496,10 @@ process_private( */ temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize); if ((temp_size != proc->sizeofitem && - temp_size != proc->v6_sizeofitem) && + temp_size != proc->v6_sizeofitem) && !(inpkt->implementation == IMPL_XNTPD && - inpkt->request == REQ_CONFIG && - temp_size == sizeof(struct old_conf_peer))) { + inpkt->request == REQ_CONFIG && + temp_size == sizeof(struct old_conf_peer))) { #ifdef DEBUG if (debug > 2) printf("process_private: wrong item size, received %d, should be %d or %d\n", @@ -1319,6 +1319,7 @@ do_conf( struct req_pkt *inpkt ) { + static u_long soonest_ifrescan_time = 0; int items; u_int fl; struct conf_peer *cp; @@ -1412,6 +1413,23 @@ do_conf( req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); return; } + + /* + * ntp_intres.c uses REQ_CONFIG/doconf() to add each + * server after its name is resolved. If we have been + * disconnected from the network, it may notice the + * network has returned and add the first server while + * the relevant interface is still disabled, awaiting + * the next interface rescan. To get things moving + * more quickly, trigger an interface scan now, except + * if we have done so in the last half minute. + */ + if (soonest_ifrescan_time < current_time) { + soonest_ifrescan_time = current_time + 30; + timer_interfacetimeout(current_time); + DPRINTF(1, ("do_conf triggering interface rescan\n")); + } + cp = (struct conf_peer *) ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); } diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index fb6de702a..812206ad2 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -343,12 +343,10 @@ timer(void) * interface update timer */ if (interface_interval && interface_timer <= current_time) { + timer_interfacetimeout(current_time + interface_interval); -#ifdef DEBUG - if (debug) - printf("timer: interface update\n"); -#endif - interface_update(NULL, NULL); + DPRINTF(1, ("timer: interface update\n")); + interface_update(NULL, NULL); } /* diff --git a/ports/winnt/include/config.h b/ports/winnt/include/config.h index c8667efce..c0ef7787f 100644 --- a/ports/winnt/include/config.h +++ b/ports/winnt/include/config.h @@ -145,17 +145,11 @@ typedef int socklen_t; /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 -/* - * FORCE_DNSRETRY will allow associations to come up later - * if DNS isn't available at first. See bug #1117. - */ -#define FORCE_DNSRETRY 1 - -#define OPEN_BCAST_SOCKET 1 /* for ntp_io.c */ -#define TYPEOF_IP_MULTICAST_LOOP BOOL -#define SETSOCKOPT_ARG_CAST (const char *) +#define OPEN_BCAST_SOCKET 1 /* for ntp_io.c */ +#define TYPEOF_IP_MULTICAST_LOOP BOOL +#define SETSOCKOPT_ARG_CAST (const char *) #define HAVE_RANDOM -#define MAXHOSTNAMELEN 64 +#define MAXHOSTNAMELEN 64 #define AUTOKEY /*