summaryrefslogtreecommitdiff
path: root/chromium/net/dns
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-29 10:46:47 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-02 12:02:10 +0000
commit99677208ff3b216fdfec551fbe548da5520cd6fb (patch)
tree476a4865c10320249360e859d8fdd3e01833b03a /chromium/net/dns
parentc30a6232df03e1efbd9f3b226777b07e087a1122 (diff)
downloadqtwebengine-chromium-99677208ff3b216fdfec551fbe548da5520cd6fb.tar.gz
BASELINE: Update Chromium to 86.0.4240.124
Change-Id: Ide0ff151e94cd665ae6521a446995d34a9d1d644 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/dns')
-rw-r--r--chromium/net/dns/BUILD.gn7
-rw-r--r--chromium/net/dns/README.md391
-rw-r--r--chromium/net/dns/address_sorter_posix.cc8
-rw-r--r--chromium/net/dns/address_sorter_posix_unittest.cc5
-rw-r--r--chromium/net/dns/address_sorter_unittest.cc2
-rw-r--r--chromium/net/dns/dns_client.cc15
-rw-r--r--chromium/net/dns/dns_config.cc1
-rw-r--r--chromium/net/dns/dns_config.h4
-rw-r--r--chromium/net/dns/dns_config_overrides.cc17
-rw-r--r--chromium/net/dns/dns_config_overrides.h1
-rw-r--r--chromium/net/dns/dns_config_service_posix.cc25
-rw-r--r--chromium/net/dns/dns_config_service_posix_unittest.cc10
-rw-r--r--chromium/net/dns/dns_config_service_win.cc98
-rw-r--r--chromium/net/dns/dns_config_service_win.h7
-rw-r--r--chromium/net/dns/dns_config_service_win_unittest.cc73
-rw-r--r--chromium/net/dns/dns_hosts.cc2
-rw-r--r--chromium/net/dns/dns_hosts_unittest.cc2
-rw-r--r--chromium/net/dns/dns_query.cc15
-rw-r--r--chromium/net/dns/dns_query.h7
-rw-r--r--chromium/net/dns/dns_query_unittest.cc11
-rw-r--r--chromium/net/dns/dns_reloader.cc6
-rw-r--r--chromium/net/dns/dns_reloader.h4
-rw-r--r--chromium/net/dns/dns_session.cc61
-rw-r--r--chromium/net/dns/dns_session.h43
-rw-r--r--chromium/net/dns/dns_session_unittest.cc243
-rw-r--r--chromium/net/dns/dns_socket_allocator.cc75
-rw-r--r--chromium/net/dns/dns_socket_allocator.h54
-rw-r--r--chromium/net/dns/dns_socket_allocator_unittest.cc82
-rw-r--r--chromium/net/dns/dns_socket_pool.cc223
-rw-r--r--chromium/net/dns/dns_socket_pool.h98
-rw-r--r--chromium/net/dns/dns_socket_pool_unittest.cc108
-rw-r--r--chromium/net/dns/dns_test_util.cc10
-rw-r--r--chromium/net/dns/dns_test_util.h4
-rw-r--r--chromium/net/dns/dns_transaction.cc162
-rw-r--r--chromium/net/dns/dns_transaction_unittest.cc559
-rw-r--r--chromium/net/dns/dns_udp_tracker.cc104
-rw-r--r--chromium/net/dns/dns_udp_tracker.h29
-rw-r--r--chromium/net/dns/dns_udp_tracker_unittest.cc136
-rw-r--r--chromium/net/dns/fuzzed_host_resolver_util.cc1
-rw-r--r--chromium/net/dns/host_resolver_manager.cc6
-rw-r--r--chromium/net/dns/host_resolver_manager_unittest.cc3
-rw-r--r--chromium/net/dns/host_resolver_proc.cc2
-rw-r--r--chromium/net/dns/httpssvc_metrics.cc14
-rw-r--r--chromium/net/dns/httpssvc_metrics.h4
-rw-r--r--chromium/net/dns/mdns_cache.cc19
-rw-r--r--chromium/net/dns/mdns_cache.h4
-rw-r--r--chromium/net/dns/mdns_cache_unittest.cc44
-rw-r--r--chromium/net/dns/mdns_client_impl.cc29
-rw-r--r--chromium/net/dns/mdns_client_impl.h16
-rw-r--r--chromium/net/dns/mdns_client_unittest.cc116
-rw-r--r--chromium/net/dns/public/util.cc6
-rw-r--r--chromium/net/dns/resolve_context.cc2
-rw-r--r--chromium/net/dns/resolve_context_unittest.cc12
-rw-r--r--chromium/net/dns/serial_worker_unittest.cc6
54 files changed, 1731 insertions, 1255 deletions
diff --git a/chromium/net/dns/BUILD.gn b/chromium/net/dns/BUILD.gn
index 3e24edd0b48..0c38656f7a1 100644
--- a/chromium/net/dns/BUILD.gn
+++ b/chromium/net/dns/BUILD.gn
@@ -61,8 +61,8 @@ source_set("dns") {
"dns_server_iterator.h",
"dns_session.cc",
"dns_session.h",
- "dns_socket_pool.cc",
- "dns_socket_pool.h",
+ "dns_socket_allocator.cc",
+ "dns_socket_allocator.h",
"dns_transaction.cc",
"dns_udp_tracker.cc",
"dns_udp_tracker.h",
@@ -391,8 +391,7 @@ source_set("tests") {
"dns_hosts_unittest.cc",
"dns_query_unittest.cc",
"dns_response_unittest.cc",
- "dns_session_unittest.cc",
- "dns_socket_pool_unittest.cc",
+ "dns_socket_allocator_unittest.cc",
"dns_transaction_unittest.cc",
"dns_udp_tracker_unittest.cc",
"dns_util_unittest.cc",
diff --git a/chromium/net/dns/README.md b/chromium/net/dns/README.md
new file mode 100644
index 00000000000..7bb8b074168
--- /dev/null
+++ b/chromium/net/dns/README.md
@@ -0,0 +1,391 @@
+# Chrome Host Resolution
+
+Implementation and support of host resolution for the Chrome network stack.
+Includes client implementations of host resolution protocols (DNS and mDNS),
+host resolution caching, support for dealing with system host resolution
+(including reading HOSTS files and tracking system network settings related to
+host resolution), and various related utilities.
+
+*** promo
+Note: "DNS" in this directory (including the directory name) is often used as
+shorthand for all host resolution, not just that using the Domain Name System.
+This document attempts to use "DNS" only to refer to the actual Domain Name
+System, except when referring to strings or paths that contain other usage of
+"DNS".
+***
+
+[TOC]
+
+## Usage
+
+### From outside the network service
+
+Most interaction with host resolution should be through the [network service](/services/network/README.md)
+[`network::HostResolver`](/services/network/public/mojom/host_resolver.mojom),
+retrieved from [`network::NetworkContext`](/services/network/public/mojom/network_context.mojom)
+using `network::NetworkContext::CreateHostResolver()`.
+
+Host resolution is requested using `network::HostResolver::ResolveHost()`. There
+is also a shortcut using `network::NetworkContext::ResolveHost()` when a
+separate passable object is not needed.
+
+Some general utilities are also available in [`/net/dns/public/`](/net/dns/public/)
+that are intended for use by any code, inside or outside the network service.
+Otherwise, code outside the network service should never interact directly with
+the code in [`/net/dns/`](/net/dns/).
+
+### From inside the network service
+
+Inside the network service or inside the Chrome networking stack, host
+resolution goes through [`net::HostResolver`](/net/dns/host_resolver.h),
+retrieved from [`net::URLRequestContext`](/net/url_request/url_request_context.h).
+
+### Stand-alone tools
+
+Tests and stand-alone tools not part of the browser may interact with host
+resolution directly by creating their own HostResolvers using
+`net::HostResolver::CreateStandaloneResolver()`.
+
+## Test support
+
+### MockHostResolver
+
+[`net::MockHostResolver`](/net/dns/mock_host_resolver.h)
+
+Tests with the ability to inject and replace the used `net::HostResolver` should
+replace it with a `net::MockHostResolver`, allowing rule-based results.
+`net::MockCachingHostResolver` is the same except it includes basic support for
+the caching functionality normally done by prod `net::HostResolver`s.
+
+Some tests may also find `net::HangingHostResolver` useful. It will begin host
+resolution requests, but never complete them until cancellation.
+
+### TestHostResolver
+
+[`content::TestHostResolver`](/content/public/test/test_host_resolver.h)
+
+Used by most browser tests (via [`content::BrowserTestBase`](/content/public/test/browser_test_base.h)),
+`content::TestHostResolver` installs itself on creation globally into all host
+resolvers in the process. By default, only allows resolution of the local host
+and returns `net::ERR_NOT_IMPLEMENTED` for other hostnames. Allows setting rules
+for other results using a [net::RuleBasedHostResolverProc](/net/dns/mock_host_resolver.h).
+
+*** note
+**Warning:** `content::TestHostResolver` only replaces host address resolution
+to the system and then artificially uses such system resolution for many
+requests that would normally be handled differently (e.g. using the built-in DNS
+client). This means a significant amount of normal prod host resolution logic
+will be bypassed in tests using `content::TestHostResolver`.
+***
+
+### Request remapping
+
+Most prod logic for creating HostResolvers will check if any global remappings
+have been requested. In the browser, this is requested using the
+["host-resolver-rules"](/services/network/public/cpp/network_switches.h)
+commandline flag.
+
+See [`net::HostMappingRules`](/net/base/host_mapping_rules.h) for details on the
+format of the rules string. Allows remapping any request hostname to another
+hostname, an IP address, or a NOTFOUND error.
+
+## Implementation
+
+### HostResolver
+
+[`net::HostResolver`](/net/dns/host_resolver.h)
+
+The main interface for requesting host resolution within the network stack or
+network service. In prod, generally owned, and retrieved as-needed from
+[`net::URLRequestContext`](/net/url_request/url_request_context.h)s. Created
+using `net::HostResolver::CreateResolver()` or
+`net::HostResolver::CreateStandaloneResolver()`.
+
+Various implementations are used in prod.
+
+#### ContextHostResolver
+
+[`net::ContextHostResolver`](/net/dns/context_host_resolver.h)
+
+The main prod implementation of `net::HostResolver`. Expected to be owned 1:1 by
+a single `net::URLRequestContext`, the `net::ContextHostResolver` owns or keeps
+references to per-URLRequestContext properties used for host resolution,
+including an owned [`net::HostCache`](/net/dns/host_cache.h).
+
+On resolution, calls into an underlying `net::HostResolverManager` with the per-
+context properties.
+
+On destruction, silently cancels all host resolution requests made through the
+`net::ContextHostResolver` instance. This prevents the underlying
+`net::HostResolverManager` from continuing to reference the per-context
+properties that may be destroyed on destruction of the `net::URLRequestContext`
+or `net::ContextHostResolver`.
+
+#### MappedHostResolver
+
+[`net::MappedHostResolver`](/net/dns/mapped_host_resolver.h)
+
+A wrapping implementation around another `net::HostResolver`. Maintains request
+remapping rules to remap request hostnames to other hostnames or IP addresses.
+
+Used to implement the ["host-resolver-rules"](/services/network/public/cpp/network_switches.h)
+commandline flag.
+
+#### StaleHostResolver
+
+[`cronet::StaleHostResolver`](/components/cronet/stale_host_resolver.h)
+
+A wrapping implementation around another `net::HostResolver`. Returns stale
+(expired or invalidated by network changes) data from the `net::HostCache` when
+non-stale results take longer than a configurable timeout. Reduces host
+resolution latency at the expense of accuracy.
+
+Only used and created by [Cronet](/components/cronet/README.md).
+
+### HostResolverManager
+
+[`net::HostResolverManager`](/net/dns/host_resolver_manager.h)
+
+Scheduler and controller of host resolution requests. Contains the logic for
+immediate host resolution from fast local sources (e.g. querying
+`net::HostCache`s, IP address literals, etc). Throttles, schedules, and merges
+asynchronous jobs for resolution from slower network sources.
+
+On destruction, silently cancels all in-progress host resolution requests.
+
+In prod, a single shared `net::HostResolverManager` is generally used for the
+entire browser. The shared manager is owned and configured by the
+[`network::NetworkService`](/services/network/network_service.h).
+
+#### Request
+
+`net::HostResolverManager::RequestImpl`
+
+Implementation of [`net::HostResolver::ResolveHostRequest`](/net/dns/host_resolver.h)
+and overall representation of a single request for resolution from a
+`net::HostResolverManager`. The `RequestImpl` object itself primarily acts only
+as a container of parameters and results for the request, leaving the actual
+logic to the `net::HostResolverManager` itself.
+
+Data collected at this layer:
+
+* "Net.DNS.Request.TotalTime" (recommended for experiments)
+* "Net.DNS.Request.TotalTimeAsync"
+
+#### Job
+
+`net::HostResolverManager::Job`
+
+Representation of an asynchronous job for resolution from slower network
+sources. Contains the logic to determine and query the appropriate source for
+host resolution results with retry and fallback support to other sources. On
+completion adds results to relevant `net::HostCache`s and invokes request
+callbacks.
+
+Multiple requests can be merged into a single Job if compatible. This includes
+merging newly-started Jobs with already-running Jobs.
+
+`net::HostResolverManager` schedules and throttles running
+`net::HostResolverManager::Job`s using a [`net::PrioritizedDispatcher`](/net/base/prioritized_dispatcher.h).
+The throttling is important to avoid overworking network sources, especially
+poorly designed home routers that may crash on only a small number of concurrent
+DNS resolves.
+
+Data collected at this layer:
+
+* "Net.DNS.ResolveSuccessTime"
+* "Net.DNS.ResolveFailureTime"
+* "Net.DNS.ResolveCategory"
+* "Net.DNS.ResolveError.Fast"
+* "Net.DNS.ResolveError.Slow"
+* "Net.DNS.SecureDnsMode.[Off/Automatic/Secure].ResolveTime"
+
+### Host resolution sources
+
+Various sources are used to query host resolution. The sources to be used by a
+`net::HostResolverManager::Job` are determined in advance of running the Job by
+`net::HostResolverManager::CreateTaskSequence()`, which outputs a list of
+`net::HostResolverManager::TaskType` specifying the order of sources to attempt.
+By default, this will use internal logic to decide the source to use and will
+often allow fallback to additional sources.
+
+The sources chosen by default are also affected by the Secure DNS mode, by
+default determined from
+[`net::DnsConfig::secure_dns_mode`](/net/dns/dns_config.h) but overridable for
+individual requests using
+`net::HostResolver::ResolveHostParameters::secure_dns_mode_override`.
+
+Specific sources for a request can be
+specified using `net::HostResolver::ResolveHostParameters::source` and
+[`net::HostResolverSource`](/net/dns/host_resolver_source.h).
+
+The Job will then use *Task objects that implement the behavior specific to the
+particular resolution sources.
+
+#### SYSTEM
+
+`net::HostResolverSource::SYSTEM`
+`net::HostResolverManager::TaskType::PROC`
+
+Implemented by: `net::HostResolverManager::ProcTask`
+
+Usually called the "system resolver" or sometimes the "proc resolver". Results
+are queried from the system or OS using the `getaddrinfo()` OS API call. This
+source is only capable of address (A and AAAA) resolves but will also query for
+canonname info if the request includes the `HOST_RESOLVER_CANONNAME` flag. The
+system will query from its own internal cache, HOSTS files, DNS, and sometimes
+mDNS, depending on the capabilities of the system.
+
+When host resolution requests do not specify a source, the system resolver will
+always be used for **address resolves** when **any** of the following are true:
+
+* Requests with the `HOST_RESOLVER_CANONNAME` flag
+* For hostnames ending in ".local"
+* When the Secure DNS mode is `net::DnsConfig::SecureDnsMode::OFF` and
+ `net::HostResolverSource::DNS` is not enabled via
+ `net::HostResolverManager::SetInsecureDnsClientEnabled(true)`
+* When a system DNS configuration could not be determined
+
+Secure DNS requests cannot be made using the system resolver.
+
+`net::HostResolverManager::ProcTask` uses a blocking
+[`base::TaskRunner`](/base/task_runner.h) to make blocking resolution requests.
+On a timeout, additional attempts are made, but previous attempts are not
+cancelled as there is no cancellation mechanism for `getaddrinfo()`. The first
+attempt to complete is used and any other attempt completions are ignored.
+
+Each attempt calls [`net::HostResolverProc`](/net/dns/host_resolver_proc.h). In
+prod, this is always implemented by a `net::SystemHostResolverProc`, which makes
+the actual call to `getaddrinfo()` using the
+[`net::AddressInfo`](/net/dns/address_info.h) helper, but in tests, the
+`net::HostResolverProc` may be replaced by a chain of test implementations to
+override behavior.
+
+Data collected specifically for this source:
+
+* "Net.DNS.SecureDnsTaskFailure.FallbackProcTask.Error"
+
+#### DNS
+
+`net::HostResolverSource::DNS`
+`net::HostResolverManager::TaskType::DNS`
+`net::HostResolverManager::TaskType::SECURE_DNS`
+
+Implemented by: `net::HostResolverManager::DnsTask`
+
+Usually called the "built-in resolver" or the "async resolver". Results are
+queried from DNS using [`net::DnsClient`](/net/dns/dns_client.h), a Chrome
+network stack implementation of a DNS "stub resolver" or "DNS client".
+
+When host resolution requests do not specify a source, the built-in resolver
+will be used when **all** of the following are true:
+
+* DnsClient is enabled for insecure requests enabled via
+ `net::HostResolverManager::SetInsecureDnsClientEnabled(true)` or
+ the Secure DNS mode is not `net::DnsConfig::SecureDnsMode::OFF`.
+* The system DNS configuration could be determined successfully
+* The request hostname does not end in ".local"
+* The request is not an address query with the `HOST_RESOLVER_CANONNAME` flag
+
+The `net::HostResolverManager::DnsTask` will create and run a
+[`net::DnsTransaction`](/net/dns/dns_transaction.h) for each DNS name/type pair
+to be queried. The task will then process successful results from the returned
+[`net::DnsResponse`](/net/dns/dns_response.h).
+
+When a request requires both A and AAAA results, they are handled via two
+separate `net::DnsTransaction`s and the `net::HostResolverManager::DnsTask` will
+request a second slots from the `net::PrioritizedDispatcher` used by
+`net::HostResolverManager`. The A transaction is started immediately on starting
+the `net::HostResolverManager::DnsTask`, and the AAAA transaction is started
+once a second dispatcher slot can be obtained.
+
+Each `net::DnsTransaction` internally makes a series of `net::DnsAttempt`s, each
+representing an individual DNS request. A single `net::DnsTransaction` can run
+many `net::DnsAttempt`s due to retry logic, fallback between multiple configured
+DNS servers, and name permutation due to configured search suffixes.
+
+Data collected specifically for this source (more internally to
+`net::DnsTransaction` implementation not listed here):
+
+* "Net.DNS.DnsTask.ErrorBeforeFallback.Fast"
+* "Net.DNS.DnsTask.ErrorBeforeFallback.Slow"
+* "Net.DNS.DnsTask.SuccessTime"
+* "Net.DNS.InsecureDnsTask.FailureTime"
+* "Net.DNS.JobQueueTime.PerTransaction"
+* "Net.DNS.JobQueueTime.Failure"
+* "Net.DNS.JobQueueTime.Success"
+* "Net.DNS.SecureDnsTask.DnsModeSecure.FailureTime"
+* "Net.DNS.SecureDnsTask.DnsModeAutomatic.FailureTime"
+* "Net.DNS.SecureDnsTask.ErrorBeforeFallback.Fast"
+* "Net.DNS.SecureDnsTask.ErrorBeforeFallback.Slow"
+* "Net.DNS.SecureDnsTaskFailure.FallbackDnsTask.Error"
+
+#### MULTICAST_DNS
+
+`net::HostResolverSource::MULTICAST_DNS`
+`net::HostResolverManager::TaskType::MDNS`
+
+Implemented by [`net::HostResolverMdnsTask`](/net/dns/host_resolver_mdns_task.h)
+
+Results are queried from mDNS using [`net::MDnsClient`](/net/dns/mdns_client.h).
+
+When host resolution requests do not specify a source, mDNS is only used for
+non-address requests when the request hostname ends in ".local".
+
+mDNS requests start with [`net::HostResolverMdnsTask`](/net/dns/host_resolver_mdns_task.h),
+which will create and run a [`net::MDnsTransaction`](/net/dns/mdns_client.h) for
+each query type needed.
+
+Unlike `net::HostResolverManager::DnsTask`, each `net::HostResolverMdnsTask`
+will only ever use a single dispatcher slot, even when both A and AAAA types are
+queried concurrently.
+
+`net::MDnsClient` maintains its own cache, separate from the main
+[`net::HostCache`](/net/dns/host_cache.h) owned by the
+[`net::ContextHostResolver`](/net/dns/context_host_resolver.h). As such, mDNS
+results are never cached in the `net::HostCache`.
+
+### IPv6 and connectivity
+
+Some poorly written DNS servers, especially on home routers, are unaware of the
+existence of IPv6 and will result in bad performance or even crash when sent
+AAAA DNS queries.
+
+To avoid such issues, `net::HostResolverManager` heuristically detects IPv4-only
+networks by attempting a UDP connection to `2001:4860:4860::8888` (the IPv6
+address for Google Public DNS). If the connection fails, Chrome will convert
+host resolution requests for `net::DnsQueryType::UNSPECIFIED` to
+`net::DnsQueryType::A`. This generally results in disallowing AAAA requests.
+
+Exceptions when AAAA requests are always allowed despite a failed connectivity
+check:
+
+* The host resolution request explicitly requests `net::DnsQueryType::AAAA`
+* IP address literal resolution including when a hostname request has been
+ rewritten to an IP address literal using `net::MappedHostResolver`
+* Results read from HOSTS files where there is no non-loopback IPv4 result. Note
+ that this exception only applies when Chrome does the read from HOSTS. When
+ Chrome's built-in DNS client is not used, HOSTS is only read by the system
+ where Chrome would only request A results to avoid the system making AAAA DNS
+ queries.
+
+The heuristic for detecting IPv4-only networks is not perfect. E.g., it fails
+and disallows AAAA requests in private (no global internet access including to
+Google Public DNS) IPv6-only networks, which could then break most Chrome usage
+on the network because, being an IPv6-only network, AAAA results are necessary.
+
+Workarounds to allow Chrome to attempt to load IPv6 endpoints when the
+connectivity check fails:
+
+* Starting Chrome with
+ `--host-resolver-rules="MAP the.hostname.com [dead::beef]"` where
+ `the.hostname.com` is the hostname to allow resolving and `dead::beef` is the
+ IPv6 address to resolve it to. `net::MappedHostResolver` acts at a level
+ before IPv6 connectivity checks, and if a hostname is remapped to an IP
+ literal, connectivity checks do not apply.
+* Add entries for the hostnames to resolve to the HOSTS file with just IPv6
+ results. Only works with the built-in DNS client is used.
+* Add a network route to `2001:4860:4860::8888`. Doesn't have to actually be
+ functional (could just drop requests to it). As long as Chrome can connect a
+ UDP socket to the address, it will pass the heuristic checking
+ IPv6-connectivity.
diff --git a/chromium/net/dns/address_sorter_posix.cc b/chromium/net/dns/address_sorter_posix.cc
index b7683911481..e0443455a67 100644
--- a/chromium/net/dns/address_sorter_posix.cc
+++ b/chromium/net/dns/address_sorter_posix.cc
@@ -9,7 +9,7 @@
#include <memory>
#include <utility>
-#if defined(OS_MACOSX) || defined(OS_BSD)
+#if defined(OS_APPLE) || defined(OS_BSD)
#include <sys/socket.h> // Must be included before ifaddrs.h.
#include <ifaddrs.h>
#include <net/if.h>
@@ -28,7 +28,7 @@
#include "net/socket/client_socket_factory.h"
#include "net/socket/datagram_client_socket.h"
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
#include "net/base/address_tracker_linux.h"
#endif
@@ -329,7 +329,7 @@ void AddressSorterPosix::Sort(const AddressList& list,
void AddressSorterPosix::OnIPAddressChanged() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
source_map_.clear();
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
const internal::AddressTrackerLinux* tracker =
NetworkChangeNotifier::GetAddressTracker();
if (!tracker)
@@ -346,7 +346,7 @@ void AddressSorterPosix::OnIPAddressChanged() {
info.prefix_length = msg.ifa_prefixlen;
FillPolicy(address, &info);
}
-#elif defined(OS_MACOSX) || defined(OS_BSD)
+#elif defined(OS_APPLE) || defined(OS_BSD)
// It's not clear we will receive notification when deprecated flag changes.
// Socket for ioctl.
int ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0);
diff --git a/chromium/net/dns/address_sorter_posix_unittest.cc b/chromium/net/dns/address_sorter_posix_unittest.cc
index 92a15b69e4e..35053c7539d 100644
--- a/chromium/net/dns/address_sorter_posix_unittest.cc
+++ b/chromium/net/dns/address_sorter_posix_unittest.cc
@@ -20,6 +20,7 @@
#include "net/socket/socket_performance_watcher.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
+#include "net/test/test_with_task_environment.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -203,7 +204,9 @@ void OnSortComplete(AddressList* result_buf,
} // namespace
-class AddressSorterPosixTest : public testing::Test {
+// TaskEnvironment is required to register an IPAddressObserver from the
+// constructor of AddressSorterPosix.
+class AddressSorterPosixTest : public TestWithTaskEnvironment {
protected:
AddressSorterPosixTest() : sorter_(&socket_factory_) {}
diff --git a/chromium/net/dns/address_sorter_unittest.cc b/chromium/net/dns/address_sorter_unittest.cc
index 49ca0c2c57f..aab36e245ce 100644
--- a/chromium/net/dns/address_sorter_unittest.cc
+++ b/chromium/net/dns/address_sorter_unittest.cc
@@ -42,9 +42,9 @@ void OnSortComplete(AddressList* result_buf,
}
TEST(AddressSorterTest, Sort) {
+ base::test::TaskEnvironment task_environment;
int expected_result = OK;
#if defined(OS_WIN)
- base::test::TaskEnvironment task_environment;
EnsureWinsockInit();
SOCKET sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET) {
diff --git a/chromium/net/dns/dns_client.cc b/chromium/net/dns/dns_client.cc
index 08358b8375e..b70f66db484 100644
--- a/chromium/net/dns/dns_client.cc
+++ b/chromium/net/dns/dns_client.cc
@@ -12,7 +12,7 @@
#include "base/values.h"
#include "net/dns/address_sorter.h"
#include "net/dns/dns_session.h"
-#include "net/dns/dns_socket_pool.h"
+#include "net/dns/dns_socket_allocator.h"
#include "net/dns/dns_transaction.h"
#include "net/dns/dns_util.h"
#include "net/dns/resolve_context.h"
@@ -245,14 +245,11 @@ class DnsClientImpl : public DnsClient {
if (new_effective_config) {
DCHECK(new_effective_config.value().IsValid());
- std::unique_ptr<DnsSocketPool> socket_pool(
- new_effective_config.value().randomize_ports
- ? DnsSocketPool::CreateDefault(socket_factory_,
- rand_int_callback_)
- : DnsSocketPool::CreateNull(socket_factory_, rand_int_callback_));
- session_ =
- new DnsSession(std::move(new_effective_config).value(),
- std::move(socket_pool), rand_int_callback_, net_log_);
+ auto socket_allocator = std::make_unique<DnsSocketAllocator>(
+ socket_factory_, new_effective_config.value().nameservers, net_log_);
+ session_ = new DnsSession(std::move(new_effective_config).value(),
+ std::move(socket_allocator), rand_int_callback_,
+ net_log_);
factory_ = DnsTransactionFactory::CreateFactory(session_.get());
}
}
diff --git a/chromium/net/dns/dns_config.cc b/chromium/net/dns/dns_config.cc
index c6d757e5144..af2c38e3f02 100644
--- a/chromium/net/dns/dns_config.cc
+++ b/chromium/net/dns/dns_config.cc
@@ -24,7 +24,6 @@ DnsConfig::DnsConfig(std::vector<IPEndPoint> nameservers)
dns_over_tls_hostname(std::string()),
unhandled_options(false),
append_to_multi_label_name(true),
- randomize_ports(false),
ndots(1),
timeout(kDnsDefaultTimeout),
attempts(2),
diff --git a/chromium/net/dns/dns_config.h b/chromium/net/dns/dns_config.h
index d65a31eb45d..6ab6e4147fb 100644
--- a/chromium/net/dns/dns_config.h
+++ b/chromium/net/dns/dns_config.h
@@ -86,10 +86,6 @@ struct NET_EXPORT DnsConfig {
// True, except on Windows where it can be configured.
bool append_to_multi_label_name;
- // Indicates that source port randomization is required. This uses additional
- // resources on some platforms.
- bool randomize_ports;
-
// Resolver options; see man resolv.conf.
// Minimum number of dots before global resolution precedes |search|.
diff --git a/chromium/net/dns/dns_config_overrides.cc b/chromium/net/dns/dns_config_overrides.cc
index 0ea96839251..fa0437e7fc4 100644
--- a/chromium/net/dns/dns_config_overrides.cc
+++ b/chromium/net/dns/dns_config_overrides.cc
@@ -25,10 +25,9 @@ bool DnsConfigOverrides::operator==(const DnsConfigOverrides& other) const {
return nameservers == other.nameservers && search == other.search &&
hosts == other.hosts &&
append_to_multi_label_name == other.append_to_multi_label_name &&
- randomize_ports == other.randomize_ports && ndots == other.ndots &&
- timeout == other.timeout && attempts == other.attempts &&
- doh_attempts == other.doh_attempts && rotate == other.rotate &&
- use_local_ipv6 == other.use_local_ipv6 &&
+ ndots == other.ndots && timeout == other.timeout &&
+ attempts == other.attempts && doh_attempts == other.doh_attempts &&
+ rotate == other.rotate && use_local_ipv6 == other.use_local_ipv6 &&
dns_over_https_servers == other.dns_over_https_servers &&
secure_dns_mode == other.secure_dns_mode &&
allow_dns_over_https_upgrade == other.allow_dns_over_https_upgrade &&
@@ -49,7 +48,6 @@ DnsConfigOverrides::CreateOverridingEverythingWithDefaults() {
overrides.search = defaults.search;
overrides.hosts = defaults.hosts;
overrides.append_to_multi_label_name = defaults.append_to_multi_label_name;
- overrides.randomize_ports = defaults.randomize_ports;
overrides.ndots = defaults.ndots;
overrides.timeout = defaults.timeout;
overrides.attempts = defaults.attempts;
@@ -67,10 +65,9 @@ DnsConfigOverrides::CreateOverridingEverythingWithDefaults() {
bool DnsConfigOverrides::OverridesEverything() const {
return nameservers && search && hosts && append_to_multi_label_name &&
- randomize_ports && ndots && timeout && attempts && doh_attempts &&
- rotate && use_local_ipv6 && dns_over_https_servers &&
- secure_dns_mode && allow_dns_over_https_upgrade &&
- disabled_upgrade_providers;
+ ndots && timeout && attempts && doh_attempts && rotate &&
+ use_local_ipv6 && dns_over_https_servers && secure_dns_mode &&
+ allow_dns_over_https_upgrade && disabled_upgrade_providers;
}
DnsConfig DnsConfigOverrides::ApplyOverrides(const DnsConfig& config) const {
@@ -87,8 +84,6 @@ DnsConfig DnsConfigOverrides::ApplyOverrides(const DnsConfig& config) const {
overridden.hosts = hosts.value();
if (append_to_multi_label_name)
overridden.append_to_multi_label_name = append_to_multi_label_name.value();
- if (randomize_ports)
- overridden.randomize_ports = randomize_ports.value();
if (ndots)
overridden.ndots = ndots.value();
if (timeout)
diff --git a/chromium/net/dns/dns_config_overrides.h b/chromium/net/dns/dns_config_overrides.h
index e09a6ee82fd..a87d0e503f4 100644
--- a/chromium/net/dns/dns_config_overrides.h
+++ b/chromium/net/dns/dns_config_overrides.h
@@ -50,7 +50,6 @@ struct NET_EXPORT DnsConfigOverrides {
base::Optional<std::vector<std::string>> search;
base::Optional<DnsHosts> hosts;
base::Optional<bool> append_to_multi_label_name;
- base::Optional<bool> randomize_ports;
base::Optional<int> ndots;
base::Optional<base::TimeDelta> timeout;
base::Optional<int> attempts;
diff --git a/chromium/net/dns/dns_config_service_posix.cc b/chromium/net/dns/dns_config_service_posix.cc
index d8224724a89..5a4aead0acf 100644
--- a/chromium/net/dns/dns_config_service_posix.cc
+++ b/chromium/net/dns/dns_config_service_posix.cc
@@ -30,7 +30,7 @@
#include "net/dns/public/dns_protocol.h"
#include "net/dns/serial_worker.h"
-#if defined(OS_MACOSX) && !defined(OS_IOS)
+#if defined(OS_MAC)
#include "net/dns/dns_config_watcher_mac.h"
#endif
@@ -96,11 +96,11 @@ class DnsConfigWatcher : public NetworkChangeNotifier::NetworkChangeObserver {
CallbackType callback_;
};
-#elif defined(OS_MACOSX)
+#elif defined(OS_MAC)
-// DnsConfigWatcher for OS_MACOSX is in dns_config_watcher_mac.{hh,cc}.
+// DnsConfigWatcher for OS_MAC is in dns_config_watcher_mac.{hh,cc}.
-#else // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
+#else // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MAC)
#ifndef _PATH_RESCONF // Normally defined in <resolv.h>
#define _PATH_RESCONF "/etc/resolv.conf"
@@ -169,14 +169,14 @@ ConfigParsePosixResult ReadDnsConfig(DnsConfig* dns_config) {
result = CONFIG_PARSE_POSIX_RES_INIT_FAILED;
}
// Prefer res_ndestroy where available.
-#if defined(OS_MACOSX) || defined(OS_FREEBSD)
+#if defined(OS_APPLE) || defined(OS_FREEBSD)
res_ndestroy(&res);
#else
res_nclose(&res);
-#endif // defined(OS_MACOSX) || defined(OS_FREEBSD)
+#endif // defined(OS_APPLE) || defined(OS_FREEBSD)
#endif // defined(OS_OPENBSD)
-#if defined(OS_MACOSX) && !defined(OS_IOS)
+#if defined(OS_MAC)
ConfigParsePosixResult error = DnsConfigWatcher::CheckDnsConfig();
switch (error) {
case CONFIG_PARSE_POSIX_OK:
@@ -188,7 +188,7 @@ ConfigParsePosixResult ReadDnsConfig(DnsConfig* dns_config) {
default:
return error;
}
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
+#endif // defined(OS_MAC)
// Override timeout value to match default setting on Windows.
dns_config->timeout = kDnsDefaultTimeout;
return result;
@@ -478,7 +478,7 @@ ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res,
dns_config->nameservers.clear();
-#if defined(OS_MACOSX) || defined(OS_FREEBSD)
+#if defined(OS_APPLE) || defined(OS_FREEBSD)
union res_sockaddr_union addresses[MAXNS];
int nscount = res_getservers(const_cast<res_state>(&res), addresses, MAXNS);
DCHECK_GE(nscount, 0);
@@ -492,7 +492,7 @@ ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res,
}
dns_config->nameservers.push_back(ipe);
}
-#elif defined(OS_LINUX)
+#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
static_assert(std::extent<decltype(res.nsaddr_list)>() >= MAXNS &&
std::extent<decltype(res._u._ext.nsaddrs)>() >= MAXNS,
"incompatible libresolv res_state");
@@ -517,7 +517,8 @@ ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res,
return CONFIG_PARSE_POSIX_BAD_ADDRESS;
dns_config->nameservers.push_back(ipe);
}
-#else // !(defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_FREEBSD))
+#else // !(defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_APPLE) ||
+ // defined(OS_FREEBSD))
DCHECK_LE(res.nscount, MAXNS);
for (int i = 0; i < res.nscount; ++i) {
IPEndPoint ipe;
@@ -528,7 +529,7 @@ ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res,
}
dns_config->nameservers.push_back(ipe);
}
-#endif // defined(OS_MACOSX) || defined(OS_FREEBSD)
+#endif // defined(OS_APPLE) || defined(OS_FREEBSD)
dns_config->search.clear();
for (int i = 0; (i < MAXDNSRCH) && res.dnsrch[i]; ++i) {
diff --git a/chromium/net/dns/dns_config_service_posix_unittest.cc b/chromium/net/dns/dns_config_service_posix_unittest.cc
index 89892406263..a98dffb783f 100644
--- a/chromium/net/dns/dns_config_service_posix_unittest.cc
+++ b/chromium/net/dns/dns_config_service_posix_unittest.cc
@@ -51,7 +51,7 @@ const char* const kNameserversIPv4[] = {
"1.0.0.1",
};
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
const char* const kNameserversIPv6[] = {
NULL,
"2001:DB8:0::42",
@@ -87,7 +87,7 @@ void InitializeResState(res_state res) {
++res->nscount;
}
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
// Install IPv6 addresses, replacing the corresponding IPv4 addresses.
unsigned nscount6 = 0;
for (unsigned i = 0; i < base::size(kNameserversIPv6) && i < MAXNS; ++i) {
@@ -108,7 +108,7 @@ void InitializeResState(res_state res) {
}
void CloseResState(res_state res) {
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
for (int i = 0; i < res->nscount; ++i) {
if (res->_u._ext.nsaddrs[i] != NULL)
free(res->_u._ext.nsaddrs[i]);
@@ -133,7 +133,7 @@ void InitializeExpectedConfig(DnsConfig* config) {
config->nameservers.push_back(IPEndPoint(ip, NS_DEFAULTPORT + i));
}
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
for (unsigned i = 0; i < base::size(kNameserversIPv6) && i < MAXNS; ++i) {
if (!kNameserversIPv6[i])
continue;
@@ -241,7 +241,7 @@ class DnsConfigServicePosixTest : public testing::Test {
service_.reset(new DnsConfigServicePosix());
}
- void TearDown() override { ASSERT_TRUE(base::DeleteFile(temp_file_, false)); }
+ void TearDown() override { ASSERT_TRUE(base::DeleteFile(temp_file_)); }
base::test::TaskEnvironment task_environment_;
bool seen_config_;
diff --git a/chromium/net/dns/dns_config_service_win.cc b/chromium/net/dns/dns_config_service_win.cc
index 9cd9d76f6bb..37fd844c1de 100644
--- a/chromium/net/dns/dns_config_service_win.cc
+++ b/chromium/net/dns/dns_config_service_win.cc
@@ -20,6 +20,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/sequence_checker.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -46,27 +47,27 @@ namespace {
const int kRetryIntervalSeconds = 5;
// Registry key paths.
-const base::char16 kTcpipPath[] =
- STRING16_LITERAL("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters");
-const base::char16 kTcpip6Path[] =
- STRING16_LITERAL("SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters");
-const base::char16 kDnscachePath[] = STRING16_LITERAL(
- "SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters");
-const base::char16 kPolicyPath[] =
- STRING16_LITERAL("SOFTWARE\\Policies\\Microsoft\\Windows NT\\DNSClient");
-const base::char16 kPrimaryDnsSuffixPath[] =
- STRING16_LITERAL("SOFTWARE\\Policies\\Microsoft\\System\\DNSClient");
-const base::char16 kNrptPath[] = STRING16_LITERAL(
- "SOFTWARE\\Policies\\Microsoft\\Windows NT\\DNSClient\\DnsPolicyConfig");
-const base::char16 kControlSetNrptPath[] = STRING16_LITERAL(
- "SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters"
- "\\DnsPolicyConfig");
-const base::char16 kDnsConnectionsPath[] = STRING16_LITERAL(
- "SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters"
- "\\DnsConnections");
-const base::char16 kDnsConnectionsProxies[] = STRING16_LITERAL(
- "SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters"
- "\\DnsConnectionsProxies");
+const wchar_t kTcpipPath[] =
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
+const wchar_t kTcpip6Path[] =
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters";
+const wchar_t kDnscachePath[] =
+ L"SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters";
+const wchar_t kPolicyPath[] =
+ L"SOFTWARE\\Policies\\Microsoft\\Windows NT\\DNSClient";
+const wchar_t kPrimaryDnsSuffixPath[] =
+ L"SOFTWARE\\Policies\\Microsoft\\System\\DNSClient";
+const wchar_t kNrptPath[] =
+ L"SOFTWARE\\Policies\\Microsoft\\Windows NT\\DNSClient\\DnsPolicyConfig";
+const wchar_t kControlSetNrptPath[] =
+ L"SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters\\"
+ L"DnsPolicyConfig";
+const wchar_t kDnsConnectionsPath[] =
+ L"SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters\\"
+ L"DnsConnections";
+const wchar_t kDnsConnectionsProxies[] =
+ L"SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters\\"
+ L"DnsConnectionsProxies";
enum HostsParseWinResult {
HOSTS_PARSE_WIN_OK = 0,
@@ -80,14 +81,14 @@ enum HostsParseWinResult {
// Convenience for reading values using RegKey.
class RegistryReader {
public:
- explicit RegistryReader(const base::char16* key) {
+ explicit RegistryReader(const wchar_t* key) {
// Ignoring the result. |key_.Valid()| will catch failures.
key_.Open(HKEY_LOCAL_MACHINE, key, KEY_QUERY_VALUE);
}
~RegistryReader() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); }
- bool ReadString(const base::char16* name,
+ bool ReadString(const wchar_t* name,
DnsSystemSettings::RegString* out) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
out->set = false;
@@ -103,8 +104,7 @@ class RegistryReader {
return (result == ERROR_FILE_NOT_FOUND);
}
- bool ReadDword(const base::char16* name,
- DnsSystemSettings::RegDword* out) const {
+ bool ReadDword(const wchar_t* name, DnsSystemSettings::RegDword* out) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
out->set = false;
if (!key_.Valid()) {
@@ -150,10 +150,8 @@ std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> ReadIpHelper(
bool ReadDevolutionSetting(const RegistryReader& reader,
DnsSystemSettings::DevolutionSetting* setting) {
- return reader.ReadDword(STRING16_LITERAL("UseDomainNameDevolution"),
- &setting->enabled) &&
- reader.ReadDword(STRING16_LITERAL("DomainNameDevolutionLevel"),
- &setting->level);
+ return reader.ReadDword(L"UseDomainNameDevolution", &setting->enabled) &&
+ reader.ReadDword(L"DomainNameDevolutionLevel", &setting->level);
}
// Reads DnsSystemSettings from IpHelper and registry.
@@ -173,17 +171,14 @@ ConfigParseWinResult ReadSystemSettings(DnsSystemSettings* settings) {
RegistryReader policy_reader(kPolicyPath);
RegistryReader primary_dns_suffix_reader(kPrimaryDnsSuffixPath);
- if (!policy_reader.ReadString(STRING16_LITERAL("SearchList"),
- &settings->policy_search_list)) {
+ if (!policy_reader.ReadString(L"SearchList", &settings->policy_search_list)) {
return CONFIG_PARSE_WIN_READ_POLICY_SEARCHLIST;
}
- if (!tcpip_reader.ReadString(STRING16_LITERAL("SearchList"),
- &settings->tcpip_search_list))
+ if (!tcpip_reader.ReadString(L"SearchList", &settings->tcpip_search_list))
return CONFIG_PARSE_WIN_READ_TCPIP_SEARCHLIST;
- if (!tcpip_reader.ReadString(STRING16_LITERAL("Domain"),
- &settings->tcpip_domain))
+ if (!tcpip_reader.ReadString(L"Domain", &settings->tcpip_domain))
return CONFIG_PARSE_WIN_READ_DOMAIN;
if (!ReadDevolutionSetting(policy_reader, &settings->policy_devolution))
@@ -195,14 +190,13 @@ ConfigParseWinResult ReadSystemSettings(DnsSystemSettings* settings) {
if (!ReadDevolutionSetting(tcpip_reader, &settings->tcpip_devolution))
return CONFIG_PARSE_WIN_READ_TCPIP_DEVOLUTION;
- if (!policy_reader.ReadDword(STRING16_LITERAL("AppendToMultiLabelName"),
+ if (!policy_reader.ReadDword(L"AppendToMultiLabelName",
&settings->append_to_multi_label_name)) {
return CONFIG_PARSE_WIN_READ_APPEND_MULTILABEL;
}
- if (!primary_dns_suffix_reader.ReadString(
- STRING16_LITERAL("PrimaryDnsSuffix"),
- &settings->primary_dns_suffix)) {
+ if (!primary_dns_suffix_reader.ReadString(L"PrimaryDnsSuffix",
+ &settings->primary_dns_suffix)) {
return CONFIG_PARSE_WIN_READ_PRIMARY_SUFFIX;
}
@@ -234,11 +228,10 @@ HostsParseWinResult AddLocalhostEntries(DnsHosts* hosts) {
hosts->insert(std::make_pair(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV6),
loopback_ipv6));
- base::char16 buffer[MAX_PATH];
+ wchar_t buffer[MAX_PATH];
DWORD size = MAX_PATH;
std::string localname;
- if (!GetComputerNameExW(ComputerNameDnsHostname,
- base::as_writable_wcstr(buffer), &size) ||
+ if (!GetComputerNameExW(ComputerNameDnsHostname, buffer, &size) ||
!ParseDomainASCII(buffer, &localname)) {
return HOSTS_PARSE_WIN_COMPUTER_NAME_FAILED;
}
@@ -296,7 +289,7 @@ class RegistryWatcher {
~RegistryWatcher() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); }
- bool Watch(const base::char16* key, const CallbackType& callback) {
+ bool Watch(const wchar_t* key, const CallbackType& callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!callback.is_null());
DCHECK(callback_.is_null());
@@ -342,8 +335,8 @@ bool IsStatelessDiscoveryAddress(const IPAddress& address) {
// Returns the path to the HOSTS file.
base::FilePath GetHostsPath() {
- base::char16 buffer[MAX_PATH];
- UINT rc = GetSystemDirectory(base::as_writable_wcstr(buffer), MAX_PATH);
+ wchar_t buffer[MAX_PATH];
+ UINT rc = GetSystemDirectory(buffer, MAX_PATH);
DCHECK(0 < rc && rc < MAX_PATH);
return base::FilePath(buffer).Append(
FILE_PATH_LITERAL("drivers\\etc\\hosts"));
@@ -462,13 +455,13 @@ DnsSystemSettings::DnsSystemSettings()
DnsSystemSettings::~DnsSystemSettings() {
}
-bool ParseDomainASCII(base::StringPiece16 widestr, std::string* domain) {
+bool ParseDomainASCII(base::WStringPiece widestr, std::string* domain) {
DCHECK(domain);
if (widestr.empty())
return false;
// Check if already ASCII.
- if (base::IsStringASCII(widestr)) {
+ if (base::IsStringASCII(base::AsStringPiece16(widestr))) {
domain->assign(widestr.begin(), widestr.end());
return true;
}
@@ -476,7 +469,7 @@ bool ParseDomainASCII(base::StringPiece16 widestr, std::string* domain) {
// Otherwise try to convert it from IDN to punycode.
const int kInitialBufferSize = 256;
url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode;
- if (!url::IDNToASCII(widestr.data(), widestr.length(), &punycode))
+ if (!url::IDNToASCII(base::as_u16cstr(widestr), widestr.length(), &punycode))
return false;
// |punycode_output| should now be ASCII; convert it to a std::string.
@@ -488,7 +481,7 @@ bool ParseDomainASCII(base::StringPiece16 widestr, std::string* domain) {
return success && !domain->empty();
}
-bool ParseSearchList(const base::string16& value,
+bool ParseSearchList(const std::wstring& value,
std::vector<std::string>* output) {
DCHECK(output);
if (value.empty())
@@ -500,9 +493,8 @@ bool ParseSearchList(const base::string16& value,
// Although nslookup and network connection property tab ignore such
// fragments ("a,b,,c" becomes ["a", "b", "c"]), our reference is getaddrinfo
// (which sees ["a", "b"]). WMI queries also return a matching search list.
- for (const base::StringPiece16& t :
- base::SplitStringPiece(value, STRING16_LITERAL(","),
- base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
+ for (base::WStringPiece t : base::SplitStringPiece(
+ value, L",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
// Convert non-ASCII to punycode, although getaddrinfo does not properly
// handle such suffixes.
std::string parsed;
@@ -561,7 +553,7 @@ ConfigParseWinResult ConvertSettingsToDnsConfig(
// obtained via DHCP (regkey: Tcpip\Parameters\Interfaces\{XXX}\DhcpDomain)
// or specified by the user (regkey: Tcpip\Parameters\Domain).
std::string dns_suffix;
- if (ParseDomainASCII(base::as_u16cstr(adapter->DnsSuffix), &dns_suffix))
+ if (ParseDomainASCII(adapter->DnsSuffix, &dns_suffix))
config->search.push_back(dns_suffix);
}
diff --git a/chromium/net/dns/dns_config_service_win.h b/chromium/net/dns/dns_config_service_win.h
index 8b64504a7c5..6c7e3df9e8a 100644
--- a/chromium/net/dns/dns_config_service_win.h
+++ b/chromium/net/dns/dns_config_service_win.h
@@ -19,6 +19,7 @@
#include "base/memory/free_deleter.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
+#include "base/strings/string_piece_forward.h"
#include "net/base/net_export.h"
#include "net/dns/dns_config_service.h"
@@ -40,14 +41,14 @@ namespace internal {
// Converts a UTF-16 domain name to ASCII, possibly using punycode.
// Returns true if the conversion succeeds and output is not empty. In case of
// failure, |domain| might become dirty.
-bool NET_EXPORT_PRIVATE ParseDomainASCII(base::StringPiece16 widestr,
+bool NET_EXPORT_PRIVATE ParseDomainASCII(base::WStringPiece widestr,
std::string* domain);
// Parses |value| as search list (comma-delimited list of domain names) from
// a registry key and stores it in |out|. Returns true on success. Empty
// entries (e.g., "chromium.org,,org") terminate the list. Non-ascii hostnames
// are converted to punycode.
-bool NET_EXPORT_PRIVATE ParseSearchList(const base::string16& value,
+bool NET_EXPORT_PRIVATE ParseSearchList(const std::wstring& value,
std::vector<std::string>* out);
// All relevant settings read from registry and IP Helper. This isolates our
@@ -57,7 +58,7 @@ struct NET_EXPORT_PRIVATE DnsSystemSettings {
// The |set| flag distinguishes between empty and unset values.
struct RegString {
bool set;
- base::string16 value;
+ std::wstring value;
};
struct RegDword {
diff --git a/chromium/net/dns/dns_config_service_win_unittest.cc b/chromium/net/dns/dns_config_service_win_unittest.cc
index cd34aa1a997..070df338e13 100644
--- a/chromium/net/dns/dns_config_service_win_unittest.cc
+++ b/chromium/net/dns/dns_config_service_win_unittest.cc
@@ -17,19 +17,19 @@ namespace {
TEST(DnsConfigServiceWinTest, ParseSearchList) {
const struct TestCase {
- const base::char16* input;
+ const wchar_t* input;
const char* output[4]; // NULL-terminated, empty if expected false
} cases[] = {
- {STRING16_LITERAL("chromium.org"), {"chromium.org", nullptr}},
- {STRING16_LITERAL("chromium.org,org"), {"chromium.org", "org", nullptr}},
+ {L"chromium.org", {"chromium.org", nullptr}},
+ {L"chromium.org,org", {"chromium.org", "org", nullptr}},
// Empty suffixes terminate the list
- {STRING16_LITERAL("crbug.com,com,,org"), {"crbug.com", "com", nullptr}},
+ {L"crbug.com,com,,org", {"crbug.com", "com", nullptr}},
// IDN are converted to punycode
- {STRING16_LITERAL("\u017c\xf3\u0142ta.pi\u0119\u015b\u0107.pl,pl"),
+ {L"\u017c\xf3\u0142ta.pi\u0119\u015b\u0107.pl,pl",
{"xn--ta-4ja03asj.xn--pi-wla5e0q.pl", "pl", nullptr}},
// Empty search list is invalid
- {STRING16_LITERAL(""), {nullptr}},
- {STRING16_LITERAL(",,"), {nullptr}},
+ {L"", {nullptr}},
+ {L",,", {nullptr}},
};
for (const auto& t : cases) {
@@ -219,11 +219,10 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
// Policy SearchList override.
{
- {true,
- STRING16_LITERAL("policy.searchlist.a,policy.searchlist.b")},
- {true, STRING16_LITERAL("tcpip.searchlist.a,tcpip.searchlist.b")},
- {true, STRING16_LITERAL("tcpip.domain")},
- {true, STRING16_LITERAL("primary.dns.suffix")},
+ {true, L"policy.searchlist.a,policy.searchlist.b"},
+ {true, L"tcpip.searchlist.a,tcpip.searchlist.b"},
+ {true, L"tcpip.domain"},
+ {true, L"primary.dns.suffix"},
},
{"policy.searchlist.a", "policy.searchlist.b"},
},
@@ -231,18 +230,18 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
// User-specified SearchList override.
{
{false},
- {true, STRING16_LITERAL("tcpip.searchlist.a,tcpip.searchlist.b")},
- {true, STRING16_LITERAL("tcpip.domain")},
- {true, STRING16_LITERAL("primary.dns.suffix")},
+ {true, L"tcpip.searchlist.a,tcpip.searchlist.b"},
+ {true, L"tcpip.domain"},
+ {true, L"primary.dns.suffix"},
},
{"tcpip.searchlist.a", "tcpip.searchlist.b"},
},
{
// Void SearchList. Using tcpip.domain
{
- {true, STRING16_LITERAL(",bad.searchlist,parsed.as.empty")},
- {true, STRING16_LITERAL("tcpip.searchlist,good.but.overridden")},
- {true, STRING16_LITERAL("tcpip.domain")},
+ {true, L",bad.searchlist,parsed.as.empty"},
+ {true, L"tcpip.searchlist,good.but.overridden"},
+ {true, L"tcpip.domain"},
{false},
},
{"tcpip.domain", "connection.suffix"},
@@ -250,10 +249,10 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
// Void SearchList. Using primary.dns.suffix
{
- {true, STRING16_LITERAL(",bad.searchlist,parsed.as.empty")},
- {true, STRING16_LITERAL("tcpip.searchlist,good.but.overridden")},
- {true, STRING16_LITERAL("tcpip.domain")},
- {true, STRING16_LITERAL("primary.dns.suffix")},
+ {true, L",bad.searchlist,parsed.as.empty"},
+ {true, L"tcpip.searchlist,good.but.overridden"},
+ {true, L"tcpip.domain"},
+ {true, L"primary.dns.suffix"},
},
{"primary.dns.suffix", "connection.suffix"},
},
@@ -261,19 +260,19 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
// Void SearchList. Using tcpip.domain when primary.dns.suffix is
// empty
{
- {true, STRING16_LITERAL(",bad.searchlist,parsed.as.empty")},
- {true, STRING16_LITERAL("tcpip.searchlist,good.but.overridden")},
- {true, STRING16_LITERAL("tcpip.domain")},
- {true, STRING16_LITERAL("")},
+ {true, L",bad.searchlist,parsed.as.empty"},
+ {true, L"tcpip.searchlist,good.but.overridden"},
+ {true, L"tcpip.domain"},
+ {true, L""},
},
{"tcpip.domain", "connection.suffix"},
},
{
// Void SearchList. Using tcpip.domain when primary.dns.suffix is NULL
{
- {true, STRING16_LITERAL(",bad.searchlist,parsed.as.empty")},
- {true, STRING16_LITERAL("tcpip.searchlist,good.but.overridden")},
- {true, STRING16_LITERAL("tcpip.domain")},
+ {true, L",bad.searchlist,parsed.as.empty"},
+ {true, L"tcpip.searchlist,good.but.overridden"},
+ {true, L"tcpip.domain"},
{true},
},
{"tcpip.domain", "connection.suffix"},
@@ -294,7 +293,7 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
{false},
{false},
- {true, STRING16_LITERAL("a.b.c.d.e")},
+ {true, L"a.b.c.d.e"},
{false},
{{true, 1}, {false}}, // policy_devolution: enabled, level
{{true, 0}, {true, 3}}, // dnscache_devolution
@@ -307,8 +306,8 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
{false},
{false},
- {true, STRING16_LITERAL("a.b.c.d.e")},
- {true, STRING16_LITERAL("f.g.i.l.j")},
+ {true, L"a.b.c.d.e"},
+ {true, L"f.g.i.l.j"},
{{false}, {true, 4}},
{{true, 1}, {false}},
{{true, 0}, {true, 3}},
@@ -320,7 +319,7 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
{false},
{false},
- {true, STRING16_LITERAL("a.b.c.d.e")},
+ {true, L"a.b.c.d.e"},
{false},
{{false}, {false}},
{{false}, {true, 3}},
@@ -333,7 +332,7 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
{false},
{false},
- {true, STRING16_LITERAL("a.b")},
+ {true, L"a.b"},
{false},
{{false}, {false}},
{{false}, {true, 2}},
@@ -346,7 +345,7 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
{false},
{false},
- {true, STRING16_LITERAL("a.b.c.d.e")},
+ {true, L"a.b.c.d.e"},
{false},
{{true, 1}, {false}},
{{true, 1}, {false}},
@@ -359,7 +358,7 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
{false},
{false},
- {true, STRING16_LITERAL("a.b.c.d.e")},
+ {true, L"a.b.c.d.e"},
{false},
{{false}, {true, 1}},
{{true, 1}, {true, 3}},
@@ -372,7 +371,7 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
{
{false},
{false},
- {true, STRING16_LITERAL("a.b.c.d.e")},
+ {true, L"a.b.c.d.e"},
{false},
{{false}, {true, 3}},
{{false}, {true, 3}},
diff --git a/chromium/net/dns/dns_hosts.cc b/chromium/net/dns/dns_hosts.cc
index 04b1596e613..42e40598e96 100644
--- a/chromium/net/dns/dns_hosts.cc
+++ b/chromium/net/dns/dns_hosts.cc
@@ -177,7 +177,7 @@ void ParseHostsWithCommaModeForTesting(const std::string& contents,
void ParseHosts(const std::string& contents, DnsHosts* dns_hosts) {
ParseHostsCommaMode comma_mode;
-#if defined(OS_MACOSX)
+#if defined(OS_APPLE)
// Mac OS X allows commas to separate hostnames.
comma_mode = PARSE_HOSTS_COMMA_IS_WHITESPACE;
#else
diff --git a/chromium/net/dns/dns_hosts_unittest.cc b/chromium/net/dns/dns_hosts_unittest.cc
index 0b5476dc0eb..50353361d11 100644
--- a/chromium/net/dns/dns_hosts_unittest.cc
+++ b/chromium/net/dns/dns_hosts_unittest.cc
@@ -112,7 +112,7 @@ TEST(DnsHostsTest, ParseHosts_CommaModeByPlatform) {
DnsHosts actual_hosts;
ParseHosts(kContents, &actual_hosts);
-#if defined(OS_MACOSX)
+#if defined(OS_APPLE)
const ExpectedHostsEntry kEntries[] = {
{ "comma1", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
{ "comma2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
diff --git a/chromium/net/dns/dns_query.cc b/chromium/net/dns/dns_query.cc
index 90176623c05..2e33f4f3543 100644
--- a/chromium/net/dns/dns_query.cc
+++ b/chromium/net/dns/dns_query.cc
@@ -148,6 +148,15 @@ DnsQuery::DnsQuery(uint16_t id,
DnsQuery::DnsQuery(scoped_refptr<IOBufferWithSize> buffer)
: io_buffer_(std::move(buffer)) {}
+DnsQuery::DnsQuery(const DnsQuery& query) {
+ CopyFrom(query);
+}
+
+DnsQuery& DnsQuery::operator=(const DnsQuery& query) {
+ CopyFrom(query);
+ return *this;
+}
+
DnsQuery::~DnsQuery() = default;
std::unique_ptr<DnsQuery> DnsQuery::CloneWithNewId(uint16_t id) const {
@@ -221,12 +230,16 @@ void DnsQuery::set_flags(uint16_t flags) {
}
DnsQuery::DnsQuery(const DnsQuery& orig, uint16_t id) {
+ CopyFrom(orig);
+ header_->id = base::HostToNet16(id);
+}
+
+void DnsQuery::CopyFrom(const DnsQuery& orig) {
qname_size_ = orig.qname_size_;
io_buffer_ = base::MakeRefCounted<IOBufferWithSize>(orig.io_buffer()->size());
memcpy(io_buffer_.get()->data(), orig.io_buffer()->data(),
io_buffer_.get()->size());
header_ = reinterpret_cast<dns_protocol::Header*>(io_buffer_->data());
- header_->id = base::HostToNet16(id);
}
bool DnsQuery::ReadHeader(base::BigEndianReader* reader,
diff --git a/chromium/net/dns/dns_query.h b/chromium/net/dns/dns_query.h
index 6ca6a1e93f0..ce3b71e2f74 100644
--- a/chromium/net/dns/dns_query.h
+++ b/chromium/net/dns/dns_query.h
@@ -59,6 +59,10 @@ class NET_EXPORT_PRIVATE DnsQuery {
// populate the empty query.
explicit DnsQuery(scoped_refptr<IOBufferWithSize> buffer);
+ // Copies are constructed with an independent cloned, not mirrored, buffer.
+ DnsQuery(const DnsQuery& query);
+ DnsQuery& operator=(const DnsQuery& query);
+
~DnsQuery();
// Clones |this| verbatim, with ID field of the header set to |id|.
@@ -95,6 +99,7 @@ class NET_EXPORT_PRIVATE DnsQuery {
private:
DnsQuery(const DnsQuery& orig, uint16_t id);
+ void CopyFrom(const DnsQuery& orig);
bool ReadHeader(base::BigEndianReader* reader, dns_protocol::Header* out);
// After read, |out| is in the DNS format, e.g.
@@ -111,8 +116,6 @@ class NET_EXPORT_PRIVATE DnsQuery {
// Pointer to the dns header section.
dns_protocol::Header* header_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(DnsQuery);
};
} // namespace net
diff --git a/chromium/net/dns/dns_query_unittest.cc b/chromium/net/dns/dns_query_unittest.cc
index 3e5990887c0..dd9cd806a40 100644
--- a/chromium/net/dns/dns_query_unittest.cc
+++ b/chromium/net/dns/dns_query_unittest.cc
@@ -70,6 +70,17 @@ TEST(DnsQueryTest, Constructor) {
EXPECT_EQ(question, q1.question());
}
+TEST(DnsQueryTest, CopiesAreIndependent) {
+ DnsQuery q1(26 /* id */, kQName, dns_protocol::kTypeAAAA);
+
+ DnsQuery q2(q1);
+
+ EXPECT_EQ(q1.id(), q2.id());
+ EXPECT_EQ(base::StringPiece(q1.io_buffer()->data(), q1.io_buffer()->size()),
+ base::StringPiece(q2.io_buffer()->data(), q2.io_buffer()->size()));
+ EXPECT_NE(q1.io_buffer(), q2.io_buffer());
+}
+
TEST(DnsQueryTest, Clone) {
base::StringPiece qname(kQNameData, sizeof(kQNameData));
diff --git a/chromium/net/dns/dns_reloader.cc b/chromium/net/dns/dns_reloader.cc
index 0c0d0d84325..0672e711afb 100644
--- a/chromium/net/dns/dns_reloader.cc
+++ b/chromium/net/dns/dns_reloader.cc
@@ -4,16 +4,16 @@
#include "net/dns/dns_reloader.h"
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \
+#if defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_OPENBSD) && \
!defined(OS_ANDROID) && !defined(OS_FUCHSIA)
#include <resolv.h>
#include "base/lazy_instance.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop_current.h"
#include "base/notreached.h"
#include "base/synchronization/lock.h"
+#include "base/task/current_thread.h"
#include "base/threading/thread_local.h"
#include "net/base/network_change_notifier.h"
@@ -111,5 +111,5 @@ void DnsReloaderMaybeReload() {
} // namespace net
-#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) &&
+#endif // defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_OPENBSD) &&
// !defined(OS_ANDROID)
diff --git a/chromium/net/dns/dns_reloader.h b/chromium/net/dns/dns_reloader.h
index 4317d9eaf63..cbc910e40e9 100644
--- a/chromium/net/dns/dns_reloader.h
+++ b/chromium/net/dns/dns_reloader.h
@@ -7,7 +7,7 @@
#include "build/build_config.h"
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
+#if defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_OPENBSD)
namespace net {
// Call on the network thread before calling DnsReloaderMaybeReload() anywhere.
@@ -18,6 +18,6 @@ void EnsureDnsReloaderInit();
void DnsReloaderMaybeReload();
} // namespace net
-#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
+#endif // defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_OPENBSD)
#endif // NET_DNS_DNS_RELOADER_H_
diff --git a/chromium/net/dns/dns_session.cc b/chromium/net/dns/dns_session.cc
index c74c4bafae2..d6fed319f58 100644
--- a/chromium/net/dns/dns_session.cc
+++ b/chromium/net/dns/dns_session.cc
@@ -10,45 +10,25 @@
#include <utility>
#include "base/bind.h"
-#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "base/stl_util.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
#include "net/dns/dns_config.h"
-#include "net/dns/dns_socket_pool.h"
-#include "net/log/net_log_event_type.h"
-#include "net/log/net_log_source.h"
-#include "net/log/net_log_with_source.h"
-#include "net/socket/datagram_client_socket.h"
-#include "net/socket/stream_socket.h"
+#include "net/dns/dns_socket_allocator.h"
+#include "net/log/net_log.h"
namespace net {
-DnsSession::SocketLease::SocketLease(
- scoped_refptr<DnsSession> session,
- size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket)
- : session_(session),
- server_index_(server_index),
- socket_(std::move(socket)) {}
-
-DnsSession::SocketLease::~SocketLease() {
- session_->FreeSocket(server_index_, std::move(socket_));
-}
-
DnsSession::DnsSession(const DnsConfig& config,
- std::unique_ptr<DnsSocketPool> socket_pool,
+ std::unique_ptr<DnsSocketAllocator> socket_allocator,
const RandIntCallback& rand_int_callback,
NetLog* net_log)
: config_(config),
- socket_pool_(std::move(socket_pool)),
+ socket_allocator_(std::move(socket_allocator)),
rand_callback_(base::BindRepeating(rand_int_callback,
0,
std::numeric_limits<uint16_t>::max())),
net_log_(net_log) {
- socket_pool_->Initialize(&config_.nameservers, net_log);
UMA_HISTOGRAM_CUSTOM_COUNTS("AsyncDNS.ServerCount",
config_.nameservers.size(), 1, 10, 11);
}
@@ -59,41 +39,8 @@ uint16_t DnsSession::NextQueryId() const {
return static_cast<uint16_t>(rand_callback_.Run());
}
-// Allocate a socket, already connected to the server address.
-std::unique_ptr<DnsSession::SocketLease> DnsSession::AllocateSocket(
- size_t server_index,
- const NetLogSource& source) {
- std::unique_ptr<DatagramClientSocket> socket;
-
- socket = socket_pool_->AllocateSocket(server_index);
- if (!socket.get())
- return std::unique_ptr<SocketLease>();
-
- socket->NetLog().BeginEventReferencingSource(NetLogEventType::SOCKET_IN_USE,
- source);
-
- SocketLease* lease = new SocketLease(this, server_index, std::move(socket));
- return std::unique_ptr<SocketLease>(lease);
-}
-
-std::unique_ptr<StreamSocket> DnsSession::CreateTCPSocket(
- size_t server_index,
- const NetLogSource& source) {
- return socket_pool_->CreateTCPSocket(server_index, source);
-}
-
void DnsSession::InvalidateWeakPtrsForTesting() {
weak_ptr_factory_.InvalidateWeakPtrs();
}
-// Release a socket.
-void DnsSession::FreeSocket(size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket) {
- DCHECK(socket.get());
-
- socket->NetLog().EndEvent(NetLogEventType::SOCKET_IN_USE);
-
- socket_pool_->FreeSocket(server_index, std::move(socket));
-}
-
} // namespace net
diff --git a/chromium/net/dns/dns_session.h b/chromium/net/dns/dns_session.h
index d9830c28949..606d9877d8a 100644
--- a/chromium/net/dns/dns_session.h
+++ b/chromium/net/dns/dns_session.h
@@ -15,15 +15,12 @@
#include "net/base/net_export.h"
#include "net/base/rand_callback.h"
#include "net/dns/dns_config.h"
-#include "net/dns/dns_socket_pool.h"
#include "net/dns/dns_udp_tracker.h"
namespace net {
-class DatagramClientSocket;
+class DnsSocketAllocator;
class NetLog;
-struct NetLogSource;
-class StreamSocket;
// Session parameters and state shared between DnsTransactions for a specific
// instance/version of a DnsConfig. Also may be used as a key handle for
@@ -38,47 +35,19 @@ class NET_EXPORT_PRIVATE DnsSession : public base::RefCounted<DnsSession> {
public:
typedef base::RepeatingCallback<int()> RandCallback;
- class NET_EXPORT_PRIVATE SocketLease {
- public:
- SocketLease(scoped_refptr<DnsSession> session,
- size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket);
- ~SocketLease();
-
- size_t server_index() const { return server_index_; }
-
- DatagramClientSocket* socket() { return socket_.get(); }
-
- private:
- scoped_refptr<DnsSession> session_;
- size_t server_index_;
- std::unique_ptr<DatagramClientSocket> socket_;
-
- DISALLOW_COPY_AND_ASSIGN(SocketLease);
- };
-
DnsSession(const DnsConfig& config,
- std::unique_ptr<DnsSocketPool> socket_pool,
+ std::unique_ptr<DnsSocketAllocator> socket_allocator,
const RandIntCallback& rand_int_callback,
NetLog* net_log);
const DnsConfig& config() const { return config_; }
+ DnsSocketAllocator* socket_allocator() { return socket_allocator_.get(); }
DnsUdpTracker* udp_tracker() { return &udp_tracker_; }
NetLog* net_log() const { return net_log_; }
// Return the next random query ID.
uint16_t NextQueryId() const;
- // Allocate a socket, already connected to the server address.
- // When the SocketLease is destroyed, the socket will be freed.
- std::unique_ptr<SocketLease> AllocateSocket(size_t server_index,
- const NetLogSource& source);
-
- // Creates a StreamSocket from the factory for a transaction over TCP. These
- // sockets are not pooled.
- std::unique_ptr<StreamSocket> CreateTCPSocket(size_t server_index,
- const NetLogSource& source);
-
base::WeakPtr<DnsSession> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
@@ -94,12 +63,8 @@ class NET_EXPORT_PRIVATE DnsSession : public base::RefCounted<DnsSession> {
~DnsSession();
- // Release a socket.
- void FreeSocket(size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket);
-
const DnsConfig config_;
- std::unique_ptr<DnsSocketPool> socket_pool_;
+ std::unique_ptr<DnsSocketAllocator> socket_allocator_;
DnsUdpTracker udp_tracker_;
RandCallback rand_callback_;
NetLog* net_log_;
diff --git a/chromium/net/dns/dns_session_unittest.cc b/chromium/net/dns/dns_session_unittest.cc
deleted file mode 100644
index 60abd6f83b5..00000000000
--- a/chromium/net/dns/dns_session_unittest.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/dns/dns_session.h"
-
-#include <list>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/memory/ptr_util.h"
-#include "base/rand_util.h"
-#include "base/run_loop.h"
-#include "base/strings/stringprintf.h"
-#include "net/base/ip_address.h"
-#include "net/base/mock_network_change_notifier.h"
-#include "net/base/net_errors.h"
-#include "net/dns/dns_socket_pool.h"
-#include "net/dns/public/dns_protocol.h"
-#include "net/dns/resolve_context.h"
-#include "net/log/net_log_source.h"
-#include "net/socket/socket_performance_watcher.h"
-#include "net/socket/socket_test_util.h"
-#include "net/socket/ssl_client_socket.h"
-#include "net/socket/stream_socket.h"
-#include "net/test/test_with_task_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-
-namespace {
-
-class TestClientSocketFactory : public ClientSocketFactory {
- public:
- ~TestClientSocketFactory() override;
-
- std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
- DatagramSocket::BindType bind_type,
- NetLog* net_log,
- const NetLogSource& source) override;
-
- std::unique_ptr<TransportClientSocket> CreateTransportClientSocket(
- const AddressList& addresses,
- std::unique_ptr<SocketPerformanceWatcher>,
- NetLog*,
- const NetLogSource&) override {
- NOTIMPLEMENTED();
- return nullptr;
- }
-
- std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
- SSLClientContext* context,
- std::unique_ptr<StreamSocket> stream_socket,
- const HostPortPair& host_and_port,
- const SSLConfig& ssl_config) override {
- NOTIMPLEMENTED();
- return nullptr;
- }
-
- std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
- std::unique_ptr<StreamSocket> stream_socket,
- const std::string& user_agent,
- const HostPortPair& endpoint,
- const ProxyServer& proxy_server,
- HttpAuthController* http_auth_controller,
- bool tunnel,
- bool using_spdy,
- NextProto negotiated_protocol,
- ProxyDelegate* proxy_delegate,
- const NetworkTrafficAnnotationTag& traffic_annotation) override {
- NOTIMPLEMENTED();
- return nullptr;
- }
-
- private:
- std::list<std::unique_ptr<SocketDataProvider>> data_providers_;
-};
-
-struct PoolEvent {
- enum { ALLOCATE, FREE } action;
- size_t server_index;
-};
-
-class DnsSessionTest : public TestWithTaskEnvironment {
- public:
- void OnSocketAllocated(size_t server_index);
- void OnSocketFreed(size_t server_index);
-
- protected:
- void Initialize(size_t num_servers);
- std::unique_ptr<DnsSession::SocketLease> Allocate(size_t server_index);
- bool DidAllocate(size_t server_index);
- bool DidFree(size_t server_index);
- bool NoMoreEvents();
-
- DnsConfig config_;
- std::unique_ptr<TestClientSocketFactory> test_client_socket_factory_;
- scoped_refptr<DnsSession> session_;
- NetLogSource source_;
-
- private:
- bool ExpectEvent(const PoolEvent& event);
- std::list<PoolEvent> events_;
-};
-
-class MockDnsSocketPool : public DnsSocketPool {
- public:
- MockDnsSocketPool(ClientSocketFactory* factory, DnsSessionTest* test)
- : DnsSocketPool(factory, base::Bind(&base::RandInt)), test_(test) {}
-
- ~MockDnsSocketPool() override = default;
-
- void Initialize(const std::vector<IPEndPoint>* nameservers,
- NetLog* net_log) override {
- InitializeInternal(nameservers, net_log);
- }
-
- std::unique_ptr<DatagramClientSocket> AllocateSocket(
- size_t server_index) override {
- test_->OnSocketAllocated(server_index);
- return CreateConnectedSocket(server_index);
- }
-
- void FreeSocket(size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket) override {
- test_->OnSocketFreed(server_index);
- }
-
- private:
- DnsSessionTest* test_;
-};
-
-void DnsSessionTest::Initialize(size_t num_servers) {
- CHECK_LT(num_servers, 256u);
- config_.nameservers.clear();
- config_.dns_over_https_servers.clear();
- for (unsigned char i = 0; i < num_servers; ++i) {
- IPEndPoint dns_endpoint(IPAddress(192, 168, 1, i),
- dns_protocol::kDefaultPort);
- config_.nameservers.push_back(dns_endpoint);
- }
-
- test_client_socket_factory_.reset(new TestClientSocketFactory());
-
- DnsSocketPool* dns_socket_pool =
- new MockDnsSocketPool(test_client_socket_factory_.get(), this);
-
- session_ =
- new DnsSession(config_, std::unique_ptr<DnsSocketPool>(dns_socket_pool),
- base::Bind(&base::RandInt), nullptr /* NetLog */);
-
- events_.clear();
-}
-
-std::unique_ptr<DnsSession::SocketLease> DnsSessionTest::Allocate(
- size_t server_index) {
- return session_->AllocateSocket(server_index, source_);
-}
-
-bool DnsSessionTest::DidAllocate(size_t server_index) {
- PoolEvent expected_event = { PoolEvent::ALLOCATE, server_index };
- return ExpectEvent(expected_event);
-}
-
-bool DnsSessionTest::DidFree(size_t server_index) {
- PoolEvent expected_event = { PoolEvent::FREE, server_index };
- return ExpectEvent(expected_event);
-}
-
-bool DnsSessionTest::NoMoreEvents() {
- return events_.empty();
-}
-
-void DnsSessionTest::OnSocketAllocated(size_t server_index) {
- PoolEvent event = { PoolEvent::ALLOCATE, server_index };
- events_.push_back(event);
-}
-
-void DnsSessionTest::OnSocketFreed(size_t server_index) {
- PoolEvent event = { PoolEvent::FREE, server_index };
- events_.push_back(event);
-}
-
-bool DnsSessionTest::ExpectEvent(const PoolEvent& expected) {
- if (events_.empty()) {
- return false;
- }
-
- const PoolEvent actual = events_.front();
- if ((expected.action != actual.action)
- || (expected.server_index != actual.server_index)) {
- return false;
- }
- events_.pop_front();
-
- return true;
-}
-
-std::unique_ptr<DatagramClientSocket>
-TestClientSocketFactory::CreateDatagramClientSocket(
- DatagramSocket::BindType bind_type,
- NetLog* net_log,
- const NetLogSource& source) {
- // We're not actually expecting to send or receive any data, so use the
- // simplest SocketDataProvider with no data supplied.
- SocketDataProvider* data_provider = new StaticSocketDataProvider();
- data_providers_.push_back(base::WrapUnique(data_provider));
- std::unique_ptr<MockUDPClientSocket> socket(
- new MockUDPClientSocket(data_provider, net_log));
- return std::move(socket);
-}
-
-TestClientSocketFactory::~TestClientSocketFactory() = default;
-
-TEST_F(DnsSessionTest, AllocateFree) {
- std::unique_ptr<DnsSession::SocketLease> lease1, lease2;
-
- Initialize(2 /* num_servers */);
- EXPECT_TRUE(NoMoreEvents());
-
- lease1 = Allocate(0);
- EXPECT_TRUE(DidAllocate(0));
- EXPECT_TRUE(NoMoreEvents());
-
- lease2 = Allocate(1);
- EXPECT_TRUE(DidAllocate(1));
- EXPECT_TRUE(NoMoreEvents());
-
- lease1.reset();
- EXPECT_TRUE(DidFree(0));
- EXPECT_TRUE(NoMoreEvents());
-
- lease2.reset();
- EXPECT_TRUE(DidFree(1));
- EXPECT_TRUE(NoMoreEvents());
-}
-
-} // namespace
-
-} // namespace net
diff --git a/chromium/net/dns/dns_socket_allocator.cc b/chromium/net/dns/dns_socket_allocator.cc
new file mode 100644
index 00000000000..0c1c9245577
--- /dev/null
+++ b/chromium/net/dns/dns_socket_allocator.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/dns/dns_socket_allocator.h"
+
+#include "base/logging.h"
+#include "base/rand_util.h"
+#include "build/build_config.h"
+#include "net/base/address_list.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/log/net_log_source.h"
+#include "net/socket/client_socket_factory.h"
+#include "net/socket/datagram_client_socket.h"
+#include "net/socket/stream_socket.h"
+
+namespace net {
+
+namespace {
+
+// On Windows, can't request specific (random) ports, since that will trigger
+// firewall prompts, so request default ones (but experimentally, the OS appears
+// to still allocate random ports).
+#if defined(OS_WIN)
+const DatagramSocket::BindType kBindType = DatagramSocket::DEFAULT_BIND;
+#else
+const DatagramSocket::BindType kBindType = DatagramSocket::RANDOM_BIND;
+#endif
+
+} // namespace
+
+DnsSocketAllocator::DnsSocketAllocator(ClientSocketFactory* socket_factory,
+ std::vector<IPEndPoint> nameservers,
+ NetLog* net_log)
+ : socket_factory_(socket_factory),
+ net_log_(net_log),
+ nameservers_(std::move(nameservers)) {
+ DCHECK(socket_factory_);
+}
+
+DnsSocketAllocator::~DnsSocketAllocator() = default;
+
+std::unique_ptr<DatagramClientSocket>
+DnsSocketAllocator::CreateConnectedUdpSocket(size_t server_index,
+ int* out_connection_error) {
+ DCHECK_LT(server_index, nameservers_.size());
+ DCHECK(out_connection_error);
+
+ std::unique_ptr<DatagramClientSocket> socket;
+
+ NetLogSource no_source;
+ socket = socket_factory_->CreateDatagramClientSocket(kBindType, net_log_,
+ no_source);
+ DCHECK(socket);
+
+ *out_connection_error = socket->Connect(nameservers_[server_index]);
+ if (*out_connection_error != OK) {
+ DVLOG(1) << "Failed to connect socket: " << *out_connection_error;
+ socket.reset();
+ }
+
+ return socket;
+}
+
+std::unique_ptr<StreamSocket> DnsSocketAllocator::CreateTcpSocket(
+ size_t server_index,
+ const NetLogSource& source) {
+ DCHECK_LT(server_index, nameservers_.size());
+
+ return socket_factory_->CreateTransportClientSocket(
+ AddressList(nameservers_[server_index]), nullptr, net_log_, source);
+}
+
+} // namespace net
diff --git a/chromium/net/dns/dns_socket_allocator.h b/chromium/net/dns/dns_socket_allocator.h
new file mode 100644
index 00000000000..9b8f986ef5e
--- /dev/null
+++ b/chromium/net/dns/dns_socket_allocator.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_DNS_DNS_SOCKET_ALLOCATOR_H_
+#define NET_DNS_DNS_SOCKET_ALLOCATOR_H_
+
+#include <memory>
+#include <vector>
+
+#include "net/base/net_export.h"
+#include "net/base/rand_callback.h"
+
+namespace net {
+
+class ClientSocketFactory;
+class DatagramClientSocket;
+class IPEndPoint;
+class NetLog;
+struct NetLogSource;
+class StreamSocket;
+
+// Allocation logic for DNS UDP and TCP sockets.
+class NET_EXPORT_PRIVATE DnsSocketAllocator {
+ public:
+ DnsSocketAllocator(ClientSocketFactory* factory,
+ std::vector<IPEndPoint> nameservers,
+ NetLog* net_log);
+ ~DnsSocketAllocator();
+
+ DnsSocketAllocator(const DnsSocketAllocator&) = delete;
+ DnsSocketAllocator& operator=(const DnsSocketAllocator&) = delete;
+
+ // Creates a UDP client socket that is already connected to the nameserver
+ // referenced by |server_index| and sets |out_connection_error| to the result
+ // of the connection. On error connecting the socket, returns null.
+ std::unique_ptr<DatagramClientSocket> CreateConnectedUdpSocket(
+ size_t server_index,
+ int* out_connection_error);
+
+ // Creates a StreamSocket for TCP to the nameserver referenced by
+ // |server_index|. Does not connect the seocket.
+ std::unique_ptr<StreamSocket> CreateTcpSocket(size_t server_index,
+ const NetLogSource& source);
+
+ private:
+ ClientSocketFactory* const socket_factory_;
+ NetLog* const net_log_;
+ const std::vector<IPEndPoint> nameservers_;
+};
+
+} // namespace net
+
+#endif // NET_DNS_DNS_SOCKET_ALLOCATOR_H_
diff --git a/chromium/net/dns/dns_socket_allocator_unittest.cc b/chromium/net/dns/dns_socket_allocator_unittest.cc
new file mode 100644
index 00000000000..2b28ff32fee
--- /dev/null
+++ b/chromium/net/dns/dns_socket_allocator_unittest.cc
@@ -0,0 +1,82 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/dns/dns_socket_allocator.h"
+
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/log/net_log_source.h"
+#include "net/socket/client_socket_factory.h"
+#include "net/socket/datagram_client_socket.h"
+#include "net/socket/socket_test_util.h"
+#include "net/test/gtest_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+const IPEndPoint kEndpoint0(IPAddress(1, 2, 3, 4), 578);
+const IPEndPoint kEndpoint1(IPAddress(2, 3, 4, 5), 678);
+
+class DnsSocketAllocatorTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ allocator_ = std::make_unique<DnsSocketAllocator>(
+ &socket_factory_, nameservers_, nullptr /* net_log */);
+ }
+
+ MockClientSocketFactory socket_factory_;
+ std::vector<IPEndPoint> nameservers_ = {kEndpoint0, kEndpoint1};
+ std::unique_ptr<DnsSocketAllocator> allocator_;
+};
+
+TEST_F(DnsSocketAllocatorTest, CreateConnectedUdpSocket) {
+ // Prep socket factory for a single do-nothing socket.
+ StaticSocketDataProvider data_provider;
+ socket_factory_.AddSocketDataProvider(&data_provider);
+
+ int connection_error = ERR_FAILED;
+ std::unique_ptr<DatagramClientSocket> socket =
+ allocator_->CreateConnectedUdpSocket(1 /* server_index */,
+ &connection_error);
+
+ ASSERT_TRUE(socket);
+ EXPECT_THAT(connection_error, test::IsOk());
+
+ IPEndPoint peer_address;
+ ASSERT_THAT(socket->GetPeerAddress(&peer_address), test::IsOk());
+ EXPECT_EQ(peer_address, kEndpoint1);
+}
+
+TEST_F(DnsSocketAllocatorTest, CreateConnectedUdpSocket_ConnectError) {
+ // Prep socket factory for a single socket with connection failure.
+ MockConnect connect_data;
+ connect_data.result = ERR_INSUFFICIENT_RESOURCES;
+ StaticSocketDataProvider data_provider;
+ data_provider.set_connect_data(connect_data);
+ socket_factory_.AddSocketDataProvider(&data_provider);
+
+ int connection_error = OK;
+ std::unique_ptr<DatagramClientSocket> socket =
+ allocator_->CreateConnectedUdpSocket(0 /* server_index */,
+ &connection_error);
+
+ EXPECT_FALSE(socket);
+ EXPECT_THAT(connection_error, test::IsError(ERR_INSUFFICIENT_RESOURCES));
+}
+
+TEST_F(DnsSocketAllocatorTest, CreateTcpSocket) {
+ // Prep socket factory for a single do-nothing socket.
+ StaticSocketDataProvider data_provider;
+ socket_factory_.AddSocketDataProvider(&data_provider);
+
+ std::unique_ptr<StreamSocket> socket =
+ allocator_->CreateTcpSocket(1 /* server_index */, NetLogSource());
+
+ EXPECT_TRUE(socket);
+}
+
+} // namespace
+} // namespace net
diff --git a/chromium/net/dns/dns_socket_pool.cc b/chromium/net/dns/dns_socket_pool.cc
deleted file mode 100644
index 177c79914b6..00000000000
--- a/chromium/net/dns/dns_socket_pool.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/dns/dns_socket_pool.h"
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/rand_util.h"
-#include "net/base/address_list.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "net/log/net_log_source.h"
-#include "net/socket/client_socket_factory.h"
-#include "net/socket/datagram_client_socket.h"
-#include "net/socket/stream_socket.h"
-
-namespace net {
-
-namespace {
-
-// When we initialize the SocketPool, we allocate kInitialPoolSize sockets.
-// When we allocate a socket, we ensure we have at least kAllocateMinSize
-// sockets to choose from. Freed sockets are not retained.
-
-// On Windows, we can't request specific (random) ports, since that will
-// trigger firewall prompts, so request default ones, but keep a pile of
-// them. Everywhere else, request fresh, random ports each time.
-#if defined(OS_WIN)
-const DatagramSocket::BindType kBindType = DatagramSocket::DEFAULT_BIND;
-const size_t kInitialPoolSize = 256;
-const size_t kAllocateMinSize = 256;
-#else
-const DatagramSocket::BindType kBindType = DatagramSocket::RANDOM_BIND;
-const size_t kInitialPoolSize = 0;
-const size_t kAllocateMinSize = 1;
-#endif
-
-} // namespace
-
-DnsSocketPool::DnsSocketPool(ClientSocketFactory* socket_factory,
- const RandIntCallback& rand_int_callback)
- : socket_factory_(socket_factory),
- rand_int_callback_(rand_int_callback),
- net_log_(nullptr),
- nameservers_(nullptr),
- initialized_(false) {}
-
-void DnsSocketPool::InitializeInternal(
- const std::vector<IPEndPoint>* nameservers,
- NetLog* net_log) {
- DCHECK(nameservers);
- DCHECK(!initialized_);
-
- net_log_ = net_log;
- nameservers_ = nameservers;
- initialized_ = true;
-}
-
-std::unique_ptr<StreamSocket> DnsSocketPool::CreateTCPSocket(
- size_t server_index,
- const NetLogSource& source) {
- DCHECK_LT(server_index, nameservers_->size());
-
- return std::unique_ptr<StreamSocket>(
- socket_factory_->CreateTransportClientSocket(
- AddressList((*nameservers_)[server_index]), nullptr, net_log_,
- source));
-}
-
-std::unique_ptr<DatagramClientSocket> DnsSocketPool::CreateConnectedSocket(
- size_t server_index) {
- DCHECK_LT(server_index, nameservers_->size());
-
- std::unique_ptr<DatagramClientSocket> socket;
-
- NetLogSource no_source;
- socket = socket_factory_->CreateDatagramClientSocket(kBindType, net_log_,
- no_source);
-
- if (socket.get()) {
- int rv = socket->Connect((*nameservers_)[server_index]);
- if (rv != OK) {
- DVLOG(1) << "Failed to connect socket: " << rv;
- socket.reset();
- }
- } else {
- DVLOG(1) << "Failed to create socket.";
- }
-
- return socket;
-}
-
-int DnsSocketPool::GetRandomInt(int min, int max) {
- return rand_int_callback_.Run(min, max);
-}
-
-class NullDnsSocketPool : public DnsSocketPool {
- public:
- NullDnsSocketPool(ClientSocketFactory* factory,
- const RandIntCallback& rand_int_callback)
- : DnsSocketPool(factory, rand_int_callback) {}
-
- void Initialize(const std::vector<IPEndPoint>* nameservers,
- NetLog* net_log) override {
- InitializeInternal(nameservers, net_log);
- }
-
- std::unique_ptr<DatagramClientSocket> AllocateSocket(
- size_t server_index) override {
- return CreateConnectedSocket(server_index);
- }
-
- void FreeSocket(size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket) override {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NullDnsSocketPool);
-};
-
-// static
-std::unique_ptr<DnsSocketPool> DnsSocketPool::CreateNull(
- ClientSocketFactory* factory,
- const RandIntCallback& rand_int_callback) {
- return std::unique_ptr<DnsSocketPool>(
- new NullDnsSocketPool(factory, rand_int_callback));
-}
-
-class DefaultDnsSocketPool : public DnsSocketPool {
- public:
- DefaultDnsSocketPool(ClientSocketFactory* factory,
- const RandIntCallback& rand_int_callback)
- : DnsSocketPool(factory, rand_int_callback) {}
-
- ~DefaultDnsSocketPool() override;
-
- void Initialize(const std::vector<IPEndPoint>* nameservers,
- NetLog* net_log) override;
-
- std::unique_ptr<DatagramClientSocket> AllocateSocket(
- size_t server_index) override;
-
- void FreeSocket(size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket) override;
-
- private:
- void FillPool(size_t server_index, size_t size);
-
- typedef std::vector<std::unique_ptr<DatagramClientSocket>> SocketVector;
-
- std::vector<SocketVector> pools_;
-
- DISALLOW_COPY_AND_ASSIGN(DefaultDnsSocketPool);
-};
-
-DnsSocketPool::~DnsSocketPool() = default;
-
-// static
-std::unique_ptr<DnsSocketPool> DnsSocketPool::CreateDefault(
- ClientSocketFactory* factory,
- const RandIntCallback& rand_int_callback) {
- return std::unique_ptr<DnsSocketPool>(
- new DefaultDnsSocketPool(factory, rand_int_callback));
-}
-
-void DefaultDnsSocketPool::Initialize(
- const std::vector<IPEndPoint>* nameservers,
- NetLog* net_log) {
- InitializeInternal(nameservers, net_log);
-
- DCHECK(pools_.empty());
- const size_t num_servers = nameservers->size();
- pools_.resize(num_servers);
- for (size_t server_index = 0; server_index < num_servers; ++server_index)
- FillPool(server_index, kInitialPoolSize);
-}
-
-DefaultDnsSocketPool::~DefaultDnsSocketPool() = default;
-
-std::unique_ptr<DatagramClientSocket> DefaultDnsSocketPool::AllocateSocket(
- size_t server_index) {
- DCHECK_LT(server_index, pools_.size());
- SocketVector& pool = pools_[server_index];
-
- FillPool(server_index, kAllocateMinSize);
- if (pool.size() == 0) {
- DVLOG(1) << "No DNS sockets available in pool " << server_index << "!";
- return std::unique_ptr<DatagramClientSocket>();
- }
-
- if (pool.size() < kAllocateMinSize) {
- DVLOG(1) << "Low DNS port entropy: wanted " << kAllocateMinSize
- << " sockets to choose from, but only have " << pool.size()
- << " in pool " << server_index << ".";
- }
-
- size_t socket_index = GetRandomInt(0, pool.size() - 1);
- std::unique_ptr<DatagramClientSocket> socket = std::move(pool[socket_index]);
- pool[socket_index] = std::move(pool.back());
- pool.pop_back();
-
- return socket;
-}
-
-void DefaultDnsSocketPool::FreeSocket(
- size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket) {
- DCHECK_LT(server_index, pools_.size());
-}
-
-void DefaultDnsSocketPool::FillPool(size_t server_index, size_t size) {
- SocketVector& pool = pools_[server_index];
-
- for (size_t pool_index = pool.size(); pool_index < size; ++pool_index) {
- std::unique_ptr<DatagramClientSocket> socket =
- CreateConnectedSocket(server_index);
- if (!socket)
- break;
- pool.push_back(std::move(socket));
- }
-}
-
-} // namespace net
diff --git a/chromium/net/dns/dns_socket_pool.h b/chromium/net/dns/dns_socket_pool.h
deleted file mode 100644
index 054787a48b8..00000000000
--- a/chromium/net/dns/dns_socket_pool.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef NET_DNS_DNS_SOCKET_POOL_H_
-#define NET_DNS_DNS_SOCKET_POOL_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "net/base/net_export.h"
-#include "net/base/rand_callback.h"
-
-namespace net {
-
-class ClientSocketFactory;
-class DatagramClientSocket;
-class IPEndPoint;
-class NetLog;
-struct NetLogSource;
-class StreamSocket;
-
-// A DnsSocketPool is an abstraction layer around a ClientSocketFactory that
-// allows preallocation, reuse, or other strategies to manage sockets connected
-// to DNS servers.
-class NET_EXPORT_PRIVATE DnsSocketPool {
- public:
- virtual ~DnsSocketPool();
-
- // Creates a DnsSocketPool that implements the default strategy for managing
- // sockets. (This varies by platform; see DnsSocketPoolImpl in
- // dns_socket_pool.cc for details.)
- static std::unique_ptr<DnsSocketPool> CreateDefault(
- ClientSocketFactory* factory,
- const RandIntCallback& rand_int_callback);
-
- // Creates a DnsSocketPool that implements a "null" strategy -- no sockets are
- // preallocated, allocation requests are satisfied by calling the factory
- // directly, and returned sockets are deleted immediately.
- static std::unique_ptr<DnsSocketPool> CreateNull(
- ClientSocketFactory* factory,
- const RandIntCallback& rand_int_callback);
-
- // Initializes the DnsSocketPool. |nameservers| is the list of nameservers
- // for which the DnsSocketPool will manage sockets; |net_log| is the NetLog
- // used when constructing sockets with the factory.
- //
- // Initialize may not be called more than once, and must be called before
- // calling AllocateSocket or FreeSocket.
- virtual void Initialize(
- const std::vector<IPEndPoint>* nameservers,
- NetLog* net_log) = 0;
-
- // Allocates a socket that is already connected to the nameserver referenced
- // by |server_index|. May return a std::unique_ptr to NULL if no sockets are
- // available to reuse and the factory fails to produce a socket (or produces
- // one on which Connect fails).
- virtual std::unique_ptr<DatagramClientSocket> AllocateSocket(
- size_t server_index) = 0;
-
- // Frees a socket allocated by AllocateSocket. |server_index| must be the
- // same index passed to AllocateSocket.
- virtual void FreeSocket(size_t server_index,
- std::unique_ptr<DatagramClientSocket> socket) = 0;
-
- // Creates a StreamSocket from the factory for a transaction over TCP. These
- // sockets are not pooled.
- std::unique_ptr<StreamSocket> CreateTCPSocket(size_t server_index,
- const NetLogSource& source);
-
- protected:
- DnsSocketPool(ClientSocketFactory* socket_factory,
- const RandIntCallback& rand_int_callback);
-
- void InitializeInternal(
- const std::vector<IPEndPoint>* nameservers,
- NetLog* net_log);
-
- std::unique_ptr<DatagramClientSocket> CreateConnectedSocket(
- size_t server_index);
-
- // Returns a random int in the specified range.
- int GetRandomInt(int min, int max);
-
- private:
- ClientSocketFactory* socket_factory_;
- const RandIntCallback rand_int_callback_;
- NetLog* net_log_;
- const std::vector<IPEndPoint>* nameservers_;
- bool initialized_;
-
- DISALLOW_COPY_AND_ASSIGN(DnsSocketPool);
-};
-
-} // namespace net
-
-#endif // NET_DNS_DNS_SOCKET_POOL_H_
diff --git a/chromium/net/dns/dns_socket_pool_unittest.cc b/chromium/net/dns/dns_socket_pool_unittest.cc
deleted file mode 100644
index 2138518e5a1..00000000000
--- a/chromium/net/dns/dns_socket_pool_unittest.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/dns/dns_socket_pool.h"
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/memory/weak_ptr.h"
-#include "net/base/rand_callback.h"
-#include "net/socket/client_socket_factory.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace {
-
-class DummyObject {
- public:
- DummyObject() {}
-
- base::WeakPtr<DummyObject> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
-
- bool HasWeakPtrs() const { return weak_factory_.HasWeakPtrs(); }
-
- private:
- base::WeakPtrFactory<DummyObject> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(DummyObject);
-};
-
-class DummyRandIntCallback {
- public:
- DummyRandIntCallback() = default;
-
- RandIntCallback MakeCallback() {
- return base::Bind(&DummyRandIntCallback::GetRandInt, dummy_.GetWeakPtr());
- }
-
- bool HasRefs() const { return dummy_.HasWeakPtrs(); }
-
- private:
- static int GetRandInt(base::WeakPtr<DummyObject> dummy, int from, int to) {
- // Chosen by fair dice roll. Guaranteed to be random.
- return 4;
- }
-
- DummyObject dummy_;
-
- DISALLOW_COPY_AND_ASSIGN(DummyRandIntCallback);
-};
-
-// Since the below tests rely upon it, make sure that DummyRandIntCallback
-// can reliably tell whether there are other refs to the callback it returns.
-
-// A const reference to the callback shouldn't keep the callback referenced.
-TEST(DummyRandIntCallbackTest, Referenced) {
- DummyRandIntCallback dummy;
-
- RandIntCallback original = dummy.MakeCallback();
- EXPECT_TRUE(dummy.HasRefs());
- const RandIntCallback& reference = original;
- EXPECT_TRUE(dummy.HasRefs());
-
- EXPECT_EQ(4, reference.Run(0, 6));
-
- original.Reset();
- EXPECT_FALSE(dummy.HasRefs());
-}
-
-// A copy of the callback should keep the callback referenced.
-TEST(DummyRandIntCallbackTest, Copied) {
- DummyRandIntCallback dummy;
-
- RandIntCallback original = dummy.MakeCallback();
- EXPECT_TRUE(dummy.HasRefs());
- RandIntCallback copy = original;
- EXPECT_TRUE(dummy.HasRefs());
-
- EXPECT_EQ(4, copy.Run(0, 6));
-
- original.Reset();
- EXPECT_TRUE(dummy.HasRefs());
-}
-
-class DnsSocketPoolTest : public ::testing::Test {
- protected:
- DummyRandIntCallback dummy_;
- std::unique_ptr<DnsSocketPool> pool_;
-};
-
-// Make sure that the DnsSocketPools returned by CreateDefault and CreateNull
-// both retain (by copying the RandIntCallback object, instead of taking a
-// reference) the RandIntCallback used for creating sockets.
-
-TEST_F(DnsSocketPoolTest, DefaultCopiesCallback) {
- pool_ = DnsSocketPool::CreateDefault(ClientSocketFactory::GetDefaultFactory(),
- dummy_.MakeCallback());
- EXPECT_TRUE(dummy_.HasRefs());
-}
-
-TEST_F(DnsSocketPoolTest, NullCopiesCallback) {
- pool_ = DnsSocketPool::CreateNull(ClientSocketFactory::GetDefaultFactory(),
- dummy_.MakeCallback());
- EXPECT_TRUE(dummy_.HasRefs());
-}
-
-} // namespace
-} // namespace net
diff --git a/chromium/net/dns/dns_test_util.cc b/chromium/net/dns/dns_test_util.cc
index efcec21579d..0ced88c66c3 100644
--- a/chromium/net/dns/dns_test_util.cc
+++ b/chromium/net/dns/dns_test_util.cc
@@ -18,6 +18,7 @@
#include "net/dns/dns_hosts.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_session.h"
+#include "net/dns/dns_socket_allocator.h"
#include "net/dns/dns_util.h"
#include "net/dns/resolve_context.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -725,10 +726,13 @@ scoped_refptr<DnsSession> MockDnsClient::BuildSession() {
auto null_random_callback =
base::BindRepeating([](int, int) -> int { IMMEDIATE_CRASH(); });
+ auto socket_allocator = std::make_unique<DnsSocketAllocator>(
+ &socket_factory_, effective_config_.value().nameservers,
+ nullptr /* net_log */);
+
return base::MakeRefCounted<DnsSession>(
- effective_config_.value(),
- DnsSocketPool::CreateNull(&socket_factory_, null_random_callback),
- null_random_callback, nullptr /* NetLog */);
+ effective_config_.value(), std::move(socket_allocator),
+ null_random_callback, nullptr /* net_log */);
}
} // namespace net
diff --git a/chromium/net/dns/dns_test_util.h b/chromium/net/dns/dns_test_util.h
index 40c619976a0..3944541e7dc 100644
--- a/chromium/net/dns/dns_test_util.h
+++ b/chromium/net/dns/dns_test_util.h
@@ -164,7 +164,7 @@ static const int kT3TTL = 0x00000015;
static const unsigned kT3RecordCount = base::size(kT3IpAddresses) + 3;
//-----------------------------------------------------------------------------
-// Query/response set for www.gstatic.com, ID is fixed to 4.
+// Query/response set for www.gstatic.com, ID is fixed to 0.
static const char kT4HostName[] = "www.gstatic.com";
static const uint16_t kT4Qtype = dns_protocol::kTypeA;
static const char kT4DnsName[] = {0x03, 'w', 'w', 'w', 0x07, 'g',
@@ -173,7 +173,7 @@ static const char kT4DnsName[] = {0x03, 'w', 'w', 'w', 0x07, 'g',
static const size_t kT4QuerySize = 33;
static const uint8_t kT4ResponseDatagram[] = {
// response contains the following IP addresses: 172.217.6.195.
- 0x00, 0x04, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x07, 0x67, 0x73, 0x74,
0x61, 0x74, 0x69, 0x63, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00,
0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
diff --git a/chromium/net/dns/dns_transaction.cc b/chromium/net/dns/dns_transaction.cc
index 60e97bf23f3..e1443c48bd2 100644
--- a/chromium/net/dns/dns_transaction.cc
+++ b/chromium/net/dns/dns_transaction.cc
@@ -48,6 +48,7 @@
#include "net/dns/dns_response.h"
#include "net/dns/dns_server_iterator.h"
#include "net/dns/dns_session.h"
+#include "net/dns/dns_socket_allocator.h"
#include "net/dns/dns_udp_tracker.h"
#include "net/dns/dns_util.h"
#include "net/dns/public/dns_over_https_server_config.h"
@@ -187,12 +188,12 @@ class DnsAttempt {
class DnsUDPAttempt : public DnsAttempt {
public:
DnsUDPAttempt(size_t server_index,
- std::unique_ptr<DnsSession::SocketLease> socket_lease,
+ std::unique_ptr<DatagramClientSocket> socket,
std::unique_ptr<DnsQuery> query,
DnsUdpTracker* udp_tracker)
: DnsAttempt(server_index),
next_state_(STATE_NONE),
- socket_lease_(std::move(socket_lease)),
+ socket_(std::move(socket)),
query_(std::move(query)),
udp_tracker_(udp_tracker) {}
@@ -205,7 +206,7 @@ class DnsUDPAttempt : public DnsAttempt {
next_state_ = STATE_SEND_QUERY;
IPEndPoint local_address;
- if (socket_lease_->socket()->GetLocalAddress(&local_address) == OK)
+ if (socket_->GetLocalAddress(&local_address) == OK)
udp_tracker_->RecordQuery(local_address.port(), query_->id());
return DoLoop(OK);
@@ -219,7 +220,7 @@ class DnsUDPAttempt : public DnsAttempt {
}
const NetLogWithSource& GetSocketNetLog() const override {
- return socket_lease_->socket()->NetLog();
+ return socket_->NetLog();
}
private:
@@ -231,8 +232,6 @@ class DnsUDPAttempt : public DnsAttempt {
STATE_NONE,
};
- DatagramClientSocket* socket() { return socket_lease_->socket(); }
-
int DoLoop(int result) {
CHECK_NE(STATE_NONE, next_state_);
int rv = result;
@@ -270,7 +269,7 @@ class DnsUDPAttempt : public DnsAttempt {
int DoSendQuery() {
next_state_ = STATE_SEND_QUERY_COMPLETE;
- return socket()->Write(
+ return socket_->Write(
query_->io_buffer(), query_->io_buffer()->size(),
base::BindOnce(&DnsUDPAttempt::OnIOComplete, base::Unretained(this)),
kTrafficAnnotation);
@@ -292,7 +291,7 @@ class DnsUDPAttempt : public DnsAttempt {
int DoReadResponse() {
next_state_ = STATE_READ_RESPONSE_COMPLETE;
response_ = std::make_unique<DnsResponse>();
- return socket()->Read(
+ return socket_->Read(
response_->io_buffer(), response_->io_buffer_size(),
base::BindOnce(&DnsUDPAttempt::OnIOComplete, base::Unretained(this)));
}
@@ -328,7 +327,7 @@ class DnsUDPAttempt : public DnsAttempt {
State next_state_;
base::TimeTicks start_time_;
- std::unique_ptr<DnsSession::SocketLease> socket_lease_;
+ std::unique_ptr<DatagramClientSocket> socket_;
std::unique_ptr<DnsQuery> query_;
// Should be owned by the DnsSession, to which the transaction should own a
@@ -579,13 +578,13 @@ void ConstructDnsHTTPAttempt(DnsSession* session,
RequestPriority request_priority) {
DCHECK(url_request_context);
- uint16_t id = session->NextQueryId();
std::unique_ptr<DnsQuery> query;
if (attempts->empty()) {
- query.reset(new DnsQuery(id, hostname, qtype, opt_rdata,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128));
+ query =
+ std::make_unique<DnsQuery>(0 /* id */, hostname, qtype, opt_rdata,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
} else {
- query = attempts->at(0)->GetQuery()->CloneWithNewId(id);
+ query = std::make_unique<DnsQuery>(*attempts->at(0)->GetQuery());
}
DCHECK_LT(doh_server_index, session->config().dns_over_https_servers.size());
@@ -1056,7 +1055,7 @@ class DnsTransactionImpl : public DnsTransaction,
net_log_(net_log),
qnames_initial_size_(0),
attempts_count_(0),
- had_tcp_attempt_(false),
+ had_tcp_retry_(false),
resolve_context_(resolve_context),
request_priority_(DEFAULT_PRIORITY) {
DCHECK(session_.get());
@@ -1112,6 +1111,7 @@ class DnsTransactionImpl : public DnsTransaction,
private:
// Wrapper for the result of a DnsUDPAttempt.
struct AttemptResult {
+ AttemptResult() = default;
AttemptResult(int rv, const DnsAttempt* attempt)
: rv(rv), attempt(attempt) {}
@@ -1119,6 +1119,15 @@ class DnsTransactionImpl : public DnsTransaction,
const DnsAttempt* attempt;
};
+ // Used in UMA (DNS.AttemptType). Do not renumber or remove values.
+ enum class DnsAttemptType {
+ kUdp = 0,
+ kTcpLowEntropy = 1,
+ kTcpTruncationRetry = 2,
+ kHttp = 3,
+ kMaxValue = kHttp,
+ };
+
// Prepares |qnames_| according to the DnsConfig.
int PrepareSearch() {
const DnsConfig& config = session_->config();
@@ -1194,23 +1203,24 @@ class DnsTransactionImpl : public DnsTransaction,
std::move(callback_).Run(this, result.rv, response, doh_provider_id);
}
+ void RecordAttemptUma(DnsAttemptType attempt_type) {
+ UMA_HISTOGRAM_ENUMERATION("Net.DNS.DnsTransaction.AttemptType",
+ attempt_type);
+ }
+
AttemptResult MakeAttempt() {
DnsConfig config = session_->config();
if (secure_) {
DCHECK_GT(config.dns_over_https_servers.size(), 0u);
+ RecordAttemptUma(DnsAttemptType::kHttp);
return MakeHTTPAttempt();
}
DCHECK_GT(config.nameservers.size(), 0u);
- return MakeUDPAttempt();
+ return MakeClassicDnsAttempt();
}
- // Makes another attempt at the current name, |qnames_.front()|, using the
- // next nameserver.
- AttemptResult MakeUDPAttempt() {
- DCHECK(!secure_);
- size_t attempt_number = attempts_.size();
-
+ AttemptResult MakeClassicDnsAttempt() {
uint16_t id = session_->NextQueryId();
std::unique_ptr<DnsQuery> query;
if (attempts_.empty()) {
@@ -1219,22 +1229,54 @@ class DnsTransactionImpl : public DnsTransaction,
query = attempts_[0]->GetQuery()->CloneWithNewId(id);
}
DCHECK(dns_server_iterator_->AttemptAvailable());
- size_t non_doh_server_index = dns_server_iterator_->GetNextAttemptIndex();
+ size_t server_index = dns_server_iterator_->GetNextAttemptIndex();
+
+ size_t attempt_number = attempts_.size();
+ AttemptResult result;
+ if (session_->udp_tracker()->low_entropy()) {
+ result = MakeTcpAttempt(server_index, std::move(query));
+ RecordAttemptUma(DnsAttemptType::kTcpLowEntropy);
+ } else {
+ result = MakeUdpAttempt(server_index, std::move(query));
+ RecordAttemptUma(DnsAttemptType::kUdp);
+ }
+
+ if (result.rv == ERR_IO_PENDING) {
+ base::TimeDelta timeout = resolve_context_->NextClassicTimeout(
+ server_index, attempt_number, session_.get());
+ timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout);
+ }
+
+ return result;
+ }
+
+ // Makes another attempt at the current name, |qnames_.front()|, using the
+ // next nameserver.
+ AttemptResult MakeUdpAttempt(size_t server_index,
+ std::unique_ptr<DnsQuery> query) {
+ DCHECK(!secure_);
+ DCHECK(!session_->udp_tracker()->low_entropy());
+ size_t attempt_number = attempts_.size();
- std::unique_ptr<DnsSession::SocketLease> lease =
- session_->AllocateSocket(non_doh_server_index, net_log_.source());
+ int connection_error = OK;
+ std::unique_ptr<DatagramClientSocket> socket =
+ session_->socket_allocator()->CreateConnectedUdpSocket(
+ server_index, &connection_error);
- bool got_socket = !!lease.get();
+ bool got_socket = !!socket.get();
+ DCHECK_EQ(got_socket, connection_error == OK);
DnsUDPAttempt* attempt =
- new DnsUDPAttempt(non_doh_server_index, std::move(lease),
- std::move(query), session_->udp_tracker());
+ new DnsUDPAttempt(server_index, std::move(socket), std::move(query),
+ session_->udp_tracker());
attempts_.push_back(base::WrapUnique(attempt));
++attempts_count_;
- if (!got_socket)
+ if (!got_socket) {
+ session_->udp_tracker()->RecordConnectionError(connection_error);
return AttemptResult(ERR_CONNECTION_REFUSED, nullptr);
+ }
net_log_.AddEventReferencingSource(NetLogEventType::DNS_TRANSACTION_ATTEMPT,
attempt->GetSocketNetLog().source());
@@ -1242,11 +1284,6 @@ class DnsTransactionImpl : public DnsTransaction,
int rv = attempt->Start(base::BindOnce(
&DnsTransactionImpl::OnAttemptComplete, base::Unretained(this),
attempt_number, true /* record_rtt */, base::TimeTicks::Now()));
- if (rv == ERR_IO_PENDING) {
- base::TimeDelta timeout = resolve_context_->NextClassicTimeout(
- non_doh_server_index, attempt_number, session_.get());
- timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout);
- }
return AttemptResult(rv, attempt);
}
@@ -1272,25 +1309,44 @@ class DnsTransactionImpl : public DnsTransaction,
return AttemptResult(rv, attempts_.back().get());
}
- AttemptResult MakeTCPAttempt(const DnsAttempt* previous_attempt) {
- DCHECK(!secure_);
+ AttemptResult RetryUdpAttemptAsTcp(const DnsAttempt* previous_attempt) {
DCHECK(previous_attempt);
- DCHECK(!had_tcp_attempt_);
-
- size_t server_index = previous_attempt->server_index();
+ DCHECK(!had_tcp_retry_);
- std::unique_ptr<StreamSocket> socket(
- session_->CreateTCPSocket(server_index, net_log_.source()));
+ // Only allow a single TCP retry per query.
+ had_tcp_retry_ = true;
- // TODO(szym): Reuse the same id to help the server?
- uint16_t id = session_->NextQueryId();
+ size_t server_index = previous_attempt->server_index();
+ // Use a new query ID instead of reusing the same one from the UDP attempt.
+ // RFC5452, section 9.2 requires an unpredictable ID for all outgoing
+ // queries, with no distinction made between queries made via TCP or UDP.
std::unique_ptr<DnsQuery> query =
- previous_attempt->GetQuery()->CloneWithNewId(id);
+ previous_attempt->GetQuery()->CloneWithNewId(session_->NextQueryId());
- // Cancel all attempts that have not received a response, no point waiting
- // on them.
+ // Cancel all attempts that have not received a response, as they will
+ // likely similarly require TCP retry.
ClearAttempts(nullptr);
+ AttemptResult result = MakeTcpAttempt(server_index, std::move(query));
+ RecordAttemptUma(DnsAttemptType::kTcpTruncationRetry);
+
+ if (result.rv == ERR_IO_PENDING) {
+ // On TCP upgrade, use 2x the upgraded timeout.
+ base::TimeDelta timeout = timer_.GetCurrentDelay() * 2;
+ timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout);
+ }
+
+ return result;
+ }
+
+ AttemptResult MakeTcpAttempt(size_t server_index,
+ std::unique_ptr<DnsQuery> query) {
+ DCHECK(!secure_);
+
+ std::unique_ptr<StreamSocket> socket(
+ session_->socket_allocator()->CreateTcpSocket(server_index,
+ net_log_.source()));
+
unsigned attempt_number = attempts_.size();
DnsTCPAttempt* attempt =
@@ -1298,7 +1354,6 @@ class DnsTransactionImpl : public DnsTransaction,
attempts_.push_back(base::WrapUnique(attempt));
++attempts_count_;
- had_tcp_attempt_ = true;
net_log_.AddEventReferencingSource(
NetLogEventType::DNS_TRANSACTION_TCP_ATTEMPT,
@@ -1307,11 +1362,6 @@ class DnsTransactionImpl : public DnsTransaction,
int rv = attempt->Start(base::BindOnce(
&DnsTransactionImpl::OnAttemptComplete, base::Unretained(this),
attempt_number, false /* record_rtt */, base::TimeTicks::Now()));
- if (rv == ERR_IO_PENDING) {
- // Custom timeout for TCP attempt.
- base::TimeDelta timeout = timer_.GetCurrentDelay() * 2;
- timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout);
- }
return AttemptResult(rv, attempt);
}
@@ -1322,7 +1372,7 @@ class DnsTransactionImpl : public DnsTransaction,
"qname", dotted_qname);
attempts_.clear();
- had_tcp_attempt_ = false;
+ had_tcp_retry_ = false;
if (secure_) {
dns_server_iterator_ = resolve_context_->GetDohIterator(
session_->config(), secure_dns_mode_, session_.get());
@@ -1365,7 +1415,7 @@ class DnsTransactionImpl : public DnsTransaction,
}
bool MoreAttemptsAllowed() const {
- if (had_tcp_attempt_)
+ if (had_tcp_retry_)
return false;
return dns_server_iterator_->AttemptAvailable();
@@ -1419,7 +1469,7 @@ class DnsTransactionImpl : public DnsTransaction,
}
break;
case ERR_DNS_SERVER_REQUIRES_TCP:
- result = MakeTCPAttempt(result.attempt);
+ result = RetryUdpAttemptAsTcp(result.attempt);
break;
case ERR_BLOCKED_BY_CLIENT:
net_log_.EndEventWithNetErrorCode(
@@ -1493,7 +1543,9 @@ class DnsTransactionImpl : public DnsTransaction,
std::vector<std::unique_ptr<DnsAttempt>> attempts_;
// Count of attempts, not reset when |attempts_| vector is cleared.
int attempts_count_;
- bool had_tcp_attempt_;
+
+ // Records when an attempt was retried via TCP due to a truncation error.
+ bool had_tcp_retry_;
// Iterator to get the index of the DNS server for each search query.
std::unique_ptr<DnsServerIterator> dns_server_iterator_;
diff --git a/chromium/net/dns/dns_transaction_unittest.cc b/chromium/net/dns/dns_transaction_unittest.cc
index 17f6bf62e72..274fea28a86 100644
--- a/chromium/net/dns/dns_transaction_unittest.cc
+++ b/chromium/net/dns/dns_transaction_unittest.cc
@@ -28,13 +28,14 @@
#include "net/base/port_util.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/url_util.h"
-#include "net/cookies/cookie_inclusion_status.h"
+#include "net/cookies/cookie_access_result.h"
#include "net/cookies/cookie_util.h"
#include "net/dns/dns_config.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_response.h"
#include "net/dns/dns_server_iterator.h"
#include "net/dns/dns_session.h"
+#include "net/dns/dns_socket_allocator.h"
#include "net/dns/dns_test_util.h"
#include "net/dns/dns_util.h"
#include "net/dns/public/dns_over_https_server_config.h"
@@ -251,8 +252,19 @@ class TestSocketFactory : public MockClientSocketFactory {
return std::unique_ptr<DatagramClientSocket>(
new FailingUDPClientSocket(&empty_data_, net_log));
}
+
SocketDataProvider* data_provider = mock_data().GetNext();
- return std::make_unique<TestUDPClientSocket>(this, data_provider, net_log);
+ auto socket =
+ std::make_unique<TestUDPClientSocket>(this, data_provider, net_log);
+
+ // Even using DEFAULT_BIND, actual sockets have been measured to very rarely
+ // repeat the same source port multiple times in a row. Need to mimic that
+ // functionality here, so DnsUdpTracker doesn't misdiagnose repeated port
+ // as low entropy.
+ if (diverse_source_ports_)
+ socket->set_source_port(next_source_port_++);
+
+ return socket;
}
void OnConnect(const IPEndPoint& endpoint) {
@@ -271,9 +283,11 @@ class TestSocketFactory : public MockClientSocketFactory {
std::vector<RemoteNameserver> remote_endpoints_;
bool fail_next_socket_;
+ bool diverse_source_ports_ = true;
private:
StaticSocketDataProvider empty_data_;
+ uint16_t next_source_port_ = 123;
DISALLOW_COPY_AND_ASSIGN(TestSocketFactory);
};
@@ -573,7 +587,12 @@ class URLRequestMockDohJob : public URLRequestJob, public AsyncSocket {
class DnsTransactionTestBase : public testing::Test {
public:
DnsTransactionTestBase() = default;
- ~DnsTransactionTestBase() override = default;
+
+ ~DnsTransactionTestBase() override {
+ // All queued transaction IDs should be used by a transaction calling
+ // GetNextId().
+ CHECK(transaction_ids_.empty());
+ }
// Generates |nameservers| for DnsConfig.
void ConfigureNumServers(size_t num_servers) {
@@ -620,18 +639,21 @@ class DnsTransactionTestBase : public testing::Test {
socket_factory_.reset(new TestSocketFactory());
session_ = new DnsSession(
config_,
- DnsSocketPool::CreateNull(socket_factory_.get(),
- base::Bind(base::RandInt)),
- base::Bind(&DnsTransactionTestBase::GetNextId, base::Unretained(this)),
+ std::make_unique<DnsSocketAllocator>(
+ socket_factory_.get(), config_.nameservers, nullptr /* net_log */),
+ base::BindRepeating(&DnsTransactionTestBase::GetNextId,
+ base::Unretained(this)),
nullptr /* NetLog */);
resolve_context_->InvalidateCachesAndPerSessionData(
session_.get(), false /* network_change */);
transaction_factory_ = DnsTransactionFactory::CreateFactory(session_.get());
}
- void AddSocketData(std::unique_ptr<DnsSocketData> data) {
+ void AddSocketData(std::unique_ptr<DnsSocketData> data,
+ bool enqueue_transaction_id = true) {
CHECK(socket_factory_.get());
- transaction_ids_.push_back(data->query_id());
+ if (enqueue_transaction_id)
+ transaction_ids_.push_back(data->query_id());
socket_factory_->AddSocketDataProvider(data->GetProvider());
socket_data_.push_back(std::move(data));
}
@@ -648,12 +670,13 @@ class DnsTransactionTestBase : public testing::Test {
Transport transport,
const OptRecordRdata* opt_rdata = nullptr,
DnsQuery::PaddingStrategy padding_strategy =
- DnsQuery::PaddingStrategy::NONE) {
+ DnsQuery::PaddingStrategy::NONE,
+ bool enqueue_transaction_id = true) {
CHECK(socket_factory_.get());
std::unique_ptr<DnsSocketData> data(new DnsSocketData(
id, dotted_name, qtype, mode, transport, opt_rdata, padding_strategy));
data->AddResponseData(response_data, response_length, mode);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), enqueue_transaction_id);
}
void AddQueryAndErrorResponse(uint16_t id,
@@ -664,12 +687,13 @@ class DnsTransactionTestBase : public testing::Test {
Transport transport,
const OptRecordRdata* opt_rdata = nullptr,
DnsQuery::PaddingStrategy padding_strategy =
- DnsQuery::PaddingStrategy::NONE) {
+ DnsQuery::PaddingStrategy::NONE,
+ bool enqueue_transaction_id = true) {
CHECK(socket_factory_.get());
std::unique_ptr<DnsSocketData> data(new DnsSocketData(
id, dotted_name, qtype, mode, transport, opt_rdata, padding_strategy));
data->AddReadError(error, mode);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), enqueue_transaction_id);
}
void AddAsyncQueryAndResponse(uint16_t id,
@@ -693,33 +717,37 @@ class DnsTransactionTestBase : public testing::Test {
}
// Add expected query of |dotted_name| and |qtype| and no response.
- void AddQueryAndTimeout(const char* dotted_name,
- uint16_t qtype,
- DnsQuery::PaddingStrategy padding_strategy =
- DnsQuery::PaddingStrategy::NONE) {
- uint16_t id = base::RandInt(0, std::numeric_limits<uint16_t>::max());
+ void AddQueryAndTimeout(
+ const char* dotted_name,
+ uint16_t qtype,
+ DnsQuery::PaddingStrategy padding_strategy =
+ DnsQuery::PaddingStrategy::NONE,
+ uint16_t id = base::RandInt(0, std::numeric_limits<uint16_t>::max()),
+ bool enqueue_transaction_id = true) {
std::unique_ptr<DnsSocketData> data(
new DnsSocketData(id, dotted_name, qtype, ASYNC, Transport::UDP,
nullptr /* opt_rdata */, padding_strategy));
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), enqueue_transaction_id);
}
// Add expected query of |dotted_name| and |qtype| and matching response with
// no answer and RCODE set to |rcode|. The id will be generated randomly.
- void AddQueryAndRcode(const char* dotted_name,
- uint16_t qtype,
- int rcode,
- IoMode mode,
- Transport trans,
- DnsQuery::PaddingStrategy padding_strategy =
- DnsQuery::PaddingStrategy::NONE) {
+ void AddQueryAndRcode(
+ const char* dotted_name,
+ uint16_t qtype,
+ int rcode,
+ IoMode mode,
+ Transport trans,
+ DnsQuery::PaddingStrategy padding_strategy =
+ DnsQuery::PaddingStrategy::NONE,
+ uint16_t id = base::RandInt(0, std::numeric_limits<uint16_t>::max()),
+ bool enqueue_transaction_id = true) {
CHECK_NE(dns_protocol::kRcodeNOERROR, rcode);
- uint16_t id = base::RandInt(0, std::numeric_limits<uint16_t>::max());
std::unique_ptr<DnsSocketData> data(
new DnsSocketData(id, dotted_name, qtype, mode, trans,
nullptr /* opt_rdata */, padding_strategy));
data->AddRcode(rcode, mode);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), enqueue_transaction_id);
}
void AddAsyncQueryAndRcode(const char* dotted_name,
@@ -1421,12 +1449,39 @@ TEST_F(DnsTransactionTest, SyncSearchQuery) {
}
TEST_F(DnsTransactionTest, ConnectFailure) {
- socket_factory_->fail_next_socket_ = true;
+ // Prep socket factory for a single socket with connection failure.
+ MockConnect connect_data;
+ connect_data.result = ERR_FAILED;
+ StaticSocketDataProvider data_provider;
+ data_provider.set_connect_data(connect_data);
+ socket_factory_->AddSocketDataProvider(&data_provider);
+
transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt.
TransactionHelper helper0("www.chromium.org", dns_protocol::kTypeA,
false /* secure */, ERR_CONNECTION_REFUSED,
resolve_context_.get());
+
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
+ EXPECT_FALSE(helper0.response());
+ EXPECT_FALSE(session_->udp_tracker()->low_entropy());
+}
+
+TEST_F(DnsTransactionTest, ConnectFailure_SocketLimitReached) {
+ // Prep socket factory for a single socket with connection failure.
+ MockConnect connect_data;
+ connect_data.result = ERR_INSUFFICIENT_RESOURCES;
+ StaticSocketDataProvider data_provider;
+ data_provider.set_connect_data(connect_data);
+ socket_factory_->AddSocketDataProvider(&data_provider);
+
+ transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt.
+ TransactionHelper helper0("www.chromium.org", dns_protocol::kTypeA,
+ false /* secure */, ERR_CONNECTION_REFUSED,
+ resolve_context_.get());
+
+ EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
+ EXPECT_FALSE(helper0.response());
+ EXPECT_TRUE(session_->udp_tracker()->low_entropy());
}
TEST_F(DnsTransactionTest, ConnectFailureFollowedBySuccess) {
@@ -1450,7 +1505,8 @@ TEST_F(DnsTransactionTest, HttpsGetLookup) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1460,7 +1516,8 @@ TEST_F(DnsTransactionTest, HttpsGetFailure) {
ConfigureDohServers(false /* use_post */);
AddQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL,
SYNCHRONOUS, Transport::HTTPS,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128, 0 /* id */,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_SERVER_FAILED, resolve_context_.get());
@@ -1471,10 +1528,12 @@ TEST_F(DnsTransactionTest, HttpsGetFailure) {
TEST_F(DnsTransactionTest, HttpsGetMalformed) {
ConfigureDohServers(false /* use_post */);
- AddQueryAndResponse(1 /* id */, kT0HostName, kT0Qtype, kT0ResponseDatagram,
- base::size(kT0ResponseDatagram), SYNCHRONOUS,
+ // Use T1 response, which is malformed for a T0 request.
+ AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, kT1ResponseDatagram,
+ base::size(kT1ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_MALFORMED_RESPONSE, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1485,7 +1544,8 @@ TEST_F(DnsTransactionTest, HttpsPostLookup) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1495,7 +1555,8 @@ TEST_F(DnsTransactionTest, HttpsPostFailure) {
ConfigureDohServers(true /* use_post */);
AddQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL,
SYNCHRONOUS, Transport::HTTPS,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128, 0 /* id */,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_SERVER_FAILED, resolve_context_.get());
@@ -1506,10 +1567,12 @@ TEST_F(DnsTransactionTest, HttpsPostFailure) {
TEST_F(DnsTransactionTest, HttpsPostMalformed) {
ConfigureDohServers(true /* use_post */);
- AddQueryAndResponse(1 /* id */, kT0HostName, kT0Qtype, kT0ResponseDatagram,
- base::size(kT0ResponseDatagram), SYNCHRONOUS,
+ // Use T1 response, which is malformed for a T0 request.
+ AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, kT1ResponseDatagram,
+ base::size(kT1ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_MALFORMED_RESPONSE, resolve_context_.get());
@@ -1521,7 +1584,8 @@ TEST_F(DnsTransactionTest, HttpsPostLookupAsync) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1541,7 +1605,8 @@ TEST_F(DnsTransactionTest, HttpsPostLookupFailDohServerLookup) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_SECURE_RESOLVER_HOSTNAME_RESOLUTION_FAILED,
resolve_context_.get());
@@ -1562,7 +1627,8 @@ TEST_F(DnsTransactionTest, HttpsPostLookupFailStart) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_FAILED, resolve_context_.get());
SetDohJobMakerCallback(base::BindRepeating(DohJobMakerCallbackFailStart));
@@ -1583,7 +1649,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookupFailSync) {
0, kT0HostName, kT0Qtype, SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128));
data->AddResponseWithLength(std::make_unique<DnsResponse>(), SYNCHRONOUS, 0);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_MALFORMED_RESPONSE, resolve_context_.get());
SetDohJobMakerCallback(base::BindRepeating(DohJobMakerCallbackFailSync));
@@ -1603,7 +1669,8 @@ TEST_F(DnsTransactionTest, HttpsPostLookupFailAsync) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_MALFORMED_RESPONSE, resolve_context_.get());
SetDohJobMakerCallback(base::BindRepeating(DohJobMakerCallbackFailAsync));
@@ -1618,7 +1685,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookup2Sync) {
data->AddResponseData(kT0ResponseDatagram, 20, SYNCHRONOUS);
data->AddResponseData(kT0ResponseDatagram + 20,
base::size(kT0ResponseDatagram) - 20, SYNCHRONOUS);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1632,7 +1699,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookup2Async) {
data->AddResponseData(kT0ResponseDatagram, 20, ASYNC);
data->AddResponseData(kT0ResponseDatagram + 20,
base::size(kT0ResponseDatagram) - 20, ASYNC);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1646,7 +1713,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookupAsyncWithAsyncZeroRead) {
data->AddResponseData(kT0ResponseDatagram, base::size(kT0ResponseDatagram),
ASYNC);
data->AddResponseData(kT0ResponseDatagram, 0, ASYNC);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1660,7 +1727,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookupSyncWithAsyncZeroRead) {
data->AddResponseData(kT0ResponseDatagram, base::size(kT0ResponseDatagram),
SYNCHRONOUS);
data->AddResponseData(kT0ResponseDatagram, 0, ASYNC);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1674,7 +1741,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookupAsyncThenSync) {
data->AddResponseData(kT0ResponseDatagram, 20, ASYNC);
data->AddResponseData(kT0ResponseDatagram + 20,
base::size(kT0ResponseDatagram) - 20, SYNCHRONOUS);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1687,7 +1754,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookupAsyncThenSyncError) {
nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128));
data->AddResponseData(kT0ResponseDatagram, 20, ASYNC);
data->AddReadError(ERR_FAILED, SYNCHRONOUS);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_FAILED, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1700,7 +1767,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookupAsyncThenAsyncError) {
nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128));
data->AddResponseData(kT0ResponseDatagram, 20, ASYNC);
data->AddReadError(ERR_FAILED, ASYNC);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_FAILED, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1713,7 +1780,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookupSyncThenAsyncError) {
nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128));
data->AddResponseData(kT0ResponseDatagram, 20, SYNCHRONOUS);
data->AddReadError(ERR_FAILED, ASYNC);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_FAILED, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1726,7 +1793,7 @@ TEST_F(DnsTransactionTest, HttpsPostLookupSyncThenSyncError) {
nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128));
data->AddResponseData(kT0ResponseDatagram, 20, SYNCHRONOUS);
data->AddReadError(ERR_FAILED, SYNCHRONOUS);
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_FAILED, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1749,31 +1816,37 @@ TEST_F(DnsTransactionTest, HttpsMarkHttpsBad) {
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndErrorResponse(1, kT1HostName, kT1Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndErrorResponse(1, kT1HostName, kT1Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(1, kT1HostName, kT1Qtype, kT1ResponseDatagram,
- base::size(kT1ResponseDatagram), ASYNC, Transport::HTTPS,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndErrorResponse(0 /* id */, kT0HostName, kT0Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndErrorResponse(0 /* id */, kT0HostName, kT0Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, kT0ResponseDatagram,
+ base::size(kT0ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
- TransactionHelper helper1(kT1HostName, kT1Qtype, true /* secure */,
- kT1RecordCount, resolve_context_.get());
+ TransactionHelper helper1(kT0HostName, kT0Qtype, true /* secure */,
+ kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
// UDP server 0 is our only UDP server, so it will be good. HTTPS
// servers 0 and 1 failed and will be marked bad. HTTPS server 2 succeeded
@@ -1834,11 +1907,13 @@ TEST_F(DnsTransactionTest, HttpsPostFailThenHTTPFallback) {
ConfigureDohServers(true /* use_post */, 2);
AddQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL, ASYNC,
Transport::HTTPS,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128, 0 /* id */,
+ false /* enqueue_transaction_id */);
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1852,11 +1927,13 @@ TEST_F(DnsTransactionTest, HttpsPostFailTwice) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_FAILED, resolve_context_.get());
SetDohJobMakerCallback(base::BindRepeating(DohJobMakerCallbackFailStart));
@@ -1886,7 +1963,8 @@ TEST_F(DnsTransactionTest, HttpsNotAvailableThenHttpFallback) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1928,7 +2006,8 @@ TEST_F(DnsTransactionTest, HttpsFailureThenNotAvailable_Automatic) {
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_CONNECTION_REFUSED, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -1978,15 +2057,18 @@ TEST_F(DnsTransactionTest, HttpsFailureThenNotAvailable_Secure) {
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_CONNECTION_REFUSED, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -2025,7 +2107,8 @@ TEST_F(DnsTransactionTest, MaxHttpsFailures_NonConsecutive) {
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper failure(kT0HostName, kT0Qtype, true /* secure */,
ERR_CONNECTION_REFUSED, resolve_context_.get());
EXPECT_TRUE(failure.RunUntilDone(transaction_factory_.get()));
@@ -2043,7 +2126,8 @@ TEST_F(DnsTransactionTest, MaxHttpsFailures_NonConsecutive) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper success(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
EXPECT_TRUE(success.RunUntilDone(transaction_factory_.get()));
@@ -2061,7 +2145,8 @@ TEST_F(DnsTransactionTest, MaxHttpsFailures_NonConsecutive) {
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper last_failure(kT0HostName, kT0Qtype, true /* secure */,
ERR_CONNECTION_REFUSED,
resolve_context_.get());
@@ -2094,7 +2179,8 @@ TEST_F(DnsTransactionTest, MaxHttpsFailures_Consecutive) {
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper failure(kT0HostName, kT0Qtype, true /* secure */,
ERR_CONNECTION_REFUSED, resolve_context_.get());
EXPECT_TRUE(failure.RunUntilDone(transaction_factory_.get()));
@@ -2111,7 +2197,8 @@ TEST_F(DnsTransactionTest, MaxHttpsFailures_Consecutive) {
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper last_failure(kT0HostName, kT0Qtype, true /* secure */,
ERR_CONNECTION_REFUSED,
resolve_context_.get());
@@ -2150,7 +2237,7 @@ TEST_F(DnsTransactionTest, SuccessfulTransactionStartedBeforeUnavailable) {
data->AddResponseData(kT0ResponseDatagram, base::size(kT0ResponseDatagram),
ASYNC);
SequencedSocketData* sequenced_socket_data = data->GetProvider();
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
TransactionHelper delayed_success(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
@@ -2161,7 +2248,8 @@ TEST_F(DnsTransactionTest, SuccessfulTransactionStartedBeforeUnavailable) {
AddQueryAndErrorResponse(0, kT0HostName, kT0Qtype, ERR_CONNECTION_REFUSED,
SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper failure(kT0HostName, kT0Qtype, true /* secure */,
ERR_CONNECTION_REFUSED, resolve_context_.get());
EXPECT_TRUE(failure.RunUntilDone(transaction_factory_.get()));
@@ -2189,8 +2277,8 @@ class CookieCallback {
CookieCallback()
: result_(false), loop_to_quit_(std::make_unique<base::RunLoop>()) {}
- void SetCookieCallback(CookieInclusionStatus result) {
- result_ = result.IsInclude();
+ void SetCookieCallback(CookieAccessResult result) {
+ result_ = result.status.IsInclude();
loop_to_quit_->Quit();
}
@@ -2219,15 +2307,17 @@ TEST_F(DnsTransactionTest, HttpsPostTestNoCookies) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(1, kT1HostName, kT1Qtype, kT1ResponseDatagram,
- base::size(kT1ResponseDatagram), SYNCHRONOUS,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, kT0ResponseDatagram,
+ base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
- TransactionHelper helper1(kT1HostName, kT1Qtype, true /* secure */,
- kT1RecordCount, resolve_context_.get());
+ TransactionHelper helper1(kT0HostName, kT0Qtype, true /* secure */,
+ kT0RecordCount, resolve_context_.get());
SetResponseModifierCallback(base::BindRepeating(MakeResponseWithCookie));
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -2262,7 +2352,8 @@ TEST_F(DnsTransactionTest, HttpsPostNoContentLength) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
SetResponseModifierCallback(base::BindRepeating(MakeResponseWithoutLength));
@@ -2279,7 +2370,8 @@ TEST_F(DnsTransactionTest, HttpsPostWithBadRequestResponse) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_MALFORMED_RESPONSE, resolve_context_.get());
SetResponseModifierCallback(
@@ -2297,7 +2389,8 @@ TEST_F(DnsTransactionTest, HttpsPostWithWrongType) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_MALFORMED_RESPONSE, resolve_context_.get());
SetResponseModifierCallback(base::BindRepeating(MakeResponseWrongType));
@@ -2317,11 +2410,13 @@ TEST_F(DnsTransactionTest, HttpsGetRedirect) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
SetResponseModifierCallback(base::BindRepeating(MakeResponseRedirect));
@@ -2337,7 +2432,8 @@ TEST_F(DnsTransactionTest, HttpsPostWithNoType) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_MALFORMED_RESPONSE, resolve_context_.get());
SetResponseModifierCallback(base::BindRepeating(MakeResponseNoType));
@@ -2350,7 +2446,8 @@ TEST_F(DnsTransactionTest, CanLookupDohServerName) {
AddQueryAndErrorResponse(0, kMockHostname, dns_protocol::kTypeA,
ERR_NAME_NOT_RESOLVED, SYNCHRONOUS, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0("mock", dns_protocol::kTypeA, true /* secure */,
ERR_NAME_NOT_RESOLVED, resolve_context_.get());
EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
@@ -2385,7 +2482,8 @@ TEST_F(DnsTransactionTest, HttpsPostLookupWithLog) {
AddQueryAndResponse(0, kT0HostName, kT0Qtype, kT0ResponseDatagram,
base::size(kT0ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TransactionHelper helper0(kT0HostName, kT0Qtype, true /* secure */,
kT0RecordCount, resolve_context_.get());
CountingObserver observer;
@@ -2403,7 +2501,8 @@ TEST_F(DnsTransactionTestWithMockTime, SlowHttpsResponse_SingleAttempt) {
ConfigureDohServers(false /* use_post */);
AddQueryAndTimeout(kT0HostName, kT0Qtype,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128, 0 /* id */,
+ false /* enqueue_transaction_id */);
TransactionHelper helper(kT0HostName, kT0Qtype, true /* secure */,
ERR_DNS_TIMED_OUT, resolve_context_.get());
@@ -2425,23 +2524,24 @@ TEST_F(DnsTransactionTestWithMockTime, SlowHttpsResponse_TwoAttempts) {
// Simulate a slow response by using an ERR_IO_PENDING read error to delay
// until SequencedSocketData::Resume() is called.
auto data = std::make_unique<DnsSocketData>(
- 1 /* id */, kT1HostName, kT1Qtype, ASYNC, Transport::HTTPS,
+ 0 /* id */, kT0HostName, kT0Qtype, ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
data->AddReadError(ERR_IO_PENDING, ASYNC);
- data->AddResponseData(kT1ResponseDatagram, base::size(kT1ResponseDatagram),
+ data->AddResponseData(kT0ResponseDatagram, base::size(kT0ResponseDatagram),
ASYNC);
SequencedSocketData* sequenced_socket_data = data->GetProvider();
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
- TransactionHelper helper(kT1HostName, kT1Qtype, true /* secure */,
- kT1RecordCount, resolve_context_.get());
+ TransactionHelper helper(kT0HostName, kT0Qtype, true /* secure */,
+ kT0RecordCount, resolve_context_.get());
ASSERT_FALSE(helper.Run(transaction_factory_.get()));
ASSERT_TRUE(sequenced_socket_data->IsPaused());
// Another attempt configured, so transaction should not fail after initial
// timeout. Setup the second attempt to never receive a response.
- AddQueryAndTimeout(kT1HostName, kT1Qtype,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ AddQueryAndTimeout(kT0HostName, kT0Qtype,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128, 0 /* id */,
+ false /* enqueue_transaction_id */);
FastForwardBy(resolve_context_->NextDohTimeout(0 /* doh_server_index */,
session_.get()));
EXPECT_FALSE(helper.has_completed());
@@ -2453,7 +2553,7 @@ TEST_F(DnsTransactionTestWithMockTime, SlowHttpsResponse_TwoAttempts) {
EXPECT_TRUE(helper.has_completed());
}
-TEST_F(DnsTransactionTest, TCPLookup) {
+TEST_F(DnsTransactionTest, TcpLookup_UdpRetry) {
AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, kT0ResponseDatagram,
@@ -2464,6 +2564,31 @@ TEST_F(DnsTransactionTest, TCPLookup) {
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
}
+TEST_F(DnsTransactionTest, TcpLookup_LowEntropy) {
+ socket_factory_->diverse_source_ports_ = false;
+
+ for (int i = 0; i <= DnsUdpTracker::kPortReuseThreshold; ++i) {
+ AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, kT0ResponseDatagram,
+ base::size(kT0ResponseDatagram), ASYNC, Transport::UDP);
+ }
+
+ AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, kT0ResponseDatagram,
+ base::size(kT0ResponseDatagram), ASYNC, Transport::TCP);
+
+ for (int i = 0; i <= DnsUdpTracker::kPortReuseThreshold; ++i) {
+ TransactionHelper udp_helper(kT0HostName, kT0Qtype, false /* secure */,
+ kT0RecordCount, resolve_context_.get());
+ udp_helper.RunUntilDone(transaction_factory_.get());
+ }
+
+ ASSERT_TRUE(session_->udp_tracker()->low_entropy());
+
+ TransactionHelper helper0(kT0HostName, kT0Qtype, false /* secure */,
+ kT0RecordCount, resolve_context_.get());
+ EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
+ EXPECT_TRUE(session_->udp_tracker()->low_entropy());
+}
+
TEST_F(DnsTransactionTest, TCPFailure) {
AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
@@ -2498,7 +2623,7 @@ TEST_F(DnsTransactionTest, TCPMalformed) {
EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
}
-TEST_F(DnsTransactionTestWithMockTime, TCPTimeout) {
+TEST_F(DnsTransactionTestWithMockTime, TcpTimeout_UdpRetry) {
ConfigureFactory();
AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
@@ -2512,6 +2637,33 @@ TEST_F(DnsTransactionTestWithMockTime, TCPTimeout) {
EXPECT_TRUE(helper0.has_completed());
}
+TEST_F(DnsTransactionTestWithMockTime, TcpTimeout_LowEntropy) {
+ ConfigureFactory();
+ socket_factory_->diverse_source_ports_ = false;
+
+ for (int i = 0; i <= DnsUdpTracker::kPortReuseThreshold; ++i) {
+ AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype, kT0ResponseDatagram,
+ base::size(kT0ResponseDatagram), ASYNC, Transport::UDP);
+ }
+
+ AddSocketData(std::make_unique<DnsSocketData>(
+ 1 /* id */, kT0HostName, kT0Qtype, ASYNC, Transport::TCP));
+
+ for (int i = 0; i <= DnsUdpTracker::kPortReuseThreshold; ++i) {
+ TransactionHelper udp_helper(kT0HostName, kT0Qtype, false /* secure */,
+ kT0RecordCount, resolve_context_.get());
+ udp_helper.RunUntilDone(transaction_factory_.get());
+ }
+
+ ASSERT_TRUE(session_->udp_tracker()->low_entropy());
+
+ TransactionHelper helper0(kT0HostName, kT0Qtype, false /* secure */,
+ ERR_DNS_TIMED_OUT, resolve_context_.get());
+ EXPECT_FALSE(helper0.Run(transaction_factory_.get()));
+ FastForwardUntilNoTasksRemain();
+ EXPECT_TRUE(helper0.has_completed());
+}
+
TEST_F(DnsTransactionTest, TCPReadReturnsZeroAsync) {
AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
@@ -2676,18 +2828,21 @@ TEST_F(DnsTransactionTest, InvalidQuery) {
TEST_F(DnsTransactionTestWithMockTime, ProbeUntilSuccess) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -2720,20 +2875,21 @@ TEST_F(DnsTransactionTestWithMockTime, HungProbe) {
// probe and not return the error until SequencedSocketData::Resume() is
// called.
auto data = std::make_unique<DnsSocketData>(
- 4, kT4HostName, kT4Qtype, ASYNC, Transport::HTTPS,
+ 0 /* id */, kT4HostName, kT4Qtype, ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */, DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
data->AddReadError(ERR_IO_PENDING, ASYNC);
data->AddReadError(ERR_CONNECTION_REFUSED, ASYNC);
data->AddResponseData(kT4ResponseDatagram, base::size(kT4ResponseDatagram),
ASYNC);
SequencedSocketData* sequenced_socket_data = data->GetProvider();
- AddSocketData(std::move(data));
+ AddSocketData(std::move(data), false /* enqueue_transaction_id */);
// Add success for second probe.
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -2764,18 +2920,21 @@ TEST_F(DnsTransactionTestWithMockTime, HungProbe) {
TEST_F(DnsTransactionTestWithMockTime, ProbeMultipleServers) {
ConfigureDohServers(true /* use_post */, 2 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
ASSERT_FALSE(resolve_context_->GetDohServerAvailability(
0u /* doh_server_index */, session_.get()));
@@ -2812,14 +2971,16 @@ TEST_F(DnsTransactionTestWithMockTime, ProbeMultipleServers) {
TEST_F(DnsTransactionTestWithMockTime, MultipleProbeRunners) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner1 =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -2856,18 +3017,21 @@ TEST_F(DnsTransactionTestWithMockTime, MultipleProbeRunners_SeparateContexts) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
TestURLRequestContext request_context2;
ResolveContext context2(&request_context2, false /* enable_caching */);
@@ -2922,14 +3086,16 @@ TEST_F(DnsTransactionTestWithMockTime, MultipleProbeRunners_SeparateContexts) {
TEST_F(DnsTransactionTestWithMockTime, CancelDohProbe) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -2961,18 +3127,21 @@ TEST_F(DnsTransactionTestWithMockTime, CancelDohProbe) {
TEST_F(DnsTransactionTestWithMockTime, CancelOneOfMultipleProbeRunners) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner1 =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -3005,14 +3174,16 @@ TEST_F(DnsTransactionTestWithMockTime, CancelOneOfMultipleProbeRunners) {
TEST_F(DnsTransactionTestWithMockTime, CancelAllOfMultipleProbeRunners) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner1 =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -3044,10 +3215,11 @@ TEST_F(DnsTransactionTestWithMockTime, CancelAllOfMultipleProbeRunners) {
TEST_F(DnsTransactionTestWithMockTime, CancelDohProbe_AfterSuccess) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), SYNCHRONOUS,
Transport::HTTPS, nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -3083,10 +3255,11 @@ TEST_F(DnsTransactionTestWithMockTime, CancelDohProbe_AfterSuccess) {
TEST_F(DnsTransactionTestWithMockTime, DestroyFactoryAfterStartingDohProbe) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -3112,14 +3285,16 @@ TEST_F(DnsTransactionTestWithMockTime, DestroyFactoryAfterStartingDohProbe) {
TEST_F(DnsTransactionTestWithMockTime, StartWhileRunning) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndErrorResponse(4, kT4HostName, kT4Qtype, ERR_CONNECTION_REFUSED,
- SYNCHRONOUS, Transport::HTTPS,
- nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndErrorResponse(0 /* id */, kT4HostName, kT4Qtype,
+ ERR_CONNECTION_REFUSED, SYNCHRONOUS,
+ Transport::HTTPS, nullptr /* opt_rdata */,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -3145,14 +3320,16 @@ TEST_F(DnsTransactionTestWithMockTime, StartWhileRunning) {
TEST_F(DnsTransactionTestWithMockTime, RestartFinishedProbe) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
@@ -3193,14 +3370,16 @@ TEST_F(DnsTransactionTestWithMockTime, RestartFinishedProbe) {
TEST_F(DnsTransactionTestWithMockTime, FastProbeRestart) {
ConfigureDohServers(true /* use_post */, 1 /* num_doh_servers */,
false /* make_available */);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
- AddQueryAndResponse(4, kT4HostName, kT4Qtype, kT4ResponseDatagram,
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
+ AddQueryAndResponse(0 /* id */, kT4HostName, kT4Qtype, kT4ResponseDatagram,
base::size(kT4ResponseDatagram), ASYNC, Transport::HTTPS,
nullptr /* opt_rdata */,
- DnsQuery::PaddingStrategy::BLOCK_LENGTH_128);
+ DnsQuery::PaddingStrategy::BLOCK_LENGTH_128,
+ false /* enqueue_transaction_id */);
std::unique_ptr<DnsProbeRunner> runner =
transaction_factory_->CreateDohProbeRunner(resolve_context_.get());
diff --git a/chromium/net/dns/dns_udp_tracker.cc b/chromium/net/dns/dns_udp_tracker.cc
index ffd50c6c471..d07a7ed8ecd 100644
--- a/chromium/net/dns/dns_udp_tracker.cc
+++ b/chromium/net/dns/dns_udp_tracker.cc
@@ -10,15 +10,45 @@
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/tick_clock.h"
+#include "net/base/net_errors.h"
namespace net {
+namespace {
+// Used in UMA (DNS.UdpLowEntropyReason). Do not renumber or remove values.
+enum class LowEntropyReason {
+ kPortReuse = 0,
+ kRecognizedIdMismatch = 1,
+ kUnrecognizedIdMismatch = 2,
+ kSocketLimitExhaustion = 3,
+ kMaxValue = kSocketLimitExhaustion,
+};
+
+void RecordLowEntropyUma(LowEntropyReason reason) {
+ UMA_HISTOGRAM_ENUMERATION("Net.DNS.DnsTransaction.UDP.LowEntropyReason",
+ reason);
+}
+
+} // namespace
+
// static
constexpr base::TimeDelta DnsUdpTracker::kMaxAge;
// static
constexpr size_t DnsUdpTracker::kMaxRecordedQueries;
+// static
+constexpr base::TimeDelta DnsUdpTracker::kMaxRecognizedIdAge;
+
+// static
+constexpr size_t DnsUdpTracker::kUnrecognizedIdMismatchThreshold;
+
+// static
+constexpr size_t DnsUdpTracker::kRecognizedIdMismatchThreshold;
+
+// static
+constexpr int DnsUdpTracker::kPortReuseThreshold;
+
struct DnsUdpTracker::QueryData {
uint16_t port;
uint16_t query_id;
@@ -31,7 +61,7 @@ DnsUdpTracker::DnsUdpTracker(DnsUdpTracker&&) = default;
DnsUdpTracker& DnsUdpTracker::operator=(DnsUdpTracker&&) = default;
void DnsUdpTracker::RecordQuery(uint16_t port, uint16_t query_id) {
- PurgeOldQueries();
+ PurgeOldRecords();
int reused_port_count = base::checked_cast<int>(std::count_if(
recent_queries_.cbegin(), recent_queries_.cend(),
@@ -50,11 +80,16 @@ void DnsUdpTracker::RecordQuery(uint16_t port, uint16_t query_id) {
now - most_recent_match->time);
}
+ if (reused_port_count >= kPortReuseThreshold && !low_entropy_) {
+ low_entropy_ = true;
+ RecordLowEntropyUma(LowEntropyReason::kPortReuse);
+ }
+
SaveQuery({port, query_id, now});
}
void DnsUdpTracker::RecordResponseId(uint16_t query_id, uint16_t response_id) {
- PurgeOldQueries();
+ PurgeOldRecords();
// Used in UMA (DNS.UdpIdMismatchStatus). Do not renumber or remove values.
enum class MismatchStatus {
@@ -68,6 +103,8 @@ void DnsUdpTracker::RecordResponseId(uint16_t query_id, uint16_t response_id) {
if (query_id == response_id) {
status = MismatchStatus::kSuccessfulParse;
} else {
+ SaveIdMismatch(response_id);
+
auto oldest_matching_id =
std::find_if(recent_queries_.cbegin(), recent_queries_.cend(),
[&](const auto& recent_query) {
@@ -87,12 +124,31 @@ void DnsUdpTracker::RecordResponseId(uint16_t query_id, uint16_t response_id) {
UMA_HISTOGRAM_ENUMERATION("Net.DNS.DnsTransaction.UDP.IdMismatch", status);
}
-void DnsUdpTracker::PurgeOldQueries() {
+void DnsUdpTracker::RecordConnectionError(int connection_error) {
+ if (!low_entropy_ && connection_error == ERR_INSUFFICIENT_RESOURCES) {
+ // On UDP connection, this error signifies that the process is using an
+ // unreasonably large number of UDP sockets, potentially a deliberate
+ // attack to reduce DNS port entropy.
+ low_entropy_ = true;
+ RecordLowEntropyUma(LowEntropyReason::kSocketLimitExhaustion);
+ }
+}
+
+void DnsUdpTracker::PurgeOldRecords() {
base::TimeTicks now = tick_clock_->NowTicks();
+
while (!recent_queries_.empty() &&
(now - recent_queries_.front().time) > kMaxAge) {
recent_queries_.pop_front();
}
+ while (!recent_unrecognized_id_hits_.empty() &&
+ now - recent_unrecognized_id_hits_.front() > kMaxAge) {
+ recent_unrecognized_id_hits_.pop_front();
+ }
+ while (!recent_recognized_id_hits_.empty() &&
+ now - recent_recognized_id_hits_.front() > kMaxAge) {
+ recent_recognized_id_hits_.pop_front();
+ }
}
void DnsUdpTracker::SaveQuery(QueryData query) {
@@ -104,4 +160,46 @@ void DnsUdpTracker::SaveQuery(QueryData query) {
recent_queries_.push_back(std::move(query));
}
+void DnsUdpTracker::SaveIdMismatch(uint16_t id) {
+ // No need to track mismatches if already flagged for low entropy.
+ if (low_entropy_)
+ return;
+
+ base::TimeTicks now = tick_clock_->NowTicks();
+ base::TimeTicks time_cutoff = now - kMaxRecognizedIdAge;
+ bool is_recognized = std::any_of(
+ recent_queries_.cbegin(), recent_queries_.cend(),
+ [&](const auto& recent_query) {
+ return recent_query.query_id == id && recent_query.time >= time_cutoff;
+ });
+
+ if (is_recognized) {
+ DCHECK_LT(recent_recognized_id_hits_.size(),
+ kRecognizedIdMismatchThreshold);
+ if (recent_recognized_id_hits_.size() ==
+ kRecognizedIdMismatchThreshold - 1) {
+ low_entropy_ = true;
+ RecordLowEntropyUma(LowEntropyReason::kRecognizedIdMismatch);
+ return;
+ }
+
+ DCHECK(recent_recognized_id_hits_.empty() ||
+ now >= recent_recognized_id_hits_.back());
+ recent_recognized_id_hits_.push_back(now);
+ } else {
+ DCHECK_LT(recent_unrecognized_id_hits_.size(),
+ kUnrecognizedIdMismatchThreshold);
+ if (recent_unrecognized_id_hits_.size() ==
+ kUnrecognizedIdMismatchThreshold - 1) {
+ low_entropy_ = true;
+ RecordLowEntropyUma(LowEntropyReason::kUnrecognizedIdMismatch);
+ return;
+ }
+
+ DCHECK(recent_unrecognized_id_hits_.empty() ||
+ now >= recent_unrecognized_id_hits_.back());
+ recent_unrecognized_id_hits_.push_back(now);
+ }
+}
+
} // namespace net
diff --git a/chromium/net/dns/dns_udp_tracker.h b/chromium/net/dns/dns_udp_tracker.h
index 6e58e64c104..597f0362028 100644
--- a/chromium/net/dns/dns_udp_tracker.h
+++ b/chromium/net/dns/dns_udp_tracker.h
@@ -29,6 +29,20 @@ class NET_EXPORT_PRIVATE DnsUdpTracker {
static constexpr base::TimeDelta kMaxAge = base::TimeDelta::FromMinutes(10);
static constexpr size_t kMaxRecordedQueries = 256;
+ // How recently an ID needs to be recorded in a recent query to be considered
+ // "recognized".
+ static constexpr base::TimeDelta kMaxRecognizedIdAge =
+ base::TimeDelta::FromSeconds(15);
+
+ // Numbers of ID mismatches required to set the |low_entropy_| flag. Also
+ // serves as the max number of mismatches to be recorded, as no more entries
+ // are recorded after setting the flag.
+ static constexpr size_t kUnrecognizedIdMismatchThreshold = 8;
+ static constexpr size_t kRecognizedIdMismatchThreshold = 128;
+
+ // Number of reuses of the same port required to set the |low_entropy_| flag.
+ static constexpr int kPortReuseThreshold = 2;
+
DnsUdpTracker();
~DnsUdpTracker();
@@ -37,6 +51,12 @@ class NET_EXPORT_PRIVATE DnsUdpTracker {
void RecordQuery(uint16_t port, uint16_t query_id);
void RecordResponseId(uint16_t query_id, uint16_t response_id);
+ void RecordConnectionError(int connection_error);
+
+ // If true, the entropy from random UDP port and DNS ID has been detected to
+ // potentially be low, e.g. due to exhaustion of the port pool or mismatches
+ // on IDs.
+ bool low_entropy() const { return low_entropy_; }
void set_tick_clock_for_testing(base::TickClock* tick_clock) {
tick_clock_ = tick_clock;
@@ -45,11 +65,18 @@ class NET_EXPORT_PRIVATE DnsUdpTracker {
private:
struct QueryData;
- void PurgeOldQueries();
+ void PurgeOldRecords();
void SaveQuery(QueryData query);
+ void SaveIdMismatch(uint16_t it);
+ bool low_entropy_ = false;
base::circular_deque<QueryData> recent_queries_;
+ // Times of recent ID mismatches, separated by whether or not the ID was
+ // recognized from recent queries.
+ base::circular_deque<base::TimeTicks> recent_unrecognized_id_hits_;
+ base::circular_deque<base::TimeTicks> recent_recognized_id_hits_;
+
const base::TickClock* tick_clock_ = base::DefaultTickClock::GetInstance();
};
diff --git a/chromium/net/dns/dns_udp_tracker_unittest.cc b/chromium/net/dns/dns_udp_tracker_unittest.cc
index 1b5681fde1d..8ed77b6dd98 100644
--- a/chromium/net/dns/dns_udp_tracker_unittest.cc
+++ b/chromium/net/dns/dns_udp_tracker_unittest.cc
@@ -5,6 +5,7 @@
#include "net/dns/dns_udp_tracker.h"
#include "base/test/simple_test_tick_clock.h"
+#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -22,38 +23,75 @@ class DnsUdpTrackerTest : public testing::Test {
base::SimpleTestTickClock test_tick_clock_;
};
-// Just testing that nothing crashes given some standard calls.
-// TODO(ericorth@chromium.org): Actually test behavior once interesting
-// side effects or data access is added.
-
TEST_F(DnsUdpTrackerTest, MatchingId) {
- static const uint16_t kId = 56;
- tracker_.RecordQuery(416 /* port */, kId);
- tracker_.RecordResponseId(kId /* query_id */, kId /* response_id */);
+ uint16_t port = 416;
+ uint16_t id = 56;
+ for (size_t i = 0; i < DnsUdpTracker::kRecognizedIdMismatchThreshold; ++i) {
+ tracker_.RecordQuery(++port, ++id);
+ tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
+ EXPECT_FALSE(tracker_.low_entropy());
+ }
}
-TEST_F(DnsUdpTrackerTest, ReusedMismatch) {
+TEST_F(DnsUdpTrackerTest, ReusedMismatches) {
static const uint16_t kOldId = 786;
tracker_.RecordQuery(123 /* port */, kOldId);
- static const uint16_t kNewId = 3456;
- tracker_.RecordQuery(3889 /* port */, kNewId);
- tracker_.RecordResponseId(kNewId /* query_id */, kOldId /* response_id */);
+ uint16_t port = 3889;
+ uint16_t id = 3456;
+ for (size_t i = 0; i < DnsUdpTracker::kRecognizedIdMismatchThreshold; ++i) {
+ EXPECT_FALSE(tracker_.low_entropy());
+ tracker_.RecordQuery(++port, ++id);
+ tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
+ }
+
+ EXPECT_TRUE(tracker_.low_entropy());
}
-TEST_F(DnsUdpTrackerTest, ReusedMismatch_Expired) {
+TEST_F(DnsUdpTrackerTest, ReusedMismatches_Expired) {
static const uint16_t kOldId = 786;
tracker_.RecordQuery(123 /* port */, kOldId);
test_tick_clock_.Advance(DnsUdpTracker::kMaxAge +
base::TimeDelta::FromMilliseconds(1));
- static const uint16_t kNewId = 3456;
- tracker_.RecordQuery(3889 /* port */, kNewId);
- tracker_.RecordResponseId(kNewId /* query_id */, kOldId /* response_id */);
+ uint16_t port = 3889;
+ uint16_t id = 3456;
+
+ // Because the query record has expired, the ID should be treated as
+ // unrecognized.
+ for (size_t i = 0; i < DnsUdpTracker::kUnrecognizedIdMismatchThreshold; ++i) {
+ EXPECT_FALSE(tracker_.low_entropy());
+ tracker_.RecordQuery(++port, ++id);
+ tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
+ }
+
+ EXPECT_TRUE(tracker_.low_entropy());
}
-TEST_F(DnsUdpTrackerTest, ReusedMismatch_Full) {
+// Test for ID mismatches using an ID still kept in recorded queries, but not
+// recent enough to be considered reognized.
+TEST_F(DnsUdpTrackerTest, ReusedMismatches_Old) {
+ static const uint16_t kOldId = 786;
+ tracker_.RecordQuery(123 /* port */, kOldId);
+
+ test_tick_clock_.Advance(DnsUdpTracker::kMaxRecognizedIdAge +
+ base::TimeDelta::FromMilliseconds(1));
+
+ uint16_t port = 3889;
+ uint16_t id = 3456;
+
+ // Expect the ID to be treated as unrecognized.
+ for (size_t i = 0; i < DnsUdpTracker::kUnrecognizedIdMismatchThreshold; ++i) {
+ EXPECT_FALSE(tracker_.low_entropy());
+ tracker_.RecordQuery(++port, ++id);
+ tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
+ }
+
+ EXPECT_TRUE(tracker_.low_entropy());
+}
+
+TEST_F(DnsUdpTrackerTest, ReusedMismatches_Full) {
static const uint16_t kOldId = 786;
tracker_.RecordQuery(123 /* port */, kOldId);
@@ -63,22 +101,39 @@ TEST_F(DnsUdpTrackerTest, ReusedMismatch_Full) {
tracker_.RecordQuery(++port, ++id);
}
- tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
+ // Expect the ID to be treated as unrecognized.
+ for (size_t i = 0; i < DnsUdpTracker::kUnrecognizedIdMismatchThreshold; ++i) {
+ EXPECT_FALSE(tracker_.low_entropy());
+ tracker_.RecordResponseId(id /* query_id */, kOldId /* response_id */);
+ }
+
+ EXPECT_TRUE(tracker_.low_entropy());
}
-TEST_F(DnsUdpTrackerTest, UnknownMismatch) {
- static const uint16_t kId = 4332;
- tracker_.RecordQuery(10014 /* port */, kId);
- tracker_.RecordResponseId(kId /* query_id */, 743 /* response_id */);
+TEST_F(DnsUdpTrackerTest, UnknownMismatches) {
+ uint16_t port = 10014;
+ uint16_t id = 4332;
+ for (size_t i = 0; i < DnsUdpTracker::kUnrecognizedIdMismatchThreshold; ++i) {
+ EXPECT_FALSE(tracker_.low_entropy());
+ tracker_.RecordQuery(++port, ++id);
+ tracker_.RecordResponseId(id /* query_id */, 743 /* response_id */);
+ }
+
+ EXPECT_TRUE(tracker_.low_entropy());
}
TEST_F(DnsUdpTrackerTest, ReusedPort) {
static const uint16_t kPort = 2135;
tracker_.RecordQuery(kPort, 579 /* query_id */);
- static const uint16_t kId = 580;
- tracker_.RecordQuery(kPort, kId);
- tracker_.RecordResponseId(kId /* query_id */, kId /* response_id */);
+ uint16_t id = 580;
+ for (int i = 0; i < DnsUdpTracker::kPortReuseThreshold; ++i) {
+ EXPECT_FALSE(tracker_.low_entropy());
+ tracker_.RecordQuery(kPort, ++id);
+ tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
+ }
+
+ EXPECT_TRUE(tracker_.low_entropy());
}
TEST_F(DnsUdpTrackerTest, ReusedPort_Expired) {
@@ -87,9 +142,15 @@ TEST_F(DnsUdpTrackerTest, ReusedPort_Expired) {
test_tick_clock_.Advance(DnsUdpTracker::kMaxAge +
base::TimeDelta::FromMilliseconds(1));
- static const uint16_t kId = 580;
- tracker_.RecordQuery(kPort, kId);
- tracker_.RecordResponseId(kId /* query_id */, kId /* response_id */);
+
+ EXPECT_FALSE(tracker_.low_entropy());
+
+ uint16_t id = 580;
+ for (int i = 0; i < DnsUdpTracker::kPortReuseThreshold; ++i) {
+ tracker_.RecordQuery(kPort, ++id);
+ tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
+ EXPECT_FALSE(tracker_.low_entropy());
+ }
}
TEST_F(DnsUdpTrackerTest, ReusedPort_Full) {
@@ -102,8 +163,25 @@ TEST_F(DnsUdpTrackerTest, ReusedPort_Full) {
tracker_.RecordQuery(++port, ++id);
}
- tracker_.RecordQuery(kPort, ++id);
- tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
+ EXPECT_FALSE(tracker_.low_entropy());
+
+ for (int i = 0; i < DnsUdpTracker::kPortReuseThreshold; ++i) {
+ tracker_.RecordQuery(kPort, ++id);
+ tracker_.RecordResponseId(id /* query_id */, id /* response_id */);
+ EXPECT_FALSE(tracker_.low_entropy());
+ }
+}
+
+TEST_F(DnsUdpTrackerTest, ConnectionError) {
+ tracker_.RecordConnectionError(ERR_FAILED);
+
+ EXPECT_FALSE(tracker_.low_entropy());
+}
+
+TEST_F(DnsUdpTrackerTest, ConnectionError_InsufficientResources) {
+ tracker_.RecordConnectionError(ERR_INSUFFICIENT_RESOURCES);
+
+ EXPECT_TRUE(tracker_.low_entropy());
}
} // namespace
diff --git a/chromium/net/dns/fuzzed_host_resolver_util.cc b/chromium/net/dns/fuzzed_host_resolver_util.cc
index 0110c3d3194..feaaa6f5bee 100644
--- a/chromium/net/dns/fuzzed_host_resolver_util.cc
+++ b/chromium/net/dns/fuzzed_host_resolver_util.cc
@@ -129,7 +129,6 @@ DnsConfig GetFuzzedDnsConfig(FuzzedDataProvider* data_provider) {
config.unhandled_options = data_provider->ConsumeBool();
config.append_to_multi_label_name = data_provider->ConsumeBool();
- config.randomize_ports = data_provider->ConsumeBool();
config.ndots = data_provider->ConsumeIntegralInRange(0, 3);
config.attempts = data_provider->ConsumeIntegralInRange(1, 3);
diff --git a/chromium/net/dns/host_resolver_manager.cc b/chromium/net/dns/host_resolver_manager.cc
index 82347fd6bf8..05fd673974a 100644
--- a/chromium/net/dns/host_resolver_manager.cc
+++ b/chromium/net/dns/host_resolver_manager.cc
@@ -2771,7 +2771,7 @@ HostResolverManager::HostResolverManager(
#if defined(OS_WIN)
EnsureWinsockInit();
#endif
-#if (defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)) || \
+#if (defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_ANDROID)) || \
defined(OS_FUCHSIA)
RunLoopbackProbeJob();
#endif
@@ -2779,7 +2779,7 @@ HostResolverManager::HostResolverManager(
NetworkChangeNotifier::AddConnectionTypeObserver(this);
if (system_dns_config_notifier_)
system_dns_config_notifier_->AddObserver(this);
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \
+#if defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_OPENBSD) && \
!defined(OS_ANDROID)
EnsureDnsReloaderInit();
#endif
@@ -3716,7 +3716,7 @@ void HostResolverManager::OnIPAddressChanged() {
// Abandon all ProbeJobs.
probe_weak_ptr_factory_.InvalidateWeakPtrs();
InvalidateCaches();
-#if (defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)) || \
+#if (defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_ANDROID)) || \
defined(OS_FUCHSIA)
RunLoopbackProbeJob();
#endif
diff --git a/chromium/net/dns/host_resolver_manager_unittest.cc b/chromium/net/dns/host_resolver_manager_unittest.cc
index f467b8e1eac..1fa2b651dcf 100644
--- a/chromium/net/dns/host_resolver_manager_unittest.cc
+++ b/chromium/net/dns/host_resolver_manager_unittest.cc
@@ -7075,7 +7075,6 @@ TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides) {
{DnsHostsKey("host", ADDRESS_FAMILY_IPV4), IPAddress(192, 168, 1, 1)}};
overrides.hosts = hosts;
overrides.append_to_multi_label_name = false;
- overrides.randomize_ports = true;
const int ndots = 5;
overrides.ndots = ndots;
const base::TimeDelta timeout = base::TimeDelta::FromSeconds(10);
@@ -7109,7 +7108,6 @@ TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides) {
EXPECT_EQ(search, overridden_config->search);
EXPECT_EQ(hosts, overridden_config->hosts);
EXPECT_FALSE(overridden_config->append_to_multi_label_name);
- EXPECT_TRUE(overridden_config->randomize_ports);
EXPECT_EQ(ndots, overridden_config->ndots);
EXPECT_EQ(timeout, overridden_config->timeout);
EXPECT_EQ(attempts, overridden_config->attempts);
@@ -7191,7 +7189,6 @@ TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides_PartialOverride) {
EXPECT_EQ(original_config.search, overridden_config->search);
EXPECT_EQ(original_config.hosts, overridden_config->hosts);
EXPECT_TRUE(overridden_config->append_to_multi_label_name);
- EXPECT_FALSE(overridden_config->randomize_ports);
EXPECT_EQ(original_config.ndots, overridden_config->ndots);
EXPECT_EQ(original_config.timeout, overridden_config->timeout);
EXPECT_EQ(original_config.attempts, overridden_config->attempts);
diff --git a/chromium/net/dns/host_resolver_proc.cc b/chromium/net/dns/host_resolver_proc.cc
index 9b8f30eda6f..9fc966797bd 100644
--- a/chromium/net/dns/host_resolver_proc.cc
+++ b/chromium/net/dns/host_resolver_proc.cc
@@ -159,7 +159,7 @@ int SystemHostResolverCall(const std::string& host,
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::WILL_BLOCK);
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \
+#if defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_OPENBSD) && \
!defined(OS_ANDROID) && !defined(OS_FUCHSIA)
DnsReloaderMaybeReload();
#endif
diff --git a/chromium/net/dns/httpssvc_metrics.cc b/chromium/net/dns/httpssvc_metrics.cc
index 453e2a32ed2..58a033aa3b5 100644
--- a/chromium/net/dns/httpssvc_metrics.cc
+++ b/chromium/net/dns/httpssvc_metrics.cc
@@ -59,7 +59,6 @@ bool HttpssvcExperimentDomainCache::IsExperimental(base::StringPiece domain) {
}
bool HttpssvcExperimentDomainCache::IsControl(base::StringPiece domain) {
- std::vector<base::StringPiece> control_domains;
if (!base::FeatureList::IsEnabled(features::kDnsHttpssvc))
return false;
if (features::kDnsHttpssvcControlDomainWildcard.Get())
@@ -153,8 +152,8 @@ void HttpssvcMetrics::RecordIntegrityMetrics() {
DCHECK(base::FeatureList::IsEnabled(features::kDnsHttpssvc));
DCHECK(features::kDnsHttpssvcUseIntegrity.Get());
- DCHECK(in_progress_);
- in_progress_ = false;
+ DCHECK(!already_recorded_);
+ already_recorded_ = true;
// We really have no metrics to record without |integrity_resolve_time_| and
// |non_integrity_resolve_times_|. If this HttpssvcMetrics is in an
@@ -198,14 +197,19 @@ void HttpssvcMetrics::RecordIntegrityCommonMetrics() {
non_integrity_resolve_times_.end());
DCHECK(slowest_non_integrity_resolve != non_integrity_resolve_times_.end());
+ // It's possible to get here with a zero resolve time in tests. Avoid
+ // divide-by-zero below by returning early; this data point is invalid anyway.
+ if (slowest_non_integrity_resolve->is_zero())
+ return;
+
// Compute a percentage showing how much larger the INTEGRITY resolve time was
// compared to the slowest A or AAAA query.
//
// Computation happens on TimeDelta objects, which use CheckedNumeric. This
// will crash if the system clock leaps forward several hundred millennia
// (numeric_limits<int64_t>::max() microseconds ~= 292,000 years).
- const int64_t resolve_time_percent =
- (100 * *integrity_resolve_time_) / *slowest_non_integrity_resolve;
+ const int64_t resolve_time_percent = base::ClampFloor<int64_t>(
+ *integrity_resolve_time_ / *slowest_non_integrity_resolve * 100);
// Scale the value of |resolve_time_percent| by dividing by |kPercentScale|.
// Sample values are bounded between 1 and 20. A recorded sample of 10 means
diff --git a/chromium/net/dns/httpssvc_metrics.h b/chromium/net/dns/httpssvc_metrics.h
index 76e4795cafc..8594b7c54da 100644
--- a/chromium/net/dns/httpssvc_metrics.h
+++ b/chromium/net/dns/httpssvc_metrics.h
@@ -93,10 +93,10 @@ class NET_EXPORT_PRIVATE HttpssvcMetrics {
void set_doh_provider_id(base::Optional<std::string> doh_provider_id);
+ const bool expect_intact_;
// RecordIntegrityMetrics() will do nothing when |disqualified_| is true.
bool disqualified_ = false;
- const bool expect_intact_;
- bool in_progress_ = true;
+ bool already_recorded_ = false;
base::Optional<std::string> doh_provider_id_;
base::Optional<enum HttpssvcDnsRcode> rcode_integrity_;
size_t num_integrity_records_ = 0;
diff --git a/chromium/net/dns/mdns_cache.cc b/chromium/net/dns/mdns_cache.cc
index 53cb2c61982..b23a5a610e8 100644
--- a/chromium/net/dns/mdns_cache.cc
+++ b/chromium/net/dns/mdns_cache.cc
@@ -9,6 +9,7 @@
#include <utility>
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "net/dns/public/dns_protocol.h"
#include "net/dns/record_parsed.h"
#include "net/dns/record_rdata.h"
@@ -26,10 +27,12 @@ constexpr size_t kDefaultEntryLimit = 100'000;
// Section 10.1.
static const unsigned kZeroTTLSeconds = 1;
-MDnsCache::Key::Key(unsigned type, const std::string& name,
+MDnsCache::Key::Key(unsigned type,
+ const std::string& name,
const std::string& optional)
- : type_(type), name_(name), optional_(optional) {
-}
+ : type_(type),
+ name_lowercase_(base::ToLowerASCII(name)),
+ optional_(optional) {}
MDnsCache::Key::Key(const MDnsCache::Key& other) = default;
@@ -39,12 +42,13 @@ MDnsCache::Key& MDnsCache::Key::operator=(const MDnsCache::Key& other) =
MDnsCache::Key::~Key() = default;
bool MDnsCache::Key::operator<(const MDnsCache::Key& other) const {
- return std::tie(name_, type_, optional_) <
- std::tie(other.name_, other.type_, other.optional_);
+ return std::tie(name_lowercase_, type_, optional_) <
+ std::tie(other.name_lowercase_, other.type_, other.optional_);
}
bool MDnsCache::Key::operator==(const MDnsCache::Key& key) const {
- return type_ == key.type_ && name_ == key.name_ && optional_ == key.optional_;
+ return type_ == key.type_ && name_lowercase_ == key.name_lowercase_ &&
+ optional_ == key.optional_;
}
// static
@@ -133,9 +137,10 @@ void MDnsCache::FindDnsRecords(unsigned type,
DCHECK(results);
results->clear();
+ const std::string name_lowercase = base::ToLowerASCII(name);
auto i = mdns_cache_.lower_bound(Key(type, name, ""));
for (; i != mdns_cache_.end(); ++i) {
- if (i->first.name() != name ||
+ if (i->first.name_lowercase() != name_lowercase ||
(type != 0 && i->first.type() != type)) {
break;
}
diff --git a/chromium/net/dns/mdns_cache.h b/chromium/net/dns/mdns_cache.h
index 6e91a9c067d..0dfaa163b39 100644
--- a/chromium/net/dns/mdns_cache.h
+++ b/chromium/net/dns/mdns_cache.h
@@ -39,14 +39,14 @@ class NET_EXPORT_PRIVATE MDnsCache {
bool operator==(const Key& key) const;
unsigned type() const { return type_; }
- const std::string& name() const { return name_; }
+ const std::string& name_lowercase() const { return name_lowercase_; }
const std::string& optional() const { return optional_; }
// Create the cache key corresponding to |record|.
static Key CreateFor(const RecordParsed* record);
private:
unsigned type_;
- std::string name_;
+ std::string name_lowercase_;
std::string optional_;
};
diff --git a/chromium/net/dns/mdns_cache_unittest.cc b/chromium/net/dns/mdns_cache_unittest.cc
index aa83e615097..b7fed7518df 100644
--- a/chromium/net/dns/mdns_cache_unittest.cc
+++ b/chromium/net/dns/mdns_cache_unittest.cc
@@ -99,6 +99,26 @@ static const uint8_t kTestResponsesGoodbyePacket[] = {
74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
};
+static const uint8_t kTestResponsesDifferentCapitalization[] = {
+ // Answer 1
+ // GHS.l.google.com in DNS format.
+ 3, 'G', 'H', 'S', 1, 'l', 6, 'g', 'o', 'o', 'g', 'l', 'e', 3, 'c', 'o', 'm',
+ 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 121, // RDATA is the IP: 74.125.95.121
+
+ // Answer 2
+ // ghs.l.GOOGLE.com in DNS format.
+ 3, 'g', 'h', 's', 1, 'l', 6, 'G', 'O', 'O', 'G', 'L', 'E', 3, 'c', 'o', 'm',
+ 0x00, 0x00, 0x01, // TYPE is A.
+ 0x00, 0x01, // CLASS is IN.
+ 0, 0, 0, 53, // TTL (4 bytes) is 53 seconds.
+ 0, 4, // RDLENGTH is 4 bytes.
+ 74, 125, 95, 122, // RDATA is the IP: 74.125.95.122
+};
+
class RecordRemovalMock {
public:
MOCK_METHOD1(OnRecordRemoved, void(const RecordParsed*));
@@ -402,4 +422,28 @@ TEST_F(MDnsCacheTest, ClearOnOverfilledCleanup) {
EXPECT_TRUE(results.empty());
}
+TEST_F(MDnsCacheTest, CaseInsensitive) {
+ DnsRecordParser parser(kTestResponsesDifferentCapitalization,
+ sizeof(kTestResponsesDifferentCapitalization), 0);
+
+ std::unique_ptr<const RecordParsed> record1;
+ std::unique_ptr<const RecordParsed> record2;
+ std::vector<const RecordParsed*> results;
+
+ record1 = RecordParsed::CreateFrom(&parser, default_time_);
+ record2 = RecordParsed::CreateFrom(&parser, default_time_);
+ EXPECT_EQ(MDnsCache::RecordAdded, cache_.UpdateDnsRecord(std::move(record1)));
+ EXPECT_EQ(MDnsCache::RecordChanged,
+ cache_.UpdateDnsRecord(std::move(record2)));
+
+ cache_.FindDnsRecords(0, "ghs.l.google.com", &results, default_time_);
+
+ EXPECT_EQ(1u, results.size());
+ EXPECT_EQ("ghs.l.GOOGLE.com", results[0]->name());
+
+ std::vector<const RecordParsed*> results2;
+ cache_.FindDnsRecords(0, "GHS.L.google.COM", &results2, default_time_);
+ EXPECT_EQ(results, results2);
+}
+
} // namespace net
diff --git a/chromium/net/dns/mdns_client_impl.cc b/chromium/net/dns/mdns_client_impl.cc
index 65adb27f93a..89f2c9337ef 100644
--- a/chromium/net/dns/mdns_client_impl.cc
+++ b/chromium/net/dns/mdns_client_impl.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
@@ -316,9 +317,12 @@ void MDnsClientImpl::Core::NotifyNsecRecord(const RecordParsed* record) {
}
// Alert all listeners waiting for the nonexistent RR types.
- auto i = listeners_.upper_bound(ListenerKey(record->name(), 0));
- for (; i != listeners_.end() && i->first.first == record->name(); i++) {
- if (!rdata->GetBit(i->first.second)) {
+ ListenerKey key(record->name(), 0);
+ auto i = listeners_.upper_bound(key);
+ for (; i != listeners_.end() &&
+ i->first.name_lowercase() == key.name_lowercase();
+ i++) {
+ if (!rdata->GetBit(i->first.type())) {
for (auto& observer : *i->second)
observer.AlertNsecRecord();
}
@@ -330,6 +334,17 @@ void MDnsClientImpl::Core::OnConnectionError(int error) {
VLOG(1) << "MDNS OnConnectionError (code: " << error << ")";
}
+MDnsClientImpl::Core::ListenerKey::ListenerKey(const std::string& name,
+ uint16_t type)
+ : name_lowercase_(base::ToLowerASCII(name)), type_(type) {}
+
+bool MDnsClientImpl::Core::ListenerKey::operator<(
+ const MDnsClientImpl::Core::ListenerKey& key) const {
+ if (name_lowercase_ == key.name_lowercase_)
+ return type_ < key.type_;
+ return name_lowercase_ < key.name_lowercase_;
+}
+
void MDnsClientImpl::Core::AlertListeners(
MDnsCache::UpdateType update_type,
const ListenerKey& key,
@@ -574,8 +589,8 @@ void MDnsListenerImpl::ScheduleNextRefresh() {
return;
}
- next_refresh_.Reset(base::Bind(&MDnsListenerImpl::DoRefresh,
- AsWeakPtr()));
+ next_refresh_.Reset(
+ base::BindRepeating(&MDnsListenerImpl::DoRefresh, AsWeakPtr()));
// Schedule refreshes at both 85% and 95% of the original TTL. These will both
// be canceled and rescheduled if the record's TTL is updated due to a
@@ -731,8 +746,8 @@ bool MDnsTransactionImpl::QueryAndListen() {
if (!client_->core()->SendQuery(rrtype_, name_))
return false;
- timeout_.Reset(base::Bind(&MDnsTransactionImpl::SignalTransactionOver,
- AsWeakPtr()));
+ timeout_.Reset(
+ base::BindOnce(&MDnsTransactionImpl::SignalTransactionOver, AsWeakPtr()));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, timeout_.callback(), kTransactionTimeout);
diff --git a/chromium/net/dns/mdns_client_impl.h b/chromium/net/dns/mdns_client_impl.h
index 0efda0b9a42..39606f970a0 100644
--- a/chromium/net/dns/mdns_client_impl.h
+++ b/chromium/net/dns/mdns_client_impl.h
@@ -154,7 +154,19 @@ class NET_EXPORT_PRIVATE MDnsClientImpl : public MDnsClient {
private:
FRIEND_TEST_ALL_PREFIXES(MDnsTest, CacheCleanupWithShortTTL);
- typedef std::pair<std::string, uint16_t> ListenerKey;
+ class ListenerKey {
+ public:
+ ListenerKey(const std::string& name, uint16_t type);
+ ListenerKey(const ListenerKey&) = default;
+ ListenerKey(ListenerKey&&) = default;
+ bool operator<(const ListenerKey& key) const;
+ const std::string& name_lowercase() const { return name_lowercase_; }
+ uint16_t type() const { return type_; }
+
+ private:
+ std::string name_lowercase_;
+ uint16_t type_;
+ };
typedef base::ObserverList<MDnsListenerImpl>::Unchecked ObserverListType;
typedef std::map<ListenerKey, std::unique_ptr<ObserverListType>>
ListenerMap;
@@ -328,7 +340,7 @@ class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>,
MDnsTransaction::ResultCallback callback_;
std::unique_ptr<MDnsListener> listener_;
- base::CancelableCallback<void()> timeout_;
+ base::CancelableOnceCallback<void()> timeout_;
MDnsClientImpl* client_;
diff --git a/chromium/net/dns/mdns_client_unittest.cc b/chromium/net/dns/mdns_client_unittest.cc
index 35342711af0..6ddb5c58eb8 100644
--- a/chromium/net/dns/mdns_client_unittest.cc
+++ b/chromium/net/dns/mdns_client_unittest.cc
@@ -76,6 +76,32 @@ const uint8_t kSamplePacket1[] = {
0x24, 0x75, 0x00, 0x08, // RDLENGTH is 8 bytes.
0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x32};
+const uint8_t kSamplePacket1WithCapitalization[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x81, 0x80, // Standard query response, RA, no error
+ 0x00, 0x00, // No questions (for simplicity)
+ 0x00, 0x02, // 2 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Answer 1
+ 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', 0x04, '_', 'T', 'C', 'P', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x00, // TTL (4 bytes) is 1 second;
+ 0x00, 0x01, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x0c,
+
+ // Answer 2
+ 0x08, '_', 'P', 'r', 'i', 'n', 't', 'e', 'R', 0xc0,
+ 0x14, // Pointer to "._tcp.local"
+ 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+ 0x00, 0x01, // TTL (4 bytes) is 20 hours, 47 minutes, 49 seconds.
+ 0x24, 0x75, 0x00, 0x08, // RDLENGTH is 8 bytes.
+ 0x05, 'h', 'e', 'l', 'l', 'o', 0xc0, 0x32};
+
const uint8_t kCorruptedPacketBadQuestion[] = {
// Header
0x00, 0x00, // ID is zeroed out
@@ -248,6 +274,22 @@ const uint8_t kQueryPacketPrivet[] = {
0x00, 0x01, // CLASS is IN.
};
+const uint8_t kQueryPacketPrivetWithCapitalization[] = {
+ // Header
+ 0x00, 0x00, // ID is zeroed out
+ 0x00, 0x00, // No flags.
+ 0x00, 0x01, // One question.
+ 0x00, 0x00, // 0 RRs (answers)
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+
+ // Question
+ // This part is echoed back from the respective query.
+ 0x07, '_', 'P', 'R', 'I', 'V', 'E', 'T', 0x04, '_', 't', 'c', 'p', 0x05,
+ 'l', 'o', 'c', 'a', 'l', 0x00, 0x00, 0x0c, // TYPE is PTR.
+ 0x00, 0x01, // CLASS is IN.
+};
+
const uint8_t kQueryPacketPrivetA[] = {
// Header
0x00, 0x00, // ID is zeroed out
@@ -469,8 +511,8 @@ void MDnsTest::DeleteBothListeners() {
}
void MDnsTest::RunFor(base::TimeDelta time_period) {
- base::CancelableCallback<void()> callback(base::Bind(&MDnsTest::Stop,
- base::Unretained(this)));
+ base::CancelableOnceCallback<void()> callback(
+ base::BindOnce(&MDnsTest::Stop, base::Unretained(this)));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, callback.callback(), time_period);
@@ -525,6 +567,48 @@ TEST_F(MDnsTest, PassiveListeners) {
listener_printer.reset();
}
+TEST_F(MDnsTest, PassiveListenersWithCapitalization) {
+ StrictMock<MockListenerDelegate> delegate_privet;
+ StrictMock<MockListenerDelegate> delegate_printer;
+
+ PtrRecordCopyContainer record_privet;
+ PtrRecordCopyContainer record_printer;
+
+ std::unique_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
+ dns_protocol::kTypePTR, "_privet._tcp.LOCAL", &delegate_privet);
+ std::unique_ptr<MDnsListener> listener_printer = test_client_->CreateListener(
+ dns_protocol::kTypePTR, "_prinTER._Tcp.Local", &delegate_printer);
+
+ ASSERT_TRUE(listener_privet->Start());
+ ASSERT_TRUE(listener_printer->Start());
+
+ // Send the same packet twice to ensure no records are double-counted.
+
+ EXPECT_CALL(delegate_privet, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
+ .Times(Exactly(1))
+ .WillOnce(
+ Invoke(&record_privet, &PtrRecordCopyContainer::SaveWithDummyArg));
+
+ EXPECT_CALL(delegate_printer, OnRecordUpdate(MDnsListener::RECORD_ADDED, _))
+ .Times(Exactly(1))
+ .WillOnce(
+ Invoke(&record_printer, &PtrRecordCopyContainer::SaveWithDummyArg));
+
+ SimulatePacketReceive(kSamplePacket1WithCapitalization,
+ sizeof(kSamplePacket1WithCapitalization));
+ SimulatePacketReceive(kSamplePacket1WithCapitalization,
+ sizeof(kSamplePacket1WithCapitalization));
+
+ EXPECT_TRUE(record_privet.IsRecordWith("_privet._TCP.local",
+ "hello._privet._TCP.local"));
+
+ EXPECT_TRUE(record_printer.IsRecordWith("_PrinteR._TCP.local",
+ "hello._PrinteR._TCP.local"));
+
+ listener_privet.reset();
+ listener_printer.reset();
+}
+
TEST_F(MDnsTest, PassiveListenersCacheCleanup) {
StrictMock<MockListenerDelegate> delegate_privet;
@@ -709,6 +793,34 @@ TEST_F(MDnsTest, TransactionWithEmptyCache) {
"hello._privet._tcp.local"));
}
+TEST_F(MDnsTest, TransactionWithEmptyCacheAndCapitalization) {
+ ExpectPacket(kQueryPacketPrivetWithCapitalization,
+ sizeof(kQueryPacketPrivetWithCapitalization));
+
+ std::unique_ptr<MDnsTransaction> transaction_privet =
+ test_client_->CreateTransaction(
+ dns_protocol::kTypePTR, "_PRIVET._tcp.local",
+ MDnsTransaction::QUERY_NETWORK | MDnsTransaction::QUERY_CACHE |
+ MDnsTransaction::SINGLE_RESULT,
+ base::BindRepeating(&MDnsTest::MockableRecordCallback,
+ base::Unretained(this)));
+
+ ASSERT_TRUE(transaction_privet->Start());
+
+ PtrRecordCopyContainer record_privet;
+
+ EXPECT_CALL(*this, MockableRecordCallback(MDnsTransaction::RESULT_RECORD, _))
+ .Times(Exactly(1))
+ .WillOnce(
+ Invoke(&record_privet, &PtrRecordCopyContainer::SaveWithDummyArg));
+
+ SimulatePacketReceive(kSamplePacket1WithCapitalization,
+ sizeof(kSamplePacket1WithCapitalization));
+
+ EXPECT_TRUE(record_privet.IsRecordWith("_privet._TCP.local",
+ "hello._privet._TCP.local"));
+}
+
TEST_F(MDnsTest, TransactionCacheOnlyNoResult) {
std::unique_ptr<MDnsTransaction> transaction_privet =
test_client_->CreateTransaction(
diff --git a/chromium/net/dns/public/util.cc b/chromium/net/dns/public/util.cc
index 5aab840a2b3..d93cf0de961 100644
--- a/chromium/net/dns/public/util.cc
+++ b/chromium/net/dns/public/util.cc
@@ -77,7 +77,7 @@ IPEndPoint GetMdnsReceiveEndPoint(AddressFamily address_family) {
// CrOS as described in crbug.com/931916, and the following is a temporary
// mitigation to reconcile the two issues. Remove this after closing
// crbug.com/899310.
-#if defined(OS_WIN) || defined(OS_FUCHSIA) || defined(OS_MACOSX)
+#if defined(OS_WIN) || defined(OS_FUCHSIA) || defined(OS_APPLE)
// With Windows, binding to a mulitcast group address is not allowed.
// Multicast messages will be received appropriate to the multicast groups the
// socket has joined. Sockets intending to receive multicast messages should
@@ -93,12 +93,12 @@ IPEndPoint GetMdnsReceiveEndPoint(AddressFamily address_family) {
NOTREACHED();
return IPEndPoint();
}
-#else // !(defined(OS_WIN) || defined(OS_FUCHSIA)) || defined(OS_MACOSX)
+#else // !(defined(OS_WIN) || defined(OS_FUCHSIA)) || defined(OS_APPLE)
// With POSIX, any socket can receive messages for multicast groups joined by
// any socket on the system. Sockets intending to receive messages for a
// specific multicast group should bind to that group address.
return GetMdnsGroupEndPoint(address_family);
-#endif // !(defined(OS_WIN) || defined(OS_FUCHSIA)) || defined(OS_MACOSX)
+#endif // !(defined(OS_WIN) || defined(OS_FUCHSIA)) || defined(OS_APPLE)
}
} // namespace dns_util
diff --git a/chromium/net/dns/resolve_context.cc b/chromium/net/dns/resolve_context.cc
index 3b15cf320ec..57b75f6566a 100644
--- a/chromium/net/dns/resolve_context.cc
+++ b/chromium/net/dns/resolve_context.cc
@@ -408,7 +408,7 @@ void ResolveContext::RecordRttForUma(size_t server_index,
// continue in parallel with new attempts made by the transaction. Scale
// the ratio up by 10 for sub-integer granularity.
// TODO(crbug.com/1105138): Remove after determining good timeout logic.
- int timeout_ratio = 10 * rtt / base_timeout;
+ int timeout_ratio = base::ClampFloor(rtt / base_timeout * 10);
UMA_HISTOGRAM_COUNTS_1000(
"Net.DNS.DnsTransaction.SecureValidated.SuccessTimeoutRatio",
timeout_ratio);
diff --git a/chromium/net/dns/resolve_context_unittest.cc b/chromium/net/dns/resolve_context_unittest.cc
index 5de6a10e3f3..2b432fc378a 100644
--- a/chromium/net/dns/resolve_context_unittest.cc
+++ b/chromium/net/dns/resolve_context_unittest.cc
@@ -23,7 +23,7 @@
#include "net/dns/dns_config.h"
#include "net/dns/dns_server_iterator.h"
#include "net/dns/dns_session.h"
-#include "net/dns/dns_socket_pool.h"
+#include "net/dns/dns_socket_allocator.h"
#include "net/dns/host_cache.h"
#include "net/dns/host_resolver_source.h"
#include "net/dns/public/dns_over_https_server_config.h"
@@ -46,12 +46,12 @@ class ResolveContextTest : public TestWithTaskEnvironment {
scoped_refptr<DnsSession> CreateDnsSession(const DnsConfig& config) {
auto null_random_callback =
base::BindRepeating([](int, int) -> int { IMMEDIATE_CRASH(); });
- std::unique_ptr<DnsSocketPool> dns_socket_pool =
- DnsSocketPool::CreateNull(socket_factory_.get(), null_random_callback);
+ auto dns_socket_allocator = std::make_unique<DnsSocketAllocator>(
+ socket_factory_.get(), config.nameservers, nullptr /* net_log */);
- return base::MakeRefCounted<DnsSession>(config, std::move(dns_socket_pool),
- null_random_callback,
- nullptr /* netlog */);
+ return base::MakeRefCounted<DnsSession>(
+ config, std::move(dns_socket_allocator), null_random_callback,
+ nullptr /* netlog */);
}
protected:
diff --git a/chromium/net/dns/serial_worker_unittest.cc b/chromium/net/dns/serial_worker_unittest.cc
index d7ce1f8fc23..061b54a0f29 100644
--- a/chromium/net/dns/serial_worker_unittest.cc
+++ b/chromium/net/dns/serial_worker_unittest.cc
@@ -6,11 +6,11 @@
#include "base/bind.h"
#include "base/location.h"
-#include "base/message_loop/message_loop_current.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/current_thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/test/test_with_task_environment.h"
@@ -158,7 +158,7 @@ TEST_F(SerialWorkerTest, ExecuteAndSerializeReads) {
WaitForWork();
RunUntilBreak("OnWorkFinished");
- EXPECT_TRUE(base::MessageLoopCurrent::Get()->IsIdleForTesting());
+ EXPECT_TRUE(base::CurrentThread::Get()->IsIdleForTesting());
}
// Schedule two calls. OnWork checks if it is called serially.
@@ -171,7 +171,7 @@ TEST_F(SerialWorkerTest, ExecuteAndSerializeReads) {
RunUntilBreak("OnWorkFinished");
// No more tasks should remain.
- EXPECT_TRUE(base::MessageLoopCurrent::Get()->IsIdleForTesting());
+ EXPECT_TRUE(base::CurrentThread::Get()->IsIdleForTesting());
}
} // namespace