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

Commit 1930eaca authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5989825 from 1209b352 to rvc-release

Change-Id: I54e861f66825a59490753b8eb3bb6767b8c6e551
parents d2d18ea8 1209b352
Loading
Loading
Loading
Loading
+67 −108
Original line number Diff line number Diff line
@@ -397,24 +397,20 @@ static DnsQueryEvent* addDnsQueryEvent(NetworkDnsEventReported* event) {

int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int anssiz, int* rcode,
              uint32_t flags) {
    int gotsomewhere, terrno, v_circuit, resplen, n;
    ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED;
    LOG(DEBUG) << __func__;

    // Should not happen
    if (anssiz < HFIXEDSZ) {
        // TODO: Remove errno once callers stop using it
        errno = EINVAL;
        return -EINVAL;
    }
    LOG(DEBUG) << __func__;
    res_pquery(buf, buflen);

    v_circuit = buflen > PACKETSZ;
    gotsomewhere = 0;
    terrno = ETIMEDOUT;

    int anslen = 0;
    Stopwatch cacheStopwatch;
    cache_status = resolv_cache_lookup(statp->netid, buf, buflen, ans, anssiz, &anslen, flags);
    ResolvCacheStatus cache_status =
            resolv_cache_lookup(statp->netid, buf, buflen, ans, anssiz, &anslen, flags);
    const int32_t cacheLatencyUs = saturate_cast<int32_t>(cacheStopwatch.timeTakenUs());
    if (cache_status == RESOLV_CACHE_FOUND) {
        HEADER* hp = (HEADER*)(void*)ans;
@@ -442,8 +438,8 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int
    // DoT
    if (!(statp->netcontext_flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS)) {
        bool fallback = false;
        resplen = res_tls_send(statp, Slice(const_cast<uint8_t*>(buf), buflen), Slice(ans, anssiz),
                               rcode, &fallback);
        int resplen = res_tls_send(statp, Slice(const_cast<uint8_t*>(buf), buflen),
                                   Slice(ans, anssiz), rcode, &fallback);
        if (resplen > 0) {
            LOG(DEBUG) << __func__ << ": got answer from DoT";
            res_pquery(ans, resplen);
@@ -454,7 +450,7 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int
        }
        if (!fallback) {
            _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
            return -terrno;
            return -ETIMEDOUT;
        }
    }

@@ -478,90 +474,62 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int
        res_set_usable_server(selectedServer, statp->nscount, usable_servers);
    }

    /*
     * Send request, RETRY times, or until successful.
     */
    // Send request, RETRY times, or until successful.
    int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : params.retry_count;
    int useTcp = buflen > PACKETSZ;
    int gotsomewhere = 0;
    int terrno = ETIMEDOUT;

    for (int attempt = 0; attempt < retryTimes; ++attempt) {

        for (int ns = 0; ns < statp->nscount; ns++) {
        for (int ns = 0; ns < statp->nscount; ++ns) {
            if (!usable_servers[ns]) continue;
            int nsaplen;
            time_t now = 0;
            int delay = 0;

            *rcode = RCODE_INTERNAL_ERROR;

            // Get server addr
            const sockaddr* nsap = get_nsaddr(statp, ns);
            nsaplen = sockaddrSize(nsap);
            const int nsaplen = sockaddrSize(nsap);

        same_ns:
            static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
            char abuf[NI_MAXHOST];
            DnsQueryEvent* dnsQueryEvent = addDnsQueryEvent(statp->event);
            dnsQueryEvent->set_cache_hit(static_cast<CacheStatus>(cache_status));

            if (getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf), NULL, 0, niflags) == 0)
                LOG(DEBUG) << __func__ << ": Querying server (# " << ns + 1
                           << ") address = " << abuf;

            ::android::net::Protocol query_proto = useTcp ? PROTO_TCP : PROTO_UDP;
            time_t now = 0;
            int delay = 0;
            bool fallbackTCP = false;
            const bool shouldRecordStats = (attempt == 0);
            int resplen;
            Stopwatch queryStopwatch;
            if (v_circuit) {
                /* Use VC; at most one attempt per server. */
                bool shouldRecordStats = (attempt == 0);
            if (useTcp) {
                // TCP; at most one attempt per server.
                attempt = retryTimes;

                n = send_vc(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &now, rcode,
                            &delay);

                dnsQueryEvent->set_latency_micros(
                        saturate_cast<int32_t>(queryStopwatch.timeTakenUs()));
                dnsQueryEvent->set_dns_server_index(ns);
                dnsQueryEvent->set_ip_version(ipFamilyToIPVersion(nsap->sa_family));
                dnsQueryEvent->set_retry_times(attempt);
                dnsQueryEvent->set_rcode(static_cast<NsRcode>(*rcode));
                dnsQueryEvent->set_protocol(PROTO_TCP);
                dnsQueryEvent->set_type(getQueryType(buf, buflen));

                /*
                 * Only record stats the first time we try a query. This ensures that
                 * queries that deterministically fail (e.g., a name that always returns
                 * SERVFAIL or times out) do not unduly affect the stats.
                 */
                if (shouldRecordStats) {
                    res_sample sample;
                    _res_stats_set_sample(&sample, now, *rcode, delay);
                    resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, nsap, sample,
                                                           params.max_samples);
                    resolv_stats_add(statp->netid, IPSockAddr::toIPSockAddr(*nsap), dnsQueryEvent);
                }

                LOG(INFO) << __func__ << ": used send_vc " << n;

                if (n < 0) {
                    _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
                    res_nclose(statp);
                    return -terrno;
                };
                if (n == 0) goto next_ns;
                resplen = n;
                resplen = send_vc(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &now,
                                  rcode, &delay);
            } else {
                /* Use datagrams. */
                LOG(INFO) << __func__ << ": using send_dg";

                n = send_dg(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &v_circuit,
                // UDP
                resplen = send_dg(statp, &params, buf, buflen, ans, anssiz, &terrno, ns, &useTcp,
                                  &gotsomewhere, &now, rcode, &delay);
                fallbackTCP = useTcp ? true : false;
            }
            LOG(INFO) << __func__ << ": used send_" << ((useTcp) ? "vc " : "dg ") << resplen;

                dnsQueryEvent->set_latency_micros(
                        saturate_cast<int32_t>(queryStopwatch.timeTakenUs()));
            DnsQueryEvent* dnsQueryEvent = addDnsQueryEvent(statp->event);
            dnsQueryEvent->set_cache_hit(static_cast<CacheStatus>(cache_status));
            dnsQueryEvent->set_latency_micros(saturate_cast<int32_t>(queryStopwatch.timeTakenUs()));
            dnsQueryEvent->set_dns_server_index(ns);
            dnsQueryEvent->set_ip_version(ipFamilyToIPVersion(nsap->sa_family));
            dnsQueryEvent->set_retry_times(attempt);
            dnsQueryEvent->set_rcode(static_cast<NsRcode>(*rcode));
                dnsQueryEvent->set_protocol(PROTO_UDP);
            dnsQueryEvent->set_protocol(query_proto);
            dnsQueryEvent->set_type(getQueryType(buf, buflen));

                /* Only record stats the first time we try a query. See above. */
                if (attempt == 0) {
            // Only record stats the first time we try a query. This ensures that
            // queries that deterministically fail (e.g., a name that always returns
            // SERVFAIL or times out) do not unduly affect the stats.
            if (shouldRecordStats) {
                res_sample sample;
                _res_stats_set_sample(&sample, now, *rcode, delay);
                resolv_cache_add_resolver_stats_sample(statp->netid, revision_id, nsap, sample,
@@ -569,17 +537,16 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int
                resolv_stats_add(statp->netid, IPSockAddr::toIPSockAddr(*nsap), dnsQueryEvent);
            }

                LOG(INFO) << __func__ << ": used send_dg " << n;

                if (n < 0) {
            if (resplen == 0) continue;
            if (fallbackTCP) {
                ns--;
                continue;
            }
            if (resplen < 0) {
                _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
                res_nclose(statp);
                return -terrno;
            };
                if (n == 0) goto next_ns;
                if (v_circuit) goto same_ns;
                resplen = n;
            }

            LOG(DEBUG) << __func__ << ": got answer:";
            res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
@@ -589,23 +556,15 @@ int res_nsend(res_state statp, const uint8_t* buf, int buflen, uint8_t* ans, int
            }
            res_nclose(statp);
            return (resplen);
        next_ns:;
        }  // for each ns
    }  // for each retry
    res_nclose(statp);
    if (!v_circuit) {
        if (!gotsomewhere) {
            // TODO: Remove errno once callers stop using it
            errno = ECONNREFUSED; /* no nameservers found */
            terrno = ECONNREFUSED;
        } else {
    terrno = useTcp ? terrno : gotsomewhere ? ETIMEDOUT : ECONNREFUSED;
    // TODO: Remove errno once callers stop using it
            errno = ETIMEDOUT; /* no answer obtained */
            terrno = ETIMEDOUT;
        }
    } else {
        errno = terrno;
    }
    errno = useTcp ? terrno
                   : gotsomewhere ? ETIMEDOUT /* no answer obtained */
                                  : ECONNREFUSED /* no nameservers found */;

    _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
    return -terrno;
}
+155 −26
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <netdutils/InternetAddresses.h>
#include <netdutils/NetworkConstants.h>  // SHA256_SIZE
#include <netdutils/ResponseCode.h>
#include <netdutils/Slice.h>
#include <netdutils/SocketOption.h>
#include <netinet/in.h>
#include <openssl/base64.h>
@@ -89,8 +90,10 @@ using android::net::INetd;
using android::net::ResolverStats;
using android::net::metrics::DnsMetricsListener;
using android::netdutils::enableSockopt;
using android::netdutils::makeSlice;
using android::netdutils::ResponseCode;
using android::netdutils::ScopedAddrinfo;
using android::netdutils::toHex;

// TODO: move into libnetdutils?
namespace {
@@ -3492,23 +3495,39 @@ TEST_F(ResolverTest, ConnectTlsServerTimeout) {
// TODO: Perhaps move parameterized tests to an independent file.
enum class CallType { GETADDRINFO, GETHOSTBYNAME };
class ResolverParameterizedTest : public ResolverTest,
                                  public testing::WithParamInterface<CallType> {};
                                  public testing::WithParamInterface<CallType> {
  protected:
    void VerifyQueryHelloExampleComV4(const test::DNSResponder& dns, const CallType calltype) {
        if (calltype == CallType::GETADDRINFO) {
            const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
            ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
            ASSERT_TRUE(result != nullptr);
            EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
        } else if (calltype == CallType::GETHOSTBYNAME) {
            const hostent* result = gethostbyname("hello");
            ASSERT_TRUE(result != nullptr);
            ASSERT_EQ(4, result->h_length);
            ASSERT_FALSE(result->h_addr_list[0] == nullptr);
            EXPECT_EQ(kHelloExampleComAddrV4, ToString(result));
            EXPECT_TRUE(result->h_addr_list[1] == nullptr);
        } else {
            FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
        }
        EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
    }
};

INSTANTIATE_TEST_SUITE_P(TestQueryCall, ResolverParameterizedTest,
INSTANTIATE_TEST_SUITE_P(QueryCallTest, ResolverParameterizedTest,
                         testing::Values(CallType::GETADDRINFO, CallType::GETHOSTBYNAME),
                         [](const testing::TestParamInfo<CallType>& info) {
                             std::string name;
                             switch (info.param) {
                                 case CallType::GETADDRINFO:
                                     name = "GetAddrInfo";
                                     break;
                                     return "GetAddrInfo";
                                 case CallType::GETHOSTBYNAME:
                                     name = "GetHostByName";
                                     break;
                                     return "GetHostByName";
                                 default:
                                     name = "InvalidParameter";  // Should not happen.
                                     return "InvalidParameter";  // Should not happen.
                             }
                             return name;
                         });

TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
@@ -3549,7 +3568,7 @@ TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
            .rclass = ns_c_in,
            .ttl = 0,  // no cache
    };
    EXPECT_TRUE(test::DNSResponder::fillRdata("1.2.3.4", recordAnswer));
    EXPECT_TRUE(test::DNSResponder::fillRdata(kHelloExampleComAddrV4, recordAnswer));
    header.answers.push_back(std::move(recordAnswer));

    // Authority section.
@@ -3580,21 +3599,131 @@ TEST_P(ResolverParameterizedTest, AuthoritySectionAndAdditionalSection) {
    dns.clearQueries();

    // Expect that get the address and the resolver doesn't crash.
    if (calltype == CallType::GETADDRINFO) {
        const addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_DGRAM};
        ScopedAddrinfo result = safe_getaddrinfo("hello", nullptr, &hints);
        EXPECT_TRUE(result != nullptr);
        EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
        EXPECT_EQ("1.2.3.4", ToString(result));
    } else if (calltype == CallType::GETHOSTBYNAME) {
        const hostent* result = gethostbyname("hello");
        EXPECT_EQ(1U, GetNumQueries(dns, kHelloExampleCom));
        ASSERT_FALSE(result == nullptr);
        ASSERT_EQ(4, result->h_length);
        ASSERT_FALSE(result->h_addr_list[0] == nullptr);
        EXPECT_EQ("1.2.3.4", ToString(result));
        EXPECT_TRUE(result->h_addr_list[1] == nullptr);
    } else {
        FAIL() << "Unsupported call type: " << static_cast<uint32_t>(calltype);
    VerifyQueryHelloExampleComV4(dns, calltype);
}

TEST_P(ResolverParameterizedTest, MessageCompression) {
    const auto& calltype = GetParam();

    // The response with compressed domain name by a pointer. See RFC 1035 section 4.1.4.
    //
    // Ignoring the other fields of the message, the domain name of question section and answer
    // section are presented as:
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 12 |           5           |           h           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 14 |           e           |           l           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 16 |           l           |           o           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 18 |           7           |           e           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 20 |           x           |           a           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 22 |           m           |           p           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 24 |           l           |           e           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 26 |           3           |           c           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 28 |           o           |           m           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 30 |           0           |          ...          |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    //
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 35 | 1  1|                12                       |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    const std::vector<uint8_t> kResponseAPointer = {
            /* Header */
            0x00, 0x00, /* Transaction ID: 0x0000 */
            0x81, 0x80, /* Flags: qr rd ra */
            0x00, 0x01, /* Questions: 1 */
            0x00, 0x01, /* Answer RRs: 1 */
            0x00, 0x00, /* Authority RRs: 0 */
            0x00, 0x00, /* Additional RRs: 0 */
            /* Queries */
            0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
            0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
            0x00, 0x01,                   /* Type: A */
            0x00, 0x01,                   /* Class: IN */
            /* Answers */
            0xc0, 0x0c,             /* Name: hello.example.com (a pointer) */
            0x00, 0x01,             /* Type: A */
            0x00, 0x01,             /* Class: IN */
            0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
            0x00, 0x04,             /* Data length: 4 */
            0x01, 0x02, 0x03, 0x04  /* Address: 1.2.3.4 */
    };

    // The response with compressed domain name by a sequence of labels ending with a pointer. See
    // RFC 1035 section 4.1.4.
    //
    // Ignoring the other fields of the message, the domain name of question section and answer
    // section are presented as:
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 12 |           5           |           h           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 14 |           e           |           l           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 16 |           l           |           o           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 18 |           7           |           e           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 20 |           x           |           a           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 22 |           m           |           p           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 24 |           l           |           e           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 26 |           3           |           c           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 28 |           o           |           m           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 30 |           0           |          ...          |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    //
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 35 |           5           |           h           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 37 |           e           |           l           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 39 |           l           |           o           |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    // 41 | 1  1|                18                       |
    //    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    const std::vector<uint8_t> kResponseLabelEndingWithAPointer = {
            /* Header */
            0x00, 0x00, /* Transaction ID: 0x0000 */
            0x81, 0x80, /* Flags: qr rd ra */
            0x00, 0x01, /* Questions: 1 */
            0x00, 0x01, /* Answer RRs: 1 */
            0x00, 0x00, /* Authority RRs: 0 */
            0x00, 0x00, /* Additional RRs: 0 */
            /* Queries */
            0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
            0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
            0x00, 0x01,                   /* Type: A */
            0x00, 0x01,                   /* Class: IN */
            /* Answers */
            0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xc0,
            0x12,                   /* Name: hello.example.com (a label ending with a pointer) */
            0x00, 0x01,             /* Type: A */
            0x00, 0x01,             /* Class: IN */
            0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
            0x00, 0x04,             /* Data length: 4 */
            0x01, 0x02, 0x03, 0x04  /* Address: 1.2.3.4 */
    };

    for (const auto& response : {kResponseAPointer, kResponseLabelEndingWithAPointer}) {
        SCOPED_TRACE(StringPrintf("Hex dump: %s", toHex(makeSlice(response)).c_str()));

        test::DNSResponder dns(test::DNSResponder::MappingType::BINARY_PACKET);
        dns.addMappingBinaryPacket(kHelloExampleComQueryV4, response);
        StartDns(dns, {});
        ASSERT_TRUE(mDnsClient.SetResolversForNetwork());

        // Expect no cache because the TTL of testing responses are 0.
        VerifyQueryHelloExampleComV4(dns, calltype);
    }
}
 No newline at end of file
+0 −38
Original line number Diff line number Diff line
@@ -33,44 +33,6 @@ namespace net {
using android::net::NetworkDnsEventReported;
using android::netdutils::ScopedAddrinfo;

static const std::vector<uint8_t> kHelloExampleComQueryV4 = {
        /* Header */
        0x00, 0x00, /* Transaction ID: 0x0000 */
        0x01, 0x00, /* Flags: rd */
        0x00, 0x01, /* Questions: 1 */
        0x00, 0x00, /* Answer RRs: 0 */
        0x00, 0x00, /* Authority RRs: 0 */
        0x00, 0x00, /* Additional RRs: 0 */
        /* Queries */
        0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03,
        0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
        0x00, 0x01,             /* Type: A */
        0x00, 0x01              /* Class: IN */
};

static const std::vector<uint8_t> kHelloExampleComResponseV4 = {
        /* Header */
        0x00, 0x00, /* Transaction ID: 0x0000 */
        0x81, 0x80, /* Flags: qr rd ra */
        0x00, 0x01, /* Questions: 1 */
        0x00, 0x01, /* Answer RRs: 1 */
        0x00, 0x00, /* Authority RRs: 0 */
        0x00, 0x00, /* Additional RRs: 0 */
        /* Queries */
        0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03,
        0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
        0x00, 0x01,             /* Type: A */
        0x00, 0x01,             /* Class: IN */
        /* Answers */
        0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03,
        0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
        0x00, 0x01,             /* Type: A */
        0x00, 0x01,             /* Class: IN */
        0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
        0x00, 0x04,             /* Data length: 4 */
        0x01, 0x02, 0x03, 0x04  /* Address: 1.2.3.4 */
};

// Fixture test class definition.
class TestBase : public ::testing::Test {
  protected:
+39 −0
Original line number Diff line number Diff line
@@ -43,6 +43,45 @@ static constexpr char kLocalHostAddr[] = "127.0.0.1";
static constexpr char kIp6LocalHost[] = "ip6-localhost";
static constexpr char kIp6LocalHostAddr[] = "::1";
static constexpr char kHelloExampleCom[] = "hello.example.com.";
static constexpr char kHelloExampleComAddrV4[] = "1.2.3.4";

static const std::vector<uint8_t> kHelloExampleComQueryV4 = {
        /* Header */
        0x00, 0x00, /* Transaction ID: 0x0000 */
        0x01, 0x00, /* Flags: rd */
        0x00, 0x01, /* Questions: 1 */
        0x00, 0x00, /* Answer RRs: 0 */
        0x00, 0x00, /* Authority RRs: 0 */
        0x00, 0x00, /* Additional RRs: 0 */
        /* Queries */
        0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03,
        0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
        0x00, 0x01,             /* Type: A */
        0x00, 0x01              /* Class: IN */
};

static const std::vector<uint8_t> kHelloExampleComResponseV4 = {
        /* Header */
        0x00, 0x00, /* Transaction ID: 0x0000 */
        0x81, 0x80, /* Flags: qr rd ra */
        0x00, 0x01, /* Questions: 1 */
        0x00, 0x01, /* Answer RRs: 1 */
        0x00, 0x00, /* Authority RRs: 0 */
        0x00, 0x00, /* Additional RRs: 0 */
        /* Queries */
        0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03,
        0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
        0x00, 0x01,             /* Type: A */
        0x00, 0x01,             /* Class: IN */
        /* Answers */
        0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03,
        0x63, 0x6f, 0x6d, 0x00, /* Name: hello.example.com */
        0x00, 0x01,             /* Type: A */
        0x00, 0x01,             /* Class: IN */
        0x00, 0x00, 0x00, 0x00, /* Time to live: 0 */
        0x00, 0x04,             /* Data length: 4 */
        0x01, 0x02, 0x03, 0x04  /* Address: 1.2.3.4 */
};

// Illegal hostnames
static constexpr char kBadCharAfterPeriodHost[] = "hello.example.^com.";