Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 598202c4 authored by Hungming Chen's avatar Hungming Chen
Browse files

Unify DNS error code for android_gethostbyaddrfornetcontext

Both gethostbyname and getaddrinfo return error code POSIX EAI_* now. Unify
the error codes of gethostbyaddr to be POSIX EAI_* as well.

Test: system/netd/tests/runtests.sh passed
Change-Id: Iee6963e2ebd21fd0c446b487784eb59af37a544e
parent dd4bfb9a
Loading
Loading
Loading
Loading
+50 −34
Original line number Original line Diff line number Diff line
@@ -135,7 +135,7 @@ static void map_v4v6_hostent(struct hostent*, char**, char*);
static void pad_v4v6_hostent(struct hostent* hp, char** bpp, char* ep);
static void pad_v4v6_hostent(struct hostent* hp, char** bpp, char* ep);
static void addrsort(char**, int, res_state);
static void addrsort(char**, int, res_state);


static bool _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
static int _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
                            const android_net_context* netcontext, getnamaddr* info);
                            const android_net_context* netcontext, getnamaddr* info);
static int _dns_gethtbyname(const char* name, int af, getnamaddr* info);
static int _dns_gethtbyname(const char* name, int af, getnamaddr* info);


@@ -144,11 +144,12 @@ static int gethostbyname_internal(const char* name, int af, res_state res, hoste
                                  const android_net_context* netcontext);
                                  const android_net_context* netcontext);
static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
                                       char* buf, size_t buflen, int* he);
                                       char* buf, size_t buflen, int* he);
static struct hostent* android_gethostbyaddrfornetcontext_proxy_internal(
static int android_gethostbyaddrfornetcontext_proxy_internal(const void*, socklen_t, int,
        const void*, socklen_t, int, struct hostent*, char*, size_t, int*,
                                                             struct hostent*, char*, size_t, int*,
                                                             const struct android_net_context*);
                                                             const struct android_net_context*);
static struct hostent* android_gethostbyaddrfornetcontext_proxy(
static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
        const void* addr, socklen_t len, int af, const struct android_net_context* netcontext);
                                                    const struct android_net_context* netcontext,
                                                    hostent** hp);


#ifdef DEBUG
#ifdef DEBUG
static void debugprintf(const char* msg, res_state res, ...) {
static void debugprintf(const char* msg, res_state res, ...) {
@@ -573,9 +574,10 @@ static int gethostbyname_internal(const char* name, int af, res_state res, hoste
    return gethostbyname_internal_real(name, af, res, hp, hbuf, hbuflen, errorp);
    return gethostbyname_internal_real(name, af, res, hp, hbuf, hbuflen, errorp);
}
}


static struct hostent* android_gethostbyaddrfornetcontext_real(
static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t len, int af,
        const void* addr, socklen_t len, int af, struct hostent* hp, char* buf, size_t buflen,
                                                   struct hostent* hp, char* buf, size_t buflen,
        int* he, const struct android_net_context* netcontext) {
                                                   int* he,
                                                   const struct android_net_context* netcontext) {
    const u_char* uaddr = (const u_char*) addr;
    const u_char* uaddr = (const u_char*) addr;
    socklen_t size;
    socklen_t size;
    struct getnamaddr info;
    struct getnamaddr info;
@@ -586,7 +588,7 @@ static struct hostent* android_gethostbyaddrfornetcontext_real(
        (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr*) addr) ||
        (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr*) addr) ||
         IN6_IS_ADDR_SITELOCAL((const struct in6_addr*) addr))) {
         IN6_IS_ADDR_SITELOCAL((const struct in6_addr*) addr))) {
        *he = HOST_NOT_FOUND;
        *he = HOST_NOT_FOUND;
        return NULL;
        return EAI_NODATA;
    }
    }
    if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
    if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
        (IN6_IS_ADDR_V4MAPPED((const struct in6_addr*) addr) ||
        (IN6_IS_ADDR_V4MAPPED((const struct in6_addr*) addr) ||
@@ -607,12 +609,13 @@ static struct hostent* android_gethostbyaddrfornetcontext_real(
        default:
        default:
            errno = EAFNOSUPPORT;
            errno = EAFNOSUPPORT;
            *he = NETDB_INTERNAL;
            *he = NETDB_INTERNAL;
            return NULL;
            return EAI_FAMILY;
    }
    }
    if (size != len) {
    if (size != len) {
        errno = EINVAL;
        errno = EINVAL;
        *he = NETDB_INTERNAL;
        *he = NETDB_INTERNAL;
        return NULL;
        // TODO: Consider to remap error code without relying on errno.
        return EAI_SYSTEM;
    }
    }
    info.hp = hp;
    info.hp = hp;
    info.buf = buf;
    info.buf = buf;
@@ -620,15 +623,16 @@ static struct hostent* android_gethostbyaddrfornetcontext_real(
    info.he = he;
    info.he = he;
    *he = NETDB_INTERNAL;
    *he = NETDB_INTERNAL;
    if (!_hf_gethtbyaddr(uaddr, len, af, &info)) {
    if (!_hf_gethtbyaddr(uaddr, len, af, &info)) {
        if (!_dns_gethtbyaddr(uaddr, len, af, netcontext, &info)) {
        int error = _dns_gethtbyaddr(uaddr, len, af, netcontext, &info);
            return NULL;
        if (error != 0) {
            return error;
        }
        }
    }
    }
    *he = NETDB_SUCCESS;
    *he = NETDB_SUCCESS;
    return hp;
    return 0;
}
}


