| Index: net/dns/dns_response_unittest.cc
|
| diff --git a/net/dns/dns_response_unittest.cc b/net/dns/dns_response_unittest.cc
|
| index 41f3a7296929c94add82acd33486d3be91fe4e1f..6cbf6a1b7b75cc4ecfac559a508ea08be218760e 100644
|
| --- a/net/dns/dns_response_unittest.cc
|
| +++ b/net/dns/dns_response_unittest.cc
|
| @@ -4,9 +4,14 @@
|
|
|
| #include "net/dns/dns_response.h"
|
|
|
| +#include "base/time.h"
|
| +#include "net/base/address_list.h"
|
| #include "net/base/io_buffer.h"
|
| +#include "net/base/net_util.h"
|
| +#include "net/base/sys_addrinfo.h"
|
| #include "net/dns/dns_protocol.h"
|
| #include "net/dns/dns_query.h"
|
| +#include "net/dns/dns_test_util.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace net {
|
| @@ -24,7 +29,7 @@ TEST(DnsRecordParserTest, Constructor) {
|
| EXPECT_TRUE(DnsRecordParser(data, 1, 1).AtEnd());
|
| }
|
|
|
| -TEST(DnsRecordParserTest, ParseName) {
|
| +TEST(DnsRecordParserTest, ReadName) {
|
| const uint8 data[] = {
|
| // all labels "foo.example.com"
|
| 0x03, 'f', 'o', 'o',
|
| @@ -46,31 +51,31 @@ TEST(DnsRecordParserTest, ParseName) {
|
| DnsRecordParser parser(data, sizeof(data), 0);
|
| ASSERT_TRUE(parser.IsValid());
|
|
|
| - EXPECT_EQ(0x11, parser.ParseName(data + 0x00, &out));
|
| + EXPECT_EQ(0x11u, parser.ReadName(data + 0x00, &out));
|
| EXPECT_EQ("foo.example.com", out);
|
| // Check that the last "." is never stored.
|
| out.clear();
|
| - EXPECT_EQ(0x1, parser.ParseName(data + 0x10, &out));
|
| + EXPECT_EQ(0x1u, parser.ReadName(data + 0x10, &out));
|
| EXPECT_EQ("", out);
|
| out.clear();
|
| - EXPECT_EQ(0x6, parser.ParseName(data + 0x11, &out));
|
| + EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, &out));
|
| EXPECT_EQ("bar.example.com", out);
|
| out.clear();
|
| - EXPECT_EQ(0x2, parser.ParseName(data + 0x17, &out));
|
| + EXPECT_EQ(0x2u, parser.ReadName(data + 0x17, &out));
|
| EXPECT_EQ("bar.example.com", out);
|
|
|
| // Parse name without storing it.
|
| - EXPECT_EQ(0x11, parser.ParseName(data + 0x00, NULL));
|
| - EXPECT_EQ(0x1, parser.ParseName(data + 0x10, NULL));
|
| - EXPECT_EQ(0x6, parser.ParseName(data + 0x11, NULL));
|
| - EXPECT_EQ(0x2, parser.ParseName(data + 0x17, NULL));
|
| + EXPECT_EQ(0x11u, parser.ReadName(data + 0x00, NULL));
|
| + EXPECT_EQ(0x1u, parser.ReadName(data + 0x10, NULL));
|
| + EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, NULL));
|
| + EXPECT_EQ(0x2u, parser.ReadName(data + 0x17, NULL));
|
|
|
| // Check that it works even if initial position is different.
|
| parser = DnsRecordParser(data, sizeof(data), 0x12);
|
| - EXPECT_EQ(0x6, parser.ParseName(data + 0x11, NULL));
|
| + EXPECT_EQ(0x6u, parser.ReadName(data + 0x11, NULL));
|
| }
|
|
|
| -TEST(DnsRecordParserTest, ParseNameFail) {
|
| +TEST(DnsRecordParserTest, ReadNameFail) {
|
| const uint8 data[] = {
|
| // label length beyond packet
|
| 0x30, 'x', 'x',
|
| @@ -90,15 +95,15 @@ TEST(DnsRecordParserTest, ParseNameFail) {
|
| ASSERT_TRUE(parser.IsValid());
|
|
|
| std::string out;
|
| - EXPECT_EQ(0, parser.ParseName(data + 0x00, &out));
|
| - EXPECT_EQ(0, parser.ParseName(data + 0x04, &out));
|
| - EXPECT_EQ(0, parser.ParseName(data + 0x08, &out));
|
| - EXPECT_EQ(0, parser.ParseName(data + 0x0a, &out));
|
| - EXPECT_EQ(0, parser.ParseName(data + 0x0c, &out));
|
| - EXPECT_EQ(0, parser.ParseName(data + 0x0e, &out));
|
| + EXPECT_EQ(0u, parser.ReadName(data + 0x00, &out));
|
| + EXPECT_EQ(0u, parser.ReadName(data + 0x04, &out));
|
| + EXPECT_EQ(0u, parser.ReadName(data + 0x08, &out));
|
| + EXPECT_EQ(0u, parser.ReadName(data + 0x0a, &out));
|
| + EXPECT_EQ(0u, parser.ReadName(data + 0x0c, &out));
|
| + EXPECT_EQ(0u, parser.ReadName(data + 0x0e, &out));
|
| }
|
|
|
| -TEST(DnsRecordParserTest, ParseRecord) {
|
| +TEST(DnsRecordParserTest, ReadRecord) {
|
| const uint8 data[] = {
|
| // Type CNAME record.
|
| 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
|
| @@ -124,17 +129,17 @@ TEST(DnsRecordParserTest, ParseRecord) {
|
| DnsRecordParser parser(data, sizeof(data), 0);
|
|
|
| DnsResourceRecord record;
|
| - EXPECT_TRUE(parser.ParseRecord(&record));
|
| + EXPECT_TRUE(parser.ReadRecord(&record));
|
| EXPECT_EQ("example.com", record.name);
|
| EXPECT_EQ(dns_protocol::kTypeCNAME, record.type);
|
| EXPECT_EQ(dns_protocol::kClassIN, record.klass);
|
| EXPECT_EQ(0x00012474u, record.ttl);
|
| EXPECT_EQ(6u, record.rdata.length());
|
| - EXPECT_EQ(6, parser.ParseName(record.rdata.data(), &out));
|
| + EXPECT_EQ(6u, parser.ReadName(record.rdata.data(), &out));
|
| EXPECT_EQ("foo.example.com", out);
|
| EXPECT_FALSE(parser.AtEnd());
|
|
|
| - EXPECT_TRUE(parser.ParseRecord(&record));
|
| + EXPECT_TRUE(parser.ReadRecord(&record));
|
| EXPECT_EQ("bar.example.com", record.name);
|
| EXPECT_EQ(dns_protocol::kTypeA, record.type);
|
| EXPECT_EQ(dns_protocol::kClassIN, record.klass);
|
| @@ -145,9 +150,9 @@ TEST(DnsRecordParserTest, ParseRecord) {
|
|
|
| // Test truncated record.
|
| parser = DnsRecordParser(data, sizeof(data) - 2, 0);
|
| - EXPECT_TRUE(parser.ParseRecord(&record));
|
| + EXPECT_TRUE(parser.ReadRecord(&record));
|
| EXPECT_FALSE(parser.AtEnd());
|
| - EXPECT_FALSE(parser.ParseRecord(&record));
|
| + EXPECT_FALSE(parser.ReadRecord(&record));
|
| }
|
|
|
| TEST(DnsResponseTest, InitParse) {
|
| @@ -225,7 +230,7 @@ TEST(DnsResponseTest, InitParse) {
|
| // Check header access.
|
| EXPECT_EQ(0x8180, resp.flags());
|
| EXPECT_EQ(0x0, resp.rcode());
|
| - EXPECT_EQ(2, resp.answer_count());
|
| + EXPECT_EQ(2u, resp.answer_count());
|
|
|
| // Check question access.
|
| EXPECT_EQ(query->qname(), resp.qname());
|
| @@ -234,11 +239,224 @@ TEST(DnsResponseTest, InitParse) {
|
|
|
| DnsResourceRecord record;
|
| DnsRecordParser parser = resp.Parser();
|
| - EXPECT_TRUE(parser.ParseRecord(&record));
|
| + EXPECT_TRUE(parser.ReadRecord(&record));
|
| EXPECT_FALSE(parser.AtEnd());
|
| - EXPECT_TRUE(parser.ParseRecord(&record));
|
| + EXPECT_TRUE(parser.ReadRecord(&record));
|
| EXPECT_TRUE(parser.AtEnd());
|
| - EXPECT_FALSE(parser.ParseRecord(&record));
|
| + EXPECT_FALSE(parser.ReadRecord(&record));
|
| +}
|
| +
|
| +void VerifyAddressList(const std::vector<const char*>& ip_addresses,
|
| + const AddressList& addrlist) {
|
| + ASSERT_GT(ip_addresses.size(), 0u);
|
| + ASSERT_NE(static_cast<addrinfo*>(NULL), addrlist.head());
|
| +
|
| + IPAddressNumber ip_number;
|
| + const struct addrinfo* ainfo = addrlist.head();
|
| + for (std::vector<const char*>::const_iterator i = ip_addresses.begin();
|
| + i != ip_addresses.end(); ++i, ainfo = ainfo->ai_next) {
|
| + ASSERT_NE(static_cast<addrinfo*>(NULL), ainfo);
|
| + EXPECT_EQ(sizeof(struct sockaddr_in),
|
| + static_cast<size_t>(ainfo->ai_addrlen));
|
| +
|
| + const struct sockaddr* sa = ainfo->ai_addr;
|
| + EXPECT_STREQ(*i, NetAddressToString(sa, ainfo->ai_addrlen).c_str());
|
| + }
|
| + ASSERT_EQ(static_cast<addrinfo*>(NULL), ainfo);
|
| +}
|
| +
|
| +TEST(DnsResponseTest, ParseToAddressList) {
|
| + const struct TestCase {
|
| + size_t query_size;
|
| + const uint8* response_data;
|
| + size_t response_size;
|
| + const char* const* expected_addresses;
|
| + size_t num_expected_addresses;
|
| + const char* expected_cname;
|
| + int expected_ttl_sec;
|
| + } cases[] = {
|
| + {
|
| + kT0QuerySize,
|
| + kT0ResponseDatagram, arraysize(kT0ResponseDatagram),
|
| + kT0IpAddresses, arraysize(kT0IpAddresses),
|
| + kT0CanonName,
|
| + kT0TTL,
|
| + },
|
| + {
|
| + kT1QuerySize,
|
| + kT1ResponseDatagram, arraysize(kT1ResponseDatagram),
|
| + kT1IpAddresses, arraysize(kT1IpAddresses),
|
| + kT1CanonName,
|
| + kT1TTL,
|
| + },
|
| + {
|
| + kT2QuerySize,
|
| + kT2ResponseDatagram, arraysize(kT2ResponseDatagram),
|
| + kT2IpAddresses, arraysize(kT2IpAddresses),
|
| + kT2CanonName,
|
| + kT2TTL,
|
| + },
|
| + {
|
| + kT3QuerySize,
|
| + kT3ResponseDatagram, arraysize(kT3ResponseDatagram),
|
| + kT3IpAddresses, arraysize(kT3IpAddresses),
|
| + kT3CanonName,
|
| + kT3TTL,
|
| + },
|
| + };
|
| +
|
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
|
| + const TestCase& t = cases[i];
|
| + DnsResponse response(t.response_data, t.response_size, t.query_size);
|
| + AddressList addr_list;
|
| + base::TimeDelta ttl;
|
| + EXPECT_EQ(DnsResponse::DNS_SUCCESS,
|
| + response.ParseToAddressList(&addr_list, &ttl));
|
| + std::vector<const char*> expected_addresses(
|
| + t.expected_addresses,
|
| + t.expected_addresses + t.num_expected_addresses);
|
| + VerifyAddressList(expected_addresses, addr_list);
|
| + std::string cname;
|
| + ASSERT_TRUE(addr_list.GetCanonicalName(&cname));
|
| + EXPECT_EQ(t.expected_cname, cname);
|
| + EXPECT_EQ(base::TimeDelta::FromSeconds(t.expected_ttl_sec), ttl);
|
| + }
|
| +}
|
| +
|
| +const uint8 kResponseTruncatedRecord[] = {
|
| + // Header: 1 question, 1 answer RR
|
| + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
| + // Question: name = 'a', type = A (0x1)
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
|
| + // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, // Truncated RDATA.
|
| +};
|
| +
|
| +const uint8 kResponseTruncatedCNAME[] = {
|
| + // Header: 1 question, 1 answer RR
|
| + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
| + // Question: name = 'a', type = A (0x1)
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
|
| + // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = 'foo' (truncated)
|
| + 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x03, 0x03, 'f', 'o', // Truncated name.
|
| +};
|
| +
|
| +const uint8 kResponseNameMismatch[] = {
|
| + // Header: 1 question, 1 answer RR
|
| + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
| + // Question: name = 'a', type = A (0x1)
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
|
| + // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
|
| + 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
|
| +};
|
| +
|
| +const uint8 kResponseNameMismatchInChain[] = {
|
| + // Header: 1 question, 3 answer RR
|
| + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
|
| + // Question: name = 'a', type = A (0x1)
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
|
| + // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = "b"
|
| + 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x03, 0x01, 'b', 0x00,
|
| + // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
|
| + 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
|
| + // Answer: name = 'c', type = A, TTL = 0xFF, RDATA = 10.10.10.11
|
| + 0x01, 'c', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0B,
|
| +};
|
| +
|
| +const uint8 kResponseSizeMismatch[] = {
|
| + // Header: 1 answer RR
|
| + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
| + // Question: name = 'a', type = AAAA (0x1c)
|
| + 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01,
|
| + // Answer: name = 'a', type = AAAA, TTL = 0xFF, RDATA = 10.10.10.10
|
| + 0x01, 'a', 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
|
| +};
|
| +
|
| +const uint8 kResponseCNAMEAfterAddress[] = {
|
| + // Header: 2 answer RR
|
| + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
| + // Question: name = 'a', type = A (0x1)
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
|
| + // Answer: name = 'a', type = A, TTL = 0xFF, RDATA = 10.10.10.10.
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
|
| + // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = "b"
|
| + 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x03, 0x01, 'b', 0x00,
|
| +};
|
| +
|
| +const uint8 kResponseTTLMismatch[] = {
|
| + // Header: 1 question, 3 answer RR
|
| + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
|
| + // Question: name = 'a', type = A (0x1)
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
|
| + // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = "b"
|
| + 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x03, 0x01, 'b', 0x00,
|
| + // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
|
| + 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
|
| + // Answer: name = 'b', type = A, TTL = 0xBB, RDATA = 10.10.10.11
|
| + 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xBB,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0B,
|
| +};
|
| +
|
| +const uint8 kResponseNoAddresses[] = {
|
| + // Header: 1 question, 1 answer RR, 1 authority RR
|
| + 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
| + // Question: name = 'a', type = A (0x1)
|
| + 0x01, 'a', 0x00, 0x00, 0x01, 0x00, 0x01,
|
| + // Answer: name = 'a', type = CNAME, TTL = 0xFF, RDATA = "b"
|
| + 0x01, 'a', 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x03, 0x01, 'b', 0x00,
|
| + // Authority section
|
| + // Answer: name = 'b', type = A, TTL = 0xFF, RDATA = 10.10.10.10
|
| + 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF,
|
| + 0x00, 0x04, 0x0A, 0x0A, 0x0A, 0x0A,
|
| +};
|
| +
|
| +TEST(DnsResponseTest, ParseToAddressListFail) {
|
| + const struct TestCase {
|
| + const uint8* data;
|
| + size_t size;
|
| + DnsResponse::Result expected_result;
|
| + } cases[] = {
|
| + { kResponseTruncatedRecord, arraysize(kResponseTruncatedRecord),
|
| + DnsResponse::DNS_MALFORMED_RESPONSE },
|
| + { kResponseTruncatedCNAME, arraysize(kResponseTruncatedCNAME),
|
| + DnsResponse::DNS_MALFORMED_CNAME },
|
| + { kResponseNameMismatch, arraysize(kResponseNameMismatch),
|
| + DnsResponse::DNS_NAME_MISMATCH },
|
| + { kResponseNameMismatchInChain, arraysize(kResponseNameMismatchInChain),
|
| + DnsResponse::DNS_NAME_MISMATCH },
|
| + { kResponseSizeMismatch, arraysize(kResponseSizeMismatch),
|
| + DnsResponse::DNS_SIZE_MISMATCH },
|
| + { kResponseCNAMEAfterAddress, arraysize(kResponseCNAMEAfterAddress),
|
| + DnsResponse::DNS_CNAME_AFTER_ADDRESS },
|
| + { kResponseTTLMismatch, arraysize(kResponseTTLMismatch),
|
| + DnsResponse::DNS_ADDRESS_TTL_MISMATCH },
|
| + { kResponseNoAddresses, arraysize(kResponseNoAddresses),
|
| + DnsResponse::DNS_NO_ADDRESSES },
|
| + };
|
| +
|
| + const size_t kQuerySize = 12 + 7;
|
| +
|
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
|
| + const TestCase& t = cases[i];
|
| +
|
| + DnsResponse response(t.data, t.size, kQuerySize);
|
| + AddressList addr_list;
|
| + base::TimeDelta ttl;
|
| + EXPECT_EQ(t.expected_result,
|
| + response.ParseToAddressList(&addr_list, &ttl));
|
| + }
|
| }
|
|
|
| } // namespace
|
|
|