diff options
Diffstat (limited to 'src/network/getaddrinfo.c')
-rw-r--r-- | src/network/getaddrinfo.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c index 5ae8cbfb..64ad259a 100644 --- a/src/network/getaddrinfo.c +++ b/src/network/getaddrinfo.c @@ -16,6 +16,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru char canon[256], *outcanon; int nservs, naddrs, nais, canon_len, i, j, k; int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0; + int no_family = 0; struct aibuf *out; if (!host && !serv) return EAI_NONAME; @@ -66,9 +67,11 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &cs); int r = connect(s, ta[i], tl[i]); + int saved_errno = errno; pthread_setcancelstate(cs, 0); close(s); if (!r) continue; + errno = saved_errno; } switch (errno) { case EADDRNOTAVAIL: @@ -80,7 +83,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru default: return EAI_SYSTEM; } - if (family == tf[i]) return EAI_NONAME; + if (family == tf[i]) no_family = 1; family = tf[1-i]; } } @@ -91,6 +94,8 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru naddrs = __lookup_name(addrs, canon, host, family, flags); if (naddrs < 0) return naddrs; + if (no_family) return EAI_NODATA; + nais = nservs * naddrs; canon_len = strlen(canon); out = calloc(1, nais * sizeof(*out) + canon_len + 1); @@ -104,7 +109,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru } for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++, k++) { - out[k].slot = i; + out[k].slot = k; out[k].ai = (struct addrinfo){ .ai_family = addrs[i].family, .ai_socktype = ports[j].socktype, @@ -113,8 +118,8 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), .ai_addr = (void *)&out[k].sa, - .ai_canonname = outcanon, - .ai_next = &out[k+1].ai }; + .ai_canonname = outcanon }; + if (k) out[k-1].ai.ai_next = &out[k].ai; switch (addrs[i].family) { case AF_INET: out[k].sa.sin.sin_family = AF_INET; @@ -130,7 +135,6 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru } } out[0].ref = nais; - out[nais-1].ai.ai_next = 0; *res = &out->ai; return 0; } |