diff -Nur ntp-stable-4.2.0a-20040617/ntpdate/ntpdate.c ntp-stable-4.2.0a-20050303/ntpdate/ntpdate.c --- ntp-stable-4.2.0a-20040617/ntpdate/ntpdate.c 2004-05-25 13:02:25.000000000 +0200 +++ ntp-stable-4.2.0a-20050303/ntpdate/ntpdate.c 2005-03-03 12:01:15.000000000 +0100 @@ -1321,6 +1321,30 @@ } +/* + * is_unreachable - check to see if we have a route to given destination + * (non-blocking). + */ +static int +is_reachable (struct sockaddr_storage *dst) +{ + SOCKET sockfd; + + sockfd = socket(dst->ss_family, SOCK_DGRAM, 0); + if (sockfd == -1) { + return 0; + } + + if(connect(sockfd, (struct sockaddr *)dst, SOCKLEN(dst))) { + closesocket(sockfd); + return 0; + } + closesocket(sockfd); + return 1; +} + + + /* XXX ELIMINATE: merge BIG slew into adj_systime in lib/systime.c */ /* * addserver - determine a server's address and allocate a new structure @@ -1333,7 +1357,7 @@ { register struct server *server; /* Address infos structure to store result of getaddrinfo */ - struct addrinfo *addrResult; + struct addrinfo *addrResult, *ptr; /* Address infos structure to store hints for getaddrinfo */ struct addrinfo hints; /* Error variable for getaddrinfo */ @@ -1364,22 +1388,28 @@ } #endif - server = (struct server *)emalloc(sizeof(struct server)); - memset((char *)server, 0, sizeof(struct server)); - - /* For now we only get the first returned server of the addrinfo list */ - memset(&(server->srcadr), 0, sizeof(struct sockaddr_storage)); - memcpy(&(server->srcadr), addrResult->ai_addr, addrResult->ai_addrlen); - server->event_time = ++sys_numservers; - if (sys_servers == NULL) - sys_servers = server; - else { - struct server *sp; - - for (sp = sys_servers; sp->next_server != NULL; - sp = sp->next_server) ; - sp->next_server = server; + /* We must get all returned server in case the first one fails */ + for (ptr = addrResult; ptr != NULL; ptr = ptr->ai_next) { + if (is_reachable ((struct sockaddr_storage *)ptr->ai_addr)) { + server = (struct server *)emalloc(sizeof(struct server)); + memset((char *)server, 0, sizeof(struct server)); + + memset(&(server->srcadr), 0, sizeof(struct sockaddr_storage)); + memcpy(&(server->srcadr), ptr->ai_addr, ptr->ai_addrlen); + server->event_time = ++sys_numservers; + if (sys_servers == NULL) + sys_servers = server; + else { + struct server *sp; + + for (sp = sys_servers; sp->next_server != NULL; + sp = sp->next_server) ; + sp->next_server = server; + } + } } + + freeaddrinfo(addrResult); }