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

Commit 483fc576 authored by Bernie Innocenti's avatar Bernie Innocenti Committed by android-build-merger
Browse files

Merge changes I01a2ea4c,I0673dd5a,Ic6e2c029

am: 059357ce

Change-Id: Ia488cb9cbc824cc0b64b5e3b3cabf40a3425ac12
parents 68c88447 059357ce
Loading
Loading
Loading
Loading
+22 −13
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ namespace {
constexpr int MAX_QUERIES_PER_UID = 256;

// Max packet size for answer, sync with getaddrinfo.c
// TODO: switch to dynamically allocated buffers with std::vector
constexpr int MAXPACKET = 8 * 1024;

android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
@@ -1033,7 +1034,8 @@ DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
    free(mName);
}

void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp,
void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf,
                                                              size_t buflen, struct hostent** hpp,
                                                              NetworkDnsEventReported* event) {
    // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
    // family AF_INET or AF_INET6.
@@ -1051,7 +1053,7 @@ void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struc
    // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
    const uid_t uid = mClient->getUid();
    if (queryLimiter.start(uid)) {
        *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp, event);
        *rv = resolv_gethostbyname(mName, AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event);
        queryLimiter.finish(uid);
        if (*rv) {
            *rv = EAI_NODATA;  // return original error code
@@ -1074,11 +1076,14 @@ void DnsProxyListener::GetHostByNameHandler::run() {
    maybeFixupNetContext(&mNetContext);
    const uid_t uid = mClient->getUid();
    hostent* hp = nullptr;
    hostent hbuf;
    char tmpbuf[MAXPACKET];
    int32_t rv = 0;
    NetworkDnsEventReported event;
    initDnsEvent(&event);
    if (queryLimiter.start(uid)) {
        rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp, &event);
        rv = resolv_gethostbyname(mName, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp,
                                  &event);
        queryLimiter.finish(uid);
    } else {
        rv = EAI_MEMORY;
@@ -1086,12 +1091,12 @@ void DnsProxyListener::GetHostByNameHandler::run() {
                   << ", max concurrent queries reached";
    }

    doDns64Synthesis(&rv, &hp, &event);
    doDns64Synthesis(&rv, &hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
    const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
    event.set_latency_micros(latencyUs);
    event.set_event_type(EVENT_GETHOSTBYNAME);

    LOG(DEBUG) << "GetHostByNameHandler::run: errno: " << (hp ? "success" : strerror(errno));
    LOG(DEBUG) << "GetHostByNameHandler::run: result: " << gai_strerror(rv);

    bool success = true;
    if (hp) {
@@ -1181,7 +1186,9 @@ DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
    free(mAddress);
}

void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp,
void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, char* buf,
                                                                  size_t buflen,
                                                                  struct hostent** hpp,
                                                                  NetworkDnsEventReported* event) {
    if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) {
        return;
@@ -1210,14 +1217,14 @@ void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent
    if (queryLimiter.start(uid)) {
        // Remove NAT64 prefix and do reverse DNS query
        struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
        android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp,
        resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext, hpp,
                             event);
        queryLimiter.finish(uid);
        if (*hpp) {
            // Replace IPv4 address with original queried IPv6 address in place. The space has
            // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
            // system/netd/resolv/gethnamaddr.cpp.
            // Note that android_gethostbyaddrfornetcontext returns only one entry in result.
            // Note that resolv_gethostbyaddr() returns only one entry in result.
            memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
            (*hpp)->h_addrtype = AF_INET6;
            (*hpp)->h_length = sizeof(struct in6_addr);
@@ -1232,12 +1239,14 @@ void DnsProxyListener::GetHostByAddrHandler::run() {
    maybeFixupNetContext(&mNetContext);
    const uid_t uid = mClient->getUid();
    hostent* hp = nullptr;
    hostent hbuf;
    char tmpbuf[MAXPACKET];
    int32_t rv = 0;
    NetworkDnsEventReported event;
    initDnsEvent(&event);
    if (queryLimiter.start(uid)) {
        rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext,
                                                &hp, &event);
        rv = resolv_gethostbyaddr(mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf,
                                  sizeof tmpbuf, &mNetContext, &hp, &event);
        queryLimiter.finish(uid);
    } else {
        rv = EAI_MEMORY;
@@ -1245,12 +1254,12 @@ void DnsProxyListener::GetHostByAddrHandler::run() {
                   << ", max concurrent queries reached";
    }

    doDns64ReverseLookup(&hp, &event);
    doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
    const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
    event.set_latency_micros(latencyUs);
    event.set_event_type(EVENT_GETHOSTBYADDR);

    LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << (hp ? "success" : gai_strerror(rv));
    LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << gai_strerror(rv);

    bool success = true;
    if (hp) {
+4 −2
Original line number Diff line number Diff line
@@ -84,7 +84,8 @@ class DnsProxyListener : public FrameworkListener {
        std::string threadName();

      private:
        void doDns64Synthesis(int32_t* rv, hostent** hpp, NetworkDnsEventReported* event);
        void doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf, size_t buflen, hostent** hpp,
                              NetworkDnsEventReported* event);

        SocketClient* mClient;  // ref counted
        char* mName;            // owned. TODO: convert to std::string.
@@ -110,7 +111,8 @@ class DnsProxyListener : public FrameworkListener {
        std::string threadName();

      private:
        void doDns64ReverseLookup(hostent** hpp, NetworkDnsEventReported* event);
        void doDns64ReverseLookup(hostent* hbuf, char* buf, size_t buflen, hostent** hpp,
                                  NetworkDnsEventReported* event);

        SocketClient* mClient;  // ref counted
        void* mAddress;         // address to lookup; owned
+17 −86
Original line number Diff line number Diff line
@@ -76,7 +76,6 @@
#include "netd_resolv/resolv.h"
#include "resolv_cache.h"
#include "resolv_private.h"
#include "resolv_static.h"
#include "stats.pb.h"

using android::net::NetworkDnsEventReported;
@@ -97,6 +96,8 @@ using android::net::NetworkDnsEventReported;

#define MAXPACKET (8 * 1024)

constexpr int MAXADDRS = 35;

typedef union {
    HEADER hdr;
    uint8_t buf[MAXPACKET];
@@ -117,20 +118,6 @@ static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
                           NetworkDnsEventReported* event);
static int dns_gethtbyname(const char* name, int af, getnamaddr* info);

static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
                                  size_t hbuflen, const android_net_context* netcontext,
                                  NetworkDnsEventReported* event);
static int gethostbyname_internal_real(const char* name, int af, hostent* hp, char* buf,
                                       size_t buflen);

static int android_gethostbyaddrfornetcontext_proxy_internal(const void*, socklen_t, int,
                                                             struct hostent*, char*, size_t,
                                                             const struct android_net_context*,
                                                             NetworkDnsEventReported* event);
static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
                                                    const struct android_net_context* netcontext,
                                                    hostent** hp, NetworkDnsEventReported* event);

#define BOUNDED_INCR(x)      \
    do {                     \
        BOUNDS_CHECK(cp, x); \
@@ -401,13 +388,16 @@ nospc:
    return NULL;
}

static int gethostbyname_internal_real(const char* name, int af, hostent* hp, char* buf,
                                       size_t buflen) {
int resolv_gethostbyname(const char* name, int af, hostent* hp, char* buf, size_t buflen,
                         const android_net_context* netcontext, hostent** result,
                         NetworkDnsEventReported* event) {
    getnamaddr info;
    size_t size;

    _DIAGASSERT(name != NULL);
    res_state res = res_get_state();
    if (res == nullptr) return EAI_MEMORY;
    res_setnetcontext(res, netcontext, event);

    size_t size;
    switch (af) {
        case AF_INET:
            size = NS_INADDRSZ;
@@ -463,6 +453,7 @@ static int gethostbyname_internal_real(const char* name, int af, hostent* hp, ch
        int error = dns_gethtbyname(name, af, &info);
        if (error != 0) return error;
    }
    *result = hp;
    return 0;
nospc:
    return EAI_MEMORY;
@@ -481,21 +472,13 @@ fake:
    buf += size;
    buflen -= size;
    HENT_SCOPY(hp->h_name, name, buf, buflen);
    *result = hp;
    return 0;
}

// very similar in proxy-ness to android_getaddrinfo_proxy
static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
                                  size_t hbuflen, const android_net_context* netcontext,
                                  NetworkDnsEventReported* event) {
    res_setnetcontext(res, netcontext, event);
    return gethostbyname_internal_real(name, af, hp, hbuf, hbuflen);
}

static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t len, int af,
                                                   struct hostent* hp, char* buf, size_t buflen,
                                                   const struct android_net_context* netcontext,
                                                   NetworkDnsEventReported* event) {
int resolv_gethostbyaddr(const void* addr, socklen_t len, int af, hostent* hp, char* buf,
                         size_t buflen, const struct android_net_context* netcontext,
                         hostent** result, NetworkDnsEventReported* event) {
    const uint8_t* uaddr = (const uint8_t*)addr;
    socklen_t size;
    struct getnamaddr info;
@@ -540,21 +523,14 @@ static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t l
        int error = dns_gethtbyaddr(uaddr, len, af, netcontext, &info, event);
        if (error != 0) return error;
    }
    *result = hp;
    return 0;
}

static int android_gethostbyaddrfornetcontext_proxy_internal(
        const void* addr, socklen_t len, int af, struct hostent* hp, char* hbuf, size_t hbuflen,
        const struct android_net_context* netcontext, NetworkDnsEventReported* event) {
    return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, netcontext,
                                                   event);
}

// 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);
    char *name;
    char* cp;
    int af, len;
@@ -569,11 +545,8 @@ struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, s
    }
    char* p = NULL;

    /* Allocate a new space to read file lines like upstream does.
     * To keep reentrancy we cannot use res_get_static()->hostbuf here,
     * as the buffer may be used to store content for a previous hostent
     * returned by non-reentrant functions like gethostbyname().
     */
    // Allocate a new space to read file lines like upstream does.
    const size_t line_buf_size = MAXPACKET;
    if ((p = (char*) malloc(line_buf_size)) == NULL) {
        goto nospc;
    }
@@ -597,9 +570,6 @@ struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, s
            len = NS_IN6ADDRSZ;
        } else {
            if (inet_pton(AF_INET, p, &host_addr) <= 0) continue;

            res_state res = res_get_state();
            if (res == NULL) goto nospc;
            af = AF_INET;
            len = NS_INADDRSZ;
        }
@@ -800,45 +770,6 @@ nospc:
    return EAI_MEMORY;
}

/*
 * Non-reentrant versions.
 */

int android_gethostbynamefornetcontext(const char* name, int af,
                                       const struct android_net_context* netcontext, hostent** hp,
                                       NetworkDnsEventReported* event) {
    assert(event != nullptr);

    res_state res = res_get_state();
    if (res == NULL) return EAI_MEMORY;
    res_static* rs = res_get_static();  // For thread-safety.
    int error;
    error = gethostbyname_internal(name, af, res, &rs->host, rs->hostbuf, sizeof(rs->hostbuf),
                                   netcontext, event);
    if (error == 0) {
        *hp = &rs->host;
    }
    return error;
}

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

static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
                                                    const struct android_net_context* netcontext,
                                                    hostent** hp, NetworkDnsEventReported* event) {
    assert(event != nullptr);

    struct res_static* rs = res_get_static();  // For thread-safety.
    int error = android_gethostbyaddrfornetcontext_proxy_internal(
            addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), netcontext, event);
    if (error == 0) *hp = &rs->host;
    return error;
}

