|
|
|
@@ -0,0 +1,481 @@
|
|
|
|
|
From: dalyk <dalyk@google.com>
|
|
|
|
|
Date: Wed, 13 Feb 2019 17:50:04 +0000
|
|
|
|
|
Subject: Support different secure DNS modes within DnsTransaction.
|
|
|
|
|
|
|
|
|
|
In SECURE mode, only DnsHTTPAttempts should be made. In AUTOMATIC mode,
|
|
|
|
|
DnsHTTPAttempts should be made first, before falling back to insecure
|
|
|
|
|
attempts. In OFF mode, only insecure attempts should be made.
|
|
|
|
|
|
|
|
|
|
Follow-up work will correct cache lookups for SECURE and AUTOMATIC modes,
|
|
|
|
|
remove the system resolver fallback for SECURE mode, set the mode
|
|
|
|
|
based on the pref setting, and make AUTOMATIC mode more conservative by
|
|
|
|
|
incorporating state related to DoH (DoH probes, successive DoH failures).
|
|
|
|
|
|
|
|
|
|
There should be no change in behavior experienced by users configuring
|
|
|
|
|
DoH via the command line since AUTOMATIC mode is used for all queries
|
|
|
|
|
currently.
|
|
|
|
|
|
|
|
|
|
Bug: 878582
|
|
|
|
|
Change-Id: I5539c5273eb846c95f9a7cdab95429522bc43f50
|
|
|
|
|
Reviewed-on: https://chromium-review.googlesource.com/c/1450858
|
|
|
|
|
Reviewed-by: Paul Jensen <pauljensen@chromium.org>
|
|
|
|
|
Commit-Queue: Katharine Daly <dalyk@google.com>
|
|
|
|
|
Cr-Commit-Position: refs/heads/master@{#631784}
|
|
|
|
|
---
|
|
|
|
|
chrome/browser/net/dns_probe_runner.cc | 3 +-
|
|
|
|
|
.../certificate_transparency/log_dns_client.cc | 3 +-
|
|
|
|
|
net/dns/BUILD.gn | 1 +
|
|
|
|
|
net/dns/dns_test_util.cc | 3 +-
|
|
|
|
|
net/dns/dns_transaction.cc | 42 ++++++---
|
|
|
|
|
net/dns/dns_transaction.h | 10 ++-
|
|
|
|
|
net/dns/dns_transaction_unittest.cc | 99 ++++++++++++++++++++--
|
|
|
|
|
net/dns/dns_util.h | 12 +++
|
|
|
|
|
net/dns/host_resolver_impl.cc | 2 +-
|
|
|
|
|
9 files changed, 154 insertions(+), 21 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/chrome/browser/net/dns_probe_runner.cc b/chrome/browser/net/dns_probe_runner.cc
|
|
|
|
|
--- a/chrome/browser/net/dns_probe_runner.cc
|
|
|
|
|
+++ b/chrome/browser/net/dns_probe_runner.cc
|
|
|
|
|
@@ -17,6 +17,7 @@
|
|
|
|
|
#include "net/dns/dns_client.h"
|
|
|
|
|
#include "net/dns/dns_response.h"
|
|
|
|
|
#include "net/dns/dns_transaction.h"
|
|
|
|
|
+#include "net/dns/dns_util.h"
|
|
|
|
|
#include "net/dns/public/dns_protocol.h"
|
|
|
|
|
#include "net/log/net_log_with_source.h"
|
|
|
|
|
|
|
|
|
|
@@ -109,7 +110,7 @@ void DnsProbeRunner::RunProbe(const base::Closure& callback) {
|
|
|
|
|
kKnownGoodHostname, net::dns_protocol::kTypeA,
|
|
|
|
|
base::Bind(&DnsProbeRunner::OnTransactionComplete,
|
|
|
|
|
weak_factory_.GetWeakPtr()),
|
|
|
|
|
- NetLogWithSource());
|
|
|
|
|
+ NetLogWithSource(), net::SecureDnsMode::AUTOMATIC);
|
|
|
|
|
|
|
|
|
|
transaction_->Start();
|
|
|
|
|
}
|
|
|
|
|
diff --git a/components/certificate_transparency/log_dns_client.cc b/components/certificate_transparency/log_dns_client.cc
|
|
|
|
|
--- a/components/certificate_transparency/log_dns_client.cc
|
|
|
|
|
+++ b/components/certificate_transparency/log_dns_client.cc
|
|
|
|
|
@@ -27,6 +27,7 @@
|
|
|
|
|
#include "net/dns/dns_config.h"
|
|
|
|
|
#include "net/dns/dns_response.h"
|
|
|
|
|
#include "net/dns/dns_transaction.h"
|
|
|
|
|
+#include "net/dns/dns_util.h"
|
|
|
|
|
#include "net/dns/public/dns_protocol.h"
|
|
|
|
|
#include "net/dns/record_parsed.h"
|
|
|
|
|
#include "net/dns/record_rdata.h"
|
|
|
|
|
@@ -471,7 +472,7 @@ bool AuditProofQueryImpl::StartDnsTransaction(const std::string& qname) {
|
|
|
|
|
qname, net::dns_protocol::kTypeTXT,
|
|
|
|
|
base::BindOnce(&AuditProofQueryImpl::OnDnsTransactionComplete,
|
|
|
|
|
weak_ptr_factory_.GetWeakPtr()),
|
|
|
|
|
- net_log_);
|
|
|
|
|
+ net_log_, net::SecureDnsMode::AUTOMATIC);
|
|
|
|
|
|
|
|
|
|
current_dns_transaction_->Start();
|
|
|
|
|
return true;
|
|
|
|
|
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
|
|
|
|
|
--- a/net/dns/BUILD.gn
|
|
|
|
|
+++ b/net/dns/BUILD.gn
|
|
|
|
|
@@ -291,6 +291,7 @@ source_set("dns_client") {
|
|
|
|
|
"dns_client.h",
|
|
|
|
|
"dns_response.h",
|
|
|
|
|
"dns_transaction.h",
|
|
|
|
|
+ "dns_util.h",
|
|
|
|
|
"record_parsed.h",
|
|
|
|
|
"record_rdata.h",
|
|
|
|
|
]
|
|
|
|
|
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc
|
|
|
|
|
--- a/net/dns/dns_test_util.cc
|
|
|
|
|
+++ b/net/dns/dns_test_util.cc
|
|
|
|
|
@@ -441,7 +441,8 @@ class MockDnsClient::MockTransactionFactory : public DnsTransactionFactory {
|
|
|
|
|
const std::string& hostname,
|
|
|
|
|
uint16_t qtype,
|
|
|
|
|
DnsTransactionFactory::CallbackType callback,
|
|
|
|
|
- const NetLogWithSource&) override {
|
|
|
|
|
+ const NetLogWithSource&,
|
|
|
|
|
+ SecureDnsMode) override {
|
|
|
|
|
std::unique_ptr<MockTransaction> transaction =
|
|
|
|
|
std::make_unique<MockTransaction>(rules_, hostname, qtype,
|
|
|
|
|
std::move(callback));
|
|
|
|
|
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
|
|
|
|
|
--- a/net/dns/dns_transaction.cc
|
|
|
|
|
+++ b/net/dns/dns_transaction.cc
|
|
|
|
|
@@ -772,11 +772,13 @@ class DnsTransactionImpl : public DnsTransaction,
|
|
|
|
|
uint16_t qtype,
|
|
|
|
|
DnsTransactionFactory::CallbackType callback,
|
|
|
|
|
const NetLogWithSource& net_log,
|
|
|
|
|
- const OptRecordRdata* opt_rdata)
|
|
|
|
|
+ const OptRecordRdata* opt_rdata,
|
|
|
|
|
+ SecureDnsMode secure_dns_mode)
|
|
|
|
|
: session_(session),
|
|
|
|
|
hostname_(hostname),
|
|
|
|
|
qtype_(qtype),
|
|
|
|
|
opt_rdata_(opt_rdata),
|
|
|
|
|
+ secure_dns_mode_(secure_dns_mode),
|
|
|
|
|
callback_(std::move(callback)),
|
|
|
|
|
net_log_(net_log),
|
|
|
|
|
qnames_initial_size_(0),
|
|
|
|
|
@@ -919,12 +921,17 @@ class DnsTransactionImpl : public DnsTransaction,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AttemptResult MakeAttempt() {
|
|
|
|
|
- // Make an HTTP attempt unless we have already made more attempts
|
|
|
|
|
- // than we have configured servers. Otherwise make a UDP attempt
|
|
|
|
|
- // as long as we have configured nameservers.
|
|
|
|
|
DnsConfig config = session_->config();
|
|
|
|
|
- if (doh_attempts_ < config.dns_over_https_servers.size())
|
|
|
|
|
+ // In AUTOMATIC and SECURE mode, make an HTTP attempt unless we have already
|
|
|
|
|
+ // made more attempts than we have configured servers.
|
|
|
|
|
+ if (secure_dns_mode_ != SecureDnsMode::OFF &&
|
|
|
|
|
+ doh_attempts_ < config.dns_over_https_servers.size()) {
|
|
|
|
|
return MakeHTTPAttempt(config.dns_over_https_servers);
|
|
|
|
|
+ }
|
|
|
|
|
+ // In AUTOMATIC mode, insecure attempts are allowed after HTTP attempts are
|
|
|
|
|
+ // exhausted. In OFF mode, only insecure attempts are allowed. It should
|
|
|
|
|
+ // not be possible to reach this point in SECURE mode.
|
|
|
|
|
+ DCHECK_NE(secure_dns_mode_, SecureDnsMode::SECURE);
|
|
|
|
|
DCHECK_GT(config.nameservers.size(), 0u);
|
|
|
|
|
return MakeUDPAttempt();
|
|
|
|
|
}
|
|
|
|
|
@@ -1112,8 +1119,19 @@ class DnsTransactionImpl : public DnsTransaction,
|
|
|
|
|
if (had_tcp_attempt_)
|
|
|
|
|
return false;
|
|
|
|
|
const DnsConfig& config = session_->config();
|
|
|
|
|
- return attempts_.size() < config.attempts * config.nameservers.size() +
|
|
|
|
|
- config.dns_over_https_servers.size();
|
|
|
|
|
+ unsigned insecure_attempts_possible =
|
|
|
|
|
+ config.attempts * config.nameservers.size();
|
|
|
|
|
+ unsigned secure_attempts_possible = config.dns_over_https_servers.size();
|
|
|
|
|
+
|
|
|
|
|
+ switch (secure_dns_mode_) {
|
|
|
|
|
+ case SecureDnsMode::SECURE:
|
|
|
|
|
+ return attempts_.size() < secure_attempts_possible;
|
|
|
|
|
+ case SecureDnsMode::AUTOMATIC:
|
|
|
|
|
+ return attempts_.size() <
|
|
|
|
|
+ secure_attempts_possible + insecure_attempts_possible;
|
|
|
|
|
+ case SecureDnsMode::OFF:
|
|
|
|
|
+ return attempts_.size() < insecure_attempts_possible;
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolves the result of a DnsAttempt until a terminal result is reached
|
|
|
|
|
@@ -1204,6 +1222,7 @@ class DnsTransactionImpl : public DnsTransaction,
|
|
|
|
|
std::string hostname_;
|
|
|
|
|
uint16_t qtype_;
|
|
|
|
|
const OptRecordRdata* opt_rdata_;
|
|
|
|
|
+ const SecureDnsMode secure_dns_mode_;
|
|
|
|
|
// Cleared in DoCallback.
|
|
|
|
|
DnsTransactionFactory::CallbackType callback_;
|
|
|
|
|
|
|
|
|
|
@@ -1248,10 +1267,11 @@ class DnsTransactionFactoryImpl : public DnsTransactionFactory {
|
|
|
|
|
const std::string& hostname,
|
|
|
|
|
uint16_t qtype,
|
|
|
|
|
CallbackType callback,
|
|
|
|
|
- const NetLogWithSource& net_log) override {
|
|
|
|
|
- return std::make_unique<DnsTransactionImpl>(session_.get(), hostname, qtype,
|
|
|
|
|
- std::move(callback), net_log,
|
|
|
|
|
- opt_rdata_.get());
|
|
|
|
|
+ const NetLogWithSource& net_log,
|
|
|
|
|
+ SecureDnsMode secure_dns_mode) override {
|
|
|
|
|
+ return std::make_unique<DnsTransactionImpl>(
|
|
|
|
|
+ session_.get(), hostname, qtype, std::move(callback), net_log,
|
|
|
|
|
+ opt_rdata_.get(), secure_dns_mode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AddEDNSOption(const OptRecordRdata::Opt& opt) override {
|
|
|
|
|
diff --git a/net/dns/dns_transaction.h b/net/dns/dns_transaction.h
|
|
|
|
|
--- a/net/dns/dns_transaction.h
|
|
|
|
|
+++ b/net/dns/dns_transaction.h
|
|
|
|
|
@@ -12,6 +12,7 @@
|
|
|
|
|
|
|
|
|
|
#include "base/callback.h"
|
|
|
|
|
#include "net/base/request_priority.h"
|
|
|
|
|
+#include "net/dns/dns_util.h"
|
|
|
|
|
#include "net/dns/record_rdata.h"
|
|
|
|
|
#include "url/gurl.h"
|
|
|
|
|
|
|
|
|
|
@@ -69,11 +70,18 @@ class NET_EXPORT_PRIVATE DnsTransactionFactory {
|
|
|
|
|
//
|
|
|
|
|
// The transaction will run |callback| upon asynchronous completion.
|
|
|
|
|
// The |net_log| is used as the parent log.
|
|
|
|
|
+ //
|
|
|
|
|
+ // The |secure_dns_mode| specifies the order in which secure and/or insecure
|
|
|
|
|
+ // DNS lookups will be performed. In SECURE mode, only secure lookups will be
|
|
|
|
|
+ // perfomed. In AUTOMATIC mode, secure lookups will be performed first when
|
|
|
|
|
+ // possible, and insecure lookups will be performed as a fallback. In OFF
|
|
|
|
|
+ // mode, only insecure lookups will be performed.
|
|
|
|
|
virtual std::unique_ptr<DnsTransaction> CreateTransaction(
|
|
|
|
|
const std::string& hostname,
|
|
|
|
|
uint16_t qtype,
|
|
|
|
|
CallbackType callback,
|
|
|
|
|
- const NetLogWithSource& net_log) WARN_UNUSED_RESULT = 0;
|
|
|
|
|
+ const NetLogWithSource& net_log,
|
|
|
|
|
+ SecureDnsMode secure_dns_mode) WARN_UNUSED_RESULT = 0;
|
|
|
|
|
|
|
|
|
|
// The given EDNS0 option will be included in all DNS queries performed by
|
|
|
|
|
// transactions from this factory.
|
|
|
|
|
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc
|
|
|
|
|
--- a/net/dns/dns_transaction_unittest.cc
|
|
|
|
|
+++ b/net/dns/dns_transaction_unittest.cc
|
|
|
|
|
@@ -246,7 +246,17 @@ class TestSocketFactory : public MockClientSocketFactory {
|
|
|
|
|
remote_endpoints_.push_back(endpoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- std::vector<IPEndPoint> remote_endpoints_;
|
|
|
|
|
+ struct RemoteNameserver {
|
|
|
|
|
+ RemoteNameserver(IPEndPoint insecure_nameserver)
|
|
|
|
|
+ : insecure_nameserver(insecure_nameserver) {}
|
|
|
|
|
+ RemoteNameserver(DnsConfig::DnsOverHttpsServerConfig secure_nameserver)
|
|
|
|
|
+ : secure_nameserver(secure_nameserver) {}
|
|
|
|
|
+
|
|
|
|
|
+ base::Optional<IPEndPoint> insecure_nameserver;
|
|
|
|
|
+ base::Optional<DnsConfig::DnsOverHttpsServerConfig> secure_nameserver;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ std::vector<RemoteNameserver> remote_endpoints_;
|
|
|
|
|
bool fail_next_socket_;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
@@ -269,6 +279,7 @@ class TransactionHelper {
|
|
|
|
|
int expected_answer_count)
|
|
|
|
|
: hostname_(hostname),
|
|
|
|
|
qtype_(qtype),
|
|
|
|
|
+ secure_dns_mode_(SecureDnsMode::AUTOMATIC),
|
|
|
|
|
response_(nullptr),
|
|
|
|
|
expected_answer_count_(expected_answer_count),
|
|
|
|
|
cancel_in_callback_(false),
|
|
|
|
|
@@ -277,13 +288,19 @@ class TransactionHelper {
|
|
|
|
|
// Mark that the transaction shall be destroyed immediately upon callback.
|
|
|
|
|
void set_cancel_in_callback() { cancel_in_callback_ = true; }
|
|
|
|
|
|
|
|
|
|
+ // Set the secure DNS mode for the transaction.
|
|
|
|
|
+ void set_secure_dns_mode(SecureDnsMode secure_dns_mode) {
|
|
|
|
|
+ secure_dns_mode_ = secure_dns_mode;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
void StartTransaction(DnsTransactionFactory* factory) {
|
|
|
|
|
EXPECT_EQ(NULL, transaction_.get());
|
|
|
|
|
transaction_ = factory->CreateTransaction(
|
|
|
|
|
hostname_, qtype_,
|
|
|
|
|
base::Bind(&TransactionHelper::OnTransactionComplete,
|
|
|
|
|
base::Unretained(this)),
|
|
|
|
|
- NetLogWithSource::Make(&net_log_, net::NetLogSourceType::NONE));
|
|
|
|
|
+ NetLogWithSource::Make(&net_log_, net::NetLogSourceType::NONE),
|
|
|
|
|
+ secure_dns_mode_);
|
|
|
|
|
transaction_->SetRequestContext(&request_context_);
|
|
|
|
|
transaction_->SetRequestPriority(DEFAULT_PRIORITY);
|
|
|
|
|
EXPECT_EQ(hostname_, transaction_->GetHostname());
|
|
|
|
|
@@ -360,6 +377,7 @@ class TransactionHelper {
|
|
|
|
|
private:
|
|
|
|
|
std::string hostname_;
|
|
|
|
|
uint16_t qtype_;
|
|
|
|
|
+ SecureDnsMode secure_dns_mode_;
|
|
|
|
|
std::unique_ptr<DnsTransaction> transaction_;
|
|
|
|
|
const DnsResponse* response_;
|
|
|
|
|
int expected_answer_count_;
|
|
|
|
|
@@ -669,9 +687,20 @@ class DnsTransactionTestBase : public testing::Test {
|
|
|
|
|
// |servers|.
|
|
|
|
|
void CheckServerOrder(const unsigned* servers, size_t num_attempts) {
|
|
|
|
|
ASSERT_EQ(num_attempts, socket_factory_->remote_endpoints_.size());
|
|
|
|
|
+ auto num_insecure_nameservers = session_->config().nameservers.size();
|
|
|
|
|
for (size_t i = 0; i < num_attempts; ++i) {
|
|
|
|
|
- EXPECT_EQ(socket_factory_->remote_endpoints_[i],
|
|
|
|
|
- session_->config().nameservers[servers[i]]);
|
|
|
|
|
+ if (servers[i] < num_insecure_nameservers) {
|
|
|
|
|
+ // Check insecure server match.
|
|
|
|
|
+ EXPECT_EQ(
|
|
|
|
|
+ socket_factory_->remote_endpoints_[i].insecure_nameserver.value(),
|
|
|
|
|
+ session_->config().nameservers[servers[i]]);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // Check secure server match.
|
|
|
|
|
+ EXPECT_EQ(
|
|
|
|
|
+ socket_factory_->remote_endpoints_[i].secure_nameserver.value(),
|
|
|
|
|
+ session_->config()
|
|
|
|
|
+ .dns_over_https_servers[servers[i] - num_insecure_nameservers]);
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -762,6 +791,7 @@ class DnsTransactionTest : public DnsTransactionTestBase,
|
|
|
|
|
if (server.use_post && request->method() == "POST") {
|
|
|
|
|
if (url_base == request->url().spec()) {
|
|
|
|
|
server_found = true;
|
|
|
|
|
+ socket_factory_->remote_endpoints_.push_back(server);
|
|
|
|
|
}
|
|
|
|
|
} else if (!server.use_post && request->method() == "GET") {
|
|
|
|
|
std::string prefix = url_base + "?dns=";
|
|
|
|
|
@@ -769,6 +799,7 @@ class DnsTransactionTest : public DnsTransactionTestBase,
|
|
|
|
|
request->url().spec().begin());
|
|
|
|
|
if (mispair.first == prefix.end()) {
|
|
|
|
|
server_found = true;
|
|
|
|
|
+ socket_factory_->remote_endpoints_.push_back(server);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -1552,6 +1583,43 @@ TEST_F(DnsTransactionTest, HttpsPostFailThenUDPFallback) {
|
|
|
|
|
TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
|
|
|
|
SetDohJobMakerCallback(base::BindRepeating(DohJobMakerCallbackFailStart));
|
|
|
|
|
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
|
|
|
|
+ unsigned kOrder0[] = {1, 0};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+TEST_F(DnsTransactionTest, HttpsPostFailNoUDPFallbackInSecureMode) {
|
|
|
|
|
+ config_.attempts = 1;
|
|
|
|
|
+ ConfigureNumServers(2);
|
|
|
|
|
+ ConfigDohServers(false /* clear_udp */, true /* use_post */, 2);
|
|
|
|
|
+ AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
|
|
|
|
|
+ SYNCHRONOUS, Transport::HTTPS);
|
|
|
|
|
+ AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
|
|
|
|
|
+ SYNCHRONOUS, Transport::HTTPS);
|
|
|
|
|
+ TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_FAILED);
|
|
|
|
|
+ helper0.set_secure_dns_mode(SecureDnsMode::SECURE);
|
|
|
|
|
+ SetDohJobMakerCallback(base::BindRepeating(DohJobMakerCallbackFailStart));
|
|
|
|
|
+ EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
|
|
|
|
+ unsigned kOrder0[] = {2, 3};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+TEST_F(DnsTransactionTest, NoHttpsAttemptInOffMode) {
|
|
|
|
|
+ config_.attempts = 2;
|
|
|
|
|
+ ConfigureNumServers(2);
|
|
|
|
|
+ ConfigDohServers(false /* clear_udp */, true /* use_post */, 2);
|
|
|
|
|
+ AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
|
|
|
|
|
+ SYNCHRONOUS, Transport::UDP);
|
|
|
|
|
+ AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
|
|
|
|
|
+ SYNCHRONOUS, Transport::UDP);
|
|
|
|
|
+ AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
|
|
|
|
|
+ SYNCHRONOUS, Transport::UDP);
|
|
|
|
|
+ AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
|
|
|
|
|
+ base::size(kT0ResponseDatagram), ASYNC, Transport::UDP);
|
|
|
|
|
+ TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
|
|
|
|
+ helper0.set_secure_dns_mode(SecureDnsMode::OFF);
|
|
|
|
|
+ EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
|
|
|
|
+ unsigned kOrder0[] = {0, 1, 0, 1};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(DnsTransactionTest, HttpsPostFailThenUDPFailThenUDPFallback) {
|
|
|
|
|
@@ -1575,6 +1643,8 @@ TEST_F(DnsTransactionTest, HttpsPostFailThenUDPFailThenUDPFallback) {
|
|
|
|
|
EXPECT_EQ(session_->NextGoodServerIndex(0), 1u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodServerIndex(1), 1u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodServerIndex(2), 2u);
|
|
|
|
|
+ unsigned kOrder0[] = {3, 0, 1};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(DnsTransactionTest, HttpsMarkUdpBad) {
|
|
|
|
|
@@ -1595,6 +1665,8 @@ TEST_F(DnsTransactionTest, HttpsMarkUdpBad) {
|
|
|
|
|
EXPECT_EQ(session_->NextGoodServerIndex(0), 1u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodServerIndex(1), 1u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodDnsOverHttpsServerIndex(2), 2u);
|
|
|
|
|
+ unsigned kOrder0[] = {2, 0, 1};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
|
|
|
|
|
AddQueryAndErrorResponse(1, kT1HostName, kT1Qtype, ERR_CONNECTION_REFUSED,
|
|
|
|
|
SYNCHRONOUS, Transport::HTTPS);
|
|
|
|
|
@@ -1612,6 +1684,11 @@ TEST_F(DnsTransactionTest, HttpsMarkUdpBad) {
|
|
|
|
|
EXPECT_EQ(session_->NextGoodServerIndex(0), 0u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodServerIndex(1), 0u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodDnsOverHttpsServerIndex(2), 2u);
|
|
|
|
|
+ unsigned kOrder1[] = {
|
|
|
|
|
+ 2, 0, 1, /* transaction0 */
|
|
|
|
|
+ 2, 1, 0 /* transaction1 */
|
|
|
|
|
+ };
|
|
|
|
|
+ CheckServerOrder(kOrder1, base::size(kOrder1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(DnsTransactionTest, HttpsMarkHttpsBad) {
|
|
|
|
|
@@ -1627,7 +1704,6 @@ TEST_F(DnsTransactionTest, HttpsMarkHttpsBad) {
|
|
|
|
|
SYNCHRONOUS, Transport::HTTPS);
|
|
|
|
|
AddQueryAndErrorResponse(1, kT1HostName, kT1Qtype, ERR_CONNECTION_REFUSED,
|
|
|
|
|
SYNCHRONOUS, Transport::HTTPS);
|
|
|
|
|
-
|
|
|
|
|
AddQueryAndResponse(1, kT1HostName, kT1Qtype, kT1ResponseDatagram,
|
|
|
|
|
base::size(kT1ResponseDatagram), ASYNC, Transport::HTTPS);
|
|
|
|
|
TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
|
|
|
|
@@ -1640,6 +1716,8 @@ TEST_F(DnsTransactionTest, HttpsMarkHttpsBad) {
|
|
|
|
|
EXPECT_EQ(session_->NextGoodDnsOverHttpsServerIndex(1), 3u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodDnsOverHttpsServerIndex(2), 3u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodDnsOverHttpsServerIndex(3), 3u);
|
|
|
|
|
+ unsigned kOrder0[] = {1, 2, 3};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(helper1.RunUntilDone(transaction_factory_.get()));
|
|
|
|
|
// Server 0 is still our only UDP server, so will be good by definition.
|
|
|
|
|
@@ -1651,6 +1729,11 @@ TEST_F(DnsTransactionTest, HttpsMarkHttpsBad) {
|
|
|
|
|
EXPECT_EQ(session_->NextGoodDnsOverHttpsServerIndex(1), 2u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodDnsOverHttpsServerIndex(2), 2u);
|
|
|
|
|
EXPECT_EQ(session_->NextGoodDnsOverHttpsServerIndex(3), 2u);
|
|
|
|
|
+ unsigned kOrder1[] = {
|
|
|
|
|
+ 1, 2, 3, /* transaction0 */
|
|
|
|
|
+ 3, 1, 2 /* transaction1 */
|
|
|
|
|
+ };
|
|
|
|
|
+ CheckServerOrder(kOrder1, base::size(kOrder1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(DnsTransactionTest, HttpsPostFailThenHTTPFallback) {
|
|
|
|
|
@@ -1662,6 +1745,8 @@ TEST_F(DnsTransactionTest, HttpsPostFailThenHTTPFallback) {
|
|
|
|
|
Transport::HTTPS);
|
|
|
|
|
TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
|
|
|
|
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
|
|
|
|
+ unsigned kOrder0[] = {0, 1};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(DnsTransactionTest, HttpsPostFailTwiceThenUDPFallback) {
|
|
|
|
|
@@ -1678,6 +1763,8 @@ TEST_F(DnsTransactionTest, HttpsPostFailTwiceThenUDPFallback) {
|
|
|
|
|
TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
|
|
|
|
SetDohJobMakerCallback(base::BindRepeating(DohJobMakerCallbackFailStart));
|
|
|
|
|
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
|
|
|
|
+ unsigned kOrder0[] = {1, 2, 0};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(DnsTransactionTest, HttpsPostFailTwice) {
|
|
|
|
|
@@ -1692,6 +1779,8 @@ TEST_F(DnsTransactionTest, HttpsPostFailTwice) {
|
|
|
|
|
TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_FAILED);
|
|
|
|
|
SetDohJobMakerCallback(base::BindRepeating(DohJobMakerCallbackFailStart));
|
|
|
|
|
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
|
|
|
|
+ unsigned kOrder0[] = {0, 1};
|
|
|
|
|
+ CheckServerOrder(kOrder0, base::size(kOrder0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MakeResponseWithCookie(URLRequest* request, HttpResponseInfo* info) {
|
|
|
|
|
diff --git a/net/dns/dns_util.h b/net/dns/dns_util.h
|
|
|
|
|
--- a/net/dns/dns_util.h
|
|
|
|
|
+++ b/net/dns/dns_util.h
|
|
|
|
|
@@ -93,6 +93,18 @@ uint16_t DnsQueryTypeToQtype(DnsQueryType dns_query_type);
|
|
|
|
|
NET_EXPORT DnsQueryType
|
|
|
|
|
AddressFamilyToDnsQueryType(AddressFamily address_family);
|
|
|
|
|
|
|
|
|
|
+// The SecureDnsMode specifies what types of lookups (secure/insecure) should
|
|
|
|
|
+// be performed and in what order when resolving a specific query.
|
|
|
|
|
+enum SecureDnsMode : int {
|
|
|
|
|
+ // In OFF mode, no DoH lookups should be performed.
|
|
|
|
|
+ OFF,
|
|
|
|
|
+ // In AUTOMATIC mode, DoH lookups should be performed first if DoH is
|
|
|
|
|
+ // available, and insecure DNS lookups should be performed as a fallback.
|
|
|
|
|
+ AUTOMATIC,
|
|
|
|
|
+ // In SECURE mode, only DoH lookups should be performed.
|
|
|
|
|
+ SECURE,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
} // namespace net
|
|
|
|
|
|
|
|
|
|
#endif // NET_DNS_DNS_UTIL_H_
|
|
|
|
|
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc
|
|
|
|
|
--- a/net/dns/host_resolver_impl.cc
|
|
|
|
|
+++ b/net/dns/host_resolver_impl.cc
|
|
|
|
|
@@ -1066,7 +1066,7 @@ class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> {
|
|
|
|
|
base::BindOnce(&DnsTask::OnTransactionComplete,
|
|
|
|
|
base::Unretained(this), tick_clock_->NowTicks(),
|
|
|
|
|
dns_query_type),
|
|
|
|
|
- net_log_);
|
|
|
|
|
+ net_log_, SecureDnsMode::AUTOMATIC);
|
|
|
|
|
trans->SetRequestContext(delegate_->url_request_context());
|
|
|
|
|
trans->SetRequestPriority(delegate_->priority());
|
|
|
|
|
return trans;
|
|
|
|
|
--
|
|
|
|
|
2.11.0
|
|
|
|
|
|