static struct hostent* android_gethostbyaddrfornetcontext_proxy_internal(
static int android_gethostbyaddrfornetcontext_proxy_internal(
        const void* addr, socklen_t len, int af, struct hostent* hp, char* hbuf, size_t hbuflen,
        const void* addr, socklen_t len, int af, struct hostent* hp, char* hbuf, size_t hbuflen,
        int* he, const struct android_net_context* netcontext) {
        int* he, const struct android_net_context* netcontext) {
    return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, he,
    return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, he,
@@ -895,7 +899,7 @@ static int _dns_gethtbyname(const char* name, int addr_type, getnamaddr* info) {
    return 0;
    return 0;
}
}


static bool _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
static int _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
                            const android_net_context* netcontext, getnamaddr* info) {
                            const android_net_context* netcontext, getnamaddr* info) {
    char qbuf[MAXDNAME + 1], *qp, *ep;
    char qbuf[MAXDNAME + 1], *qp, *ep;
    int n;
    int n;
@@ -922,27 +926,29 @@ static bool _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
                    qp += advance;
                    qp += advance;
                else {
                else {
                    *info->he = NETDB_INTERNAL;
                    *info->he = NETDB_INTERNAL;
                    return false;
                    // TODO: Consider to remap error code without relying on errno.
                    return EAI_SYSTEM;
                }
                }
            }
            }
            if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) {
            if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) {
                *info->he = NETDB_INTERNAL;
                *info->he = NETDB_INTERNAL;
                return false;
                // TODO: Consider to remap error code without relying on errno.
                return EAI_SYSTEM;
            }
            }
            break;
            break;
        default:
        default:
            return false;
            return EAI_FAMILY;
    }
    }


    querybuf* buf = (querybuf*) malloc(sizeof(querybuf));
    querybuf* buf = (querybuf*) malloc(sizeof(querybuf));
    if (buf == NULL) {
    if (buf == NULL) {
        *info->he = NETDB_INTERNAL;
        *info->he = NETDB_INTERNAL;
        return false;
        return EAI_MEMORY;
    }
    }
    res = res_get_state();
    res = res_get_state();
    if (res == NULL) {
    if (res == NULL) {
        free(buf);
        free(buf);
        return false;
        return EAI_MEMORY;
    }
    }
    res_setnetcontext(res, netcontext);
    res_setnetcontext(res, netcontext);
    int ai_error = 0;
    int ai_error = 0;
@@ -950,12 +956,19 @@ static bool _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
    if (n < 0) {
    if (n < 0) {
        free(buf);
        free(buf);
        debugprintf("res_nquery failed (%d)\n", res, n);
        debugprintf("res_nquery failed (%d)\n", res, n);
        return false;

        // TODO: Consider to return more meaningful error codes.
        // Currently, doesn't consider ai_error as _dns_gethtbyname() does because current ai_error
        // comes from rcode only and rcode NOERROR doesn't really mean no error for the whole DNS
        // query progress. DNS server may respond a DNS packet without any answer for queried
        // address. In this case, return error code from h_errno NO_DATA rather than rcode NOERROR
        // (ai_error).
        return herrnoToAiError(h_errno);
    }
    }
    hp = getanswer(buf, n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, info->he);
    hp = getanswer(buf, n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, info->he);
    free(buf);
    free(buf);
    if (hp == NULL) {
    if (hp == NULL) {
        return false;
        return herrnoToAiError(h_errno);
    }
    }


    char* bf = (char*) (hp->h_addr_list + 2);
    char* bf = (char*) (hp->h_addr_list + 2);
