lib/fetch: remember if ipv6 or ipv4 are unreachable and don't try to connect again

This commit is contained in:
Duncaen 2019-06-19 23:07:11 +02:00 committed by Duncan Overbruck
parent 3527a1374a
commit a3af0e5559

View File

@ -449,9 +449,12 @@ fetch_socks5(conn_t *conn, struct url *url, struct url *socks, int verbose)
* close all sockets and return -1 and set errno to * close all sockets and return -1 and set errno to
* `ETIMEDOUT`. * `ETIMEDOUT`.
*/ */
#define UNREACH_IPV6 0x01
#define UNREACH_IPV4 0x10
static int static int
happy_eyeballs_connect(struct addrinfo *res0) happy_eyeballs_connect(struct addrinfo *res0)
{ {
static int unreach = 0;
struct pollfd *pfd; struct pollfd *pfd;
struct addrinfo *res; struct addrinfo *res;
const char *bindaddr; const char *bindaddr;
@ -484,6 +487,14 @@ happy_eyeballs_connect(struct addrinfo *res0)
if (getenv("FORCE_IPV6")) if (getenv("FORCE_IPV6"))
i4 = n4; i4 = n4;
if (unreach & UNREACH_IPV6)
i6 = n6;
if (unreach & UNREACH_IPV4)
i4 = n4;
if (i6+i4 == n6+n4)
goto error;
res = NULL; res = NULL;
for (;;) { for (;;) {
int sd = -1; int sd = -1;
@ -548,24 +559,25 @@ happy_eyeballs_connect(struct addrinfo *res0)
continue; continue;
} }
#ifdef FULL_DEBUG
{ {
char hbuf[1025]; char hbuf[1025];
if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), NULL, if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), NULL,
0, NI_NUMERICHOST) == 0) 0, NI_NUMERICHOST) == 0)
fetch_info("connecting to %s", hbuf); fetch_info("connecting to %s", hbuf);
} }
#endif
if (connect(sd, res->ai_addr, res->ai_addrlen) == -1) { if (connect(sd, res->ai_addr, res->ai_addrlen) == -1) {
if (errno == EINPROGRESS) { if (errno == EINPROGRESS) {
pfd[attempts].fd = sd; pfd[attempts].fd = sd;
} else if (errno == ENETUNREACH) { } else if (errno == ENETUNREACH) {
close(sd); close(sd);
if (family == AF_INET) if (family == AF_INET) {
i4 = n4; i4 = n4;
else unreach |= UNREACH_IPV4;
} else {
i6 = n6; i6 = n6;
unreach |= UNREACH_IPV6;
}
continue; continue;
} else { } else {
err = errno; err = errno;