Commit c2213d5d authored by Qingsi Wang's avatar Qingsi Wang Committed by Commit Bot

Add the mDNS responder service.

WebRTC will improve its IP handling with mDNS and replace private IP
addresses with mDNS hostnames when signaling ICE host candidates to the
application. See the Internet Draft (draft-mdns-ice-candidates-02) for
the detailed approach.

This CL defines a Mojo interface of mDNS responder and implements it as
a service that will be consumed by WebRTC.

Bug: 878465
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: I4b644286467622b3dfdb728a9d5f3a4bde9fc1ec
Reviewed-on: https://chromium-review.googlesource.com/c/1182875Reviewed-by: default avatarChris Palmer <palmer@chromium.org>
Reviewed-by: default avatarEric Orth <ericorth@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Commit-Queue: Qingsi Wang <qingsi@google.com>
Cr-Commit-Position: refs/heads/master@{#604803}
parent 884edb78
...@@ -4006,17 +4006,6 @@ jumbo_split_static_library("browser") { ...@@ -4006,17 +4006,6 @@ jumbo_split_static_library("browser") {
] ]
} }
if (enable_mdns) {
sources += [
"local_discovery/service_discovery_client_impl.cc",
"local_discovery/service_discovery_client_impl.h",
"local_discovery/service_discovery_client_mdns.cc",
"local_discovery/service_discovery_client_mdns.h",
"printing/cloud_print/privet_traffic_detector.cc",
"printing/cloud_print/privet_traffic_detector.h",
]
}
if (enable_message_center) { if (enable_message_center) {
sources += [ sources += [
"notifications/notification_platform_bridge_message_center.cc", "notifications/notification_platform_bridge_message_center.cc",
...@@ -4348,6 +4337,17 @@ jumbo_split_static_library("browser") { ...@@ -4348,6 +4337,17 @@ jumbo_split_static_library("browser") {
"printing/cloud_print/privet_url_loader.cc", "printing/cloud_print/privet_url_loader.cc",
"printing/cloud_print/privet_url_loader.h", "printing/cloud_print/privet_url_loader.h",
] ]
if (enable_mdns) {
sources += [
"local_discovery/service_discovery_client_impl.cc",
"local_discovery/service_discovery_client_impl.h",
"local_discovery/service_discovery_client_mdns.cc",
"local_discovery/service_discovery_client_mdns.h",
"printing/cloud_print/privet_traffic_detector.cc",
"printing/cloud_print/privet_traffic_detector.h",
]
}
} }
if (enable_session_service) { if (enable_session_service) {
...@@ -5339,7 +5339,7 @@ static_library("test_support") { ...@@ -5339,7 +5339,7 @@ static_library("test_support") {
deps += [ "//media/cdm:cdm_paths" ] deps += [ "//media/cdm:cdm_paths" ]
} }
if (enable_mdns) { if (enable_service_discovery) {
sources += [ sources += [
"local_discovery/test_service_discovery_client.cc", "local_discovery/test_service_discovery_client.cc",
"local_discovery/test_service_discovery_client.h", "local_discovery/test_service_discovery_client.h",
......
...@@ -43,7 +43,7 @@ declare_args() { ...@@ -43,7 +43,7 @@ declare_args() {
enable_one_click_signin = enable_one_click_signin =
is_win || is_mac || (is_linux && !is_chromeos && !is_chromecast) is_win || is_mac || (is_linux && !is_chromeos && !is_chromecast)
enable_service_discovery = enable_mdns || is_mac enable_service_discovery = (enable_mdns && !is_android && !is_ios) || is_mac
# Enables use of the session service, which is enabled by default. # Enables use of the session service, which is enabled by default.
# Android stores them separately on the Java side. # Android stores them separately on the Java side.
......
...@@ -2107,7 +2107,7 @@ test("browser_tests") { ...@@ -2107,7 +2107,7 @@ test("browser_tests") {
] ]
} }
} }
if (enable_mdns) { if (enable_service_discovery && !is_mac) {
sources += [ sources += [
"../browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc", "../browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc",
] ]
...@@ -3875,14 +3875,6 @@ test("unit_tests") { ...@@ -3875,14 +3875,6 @@ test("unit_tests") {
deps += [ "//chrome/browser/ui/libgtkui" ] deps += [ "//chrome/browser/ui/libgtkui" ]
} }
if (enable_mdns) {
sources += [
"../browser/local_discovery/local_domain_resolver_unittest.cc",
"../browser/local_discovery/service_discovery_client_unittest.cc",
"../browser/printing/cloud_print/privet_device_lister_unittest.cc",
"../browser/printing/cloud_print/privet_local_printer_lister_unittest.cc",
]
}
if (enable_service_discovery) { if (enable_service_discovery) {
sources += [ sources += [
"../browser/devtools/device/cast_device_provider_unittest.cc", "../browser/devtools/device/cast_device_provider_unittest.cc",
...@@ -3894,6 +3886,15 @@ test("unit_tests") { ...@@ -3894,6 +3886,15 @@ test("unit_tests") {
"../browser/printing/cloud_print/privet_notifications_unittest.cc", "../browser/printing/cloud_print/privet_notifications_unittest.cc",
"../browser/printing/cloud_print/privet_url_loader_unittest.cc", "../browser/printing/cloud_print/privet_url_loader_unittest.cc",
] ]
if (!is_mac) {
sources += [
"../browser/local_discovery/local_domain_resolver_unittest.cc",
"../browser/local_discovery/service_discovery_client_unittest.cc",
"../browser/printing/cloud_print/privet_device_lister_unittest.cc",
"../browser/printing/cloud_print/privet_local_printer_lister_unittest.cc",
]
}
} }
if (safe_browsing_mode > 0) { if (safe_browsing_mode > 0) {
......
...@@ -2228,6 +2228,13 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() { ...@@ -2228,6 +2228,13 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::BindRepeating(&P2PSocketDispatcherHost::BindRequest, base::BindRepeating(&P2PSocketDispatcherHost::BindRequest,
base::Unretained(p2p_socket_dispatcher_host_.get()))); base::Unretained(p2p_socket_dispatcher_host_.get())));
#if BUILDFLAG(ENABLE_MDNS)
AddUIThreadInterface(
registry.get(),
base::BindRepeating(&RenderProcessHostImpl::CreateMdnsResponder,
base::Unretained(this)));
#endif // BUILDFLAG(ENABLE_MDNS)
AddUIThreadInterface(registry.get(), base::Bind(&FieldTrialRecorder::Create)); AddUIThreadInterface(registry.get(), base::Bind(&FieldTrialRecorder::Create));
associated_interfaces_ = associated_interfaces_ =
...@@ -4557,6 +4564,14 @@ void RenderProcessHostImpl::CreateMediaStreamTrackMetricsHost( ...@@ -4557,6 +4564,14 @@ void RenderProcessHostImpl::CreateMediaStreamTrackMetricsHost(
media_stream_track_metrics_host_->BindRequest(std::move(request)); media_stream_track_metrics_host_->BindRequest(std::move(request));
} }
#if BUILDFLAG(ENABLE_MDNS)
void RenderProcessHostImpl::CreateMdnsResponder(
network::mojom::MdnsResponderRequest request) {
GetStoragePartition()->GetNetworkContext()->CreateMdnsResponder(
std::move(request));
}
#endif // BUILDFLAG(ENABLE_MDNS)
void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) { void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
base::PostTaskWithTraits( base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI}, FROM_HERE, {BrowserThread::UI},
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "mojo/public/cpp/bindings/associated_binding_set.h" #include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr.h" #include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/system/invitation.h" #include "mojo/public/cpp/system/invitation.h"
#include "services/network/public/mojom/mdns_responder.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/mojom/service.mojom.h" #include "services/service_manager/public/mojom/service.mojom.h"
...@@ -599,6 +600,10 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -599,6 +600,10 @@ class CONTENT_EXPORT RenderProcessHostImpl
void CreateMediaStreamTrackMetricsHost( void CreateMediaStreamTrackMetricsHost(
mojom::MediaStreamTrackMetricsHostRequest request); mojom::MediaStreamTrackMetricsHostRequest request);
#if BUILDFLAG(ENABLE_MDNS)
void CreateMdnsResponder(network::mojom::MdnsResponderRequest request);
#endif // BUILDFLAG(ENABLE_MDNS)
void OnRegisterAecDumpConsumer(int id); void OnRegisterAecDumpConsumer(int id);
void OnUnregisterAecDumpConsumer(int id); void OnUnregisterAecDumpConsumer(int id);
void RegisterAecDumpConsumerOnUIThread(int id); void RegisterAecDumpConsumerOnUIThread(int id);
......
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
"memory_coordinator.mojom.MemoryCoordinatorHandle", "memory_coordinator.mojom.MemoryCoordinatorHandle",
"metrics.mojom.SingleSampleMetricsProvider", "metrics.mojom.SingleSampleMetricsProvider",
"network.mojom.P2PSocketManager", "network.mojom.P2PSocketManager",
"network.mojom.MdnsResponder",
"network.mojom.URLLoaderFactory", "network.mojom.URLLoaderFactory",
"resource_coordinator.mojom.ProcessCoordinationUnit", "resource_coordinator.mojom.ProcessCoordinationUnit",
"viz.mojom.CompositingModeReporter", "viz.mojom.CompositingModeReporter",
......
...@@ -322,6 +322,7 @@ source_set("mdns_client") { ...@@ -322,6 +322,7 @@ source_set("mdns_client") {
"//chrome/browser/chromeos", "//chrome/browser/chromeos",
"//chrome/tools/service_discovery_sniffer", "//chrome/tools/service_discovery_sniffer",
"//net/*", "//net/*",
"//services/network/*",
] ]
public = [] public = []
......
...@@ -126,6 +126,7 @@ static const uint16_t kTypeAAAA = 28; ...@@ -126,6 +126,7 @@ static const uint16_t kTypeAAAA = 28;
static const uint16_t kTypeSRV = 33; static const uint16_t kTypeSRV = 33;
static const uint16_t kTypeOPT = 41; static const uint16_t kTypeOPT = 41;
static const uint16_t kTypeNSEC = 47; static const uint16_t kTypeNSEC = 47;
static const uint16_t kTypeANY = 255;
// DNS reply codes (RCODEs). // DNS reply codes (RCODEs).
// //
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <limits> #include <limits>
#include <numeric> #include <numeric>
#include <utility>
#include <vector> #include <vector>
#include "base/big_endian.h" #include "base/big_endian.h"
...@@ -38,13 +39,81 @@ const size_t kResourceRecordSizeInBytesWithoutNameAndRData = 10; ...@@ -38,13 +39,81 @@ const size_t kResourceRecordSizeInBytesWithoutNameAndRData = 10;
DnsResourceRecord::DnsResourceRecord() = default; DnsResourceRecord::DnsResourceRecord() = default;
DnsResourceRecord::DnsResourceRecord(const DnsResourceRecord& other) = default; DnsResourceRecord::DnsResourceRecord(const DnsResourceRecord& other)
: name(other.name),
type(other.type),
klass(other.klass),
ttl(other.ttl),
owned_rdata(other.owned_rdata) {
if (!owned_rdata.empty())
rdata = owned_rdata;
else
rdata = other.rdata;
}
DnsResourceRecord::DnsResourceRecord(DnsResourceRecord&& other)
: name(std::move(other.name)),
type(other.type),
klass(other.klass),
ttl(other.ttl),
owned_rdata(std::move(other.owned_rdata)) {
if (!owned_rdata.empty())
rdata = owned_rdata;
else
rdata = other.rdata;
}
DnsResourceRecord::~DnsResourceRecord() = default; DnsResourceRecord::~DnsResourceRecord() = default;
DnsRecordParser::DnsRecordParser() : packet_(NULL), length_(0), cur_(0) { DnsResourceRecord& DnsResourceRecord::operator=(
const DnsResourceRecord& other) {
name = other.name;
type = other.type;
klass = other.klass;
ttl = other.ttl;
owned_rdata = other.owned_rdata;
if (!owned_rdata.empty())
rdata = owned_rdata;
else
rdata = other.rdata;
return *this;
}
DnsResourceRecord& DnsResourceRecord::operator=(DnsResourceRecord&& other) {
name = std::move(other.name);
type = other.type;
klass = other.klass;
ttl = other.ttl;
owned_rdata = std::move(other.owned_rdata);
if (!owned_rdata.empty())
rdata = owned_rdata;
else
rdata = other.rdata;
return *this;
}
void DnsResourceRecord::SetOwnedRdata(std::string value) {
owned_rdata = std::move(value);
rdata = owned_rdata;
} }
size_t DnsResourceRecord::CalculateRecordSize() const {
bool has_final_dot = name.back() == '.';
// Depending on if |name| in the dotted format has the final dot for the root
// domain or not, the corresponding wire data in the DNS domain name format is
// 1 byte (with dot) or 2 bytes larger in size. See RFC 1035, Section 3.1 and
// DNSDomainFromDot.
return name.size() + (has_final_dot ? 1 : 2) +
kResourceRecordSizeInBytesWithoutNameAndRData +
(owned_rdata.empty() ? rdata.size() : owned_rdata.size());
}
DnsRecordParser::DnsRecordParser() : packet_(nullptr), length_(0), cur_(0) {}
DnsRecordParser::DnsRecordParser(const void* packet, DnsRecordParser::DnsRecordParser(const void* packet,
size_t length, size_t length,
size_t offset) size_t offset)
...@@ -148,7 +217,7 @@ bool DnsRecordParser::ReadRecord(DnsResourceRecord* out) { ...@@ -148,7 +217,7 @@ bool DnsRecordParser::ReadRecord(DnsResourceRecord* out) {
} }
bool DnsRecordParser::SkipQuestion() { bool DnsRecordParser::SkipQuestion() {
size_t consumed = ReadName(cur_, NULL); size_t consumed = ReadName(cur_, nullptr);
if (!consumed) if (!consumed)
return false; return false;
...@@ -178,9 +247,9 @@ DnsResponse::DnsResponse( ...@@ -178,9 +247,9 @@ DnsResponse::DnsResponse(
header.qdcount = 1; header.qdcount = 1;
} }
header.flags |= dns_protocol::kFlagResponse; header.flags |= dns_protocol::kFlagResponse;
if (is_authoritative) { if (is_authoritative)
header.flags |= dns_protocol::kFlagAA; header.flags |= dns_protocol::kFlagAA;
}
header.ancount = answers.size(); header.ancount = answers.size();
header.arcount = additional_records.size(); header.arcount = additional_records.size();
...@@ -189,18 +258,11 @@ DnsResponse::DnsResponse( ...@@ -189,18 +258,11 @@ DnsResponse::DnsResponse(
? sizeof(header) + query.value().question_size() ? sizeof(header) + query.value().question_size()
: sizeof(header); : sizeof(header);
// Add the size of all answers and additional records. // Add the size of all answers and additional records.
auto do_accumulation = [](size_t cur_size, const DnsResourceRecord& answer) { auto do_accumulation = [](size_t cur_size, const DnsResourceRecord& record) {
bool has_final_dot = answer.name.back() == '.'; return cur_size + record.CalculateRecordSize();
// Depending on if answer.name in the dotted format has the final dot
// for the root domain or not, the corresponding DNS domain name format
// to be written to rdata is 1 byte (with dot) or 2 bytes larger in
// size. See RFC 1035, Section 3.1 and DNSDomainFromDot.
return cur_size + answer.name.size() + (has_final_dot ? 1 : 2) +
kResourceRecordSizeInBytesWithoutNameAndRData + answer.rdata.size();
}; };
response_size = std::accumulate(answers.begin(), answers.end(), response_size, response_size = std::accumulate(answers.begin(), answers.end(), response_size,
do_accumulation); do_accumulation);
response_size = response_size =
std::accumulate(additional_records.begin(), additional_records.end(), std::accumulate(additional_records.begin(), additional_records.end(),
response_size, do_accumulation); response_size, do_accumulation);
...@@ -232,11 +294,10 @@ DnsResponse::DnsResponse( ...@@ -232,11 +294,10 @@ DnsResponse::DnsResponse(
// Ensure we don't have any remaining uninitialized bytes in the buffer. // Ensure we don't have any remaining uninitialized bytes in the buffer.
DCHECK(!writer.remaining()); DCHECK(!writer.remaining());
memset(writer.ptr(), 0, writer.remaining()); memset(writer.ptr(), 0, writer.remaining());
if (has_query) { if (has_query)
InitParse(io_buffer_size_, query.value()); InitParse(io_buffer_size_, query.value());
} else { else
InitParseWithoutQuery(io_buffer_size_); InitParseWithoutQuery(io_buffer_size_);
}
} }
DnsResponse::DnsResponse() DnsResponse::DnsResponse()
...@@ -462,7 +523,13 @@ bool DnsResponse::WriteQuestion(base::BigEndianWriter* writer, ...@@ -462,7 +523,13 @@ bool DnsResponse::WriteQuestion(base::BigEndianWriter* writer,
bool DnsResponse::WriteRecord(base::BigEndianWriter* writer, bool DnsResponse::WriteRecord(base::BigEndianWriter* writer,
const DnsResourceRecord& record) { const DnsResourceRecord& record) {
if (!RecordRdata::HasValidSize(record.rdata, record.type)) { if (record.rdata.data() != record.owned_rdata.data() ||
record.rdata.size() != record.owned_rdata.size()) {
VLOG(1) << "record.rdata should point to record.owned_rdata.";
return false;
}
if (!RecordRdata::HasValidSize(record.owned_rdata, record.type)) {
VLOG(1) << "Invalid RDATA size for a record."; VLOG(1) << "Invalid RDATA size for a record.";
return false; return false;
} }
...@@ -474,8 +541,10 @@ bool DnsResponse::WriteRecord(base::BigEndianWriter* writer, ...@@ -474,8 +541,10 @@ bool DnsResponse::WriteRecord(base::BigEndianWriter* writer,
return writer->WriteBytes(domain_name.data(), domain_name.size()) && return writer->WriteBytes(domain_name.data(), domain_name.size()) &&
writer->WriteU16(record.type) && writer->WriteU16(record.klass) && writer->WriteU16(record.type) && writer->WriteU16(record.klass) &&
writer->WriteU32(record.ttl) && writer->WriteU32(record.ttl) &&
writer->WriteU16(record.rdata.size()) && writer->WriteU16(record.owned_rdata.size()) &&
writer->WriteBytes(record.rdata.data(), record.rdata.size()); // Use the owned RDATA in the record to construct the response.
writer->WriteBytes(record.owned_rdata.data(),
record.owned_rdata.size());
} }
bool DnsResponse::WriteAnswer(base::BigEndianWriter* writer, bool DnsResponse::WriteAnswer(base::BigEndianWriter* writer,
......
...@@ -36,13 +36,31 @@ struct Header; ...@@ -36,13 +36,31 @@ struct Header;
struct NET_EXPORT_PRIVATE DnsResourceRecord { struct NET_EXPORT_PRIVATE DnsResourceRecord {
DnsResourceRecord(); DnsResourceRecord();
explicit DnsResourceRecord(const DnsResourceRecord& other); explicit DnsResourceRecord(const DnsResourceRecord& other);
DnsResourceRecord(DnsResourceRecord&& other);
~DnsResourceRecord(); ~DnsResourceRecord();
DnsResourceRecord& operator=(const DnsResourceRecord& other);
DnsResourceRecord& operator=(DnsResourceRecord&& other);
// A helper to set |owned_rdata| that also sets |rdata| to point to it.
// See the definition of |owned_rdata| below.
void SetOwnedRdata(std::string value);
// NAME (variable length) + TYPE (2 bytes) + CLASS (2 bytes) + TTL (4 bytes) +
// RDLENGTH (2 bytes) + RDATA (variable length)
//
// Uses |owned_rdata| for RDATA if non-empty.
size_t CalculateRecordSize() const;
std::string name; // in dotted form std::string name; // in dotted form
uint16_t type = 0; uint16_t type = 0;
uint16_t klass = 0; uint16_t klass = 0;
uint32_t ttl = 0; uint32_t ttl = 0;
base::StringPiece rdata; // points to the original response buffer // Points to the original response buffer or otherwise to |owned_rdata|.
base::StringPiece rdata;
// Used to construct a DnsResponse from data. This field is empty if |rdata|
// points to the response buffer.
std::string owned_rdata;
}; };
// Iterator to walk over resource records of the DNS response packet. // Iterator to walk over resource records of the DNS response packet.
......
...@@ -670,7 +670,7 @@ TEST(DnsResponseWriteTest, SingleARecordAnswer) { ...@@ -670,7 +670,7 @@ TEST(DnsResponseWriteTest, SingleARecordAnswer) {
answer.type = dns_protocol::kTypeA; answer.type = dns_protocol::kTypeA;
answer.klass = dns_protocol::kClassIN; answer.klass = dns_protocol::kClassIN;
answer.ttl = 120; // 120 seconds. answer.ttl = 120; // 120 seconds.
answer.rdata = base::StringPiece("\xc0\xa8\x00\x01", 4); answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
std::vector<DnsResourceRecord> answers(1, answer); std::vector<DnsResourceRecord> answers(1, answer);
DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/, DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/,
answers, {} /* additional records */, base::nullopt); answers, {} /* additional records */, base::nullopt);
...@@ -704,7 +704,7 @@ TEST(DnsResponseWriteTest, SingleARecordAnswerWithFinalDotInName) { ...@@ -704,7 +704,7 @@ TEST(DnsResponseWriteTest, SingleARecordAnswerWithFinalDotInName) {
answer.type = dns_protocol::kTypeA; answer.type = dns_protocol::kTypeA;
answer.klass = dns_protocol::kClassIN; answer.klass = dns_protocol::kClassIN;
answer.ttl = 120; // 120 seconds. answer.ttl = 120; // 120 seconds.
answer.rdata = base::StringPiece("\xc0\xa8\x00\x01", 4); answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
std::vector<DnsResourceRecord> answers(1, answer); std::vector<DnsResourceRecord> answers(1, answer);
DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/, DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/,
answers, {} /* additional records */, base::nullopt); answers, {} /* additional records */, base::nullopt);
...@@ -750,7 +750,7 @@ TEST(DnsResponseWriteTest, SingleARecordAnswerWithQuestion) { ...@@ -750,7 +750,7 @@ TEST(DnsResponseWriteTest, SingleARecordAnswerWithQuestion) {
answer.type = dns_protocol::kTypeA; answer.type = dns_protocol::kTypeA;
answer.klass = dns_protocol::kClassIN; answer.klass = dns_protocol::kClassIN;
answer.ttl = 120; // 120 seconds. answer.ttl = 120; // 120 seconds.
answer.rdata = base::StringPiece("\xc0\xa8\x00\x01", 4); answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
std::vector<DnsResourceRecord> answers(1, answer); std::vector<DnsResourceRecord> answers(1, answer);
DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers, DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
{} /* additional records */, query); {} /* additional records */, query);
...@@ -813,7 +813,7 @@ TEST(DnsResponseWriteTest, ...@@ -813,7 +813,7 @@ TEST(DnsResponseWriteTest,
answer.type = dns_protocol::kTypeA; answer.type = dns_protocol::kTypeA;
answer.klass = dns_protocol::kClassIN; answer.klass = dns_protocol::kClassIN;
answer.ttl = 120; // 120 seconds. answer.ttl = 120; // 120 seconds.
answer.rdata = base::StringPiece("\xc0\xa8\x00\x01", 4); answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
std::vector<DnsResourceRecord> answers(1, answer); std::vector<DnsResourceRecord> answers(1, answer);
DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers, DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
{} /* additional records */, query); {} /* additional records */, query);
...@@ -848,8 +848,8 @@ TEST(DnsResponseWriteTest, SingleQuadARecordAnswer) { ...@@ -848,8 +848,8 @@ TEST(DnsResponseWriteTest, SingleQuadARecordAnswer) {
answer.type = dns_protocol::kTypeAAAA; answer.type = dns_protocol::kTypeAAAA;
answer.klass = dns_protocol::kClassIN; answer.klass = dns_protocol::kClassIN;
answer.ttl = 120; // 120 seconds. answer.ttl = 120; // 120 seconds.
answer.rdata = base::StringPiece( answer.SetOwnedRdata(std::string(
"\xfd\x12\x34\x56\x78\x9a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01", 16); "\xfd\x12\x34\x56\x78\x9a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01", 16));
std::vector<DnsResourceRecord> answers(1, answer); std::vector<DnsResourceRecord> answers(1, answer);
DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers, DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
{} /* additional records */, base::nullopt); {} /* additional records */, base::nullopt);
...@@ -904,7 +904,7 @@ TEST(DnsResponseWriteTest, ...@@ -904,7 +904,7 @@ TEST(DnsResponseWriteTest,
answer.type = dns_protocol::kTypeA; answer.type = dns_protocol::kTypeA;
answer.klass = dns_protocol::kClassIN; answer.klass = dns_protocol::kClassIN;
answer.ttl = 120; // 120 seconds. answer.ttl = 120; // 120 seconds.
answer.rdata = base::StringPiece("\xc0\xa8\x00\x01", 4); answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
std::vector<DnsResourceRecord> answers(1, answer); std::vector<DnsResourceRecord> answers(1, answer);
net::DnsResourceRecord additional_record; net::DnsResourceRecord additional_record;
additional_record.name = dotted_name; additional_record.name = dotted_name;
...@@ -912,7 +912,7 @@ TEST(DnsResponseWriteTest, ...@@ -912,7 +912,7 @@ TEST(DnsResponseWriteTest,
additional_record.klass = dns_protocol::kClassIN; additional_record.klass = dns_protocol::kClassIN;
additional_record.ttl = 120; // 120 seconds. additional_record.ttl = 120; // 120 seconds.
// Bitmap for "www.example.com" with type A set. // Bitmap for "www.example.com" with type A set.
additional_record.rdata = base::StringPiece("\xc0\x0c\x00\x01\x40", 5); additional_record.SetOwnedRdata(std::string("\xc0\x0c\x00\x01\x40", 5));
std::vector<DnsResourceRecord> additional_records(1, additional_record); std::vector<DnsResourceRecord> additional_records(1, additional_record);
DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers, DnsResponse response(0x1234 /* id */, true /* is_authoritative*/, answers,
additional_records, query); additional_records, query);
...@@ -954,14 +954,14 @@ TEST(DnsResponseWriteTest, TwoAnswersWithAAndQuadARecords) { ...@@ -954,14 +954,14 @@ TEST(DnsResponseWriteTest, TwoAnswersWithAAndQuadARecords) {
answer1.type = dns_protocol::kTypeA; answer1.type = dns_protocol::kTypeA;
answer1.klass = dns_protocol::kClassIN; answer1.klass = dns_protocol::kClassIN;
answer1.ttl = 120; // 120 seconds. answer1.ttl = 120; // 120 seconds.
answer1.rdata = base::StringPiece("\xc0\xa8\x00\x01", 4); answer1.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
net::DnsResourceRecord answer2; net::DnsResourceRecord answer2;
answer2.name = "example.org"; answer2.name = "example.org";
answer2.type = dns_protocol::kTypeAAAA; answer2.type = dns_protocol::kTypeAAAA;
answer2.klass = dns_protocol::kClassIN; answer2.klass = dns_protocol::kClassIN;
answer2.ttl = 60; answer2.ttl = 60;
answer2.rdata = base::StringPiece( answer2.SetOwnedRdata(std::string(
"\xfd\x12\x34\x56\x78\x9a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01", 16); "\xfd\x12\x34\x56\x78\x9a\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01", 16));
std::vector<DnsResourceRecord> answers(2); std::vector<DnsResourceRecord> answers(2);
answers[0] = answer1; answers[0] = answer1;
answers[1] = answer2; answers[1] = answer2;
...@@ -982,14 +982,14 @@ TEST(DnsResponseWriteTest, WrittenResponseCanBeParsed) { ...@@ -982,14 +982,14 @@ TEST(DnsResponseWriteTest, WrittenResponseCanBeParsed) {
answer.type = dns_protocol::kTypeA; answer.type = dns_protocol::kTypeA;
answer.klass = dns_protocol::kClassIN; answer.klass = dns_protocol::kClassIN;
answer.ttl = 120; // 120 seconds. answer.ttl = 120; // 120 seconds.
answer.rdata = base::StringPiece("\xc0\xa8\x00\x01", 4); answer.SetOwnedRdata(std::string("\xc0\xa8\x00\x01", 4));
std::vector<DnsResourceRecord> answers(1, answer); std::vector<DnsResourceRecord> answers(1, answer);
net::DnsResourceRecord additional_record; net::DnsResourceRecord additional_record;
additional_record.name = dotted_name; additional_record.name = dotted_name;
additional_record.type = dns_protocol::kTypeNSEC; additional_record.type = dns_protocol::kTypeNSEC;
additional_record.klass = dns_protocol::kClassIN; additional_record.klass = dns_protocol::kClassIN;
additional_record.ttl = 120; // 120 seconds. additional_record.ttl = 120; // 120 seconds.
additional_record.rdata = base::StringPiece("\xc0\x0c\x00\x01\x04", 5); additional_record.SetOwnedRdata(std::string("\xc0\x0c\x00\x01\x04", 5));
std::vector<DnsResourceRecord> additional_records(1, additional_record); std::vector<DnsResourceRecord> additional_records(1, additional_record);
DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/, DnsResponse response(0x1234 /* response_id */, true /* is_authoritative*/,
answers, additional_records, base::nullopt); answers, additional_records, base::nullopt);
...@@ -1005,14 +1005,14 @@ TEST(DnsResponseWriteTest, WrittenResponseCanBeParsed) { ...@@ -1005,14 +1005,14 @@ TEST(DnsResponseWriteTest, WrittenResponseCanBeParsed) {
EXPECT_EQ(answer.type, parsed_record.type); EXPECT_EQ(answer.type, parsed_record.type);
EXPECT_EQ(answer.klass, parsed_record.klass); EXPECT_EQ(answer.klass, parsed_record.klass);
EXPECT_EQ(answer.ttl, parsed_record.ttl); EXPECT_EQ(answer.ttl, parsed_record.ttl);
EXPECT_EQ(answer.rdata, parsed_record.rdata); EXPECT_EQ(answer.owned_rdata, parsed_record.rdata);
// Additional NSEC record. // Additional NSEC record.
EXPECT_TRUE(parser.ReadRecord(&parsed_record)); EXPECT_TRUE(parser.ReadRecord(&parsed_record));
EXPECT_EQ(additional_record.name, parsed_record.name); EXPECT_EQ(additional_record.name, parsed_record.name);
EXPECT_EQ(additional_record.type, parsed_record.type); EXPECT_EQ(additional_record.type, parsed_record.type);
EXPECT_EQ(additional_record.klass, parsed_record.klass); EXPECT_EQ(additional_record.klass, parsed_record.klass);
EXPECT_EQ(additional_record.ttl, parsed_record.ttl); EXPECT_EQ(additional_record.ttl, parsed_record.ttl);
EXPECT_EQ(additional_record.rdata, parsed_record.rdata); EXPECT_EQ(additional_record.owned_rdata, parsed_record.rdata);
} }
} // namespace } // namespace
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "base/big_endian.h"
#include "base/metrics/field_trial.h" #include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
...@@ -31,6 +32,10 @@ namespace { ...@@ -31,6 +32,10 @@ namespace {
// by that number of octets. // by that number of octets.
const int kMaxLabelLength = 63; const int kMaxLabelLength = 63;
// RFC 1035, section 4.1.4: the first two bits of a 16-bit name pointer are
// ones.
const uint16_t kFlagNamePointer = 0xc000;
} // namespace } // namespace
#if defined(OS_POSIX) #if defined(OS_POSIX)
...@@ -240,4 +245,12 @@ AddressListDeltaType FindAddressListDeltaType(const AddressList& a, ...@@ -240,4 +245,12 @@ AddressListDeltaType FindAddressListDeltaType(const AddressList& a,
return DELTA_DISJOINT; return DELTA_DISJOINT;
} }
std::string CreateNamePointer(uint16_t offset) {
DCHECK_LE(offset, 0x3fff);
offset |= kFlagNamePointer;
char buf[2];
base::WriteBigEndian(buf, offset);
return std::string(buf, sizeof(buf));
}
} // namespace net } // namespace net
...@@ -21,8 +21,8 @@ class AddressList; ...@@ -21,8 +21,8 @@ class AddressList;
// //
// dotted: a string in dotted form: "www.google.com" // dotted: a string in dotted form: "www.google.com"
// out: a result in DNS form: "\x03www\x06google\x03com\x00" // out: a result in DNS form: "\x03www\x06google\x03com\x00"
NET_EXPORT_PRIVATE bool DNSDomainFromDot(const base::StringPiece& dotted, NET_EXPORT bool DNSDomainFromDot(const base::StringPiece& dotted,
std::string* out); std::string* out);
// Checks that a hostname is valid. Simple wrapper around DNSDomainFromDot. // Checks that a hostname is valid. Simple wrapper around DNSDomainFromDot.
NET_EXPORT_PRIVATE bool IsValidDNSDomain(const base::StringPiece& dotted); NET_EXPORT_PRIVATE bool IsValidDNSDomain(const base::StringPiece& dotted);
...@@ -44,8 +44,7 @@ NET_EXPORT_PRIVATE bool IsValidHostLabelCharacter(char c, bool is_first_char); ...@@ -44,8 +44,7 @@ NET_EXPORT_PRIVATE bool IsValidHostLabelCharacter(char c, bool is_first_char);
// DNSDomainToString converts a domain in DNS format to a dotted string. // DNSDomainToString converts a domain in DNS format to a dotted string.
// Excludes the dot at the end. // Excludes the dot at the end.
NET_EXPORT_PRIVATE std::string DNSDomainToString( NET_EXPORT std::string DNSDomainToString(const base::StringPiece& domain);
const base::StringPiece& domain);
// Return the expanded template when no variables have corresponding values. // Return the expanded template when no variables have corresponding values.
NET_EXPORT_PRIVATE std::string GetURLFromTemplateWithoutParameters( NET_EXPORT_PRIVATE std::string GetURLFromTemplateWithoutParameters(
...@@ -86,6 +85,13 @@ NET_EXPORT ...@@ -86,6 +85,13 @@ NET_EXPORT
AddressListDeltaType FindAddressListDeltaType(const AddressList& a, AddressListDeltaType FindAddressListDeltaType(const AddressList& a,
const AddressList& b); const AddressList& b);
// Creates a 2-byte string that represents the name pointer defined in Section
// 4.1.1 of RFC 1035 for the given offset. The first two bits in the first byte
// of the name pointer are ones, and the rest 14 bits are given to |offset|,
// which specifies an offset from the start of the message for the pointed name.
// Note that |offset| must be less than 2^14 - 1 by definition.
NET_EXPORT std::string CreateNamePointer(uint16_t offset);
} // namespace net } // namespace net
#endif // NET_DNS_DNS_UTIL_H_ #endif // NET_DNS_DNS_UTIL_H_
...@@ -26,7 +26,7 @@ class DnsRecordParser; ...@@ -26,7 +26,7 @@ class DnsRecordParser;
// Parsed represenation of the extra data in a record. Does not include standard // Parsed represenation of the extra data in a record. Does not include standard
// DNS record data such as TTL, Name, Type and Class. // DNS record data such as TTL, Name, Type and Class.
class NET_EXPORT_PRIVATE RecordRdata { class NET_EXPORT RecordRdata {
public: public:
virtual ~RecordRdata() {} virtual ~RecordRdata() {}
...@@ -79,7 +79,7 @@ class NET_EXPORT_PRIVATE SrvRecordRdata : public RecordRdata { ...@@ -79,7 +79,7 @@ class NET_EXPORT_PRIVATE SrvRecordRdata : public RecordRdata {
// A Record format (http://www.ietf.org/rfc/rfc1035.txt): // A Record format (http://www.ietf.org/rfc/rfc1035.txt):
// 4 bytes for IP address. // 4 bytes for IP address.
class NET_EXPORT_PRIVATE ARecordRdata : public RecordRdata { class NET_EXPORT ARecordRdata : public RecordRdata {
public: public:
static const uint16_t kType = dns_protocol::kTypeA; static const uint16_t kType = dns_protocol::kTypeA;
...@@ -101,7 +101,7 @@ class NET_EXPORT_PRIVATE ARecordRdata : public RecordRdata { ...@@ -101,7 +101,7 @@ class NET_EXPORT_PRIVATE ARecordRdata : public RecordRdata {
// AAAA Record format (http://www.ietf.org/rfc/rfc1035.txt): // AAAA Record format (http://www.ietf.org/rfc/rfc1035.txt):
// 16 bytes for IP address. // 16 bytes for IP address.
class NET_EXPORT_PRIVATE AAAARecordRdata : public RecordRdata { class NET_EXPORT AAAARecordRdata : public RecordRdata {
public: public:
static const uint16_t kType = dns_protocol::kTypeAAAA; static const uint16_t kType = dns_protocol::kTypeAAAA;
......
...@@ -27,7 +27,7 @@ declare_args() { ...@@ -27,7 +27,7 @@ declare_args() {
disable_brotli_filter = false disable_brotli_filter = false
# Multicast DNS. # Multicast DNS.
enable_mdns = is_win || is_linux || is_fuchsia enable_mdns = is_win || is_linux || is_fuchsia || is_mac || is_ios
# Reporting not used on iOS. # Reporting not used on iOS.
enable_reporting = !is_ios enable_reporting = !is_ios
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import("//build/config/jumbo.gni") import("//build/config/jumbo.gni")
import("//mojo/public/tools/bindings/mojom.gni") import("//mojo/public/tools/bindings/mojom.gni")
import("//net/features.gni")
import("//services/catalog/public/tools/catalog.gni") import("//services/catalog/public/tools/catalog.gni")
import("//services/network/public/cpp/features.gni") import("//services/network/public/cpp/features.gni")
import("//services/service_manager/public/cpp/service.gni") import("//services/service_manager/public/cpp/service.gni")
...@@ -158,6 +159,13 @@ jumbo_component("network_service") { ...@@ -158,6 +159,13 @@ jumbo_component("network_service") {
"url_request_context_owner.h", "url_request_context_owner.h",
] ]
if (enable_mdns) {
sources += [
"mdns_responder.cc",
"mdns_responder.h",
]
}
if (!is_ios) { if (!is_ios) {
sources += [ sources += [
"websocket.cc", "websocket.cc",
...@@ -301,6 +309,10 @@ source_set("tests") { ...@@ -301,6 +309,10 @@ source_set("tests") {
"url_loader_unittest.cc", "url_loader_unittest.cc",
] ]
if (enable_mdns) {
sources += [ "mdns_responder_unittest.cc" ]
}
if (!is_ios) { if (!is_ios) {
sources += [ sources += [
"proxy_resolver_factory_mojo_unittest.cc", "proxy_resolver_factory_mojo_unittest.cc",
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -118,6 +118,10 @@ ...@@ -118,6 +118,10 @@
#include "net/url_request/http_user_agent_settings.h" #include "net/url_request/http_user_agent_settings.h"
#endif // BUILDFLAG(ENABLE_REPORTING) #endif // BUILDFLAG(ENABLE_REPORTING)
#if BUILDFLAG(ENABLE_MDNS)
#include "services/network/mdns_responder.h"
#endif // BUILDFLAG(ENABLE_MDNS)
#if defined(USE_NSS_CERTS) #if defined(USE_NSS_CERTS)
#include "net/cert_net/nss_ocsp.h" #include "net/cert_net/nss_ocsp.h"
#endif // defined(USE_NSS_CERTS) #endif // defined(USE_NSS_CERTS)
...@@ -1458,6 +1462,18 @@ void NetworkContext::CreateP2PSocketManager( ...@@ -1458,6 +1462,18 @@ void NetworkContext::CreateP2PSocketManager(
socket_managers_[socket_manager.get()] = std::move(socket_manager); socket_managers_[socket_manager.get()] = std::move(socket_manager);
} }
void NetworkContext::CreateMdnsResponder(
mojom::MdnsResponderRequest responder_request) {
#if BUILDFLAG(ENABLE_MDNS)
if (!mdns_responder_manager_)
mdns_responder_manager_ = std::make_unique<MdnsResponderManager>();
mdns_responder_manager_->CreateMdnsResponder(std::move(responder_request));
#else
NOTREACHED();
#endif // BUILDFLAG(ENABLE_MDNS)
}
void NetworkContext::ResetURLLoaderFactories() { void NetworkContext::ResetURLLoaderFactories() {
for (const auto& factory : url_loader_factories_) for (const auto& factory : url_loader_factories_)
factory->ClearBindings(); factory->ClearBindings();
......
...@@ -69,6 +69,7 @@ class ExpectCTReporter; ...@@ -69,6 +69,7 @@ class ExpectCTReporter;
class HostResolver; class HostResolver;
class NetworkService; class NetworkService;
class NetworkServiceProxyDelegate; class NetworkServiceProxyDelegate;
class MdnsResponderManager;
class P2PSocketManager; class P2PSocketManager;
class ProxyLookupRequest; class ProxyLookupRequest;
class ResourceScheduler; class ResourceScheduler;
...@@ -300,6 +301,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext ...@@ -300,6 +301,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
mojom::P2PTrustedSocketManagerClientPtr client, mojom::P2PTrustedSocketManagerClientPtr client,
mojom::P2PTrustedSocketManagerRequest trusted_socket_manager, mojom::P2PTrustedSocketManagerRequest trusted_socket_manager,
mojom::P2PSocketManagerRequest socket_manager_request) override; mojom::P2PSocketManagerRequest socket_manager_request) override;
void CreateMdnsResponder(
mojom::MdnsResponderRequest responder_request) override;
void ResetURLLoaderFactories() override; void ResetURLLoaderFactories() override;
void QueueReport(const std::string& type, void QueueReport(const std::string& type,
const std::string& group, const std::string& group,
...@@ -431,6 +435,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext ...@@ -431,6 +435,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
base::flat_map<P2PSocketManager*, std::unique_ptr<P2PSocketManager>> base::flat_map<P2PSocketManager*, std::unique_ptr<P2PSocketManager>>
socket_managers_; socket_managers_;
#if BUILDFLAG(ENABLE_MDNS)
std::unique_ptr<MdnsResponderManager> mdns_responder_manager_;
#endif // BUILDFLAG(ENABLE_MDNS)
mojo::StrongBindingSet<mojom::NetLogExporter> net_log_exporter_bindings_; mojo::StrongBindingSet<mojom::NetLogExporter> net_log_exporter_bindings_;
mojo::StrongBindingSet<mojom::RestrictedCookieManager> mojo::StrongBindingSet<mojom::RestrictedCookieManager>
......
...@@ -82,6 +82,7 @@ mojom("mojom") { ...@@ -82,6 +82,7 @@ mojom("mojom") {
"fetch_api.mojom", "fetch_api.mojom",
"host_resolver.mojom", "host_resolver.mojom",
"http_request_headers.mojom", "http_request_headers.mojom",
"mdns_responder.mojom",
"net_log.mojom", "net_log.mojom",
"network_change_manager.mojom", "network_change_manager.mojom",
"network_context.mojom", "network_context.mojom",
......
// Copyright 2018 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.
module network.mojom;
import "net/interfaces/ip_address.mojom";
// An mDNS responder is created for each Mojo binding and it manages the
// name-address maps created through the interface. The name-address maps are
// isolated among different responders, so that the creation and the removal
// of a name for an address is specific to the given responder. When the Mojo
// pipe is closed, all name-address maps created through the interface are
// removed by the responder and the responder is destroyed afterwards. For a
// given responder, all created names are reference counted, and each
// CreateNameForAddress call and RemoveNameForAddress call respectively
// increases and decreases the reference count for existing names.
//
// This interface is intended to be safe to use from renderer processes.
interface MdnsResponder {
// Creates and returns a new name for the address if there is no name mapped
// to it by this responder, and initializes the reference count of this name
// to one. Otherwise the existing name mapped to the given address is returned
// and its reference count is incremented by one. Since the name-address maps
// are specific to the given responder, there could be separated names for the
// same address. After a new name is mapped to an address, an mDNS response to
// announce the ownership of this name is scheduled to send to the mDNS
// multicast group over all interfaces, with a TTL for the name set to 120
// seconds (see RFC 6762, Section 10). Returns true in
// |announcement_scheduled| if the schedule is done on all interfaces after
// rate limiting, and false otherwise. The responder will also start to
// respond to queries for the created name until its reference count is
// decremented to zero.
CreateNameForAddress(net.interfaces.IPAddress address)
=> (string name, bool announcement_scheduled);
// Decrements the reference count of the mapped name of the given address, if
// there is a map created previously via CreateNameForAddress; removes the
// association between the address and its mapped name and returns true in
// |removed| if the decremented reference count reaches zero. Otherwise no
// operation is done and false is returned in |removed|. If the association
// between the address and its mapped name is removed, an mDNS response to
// renounce the ownership of this name is scheduled to send to the mDNS
// multicast group over all interfaces, by setting a zero TTL. Returns true in
// |goodbye_scheduled| if the schedule is done on all interfaces after rate
// limiting, and false otherwise. The responder will also stop responding to
// queries for the removed name. Note that this does not impact separated
// names mapped to the same address by other responders.
RemoveNameForAddress(net.interfaces.IPAddress address)
=> (bool removed, bool goodbye_scheduled);
};
...@@ -14,6 +14,7 @@ import "services/network/public/mojom/cookie_manager.mojom"; ...@@ -14,6 +14,7 @@ import "services/network/public/mojom/cookie_manager.mojom";
import "services/network/public/mojom/cors_origin_pattern.mojom"; import "services/network/public/mojom/cors_origin_pattern.mojom";
import "services/network/public/mojom/host_resolver.mojom"; import "services/network/public/mojom/host_resolver.mojom";
import "services/network/public/mojom/http_request_headers.mojom"; import "services/network/public/mojom/http_request_headers.mojom";
import "services/network/public/mojom/mdns_responder.mojom";
import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom"; import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom";
import "services/network/public/mojom/net_log.mojom"; import "services/network/public/mojom/net_log.mojom";
import "services/network/public/mojom/network_param.mojom"; import "services/network/public/mojom/network_param.mojom";
...@@ -651,6 +652,9 @@ interface NetworkContext { ...@@ -651,6 +652,9 @@ interface NetworkContext {
P2PTrustedSocketManager& trusted_socket_manager, P2PTrustedSocketManager& trusted_socket_manager,
P2PSocketManager& socket_manager); P2PSocketManager& socket_manager);
// Creates an MdnsResponder instance.
CreateMdnsResponder(MdnsResponder& responder_request);
// Destroys all URLLoaderFactory bindings, which should then be regenerated. // Destroys all URLLoaderFactory bindings, which should then be regenerated.
// This should be called if there is a change to the proxies which should be // This should be called if there is a change to the proxies which should be
// used on URLLoaders. // used on URLLoaders.
......
...@@ -180,6 +180,9 @@ class TestNetworkContext : public mojom::NetworkContext { ...@@ -180,6 +180,9 @@ class TestNetworkContext : public mojom::NetworkContext {
mojom::P2PTrustedSocketManagerClientPtr client, mojom::P2PTrustedSocketManagerClientPtr client,
mojom::P2PTrustedSocketManagerRequest trusted_socket_manager, mojom::P2PTrustedSocketManagerRequest trusted_socket_manager,
mojom::P2PSocketManagerRequest socket_manager_request) override {} mojom::P2PSocketManagerRequest socket_manager_request) override {}
void CreateMdnsResponder(
mojom::MdnsResponderRequest responder_request) override {}
void ResetURLLoaderFactories() override {} void ResetURLLoaderFactories() override {}
void ForceReloadProxyConfig( void ForceReloadProxyConfig(
ForceReloadProxyConfigCallback callback) override {} ForceReloadProxyConfigCallback callback) override {}
......
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