In message <6CF0E212-C5F0-419F-87F1-1D8937C99E27@xxxxxxxxxxxxxxx>, David Conrad writes: > On Jun 24, 2010, at 4:48 PM, Mark Andrews wrote: > > The third choice is to do a non-blocking connect to IPv6 then if that = > does > > not succeed in 1 or 2 seconds (most successful connects are within = > this > > peroid but connect failures are considerably longer) initiate a non = > blocking > > IPv4 connection and keep whichever completes first and abort the = > other. > > That sounds like a variation of the v6-then-v4 serial case, just = > slightly accelerated. But maybe I'm missing something... This starts out as serial but finishes as parallel. You don't hammer the server initially but you don't wait a long time either if one of the addresses is unreachable. You can adjust the rate at which you try new addresses. Mark fdset set1, set2; struct timeval timeout = { 1, 0 }; /* 1 second */ int fd = -1, min = -1, max = -1; int active = 0; struct addrinfo *res0 = NULL, res0; getaddrinfo(...., &res0): res = res0; while (res != NULL || active > 0) { int r; if (res != NULL) { int tmpfd = socket(); makenonblocking(tmpfd); connect(tmpfd); if (tmpfd < min || min == -1) min = tmpfd; if (tmpfd > max || max == -1) max = tmpfd; FD_SET(tmpfd, set1); res = res->ai_next active++; } set2 = set1; r = select(NULL, &set2, NULL, (res == NULL) ? NULL : &timeout); if (r == 0) { /* adjust the next timeout here if you want */ continue; } if (r > 0) { int i; for (i = min; i <= max; i++) { if (FD_ISSET(i, set2)) { if (success) { fd = i; close other fds; goto done; } /* Connect failed. */ close(i); FD_CLR(i, &set1); active--; } } continue; } /* handle errors */ } done: freeaddrinfo(res0); return fd; > Regards, > -drc -- Mark Andrews, ISC 1 Seymour St., Dundas Valley, NSW 2117, Australia PHONE: +61 2 9871 4742 INTERNET: marka@xxxxxxx _______________________________________________ Ietf mailing list Ietf@xxxxxxxx https://www.ietf.org/mailman/listinfo/ietf