lib/fetch: fix happy eyeballs without any usable addresses and catch more errors
This commit is contained in:
parent
8018833010
commit
104e8393f3
@ -488,19 +488,28 @@ happy_eyeballs_connect(struct addrinfo *res0)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
int sd = -1;
|
int sd = -1;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned short family;
|
unsigned short family = 0;
|
||||||
|
|
||||||
#ifdef FULL_DEBUG
|
#ifdef FULL_DEBUG
|
||||||
fetch_info("happy eyeballs state: i4=%u n4=%u i6=%u n6=%u", i4, n4, i6, n6);
|
fetch_info("happy eyeballs state: i4=%u n4=%u i6=%u n6=%u"
|
||||||
|
" attempts=%u waiting=%u", i4, n4, i6, n6, attempts, waiting);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (res == NULL) {
|
if (i6+i4 < n6+n4) {
|
||||||
/* prefer ipv6 */
|
/* first round when res == NULL, prefer ipv6 */
|
||||||
family = i6+1 < n6 ? AF_INET6 : AF_INET;
|
if (res == NULL || res->ai_family == AF_INET) {
|
||||||
} else if (i4+1 < n4) {
|
/* prefer ipv6 */
|
||||||
family = res->ai_family == AF_INET && i6+1 < n6 ? AF_INET6 : AF_INET;
|
if (i6 < n6)
|
||||||
} else if (i6+1 < n6) {
|
family = AF_INET6;
|
||||||
family = res->ai_family == AF_INET6 && i4+1 < n4 ? AF_INET : AF_INET6;
|
else if (i4 < n4)
|
||||||
|
family = AF_INET;
|
||||||
|
} else {
|
||||||
|
/* prefer ipv4 */
|
||||||
|
if (i4 < n4)
|
||||||
|
family = AF_INET;
|
||||||
|
else if (i6 < n6)
|
||||||
|
family = AF_INET6;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* no more connections to try */
|
/* no more connections to try */
|
||||||
#ifdef FULL_DEBUG
|
#ifdef FULL_DEBUG
|
||||||
@ -511,6 +520,7 @@ happy_eyeballs_connect(struct addrinfo *res0)
|
|||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (i = 0, res = res0; res; res = res->ai_next) {
|
for (i = 0, res = res0; res; res = res->ai_next) {
|
||||||
if (res->ai_family == family) {
|
if (res->ai_family == family) {
|
||||||
if (family == AF_INET && i == i4) {
|
if (family == AF_INET && i == i4) {
|
||||||
@ -524,6 +534,8 @@ happy_eyeballs_connect(struct addrinfo *res0)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (res == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if ((sd = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK,
|
if ((sd = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK,
|
||||||
res->ai_protocol)) == -1)
|
res->ai_protocol)) == -1)
|
||||||
@ -570,6 +582,11 @@ happy_eyeballs_connect(struct addrinfo *res0)
|
|||||||
attempts++;
|
attempts++;
|
||||||
waiting++;
|
waiting++;
|
||||||
wait:
|
wait:
|
||||||
|
if (!attempts) {
|
||||||
|
error:
|
||||||
|
netdb_seterr(EAI_FAIL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
for (i = 0; i < attempts; i++) {
|
for (i = 0; i < attempts; i++) {
|
||||||
pfd[i].revents = pfd[i].events = 0;
|
pfd[i].revents = pfd[i].events = 0;
|
||||||
if (pfd[i].fd != -1)
|
if (pfd[i].fd != -1)
|
||||||
@ -621,8 +638,8 @@ wait:
|
|||||||
rv = -1;
|
rv = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((errno = err))
|
||||||
errno = err;
|
fetch_syserr();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,10 +692,8 @@ fetch_connect(struct url *url, int af, int verbose)
|
|||||||
|
|
||||||
sd = happy_eyeballs_connect(res0);
|
sd = happy_eyeballs_connect(res0);
|
||||||
freeaddrinfo(res0);
|
freeaddrinfo(res0);
|
||||||
if (sd == -1) {
|
if (sd == -1)
|
||||||
fetch_syserr();
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
|
||||||
|
|
||||||
if ((conn = fetch_reopen(sd)) == NULL) {
|
if ((conn = fetch_reopen(sd)) == NULL) {
|
||||||
fetch_syserr();
|
fetch_syserr();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user