Commit edc8e235 authored by Eric Orth's avatar Eric Orth Committed by Commit Bot

Load DnsSession into ResolveContext at registration

In HostResolverManager::RegisterResolveContext(), perform an initial
cache "invalidation" (in this case, more of an "initialization") to load
the current DnsSession (if there is one) into the ResolveContext. This
will allow DoH requests and other transaction operations requiring
per-context state to work if the context is created after the last
config load or connection change.

Bug: 1022059
Change-Id: I6c6eddd9ae992430b5c72f00caf03e9694be56a1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2068833Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Commit-Queue: Eric Orth <ericorth@chromium.org>
Cr-Commit-Position: refs/heads/master@{#745243}
parent c1d0db71
......@@ -577,20 +577,23 @@ TEST_F(ContextHostResolverTest, OnShutdown_DelayedStartDohProbeRequest) {
TEST_F(ContextHostResolverTest, ResolveFromCache) {
auto resolve_context = std::make_unique<ResolveContext>(
nullptr /* url_request_context */, true /* enable_caching */);
HostCache* host_cache = resolve_context->host_cache();
auto resolver = std::make_unique<ContextHostResolver>(
manager_.get(), std::move(resolve_context));
// Create the cache entry after creating the ContextHostResolver, as
// registering into the HostResolverManager initializes and invalidates the
// cache.
base::SimpleTestTickClock clock;
clock.Advance(base::TimeDelta::FromDays(62)); // Arbitrary non-zero time.
AddressList expected(kEndpoint);
resolve_context->host_cache()->Set(
host_cache->Set(
HostCache::Key("example.com", DnsQueryType::UNSPECIFIED,
0 /* host_resolver_flags */, HostResolverSource::ANY,
NetworkIsolationKey()),
HostCache::Entry(OK, expected, HostCache::Entry::SOURCE_DNS,
base::TimeDelta::FromDays(1)),
clock.NowTicks(), base::TimeDelta::FromDays(1));
auto resolver = std::make_unique<ContextHostResolver>(
manager_.get(), std::move(resolve_context));
resolver->SetTickClockForTesting(&clock);
// Allow stale results and then confirm the result is not stale in order to
......@@ -715,14 +718,16 @@ TEST_F(ContextHostResolverTest, HostCacheInvalidation) {
auto resolver = std::make_unique<ContextHostResolver>(
manager_.get(), std::move(resolve_context));
// No invalidations yet.
ASSERT_EQ(resolve_context_ptr->current_session_for_testing(), nullptr);
ASSERT_EQ(resolve_context_ptr->host_cache()->network_changes(), 0);
// No invalidations yet (other than the initialization "invalidation" from
// registering the context).
ASSERT_EQ(resolve_context_ptr->current_session_for_testing(),
dns_client_->GetCurrentSession());
ASSERT_EQ(resolve_context_ptr->host_cache()->network_changes(), 1);
manager_->InvalidateCachesForTesting();
EXPECT_EQ(resolve_context_ptr->current_session_for_testing(),
dns_client_->GetCurrentSession());
EXPECT_EQ(resolve_context_ptr->host_cache()->network_changes(), 1);
EXPECT_EQ(resolve_context_ptr->host_cache()->network_changes(), 2);
// Expect manager to be able to safely do invalidations after an individual
// ContextHostResolver has been destroyed (and deregisters its ResolveContext)
......
......@@ -2863,6 +2863,8 @@ void HostResolverManager::SetDnsConfigOverrides(DnsConfigOverrides overrides) {
void HostResolverManager::RegisterResolveContext(ResolveContext* context) {
registered_contexts_.AddObserver(context);
context->InvalidateCaches(dns_client_ ? dns_client_->GetCurrentSession()
: nullptr);
}
void HostResolverManager::DeregisterResolveContext(
......
......@@ -9074,6 +9074,78 @@ TEST_F(HostResolverManagerDnsTest, EsniDnsQuery) {
c1.keys_for_addresses());
}
// Test that a newly-registered ResolveContext is immediately usable with a DNS
// configuration loaded before the context registration.
TEST_F(HostResolverManagerDnsTest,
NewlyRegisteredContext_ConfigBeforeRegistration) {
ResolveContext context(nullptr /* url_request_context */,
true /* enable_caching */);
set_allow_fallback_to_proctask(false);
ChangeDnsConfig(CreateValidDnsConfig());
DnsConfigOverrides overrides;
overrides.secure_dns_mode = DnsConfig::SecureDnsMode::SECURE;
resolver_->SetDnsConfigOverrides(overrides);
ASSERT_TRUE(dns_client_->GetCurrentSession());
resolver_->RegisterResolveContext(&context);
EXPECT_EQ(context.current_session_for_testing(),
dns_client_->GetCurrentSession());
// Test a SECURE-mode DoH request with SetForceDohServerAvailable(false).
// Should only succeed if a DoH server is marked available in the
// ResolveContext. MockDnsClient skips most other interaction with
// ResolveContext.
dns_client_->SetForceDohServerAvailable(false);
context.SetProbeSuccess(0u /* doh_server_index */, true /* success */,
dns_client_->GetCurrentSession());
ResolveHostResponseHelper response(resolver_->CreateRequest(
HostPortPair("secure", 80), NetworkIsolationKey(), NetLogWithSource(),
base::nullopt, &context, context.host_cache()));
EXPECT_THAT(response.result_error(), IsOk());
resolver_->DeregisterResolveContext(&context);
}
// Test interaction with a ResolveContext registered before a DNS config is
// ready.
TEST_F(HostResolverManagerDnsTest,
NewlyRegisteredContext_NoConfigAtRegistration) {
ResolveContext context(nullptr /* url_request_context */,
true /* enable_caching */);
set_allow_fallback_to_proctask(false);
InvalidateDnsConfig();
DnsConfigOverrides overrides;
overrides.secure_dns_mode = DnsConfig::SecureDnsMode::SECURE;
resolver_->SetDnsConfigOverrides(overrides);
ASSERT_FALSE(dns_client_->GetCurrentSession());
// Register context before loading a DNS config.
resolver_->RegisterResolveContext(&context);
EXPECT_FALSE(context.current_session_for_testing());
// Load DNS config and expect the session to be loaded into the ResolveContext
ChangeDnsConfig(CreateValidDnsConfig());
ASSERT_TRUE(dns_client_->GetCurrentSession());
EXPECT_EQ(context.current_session_for_testing(),
dns_client_->GetCurrentSession());
// Test a SECURE-mode DoH request with SetForceDohServerAvailable(false).
// Should only succeed if a DoH server is marked available in the
// ResolveContext. MockDnsClient skips most other interaction with
// ResolveContext.
dns_client_->SetForceDohServerAvailable(false);
context.SetProbeSuccess(0u /* doh_server_index */, true /* success */,
dns_client_->GetCurrentSession());
ResolveHostResponseHelper response(resolver_->CreateRequest(
HostPortPair("secure", 80), NetworkIsolationKey(), NetLogWithSource(),
base::nullopt, &context, context.host_cache()));
EXPECT_THAT(response.result_error(), IsOk());
resolver_->DeregisterResolveContext(&context);
}
class HostResolverManagerEsniTest : public HostResolverManagerDnsTest {
public:
HostResolverManagerEsniTest()
......
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