]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 389] Fix from Remi Demis-Courmont, via Loic Minier (http://bugs.debian.org/293793
authorHarlan Stenn <stenn@ntp.org>
Wed, 2 Mar 2005 21:18:07 +0000 (16:18 -0500)
committerHarlan Stenn <stenn@ntp.org>
Wed, 2 Mar 2005 21:18:07 +0000 (16:18 -0500)
bk: 42262d8fH2lVb1ZYI2YAIe5BLM-BqQ

ntpdate/ntpdate.c

index 0408d74724cc15994642b4c5476b9099298b52c7..9ce701b042339fcba90dfeeea92fce32532f8858 100644 (file)
@@ -1321,6 +1321,30 @@ clock_adjust(void)
 }
 
 
+/*
+ * 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 @@ addserver(
 {
        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 @@ addserver(
        }
 #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;
+       /* 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;
+                               for (sp = sys_servers; sp->next_server != NULL;
+                                    sp = sp->next_server) ;
+                               sp->next_server = server;
+                       }
+               }
        }
+
+       freeaddrinfo(addrResult);
 }