In message <6CF0E212-C5F0-419F-87F1-1D8937C99E27(_at_)virtualized(_dot_)org>,
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(_at_)isc(_dot_)org
_______________________________________________
Ietf mailing list
Ietf(_at_)ietf(_dot_)org
https://www.ietf.org/mailman/listinfo/ietf