ietf
[Top] [All Lists]

Re: The IPv6 Transitional Preference Problem

2010-06-24 19:41:21

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