> 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