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

Commit 49b70b98 authored by Luke Huang's avatar Luke Huang Committed by android-build-merger
Browse files

Unify MAXPACKET and refactor buffer allocation of getaddrinfo

am: c98fd802

Change-Id: Iaba79c799d550df29f8727b85b95dc73689eff52
parents a8773afe c98fd802
Loading
Loading
Loading
Loading
+0 −4
Original line number Original line Diff line number Diff line
@@ -74,10 +74,6 @@ namespace {
// Limits the number of outstanding DNS queries by client UID.
// Limits the number of outstanding DNS queries by client UID.
constexpr int MAX_QUERIES_PER_UID = 256;
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);
android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);


void logArguments(int argc, char** argv) {
void logArguments(int argc, char** argv) {
+20 −44
Original line number Original line Diff line number Diff line
@@ -108,20 +108,13 @@ const Explore explore_options[] = {
};
};


#define PTON_MAX 16
#define PTON_MAX 16
#define MAXPACKET (8 * 1024)

typedef union {
    HEADER hdr;
    uint8_t buf[MAXPACKET];
} querybuf;


struct res_target {
struct res_target {
    struct res_target* next;
    struct res_target* next;
    const char* name;  /* domain name */
    const char* name;                                                  // domain name
    int qclass, qtype; /* class and type of query */
    int qclass, qtype;                                                 // class and type of query
    uint8_t* answer;   /* buffer to put answer */
    std::vector<uint8_t> answer = std::vector<uint8_t>(MAXPACKET, 0);  // buffer to put answer
    int anslen;        /* size of answer buffer */
    int n = 0;                                                         // result length
    int n;             /* result length */
};
};


static int str2number(const char*);
static int str2number(const char*);
@@ -139,8 +132,8 @@ static int get_port(const struct addrinfo*, const char*, int);
static const struct afd* find_afd(int);
static const struct afd* find_afd(int);
static int ip6_str2scopeid(const char*, struct sockaddr_in6*, uint32_t*);
static int ip6_str2scopeid(const char*, struct sockaddr_in6*, uint32_t*);


static struct addrinfo* getanswer(const querybuf*, int, const char*, int, const struct addrinfo*,
static struct addrinfo* getanswer(const std::vector<uint8_t>&, int, const char*, int,
                                  int* herrno);
                                  const struct addrinfo*, int* herrno);
static int dns_getaddrinfo(const char* name, const addrinfo* pai,
static int dns_getaddrinfo(const char* name, const addrinfo* pai,
                           const android_net_context* netcontext, addrinfo** rv,
                           const android_net_context* netcontext, addrinfo** rv,
                           NetworkDnsEventReported* event);
                           NetworkDnsEventReported* event);
@@ -838,8 +831,8 @@ static int ip6_str2scopeid(const char* scope, struct sockaddr_in6* sin6, uint32_
        }                            \
        }                            \
    } while (0)
    } while (0)


