Service API for HostResolver MDNS listener
Bug: 922161
Change-Id: I33ba427d5449a0e93d36bdd9078d8a9b59b90422
Reviewed-on: https://chromium-review.googlesource.com/c/1413057
Commit-Queue: Eric Orth <ericorth@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Maks Orlovich <morlovich@chromium.org>
Cr-Commit-Position: refs/heads/master@{#625337}
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn
index 2795da5b..6a852c7d 100644
--- a/services/network/BUILD.gn
+++ b/services/network/BUILD.gn
@@ -38,6 +38,8 @@
"empty_url_loader_client.h",
"host_resolver.cc",
"host_resolver.h",
+ "host_resolver_mdns_listener.cc",
+ "host_resolver_mdns_listener.h",
"http_auth_cache_copier.cc",
"http_auth_cache_copier.h",
"http_cache_data_counter.cc",
diff --git a/services/network/host_resolver.cc b/services/network/host_resolver.cc
index cf52398..a9039450 100644
--- a/services/network/host_resolver.cc
+++ b/services/network/host_resolver.cc
@@ -14,6 +14,7 @@
#include "net/dns/host_resolver.h"
#include "net/dns/host_resolver_source.h"
#include "net/log/net_log.h"
+#include "services/network/host_resolver_mdns_listener.h"
#include "services/network/resolve_host_request.h"
namespace network {
@@ -100,6 +101,28 @@
DCHECK(insertion_result);
}
+void HostResolver::MdnsListen(const net::HostPortPair& host,
+ net::DnsQueryType query_type,
+ mojom::MdnsListenClientPtr response_client,
+ MdnsListenCallback callback) {
+#if !BUILDFLAG(ENABLE_MDNS)
+ NOTREACHED();
+#endif // !BUILDFLAG(ENABLE_MDNS)
+
+ auto listener = std::make_unique<HostResolverMdnsListener>(internal_resolver_,
+ host, query_type);
+ int rv =
+ listener->Start(std::move(response_client),
+ base::BindOnce(&HostResolver::OnMdnsListenerCancelled,
+ base::Unretained(this), listener.get()));
+ if (rv == net::OK) {
+ bool insertion_result = listeners_.emplace(std::move(listener)).second;
+ DCHECK(insertion_result);
+ }
+
+ std::move(callback).Run(rv);
+}
+
size_t HostResolver::GetNumOutstandingRequestsForTesting() const {
return requests_.size();
}
@@ -118,6 +141,12 @@
requests_.erase(found_request);
}
+void HostResolver::OnMdnsListenerCancelled(HostResolverMdnsListener* listener) {
+ auto found_listener = listeners_.find(listener);
+ DCHECK(found_listener != listeners_.end());
+ listeners_.erase(found_listener);
+}
+
void HostResolver::OnConnectionError() {
DCHECK(connection_shutdown_callback_);
diff --git a/services/network/host_resolver.h b/services/network/host_resolver.h
index fb4c00e7..b4629c6 100644
--- a/services/network/host_resolver.h
+++ b/services/network/host_resolver.h
@@ -7,12 +7,14 @@
#include <memory>
#include <set>
+#include <string>
#include "base/callback.h"
#include "base/component_export.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "net/dns/public/dns_query_type.h"
#include "services/network/public/mojom/host_resolver.mojom.h"
namespace net {
@@ -22,6 +24,7 @@
} // namespace net
namespace network {
+class HostResolverMdnsListener;
class ResolveHostRequest;
class COMPONENT_EXPORT(NETWORK_SERVICE) HostResolver
@@ -47,6 +50,10 @@
void ResolveHost(const net::HostPortPair& host,
mojom::ResolveHostParametersPtr optional_parameters,
mojom::ResolveHostClientPtr response_client) override;
+ void MdnsListen(const net::HostPortPair& host,
+ net::DnsQueryType query_type,
+ mojom::MdnsListenClientPtr response_client,
+ MdnsListenCallback callback) override;
size_t GetNumOutstandingRequestsForTesting() const;
@@ -57,12 +64,15 @@
private:
void OnResolveHostComplete(ResolveHostRequest* request, int error);
+ void OnMdnsListenerCancelled(HostResolverMdnsListener* listener);
void OnConnectionError();
mojo::Binding<mojom::HostResolver> binding_;
ConnectionShutdownCallback connection_shutdown_callback_;
std::set<std::unique_ptr<ResolveHostRequest>, base::UniquePtrComparator>
requests_;
+ std::set<std::unique_ptr<HostResolverMdnsListener>, base::UniquePtrComparator>
+ listeners_;
net::HostResolver* const internal_resolver_;
net::NetLog* const net_log_;
diff --git a/services/network/host_resolver_mdns_listener.cc b/services/network/host_resolver_mdns_listener.cc
new file mode 100644
index 0000000..55732e3
--- /dev/null
+++ b/services/network/host_resolver_mdns_listener.cc
@@ -0,0 +1,88 @@
+// Copyright 2019 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 "services/network/host_resolver_mdns_listener.h"
+
+#include <utility>
+
+#include "base/callback.h"
+#include "net/base/host_port_pair.h"
+
+namespace network {
+
+HostResolverMdnsListener::HostResolverMdnsListener(
+ net::HostResolver* resolver,
+ const net::HostPortPair& host,
+ net::DnsQueryType query_type) {
+ DCHECK(resolver);
+
+ internal_listener_ = resolver->CreateMdnsListener(host, query_type);
+}
+
+HostResolverMdnsListener::~HostResolverMdnsListener() {
+ internal_listener_ = nullptr;
+ response_client_ = nullptr;
+}
+
+int HostResolverMdnsListener::Start(mojom::MdnsListenClientPtr response_client,
+ base::OnceClosure cancellation_callback) {
+ DCHECK(internal_listener_);
+ DCHECK(!response_client_.is_bound());
+
+ int rv = internal_listener_->Start(this);
+ if (rv != net::OK)
+ return rv;
+
+ response_client_ = std::move(response_client);
+ // Unretained |this| reference is safe because connection error cannot occur
+ // if |response_client_| goes out of scope.
+ response_client_.set_connection_error_handler(base::BindOnce(
+ &HostResolverMdnsListener::OnConnectionError, base::Unretained(this)));
+
+ cancellation_callback_ = std::move(cancellation_callback);
+
+ return net::OK;
+}
+
+void HostResolverMdnsListener::OnAddressResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType update_type,
+ net::DnsQueryType query_type,
+ net::IPEndPoint address) {
+ DCHECK(response_client_.is_bound());
+ response_client_->OnAddressResult(update_type, query_type, address);
+}
+
+void HostResolverMdnsListener::OnTextResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType update_type,
+ net::DnsQueryType query_type,
+ std::vector<std::string> text_records) {
+ DCHECK(response_client_.is_bound());
+ response_client_->OnTextResult(update_type, query_type, text_records);
+}
+
+void HostResolverMdnsListener::OnHostnameResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType update_type,
+ net::DnsQueryType query_type,
+ net::HostPortPair host) {
+ DCHECK(response_client_.is_bound());
+ response_client_->OnHostnameResult(update_type, query_type, host);
+}
+
+void HostResolverMdnsListener::OnUnhandledResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType update_type,
+ net::DnsQueryType query_type) {
+ DCHECK(response_client_.is_bound());
+ response_client_->OnUnhandledResult(update_type, query_type);
+}
+
+void HostResolverMdnsListener::OnConnectionError() {
+ DCHECK(cancellation_callback_);
+
+ internal_listener_ = nullptr;
+
+ // Invoke cancellation callback last as it may delete |this|.
+ std::move(cancellation_callback_).Run();
+}
+
+} // namespace network
diff --git a/services/network/host_resolver_mdns_listener.h b/services/network/host_resolver_mdns_listener.h
new file mode 100644
index 0000000..7f14e25
--- /dev/null
+++ b/services/network/host_resolver_mdns_listener.h
@@ -0,0 +1,66 @@
+// Copyright 2019 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 SERVICES_NETWORK_HOST_RESOLVER_MDNS_LISTENER_H_
+#define SERVICES_NETWORK_HOST_RESOLVER_MDNS_LISTENER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "net/base/ip_endpoint.h"
+#include "net/dns/host_resolver.h"
+#include "net/dns/public/dns_query_type.h"
+#include "services/network/public/mojom/host_resolver.mojom.h"
+
+namespace net {
+class HostPortPair;
+} // namespace net
+
+namespace network {
+
+class HostResolverMdnsListener
+ : public net::HostResolver::MdnsListener::Delegate {
+ public:
+ HostResolverMdnsListener(net::HostResolver* resolver,
+ const net::HostPortPair& host,
+ net::DnsQueryType query_type);
+ ~HostResolverMdnsListener() override;
+
+ int Start(mojom::MdnsListenClientPtr response_client,
+ base::OnceClosure cancellation_callback);
+
+ // net::HostResolver::MdnsListenerDelegate implementation
+ void OnAddressResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType update_type,
+ net::DnsQueryType query_type,
+ net::IPEndPoint address) override;
+ void OnTextResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType update_type,
+ net::DnsQueryType query_type,
+ std::vector<std::string> text_records) override;
+ void OnHostnameResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType update_type,
+ net::DnsQueryType query_type,
+ net::HostPortPair host) override;
+ void OnUnhandledResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType update_type,
+ net::DnsQueryType query_type) override;
+
+ private:
+ void OnConnectionError();
+
+ std::unique_ptr<net::HostResolver::MdnsListener> internal_listener_;
+ mojom::MdnsListenClientPtr response_client_;
+
+ base::OnceClosure cancellation_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(HostResolverMdnsListener);
+};
+
+} // namespace network
+
+#endif // SERVICES_NETWORK_HOST_RESOLVER_MDNS_LISTENER_H_
diff --git a/services/network/host_resolver_unittest.cc b/services/network/host_resolver_unittest.cc
index 57cbc807..3980779d 100644
--- a/services/network/host_resolver_unittest.cc
+++ b/services/network/host_resolver_unittest.cc
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <memory>
-#include <string>
+#include "services/network/host_resolver.h"
+
+#include <map>
#include <utility>
#include <vector>
@@ -13,7 +14,6 @@
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_tick_clock.h"
-#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/base/address_list.h"
#include "net/base/host_port_pair.h"
@@ -22,13 +22,11 @@
#include "net/base/net_errors.h"
#include "net/dns/dns_config.h"
#include "net/dns/dns_test_util.h"
+#include "net/dns/host_resolver.h"
#include "net/dns/host_resolver_impl.h"
#include "net/dns/mock_host_resolver.h"
#include "net/dns/public/dns_protocol.h"
-#include "net/dns/public/dns_query_type.h"
#include "net/log/net_log.h"
-#include "services/network/host_resolver.h"
-#include "services/network/public/mojom/host_resolver.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -118,6 +116,72 @@
base::RunLoop* const run_loop_;
};
+class TestMdnsListenClient : public mojom::MdnsListenClient {
+ public:
+ using UpdateType = net::HostResolver::MdnsListener::Delegate::UpdateType;
+ using UpdateKey = std::pair<UpdateType, net::DnsQueryType>;
+
+ explicit TestMdnsListenClient(mojom::MdnsListenClientPtr* interface_ptr)
+ : binding_(this, mojo::MakeRequest(interface_ptr)) {}
+
+ void OnAddressResult(UpdateType update_type,
+ net::DnsQueryType result_type,
+ const net::IPEndPoint& address) override {
+ address_results_.insert({{update_type, result_type}, address});
+ }
+
+ void OnTextResult(UpdateType update_type,
+ net::DnsQueryType result_type,
+ const std::vector<std::string>& text_records) override {
+ for (auto& text_record : text_records) {
+ text_results_.insert({{update_type, result_type}, text_record});
+ }
+ }
+
+ void OnHostnameResult(UpdateType update_type,
+ net::DnsQueryType result_type,
+ const net::HostPortPair& host) override {
+ hostname_results_.insert({{update_type, result_type}, host});
+ }
+
+ void OnUnhandledResult(UpdateType update_type,
+ net::DnsQueryType result_type) override {
+ unhandled_results_.insert({update_type, result_type});
+ }
+
+ const std::multimap<UpdateKey, net::IPEndPoint>& address_results() {
+ return address_results_;
+ }
+
+ const std::multimap<UpdateKey, std::string>& text_results() {
+ return text_results_;
+ }
+
+ const std::multimap<UpdateKey, net::HostPortPair>& hostname_results() {
+ return hostname_results_;
+ }
+
+ const std::multiset<UpdateKey>& unhandled_results() {
+ return unhandled_results_;
+ }
+
+ template <typename T>
+ static std::pair<UpdateKey, T> CreateExpectedResult(
+ UpdateType update_type,
+ net::DnsQueryType query_type,
+ T result) {
+ return std::make_pair(std::make_pair(update_type, query_type), result);
+ }
+
+ private:
+ mojo::Binding<mojom::MdnsListenClient> binding_;
+
+ std::multimap<UpdateKey, net::IPEndPoint> address_results_;
+ std::multimap<UpdateKey, std::string> text_results_;
+ std::multimap<UpdateKey, net::HostPortPair> hostname_results_;
+ std::multiset<UpdateKey> unhandled_results_;
+};
+
TEST_F(HostResolverTest, Sync) {
auto inner_resolver = std::make_unique<net::MockHostResolver>();
inner_resolver->set_synchronous_mode(true);
@@ -1148,5 +1212,161 @@
EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
}
+#if BUILDFLAG(ENABLE_MDNS)
+TEST_F(HostResolverTest, MdnsListener_AddressResult) {
+ net::NetLog net_log;
+ auto inner_resolver = std::make_unique<net::MockHostResolver>();
+ HostResolver resolver(inner_resolver.get(), &net_log);
+
+ mojom::MdnsListenClientPtr response_client_ptr;
+ TestMdnsListenClient response_client(&response_client_ptr);
+
+ int error = net::ERR_FAILED;
+ base::RunLoop run_loop;
+ net::HostPortPair host("host.local", 41);
+ resolver.MdnsListen(host, net::DnsQueryType::A,
+ std::move(response_client_ptr),
+ base::BindLambdaForTesting([&](int error_val) {
+ error = error_val;
+ run_loop.Quit();
+ }));
+
+ run_loop.Run();
+ ASSERT_EQ(net::OK, error);
+
+ net::IPAddress result_address(1, 2, 3, 4);
+ net::IPEndPoint result(result_address, 41);
+ inner_resolver->TriggerMdnsListeners(
+ host, net::DnsQueryType::A,
+ net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED, result);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(response_client.address_results(),
+ testing::ElementsAre(TestMdnsListenClient::CreateExpectedResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED,
+ net::DnsQueryType::A, result)));
+
+ EXPECT_THAT(response_client.text_results(), testing::IsEmpty());
+ EXPECT_THAT(response_client.hostname_results(), testing::IsEmpty());
+ EXPECT_THAT(response_client.unhandled_results(), testing::IsEmpty());
+}
+
+TEST_F(HostResolverTest, MdnsListener_TextResult) {
+ net::NetLog net_log;
+ auto inner_resolver = std::make_unique<net::MockHostResolver>();
+ HostResolver resolver(inner_resolver.get(), &net_log);
+
+ mojom::MdnsListenClientPtr response_client_ptr;
+ TestMdnsListenClient response_client(&response_client_ptr);
+
+ int error = net::ERR_FAILED;
+ base::RunLoop run_loop;
+ net::HostPortPair host("host.local", 42);
+ resolver.MdnsListen(host, net::DnsQueryType::TXT,
+ std::move(response_client_ptr),
+ base::BindLambdaForTesting([&](int error_val) {
+ error = error_val;
+ run_loop.Quit();
+ }));
+
+ run_loop.Run();
+ ASSERT_EQ(net::OK, error);
+
+ inner_resolver->TriggerMdnsListeners(
+ host, net::DnsQueryType::TXT,
+ net::HostResolver::MdnsListener::Delegate::UpdateType::CHANGED,
+ {"foo", "bar"});
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(
+ response_client.text_results(),
+ testing::UnorderedElementsAre(
+ TestMdnsListenClient::CreateExpectedResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType::CHANGED,
+ net::DnsQueryType::TXT, "foo"),
+ TestMdnsListenClient::CreateExpectedResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType::CHANGED,
+ net::DnsQueryType::TXT, "bar")));
+
+ EXPECT_THAT(response_client.address_results(), testing::IsEmpty());
+ EXPECT_THAT(response_client.hostname_results(), testing::IsEmpty());
+ EXPECT_THAT(response_client.unhandled_results(), testing::IsEmpty());
+}
+
+TEST_F(HostResolverTest, MdnsListener_HostnameResult) {
+ net::NetLog net_log;
+ auto inner_resolver = std::make_unique<net::MockHostResolver>();
+ HostResolver resolver(inner_resolver.get(), &net_log);
+
+ mojom::MdnsListenClientPtr response_client_ptr;
+ TestMdnsListenClient response_client(&response_client_ptr);
+
+ int error = net::ERR_FAILED;
+ base::RunLoop run_loop;
+ net::HostPortPair host("host.local", 43);
+ resolver.MdnsListen(host, net::DnsQueryType::PTR,
+ std::move(response_client_ptr),
+ base::BindLambdaForTesting([&](int error_val) {
+ error = error_val;
+ run_loop.Quit();
+ }));
+
+ run_loop.Run();
+ ASSERT_EQ(net::OK, error);
+
+ net::HostPortPair result("example.com", 43);
+ inner_resolver->TriggerMdnsListeners(
+ host, net::DnsQueryType::PTR,
+ net::HostResolver::MdnsListener::Delegate::UpdateType::REMOVED, result);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(
+ response_client.hostname_results(),
+ testing::ElementsAre(TestMdnsListenClient::CreateExpectedResult(
+ net::HostResolver::MdnsListener::Delegate::UpdateType::REMOVED,
+ net::DnsQueryType::PTR, result)));
+
+ EXPECT_THAT(response_client.address_results(), testing::IsEmpty());
+ EXPECT_THAT(response_client.text_results(), testing::IsEmpty());
+ EXPECT_THAT(response_client.unhandled_results(), testing::IsEmpty());
+}
+
+TEST_F(HostResolverTest, MdnsListener_UnhandledResult) {
+ net::NetLog net_log;
+ auto inner_resolver = std::make_unique<net::MockHostResolver>();
+ HostResolver resolver(inner_resolver.get(), &net_log);
+
+ mojom::MdnsListenClientPtr response_client_ptr;
+ TestMdnsListenClient response_client(&response_client_ptr);
+
+ int error = net::ERR_FAILED;
+ base::RunLoop run_loop;
+ net::HostPortPair host("host.local", 44);
+ resolver.MdnsListen(host, net::DnsQueryType::PTR,
+ std::move(response_client_ptr),
+ base::BindLambdaForTesting([&](int error_val) {
+ error = error_val;
+ run_loop.Quit();
+ }));
+
+ run_loop.Run();
+ ASSERT_EQ(net::OK, error);
+
+ inner_resolver->TriggerMdnsListeners(
+ host, net::DnsQueryType::PTR,
+ net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(response_client.unhandled_results(),
+ testing::ElementsAre(std::make_pair(
+ net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED,
+ net::DnsQueryType::PTR)));
+
+ EXPECT_THAT(response_client.address_results(), testing::IsEmpty());
+ EXPECT_THAT(response_client.text_results(), testing::IsEmpty());
+ EXPECT_THAT(response_client.hostname_results(), testing::IsEmpty());
+}
+#endif // BUILDFLAG(ENABLE_MDNS)
+
} // namespace
} // namespace network
diff --git a/services/network/public/cpp/host_resolver.typemap b/services/network/public/cpp/host_resolver.typemap
index 8921967..20cb2428 100644
--- a/services/network/public/cpp/host_resolver.typemap
+++ b/services/network/public/cpp/host_resolver.typemap
@@ -5,6 +5,7 @@
mojom = "//services/network/public/mojom/host_resolver.mojom"
public_headers = [
"//net/dns/dns_config_overrides.h",
+ "//net/dns/host_resolver.h",
"//net/dns/host_resolver_source.h",
"//net/dns/public/dns_query_type.h",
]
@@ -18,6 +19,7 @@
]
type_mappings = [
"network.mojom.DnsConfigOverrides=net::DnsConfigOverrides",
- "network.mojom.ResolveHostParameters.DnsQueryType=net::DnsQueryType",
+ "network.mojom.DnsQueryType=net::DnsQueryType",
"network.mojom.ResolveHostParameters.Source=net::HostResolverSource",
+ "network.mojom.MdnsListenClient.UpdateType=net::HostResolver::MdnsListener::Delegate::UpdateType",
]
diff --git a/services/network/public/cpp/host_resolver_mojom_traits.cc b/services/network/public/cpp/host_resolver_mojom_traits.cc
index 78a22a7..424cba4 100644
--- a/services/network/public/cpp/host_resolver_mojom_traits.cc
+++ b/services/network/public/cpp/host_resolver_mojom_traits.cc
@@ -18,6 +18,8 @@
using network::mojom::DnsOverHttpsServer;
using network::mojom::DnsOverHttpsServerDataView;
using network::mojom::DnsOverHttpsServerPtr;
+using network::mojom::DnsQueryType;
+using network::mojom::MdnsListenClient;
using network::mojom::ResolveHostParameters;
namespace {
@@ -215,46 +217,45 @@
}
// static
-ResolveHostParameters::DnsQueryType
-EnumTraits<ResolveHostParameters::DnsQueryType, net::DnsQueryType>::ToMojom(
+DnsQueryType EnumTraits<DnsQueryType, net::DnsQueryType>::ToMojom(
net::DnsQueryType input) {
switch (input) {
case net::DnsQueryType::UNSPECIFIED:
- return ResolveHostParameters::DnsQueryType::UNSPECIFIED;
+ return DnsQueryType::UNSPECIFIED;
case net::DnsQueryType::A:
- return ResolveHostParameters::DnsQueryType::A;
+ return DnsQueryType::A;
case net::DnsQueryType::AAAA:
- return ResolveHostParameters::DnsQueryType::AAAA;
+ return DnsQueryType::AAAA;
case net::DnsQueryType::TXT:
- return ResolveHostParameters::DnsQueryType::TXT;
+ return DnsQueryType::TXT;
case net::DnsQueryType::PTR:
- return ResolveHostParameters::DnsQueryType::PTR;
+ return DnsQueryType::PTR;
case net::DnsQueryType::SRV:
- return ResolveHostParameters::DnsQueryType::SRV;
+ return DnsQueryType::SRV;
}
}
// static
-bool EnumTraits<ResolveHostParameters::DnsQueryType, net::DnsQueryType>::
- FromMojom(ResolveHostParameters::DnsQueryType input,
- net::DnsQueryType* output) {
+bool EnumTraits<DnsQueryType, net::DnsQueryType>::FromMojom(
+ DnsQueryType input,
+ net::DnsQueryType* output) {
switch (input) {
- case ResolveHostParameters::DnsQueryType::UNSPECIFIED:
+ case DnsQueryType::UNSPECIFIED:
*output = net::DnsQueryType::UNSPECIFIED;
return true;
- case ResolveHostParameters::DnsQueryType::A:
+ case DnsQueryType::A:
*output = net::DnsQueryType::A;
return true;
- case ResolveHostParameters::DnsQueryType::AAAA:
+ case DnsQueryType::AAAA:
*output = net::DnsQueryType::AAAA;
return true;
- case ResolveHostParameters::DnsQueryType::TXT:
+ case DnsQueryType::TXT:
*output = net::DnsQueryType::TXT;
return true;
- case ResolveHostParameters::DnsQueryType::PTR:
+ case DnsQueryType::PTR:
*output = net::DnsQueryType::PTR;
return true;
- case ResolveHostParameters::DnsQueryType::SRV:
+ case DnsQueryType::SRV:
*output = net::DnsQueryType::SRV;
return true;
}
@@ -296,4 +297,37 @@
}
}
+// static
+MdnsListenClient::UpdateType
+EnumTraits<MdnsListenClient::UpdateType,
+ net::HostResolver::MdnsListener::Delegate::UpdateType>::
+ ToMojom(net::HostResolver::MdnsListener::Delegate::UpdateType input) {
+ switch (input) {
+ case net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED:
+ return MdnsListenClient::UpdateType::ADDED;
+ case net::HostResolver::MdnsListener::Delegate::UpdateType::CHANGED:
+ return MdnsListenClient::UpdateType::CHANGED;
+ case net::HostResolver::MdnsListener::Delegate::UpdateType::REMOVED:
+ return MdnsListenClient::UpdateType::REMOVED;
+ }
+}
+
+// static
+bool EnumTraits<MdnsListenClient::UpdateType,
+ net::HostResolver::MdnsListener::Delegate::UpdateType>::
+ FromMojom(MdnsListenClient::UpdateType input,
+ net::HostResolver::MdnsListener::Delegate::UpdateType* output) {
+ switch (input) {
+ case MdnsListenClient::UpdateType::ADDED:
+ *output = net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED;
+ return true;
+ case MdnsListenClient::UpdateType::CHANGED:
+ *output = net::HostResolver::MdnsListener::Delegate::UpdateType::CHANGED;
+ return true;
+ case MdnsListenClient::UpdateType::REMOVED:
+ *output = net::HostResolver::MdnsListener::Delegate::UpdateType::REMOVED;
+ return true;
+ }
+}
+
} // namespace mojo
diff --git a/services/network/public/cpp/host_resolver_mojom_traits.h b/services/network/public/cpp/host_resolver_mojom_traits.h
index 3d18769a..3a5fd42 100644
--- a/services/network/public/cpp/host_resolver_mojom_traits.h
+++ b/services/network/public/cpp/host_resolver_mojom_traits.h
@@ -72,13 +72,10 @@
};
template <>
-struct EnumTraits<network::mojom::ResolveHostParameters::DnsQueryType,
- net::DnsQueryType> {
- static network::mojom::ResolveHostParameters::DnsQueryType ToMojom(
- net::DnsQueryType input);
- static bool FromMojom(
- network::mojom::ResolveHostParameters::DnsQueryType input,
- net::DnsQueryType* output);
+struct EnumTraits<network::mojom::DnsQueryType, net::DnsQueryType> {
+ static network::mojom::DnsQueryType ToMojom(net::DnsQueryType input);
+ static bool FromMojom(network::mojom::DnsQueryType input,
+ net::DnsQueryType* output);
};
template <>
@@ -90,6 +87,16 @@
net::HostResolverSource* output);
};
+template <>
+struct EnumTraits<network::mojom::MdnsListenClient::UpdateType,
+ net::HostResolver::MdnsListener::Delegate::UpdateType> {
+ static network::mojom::MdnsListenClient::UpdateType ToMojom(
+ net::HostResolver::MdnsListener::Delegate::UpdateType input);
+ static bool FromMojom(
+ network::mojom::MdnsListenClient::UpdateType input,
+ net::HostResolver::MdnsListener::Delegate::UpdateType* output);
+};
+
} // namespace mojo
#endif // SERVICES_NETWORK_PUBLIC_CPP_HOST_RESOLVER_MOJOM_TRAITS_H_
diff --git a/services/network/public/mojom/host_resolver.mojom b/services/network/public/mojom/host_resolver.mojom
index b3e723f1..3fe9011e 100644
--- a/services/network/public/mojom/host_resolver.mojom
+++ b/services/network/public/mojom/host_resolver.mojom
@@ -118,22 +118,22 @@
OnHostnameResults(array<HostPortPair> hosts);
};
+// DNS query type for a ResolveHostRequest.
+// See:
+// https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
+enum DnsQueryType {
+ UNSPECIFIED,
+ A,
+ AAAA,
+ TXT,
+ PTR,
+ SRV,
+};
+
// Parameter-grouping struct for additional optional parameters for
// HostResolver::ResolveHost() calls. All fields are optional and have a
// reasonable default.
struct ResolveHostParameters {
- // DNS query type for a ResolveHostRequest.
- // See:
- // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
- enum DnsQueryType {
- UNSPECIFIED,
- A,
- AAAA,
- TXT,
- PTR,
- SRV,
- };
-
// Requested DNS query type. If UNSPECIFIED, resolver will pick A or AAAA (or
// both) based on IPv4/IPv6 settings.
DnsQueryType dns_query_type = DnsQueryType.UNSPECIFIED;
@@ -189,9 +189,36 @@
bool is_speculative = false;
};
+// Response interface used to receive notifications from
+// HostResolver::MdnsListen requests. All methods have a |query_type| field to
+// allow a single BindingSet and implementation to be used to listen for updates
+// for multiple types for the same host.
+interface MdnsListenClient {
+ enum UpdateType {
+ ADDED,
+ CHANGED,
+ REMOVED
+ };
+
+ OnAddressResult(UpdateType update_type,
+ DnsQueryType query_type,
+ IPEndPoint endpoint);
+ OnTextResult(UpdateType update_type,
+ DnsQueryType query_type,
+ array<string> text_records);
+ OnHostnameResult(UpdateType update_type,
+ DnsQueryType query_type,
+ HostPortPair host);
+
+ // For results which may be valid MDNS but are not handled/parsed by network
+ // service, e.g. pointers to the root domain.
+ OnUnhandledResult(UpdateType update_type, DnsQueryType query_type);
+};
+
// Interface that can be passed to code/processes without direct access to
// NetworkContext to make ResolveHost requests. If destroyed, all outstanding
-// ResolveHost requests from the destroyed interface will be cancelled.
+// ResolveHost and MdnsListen requests from the destroyed interface will be
+// cancelled.
interface HostResolver {
// Resolves the given hostname (or IP address literal). Results are a network
// error code, and on success (network error code OK), an AddressList. All
@@ -214,6 +241,17 @@
ResolveHost(HostPortPair host,
ResolveHostParameters? optional_parameters,
ResolveHostClient response_client);
+
+ // Starts a listener to watch for updates to a multicast DNS result. Result is
+ // a network error code indicating the success of starting the listener. On
+ // success (result OK), |response_client| will begin receiving update
+ // notifications.
+ //
+ // All outstanding listeners are cancelled and will receive no further
+ // notifications if the HostResolver or parent NetworkContext are destroyed.
+ MdnsListen(HostPortPair host,
+ DnsQueryType query_type,
+ MdnsListenClient response_client) => (int32 result);
};
// A client interface that subscribes to DNS config change events from