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

Commit 14eba9a3 authored by Pabba Prakash's avatar Pabba Prakash Committed by Automerger Merge Worker
Browse files

DnsResolver: Support case-insensitive domain name hash am: 66707820 am:...

DnsResolver: Support case-insensitive domain name hash am: 66707820 am: 9a057c71 am: 6937fe88 am: 8425d207

Original change: https://android-review.googlesource.com/c/platform/packages/modules/DnsResolver/+/1202636

Change-Id: I99f9995a716ba677bc001ca3f4821bc2864cfe1b
parents 539777b2 8425d207
Loading
Loading
Loading
Loading
+25 −10
Original line number Diff line number Diff line
@@ -264,6 +264,22 @@ struct DnsPacket {
    const uint8_t* cursor;
};

static uint8_t res_tolower(uint8_t c) {
    return (c >= 'A' && c <= 'Z') ? (c | 0x20) : c;
}

static int res_memcasecmp(const unsigned char *s1, const unsigned char *s2, size_t len) {
    for (size_t i = 0; i < len; i++) {
        int ch1 = *s1++;
        int ch2 = *s2++;
        int d = res_tolower(ch1) - res_tolower(ch2);
        if (d != 0) {
            return d;
        }
    }
    return 0;
}

static void _dnsPacket_init(DnsPacket* packet, const uint8_t* buff, int bufflen) {
    packet->base = buff;
    packet->end = buff + bufflen;
@@ -451,14 +467,12 @@ static unsigned _dnsPacket_hashQName(DnsPacket* packet, unsigned hash) {
    const uint8_t* end = packet->end;

    for (;;) {
        int c;

        if (p >= end) { /* should not happen */
            LOG(INFO) << __func__ << ": INTERNAL_ERROR: read-overflow";
            break;
        }

        c = *p++;
        int c = *p++;

        if (c == 0) break;

@@ -470,9 +484,12 @@ static unsigned _dnsPacket_hashQName(DnsPacket* packet, unsigned hash) {
            LOG(INFO) << __func__ << ": INTERNAL_ERROR: simple label read-overflow";
            break;
        }

        while (c > 0) {
            hash = hash * FNV_MULT ^ *p++;
            c -= 1;
            uint8_t ch = *p++;
            ch = res_tolower(ch);
            hash = hash * FNV_MULT ^ ch;
            c--;
        }
    }
    packet->cursor = p;
@@ -548,14 +565,12 @@ static int _dnsPacket_isEqualDomainName(DnsPacket* pack1, DnsPacket* pack2) {
    const uint8_t* end2 = pack2->end;

    for (;;) {
        int c1, c2;

        if (p1 >= end1 || p2 >= end2) {
            LOG(INFO) << __func__ << ": INTERNAL_ERROR: read-overflow";
            break;
        }
        c1 = *p1++;
        c2 = *p2++;
        int c1 = *p1++;
        int c2 = *p2++;
        if (c1 != c2) break;

        if (c1 == 0) {
@@ -571,7 +586,7 @@ static int _dnsPacket_isEqualDomainName(DnsPacket* pack1, DnsPacket* pack2) {
            LOG(INFO) << __func__ << ": INTERNAL_ERROR: simple label read-overflow";
            break;
        }
        if (memcmp(p1, p2, c1) != 0) break;
        if (res_memcasecmp(p1, p2, c1) != 0) break;
        p1 += c1;
        p2 += c1;
        /* we rely on the bound checks at the start of the loop */
+45 −0
Original line number Diff line number Diff line
@@ -893,6 +893,51 @@ TEST_F(ResolverTest, GetAddrInfo_cnamesIllegalRdata) {
    EXPECT_TRUE(result == nullptr);
}

TEST_F(ResolverTest, GetAddrInfoForCaseInSensitiveDomains) {
    test::DNSResponder dns;
    const char* host_name = "howdy.example.com.";
    const char* host_name2 = "HOWDY.example.com.";
    const std::vector<DnsRecord> records = {
            {host_name, ns_type::ns_t_a, "1.2.3.4"},
            {host_name, ns_type::ns_t_aaaa, "::1.2.3.4"},
            {host_name2, ns_type::ns_t_a, "1.2.3.5"},
            {host_name2, ns_type::ns_t_aaaa, "::1.2.3.5"},
    };
    StartDns(dns, records);
    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());

    ScopedAddrinfo hostname_result = safe_getaddrinfo("howdy", nullptr, nullptr);
    EXPECT_TRUE(hostname_result != nullptr);
    const size_t hostname1_count_after_first_query = GetNumQueries(dns, host_name);
    EXPECT_LE(1U, hostname1_count_after_first_query);
    // Could be A or AAAA
    std::string hostname_result_str = ToString(hostname_result);
    EXPECT_TRUE(hostname_result_str == "1.2.3.4" || hostname_result_str == "::1.2.3.4");

    // Verify that the name is cached.
    ScopedAddrinfo hostname2_result = safe_getaddrinfo("HOWDY", nullptr, nullptr);
    EXPECT_TRUE(hostname2_result != nullptr);
    const size_t hostname1_count_after_second_query = GetNumQueries(dns, host_name);
    EXPECT_LE(1U, hostname1_count_after_second_query);

    // verify that there is no change in num of queries for howdy.example.com
    EXPECT_EQ(hostname1_count_after_first_query, hostname1_count_after_second_query);

    // Number of queries for HOWDY.example.com would be >= 1 if domain names
    // are considered case-sensitive, else number of queries should be 0.
    const size_t hostname2_count = GetNumQueries(dns, host_name2);
    EXPECT_EQ(0U,hostname2_count);
    std::string hostname2_result_str = ToString(hostname2_result);
    EXPECT_TRUE(hostname2_result_str == "1.2.3.4" || hostname2_result_str == "::1.2.3.4");

    // verify that the result is still the same address even though
    // mixed-case string is not in the DNS
    ScopedAddrinfo result = safe_getaddrinfo("HowDY", nullptr, nullptr);
    EXPECT_TRUE(result != nullptr);
    std::string result_str = ToString(result);
    EXPECT_TRUE(result_str == "1.2.3.4" || result_str == "::1.2.3.4");
}

TEST_F(ResolverTest, MultidomainResolution) {
    constexpr char host_name[] = "nihao.example2.com.";
    std::vector<std::string> searchDomains = {"example1.com", "example2.com", "example3.com"};