@@ -979,12 +992,12 @@ static bool _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
    }
    }


    *info->he = NETDB_SUCCESS;
    *info->he = NETDB_SUCCESS;
    return true;
    return 0;


nospc:
nospc:
    errno = ENOSPC;
    errno = ENOSPC;
    *info->he = NETDB_INTERNAL;
    *info->he = NETDB_INTERNAL;
    return false;
    return EAI_MEMORY;
}
}


/*
/*
@@ -1005,16 +1018,19 @@ int android_gethostbynamefornetcontext(const char* name, int af,
    return error;
    return error;
}
}


struct hostent* android_gethostbyaddrfornetcontext(const void* addr, socklen_t len, int af,
int android_gethostbyaddrfornetcontext(const void* addr, socklen_t len, int af,
                                                   const struct android_net_context* netcontext) {
                                       const struct android_net_context* netcontext, hostent** hp) {
    return android_gethostbyaddrfornetcontext_proxy(addr, len, af, netcontext);
    return android_gethostbyaddrfornetcontext_proxy(addr, len, af, netcontext, hp);
}
}


static struct hostent* android_gethostbyaddrfornetcontext_proxy(
static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
        const void* addr, socklen_t len, int af, const struct android_net_context* netcontext) {
                                                    const struct android_net_context* netcontext,
                                                    hostent** hp) {
    struct res_static* rs = res_get_static();  // For thread-safety.
    struct res_static* rs = res_get_static();  // For thread-safety.
    return android_gethostbyaddrfornetcontext_proxy_internal(
    int error = android_gethostbyaddrfornetcontext_proxy_internal(
            addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), &h_errno, netcontext);
            addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), &h_errno, netcontext);
    if (error == 0) *hp = &rs->host;
    return error;
}
}


int herrnoToAiError(int herror) {
int herrnoToAiError(int herror) {
+2 −2
Original line number Original line Diff line number Diff line
@@ -102,8 +102,8 @@ struct ExternalPrivateDnsStatus {
typedef void (*private_dns_validated_callback)(unsigned netid, const char* server,
typedef void (*private_dns_validated_callback)(unsigned netid, const char* server,
                                               const char* hostname, bool success);
                                               const char* hostname, bool success);


LIBNETD_RESOLV_PUBLIC hostent* android_gethostbyaddrfornetcontext(const void*, socklen_t, int,
LIBNETD_RESOLV_PUBLIC int android_gethostbyaddrfornetcontext(const void*, socklen_t, int,
                                                                  const android_net_context*);
                                                             const android_net_context*, hostent**);
LIBNETD_RESOLV_PUBLIC int android_gethostbynamefornetcontext(const char*, int,
LIBNETD_RESOLV_PUBLIC int android_gethostbynamefornetcontext(const char*, int,
                                                             const android_net_context*, hostent**);
                                                             const android_net_context*, hostent**);
LIBNETD_RESOLV_PUBLIC int android_getaddrinfofornetcontext(const char*, const char*,
LIBNETD_RESOLV_PUBLIC int android_getaddrinfofornetcontext(const char*, const char*,
+2 −2
Original line number Original line Diff line number Diff line
@@ -37,8 +37,8 @@ extern struct ResolvStub {
    int (*android_getaddrinfofornetcontext)(const char*, const char*, const addrinfo*,
    int (*android_getaddrinfofornetcontext)(const char*, const char*, const addrinfo*,
                                            const android_net_context*, addrinfo**);
                                            const android_net_context*, addrinfo**);


    hostent* (*android_gethostbyaddrfornetcontext)(const void*, socklen_t, int,
    int (*android_gethostbyaddrfornetcontext)(const void*, socklen_t, int,
                                                   const android_net_context*);
                                              const android_net_context*, hostent**);


    int (*android_gethostbynamefornetcontext)(const char*, int, const android_net_context*,
    int (*android_gethostbynamefornetcontext)(const char*, int, const android_net_context*,
                                              hostent**);
                                              hostent**);