nanog mailing list archives

Re: DoD IP Space


From: Mark Andrews <marka () isc org>
Date: Mon, 15 Feb 2021 18:01:47 +1100


On 15 Feb 2021, at 17:25, William Herrin <bill () herrin us> wrote:

On Sun, Feb 14, 2021 at 8:27 PM Mark Tinka <mark@tinka.africa> wrote:
Dropping a few feet from cloud nine, there, really, is no other thing
that will facilitate or hold back the adoption of IPv6, like money.

Well actually, that's not entirely true. One thing holding back IPv6
is the unfortunately routine need to turn it off in order to get one
or another IPv4 thing back working again. Like the disney thing
earlier in this thread. Or like my experience yesterday where I had to
disable IPv6 to fetch files on a particular server because SLAAC was
serving up invalid addresses but the app insisted on trying all 8 IPv6
addresses before it would attempt any of the IPv4 addresses. And of
course I can't call my ISP and say: you're causing my Linux box to
pick up bad IPv6 addresses. Front line support can barely handle IPv4
and Windows.

I stuck with it for a couple hours and figured out how to disable
SLAAC without disabling DHCP-PD so that I could turn IPv6 back on with
addresses which worked. But really, how many people are going to do
that? Most tick the IPv6 checkbox to off and are done with it.

This particular problem could be quickly resolved if the OSes still
getting updates were updated to default name resolution to prioritize
the IPv4 addresses instead. That would allow broken IPv6
configurations to exist without breaking the user's entire Internet
experience. Which would allow them to leave it turned on so that it
resumes working when the error is eventually found and fixed.

Prioritizing IPv6 over IPv4 for newly initiated connections is one of
the trifecta of critical design errors that have been killing IPv6 for
two decades. One of the two that if key folks weren't being so
bull-headed about it, it would be trivial to fix.

Complain to your vendors about not implementing RFC 8305, RFC 6724, and
RFC 7078.  RFC 8305 or RFC6724 + RFC 7078 would fix your issue.

Thats Happy Eyeballs and tuneable address selection rules.

You don’t have to perform the naive connection from getaddrinfo() man page.

           struct addrinfo hints, *res, *res0;
           int error;
           int s;
           const char *cause = NULL;

           memset(&hints, 0, sizeof(hints));
           hints.ai_family = PF_UNSPEC;
           hints.ai_socktype = SOCK_STREAM;
           error = getaddrinfo("www.kame.net", "http", &hints, &res0);
           if (error) {
                   errx(1, "%s", gai_strerror(error));
                   /*NOTREACHED*/
           }
           s = -1;
           for (res = res0; res; res = res->ai_next) {
                   s = socket(res->ai_family, res->ai_socktype,
                       res->ai_protocol);
                   if (s < 0) {
                           cause = "socket";
                           continue;
                   }

                   if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
                           cause = "connect";
                           close(s);
                           s = -1;
                           continue;
                   }

                   break;  /* okay we got one */
           }
           if (s < 0) {
                   err(1, "%s", cause);
                   /*NOTREACHED*/
           }
           freeaddrinfo(res0);

You could actually use something a little more sophisticated like

int
connect_to_host(struct addrinfo *res0) {
        struct addrinfo *res;
        int fd = -1, n, i, j, flags, count;
        struct pollfd *fds;
        int timeout = TIMEOUT;

        /*
         * Work out how many possible descriptors we could use.
         */
        for (res = res0, count = 0; res; res = res->ai_next)
                count++;
        fds = calloc(count, sizeof(*fds));
        if (fds == NULL) {
                perror("calloc");
                goto cleanup;
        }

        for (res = res0, i = 0, count = 0; res; res = res->ai_next) {
                fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
                if (fd == -1) {
                        /*
                         * If AI_ADDRCONFIG is not supported we will get
                         * EAFNOSUPPORT returned.  Behave as if the address
                         * was not there.
                         */
                        if (errno != EAFNOSUPPORT)
                                perror("socket");
                        else if (res->ai_next != NULL)
                                continue;
                } else if ((flags = fcntl(fd, F_GETFL)) == -1) {
                        perror("fcntl");
                        close(fd);
                } else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
                        perror("fcntl");
                        close(fd);
                } else if (connect(fd, res->ai_addr, res->ai_addrlen) == -1) {
                        if (errno != EINPROGRESS) {
                                perror("connect");
                                close(fd);
                        } else {
                                /*
                                 * Record the information for this descriptor.
                                 */
                                fds[i].fd = fd;
                                fds[i].events = POLLERR | POLLHUP |
                                                POLLIN | POLLOUT;
                                count++;
                                i++;
                        }
                } else  {
                        /*
                         * We connected without blocking.
                         */
                        goto done;
                }

                if (count == 0)
                        continue;

                do {
                        if (res->ai_next == NULL)
                                timeout = -1;

                        n = poll(fds, i, timeout);
                        if (n == 0) {
                                timeout >>= 1;
                                break;
                        }
                        if (n < 0) {
                                if (errno == EAGAIN || errno == EINTR)
                                        continue;
                                perror("poll");
                                fd = -1;
                                goto done;
                        }
                        for (j = 0; j < i; j++) {
                                if (fds[j].fd == -1 || fds[j].events == 0 ||
                                    fds[j].revents == 0)
                                        continue;
                                fd = fds[j].fd;
                                if (fds[j].revents & POLLHUP) {
                                        close(fd);
                                        fds[j].fd = -1;
                                        fds[j].events = 0;
                                        count--;
                                        continue;
                                }
                                /* Connect succeeded. */
                                goto done;
                        }
                } while (timeout == -1 && count != 0);
        }

        /* We failed to connect. */
        fd = -1;

 done:
        /* Close all other descriptors we have created. */
        for (j = 0; j < i; j++)
                if (fds[j].fd != fd && fds[j].fd != -1) {
                        close(fds[j].fd);
                }

        if (fd != -1) {
                /* Restore default blocking behaviour.  */
                if ((flags = fcntl(fd, F_GETFL)) != -1) {
                        flags &= ~O_NONBLOCK;
                        if (fcntl(fd, F_SETFL, flags) == -1)
                                perror("fcntl");
                } else
                        perror("fcntl");
        }

 cleanup:
        /* Free everything. */
        if (fds != NULL) free(fds);

        return (fd);
}

See https://users.isc.org/~marka/

Mark

Regards,
Bill Herrin

--
William Herrin
bill () herrin us
https://bill.herrin.us/

-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742              INTERNET: marka () isc org


Current thread: