}
+/*
+ * 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
{
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 */
}
#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);
}