static struct addrinfo* getanswer(const querybuf* answer, int anslen, const char* qname, int qtype,
static struct addrinfo* getanswer(const std::vector<uint8_t>& answer, int anslen, const char* qname,
                                  const struct addrinfo* pai, int* herrno) {
                                  int qtype, const struct addrinfo* pai, int* herrno) {
    struct addrinfo sentinel = {};
    struct addrinfo sentinel = {};
    struct addrinfo *cur;
    struct addrinfo *cur;
    struct addrinfo ai;
    struct addrinfo ai;
@@ -856,14 +849,13 @@ static struct addrinfo* getanswer(const querybuf* answer, int anslen, const char
    int (*name_ok)(const char*);
    int (*name_ok)(const char*);
    char hostbuf[8 * 1024];
    char hostbuf[8 * 1024];


    assert(answer != NULL);
    assert(qname != NULL);
    assert(qname != NULL);
    assert(pai != NULL);
    assert(pai != NULL);


    cur = &sentinel;
    cur = &sentinel;


    canonname = NULL;
    canonname = NULL;
    eom = answer->buf + anslen;
    eom = answer.data() + anslen;
    switch (qtype) {
    switch (qtype) {
        case T_A:
        case T_A:
        case T_AAAA:
        case T_AAAA:
@@ -876,18 +868,18 @@ static struct addrinfo* getanswer(const querybuf* answer, int anslen, const char
    /*
    /*
     * find first satisfactory answer
     * find first satisfactory answer
     */
     */
    hp = &answer->hdr;
    hp = reinterpret_cast<const HEADER*>(answer.data());
    ancount = ntohs(hp->ancount);
    ancount = ntohs(hp->ancount);
    qdcount = ntohs(hp->qdcount);
    qdcount = ntohs(hp->qdcount);
    bp = hostbuf;
    bp = hostbuf;
    ep = hostbuf + sizeof hostbuf;
    ep = hostbuf + sizeof hostbuf;
    cp = answer->buf;
    cp = answer.data();
    BOUNDED_INCR(HFIXEDSZ);
    BOUNDED_INCR(HFIXEDSZ);
    if (qdcount != 1) {
    if (qdcount != 1) {
        *herrno = NO_RECOVERY;
        *herrno = NO_RECOVERY;
        return (NULL);
        return (NULL);
    }
    }
    n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
    n = dn_expand(answer.data(), eom, cp, bp, ep - bp);
    if ((n < 0) || !(*name_ok)(bp)) {
    if ((n < 0) || !(*name_ok)(bp)) {
        *herrno = NO_RECOVERY;
        *herrno = NO_RECOVERY;
        return (NULL);
        return (NULL);
@@ -911,7 +903,7 @@ static struct addrinfo* getanswer(const querybuf* answer, int anslen, const char
    haveanswer = 0;
    haveanswer = 0;
    had_error = 0;
    had_error = 0;
    while (ancount-- > 0 && cp < eom && !had_error) {
    while (ancount-- > 0 && cp < eom && !had_error) {
        n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
        n = dn_expand(answer.data(), eom, cp, bp, ep - bp);
        if ((n < 0) || !(*name_ok)(bp)) {
        if ((n < 0) || !(*name_ok)(bp)) {
            had_error++;
            had_error++;
            continue;
            continue;
@@ -931,7 +923,7 @@ static struct addrinfo* getanswer(const querybuf* answer, int anslen, const char
            continue; /* XXX - had_error++ ? */
            continue; /* XXX - had_error++ ? */
        }
        }
        if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && type == T_CNAME) {
        if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && type == T_CNAME) {
            n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
            n = dn_expand(answer.data(), eom, cp, tbuf, sizeof tbuf);
            if ((n < 0) || !(*name_ok)(tbuf)) {
            if ((n < 0) || !(*name_ok)(tbuf)) {
                had_error++;
                had_error++;
                continue;
                continue;
@@ -1397,16 +1389,11 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai,
    res_target q = {};
    res_target q = {};
    res_target q2 = {};
    res_target q2 = {};


    auto buf = std::make_unique<querybuf>();
    auto buf2 = std::make_unique<querybuf>();

    switch (pai->ai_family) {
    switch (pai->ai_family) {
        case AF_UNSPEC: {
        case AF_UNSPEC: {
            /* prefer IPv6 */
            /* prefer IPv6 */
            q.name = name;
            q.name = name;
            q.qclass = C_IN;
            q.qclass = C_IN;
            q.answer = buf->buf;
            q.anslen = sizeof(buf->buf);
            int query_ipv6 = 1, query_ipv4 = 1;
            int query_ipv6 = 1, query_ipv4 = 1;
            if (pai->ai_flags & AI_ADDRCONFIG) {
            if (pai->ai_flags & AI_ADDRCONFIG) {
                query_ipv6 = have_ipv6(netcontext->app_mark, netcontext->uid);
                query_ipv6 = have_ipv6(netcontext->app_mark, netcontext->uid);
@@ -1419,8 +1406,6 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai,
                    q2.name = name;
                    q2.name = name;
                    q2.qclass = C_IN;
                    q2.qclass = C_IN;
                    q2.qtype = T_A;
                    q2.qtype = T_A;
                    q2.answer = buf2->buf;
                    q2.anslen = sizeof(buf2->buf);
                }
                }
            } else if (query_ipv4) {
            } else if (query_ipv4) {
                q.qtype = T_A;
                q.qtype = T_A;
@@ -1433,15 +1418,11 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai,
            q.name = name;
            q.name = name;
            q.qclass = C_IN;
            q.qclass = C_IN;
            q.qtype = T_A;
            q.qtype = T_A;
            q.answer = buf->buf;
            q.anslen = sizeof(buf->buf);
            break;
            break;
        case AF_INET6:
        case AF_INET6:
            q.name = name;
            q.name = name;
            q.qclass = C_IN;
            q.qclass = C_IN;
            q.qtype = T_AAAA;
            q.qtype = T_AAAA;
            q.answer = buf->buf;
            q.anslen = sizeof(buf->buf);
            break;
            break;
        default:
        default:
            return EAI_FAMILY;
            return EAI_FAMILY;
@@ -1460,13 +1441,13 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai,


    addrinfo sentinel = {};
    addrinfo sentinel = {};
    addrinfo* cur = &sentinel;
    addrinfo* cur = &sentinel;
    addrinfo* ai = getanswer(buf.get(), q.n, q.name, q.qtype, pai, &he);
    addrinfo* ai = getanswer(q.answer, q.n, q.name, q.qtype, pai, &he);
    if (ai) {
    if (ai) {
        cur->ai_next = ai;
        cur->ai_next = ai;
        while (cur && cur->ai_next) cur = cur->ai_next;
        while (cur && cur->ai_next) cur = cur->ai_next;
    }
    }
    if (q.next) {
    if (q.next) {
        ai = getanswer(buf2.get(), q2.n, q2.name, q2.qtype, pai, &he);
        ai = getanswer(q2.answer, q2.n, q2.name, q2.qtype, pai, &he);
        if (ai) cur->ai_next = ai;
        if (ai) cur->ai_next = ai;
    }
    }
    if (sentinel.ai_next == NULL) {
    if (sentinel.ai_next == NULL) {
@@ -1578,7 +1559,6 @@ static bool files_getaddrinfo(const char* name, const addrinfo* pai, addrinfo**
 */
 */
static int res_queryN(const char* name, res_target* target, res_state res, int* herrno) {
static int res_queryN(const char* name, res_target* target, res_state res, int* herrno) {
    uint8_t buf[MAXPACKET];
    uint8_t buf[MAXPACKET];
    HEADER* hp;
    int n;
    int n;
    struct res_target* t;
    struct res_target* t;
    int rcode;
    int rcode;
@@ -1591,10 +1571,7 @@ static int res_queryN(const char* name, res_target* target, res_state res, int*
    ancount = 0;
    ancount = 0;


    for (t = target; t; t = t->next) {
    for (t = target; t; t = t->next) {
        uint8_t* answer;
        HEADER* hp = (HEADER*)(void*)t->answer.data();
        int anslen;

        hp = (HEADER*) (void*) t->answer;
        bool retried = false;
        bool retried = false;
    again:
    again:
        hp->rcode = NOERROR; /* default */
        hp->rcode = NOERROR; /* default */
@@ -1602,8 +1579,7 @@ static int res_queryN(const char* name, res_target* target, res_state res, int*
        /* make it easier... */
        /* make it easier... */
        int cl = t->qclass;
        int cl = t->qclass;
        int type = t->qtype;
        int type = t->qtype;
        answer = t->answer;
        const int anslen = t->answer.size();
        anslen = t->anslen;


        LOG(DEBUG) << __func__ << ": (" << cl << ", " << type << ")";
        LOG(DEBUG) << __func__ << ": (" << cl << ", " << type << ")";


@@ -1620,7 +1596,7 @@ static int res_queryN(const char* name, res_target* target, res_state res, int*
            return n;
            return n;
        }
        }


        n = res_nsend(res, buf, n, answer, anslen, &rcode, 0);
        n = res_nsend(res, buf, n, t->answer.data(), anslen, &rcode, 0);
        if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
        if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
            // Record rcode from DNS response header only if no timeout.
            // Record rcode from DNS response header only if no timeout.
            // Keep rcode timeout for reporting later if any.
            // Keep rcode timeout for reporting later if any.
@@ -1689,7 +1665,7 @@ static int res_searchN(const char* name, res_target* target, res_state res, int*
    assert(name != NULL);
    assert(name != NULL);
    assert(target != NULL);
    assert(target != NULL);


    hp = (HEADER*) (void*) target->answer; /*XXX*/
    hp = (HEADER*)(void*)target->answer.data();


    errno = 0;
    errno = 0;
    *herrno = HOST_NOT_FOUND; /* default, if we never query */
    *herrno = HOST_NOT_FOUND; /* default, if we never query */
+0 −2
Original line number Original line Diff line number Diff line
@@ -95,8 +95,6 @@ using android::net::NetworkDnsEventReported;
#define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
#define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
#define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)
#define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)


#define MAXPACKET (8 * 1024)

constexpr int MAXADDRS = 35;
constexpr int MAXADDRS = 35;


typedef union {
typedef union {
+0 −6
Original line number Original line Diff line number Diff line
@@ -89,12 +89,6 @@
#include "resolv_cache.h"
#include "resolv_cache.h"
#include "resolv_private.h"
#include "resolv_private.h"


#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
#else
#define MAXPACKET 1024
#endif

/*
/*
 * Formulate a normal query, send, and await answer.
 * Formulate a normal query, send, and await answer.
 * Returned answer is placed in supplied buffer "answer".
 * Returned answer is placed in supplied buffer "answer".
+10 −16
Original line number Original line Diff line number Diff line
@@ -226,15 +226,6 @@ static struct timespec evNowTime(void) {
    return tsnow;
    return tsnow;
}
}


static struct iovec evConsIovec(void* buf, size_t cnt) {
    struct iovec ret;

    memset(&ret, 0xf5, sizeof ret);
    ret.iov_base = buf;
    ret.iov_len = cnt;
    return ret;
}

// END: Code copied from ISC eventlib
// END: Code copied from ISC eventlib


/* BIONIC-BEGIN: implement source port randomization */
/* BIONIC-BEGIN: implement source port randomization */
@@ -669,7 +660,6 @@ static int send_vc(res_state statp, res_params* params, const uint8_t* buf, int
    struct sockaddr* nsap;
    struct sockaddr* nsap;
    int nsaplen;
    int nsaplen;
    int truncating, connreset, n;
    int truncating, connreset, n;
    struct iovec iov[2];
    uint8_t* cp;
    uint8_t* cp;


    LOG(INFO) << __func__ << ": using send_vc";
    LOG(INFO) << __func__ << ": using send_vc";
@@ -754,8 +744,10 @@ same_ns:
     * Send length & message
     * Send length & message
     */
     */
    uint16_t len = htons(static_cast<uint16_t>(buflen));
    uint16_t len = htons(static_cast<uint16_t>(buflen));
    iov[0] = evConsIovec(&len, INT16SZ);
    const iovec iov[] = {
    iov[1] = evConsIovec((void*) buf, (size_t) buflen);
            {.iov_base = &len, .iov_len = INT16SZ},
            {.iov_base = const_cast<uint8_t*>(buf), .iov_len = static_cast<size_t>(buflen)},
    };
    if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
    if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
        *terrno = errno;
        *terrno = errno;
        PLOG(DEBUG) << __func__ << ": write failed: ";
        PLOG(DEBUG) << __func__ << ": write failed: ";
@@ -863,8 +855,8 @@ read_len:
}
}


/* return -1 on error (errno set), 0 on success */
/* return -1 on error (errno set), 0 on success */
static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t salen,
static int connect_with_timeout(int sock, const sockaddr* nsap, socklen_t salen,
                                const struct timespec timeout) {
                                const timespec timeout) {
    int res, origflags;
    int res, origflags;


    origflags = fcntl(sock, F_GETFL, 0);
    origflags = fcntl(sock, F_GETFL, 0);
@@ -876,8 +868,8 @@ static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t
        goto done;
        goto done;
    }
    }
    if (res != 0) {
    if (res != 0) {
        struct timespec now = evNowTime();
        timespec now = evNowTime();
        struct timespec finish = evAddTime(now, timeout);
        timespec finish = evAddTime(now, timeout);
        LOG(INFO) << __func__ << ": " << sock << " send_vc";
        LOG(INFO) << __func__ << ": " << sock << " send_vc";
        res = retrying_poll(sock, POLLIN | POLLOUT, &finish);
        res = retrying_poll(sock, POLLIN | POLLOUT, &finish);
        if (res <= 0) {
        if (res <= 0) {
@@ -1102,6 +1094,7 @@ static void dump_error(const char* str, const struct sockaddr* address, int alen
    char hbuf[NI_MAXHOST];
    char hbuf[NI_MAXHOST];
    char sbuf[NI_MAXSERV];
    char sbuf[NI_MAXSERV];
    constexpr int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
    constexpr int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
    const int err = errno;


    if (!WOULD_LOG(DEBUG)) return;
    if (!WOULD_LOG(DEBUG)) return;


@@ -1111,6 +1104,7 @@ static void dump_error(const char* str, const struct sockaddr* address, int alen
        strncpy(sbuf, "?", sizeof(sbuf) - 1);
        strncpy(sbuf, "?", sizeof(sbuf) - 1);
        sbuf[sizeof(sbuf) - 1] = '\0';
        sbuf[sizeof(sbuf) - 1] = '\0';
    }
    }
    errno = err;
    PLOG(DEBUG) << __func__ << ": " << str << " ([" << hbuf << "]." << sbuf << "): ";
    PLOG(DEBUG) << __func__ << ": " << str << " ([" << hbuf << "]." << sbuf << "): ";
}
}


Loading