Commit 779b630b authored by Song Fangzhen's avatar Song Fangzhen Committed by Chromium LUCI CQ

Direct Sockets: Update MockNetworkContext and MockHostResolver.

This CL builds on
https://chromium-review.googlesource.com/c/chromium/src/+/2606873

We update the MockNetworkContext and MockHostResolver to make them
behave the same as in network when resolving hostnames.

And the tests should all pass whithout special machines' failures.

Bug: 1141241
Change-Id: Iffeec31910faafe7e42dd42d15ee4ce63ec9a33d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2624316
Commit-Queue: Ke He <kehe@chromium.org>
Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Reviewed-by: default avatarGlen Robertson <glenrob@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842935}
parent 4b184813
...@@ -59,58 +59,40 @@ struct RecordedCall { ...@@ -59,58 +59,40 @@ struct RecordedCall {
class MockHostResolver : public network::mojom::HostResolver { class MockHostResolver : public network::mojom::HostResolver {
public: public:
explicit MockHostResolver( explicit MockHostResolver(
mojo::PendingReceiver<network::mojom::HostResolver> resolver_receiver) mojo::PendingReceiver<network::mojom::HostResolver> resolver_receiver,
: receiver_(this) { net::HostResolver* internal_resolver)
: receiver_(this), internal_resolver_(internal_resolver) {
receiver_.Bind(std::move(resolver_receiver)); receiver_.Bind(std::move(resolver_receiver));
} }
MockHostResolver(const MockHostResolver&) = delete; MockHostResolver(const MockHostResolver&) = delete;
MockHostResolver& operator=(const MockHostResolver&) = delete; MockHostResolver& operator=(const MockHostResolver&) = delete;
static std::map<std::string, std::string>& known_hosts() { void ResolveHost(const ::net::HostPortPair& host,
static base::NoDestructor<std::map<std::string, std::string>> hosts;
return *hosts;
}
void ResolveHost(const ::net::HostPortPair& host_port_pair,
const ::net::NetworkIsolationKey& network_isolation_key, const ::net::NetworkIsolationKey& network_isolation_key,
network::mojom::ResolveHostParametersPtr optional_parameters, network::mojom::ResolveHostParametersPtr optional_parameters,
::mojo::PendingRemote<network::mojom::ResolveHostClient> ::mojo::PendingRemote<network::mojom::ResolveHostClient>
pending_response_client) override { pending_response_client) override {
DCHECK(!internal_request_);
DCHECK(!response_client_.is_bound());
internal_request_ = internal_resolver_->CreateRequest(
host, network_isolation_key,
net::NetLogWithSource::Make(net::NetLog::Get(),
net::NetLogSourceType::NONE),
base::nullopt);
mojo::Remote<network::mojom::ResolveHostClient> response_client( mojo::Remote<network::mojom::ResolveHostClient> response_client(
std::move(pending_response_client)); std::move(pending_response_client));
std::string host = host_port_pair.host(); int rv = internal_request_->Start(
auto iter = known_hosts().find(host); base::BindOnce(&MockHostResolver::OnComplete, base::Unretained(this)));
if (iter != known_hosts().end()) if (rv != net::ERR_IO_PENDING) {
host = iter->second; response_client->OnComplete(rv, internal_request_->GetResolveErrorInfo(),
internal_request_->GetAddressResults());
net::IPAddress remote_address; return;
// TODO(crbug.com/1141241): Replace if/else with AssignFromIPLiteral.
if (host.find(':') != std::string::npos) {
// GURL expects IPv6 hostnames to be surrounded with brackets.
std::string host_brackets = base::StrCat({"[", host, "]"});
url::Component host_comp(0, host_brackets.size());
std::array<uint8_t, 16> bytes;
EXPECT_TRUE(url::IPv6AddressToNumber(host_brackets.data(), host_comp,
bytes.data()));
remote_address = net::IPAddress(bytes.data(), bytes.size());
} else {
// Otherwise the string is an IPv4 address.
url::Component host_comp(0, host.size());
std::array<uint8_t, 4> bytes;
int num_components;
url::CanonHostInfo::Family family = url::IPv4AddressToNumber(
host.data(), host_comp, bytes.data(), &num_components);
EXPECT_EQ(family, url::CanonHostInfo::IPV4);
EXPECT_EQ(num_components, 4);
remote_address = net::IPAddress(bytes.data(), bytes.size());
} }
EXPECT_EQ(remote_address.ToString(), host);
response_client->OnComplete(net::OK, net::ResolveErrorInfo(), response_client_ = std::move(response_client);
net::AddressList::CreateFromIPAddress(
remote_address, host_port_pair.port()));
} }
void MdnsListen( void MdnsListen(
...@@ -122,7 +104,20 @@ class MockHostResolver : public network::mojom::HostResolver { ...@@ -122,7 +104,20 @@ class MockHostResolver : public network::mojom::HostResolver {
} }
private: private:
void OnComplete(int error) {
DCHECK(response_client_.is_bound());
DCHECK(internal_request_);
response_client_->OnComplete(error,
internal_request_->GetResolveErrorInfo(),
internal_request_->GetAddressResults());
response_client_.reset();
}
std::unique_ptr<net::HostResolver::ResolveHostRequest> internal_request_;
mojo::Remote<network::mojom::ResolveHostClient> response_client_;
mojo::Receiver<network::mojom::HostResolver> receiver_; mojo::Receiver<network::mojom::HostResolver> receiver_;
net::HostResolver* const internal_resolver_;
}; };
class MockNetworkContext : public network::TestNetworkContext { class MockNetworkContext : public network::TestNetworkContext {
...@@ -163,13 +158,29 @@ class MockNetworkContext : public network::TestNetworkContext { ...@@ -163,13 +158,29 @@ class MockNetworkContext : public network::TestNetworkContext {
const base::Optional<net::DnsConfigOverrides>& config_overrides, const base::Optional<net::DnsConfigOverrides>& config_overrides,
mojo::PendingReceiver<network::mojom::HostResolver> receiver) override { mojo::PendingReceiver<network::mojom::HostResolver> receiver) override {
DCHECK(!config_overrides.has_value()); DCHECK(!config_overrides.has_value());
DCHECK(!internal_resolver_);
DCHECK(!host_resolver_); DCHECK(!host_resolver_);
host_resolver_ = std::make_unique<MockHostResolver>(std::move(receiver));
internal_resolver_ = net::HostResolver::CreateStandaloneResolver(
net::NetLog::Get(), /*options=*/base::nullopt, host_mapping_rules_,
/*enable_caching=*/false);
host_resolver_ = std::make_unique<MockHostResolver>(
std::move(receiver), internal_resolver_.get());
}
// If set to non-empty, the mapping rules will be applied to requests to the
// created internal host resolver. See MappedHostResolver for details. Should
// be called before CreateHostResolver().
void set_host_mapping_rules(std::string host_mapping_rules) {
DCHECK(!internal_resolver_);
host_mapping_rules_ = std::move(host_mapping_rules);
} }
private: private:
const net::Error result_; const net::Error result_;
std::vector<RecordedCall> history_; std::vector<RecordedCall> history_;
std::string host_mapping_rules_;
std::unique_ptr<net::HostResolver> internal_resolver_;
std::unique_ptr<network::mojom::HostResolver> host_resolver_; std::unique_ptr<network::mojom::HostResolver> host_resolver_;
}; };
...@@ -287,9 +298,11 @@ IN_PROC_BROWSER_TEST_F(DirectSocketsBrowserTest, OpenTcp_Success_Hostname) { ...@@ -287,9 +298,11 @@ IN_PROC_BROWSER_TEST_F(DirectSocketsBrowserTest, OpenTcp_Success_Hostname) {
const char kExampleHostname[] = "mail.example.com"; const char kExampleHostname[] = "mail.example.com";
const char kExampleAddress[] = "98.76.54.32"; const char kExampleAddress[] = "98.76.54.32";
MockHostResolver::known_hosts()[kExampleHostname] = kExampleAddress; const std::string mapping_rules =
base::StringPrintf("MAP %s %s", kExampleHostname, kExampleAddress);
MockNetworkContext mock_network_context(net::OK); MockNetworkContext mock_network_context(net::OK);
mock_network_context.set_host_mapping_rules(mapping_rules);
DirectSocketsServiceImpl::SetNetworkContextForTesting(&mock_network_context); DirectSocketsServiceImpl::SetNetworkContextForTesting(&mock_network_context);
const std::string expected_result = base::StringPrintf( const std::string expected_result = base::StringPrintf(
"openTcp succeeded: {remoteAddress: \"%s\", remotePort: 993}", "openTcp succeeded: {remoteAddress: \"%s\", remotePort: 993}",
......
...@@ -53,7 +53,6 @@ base::Optional<net::IPEndPoint> GetLocalAddr( ...@@ -53,7 +53,6 @@ base::Optional<net::IPEndPoint> GetLocalAddr(
return local_addr; return local_addr;
} }
// True if |hostname| ends with either ".local" or ".local.".
bool ResemblesMulticastDNSName(const std::string& hostname) { bool ResemblesMulticastDNSName(const std::string& hostname) {
return base::EndsWith(hostname, ".local") || return base::EndsWith(hostname, ".local") ||
base::EndsWith(hostname, ".local."); base::EndsWith(hostname, ".local.");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment