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

Commit 041d76df authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Don't query AAAA in case DUT has only link local address." am: 47c1f052

parents 50a32e0f 47c1f052
Loading
Loading
Loading
Loading
+28 −13
Original line number Diff line number Diff line
@@ -147,7 +147,8 @@ static struct addrinfo* _gethtent(FILE**, const char*, const struct addrinfo*);
static struct addrinfo* getCustomHosts(const size_t netid, const char*, const struct addrinfo*);
static bool files_getaddrinfo(const size_t netid, const char* name, const addrinfo* pai,
                              addrinfo** res);
static int _find_src_addr(const struct sockaddr*, struct sockaddr*, unsigned, uid_t);
static int _find_src_addr(const struct sockaddr*, struct sockaddr*, unsigned, uid_t,
                          bool allow_v6_linklocal);

static int res_queryN(const char* name, res_target* target, ResState* res, int* herrno);
static int res_searchN(const char* name, res_target* target, ResState* res, int* herrno);
@@ -220,13 +221,14 @@ void freeaddrinfo(struct addrinfo* ai) {
 * on the local system". However, bionic doesn't currently support getifaddrs,
 * so checking for connectivity is the next best thing.
 */
static int have_ipv6(unsigned mark, uid_t uid) {
static int have_ipv6(unsigned mark, uid_t uid, bool mdns) {
    static const struct sockaddr_in6 sin6_test = {
            .sin6_family = AF_INET6,
            .sin6_addr.s6_addr = {// 2000::
                                  0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
    sockaddr_union addr = {.sin6 = sin6_test};
    return _find_src_addr(&addr.sa, NULL, mark, uid) == 1;
    sockaddr sa;
    return _find_src_addr(&addr.sa, &sa, mark, uid, /*allow_v6_linklocal=*/mdns) == 1;
}

static int have_ipv4(unsigned mark, uid_t uid) {
@@ -235,7 +237,8 @@ static int have_ipv4(unsigned mark, uid_t uid) {
            .sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
    };
    sockaddr_union addr = {.sin = sin_test};
    return _find_src_addr(&addr.sa, NULL, mark, uid) == 1;
    sockaddr sa;
    return _find_src_addr(&addr.sa, &sa, mark, uid, /*(don't care) allow_v6_linklocal=*/false) == 1;
}

// Internal version of getaddrinfo(), but limited to AI_NUMERICHOST.
@@ -1256,7 +1259,8 @@ static int _rfc6724_compare(const void* ptr1, const void* ptr2) {

/*
 * Find the source address that will be used if trying to connect to the given
 * address. src_addr must be large enough to hold a struct sockaddr_in6.
 * address. src_addr must be assigned and large enough to hold a struct sockaddr_in6.
 * allow_v6_linklocal controls whether to accept link-local source addresses.
 *
 * Returns 1 if a source address was found, 0 if the address is unreachable,
 * and -1 if a fatal error occurred. If 0 or -1, the contents of src_addr are
@@ -1264,7 +1268,9 @@ static int _rfc6724_compare(const void* ptr1, const void* ptr2) {
 */

static int _find_src_addr(const struct sockaddr* addr, struct sockaddr* src_addr, unsigned mark,
                          uid_t uid) {
                          uid_t uid, bool allow_v6_linklocal) {
    if (src_addr == nullptr) return -1;

    int sock;
    int ret;
    socklen_t len;
@@ -1306,10 +1312,19 @@ static int _find_src_addr(const struct sockaddr* addr, struct sockaddr* src_addr
        return 0;
    }

    if (src_addr && getsockname(sock, src_addr, &len) == -1) {
    if (getsockname(sock, src_addr, &len) == -1) {
        close(sock);
        return -1;
    }

    if (src_addr->sa_family == AF_INET6) {
        sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(src_addr);
        if (!allow_v6_linklocal && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
            close(sock);
            return 0;
        }
    }

    close(sock);
    return 1;
}
@@ -1347,7 +1362,8 @@ void resolv_rfc6724_sort(struct addrinfo* list_sentinel, unsigned mark, uid_t ui
        elems[i].ai = cur;
        elems[i].original_order = i;

        has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.sa, mark, uid);
        has_src_addr = _find_src_addr(cur->ai_addr, &elems[i].src_addr.sa, mark, uid,
                                      /*allow_v6_linklocal=*/true);
        if (has_src_addr == -1) {
            goto error;
        }
@@ -1372,6 +1388,8 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai,
                           NetworkDnsEventReported* event) {
    res_target q = {};
    res_target q2 = {};
    ResState res(netcontext, event);
    setMdnsFlag(name, res.netid, &(res.flags));

    switch (pai->ai_family) {
        case AF_UNSPEC: {
@@ -1380,7 +1398,8 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai,
            q.qclass = C_IN;
            int query_ipv6 = 1, query_ipv4 = 1;
            if (pai->ai_flags & AI_ADDRCONFIG) {
                query_ipv6 = have_ipv6(netcontext->app_mark, netcontext->uid);
                query_ipv6 = have_ipv6(netcontext->app_mark, netcontext->uid,
                                       isMdnsResolution(res.flags));
                query_ipv4 = have_ipv4(netcontext->app_mark, netcontext->uid);
            }
            if (query_ipv6) {
@@ -1412,10 +1431,6 @@ static int dns_getaddrinfo(const char* name, const addrinfo* pai,
            return EAI_FAMILY;
    }

    ResState res(netcontext, event);

    setMdnsFlag(name, res.netid, &(res.flags));

    int he;
    if (res_searchN(name, &q, &res, &he) < 0) {
        // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA.