Implement Canary Domain check to disable DoH fallback. [chromium/src : main]

0 views
Skip to first unread message

Brian Begnoche (Gerrit)

unread,
Feb 4, 2026, 4:43:56 PMFeb 4
to Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
Attention needed from Andrew Williams and David Schinazi

Brian Begnoche added 19 comments

Patchset-level comments
File-level comment, Patchset 19:
Brian Begnoche . resolved

Thanks! I haven't responded to some comments that require a bit more thought.

File net/dns/canary_domain_service.h
Line 53, Patchset 15: // Probes a domain with the given |probe_name| (used for metrics) and |host|
Andrew Williams . resolved

nit: for new comments prefer backticks: https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-dos-and-donts.md#comment-style

Brian Begnoche

Done

File net/dns/canary_domain_service.cc
Line 32, Patchset 15: HostResolver::ResolveHostRequest* request,
Andrew Williams . resolved

optional: if we use `const HostResolver::ResolveHostRequest&` for this then it's clear it can never be NULL and we can remove the DCHECK.

Brian Begnoche

Done

Line 71, Patchset 15: HostPortPair host_port_pair(host, 80);
Andrew Williams . resolved

nit: can std::move(host) here

Brian Begnoche

Done

Line 81, Patchset 15: std::move(request), std::move(callback), probe_name));
Andrew Williams . resolved

To avoid the use-after-move, at least for callback you may want to use SplitOnceCallback. idk what's best to do for request

Brian Begnoche

Good catch. I think this is cleaned up now.

Line 86, Patchset 15: OnProbeComplete(std::move(request), std::move(callback), probe_name,
Andrew Williams . resolved

nit: can std::move(probe_name) here

Brian Begnoche

Done

Line 98, Patchset 15: base::StrCat({"Net.DNS.CanaryDomainService.", probe_name, ".Result"}),
Andrew Williams . unresolved

nit: can std::move(probe_name) here

Brian Begnoche

I'm less clear on whether this still makes sense, since it's now owned now by the probe struct?

Line 98, Patchset 15: base::StrCat({"Net.DNS.CanaryDomainService.", probe_name, ".Result"}),
Andrew Williams . resolved

Can we do a pass double-checking includes? I think we're missing at least the base/strings/strcat.h include

Brian Begnoche

strcat.h is added. Will check for others.

File net/dns/canary_domain_service_unittest.cc
Line 46, Patchset 18: service->ProbeSecureDnsDomain(
Andrew Williams . resolved

I think this could be simplified to:
```
base::test::TestFuture<bool> future;
service->ProbeSecureDnsDomain(future.GetCallback());
bool result = future.Get();
```

Brian Begnoche

Done

Line 91, Patchset 18:
Andrew Williams . unresolved

It might be useful to add a SERVFAIL case as well to test the default case

Brian Begnoche

I tried really hard to make this happen. I don't think it's possible, at least not trivially.

The short of it is that `MockHostResolver::Resolve` sees no rule that resolves to an IP and returns `ERR_NAME_NOT_RESOLVED`, even if the rule specifies some other error code.

File net/dns/dns_client.cc
Line 253, Patchset 15: doh_fallback_allowed_by_canary_domain_ = allowed;
Andrew Williams . unresolved

I wonder if the more consistent way of applying this change would be to have an entry in DnsConfigOverrides for this boolean and setting that here. Then we don't need the `doh_fallback_allowed_by_canary_domain_ == allowed` check, because IIUC that's handled by UpdateDnsConfig

Brian Begnoche

I thought about this too. The reason I didn't do that was that I didn't want `SetConfigOverrides` to clobber this. So it'd need to do something to persist this value after updating the overrides. It's like an override of overrides, so kind of odd.

Alternatively, it could be a second DnsConfigOverrides that just stores this override, but then `UpdateDnsConfig` needs to be updated regardless. I guess there is an advantage to this in that it would be a canned `DnsConfigOverrides` that can (1) set this value (2) override `secure_dns_mode` (3) clear `doh_config.servers`.

I think I would prefer the latter approach, if anything. What are your thoughts?

Line 304, Patchset 15: dict.Set("doh_fallback_allowed_by_canary_domain",
Andrew Williams . resolved

I don't think we need this in addition to the change in `DnsConfig::ToDict`, right?

Brian Begnoche

Nope, removed.

File net/dns/dns_client_unittest.cc
Line 679, Patchset 18: config.nameservers = {IPEndPoint(IPAddress(1, 2, 3, 4), 53)};
Line 679, Patchset 18: config.nameservers = {IPEndPoint(IPAddress(1, 2, 3, 4), 53)};
File net/dns/host_resolver_manager.cc
Line 489, Patchset 15: nullptr /* url_request_context= */, false /* enable_caching */);
Andrew Williams . resolved

nit: for new code prefer using the format `/*url_request_context=*/nullptr` so that the tooling will ensure that the comment correctly indicates the parameter name

https://clang.llvm.org/extra/clang-tidy/checks/bugprone/argument-comment.html

Brian Begnoche

Ack. This is resolved with the chagne to use CreateResolver.

I'll look for this anywhere else. Please comment if I miss any.

Line 490, Patchset 15: std::unique_ptr<HostResolver> resolver = std::make_unique<ContextHostResolver>(this, std::move(context));
Andrew Williams . resolved

Can we use HostResolver::CreateResolver for this? It seems to do the same things

Brian Begnoche

Done

Line 673, Patchset 15: MaybeProbeSecureDnsCanaryDomain();
Andrew Williams . resolved

Just to check, do we need to do this in the !changed case?

Brian Begnoche

No, moved.

Line 1734, Patchset 15: DnsConfig config_copy = config.value_or(DnsConfig());
Andrew Williams . resolved

looks like we don't need this anymore

Brian Begnoche

Done

File net/dns/host_resolver_manager_unittest.cc
Line 4507, Patchset 18:TEST_F(HostResolverManagerDnsTest, SecureDnsCanaryDomainProbe_KeepsDohFallbackEnabled) {
Andrew Williams . resolved

nit: It'd probably be worth a subclass that enables the feature since we have multiple tests here using that

Brian Begnoche

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Andrew Williams
  • David Schinazi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
Gerrit-Change-Number: 7509892
Gerrit-PatchSet: 19
Gerrit-Owner: Brian Begnoche <b...@chromium.org>
Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
Gerrit-Attention: Andrew Williams <awi...@chromium.org>
Gerrit-Attention: David Schinazi <dsch...@chromium.org>
Gerrit-Comment-Date: Wed, 04 Feb 2026 21:43:47 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Andrew Williams <awi...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Brian Begnoche (Gerrit)

unread,
Feb 6, 2026, 4:44:46 PMFeb 6
to Kenichi Ishibashi, Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
Attention needed from Andrew Williams, David Schinazi and Kenichi Ishibashi

Brian Begnoche added 8 comments

File net/dns/canary_domain_service.cc
Line 23, Patchset 15: params.source = HostResolverSource::SYSTEM;
Andrew Williams . unresolved

I wonder if `HostResolverSource::ANY` should be used to allow use of the built-in resolver, given that we don't require use of the system provider. I'm not sure the full implications of this, though.

Brian Begnoche

I don't know either, but I don't have a reason to prevent the built-in resolver. I'll leave this comment open for net owners to comment.

Line 98, Patchset 15: base::StrCat({"Net.DNS.CanaryDomainService.", probe_name, ".Result"}),
Andrew Williams . resolved

nit: can std::move(probe_name) here

Brian Begnoche

I'm less clear on whether this still makes sense, since it's now owned now by the probe struct?

Brian Begnoche

In any case, the probe callback is moved, so moving the name is fine too. Done.

File net/dns/canary_domain_service_unittest.cc
Line 91, Patchset 18:
Andrew Williams . resolved

It might be useful to add a SERVFAIL case as well to test the default case

Brian Begnoche

I tried really hard to make this happen. I don't think it's possible, at least not trivially.

The short of it is that `MockHostResolver::Resolve` sees no rule that resolves to an IP and returns `ERR_NAME_NOT_RESOLVED`, even if the rule specifies some other error code.

Brian Begnoche

I've addressed this the best I can with reworking the result that is logged and to test appropriately here.

I was wrong with what I said before. `MockHostResolver` is WAI, but `HostResolver::SquashErrorCode()` squashes various error codes to `ERR_NAME_NOT_RESOLVED`.

File net/dns/dns_client.cc
Line 135, Patchset 15: config->secure_dns_mode = SecureDnsMode::kOff;
Andrew Williams . unresolved

I don't think we should change secure_dns_mode, can we not just avoid modifying doh_config in the case when the canary domain indicates we should fallback to Google DNS? That's how the code works today

Brian Begnoche

I can see both ways. IMO it makes sense to clearly categorize this as a case where Secure DNS is turned off because fallback is not possible.

I'd like to hear thoughts from net owners.

File net/dns/dns_config.h
Line 116, Patchset 15: bool doh_fallback_allowed_by_canary_domain = true;
Andrew Williams . resolved

Should probably default to false? Should we disable the fallback until we hear back that it's OK?

Brian Begnoche

I think so, after thinking about it more. Done.

File net/dns/host_resolver_manager.cc
Line 1753, Patchset 15: MaybeProbeSecureDnsCanaryDomain();
Andrew Williams . resolved

Should we invalidate the existing canary domain check status on system DNS config change prior to the results of the query coming back?

Brian Begnoche

I reworked `CanaryDomainService` to do this. There should only ever be one pending probe at any given time now.

Line 1779, Patchset 15: canary_domain_service_->ProbeSecureDnsDomain(
Andrew Williams . resolved

I wonder if we should set a boolean when a probe is currently running and not start a new one if so

Brian Begnoche

I think that this is addressed now. Please reopen or add a new comment if you still see an issue.

File tools/metrics/histograms/metadata/net/histograms.xml
Line 2366, Patchset 18: Records the result of a canary domain probe used to determine whether Secure
Andrew Williams . resolved

I think we'll need a bit more description for these, specifically when it is recorded

https://chromium.googlesource.com/chromium/src/+/lkgr/tools/metrics/histograms/README.md#documenting-histograms

Brian Begnoche

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Andrew Williams
  • David Schinazi
  • Kenichi Ishibashi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
Gerrit-Change-Number: 7509892
Gerrit-PatchSet: 22
Gerrit-Owner: Brian Begnoche <b...@chromium.org>
Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Attention: Andrew Williams <awi...@chromium.org>
Gerrit-Attention: David Schinazi <dsch...@chromium.org>
Gerrit-Comment-Date: Fri, 06 Feb 2026 21:44:38 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Brian Begnoche <b...@chromium.org>
Comment-In-Reply-To: Andrew Williams <awi...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Kenichi Ishibashi (Gerrit)

unread,
Feb 8, 2026, 10:55:34 PM (12 days ago) Feb 8
to Brian Begnoche, Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
Attention needed from Andrew Williams, Brian Begnoche and David Schinazi

Kenichi Ishibashi added 15 comments

Patchset-level comments
File-level comment, Patchset 22 (Latest):
Kenichi Ishibashi . resolved

I haven't looked into tests yet.

File net/dns/canary_domain_service.h
Line 45, Patchset 21: explicit CanaryDomainService(std::unique_ptr<HostResolver> host_resolver,
Kenichi Ishibashi . unresolved

nit: Remove `explicit`.

File net/dns/canary_domain_service.cc
Line 23, Patchset 15: params.source = HostResolverSource::SYSTEM;
Andrew Williams . unresolved

I wonder if `HostResolverSource::ANY` should be used to allow use of the built-in resolver, given that we don't require use of the system provider. I'm not sure the full implications of this, though.

Kenichi Ishibashi

Yeah, why do we want to restrict to use SYSTEM?

Line 34, Patchset 22 (Latest): params.source = HostResolverSource::ANY;
Kenichi Ishibashi . unresolved

If we use `ANY`, we don't have to set this since `ANY` is the default initial value.

Line 37, Patchset 21: params.dns_query_type = DnsQueryType::UNSPECIFIED; // both A and AAAA
Kenichi Ishibashi . unresolved

We don't have to set this since `UNSPECIFIED` is the default initial value (also UNSPECIFIED may query HTTPS).

Line 66, Patchset 21: NetLogWithSource::Make(net_log, NetLogSourceType::DNS_TRANSACTION)) {}
Kenichi Ishibashi . unresolved

This doesn't seems an appropriate source type. Maybe we should add a new source type.

Line 75, Patchset 22 (Latest): Probe("SecureDns", features::kSecureDnsCanaryDomainHost.Get(),
Kenichi Ishibashi . unresolved

Just inline `Probe()` here?

Line 84, Patchset 22 (Latest): HostPortPair host_port_pair(host, 80);
Kenichi Ishibashi . unresolved

Why do we use `80` here? If arbitrary port works, using `0` might be a better one (since it doesn't imply HTTP)

Line 90, Patchset 22 (Latest): host_resolver_->CreateRequest(host_port_pair,
Kenichi Ishibashi . unresolved

nit: std::move(host_port_pair), or inline.

Line 109, Patchset 22 (Latest):void CanaryDomainService::OnProbeComplete(const std::string& probe_name,
Kenichi Ishibashi . unresolved

We don't need this since `pending_probe_` has it?

Line 133, Patchset 22 (Latest):CanaryDomainService::PendingProbe::PendingProbe(
std::unique_ptr<HostResolver::ResolveHostRequest> request,
Callback callback,
std::string probe_name)
: request(std::move(request)),
callback(std::move(callback)),
probe_name(std::move(probe_name)) {}

CanaryDomainService::PendingProbe::~PendingProbe() = default;
Kenichi Ishibashi . unresolved

nit: Move these above CanaryDomainService methods (we usually do so).

File net/dns/dns_client.cc
Line 128, Patchset 19: config->doh_config =
Andrew Williams . unresolved

I was originally wondering whether the canary domain check and the test DoH probes would need to happen in that order. I had convinced myself that they didn't need to be ordered and that once both succeeded we'd upgrade queries that happen after. After thinking about it again, though, it seems like before the test DoH probes run we need `config->doh_config` to be set to the DoH config we should send probes for (which wouldn't be the case in this if block)... I'm not sure what the right thing to do here is

Kenichi Ishibashi

It seems we should have a state (enum class) instead of having a boolean flag to distinguish the states? Probably kUnknown (checking), kPositive, kNegative.

Line 135, Patchset 15: config->secure_dns_mode = SecureDnsMode::kOff;
Andrew Williams . unresolved

I don't think we should change secure_dns_mode, can we not just avoid modifying doh_config in the case when the canary domain indicates we should fallback to Google DNS? That's how the code works today

Brian Begnoche

I can see both ways. IMO it makes sense to clearly categorize this as a case where Secure DNS is turned off because fallback is not possible.

I'd like to hear thoughts from net owners.

Kenichi Ishibashi

I'm wondering if we should add kDisabledByCanaryDomainCheck to categorize precisely.

Line 253, Patchset 15: doh_fallback_allowed_by_canary_domain_ = allowed;
Andrew Williams . unresolved

I wonder if the more consistent way of applying this change would be to have an entry in DnsConfigOverrides for this boolean and setting that here. Then we don't need the `doh_fallback_allowed_by_canary_domain_ == allowed` check, because IIUC that's handled by UpdateDnsConfig

Brian Begnoche

I thought about this too. The reason I didn't do that was that I didn't want `SetConfigOverrides` to clobber this. So it'd need to do something to persist this value after updating the overrides. It's like an override of overrides, so kind of odd.

Alternatively, it could be a second DnsConfigOverrides that just stores this override, but then `UpdateDnsConfig` needs to be updated regardless. I guess there is an advantage to this in that it would be a canned `DnsConfigOverrides` that can (1) set this value (2) override `secure_dns_mode` (3) clear `doh_config.servers`.

I think I would prefer the latter approach, if anything. What are your thoughts?

Kenichi Ishibashi

I had the same question. It's a good point we don't want to clobber canary domain check. Regardless how we handle it, could you document the requirement?

File net/dns/host_resolver_manager.cc
Line 491, Patchset 15: canary_domain_service_ = std::make_unique<CanaryDomainService>(std::move(resolver), net_log);
Andrew Williams . unresolved

I'm not sure if it makes the most sense for HostResolverManager to own this... I wonder if it should be owned by the NetworkService the way DelayedDohProbeActivator is (so, is a sibling to HostResolverManager):

https://source.chromium.org/chromium/chromium/src/+/main:services/network/network_service.cc;l=478-485;drc=85adc28ab1a46f69c6f24479242288f0edc4589d

WDYT?

I think using a delayed approach like DelayedDohProbeActivator is worth doing as well. For IP Protection we triggered requests right at NetworkService creation time and particularly on Android we had a lot of issue with requests failing. Those were HTTP requests instead of DNS requests, but still, it seems safest to a wait a bit.

Kenichi Ishibashi

It seems NetworkService is an appropriate owner of CanaryDomainService. NetworkService listens to config changes via NetworkChangeNotifier::DNSObserver (or SystemDnsConfigChangeNotifier, less preferable) and uses host_resolver_manager_ to create an inner HostResolver.

IIUC we will move DnsClient from HostResolverManager to ResolveContext in the future so if we make HostResolverManager owns CanaryDomainService I guess we would need to update it later as well.

Open in Gerrit

Related details

Attention is currently required from:
  • Andrew Williams
  • Brian Begnoche
  • David Schinazi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
Gerrit-Change-Number: 7509892
Gerrit-PatchSet: 22
Gerrit-Owner: Brian Begnoche <b...@chromium.org>
Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
Gerrit-Attention: Brian Begnoche <b...@chromium.org>
Gerrit-Attention: Andrew Williams <awi...@chromium.org>
Gerrit-Attention: David Schinazi <dsch...@chromium.org>
Gerrit-Comment-Date: Mon, 09 Feb 2026 03:55:02 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Brian Begnoche (Gerrit)

unread,
Feb 9, 2026, 5:47:11 PM (12 days ago) Feb 9
to Kenichi Ishibashi, Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
Attention needed from Andrew Williams, David Schinazi and Kenichi Ishibashi

Brian Begnoche added 12 comments

File net/dns/canary_domain_service.h
Line 45, Patchset 21: explicit CanaryDomainService(std::unique_ptr<HostResolver> host_resolver,
Kenichi Ishibashi . resolved

nit: Remove `explicit`.

Brian Begnoche

Done

File net/dns/canary_domain_service.cc
Line 23, Patchset 15: params.source = HostResolverSource::SYSTEM;
Andrew Williams . resolved

I wonder if `HostResolverSource::ANY` should be used to allow use of the built-in resolver, given that we don't require use of the system provider. I'm not sure the full implications of this, though.

Kenichi Ishibashi

Yeah, why do we want to restrict to use SYSTEM?

Brian Begnoche

This is now ANY.

Line 34, Patchset 22: params.source = HostResolverSource::ANY;
Kenichi Ishibashi . resolved

If we use `ANY`, we don't have to set this since `ANY` is the default initial value.

Brian Begnoche

Removed

Line 37, Patchset 21: params.dns_query_type = DnsQueryType::UNSPECIFIED; // both A and AAAA
Kenichi Ishibashi . unresolved

We don't have to set this since `UNSPECIFIED` is the default initial value (also UNSPECIFIED may query HTTPS).

Brian Begnoche

I removed this.

About UNSPECIFIED possibly using HTTPS, does this present an issue with being consistent with the canary domain check for prefetch proxy? It specifically mentions just A and AAAA, so I'm not sure whether allowing anything else makes sense.

 https://developer.chrome.com/docs/privacy-security/private-prefetch-proxy-for-network-admins#details_of_the_signaling_mechanism?
Line 66, Patchset 21: NetLogWithSource::Make(net_log, NetLogSourceType::DNS_TRANSACTION)) {}
Kenichi Ishibashi . resolved

This doesn't seems an appropriate source type. Maybe we should add a new source type.

Brian Begnoche

Added a new `CANARY_DOMAIN_RESOLUTION` source type

Line 75, Patchset 22: Probe("SecureDns", features::kSecureDnsCanaryDomainHost.Get(),
Kenichi Ishibashi . resolved

Just inline `Probe()` here?

Brian Begnoche

Done

Line 84, Patchset 22: HostPortPair host_port_pair(host, 80);
Kenichi Ishibashi . resolved

Why do we use `80` here? If arbitrary port works, using `0` might be a better one (since it doesn't imply HTTP)

Brian Begnoche

I just picked this up from an example. I appreciate your scrutinizing the details.

Changed to 0.

Line 90, Patchset 22: host_resolver_->CreateRequest(host_port_pair,
Kenichi Ishibashi . resolved

nit: std::move(host_port_pair), or inline.

Brian Begnoche

Done

Line 109, Patchset 22:void CanaryDomainService::OnProbeComplete(const std::string& probe_name,
Kenichi Ishibashi . unresolved

We don't need this since `pending_probe_` has it?

Brian Begnoche

I did this to be able to log the case where `std::move(pending_probe_)` returns null. What do you think? Unnecessary?

Line 133, Patchset 22:CanaryDomainService::PendingProbe::PendingProbe(

std::unique_ptr<HostResolver::ResolveHostRequest> request,
Callback callback,
std::string probe_name)
: request(std::move(request)),
callback(std::move(callback)),
probe_name(std::move(probe_name)) {}

CanaryDomainService::PendingProbe::~PendingProbe() = default;
Kenichi Ishibashi . resolved

nit: Move these above CanaryDomainService methods (we usually do so).

Brian Begnoche

Done

File net/dns/dns_client.cc
Line 253, Patchset 15: doh_fallback_allowed_by_canary_domain_ = allowed;
Andrew Williams . unresolved

I wonder if the more consistent way of applying this change would be to have an entry in DnsConfigOverrides for this boolean and setting that here. Then we don't need the `doh_fallback_allowed_by_canary_domain_ == allowed` check, because IIUC that's handled by UpdateDnsConfig

Brian Begnoche

I thought about this too. The reason I didn't do that was that I didn't want `SetConfigOverrides` to clobber this. So it'd need to do something to persist this value after updating the overrides. It's like an override of overrides, so kind of odd.

Alternatively, it could be a second DnsConfigOverrides that just stores this override, but then `UpdateDnsConfig` needs to be updated regardless. I guess there is an advantage to this in that it would be a canned `DnsConfigOverrides` that can (1) set this value (2) override `secure_dns_mode` (3) clear `doh_config.servers`.

I think I would prefer the latter approach, if anything. What are your thoughts?

Kenichi Ishibashi

I had the same question. It's a good point we don't want to clobber canary domain check. Regardless how we handle it, could you document the requirement?

Brian Begnoche

I still need to act on this comment on way or the other. I'm hesitant to introduce a precedent for overrides that aren't overridable, or something novel like that, so I'm still a bit inclined to keep this as is.

Ack to bashi to document whatever we end up with.

I'd appreciate hearing any strong opinions against leaving it like this.

File net/dns/host_resolver_manager.cc
Line 491, Patchset 15: canary_domain_service_ = std::make_unique<CanaryDomainService>(std::move(resolver), net_log);
Andrew Williams . resolved

I'm not sure if it makes the most sense for HostResolverManager to own this... I wonder if it should be owned by the NetworkService the way DelayedDohProbeActivator is (so, is a sibling to HostResolverManager):

https://source.chromium.org/chromium/chromium/src/+/main:services/network/network_service.cc;l=478-485;drc=85adc28ab1a46f69c6f24479242288f0edc4589d

WDYT?

I think using a delayed approach like DelayedDohProbeActivator is worth doing as well. For IP Protection we triggered requests right at NetworkService creation time and particularly on Android we had a lot of issue with requests failing. Those were HTTP requests instead of DNS requests, but still, it seems safest to a wait a bit.

Kenichi Ishibashi

It seems NetworkService is an appropriate owner of CanaryDomainService. NetworkService listens to config changes via NetworkChangeNotifier::DNSObserver (or SystemDnsConfigChangeNotifier, less preferable) and uses host_resolver_manager_ to create an inner HostResolver.

IIUC we will move DnsClient from HostResolverManager to ResolveContext in the future so if we make HostResolverManager owns CanaryDomainService I guess we would need to update it later as well.

Brian Begnoche

I've moved CanaryDomainService to be owned by NetworkService. Relevant tests are now in network_service_unittest.cc instead of host_resolver_manager_unittest.cc.

When HRM is updated to manage a DnsClient owned by each ResolveContext, `SetDohFallbackAllowedByCanaryDomain` will need to propagate the call to each DnsClient instead of just the one.

Open in Gerrit

Related details

Attention is currently required from:
  • Andrew Williams
  • David Schinazi
  • Kenichi Ishibashi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
Gerrit-Change-Number: 7509892
Gerrit-PatchSet: 23
Gerrit-Owner: Brian Begnoche <b...@chromium.org>
Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Attention: Andrew Williams <awi...@chromium.org>
Gerrit-Attention: David Schinazi <dsch...@chromium.org>
Gerrit-Comment-Date: Mon, 09 Feb 2026 22:47:07 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Brian Begnoche <b...@chromium.org>
Comment-In-Reply-To: Kenichi Ishibashi <ba...@chromium.org>
Comment-In-Reply-To: Andrew Williams <awi...@chromium.org>
satisfied_requirement
unsatisfied_requirement
open
diffy

Brian Begnoche (Gerrit)

unread,
Feb 11, 2026, 2:05:40 PM (10 days ago) Feb 11
to Kenichi Ishibashi, Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
Attention needed from Andrew Williams, David Schinazi and Kenichi Ishibashi

Brian Begnoche added 5 comments

Patchset-level comments
File-level comment, Patchset 15:
Brian Begnoche . resolved

I will close this once I've added tests to host_resolver_manager_unittest.cc.

Brian Begnoche

Done

File net/dns/canary_domain_service.cc
Line 109, Patchset 22:void CanaryDomainService::OnProbeComplete(const std::string& probe_name,
Kenichi Ishibashi . resolved

We don't need this since `pending_probe_` has it?

Brian Begnoche

I did this to be able to log the case where `std::move(pending_probe_)` returns null. What do you think? Unnecessary?

Brian Begnoche

In any case, this is moot now that I've made this callback specifically for Secure DNS probe to match.

File net/dns/dns_client.cc
Line 128, Patchset 19: config->doh_config =
Andrew Williams . resolved

I was originally wondering whether the canary domain check and the test DoH probes would need to happen in that order. I had convinced myself that they didn't need to be ordered and that once both succeeded we'd upgrade queries that happen after. After thinking about it again, though, it seems like before the test DoH probes run we need `config->doh_config` to be set to the DoH config we should send probes for (which wouldn't be the case in this if block)... I'm not sure what the right thing to do here is

Kenichi Ishibashi

It seems we should have a state (enum class) instead of having a boolean flag to distinguish the states? Probably kUnknown (checking), kPositive, kNegative.

Brian Begnoche

Andrew and I talked more about this timing thing. Our conclusion is that timing is OK for two reasons:

1. Because the code here doesn't allow fallback upgrade until the canary domain check finishes successfully, the prober when fallback is needed won't occur until that happens and a system config update triggers the probe.

2. `HostResolverManager::PushDnsTasks` won't push the `SECURE_DNS` task until the following two things both happen:

 (a) The canary domain check is positive and retriggers config update here to allow the fallback upgrade.

(b) The DoH prober doesn't record enough failures to make `DnsClient::FallbackFromSecureTransactionPreferred` start returning false.

I've also updated the histogram to log an enum.
Line 135, Patchset 15: config->secure_dns_mode = SecureDnsMode::kOff;
Andrew Williams . resolved

I don't think we should change secure_dns_mode, can we not just avoid modifying doh_config in the case when the canary domain indicates we should fallback to Google DNS? That's how the code works today

Brian Begnoche

I can see both ways. IMO it makes sense to clearly categorize this as a case where Secure DNS is turned off because fallback is not possible.

I'd like to hear thoughts from net owners.

Kenichi Ishibashi

I'm wondering if we should add kDisabledByCanaryDomainCheck to categorize precisely.

Brian Begnoche

Andrew and I talked about this. I'm happy to sync with you on this if needed, Kenichi.

The gist is that we want to remain consistent with the way the Doh prober works today. That prober only prevents pushing the `SECURE_DNS` task for DNS lookups. The way this happens is that `DnsClient::FallbackFromSecureTransactionPreferred` returns false when the prober has failed, and the `SECURE_DNS` task is not allowed.

crsrc.org/c/net/dns/host_resolver_manager.cc;l=1310;drc=ef55be496e45889ace33ace4b05094ca19cb499b;bpv=1;bpt=1

The failed probe doesn't set `secure_dns_mode` to OFF, so we won't do that here either. I've added mention of this in the design doc too.

Line 253, Patchset 15: doh_fallback_allowed_by_canary_domain_ = allowed;
Andrew Williams . resolved

I wonder if the more consistent way of applying this change would be to have an entry in DnsConfigOverrides for this boolean and setting that here. Then we don't need the `doh_fallback_allowed_by_canary_domain_ == allowed` check, because IIUC that's handled by UpdateDnsConfig

Brian Begnoche

I thought about this too. The reason I didn't do that was that I didn't want `SetConfigOverrides` to clobber this. So it'd need to do something to persist this value after updating the overrides. It's like an override of overrides, so kind of odd.

Alternatively, it could be a second DnsConfigOverrides that just stores this override, but then `UpdateDnsConfig` needs to be updated regardless. I guess there is an advantage to this in that it would be a canned `DnsConfigOverrides` that can (1) set this value (2) override `secure_dns_mode` (3) clear `doh_config.servers`.

I think I would prefer the latter approach, if anything. What are your thoughts?

Kenichi Ishibashi

I had the same question. It's a good point we don't want to clobber canary domain check. Regardless how we handle it, could you document the requirement?

Brian Begnoche

I still need to act on this comment on way or the other. I'm hesitant to introduce a precedent for overrides that aren't overridable, or something novel like that, so I'm still a bit inclined to keep this as is.

Ack to bashi to document whatever we end up with.

I'd appreciate hearing any strong opinions against leaving it like this.

Brian Begnoche

I added discussion on why `SetDohFallbackAllowedByCanaryDomain` is added to record and retain the canary domain result.

https://docs.google.com/document/d/1hN7cVtyqKE-qCArtQJWnOeniRjx6NSaYyyz5EP9cpWA/edit?pli=1&resourcekey=0-rdt7WOE8fVokAgiByxGCLQ&tab=t.0#bookmark=id.w9hakfa0iqhc

Please comment where you feel that comments in code are not inadequate.

Open in Gerrit

Related details

Attention is currently required from:
  • Andrew Williams
  • David Schinazi
  • Kenichi Ishibashi
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
Gerrit-Change-Number: 7509892
Gerrit-PatchSet: 24
Gerrit-Owner: Brian Begnoche <b...@chromium.org>
Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
Gerrit-Attention: Andrew Williams <awi...@chromium.org>
Gerrit-Attention: David Schinazi <dsch...@chromium.org>
Gerrit-Comment-Date: Wed, 11 Feb 2026 19:05:34 +0000
satisfied_requirement
unsatisfied_requirement
open
diffy

Kenichi Ishibashi (Gerrit)

unread,
Feb 11, 2026, 11:50:18 PM (9 days ago) Feb 11
to Brian Begnoche, Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
Attention needed from Andrew Williams, Brian Begnoche and David Schinazi

Kenichi Ishibashi added 1 comment

File net/dns/canary_domain_service.cc
Line 37, Patchset 21: params.dns_query_type = DnsQueryType::UNSPECIFIED; // both A and AAAA
Kenichi Ishibashi . resolved

We don't have to set this since `UNSPECIFIED` is the default initial value (also UNSPECIFIED may query HTTPS).

Brian Begnoche

I removed this.

About UNSPECIFIED possibly using HTTPS, does this present an issue with being consistent with the canary domain check for prefetch proxy? It specifically mentions just A and AAAA, so I'm not sure whether allowing anything else makes sense.

 https://developer.chrome.com/docs/privacy-security/private-prefetch-proxy-for-network-admins#details_of_the_signaling_mechanism?
Kenichi Ishibashi

I just realized we wouldn't query HTTPS in this check since we use HostPortPair to call HostResolver::CreateRequest(). We only query HTTPS when scheme (`https://`) is specified.

Open in Gerrit

Related details

Attention is currently required from:
  • Andrew Williams
  • Brian Begnoche
  • David Schinazi
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
    Gerrit-Change-Number: 7509892
    Gerrit-PatchSet: 24
    Gerrit-Owner: Brian Begnoche <b...@chromium.org>
    Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
    Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
    Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
    Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
    Gerrit-Attention: Brian Begnoche <b...@chromium.org>
    Gerrit-Attention: Andrew Williams <awi...@chromium.org>
    Gerrit-Attention: David Schinazi <dsch...@chromium.org>
    Gerrit-Comment-Date: Thu, 12 Feb 2026 04:49:45 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Andrew Williams (Gerrit)

    unread,
    Feb 12, 2026, 10:32:19 AM (9 days ago) Feb 12
    to Brian Begnoche, Kenichi Ishibashi, David Schinazi, Chromium Metrics Reviews, AyeAye, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
    Attention needed from Brian Begnoche and David Schinazi

    Andrew Williams added 2 comments

    File services/network/network_service.h
    Line 96, Patchset 24 (Latest): public net::NetworkChangeNotifier::DNSObserver {
    Andrew Williams . unresolved

    I think we're missing the NetworkChangeNotifier::AddDNSObserver / NetworkChangeNotifier::RemoveDNSObserver calls needed to hook this up

    File services/network/network_service.cc
    Line 1261, Patchset 24 (Latest): MaybeProbeSecureDnsCanaryDomain();
    Andrew Williams . unresolved

    Should we call `host_resolver_manager()->SetDohFallbackAllowedByCanaryDomain(false)` here so that we don't attempt to use secure DNS until the new canary domain check comes back?

    I'm not sure whether OnDNSChanged will trigger before the state of the probes change (triggering resending the probes), though, so if not it seems unfortunate that we might:
    - Received a system DNS change
    - Start the probes
    - This method gets called and we update the DnsConfig to indicate that the canary domain check hasn't succeeded
    - Cancel the DoH probes (I think?)
    - Do the canary domain check and update the DnsConfig if they pass
    - Restart the DoH probes
    Open in Gerrit

    Related details

    Attention is currently required from:
    • Brian Begnoche
    • David Schinazi
    Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
      Gerrit-Change-Number: 7509892
      Gerrit-PatchSet: 24
      Gerrit-Owner: Brian Begnoche <b...@chromium.org>
      Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
      Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
      Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
      Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
      Gerrit-Attention: Brian Begnoche <b...@chromium.org>
      Gerrit-Attention: David Schinazi <dsch...@chromium.org>
      Gerrit-Comment-Date: Thu, 12 Feb 2026 15:32:12 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Brian Begnoche (Gerrit)

      unread,
      Feb 15, 2026, 11:53:17 AM (6 days ago) Feb 15
      to Kenichi Ishibashi, Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
      Attention needed from Andrew Williams and David Schinazi

      Brian Begnoche added 4 comments

      Patchset-level comments
      File-level comment, Patchset 26:
      Brian Begnoche . resolved

      bashi's feedback is to incorporate awillia's proposal (crrev.com/c/7567908) to shift to CanaryDomainService ownership by NetworkContext. I have done that.

      File services/network/network_context.cc
      Line 1025, Patchset 27 (Latest): if (base::FeatureList::IsEnabled(
      Brian Begnoche . resolved

      I have added this here, which means that the canary domain check won't start until after the DoH probe delay. Basically they start together.

      I pondered and concluded that this is reasonable. I've become more and more convinced that the more that these two are consistent and work in concert, the better.

      If we don't want to delay on the canary domain check, then we could add an `NetworkContext::ActivateCanaryDomainCheck` method that just does this added bit, and then `NetworkService::ActivateAllDohProbes` would call this new method to avoid the timer delay.

      File services/network/network_service.h
      Line 96, Patchset 24: public net::NetworkChangeNotifier::DNSObserver {
      Andrew Williams . resolved

      I think we're missing the NetworkChangeNotifier::AddDNSObserver / NetworkChangeNotifier::RemoveDNSObserver calls needed to hook this up

      Brian Begnoche

      You're right. I did this and didn't upload. This is a moot point now after moving `CanaryDomainService` ownership to `NetworkContext`.

      File services/network/network_service.cc
      Line 1261, Patchset 24: MaybeProbeSecureDnsCanaryDomain();
      Andrew Williams . resolved

      Should we call `host_resolver_manager()->SetDohFallbackAllowedByCanaryDomain(false)` here so that we don't attempt to use secure DNS until the new canary domain check comes back?

      I'm not sure whether OnDNSChanged will trigger before the state of the probes change (triggering resending the probes), though, so if not it seems unfortunate that we might:
      - Received a system DNS change
      - Start the probes
      - This method gets called and we update the DnsConfig to indicate that the canary domain check hasn't succeeded
      - Cancel the DoH probes (I think?)
      - Do the canary domain check and update the DnsConfig if they pass
      - Restart the DoH probes
      Brian Begnoche

      This is a moot point now that `CanaryDomainService` creation and triggering the canary domain probe are moved to `NetworkContext::ActivateDohProbes`.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Andrew Williams
      • David Schinazi
      Submit Requirements:
        • requirement satisfiedCode-Coverage
        • requirement is not satisfiedCode-Owners
        • requirement is not satisfiedCode-Review
        • requirement is not satisfiedReview-Enforcement
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: chromium/src
        Gerrit-Branch: main
        Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
        Gerrit-Change-Number: 7509892
        Gerrit-PatchSet: 27
        Gerrit-Owner: Brian Begnoche <b...@chromium.org>
        Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
        Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
        Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
        Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
        Gerrit-Attention: Andrew Williams <awi...@chromium.org>
        Gerrit-Attention: David Schinazi <dsch...@chromium.org>
        Gerrit-Comment-Date: Sun, 15 Feb 2026 16:53:10 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        Comment-In-Reply-To: Andrew Williams <awi...@chromium.org>
        satisfied_requirement
        unsatisfied_requirement
        open
        diffy

        Kenichi Ishibashi (Gerrit)

        unread,
        Feb 15, 2026, 9:10:07 PM (5 days ago) Feb 15
        to Brian Begnoche, Chromium LUCI CQ, Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
        Attention needed from Andrew Williams, Brian Begnoche and David Schinazi

        Kenichi Ishibashi added 14 comments

        Patchset-level comments
        File-level comment, Patchset 27 (Latest):
        Kenichi Ishibashi . resolved

        (Still haven't looked into tests)

        File net/dns/canary_domain_service.h
        Line 71, Patchset 27 (Latest): base::WeakPtr<ResolveContext> resolve_context_;

        // The HostResolver that this service uses to perform probes.
        base::WeakPtr<HostResolver> host_resolver_;
        Kenichi Ishibashi . unresolved

        What's the expected life time relation between `resolve_context_`, `host_resolver_` and this service? IIUC NetworkContext owns ResolveContext (via UrlRequestContext, ContextHostResolver). If ResolveContext/HostResolver are expected to outlive `this`, probably using base::SafeRef would be better.

        Line 39, Patchset 27 (Latest):// Service for probing canary domains. It is owned by a HostResolverManager.
        Kenichi Ishibashi . unresolved

        NetworkContext?

        File net/dns/canary_domain_service.cc
        Line 35, Patchset 27 (Latest): HostResolver::ResolveHostParameters::CacheUsage::DISALLOWED;
        Kenichi Ishibashi . unresolved

        nit: Could you add a comment why we disable secure DNS for this probe (it may not be obvious if the reader is not very familiar with canary domain check)?

        Line 70, Patchset 27 (Latest): NetLogSourceType::CANARY_DOMAIN_SERVICE)) {}
        Kenichi Ishibashi . unresolved

        Add `CHECK(base::FeatureList::IsEnabled(features::kProbeSecureDnsCanaryDomain))` ?

        Line 79, Patchset 27 (Latest): if (resolve_context_) {
        Kenichi Ishibashi . unresolved

        Should we CHECK(resolve_context_) instead?

        Line 80, Patchset 27 (Latest): resolve_context_->RegisterDohStatusObserver(this);
        Kenichi Ishibashi . unresolved

        optional: Does this mean Start() should be called only once. Should we somehow ensure the precondition?

        Line 90, Patchset 27 (Latest): if (base::FeatureList::IsEnabled(features::kProbeSecureDnsCanaryDomain)) {
        Kenichi Ishibashi . unresolved

        Should this be `CHECK(base::FeatureList::IsEnabled(features::kProbeSecureDnsCanaryDomain))`?

        If we add CHECK in the ctor, the check would be redundant.

        Line 92, Patchset 27 (Latest): resolve_context_->canary_domain_check_status() ==
        ResolveContext::CanaryDomainCheckStatus::kNotStarted) {
        Kenichi Ishibashi . unresolved

        awillia@: Does this look reasonable (I guess the answer is yes)? Or should we always (re)start probe? If so, should we reset the check status?

        File net/dns/canary_domain_service_unittest.cc
        Line 1, Patchset 27 (Latest):#include "net/dns/canary_domain_service.h"
        Kenichi Ishibashi . unresolved

        Missing licence header comment.

        File net/dns/dns_client.cc
        Line 224, Patchset 27 (Latest): UMA_HISTOGRAM_ENUMERATION("Net.DNS.FallbackFromSecureTransactionPreferred",
        File net/dns/host_resolver.h
        Line 567, Patchset 27 (Latest): virtual std::unique_ptr<CanaryDomainService> CreateCanaryDomainService();
        Kenichi Ishibashi . unresolved

        Please add a description comment for virtual method that is considered as an interface to HostResolver.

        File net/dns/resolve_context.h
        Line 233, Patchset 27 (Latest): enum class CanaryDomainCheckStatus {
        Kenichi Ishibashi . unresolved

        nit: Please add description comments.

        File services/network/network_service_unittest.cc
        Line 139, Patchset 27 (Latest): protected:
        Kenichi Ishibashi . unresolved

        Why do we need make this change? Can't we use `task_environment()` and `service()` in tests?

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Andrew Williams
        • Brian Begnoche
        • David Schinazi
        Submit Requirements:
          • requirement satisfiedCode-Coverage
          • requirement is not satisfiedCode-Owners
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: chromium/src
          Gerrit-Branch: main
          Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
          Gerrit-Change-Number: 7509892
          Gerrit-PatchSet: 27
          Gerrit-Owner: Brian Begnoche <b...@chromium.org>
          Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
          Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
          Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
          Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
          Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
          Gerrit-Attention: Brian Begnoche <b...@chromium.org>
          Gerrit-Attention: Andrew Williams <awi...@chromium.org>
          Gerrit-Attention: David Schinazi <dsch...@chromium.org>
          Gerrit-Comment-Date: Mon, 16 Feb 2026 02:09:33 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          Brian Begnoche (Gerrit)

          unread,
          Feb 17, 2026, 3:57:08 PM (4 days ago) Feb 17
          to Chromium LUCI CQ, Kenichi Ishibashi, Andrew Williams, David Schinazi, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
          Attention needed from Andrew Williams, David Schinazi and Kenichi Ishibashi

          Brian Begnoche added 14 comments

          File net/dns/canary_domain_service.h
          Line 71, Patchset 27: base::WeakPtr<ResolveContext> resolve_context_;


          // The HostResolver that this service uses to perform probes.
          base::WeakPtr<HostResolver> host_resolver_;
          Kenichi Ishibashi . resolved

          What's the expected life time relation between `resolve_context_`, `host_resolver_` and this service? IIUC NetworkContext owns ResolveContext (via UrlRequestContext, ContextHostResolver). If ResolveContext/HostResolver are expected to outlive `this`, probably using base::SafeRef would be better.

          Brian Begnoche

          I've changed to SafeRef and added documentation on these, as well as on the constructor above and HostResolver::CreateCanaryDomainService to clarify lifetime expectations.

          Line 39, Patchset 27:// Service for probing canary domains. It is owned by a HostResolverManager.
          Kenichi Ishibashi . resolved

          NetworkContext?

          Brian Begnoche

          Done

          File net/dns/canary_domain_service.cc
          Line 35, Patchset 27: HostResolver::ResolveHostParameters::CacheUsage::DISALLOWED;
          Kenichi Ishibashi . resolved

          nit: Could you add a comment why we disable secure DNS for this probe (it may not be obvious if the reader is not very familiar with canary domain check)?

          Brian Begnoche

          Done

          Line 70, Patchset 27: NetLogSourceType::CANARY_DOMAIN_SERVICE)) {}
          Kenichi Ishibashi . resolved

          Add `CHECK(base::FeatureList::IsEnabled(features::kProbeSecureDnsCanaryDomain))` ?

          Brian Begnoche

          Done. Also checked for canary domain. I added a comment in .h file to specify that this feature needs to be enabled.

          Line 79, Patchset 27: if (resolve_context_) {
          Kenichi Ishibashi . resolved

          Should we CHECK(resolve_context_) instead?

          Brian Begnoche

          This happens now implicitly since it is a SafeRef.

          Line 80, Patchset 27: resolve_context_->RegisterDohStatusObserver(this);
          Kenichi Ishibashi . resolved

          optional: Does this mean Start() should be called only once. Should we somehow ensure the precondition?

          Brian Begnoche

          You're right. `RegisterDohStatusObserver` will enforce this implicitly by failing on a check that the passed in observer isn't already registered.

          I'm going to assume that this is sufficient and not needing additional, more explicit enforcement. I added a comment on this method in the .h file to call this out.

          Line 90, Patchset 27: if (base::FeatureList::IsEnabled(features::kProbeSecureDnsCanaryDomain)) {
          Kenichi Ishibashi . resolved

          Should this be `CHECK(base::FeatureList::IsEnabled(features::kProbeSecureDnsCanaryDomain))`?

          If we add CHECK in the ctor, the check would be redundant.

          Brian Begnoche

          CHECK is added to the constructor. Removed this check here.

          Line 92, Patchset 27: resolve_context_->canary_domain_check_status() ==
          ResolveContext::CanaryDomainCheckStatus::kNotStarted) {
          Kenichi Ishibashi . resolved

          awillia@: Does this look reasonable (I guess the answer is yes)? Or should we always (re)start probe? If so, should we reset the check status?

          Brian Begnoche

          awillia and I talked about this a bit, and I think we agree with your suggestion to restart. I've updated ProbeSecureDnsDomain to reset the check status and added a test.

          File net/dns/canary_domain_service_unittest.cc
          Line 1, Patchset 27:#include "net/dns/canary_domain_service.h"
          Kenichi Ishibashi . resolved

          Missing licence header comment.

          Brian Begnoche

          Done

          File net/dns/dns_client.cc
          Line 224, Patchset 27: UMA_HISTOGRAM_ENUMERATION("Net.DNS.FallbackFromSecureTransactionPreferred",
          Kenichi Ishibashi . resolved
          Brian Begnoche

          Done

          Line 224, Patchset 27: UMA_HISTOGRAM_ENUMERATION("Net.DNS.FallbackFromSecureTransactionPreferred",
          Kenichi Ishibashi . resolved
          Brian Begnoche

          Done

          File net/dns/host_resolver.h
          Line 567, Patchset 27: virtual std::unique_ptr<CanaryDomainService> CreateCanaryDomainService();
          Kenichi Ishibashi . resolved

          Please add a description comment for virtual method that is considered as an interface to HostResolver.

          Brian Begnoche

          Done

          File net/dns/resolve_context.h
          Line 233, Patchset 27: enum class CanaryDomainCheckStatus {
          Kenichi Ishibashi . resolved

          nit: Please add description comments.

          Brian Begnoche

          Done

          File services/network/network_service_unittest.cc
          Line 139, Patchset 27: protected:
          Kenichi Ishibashi . resolved

          Why do we need make this change? Can't we use `task_environment()` and `service()` in tests?

          Brian Begnoche

          reverted

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Andrew Williams
          • David Schinazi
          • Kenichi Ishibashi
          Submit Requirements:
            • requirement satisfiedCode-Coverage
            • requirement is not satisfiedCode-Owners
            • requirement is not satisfiedCode-Review
            • requirement is not satisfiedReview-Enforcement
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: comment
            Gerrit-Project: chromium/src
            Gerrit-Branch: main
            Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
            Gerrit-Change-Number: 7509892
            Gerrit-PatchSet: 27
            Gerrit-Owner: Brian Begnoche <b...@chromium.org>
            Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
            Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
            Gerrit-Reviewer: David Schinazi <dsch...@chromium.org>
            Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
            Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
            Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
            Gerrit-Attention: Andrew Williams <awi...@chromium.org>
            Gerrit-Attention: David Schinazi <dsch...@chromium.org>
            Gerrit-Comment-Date: Tue, 17 Feb 2026 20:57:03 +0000
            Gerrit-HasComments: Yes
            Gerrit-Has-Labels: No
            Comment-In-Reply-To: Kenichi Ishibashi <ba...@chromium.org>
            satisfied_requirement
            unsatisfied_requirement
            open
            diffy

            David Schinazi (Gerrit)

            unread,
            Feb 18, 2026, 2:45:49 PM (3 days ago) Feb 18
            to Brian Begnoche, Chromium LUCI CQ, Kenichi Ishibashi, Andrew Williams, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
            Attention needed from Andrew Williams, Brian Begnoche and Kenichi Ishibashi

            David Schinazi added 1 comment

            Patchset-level comments
            File-level comment, Patchset 29 (Latest):
            David Schinazi . resolved

            I've reviewed this change and overall the approach seems reasonable to me. I'll let Kenichi do the actual review though, so I'm moving myself from R= to CC=.

            Open in Gerrit

            Related details

            Attention is currently required from:
            • Andrew Williams
            • Brian Begnoche
            • Kenichi Ishibashi
            Submit Requirements:
            • requirement satisfiedCode-Coverage
            • requirement is not satisfiedCode-Owners
            • requirement is not satisfiedCode-Review
            • requirement is not satisfiedReview-Enforcement
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: comment
            Gerrit-Project: chromium/src
            Gerrit-Branch: main
            Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
            Gerrit-Change-Number: 7509892
            Gerrit-PatchSet: 29
            Gerrit-Owner: Brian Begnoche <b...@chromium.org>
            Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
            Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
            Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
            Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
            Gerrit-CC: David Schinazi <dsch...@chromium.org>
            Gerrit-Attention: Brian Begnoche <b...@chromium.org>
            Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
            Gerrit-Attention: Andrew Williams <awi...@chromium.org>
            Gerrit-Comment-Date: Wed, 18 Feb 2026 19:45:38 +0000
            Gerrit-HasComments: Yes
            Gerrit-Has-Labels: No
            satisfied_requirement
            unsatisfied_requirement
            open
            diffy

            Kenichi Ishibashi (Gerrit)

            unread,
            Feb 19, 2026, 2:25:05 AM (2 days ago) Feb 19
            to Brian Begnoche, David Schinazi, Chromium LUCI CQ, Andrew Williams, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
            Attention needed from Andrew Williams and Brian Begnoche

            Kenichi Ishibashi added 15 comments

            File net/dns/canary_domain_service_unittest.cc
            Line 59, Patchset 30 (Latest): base::RunLoop().RunUntilIdle();
            Kenichi Ishibashi . unresolved

            We shouldn't use RunUntilIdle() in new tests since it's one of major sources of flakiness.

            Instead, we probably want to add SetSecureDnsProbeCompleteCallbackForTesting() to CanaryDomainService, in a way similar to https://source.chromium.org/chromium/chromium/src/+/main:net/http/http_stream_pool_test_util.cc;l=438;drc=21d7e84d240f65df7594e5f3526d63e4439dd356

            (I don't think we need an extra PostTask in the callback for these tests)

            Line 158, Patchset 30 (Latest): base::RunLoop().RunUntilIdle();
            Kenichi Ishibashi . unresolved

            Ditto.

            File net/dns/dns_client.cc
            Line 94, Patchset 30 (Latest): config.dns_over_tls_hostname)))) {
            Kenichi Ishibashi . unresolved

            Q: Do we support DoT? I'm not aware of DoT support and I'm wondering why we need to check it.

            Line 213, Patchset 30 (Latest): enum class FallbackFromSecureTransactionPreferredReason {
            Kenichi Ishibashi . unresolved

            nit: We prefer putting enum declarations before methods/constructors.

            https://google.github.io/styleguide/cppguide.html#Declaration_Order

            File net/dns/dns_client_unittest.cc
            Line 269, Patchset 30 (Latest):TEST_F(DnsClientTest, FallbackFromSecureTransactionPreferred_Failures) {
            Kenichi Ishibashi . unresolved

            Does this mean the previous name was wrong?

            Line 311, Patchset 30 (Latest): DnsConfig config = ValidConfigWithDoh(false /* doh_only */);
            Kenichi Ishibashi . unresolved

            nit: `/*doh_only=*/false`. Ditto below.

            Line 394, Patchset 30 (Latest): // Note: Current implementation of ShouldPerformDohFallbackUpgrade has a bug
            // that prevents fallback from being added if the initial upgrade results in
            // an empty config. Updating test to match current behavior.
            Kenichi Ishibashi . unresolved

            I'm uncertain about this comment. Do we need to fix ShouldPerformDohFallbackUpgrade, or should we update this test?

            Either way, I'm not very comfortable just modifying this test. We probably need to fix the bug first (or at least file an issue and put TODO comment with the issue number)?

            File net/dns/dns_test_util.h
            Line 384, Patchset 30 (Latest): class MockTransaction;
            Kenichi Ishibashi . unresolved

            nit: Put Forward class declaration after `public:`.

            File net/dns/host_resolver.cc
            Line 384, Patchset 30 (Latest): NOTREACHED();
            Kenichi Ishibashi . unresolved

            nit: Nice to have a comment similar to GetContextForTesting().

            File net/dns/mock_host_resolver.h
            Line 410, Patchset 30 (Latest): void SetResolveContextForTesting(ResolveContext* resolve_context) {
            resolve_context_ = resolve_context;
            }
            Kenichi Ishibashi . unresolved

            nit: We usually prefer putting `*ForTesting()` methods after non `*ForTesting()` methods.

            Line 410, Patchset 30 (Latest): void SetResolveContextForTesting(ResolveContext* resolve_context) {
            Kenichi Ishibashi . unresolved

            Might want to pass `base::SafeRef<ResolveContext>` directly since we call GetSafeRef() on this?

            File net/dns/resolve_context.h
            Line 249, Patchset 30 (Latest): void set_doh_fallback_canary_domain_check_status(CanaryDomainCheckStatus status) {
            Kenichi Ishibashi . resolved

            nit: Is this correctly formatted?

            Line 237, Patchset 30 (Latest): kNotStarted,
            Kenichi Ishibashi . unresolved

            Probably `kUnknown` might be better since we could reset the status to this value when OnDohServerUnavailable() is called?

            Line 235, Patchset 30 (Latest): enum class CanaryDomainCheckStatus {
            Kenichi Ishibashi . unresolved

            nit: Put enum declaration before methods/constructors (see other comment)

            File services/network/network_context_unittest.cc
            Line 5521, Patchset 30 (Latest): {{"canary_domain_host", "positive.test"}});
            Kenichi Ishibashi . unresolved

            Please separate tests for positive and negative cases. Having separate tests is useful which case actually works or fails when running tests.

            Open in Gerrit

            Related details

            Attention is currently required from:
            • Andrew Williams
            • Brian Begnoche
            Submit Requirements:
              • requirement satisfiedCode-Coverage
              • requirement is not satisfiedCode-Owners
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: chromium/src
              Gerrit-Branch: main
              Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
              Gerrit-Change-Number: 7509892
              Gerrit-PatchSet: 30
              Gerrit-Owner: Brian Begnoche <b...@chromium.org>
              Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
              Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
              Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
              Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
              Gerrit-CC: David Schinazi <dsch...@chromium.org>
              Gerrit-Attention: Brian Begnoche <b...@chromium.org>
              Gerrit-Attention: Andrew Williams <awi...@chromium.org>
              Gerrit-Comment-Date: Thu, 19 Feb 2026 07:24:33 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              satisfied_requirement
              unsatisfied_requirement
              open
              diffy

              Brian Begnoche (Gerrit)

              unread,
              Feb 19, 2026, 12:20:27 PM (2 days ago) Feb 19
              to David Schinazi, Chromium LUCI CQ, Kenichi Ishibashi, Andrew Williams, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
              Attention needed from Andrew Williams and Kenichi Ishibashi

              Brian Begnoche added 15 comments

              File net/dns/canary_domain_service_unittest.cc
              Line 59, Patchset 30: base::RunLoop().RunUntilIdle();
              Kenichi Ishibashi . resolved

              We shouldn't use RunUntilIdle() in new tests since it's one of major sources of flakiness.

              Instead, we probably want to add SetSecureDnsProbeCompleteCallbackForTesting() to CanaryDomainService, in a way similar to https://source.chromium.org/chromium/chromium/src/+/main:net/http/http_stream_pool_test_util.cc;l=438;drc=21d7e84d240f65df7594e5f3526d63e4439dd356

              (I don't think we need an extra PostTask in the callback for these tests)

              Brian Begnoche

              Done

              Line 158, Patchset 30: base::RunLoop().RunUntilIdle();
              Kenichi Ishibashi . resolved

              Ditto.

              Brian Begnoche

              Done

              File net/dns/dns_client.cc
              Line 94, Patchset 30: config.dns_over_tls_hostname)))) {
              Kenichi Ishibashi . resolved

              Q: Do we support DoT? I'm not aware of DoT support and I'm wondering why we need to check it.

              Brian Begnoche

              Apparently, yes:

              https://source.chromium.org/chromium/chromium/src/+/main:net/dns/dns_client.cc;l=78;drc=2f853cacd7a67069cde527e2bf02b6af1f1ee006

              I only see that that histogram is logged for Android, which is consistent with the comment there. I suspect that net/dns/dns_config_service_android.h is the only thing that sets this config value.

              In any case, here I want to maintain that if any nameserver has already been copied to `doh_coonfig`, then this should return false.

              Please re-open if I got something wrong, or if there is still follow up needed.

              Line 213, Patchset 30: enum class FallbackFromSecureTransactionPreferredReason {
              Kenichi Ishibashi . resolved

              nit: We prefer putting enum declarations before methods/constructors.

              https://google.github.io/styleguide/cppguide.html#Declaration_Order

              Brian Begnoche

              Done

              File net/dns/dns_client_unittest.cc
              Line 269, Patchset 30:TEST_F(DnsClientTest, FallbackFromSecureTransactionPreferred_Failures) {
              Kenichi Ishibashi . resolved

              Does this mean the previous name was wrong?

              Brian Begnoche

              Yes, actually. It is testing the `FallbackFromSecureTransactionPreferred` method.

              The source of the confusion or perhaps how it was misnamed could be that things evolved. Maybe this other method used to exist. But what I suspect is that the term "fallback" is overloaded in a confusing way. It can be used for DoH fallback, which refers to using Google DNS when the system config DNS doesn't support DoH. In contrast, this `FallbackFromSecureTransactionPreferred` method uses "fallback" to mean not allowing Secure DNS even though the config specifies values to do so.

              That is to say, yes, this method is testing behavior around "fallback" with the meaning of reverting back *from* configured Secure DNS to actually using insecure DNS.

              Line 311, Patchset 30: DnsConfig config = ValidConfigWithDoh(false /* doh_only */);
              Kenichi Ishibashi . resolved

              nit: `/*doh_only=*/false`. Ditto below.

              Brian Begnoche

              Done

              Line 394, Patchset 30: // Note: Current implementation of ShouldPerformDohFallbackUpgrade has a bug

              // that prevents fallback from being added if the initial upgrade results in
              // an empty config. Updating test to match current behavior.
              Kenichi Ishibashi . resolved

              I'm uncertain about this comment. Do we need to fix ShouldPerformDohFallbackUpgrade, or should we update this test?

              Either way, I'm not very comfortable just modifying this test. We probably need to fix the bug first (or at least file an issue and put TODO comment with the issue number)?

              Brian Begnoche

              Ah. This was Gemini off the rails at one point, and I missed that this comment had leaked in. I thought I had undone that bad detour.

              Note that this test wasn't actually changed meaningfully, and I've reverted these changes.

              File net/dns/dns_test_util.h
              Line 384, Patchset 30: class MockTransaction;
              Kenichi Ishibashi . resolved

              nit: Put Forward class declaration after `public:`.

              Brian Begnoche

              Done

              File net/dns/host_resolver.cc
              Line 384, Patchset 30: NOTREACHED();
              Kenichi Ishibashi . resolved

              nit: Nice to have a comment similar to GetContextForTesting().

              Brian Begnoche

              Done

              File net/dns/mock_host_resolver.h
              Line 410, Patchset 30: void SetResolveContextForTesting(ResolveContext* resolve_context) {
              resolve_context_ = resolve_context;
              }
              Kenichi Ishibashi . resolved

              nit: We usually prefer putting `*ForTesting()` methods after non `*ForTesting()` methods.

              Brian Begnoche

              Done.

              I will note also that perhaps the `ForTesting` suffix is redundant. I'm not sure what the best practice is, but the entirety of a mock is for testing.

              Line 410, Patchset 30: void SetResolveContextForTesting(ResolveContext* resolve_context) {
              Kenichi Ishibashi . resolved

              Might want to pass `base::SafeRef<ResolveContext>` directly since we call GetSafeRef() on this?

              Brian Begnoche

              I think that SafeRef doesn't make sense. `resolve_context_ would need to be set in the constructor, whereas this is only needed in combination with `CreateCanaryDomainService`.

              I could see passing a `unique_ptr<ResolveContext>` instead and taking ownership. In the spots where this is used (network_context_unittest.cc), that would require the pattern of creating a unique pointer, getting a raw pointer, passing ownership, then accessing via the raw pointer. I'm disinclined to do that in the absence of more reason, but please do re-open if that is more appropriate.

              File net/dns/resolve_context.h
              Line 237, Patchset 30: kNotStarted,
              Kenichi Ishibashi . resolved

              Probably `kUnknown` might be better since we could reset the status to this value when OnDohServerUnavailable() is called?

              Brian Begnoche

              I still think that `kNotStarted` makes more sense. Resetting the status is resetting back to a not started state, and this is a known state, both to start and after reset.

              I could see a case for having both `kUnknown` and `kNotStarted`, if there was a need for when this enum isn't set to something meaningful, but I don't think that need actually exists in this case.

              Well, I guess it makes sense for the case where the canary domain check isn't enabled at all. So OK, I've *added* `kUnknown`, but I've changed `CanaryDomainService::ProbeSecureDnsDomain` to set the status to `kStarted`. (I think it was incorrect that it set the status to `kNotStarted`.) See added comments there.

              Line 235, Patchset 30: enum class CanaryDomainCheckStatus {
              Kenichi Ishibashi . resolved

              nit: Put enum declaration before methods/constructors (see other comment)

              Brian Begnoche

              Done

              File services/network/network_context_unittest.cc
              Line 5521, Patchset 30: {{"canary_domain_host", "positive.test"}});
              Kenichi Ishibashi . resolved

              Please separate tests for positive and negative cases. Having separate tests is useful which case actually works or fails when running tests.

              Brian Begnoche

              Done

              Line 5521, Patchset 30: {{"canary_domain_host", "positive.test"}});
              Kenichi Ishibashi . resolved

              Please separate tests for positive and negative cases. Having separate tests is useful which case actually works or fails when running tests.

              Brian Begnoche

              Done

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Andrew Williams
              • Kenichi Ishibashi
              Submit Requirements:
                • requirement satisfiedCode-Coverage
                • requirement is not satisfiedCode-Owners
                • requirement is not satisfiedCode-Review
                • requirement is not satisfiedReview-Enforcement
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: comment
                Gerrit-Project: chromium/src
                Gerrit-Branch: main
                Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
                Gerrit-Change-Number: 7509892
                Gerrit-PatchSet: 31
                Gerrit-Owner: Brian Begnoche <b...@chromium.org>
                Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
                Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
                Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
                Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
                Gerrit-CC: David Schinazi <dsch...@chromium.org>
                Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
                Gerrit-Attention: Andrew Williams <awi...@chromium.org>
                Gerrit-Comment-Date: Thu, 19 Feb 2026 17:20:22 +0000
                Gerrit-HasComments: Yes
                Gerrit-Has-Labels: No
                Comment-In-Reply-To: Kenichi Ishibashi <ba...@chromium.org>
                satisfied_requirement
                unsatisfied_requirement
                open
                diffy

                Kenichi Ishibashi (Gerrit)

                unread,
                Feb 20, 2026, 2:42:03 AM (yesterday) Feb 20
                to Brian Begnoche, David Schinazi, Chromium LUCI CQ, Andrew Williams, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
                Attention needed from Andrew Williams and Brian Begnoche

                Kenichi Ishibashi added 5 comments

                Patchset-level comments
                File-level comment, Patchset 32 (Latest):
                Kenichi Ishibashi . resolved

                Looking good! Before signing off, I want to check the flakiness (https://ci.chromium.org/ui/p/chromium/builders/try/android-x64-rel/807223/overview) is a noise or it's actually flaky.

                My experience is that the flakiness detector actually detects test flakiness.

                File net/dns/canary_domain_service.cc
                Line 124, Patchset 32 (Latest): // If the resolution completes synchronously (unlikely for uncached DNS),
                Kenichi Ishibashi . unresolved

                I'm not 100% sure it's unlikely that the resolution completes synchronously. For example, if the canary domain host is present in /etc/hosts (or equivalent), Start() could complete synchronously.

                So I think it's good to remove the comment and add a test to cover the path.

                File net/dns/canary_domain_service_unittest.cc
                Line 59, Patchset 32 (Latest): base::RunLoop().RunUntilIdle();
                Kenichi Ishibashi . unresolved

                Why do we need this? Probably remove RunProbe() entirely?

                File net/dns/dns_client.cc
                Line 229, Patchset 32 (Latest): bool FallbackFromSecureTransactionPreferred(
                Kenichi Ishibashi . unresolved

                awillia@: Does this change looks reasonable to you? Just want to confirm.

                File net/dns/mock_host_resolver.h
                Line 410, Patchset 30: void SetResolveContextForTesting(ResolveContext* resolve_context) {
                resolve_context_ = resolve_context;
                }
                Kenichi Ishibashi . resolved

                nit: We usually prefer putting `*ForTesting()` methods after non `*ForTesting()` methods.

                Brian Begnoche

                Done.

                I will note also that perhaps the `ForTesting` suffix is redundant. I'm not sure what the best practice is, but the entirety of a mock is for testing.

                Kenichi Ishibashi

                Usually we start with `ForTesting` suffix if the method is only called from tests. We can remove the suffix if we use the method in prod code.

                Open in Gerrit

                Related details

                Attention is currently required from:
                • Andrew Williams
                • Brian Begnoche
                Submit Requirements:
                  • requirement satisfiedCode-Coverage
                  • requirement is not satisfiedCode-Owners
                  • requirement is not satisfiedCode-Review
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement is not satisfiedReview-Enforcement
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: chromium/src
                  Gerrit-Branch: main
                  Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
                  Gerrit-Change-Number: 7509892
                  Gerrit-PatchSet: 32
                  Gerrit-Owner: Brian Begnoche <b...@chromium.org>
                  Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
                  Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
                  Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
                  Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
                  Gerrit-CC: David Schinazi <dsch...@chromium.org>
                  Gerrit-CC: Varun Khaneja <va...@chromium.org>
                  Gerrit-Attention: Brian Begnoche <b...@chromium.org>
                  Gerrit-Attention: Andrew Williams <awi...@chromium.org>
                  Gerrit-Comment-Date: Fri, 20 Feb 2026 07:41:33 +0000
                  Gerrit-HasComments: Yes
                  Gerrit-Has-Labels: No
                  satisfied_requirement
                  unsatisfied_requirement
                  open
                  diffy

                  Brian Begnoche (Gerrit)

                  unread,
                  Feb 20, 2026, 12:33:06 PM (21 hours ago) Feb 20
                  to David Schinazi, Chromium LUCI CQ, Kenichi Ishibashi, Andrew Williams, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
                  Attention needed from Andrew Williams and Kenichi Ishibashi

                  Brian Begnoche added 4 comments

                  File net/dns/canary_domain_service.cc
                  Line 124, Patchset 32: // If the resolution completes synchronously (unlikely for uncached DNS),
                  Kenichi Ishibashi . resolved

                  I'm not 100% sure it's unlikely that the resolution completes synchronously. For example, if the canary domain host is present in /etc/hosts (or equivalent), Start() could complete synchronously.

                  So I think it's good to remove the comment and add a test to cover the path.

                  Brian Begnoche

                  I've parameterized CanaryDomainServiceTest so that every test case is tested with and without synchronous mode. Synchronous mode tests the case that hits line 127 here.

                  Line 124, Patchset 32: // If the resolution completes synchronously (unlikely for uncached DNS),
                  Kenichi Ishibashi . resolved

                  I'm not 100% sure it's unlikely that the resolution completes synchronously. For example, if the canary domain host is present in /etc/hosts (or equivalent), Start() could complete synchronously.

                  So I think it's good to remove the comment and add a test to cover the path.

                  Brian Begnoche

                  Done

                  File net/dns/canary_domain_service_unittest.cc
                  Line 59, Patchset 32: base::RunLoop().RunUntilIdle();
                  Kenichi Ishibashi . resolved

                  Why do we need this? Probably remove RunProbe() entirely?

                  Brian Begnoche

                  Yes, removed. I just forgot to remove it.

                  File net/dns/mock_host_resolver.h
                  Line 410, Patchset 30: void SetResolveContextForTesting(ResolveContext* resolve_context) {
                  resolve_context_ = resolve_context;
                  }
                  Kenichi Ishibashi . resolved

                  nit: We usually prefer putting `*ForTesting()` methods after non `*ForTesting()` methods.

                  Brian Begnoche

                  Done.

                  I will note also that perhaps the `ForTesting` suffix is redundant. I'm not sure what the best practice is, but the entirety of a mock is for testing.

                  Kenichi Ishibashi

                  Usually we start with `ForTesting` suffix if the method is only called from tests. We can remove the suffix if we use the method in prod code.

                  Brian Begnoche

                  Ack. This is my understanding too.

                  My point is that a mock is never called in prod.

                  Open in Gerrit

                  Related details

                  Attention is currently required from:
                  • Andrew Williams
                  • Kenichi Ishibashi
                  Submit Requirements:
                  • requirement satisfiedCode-Coverage
                  • requirement is not satisfiedCode-Owners
                  • requirement is not satisfiedCode-Review
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement is not satisfiedReview-Enforcement
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: chromium/src
                  Gerrit-Branch: main
                  Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
                  Gerrit-Change-Number: 7509892
                  Gerrit-PatchSet: 33
                  Gerrit-Owner: Brian Begnoche <b...@chromium.org>
                  Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
                  Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
                  Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
                  Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
                  Gerrit-CC: David Schinazi <dsch...@chromium.org>
                  Gerrit-CC: Varun Khaneja <va...@chromium.org>
                  Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
                  Gerrit-Attention: Andrew Williams <awi...@chromium.org>
                  Gerrit-Comment-Date: Fri, 20 Feb 2026 17:32:59 +0000
                  satisfied_requirement
                  unsatisfied_requirement
                  open
                  diffy

                  Brian Begnoche (Gerrit)

                  unread,
                  Feb 20, 2026, 1:38:45 PM (19 hours ago) Feb 20
                  to David Schinazi, Chromium LUCI CQ, Kenichi Ishibashi, Andrew Williams, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
                  Attention needed from Andrew Williams and Kenichi Ishibashi

                  Brian Begnoche added 1 comment

                  Patchset-level comments
                  Kenichi Ishibashi . resolved

                  Looking good! Before signing off, I want to check the flakiness (https://ci.chromium.org/ui/p/chromium/builders/try/android-x64-rel/807223/overview) is a noise or it's actually flaky.

                  My experience is that the flakiness detector actually detects test flakiness.

                  Brian Begnoche

                  FYI that appears to be an overall flakiness issue with net_unittests. I see loads of tests in log search that have this failure occasionally.

                  [0219/181837.682407:FATAL:net/test/net_test_suite.cc:56] DCHECK failed: !g_current_net_test_suite.

                  I'm rerunning commit queue (dry) and rerunning checks, and I will continue to look at this if it persists.

                  Open in Gerrit

                  Related details

                  Attention is currently required from:
                  • Andrew Williams
                  • Kenichi Ishibashi
                  Submit Requirements:
                  • requirement satisfiedCode-Coverage
                  • requirement is not satisfiedCode-Owners
                  • requirement is not satisfiedCode-Review
                  • requirement is not satisfiedNo-Unresolved-Comments
                  • requirement is not satisfiedReview-Enforcement
                  Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                  Gerrit-MessageType: comment
                  Gerrit-Project: chromium/src
                  Gerrit-Branch: main
                  Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
                  Gerrit-Change-Number: 7509892
                  Gerrit-PatchSet: 34
                  Gerrit-Owner: Brian Begnoche <b...@chromium.org>
                  Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
                  Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
                  Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
                  Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
                  Gerrit-CC: David Schinazi <dsch...@chromium.org>
                  Gerrit-CC: Varun Khaneja <va...@chromium.org>
                  Gerrit-Attention: Kenichi Ishibashi <ba...@chromium.org>
                  Gerrit-Attention: Andrew Williams <awi...@chromium.org>
                  Gerrit-Comment-Date: Fri, 20 Feb 2026 18:38:40 +0000
                  Gerrit-HasComments: Yes
                  Gerrit-Has-Labels: No
                  Comment-In-Reply-To: Kenichi Ishibashi <ba...@chromium.org>
                  satisfied_requirement
                  unsatisfied_requirement
                  open
                  diffy

                  Kenichi Ishibashi (Gerrit)

                  unread,
                  Feb 20, 2026, 6:06:40 PM (15 hours ago) Feb 20
                  to Brian Begnoche, David Schinazi, Chromium LUCI CQ, Andrew Williams, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
                  Attention needed from Andrew Williams and Brian Begnoche

                  Kenichi Ishibashi voted and added 2 comments

                  Votes added by Kenichi Ishibashi

                  Code-Review+1

                  2 comments

                  Patchset-level comments
                  File-level comment, Patchset 34 (Latest):
                  Kenichi Ishibashi . resolved

                  lgtm on my side (except for comment on FallbackFromSecureTransactionPreferred), thanks!

                  File net/dns/canary_domain_service.h
                  Line 63, Patchset 34 (Latest): void SetOnProbeCompleteCallbackForTesting(base::RepeatingClosure callback);
                  Kenichi Ishibashi . unresolved

                  nit: Sorry I missed this before, but why is this RepeatingClosure instead of OnceClosure? We prefer OnceClosure if the callback is called only once.

                  Open in Gerrit

                  Related details

                  Attention is currently required from:
                  • Andrew Williams
                  • Brian Begnoche
                  Submit Requirements:
                    • requirement satisfiedCode-Coverage
                    • requirement is not satisfiedCode-Owners
                    • requirement satisfiedCode-Review
                    • requirement is not satisfiedNo-Unresolved-Comments
                    • requirement satisfiedReview-Enforcement
                    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                    Gerrit-MessageType: comment
                    Gerrit-Project: chromium/src
                    Gerrit-Branch: main
                    Gerrit-Change-Id: Ie3775a32eb925c348c499a2e31fa4b0c1518ddc0
                    Gerrit-Change-Number: 7509892
                    Gerrit-PatchSet: 34
                    Gerrit-Owner: Brian Begnoche <b...@chromium.org>
                    Gerrit-Reviewer: Andrew Williams <awi...@chromium.org>
                    Gerrit-Reviewer: Brian Begnoche <b...@chromium.org>
                    Gerrit-Reviewer: Kenichi Ishibashi <ba...@chromium.org>
                    Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
                    Gerrit-CC: David Schinazi <dsch...@chromium.org>
                    Gerrit-CC: Varun Khaneja <va...@chromium.org>
                    Gerrit-Attention: Brian Begnoche <b...@chromium.org>
                    Gerrit-Attention: Andrew Williams <awi...@chromium.org>
                    Gerrit-Comment-Date: Fri, 20 Feb 2026 23:06:04 +0000
                    Gerrit-HasComments: Yes
                    Gerrit-Has-Labels: Yes
                    satisfied_requirement
                    unsatisfied_requirement
                    open
                    diffy

                    Andrew Williams (Gerrit)

                    unread,
                    12:47 AM (8 hours ago) 12:47 AM
                    to Brian Begnoche, Kenichi Ishibashi, David Schinazi, Chromium LUCI CQ, Chromium Metrics Reviews, AyeAye, fenced-fra...@chromium.org, network-ser...@chromium.org, asvitkine...@chromium.org, net-r...@chromium.org, bnc+...@chromium.org
                    Attention needed from Brian Begnoche

                    Andrew Williams added 25 comments

                    Patchset-level comments
                    Andrew Williams . resolved

                    I think this looks good overall, but leaving some remaining feedback, questions, and comments. Thanks Brian, so close!

                    Commit Message
                    Line 13, Patchset 34 (Latest):* `DnsClient::FallbackFromSecureTransactionPreferred` is updated so that both at least one available DoH server *and* a positive canary domain result are needed to allow Secure DNS (return false).
                    Andrew Williams . unresolved

                    nit: wrap long lines (Gerrit can do this automatically if you click Edit -> Format) and also update this to say something like "are needed to allow Secure DNS to the fallback provider)"

                    File net/base/features.h
                    Line 761, Patchset 34 (Latest):// When enabled, upon reading a new DNS config that enables Secure DNS, the
                    Andrew Williams . unresolved

                    nit: maybe update this to reflect that the canary domain check will be sent when probes are sent

                    File net/dns/canary_domain_service.cc
                    Line 39, Patchset 34 (Latest): params.cache_usage =
                    Andrew Williams . unresolved

                    optional: it might be useful to have a test demonstrating that the canary domain checks aren't cached / get re-issued when the network changes.

                    Line 49, Patchset 34 (Latest): const HostResolver::ResolveHostRequest* request,
                    Andrew Williams . unresolved

                    nit: can use a const reference here instead and then remove the `DCHECK(request)`

                    https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs

                    Line 95, Patchset 34 (Latest): // Reset any previous result. Secure DNS should only be allowed if a new probe
                    Andrew Williams . unresolved

                    nit: "Secure DNS to the fallback provider should only be allowed"

                    Line 117, Patchset 34 (Latest): std::move(host_port_pair), NetworkAnonymizationKey::CreateTransient(),
                    Andrew Williams . unresolved

                    nit: this version of CreateRequest takes a const reference for the first parameter, so no need to std::move here. Since we only ever create a HostPortPair with this member, we could create the HostPortPair in the constructor and store that instead.

                    Line 122, Patchset 34 (Latest): weak_ptr_factory_.GetWeakPtr()));
                    Andrew Williams . unresolved

                    since we own pending_probe_request_ we can use base::Unretained(this) here instead of needing to use a weak pointer (and could get rid of this classes WeakPtrFactory then, I think)

                    Line 133, Patchset 34 (Latest): if (!probe_request) {
                    Andrew Williams . unresolved

                    Is this case still possible? it seems like it isn't, because if pending_probe_request_ is destroyed then the provided callback won't be called

                    https://source.chromium.org/chromium/chromium/src/+/main:net/dns/host_resolver.h;l=125;drc=d209eefee6037bd0905e43f88570fda8edab89a1

                    If this case is possible we may want to consider calling set_doh_fallback_canary_domain_check_status so the status doesn't remain kStarted, and ideally we'd have a test.

                    Line 143, Patchset 34 (Latest): if (net_error != net::ERR_ABORTED) {
                    Andrew Williams . unresolved

                    is ERR_ABORTED possible here? There was a comment elsewhere that "HostResolver squashes ERR_ABORTED to ERR_NAME_NOT_RESOLVED.". If it is possible, it seems like it'd still be better to call set_doh_fallback_canary_domain_check_status so that the status isn't kStarted?

                    Line 151, Patchset 34 (Latest): base::StrCat({"Net.DNS.CanaryDomainService.SecureDns.Result"}), result);
                    Andrew Williams . unresolved

                    can remove base::StrCat here (and above if we keep that code)

                    Line 153, Patchset 34 (Latest): if (on_probe_complete_callback_for_testing_) {
                    Andrew Williams . unresolved

                    If we keep the if `if (!probe_request)` block above we may want to consider whether this should be called before the return there for consistency given the name

                    File net/dns/context_host_resolver.h
                    Line 83, Patchset 34 (Latest):
                    Andrew Williams . unresolved

                    nit: remove new line since these are all part of the same interface

                    File net/dns/dns_client.h
                    Line 99, Patchset 34 (Latest): // conditions. See SetSecureDnsAllowedByCanaryDomain().
                    Andrew Williams . unresolved

                    nit: update `SetSecureDnsAllowedByCanaryDomain` to the new name

                    File net/dns/dns_client.cc
                    Line 44, Patchset 34 (Latest):// LINT.IfChange(FallbackFromSecureTransactionPreferredReason)
                    Andrew Williams . unresolved

                    nit: we should add the header comment about these being logged to histograms:

                    https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#requirements

                    Line 94, Patchset 30: config.dns_over_tls_hostname)))) {
                    Kenichi Ishibashi . resolved

                    Q: Do we support DoT? I'm not aware of DoT support and I'm wondering why we need to check it.

                    Brian Begnoche

                    Apparently, yes:

                    https://source.chromium.org/chromium/chromium/src/+/main:net/dns/dns_client.cc;l=78;drc=2f853cacd7a67069cde527e2bf02b6af1f1ee006

                    I only see that that histogram is logged for Android, which is consistent with the comment there. I suspect that net/dns/dns_config_service_android.h is the only thing that sets this config value.

                    In any case, here I want to maintain that if any nameserver has already been copied to `doh_coonfig`, then this should return false.

                    Please re-open if I got something wrong, or if there is still follow up needed.

                    Andrew Williams

                    We don't support use of DoT, but for Android we do support checking whether the system is configured to use DoT and if so, we use the DoT server hostname to determine whether we have a corresponding entry in our DoH provider list so we can use DoH. I looked into how this worked a few years ago and IIRC it was related to this: https://developer.android.com/reference/android/net/LinkProperties.html#isPrivateDnsActive()

                    Line 105, Patchset 34 (Latest): config.dns_over_tls_hostname)))) {
                    Andrew Williams . unresolved

                    Looking again at how UpdateConfigForDohUpgrade is implemented, we don't attempt the fallback at all unless config.dns_over_tls_hostname is empty...

                    If we keep this separate logic instead of using a boolean, I think it'd be better for consistency and simplicity if we replace `config.doh_config == DnsOverHttpsConfig(GetDohUpgradeServersFromDotHostname(config.dns_over_tls_hostname))` with a `if (!config->dns_over_tls_hostname.empty()) { return false }` check instead

                    Line 105, Patchset 34 (Latest): config.dns_over_tls_hostname)))) {
                    Andrew Williams . unresolved

                    Following up on the conversation from: https://chromium-review.googlesource.com/c/chromium/src/+/7567908/comment/b954f680_c90ed469/

                    I can see your point about not wanting the DnsConfig to contain metadata about how it was constructed, but if we added a new boolean named something like `should_perform_doh_fallback_upgrade` (and set it to true when doh_config corresponds to the fallback provider DoH config) I think it would feel more like a configuration option than metadata, and then we could use that in FallbackFromSecureTransactionPreferred more simply instead.

                    I don't think I realized exactly how complex the logic in UpdateConfigForDohUpgrade is and that we'd have to replicate each piece of that in this function as well. I think having to mirror the two is more error prone and possible to break over time than just using the boolean approach. Something to consider (I know, I know, thinking through how best to implement all this has already required way too much brainpower!)

                    Line 229, Patchset 32: bool FallbackFromSecureTransactionPreferred(
                    Kenichi Ishibashi . resolved

                    awillia@: Does this change looks reasonable to you? Just want to confirm.

                    Andrew Williams

                    yeah this new logic LGTM, with some thoughts in other comments about whether using a boolean in DnsConfig instead of ShouldPerformDohFallbackUpgrade might be worthwhile. thanks!

                    File net/dns/dns_test_util.h
                    Line 386, Patchset 34 (Latest): const std::vector<base::WeakPtr<MockTransaction>>& delayed_transactions()
                    Andrew Williams . unresolved

                    Are the changes to this file still needed? I don't see where delayed_transactions() is called

                    File net/dns/mock_host_resolver.h
                    Line 410, Patchset 34 (Latest): std::unique_ptr<CanaryDomainService> CreateCanaryDomainService() override;
                    Andrew Williams . unresolved

                    nit: move into the "// HostResolver methods:" section above

                    File services/network/network_context_unittest.cc
                    Line 5516, Patchset 34 (Latest):TEST_F(NetworkContextTest, CanaryDomainServiceProbe_PositiveResult) {
                    Andrew Williams . unresolved

                    optional: could combine this and the test below into one parameterized test (actually I've found Gemini pretty good at doing this type of thing)

                    Line 5527, Patchset 34 (Latest): net::ResolveContext resolve_context(nullptr, false);
                    Andrew Williams . unresolved
                    nit: 
                    ```suggestion
                    net::ResolveContext resolve_context(/*url_request_context=*/nullptr, /*enable_caching=*/false);
                    ```

                    here and below

                    Line 5612, Patchset 34 (Latest): auto* mock_resolver = static_cast<net::MockHostResolverBase*>(
                    Andrew Williams . unresolved

                    Do we need these four lines (and resolve_context created above) for this test?

                    File tools/metrics/histograms/metadata/net/enums.xml
                    Line 152, Patchset 34 (Latest):<!-- LINT.ThenChange(/net/dns/canary_domain_service.cc:CanaryDomainResult) -->
                    Andrew Williams . unresolved

                    nit (thanks Gemini):
                    ```suggestion
                    <!-- LINT.ThenChange(/net/dns/canary_domain_service.h:CanaryDomainResult) -->
                    ```

                    Open in Gerrit

                    Related details

                    Attention is currently required from:
                    • Brian Begnoche
                    Gerrit-Comment-Date: Sat, 21 Feb 2026 05:47:09 +0000
                    Gerrit-HasComments: Yes
                    Gerrit-Has-Labels: No
                    satisfied_requirement
                    unsatisfied_requirement
                    open
                    diffy
                    Reply all
                    Reply to author
                    Forward
                    0 new messages