Commit 8539e492 authored by Eric Orth's avatar Eric Orth Committed by Commit Bot

Create generic DNS test response/record builders

Convert and simplify all the type-specific builders to use them. Also
convert integrity tests to just use a generic builder because the
integrity-specific builder only ever took raw bytes anyway.

Change-Id: I1972c9aaf79b749ed82516fccd473547b2c931ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2477535Reviewed-by: default avatarDan McArdle <dmcardle@chromium.org>
Commit-Queue: Eric Orth <ericorth@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818604}
parent 8f53fa95
...@@ -67,177 +67,88 @@ class MockAddressSorter : public AddressSorter { ...@@ -67,177 +67,88 @@ class MockAddressSorter : public AddressSorter {
} }
}; };
DnsResourceRecord BuildCannonnameRecord(std::string name, } // namespace
std::string cannonname) {
DCHECK(!name.empty());
DCHECK(!cannonname.empty());
DnsResourceRecord record;
record.name = std::move(name);
record.type = dns_protocol::kTypeCNAME;
record.klass = dns_protocol::kClassIN;
record.ttl = base::TimeDelta::FromDays(1).InSeconds();
CHECK(DNSDomainFromDot(cannonname, &record.owned_rdata));
record.rdata = record.owned_rdata;
return record;
}
// Note: This is not a fully compliant SOA record, merely the bare amount needed
// in DnsRecord::ParseToAddressList() processessing. This record will not pass
// RecordParsed validation.
DnsResourceRecord BuildSoaRecord(std::string name) {
DCHECK(!name.empty());
DnsResourceRecord record;
record.name = std::move(name);
record.type = dns_protocol::kTypeSOA;
record.klass = dns_protocol::kClassIN;
record.ttl = base::TimeDelta::FromDays(1).InSeconds();
record.SetOwnedRdata("fake_rdata");
return record;
}
DnsResourceRecord BuildTextRecord(std::string name, DnsResourceRecord BuildTestDnsRecord(std::string name,
std::vector<std::string> text_strings) { uint16_t type,
std::string rdata,
base::TimeDelta ttl) {
DCHECK(!name.empty()); DCHECK(!name.empty());
DCHECK(!text_strings.empty());
DnsResourceRecord record; DnsResourceRecord record;
record.name = std::move(name); record.name = std::move(name);
record.type = dns_protocol::kTypeTXT; record.type = type;
record.klass = dns_protocol::kClassIN; record.klass = dns_protocol::kClassIN;
record.ttl = base::TimeDelta::FromDays(1).InSeconds(); record.ttl = ttl.InSeconds();
std::string rdata;
for (std::string text_string : text_strings) {
DCHECK(!text_string.empty());
rdata += base::checked_cast<unsigned char>(text_string.size());
rdata += std::move(text_string);
}
record.SetOwnedRdata(std::move(rdata)); record.SetOwnedRdata(std::move(rdata));
return record; return record;
} }
DnsResourceRecord BuildPointerRecord(std::string name, DnsResourceRecord BuildTestAddressRecord(std::string name,
std::string pointer_name) { const IPAddress& ip,
base::TimeDelta ttl) {
DCHECK(!name.empty()); DCHECK(!name.empty());
DCHECK(!pointer_name.empty()); DCHECK(ip.IsValid());
DnsResourceRecord record;
record.name = std::move(name);
record.type = dns_protocol::kTypePTR;
record.klass = dns_protocol::kClassIN;
record.ttl = base::TimeDelta::FromDays(1).InSeconds();
CHECK(DNSDomainFromDot(pointer_name, &record.owned_rdata));
record.rdata = record.owned_rdata;
return record; return BuildTestDnsRecord(
std::move(name),
ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA,
net::IPAddressToPackedString(ip), ttl);
} }
DnsResourceRecord BuildServiceRecord(std::string name, DnsResponse BuildTestDnsResponse(
TestServiceRecord service) { std::string name,
uint16_t type,
const std::vector<DnsResourceRecord>& answers) {
DCHECK(!name.empty()); DCHECK(!name.empty());
DCHECK(!service.target.empty());
DnsResourceRecord record;
record.name = std::move(name);
record.type = dns_protocol::kTypeSRV;
record.klass = dns_protocol::kClassIN;
record.ttl = base::TimeDelta::FromHours(5).InSeconds();
std::string rdata;
char num_buffer[2];
base::WriteBigEndian(num_buffer, service.priority);
rdata.append(num_buffer, 2);
base::WriteBigEndian(num_buffer, service.weight);
rdata.append(num_buffer, 2);
base::WriteBigEndian(num_buffer, service.port);
rdata.append(num_buffer, 2);
std::string dns_name; std::string dns_name;
CHECK(DNSDomainFromDot(service.target, &dns_name)); CHECK(DNSDomainFromDot(name, &dns_name));
rdata += dns_name;
record.SetOwnedRdata(std::move(rdata));
return record;
}
DnsResourceRecord BuildIntegrityRecord(
std::string name,
const std::vector<uint8_t>& serialized_rdata) {
CHECK(!name.empty());
DnsResourceRecord record;
record.name = std::move(name);
record.type = dns_protocol::kExperimentalTypeIntegrity;
record.klass = dns_protocol::kClassIN;
record.ttl = base::TimeDelta::FromDays(1).InSeconds();
std::string serialized_rdata_str(serialized_rdata.begin(),
serialized_rdata.end());
record.SetOwnedRdata(std::move(serialized_rdata_str));
CHECK_EQ(record.rdata.data(), record.owned_rdata.data());
return record; base::Optional<DnsQuery> query(base::in_place, 0, std::move(dns_name), type);
return DnsResponse(0, true /* is_authoritative */, answers,
{} /* authority_records */, {} /* additional_records */,
query);
} }
} // namespace DnsResponse BuildTestDnsAddressResponse(std::string name,
const IPAddress& ip,
DnsResourceRecord BuildTestAddressRecord(std::string name, std::string answer_name) {
const IPAddress& ip) {
DCHECK(!name.empty());
DCHECK(ip.IsValid()); DCHECK(ip.IsValid());
DnsResourceRecord record; if (answer_name.empty())
record.name = std::move(name); answer_name = name;
record.type = ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA;
record.klass = dns_protocol::kClassIN;
record.ttl = base::TimeDelta::FromDays(1).InSeconds();
record.SetOwnedRdata(net::IPAddressToPackedString(ip));
return record;
}
DnsResponse BuildTestDnsAddressResponse(std::string name, const IPAddress& ip) { std::vector<DnsResourceRecord> answers = {
DCHECK(ip.IsValid()); BuildTestAddressRecord(std::move(answer_name), ip)};
std::vector<DnsResourceRecord> answers = {BuildTestAddressRecord(name, ip)}; return BuildTestDnsResponse(
std::string dns_name; std::move(name),
CHECK(DNSDomainFromDot(name, &dns_name)); ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA, answers);
base::Optional<DnsQuery> query(
base::in_place, 0, dns_name,
ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA);
return DnsResponse(0, false, std::move(answers),
std::vector<DnsResourceRecord>() /* authority_records */,
std::vector<DnsResourceRecord>() /* additional_records */,
query);
} }
DnsResponse BuildTestDnsAddressResponseWithCname(std::string name, DnsResponse BuildTestDnsAddressResponseWithCname(std::string name,
const IPAddress& ip, const IPAddress& ip,
std::string cannonname) { std::string cannonname,
std::string answer_name) {
DCHECK(ip.IsValid()); DCHECK(ip.IsValid());
DCHECK(!cannonname.empty()); DCHECK(!cannonname.empty());
if (answer_name.empty())
answer_name = name;
std::string cname_rdata;
CHECK(DNSDomainFromDot(cannonname, &cname_rdata));
std::vector<DnsResourceRecord> answers = { std::vector<DnsResourceRecord> answers = {
BuildCannonnameRecord(name, cannonname), BuildTestDnsRecord(std::move(answer_name), dns_protocol::kTypeCNAME,
BuildTestAddressRecord(cannonname, ip)}; std::move(cname_rdata)),
std::string dns_name; BuildTestAddressRecord(std::move(cannonname), ip)};
CHECK(DNSDomainFromDot(name, &dns_name));
base::Optional<DnsQuery> query( return BuildTestDnsResponse(
base::in_place, 0, dns_name, std::move(name),
ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA); ip.IsIPv4() ? dns_protocol::kTypeA : dns_protocol::kTypeAAAA, answers);
return DnsResponse(0, false, std::move(answers),
std::vector<DnsResourceRecord>() /* authority_records */,
std::vector<DnsResourceRecord>() /* additional_records */,
query);
} }
DnsResponse BuildTestDnsTextResponse( DnsResponse BuildTestDnsTextResponse(
...@@ -249,18 +160,21 @@ DnsResponse BuildTestDnsTextResponse( ...@@ -249,18 +160,21 @@ DnsResponse BuildTestDnsTextResponse(
std::vector<DnsResourceRecord> answers; std::vector<DnsResourceRecord> answers;
for (std::vector<std::string>& text_record : text_records) { for (std::vector<std::string>& text_record : text_records) {
answers.push_back(BuildTextRecord(answer_name, std::move(text_record))); DCHECK(!text_record.empty());
}
std::string dns_name; std::string rdata;
CHECK(DNSDomainFromDot(name, &dns_name)); for (std::string text_string : text_record) {
base::Optional<DnsQuery> query(base::in_place, 0, dns_name, DCHECK(!text_string.empty());
dns_protocol::kTypeTXT);
return DnsResponse(0, false, std::move(answers), rdata += base::checked_cast<unsigned char>(text_string.size());
std::vector<DnsResourceRecord>() /* authority_records */, rdata += std::move(text_string);
std::vector<DnsResourceRecord>() /* additional_records */, }
query);
answers.push_back(BuildTestDnsRecord(answer_name, dns_protocol::kTypeTXT,
std::move(rdata)));
}
return BuildTestDnsResponse(std::move(name), dns_protocol::kTypeTXT, answers);
} }
DnsResponse BuildTestDnsPointerResponse(std::string name, DnsResponse BuildTestDnsPointerResponse(std::string name,
...@@ -271,18 +185,14 @@ DnsResponse BuildTestDnsPointerResponse(std::string name, ...@@ -271,18 +185,14 @@ DnsResponse BuildTestDnsPointerResponse(std::string name,
std::vector<DnsResourceRecord> answers; std::vector<DnsResourceRecord> answers;
for (std::string& pointer_name : pointer_names) { for (std::string& pointer_name : pointer_names) {
answers.push_back(BuildPointerRecord(answer_name, std::move(pointer_name))); std::string rdata;
} CHECK(DNSDomainFromDot(pointer_name, &rdata));
std::string dns_name; answers.push_back(BuildTestDnsRecord(answer_name, dns_protocol::kTypePTR,
CHECK(DNSDomainFromDot(name, &dns_name)); std::move(rdata)));
base::Optional<DnsQuery> query(base::in_place, 0, dns_name, }
dns_protocol::kTypePTR);
return DnsResponse(0, false, std::move(answers), return BuildTestDnsResponse(std::move(name), dns_protocol::kTypePTR, answers);
std::vector<DnsResourceRecord>() /* authority_records */,
std::vector<DnsResourceRecord>() /* additional_records */,
query);
} }
DnsResponse BuildTestDnsServiceResponse( DnsResponse BuildTestDnsServiceResponse(
...@@ -294,38 +204,24 @@ DnsResponse BuildTestDnsServiceResponse( ...@@ -294,38 +204,24 @@ DnsResponse BuildTestDnsServiceResponse(
std::vector<DnsResourceRecord> answers; std::vector<DnsResourceRecord> answers;
for (TestServiceRecord& service_record : service_records) { for (TestServiceRecord& service_record : service_records) {
answers.push_back( std::string rdata;
BuildServiceRecord(answer_name, std::move(service_record))); char num_buffer[2];
base::WriteBigEndian(num_buffer, service_record.priority);
rdata.append(num_buffer, 2);
base::WriteBigEndian(num_buffer, service_record.weight);
rdata.append(num_buffer, 2);
base::WriteBigEndian(num_buffer, service_record.port);
rdata.append(num_buffer, 2);
std::string dns_name;
CHECK(DNSDomainFromDot(service_record.target, &dns_name));
rdata += dns_name;
answers.push_back(BuildTestDnsRecord(answer_name, dns_protocol::kTypeSRV,
std::move(rdata),
base::TimeDelta::FromHours(5)));
} }
std::string dns_name; return BuildTestDnsResponse(std::move(name), dns_protocol::kTypeSRV, answers);
CHECK(DNSDomainFromDot(name, &dns_name));
base::Optional<DnsQuery> query(base::in_place, 0, dns_name,
dns_protocol::kTypeSRV);
return DnsResponse(0, false, std::move(answers),
std::vector<DnsResourceRecord>() /* authority_records */,
std::vector<DnsResourceRecord>() /* additional_records */,
query);
}
DnsResponse BuildTestDnsIntegrityResponse(
std::string hostname,
const std::vector<uint8_t>& serialized_rdata) {
CHECK(!hostname.empty());
std::vector<DnsResourceRecord> answers{
BuildIntegrityRecord(hostname, serialized_rdata)};
std::string dns_name;
CHECK(DNSDomainFromDot(hostname, &dns_name));
base::Optional<DnsQuery> query(base::in_place, 0, dns_name,
dns_protocol::kExperimentalTypeIntegrity);
return DnsResponse(0, false, std::move(answers),
std::vector<DnsResourceRecord>() /* authority_records */,
std::vector<DnsResourceRecord>() /* additional_records */,
query);
} }
MockDnsClientRule::Result::Result(ResultType type, MockDnsClientRule::Result::Result(ResultType type,
...@@ -406,7 +302,8 @@ class MockDnsTransactionFactory::MockTransaction ...@@ -406,7 +302,8 @@ class MockDnsTransactionFactory::MockTransaction
case MockDnsClientRule::NODOMAIN: case MockDnsClientRule::NODOMAIN:
case MockDnsClientRule::EMPTY: case MockDnsClientRule::EMPTY:
DCHECK(!result->response); // Not expected to be provided. DCHECK(!result->response); // Not expected to be provided.
authority_records = {BuildSoaRecord(hostname_)}; authority_records = {BuildTestDnsRecord(
hostname_, dns_protocol::kTypeSOA, "fake rdata")};
result_.response = DnsResponse( result_.response = DnsResponse(
22 /* id */, false /* is_authoritative */, 22 /* id */, false /* is_authoritative */,
std::vector<DnsResourceRecord>() /* answers */, std::vector<DnsResourceRecord>() /* answers */,
......
...@@ -192,14 +192,28 @@ class IPAddress; ...@@ -192,14 +192,28 @@ class IPAddress;
class ResolveContext; class ResolveContext;
class URLRequestContext; class URLRequestContext;
// Builds an address record for the given name and IP. DnsResourceRecord BuildTestDnsRecord(
DnsResourceRecord BuildTestAddressRecord(std::string name, const IPAddress& ip); std::string name,
uint16_t type,
std::string rdata,
base::TimeDelta ttl = base::TimeDelta::FromDays(1));
DnsResourceRecord BuildTestAddressRecord(
std::string name,
const IPAddress& ip,
base::TimeDelta ttl = base::TimeDelta::FromDays(1));
// Builds a DNS response that includes address records. DnsResponse BuildTestDnsResponse(std::string name,
DnsResponse BuildTestDnsAddressResponse(std::string name, const IPAddress& ip); uint16_t type,
const std::vector<DnsResourceRecord>& answers);
DnsResponse BuildTestDnsAddressResponse(std::string name,
const IPAddress& ip,
std::string answer_name = "");
DnsResponse BuildTestDnsAddressResponseWithCname(std::string name, DnsResponse BuildTestDnsAddressResponseWithCname(std::string name,
const IPAddress& ip, const IPAddress& ip,
std::string cannonname); std::string cannonname,
std::string answer_name = "");
// If |answer_name| is empty, |name| will be used for all answer records, as is // If |answer_name| is empty, |name| will be used for all answer records, as is
// the normal behavior. // the normal behavior.
...@@ -223,10 +237,6 @@ DnsResponse BuildTestDnsServiceResponse( ...@@ -223,10 +237,6 @@ DnsResponse BuildTestDnsServiceResponse(
std::vector<TestServiceRecord> service_records, std::vector<TestServiceRecord> service_records,
std::string answer_name = ""); std::string answer_name = "");
DnsResponse BuildTestDnsIntegrityResponse(
std::string hostname,
const std::vector<uint8_t>& serialized_rdata);
struct MockDnsClientRule { struct MockDnsClientRule {
enum ResultType { enum ResultType {
// Fail asynchronously with ERR_NAME_NOT_RESOLVED and NXDOMAIN. // Fail asynchronously with ERR_NAME_NOT_RESOLVED and NXDOMAIN.
......
...@@ -8899,12 +8899,18 @@ class HostResolverManagerDnsTestIntegrity : public HostResolverManagerDnsTest { ...@@ -8899,12 +8899,18 @@ class HostResolverManagerDnsTestIntegrity : public HostResolverManagerDnsTest {
std::vector<uint8_t> integrity_rdata = options.integrity_mangled std::vector<uint8_t> integrity_rdata = options.integrity_mangled
? GetMangledIntegrityRdata() ? GetMangledIntegrityRdata()
: GetValidIntegrityRdata(); : GetValidIntegrityRdata();
rules.emplace_back( std::string integrity_rdata_str(integrity_rdata.begin(),
"host", dns_protocol::kExperimentalTypeIntegrity, integrity_rdata.end());
options.secure_integrity, std::vector<DnsResourceRecord> answers{
MockDnsClientRule::Result(BuildTestDnsIntegrityResponse( BuildTestDnsRecord("host", dns_protocol::kExperimentalTypeIntegrity,
"host", std::move(integrity_rdata))), std::move(integrity_rdata_str))};
options.delay_integrity); DnsResponse response = BuildTestDnsResponse(
"host", dns_protocol::kExperimentalTypeIntegrity, answers);
rules.emplace_back("host", dns_protocol::kExperimentalTypeIntegrity,
options.secure_integrity,
MockDnsClientRule::Result(std::move(response)),
options.delay_integrity);
} }
CreateResolver(); CreateResolver();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment