Loading getaddrinfo.cpp +11 −7 Original line number Diff line number Diff line Loading @@ -1441,25 +1441,29 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai, */ res_setnetcontext(res, netcontext); int herrno = NETDB_INTERNAL; if (res_searchN(name, &q, res, &herrno) < 0) { // Pass herrno to catch more detailed errors rather than EAI_NODATA. return herrnoToAiErrno(herrno); int he; if (res_searchN(name, &q, res, &he) < 0) { // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA. // Note that res_searchN() doesn't set the pair NETDB_INTERNAL and errno. // See also herrnoToAiErrno(). return herrnoToAiErrno(he); } addrinfo sentinel = {}; addrinfo* cur = &sentinel; addrinfo* ai = getanswer(buf.get(), q.n, q.name, q.qtype, pai, &herrno); addrinfo* ai = getanswer(buf.get(), q.n, q.name, q.qtype, pai, &he); if (ai) { cur->ai_next = ai; while (cur && cur->ai_next) cur = cur->ai_next; } if (q.next) { ai = getanswer(buf2.get(), q2.n, q2.name, q2.qtype, pai, &herrno); ai = getanswer(buf2.get(), q2.n, q2.name, q2.qtype, pai, &he); if (ai) cur->ai_next = ai; } if (sentinel.ai_next == NULL) { return herrnoToAiErrno(herrno); // Note that getanswer() doesn't set the pair NETDB_INTERNAL and errno. // See also herrnoToAiErrno(). return herrnoToAiErrno(he); } _rfc6724_sort(&sentinel, netcontext->app_mark, netcontext->uid); Loading gethnamaddr.cpp +48 −38 Original line number Diff line number Diff line Loading @@ -421,7 +421,6 @@ static int gethostbyname_internal_real(const char* name, int af, res_state res, size = NS_IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; return EAI_FAMILY; } if (buflen < size) goto nospc; Loading Loading @@ -467,13 +466,10 @@ static int gethostbyname_internal_real(const char* name, int af, res_state res, info.buflen = buflen; if (_hf_gethtbyname2(name, af, &info)) { int error = dns_gethtbyname(name, af, &info); if (error != 0) { return error; } if (error != 0) return error; } return 0; nospc: errno = ENOSPC; return EAI_MEMORY; fake: HENT_ARRAY(hp->h_addr_list, 1, buf, buflen); Loading Loading @@ -532,22 +528,21 @@ static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t l size = NS_IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; return EAI_FAMILY; } if (size != len) { errno = EINVAL; // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for invalid argument socket // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM // and EINVAL, to EAI_FAIL. return EAI_FAIL; } info.hp = hp; info.buf = buf; info.buflen = buflen; if (_hf_gethtbyaddr(uaddr, len, af, &info)) { int error = dns_gethtbyaddr(uaddr, len, af, netcontext, &info); if (error != 0) { return error; } if (error != 0) return error; } return 0; } Loading @@ -558,6 +553,8 @@ static int android_gethostbyaddrfornetcontext_proxy_internal( return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, netcontext); } // TODO: Consider leaving function without returning error code as _gethtent() does because // the error code of the caller does not currently return to netd. struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, size_t buflen, int* he) { const size_t line_buf_size = sizeof(res_get_static()->hostbuf); Loading Loading @@ -780,18 +777,18 @@ static int dns_gethtbyname(const char* name, int addr_type, getnamaddr* info) { res_state res = res_get_state(); if (!res) return EAI_MEMORY; int herrno = NETDB_INTERNAL; n = res_nsearch(res, name, C_IN, type, buf->buf, (int) sizeof(buf->buf), &herrno); int he; n = res_nsearch(res, name, C_IN, type, buf->buf, (int)sizeof(buf->buf), &he); if (n < 0) { LOG(DEBUG) << __func__ << ": res_nsearch failed (" << n << ")"; // Pass herrno to catch more detailed errors rather than EAI_NODATA. return herrnoToAiErrno(herrno); } hostent* hp = getanswer(buf.get(), n, name, type, res, info->hp, info->buf, info->buflen, &herrno); if (hp == NULL) { return herrnoToAiErrno(herrno); // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA. // Note that res_nsearch() doesn't set the pair NETDB_INTERNAL and errno. // See also herrnoToAiErrno(). return herrnoToAiErrno(he); } hostent* hp = getanswer(buf.get(), n, name, type, res, info->hp, info->buf, info->buflen, &he); if (hp == NULL) return herrnoToAiErrno(he); return 0; } Loading Loading @@ -819,13 +816,19 @@ static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af, if (advance > 0 && qp + advance < ep) qp += advance; else { // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for an internal // out of buffer space. In order to not rely on errno, convert the original // error code EAI_SYSTEM to EAI_MEMORY. return EAI_MEMORY; } } if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) { // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for an internal // out of buffer space. In order to not rely on errno, convert the original // error code EAI_SYSTEM to EAI_MEMORY. return EAI_MEMORY; } break; default: Loading @@ -838,17 +841,17 @@ static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af, if (!res) return EAI_MEMORY; res_setnetcontext(res, netcontext); int herrno = NETDB_INTERNAL; n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int) sizeof(buf->buf), &herrno); int he; n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int)sizeof(buf->buf), &he); if (n < 0) { LOG(DEBUG) << __func__ << ": res_nquery failed (" << n << ")"; return herrnoToAiErrno(herrno); } hostent* hp = getanswer(buf.get(), n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, &herrno); if (hp == NULL) { return herrnoToAiErrno(herrno); // Note that res_nquery() doesn't set the pair NETDB_INTERNAL and errno. // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA. // See also herrnoToAiErrno(). return herrnoToAiErrno(he); } hostent* hp = getanswer(buf.get(), n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, &he); if (hp == NULL) return herrnoToAiErrno(he); char* bf = (char*) (hp->h_addr_list + 2); size_t blen = (size_t)(bf - info->buf); Loading @@ -873,7 +876,6 @@ static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af, return 0; nospc: errno = ENOSPC; return EAI_MEMORY; } Loading Loading @@ -910,8 +912,8 @@ static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t return error; } int herrnoToAiErrno(int herrno) { switch (herrno) { int herrnoToAiErrno(int he) { switch (he) { // extended h_errno case NETD_RESOLV_H_ERRNO_EXT_TIMEOUT: return NETD_RESOLV_TIMEOUT; Loading @@ -924,9 +926,17 @@ int herrnoToAiErrno(int herrno) { case TRY_AGAIN: return EAI_AGAIN; case NETDB_INTERNAL: // TODO: Remove ENOSPC and call abort() immediately whenever any allocation fails. if (errno == ENOSPC) return EAI_MEMORY; // Theoretically, this should not happen. Leave this here just in case. // Currently, getanswer() of {gethnamaddr, getaddrinfo}.cpp, res_nsearch() and // res_searchN() use this function to convert error code. Only getanswer() // of gethnamaddr.cpp may return the error code pair, herrno NETDB_INTERNAL and // errno ENOSPC, which has already converted to EAI_MEMORY. The remaining functions // don't set the pair herrno and errno. return EAI_SYSTEM; // see errno for detail case NO_RECOVERY: default: return EAI_FAIL; return EAI_FAIL; // TODO: Perhaps convert default to EAI_MAX (unknown error) instead } } No newline at end of file sethostent.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ static void endhostent_r(FILE** hf) { } } // TODO: Consider returning a boolean result as files_getaddrinfo() does because the error code // does not currently return to netd. int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) { struct hostent *hp, hent; char *buf, *ptr; Loading @@ -71,9 +73,11 @@ int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) { FILE* hf = NULL; sethostent_r(&hf); if (hf == NULL) { errno = EINVAL; // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for invalid argument socket // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM // and EINVAL, to EAI_FAIL. return EAI_FAIL; } if ((ptr = buf = (char*) malloc(len = info->buflen)) == NULL) { Loading @@ -89,10 +93,10 @@ int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) { info->hp->h_addrtype = af; info->hp->h_length = 0; int herrno; hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &herrno); int he; hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &he); if (hp == NULL) { if (herrno == NETDB_INTERNAL && errno == ENOSPC) { if (he == NETDB_INTERNAL && errno == ENOSPC) { goto nospc; // glibc compatibility. } break; Loading Loading @@ -165,10 +169,11 @@ int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) { return 0; nospc: free(buf); errno = ENOSPC; return EAI_MEMORY; } // TODO: Consider returning a boolean result as files_getaddrinfo() does because the error code // does not currently return to netd. int _hf_gethtbyaddr(const unsigned char* uaddr, int len, int af, getnamaddr* info) { info->hp->h_length = len; info->hp->h_addrtype = af; Loading @@ -176,12 +181,15 @@ int _hf_gethtbyaddr(const unsigned char* uaddr, int len, int af, getnamaddr* inf FILE* hf = NULL; sethostent_r(&hf); if (hf == NULL) { // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for invalid argument socket // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM // and EINVAL, to EAI_FAIL. return EAI_FAIL; } struct hostent* hp; int herrno; while ((hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &herrno)) != NULL) int he; while ((hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &he)) != NULL) if (!memcmp(hp->h_addr_list[0], uaddr, (size_t) hp->h_length)) break; endhostent_r(&hf); Loading Loading
getaddrinfo.cpp +11 −7 Original line number Diff line number Diff line Loading @@ -1441,25 +1441,29 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai, */ res_setnetcontext(res, netcontext); int herrno = NETDB_INTERNAL; if (res_searchN(name, &q, res, &herrno) < 0) { // Pass herrno to catch more detailed errors rather than EAI_NODATA. return herrnoToAiErrno(herrno); int he; if (res_searchN(name, &q, res, &he) < 0) { // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA. // Note that res_searchN() doesn't set the pair NETDB_INTERNAL and errno. // See also herrnoToAiErrno(). return herrnoToAiErrno(he); } addrinfo sentinel = {}; addrinfo* cur = &sentinel; addrinfo* ai = getanswer(buf.get(), q.n, q.name, q.qtype, pai, &herrno); addrinfo* ai = getanswer(buf.get(), q.n, q.name, q.qtype, pai, &he); if (ai) { cur->ai_next = ai; while (cur && cur->ai_next) cur = cur->ai_next; } if (q.next) { ai = getanswer(buf2.get(), q2.n, q2.name, q2.qtype, pai, &herrno); ai = getanswer(buf2.get(), q2.n, q2.name, q2.qtype, pai, &he); if (ai) cur->ai_next = ai; } if (sentinel.ai_next == NULL) { return herrnoToAiErrno(herrno); // Note that getanswer() doesn't set the pair NETDB_INTERNAL and errno. // See also herrnoToAiErrno(). return herrnoToAiErrno(he); } _rfc6724_sort(&sentinel, netcontext->app_mark, netcontext->uid); Loading
gethnamaddr.cpp +48 −38 Original line number Diff line number Diff line Loading @@ -421,7 +421,6 @@ static int gethostbyname_internal_real(const char* name, int af, res_state res, size = NS_IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; return EAI_FAMILY; } if (buflen < size) goto nospc; Loading Loading @@ -467,13 +466,10 @@ static int gethostbyname_internal_real(const char* name, int af, res_state res, info.buflen = buflen; if (_hf_gethtbyname2(name, af, &info)) { int error = dns_gethtbyname(name, af, &info); if (error != 0) { return error; } if (error != 0) return error; } return 0; nospc: errno = ENOSPC; return EAI_MEMORY; fake: HENT_ARRAY(hp->h_addr_list, 1, buf, buflen); Loading Loading @@ -532,22 +528,21 @@ static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t l size = NS_IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; return EAI_FAMILY; } if (size != len) { errno = EINVAL; // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for invalid argument socket // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM // and EINVAL, to EAI_FAIL. return EAI_FAIL; } info.hp = hp; info.buf = buf; info.buflen = buflen; if (_hf_gethtbyaddr(uaddr, len, af, &info)) { int error = dns_gethtbyaddr(uaddr, len, af, netcontext, &info); if (error != 0) { return error; } if (error != 0) return error; } return 0; } Loading @@ -558,6 +553,8 @@ static int android_gethostbyaddrfornetcontext_proxy_internal( return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, netcontext); } // TODO: Consider leaving function without returning error code as _gethtent() does because // the error code of the caller does not currently return to netd. struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, size_t buflen, int* he) { const size_t line_buf_size = sizeof(res_get_static()->hostbuf); Loading Loading @@ -780,18 +777,18 @@ static int dns_gethtbyname(const char* name, int addr_type, getnamaddr* info) { res_state res = res_get_state(); if (!res) return EAI_MEMORY; int herrno = NETDB_INTERNAL; n = res_nsearch(res, name, C_IN, type, buf->buf, (int) sizeof(buf->buf), &herrno); int he; n = res_nsearch(res, name, C_IN, type, buf->buf, (int)sizeof(buf->buf), &he); if (n < 0) { LOG(DEBUG) << __func__ << ": res_nsearch failed (" << n << ")"; // Pass herrno to catch more detailed errors rather than EAI_NODATA. return herrnoToAiErrno(herrno); } hostent* hp = getanswer(buf.get(), n, name, type, res, info->hp, info->buf, info->buflen, &herrno); if (hp == NULL) { return herrnoToAiErrno(herrno); // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA. // Note that res_nsearch() doesn't set the pair NETDB_INTERNAL and errno. // See also herrnoToAiErrno(). return herrnoToAiErrno(he); } hostent* hp = getanswer(buf.get(), n, name, type, res, info->hp, info->buf, info->buflen, &he); if (hp == NULL) return herrnoToAiErrno(he); return 0; } Loading Loading @@ -819,13 +816,19 @@ static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af, if (advance > 0 && qp + advance < ep) qp += advance; else { // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for an internal // out of buffer space. In order to not rely on errno, convert the original // error code EAI_SYSTEM to EAI_MEMORY. return EAI_MEMORY; } } if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) { // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for an internal // out of buffer space. In order to not rely on errno, convert the original // error code EAI_SYSTEM to EAI_MEMORY. return EAI_MEMORY; } break; default: Loading @@ -838,17 +841,17 @@ static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af, if (!res) return EAI_MEMORY; res_setnetcontext(res, netcontext); int herrno = NETDB_INTERNAL; n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int) sizeof(buf->buf), &herrno); int he; n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int)sizeof(buf->buf), &he); if (n < 0) { LOG(DEBUG) << __func__ << ": res_nquery failed (" << n << ")"; return herrnoToAiErrno(herrno); } hostent* hp = getanswer(buf.get(), n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, &herrno); if (hp == NULL) { return herrnoToAiErrno(herrno); // Note that res_nquery() doesn't set the pair NETDB_INTERNAL and errno. // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA. // See also herrnoToAiErrno(). return herrnoToAiErrno(he); } hostent* hp = getanswer(buf.get(), n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, &he); if (hp == NULL) return herrnoToAiErrno(he); char* bf = (char*) (hp->h_addr_list + 2); size_t blen = (size_t)(bf - info->buf); Loading @@ -873,7 +876,6 @@ static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af, return 0; nospc: errno = ENOSPC; return EAI_MEMORY; } Loading Loading @@ -910,8 +912,8 @@ static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t return error; } int herrnoToAiErrno(int herrno) { switch (herrno) { int herrnoToAiErrno(int he) { switch (he) { // extended h_errno case NETD_RESOLV_H_ERRNO_EXT_TIMEOUT: return NETD_RESOLV_TIMEOUT; Loading @@ -924,9 +926,17 @@ int herrnoToAiErrno(int herrno) { case TRY_AGAIN: return EAI_AGAIN; case NETDB_INTERNAL: // TODO: Remove ENOSPC and call abort() immediately whenever any allocation fails. if (errno == ENOSPC) return EAI_MEMORY; // Theoretically, this should not happen. Leave this here just in case. // Currently, getanswer() of {gethnamaddr, getaddrinfo}.cpp, res_nsearch() and // res_searchN() use this function to convert error code. Only getanswer() // of gethnamaddr.cpp may return the error code pair, herrno NETDB_INTERNAL and // errno ENOSPC, which has already converted to EAI_MEMORY. The remaining functions // don't set the pair herrno and errno. return EAI_SYSTEM; // see errno for detail case NO_RECOVERY: default: return EAI_FAIL; return EAI_FAIL; // TODO: Perhaps convert default to EAI_MAX (unknown error) instead } } No newline at end of file
sethostent.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ static void endhostent_r(FILE** hf) { } } // TODO: Consider returning a boolean result as files_getaddrinfo() does because the error code // does not currently return to netd. int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) { struct hostent *hp, hent; char *buf, *ptr; Loading @@ -71,9 +73,11 @@ int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) { FILE* hf = NULL; sethostent_r(&hf); if (hf == NULL) { errno = EINVAL; // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for invalid argument socket // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM // and EINVAL, to EAI_FAIL. return EAI_FAIL; } if ((ptr = buf = (char*) malloc(len = info->buflen)) == NULL) { Loading @@ -89,10 +93,10 @@ int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) { info->hp->h_addrtype = af; info->hp->h_length = 0; int herrno; hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &herrno); int he; hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &he); if (hp == NULL) { if (herrno == NETDB_INTERNAL && errno == ENOSPC) { if (he == NETDB_INTERNAL && errno == ENOSPC) { goto nospc; // glibc compatibility. } break; Loading Loading @@ -165,10 +169,11 @@ int _hf_gethtbyname2(const char* name, int af, getnamaddr* info) { return 0; nospc: free(buf); errno = ENOSPC; return EAI_MEMORY; } // TODO: Consider returning a boolean result as files_getaddrinfo() does because the error code // does not currently return to netd. int _hf_gethtbyaddr(const unsigned char* uaddr, int len, int af, getnamaddr* info) { info->hp->h_length = len; info->hp->h_addrtype = af; Loading @@ -176,12 +181,15 @@ int _hf_gethtbyaddr(const unsigned char* uaddr, int len, int af, getnamaddr* inf FILE* hf = NULL; sethostent_r(&hf); if (hf == NULL) { // TODO: Consider to remap error code without relying on errno. return EAI_SYSTEM; // TODO: Consider converting to a private extended EAI_* error code. // Currently, the EAI_* value has no corresponding error code for invalid argument socket // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM // and EINVAL, to EAI_FAIL. return EAI_FAIL; } struct hostent* hp; int herrno; while ((hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &herrno)) != NULL) int he; while ((hp = netbsd_gethostent_r(hf, info->hp, info->buf, info->buflen, &he)) != NULL) if (!memcmp(hp->h_addr_list[0], uaddr, (size_t) hp->h_length)) break; endhostent_r(&hf); Loading