int herrnoToAiErrno(int he) {
    switch (he) {
        // extended h_errno
+13 −4
Original line number Diff line number Diff line
@@ -20,10 +20,19 @@
#include "netd_resolv/resolv.h"  // struct android_net_context
#include "stats.pb.h"

/*
 * Error code extending EAI_* codes defined in bionic/libc/include/netdb.h.
 * This error code, including EAI_*, returned from android_getaddrinfofornetcontext()
 * and resolv_gethostbyname() are used for DNS metrics.
 */
#define NETD_RESOLV_TIMEOUT 255  // consistent with RCODE_TIMEOUT

// This is the entry point for the gethostbyname() family of legacy calls.
int android_gethostbynamefornetcontext(const char*, int, const android_net_context*, hostent**,
                                       android::net::NetworkDnsEventReported*);
int resolv_gethostbyname(const char* name, int af, hostent* hp, char* buf, size_t buflen,
                         const android_net_context* netcontext, hostent** result,
                         android::net::NetworkDnsEventReported* event);

// This is the entry point for the gethostbyaddr() family of legacy calls.
int android_gethostbyaddrfornetcontext(const void*, socklen_t, int, const android_net_context*,
                                       hostent**, android::net::NetworkDnsEventReported*);
int resolv_gethostbyaddr(const void* addr, socklen_t len, int af, hostent* hp, char* buf,
                         size_t buflen, const android_net_context* netcontext, hostent** result,
                         android::net::NetworkDnsEventReported* event);
+0 −7
Original line number Diff line number Diff line
@@ -43,13 +43,6 @@
 */
#define MARK_UNSET 0u

/*
 * Error code extending EAI_* codes defined in bionic/libc/include/netdb.h.
 * This error code, including EAI_*, returned from android_getaddrinfofornetcontext()
 * and android_gethostbynamefornetcontext() are used for DNS metrics.
 */
#define NETD_RESOLV_TIMEOUT 255  // consistent with RCODE_TIMEOUT

/*
 * A struct to capture context relevant to network operations.
 *
Loading