> On 15 Feb 2021, at 17:25, William Herrin <b...@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 > b...@herrin.us > https://bill.herrin.us/ -- Mark Andrews, ISC 1 Seymour St., Dundas Valley, NSW 2117, Australia PHONE: +61 2 9871 4742 INTERNET: ma...@isc.org