diff --git a/garnet/bin/mdns/service/address_prober.cc b/garnet/bin/mdns/service/address_prober.cc index a7691de45967b4c70f591a869edd33659c54694d..206b38f369f010bb2dc2a2b44abaa0a67493551c 100644 --- a/garnet/bin/mdns/service/address_prober.cc +++ b/garnet/bin/mdns/service/address_prober.cc @@ -16,7 +16,7 @@ AddressProber::~AddressProber() {} const std::string& AddressProber::ResourceName() { return host_full_name(); } void AddressProber::SendProposedResources(MdnsResourceSection section) { - SendAddresses(section); + SendAddresses(section, MdnsAddresses::V4MulticastReply(mdns_port())); } } // namespace mdns diff --git a/garnet/bin/mdns/service/address_responder.cc b/garnet/bin/mdns/service/address_responder.cc index 16a93bc84ae5c6eb1db3f64dc79bc050c795d247..f4d9a4492c0798e2dfdb1018c8766296bcce0ce1 100644 --- a/garnet/bin/mdns/service/address_responder.cc +++ b/garnet/bin/mdns/service/address_responder.cc @@ -14,9 +14,11 @@ AddressResponder::AddressResponder(MdnsAgent::Host* host) : MdnsAgent(host) {} AddressResponder::~AddressResponder() {} -void AddressResponder::Start(const std::string& host_full_name) { +void AddressResponder::Start(const std::string& host_full_name, + inet::IpPort mdns_port) { FXL_DCHECK(!host_full_name.empty()); + MdnsAgent::Start(host_full_name, mdns_port); host_full_name_ = host_full_name; } diff --git a/garnet/bin/mdns/service/address_responder.h b/garnet/bin/mdns/service/address_responder.h index cab7760a070cf0b197e702a3e4d1c21305a02846..bf1f0c42b73ea07ced89f771bd8bf46912cf34b4 100644 --- a/garnet/bin/mdns/service/address_responder.h +++ b/garnet/bin/mdns/service/address_responder.h @@ -23,7 +23,8 @@ class AddressResponder : public MdnsAgent { ~AddressResponder() override; // MdnsAgent overrides. - void Start(const std::string& host_full_name) override; + void Start(const std::string& host_full_name, + inet::IpPort mdns_port) override; void ReceiveQuestion(const DnsQuestion& question, const ReplyAddress& reply_address) override; diff --git a/garnet/bin/mdns/service/config.cc b/garnet/bin/mdns/service/config.cc index 840ece937d9aabc6fc7cd2b981e0cfe3648803b4..1ed3cd3ca5db532251e52009af51b514350160c9 100644 --- a/garnet/bin/mdns/service/config.cc +++ b/garnet/bin/mdns/service/config.cc @@ -17,6 +17,11 @@ const char kSchema[] = R"({ "type": "object", "additionalProperties": false, "properties": { + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, "perform_host_name_probe": { "type": "boolean" }, @@ -89,6 +94,13 @@ void Config::IntegrateDocument(const rapidjson::Document& document, const std::string& host_name) { FXL_DCHECK(document.IsObject()); + if (document.HasMember(kPortKey)) { + FXL_DCHECK(document[kPortKey].IsUint()); + FXL_DCHECK(document[kPortKey].GetUint() >= 1); + FXL_DCHECK(document[kPortKey].GetUint() <= 65535); + mdns_port_ = inet::IpPort::From_uint16_t(document[kPortKey].GetUint()); + } + if (document.HasMember(kPerformHostNameProbeKey)) { FXL_DCHECK(document[kPerformHostNameProbeKey].IsBool()); SetPerformHostNameProbe(document[kPerformHostNameProbeKey].GetBool()); diff --git a/garnet/bin/mdns/service/config.h b/garnet/bin/mdns/service/config.h index 4e472896c4145d9f61426dae7700c09914e12fe4..9d827fd979c3622f4223863a103fdb1e6e5d7d7c 100644 --- a/garnet/bin/mdns/service/config.h +++ b/garnet/bin/mdns/service/config.h @@ -8,6 +8,7 @@ #include <optional> #include "garnet/bin/mdns/service/mdns.h" +#include "garnet/bin/mdns/service/mdns_addresses.h" #include "lib/json/json_parser.h" #include "rapidjson/document.h" @@ -39,6 +40,9 @@ class Config { // an empty string. std::string error() { return parser_.error_str(); } + // Returns the port to use for mDNS multicast communication (normally 5353). + inet::IpPort mdns_port() { return mdns_port_; } + // Indicates whether a probe should be performed for the hostname. bool perform_host_name_probe() { return perform_host_name_probe_.has_value() @@ -66,6 +70,7 @@ class Config { void SetPerformHostNameProbe(bool perform_host_name_probe); json::JSONParser parser_; + inet::IpPort mdns_port_ = MdnsAddresses::kDefaultMdnsPort; std::optional<bool> perform_host_name_probe_; std::vector<Publication> publications_; }; diff --git a/garnet/bin/mdns/service/host_name_resolver.cc b/garnet/bin/mdns/service/host_name_resolver.cc index 412bdde8e696cbc029b60b244a656cdbaae5e8e1..7a728ec652373cf8f4ad006fe1e702960eafaa6c 100644 --- a/garnet/bin/mdns/service/host_name_resolver.cc +++ b/garnet/bin/mdns/service/host_name_resolver.cc @@ -24,10 +24,13 @@ HostNameResolver::HostNameResolver(MdnsAgent::Host* host, HostNameResolver::~HostNameResolver() {} -void HostNameResolver::Start(const std::string& host_full_name) { +void HostNameResolver::Start(const std::string& host_full_name, + inet::IpPort mdns_port) { // Note that |host_full_name_| is the name we're trying to resolve, not the // name of the local host, which is the (ignored) parameter to this method. + MdnsAgent::Start(host_full_name, mdns_port); + SendQuestion(std::make_shared<DnsQuestion>(host_full_name_, DnsType::kA)); SendQuestion(std::make_shared<DnsQuestion>(host_full_name_, DnsType::kAaaa)); diff --git a/garnet/bin/mdns/service/host_name_resolver.h b/garnet/bin/mdns/service/host_name_resolver.h index 24566d2a57ed35ec4631d8ab0e2dda7c820656f9..6a4a70c4889df9567ce5f680cd35b764a155e8db 100644 --- a/garnet/bin/mdns/service/host_name_resolver.h +++ b/garnet/bin/mdns/service/host_name_resolver.h @@ -26,7 +26,8 @@ class HostNameResolver : public MdnsAgent { ~HostNameResolver() override; // MdnsAgent overrides. - void Start(const std::string& host_full_name) override; + void Start(const std::string& host_full_name, + inet::IpPort mdns_port) override; void ReceiveResource(const DnsResource& resource, MdnsResourceSection section) override; diff --git a/garnet/bin/mdns/service/instance_prober.cc b/garnet/bin/mdns/service/instance_prober.cc index 557232c641605fe6c5cbea86cf1e0f1afcd3fe06..af9cd9944c3ea7695d451a8c56e56ee38ca90343 100644 --- a/garnet/bin/mdns/service/instance_prober.cc +++ b/garnet/bin/mdns/service/instance_prober.cc @@ -12,8 +12,7 @@ namespace mdns { InstanceProber::InstanceProber(MdnsAgent::Host* host, const std::string& service_name, const std::string& instance_name, - inet::IpPort port, - CompletionCallback callback) + inet::IpPort port, CompletionCallback callback) : Prober(host, DnsType::kSrv, std::move(callback)), instance_full_name_( MdnsNames::LocalInstanceFullName(instance_name, service_name)), @@ -30,7 +29,8 @@ void InstanceProber::SendProposedResources(MdnsResourceSection section) { std::make_shared<DnsResource>(instance_full_name_, DnsType::kSrv); srv_resource->srv_.port_ = port_; srv_resource->srv_.target_ = host_full_name(); - SendResource(srv_resource, section); + SendResource(srv_resource, section, + MdnsAddresses::V4MulticastReply(mdns_port())); } } // namespace mdns diff --git a/garnet/bin/mdns/service/instance_requestor.cc b/garnet/bin/mdns/service/instance_requestor.cc index 98f2ac4181dca225d3a85992d92a9f116b49c172..1be9300fb51d10b052cc093db0f404beb699d59a 100644 --- a/garnet/bin/mdns/service/instance_requestor.cc +++ b/garnet/bin/mdns/service/instance_requestor.cc @@ -38,7 +38,9 @@ void InstanceRequestor::RemoveSubscriber(Mdns::Subscriber* subscriber) { } } -void InstanceRequestor::Start(const std::string& host_full_name) { +void InstanceRequestor::Start(const std::string& host_full_name, + inet::IpPort mdns_port) { + MdnsAgent::Start(host_full_name, mdns_port); SendQuery(); } diff --git a/garnet/bin/mdns/service/instance_requestor.h b/garnet/bin/mdns/service/instance_requestor.h index 9f48d368ac96f3ae6ac178da5e259b16e5d20136..cb5c416424759ec5e1dbb43294adf7c237b4a507 100644 --- a/garnet/bin/mdns/service/instance_requestor.h +++ b/garnet/bin/mdns/service/instance_requestor.h @@ -33,7 +33,8 @@ class InstanceRequestor : public MdnsAgent { void RemoveSubscriber(Mdns::Subscriber* subscriber); // MdnsAgent overrides. - void Start(const std::string& host_full_name) override; + void Start(const std::string& host_full_name, + inet::IpPort mdns_port) override; void ReceiveResource(const DnsResource& resource, MdnsResourceSection section) override; diff --git a/garnet/bin/mdns/service/instance_responder.cc b/garnet/bin/mdns/service/instance_responder.cc index 6f6a35df04599a682644596a655fad8b541af885..9308e7b22d0fb5c88030cd5522f5de9fe8c5bd2d 100644 --- a/garnet/bin/mdns/service/instance_responder.cc +++ b/garnet/bin/mdns/service/instance_responder.cc @@ -25,9 +25,12 @@ InstanceResponder::InstanceResponder(MdnsAgent::Host* host, InstanceResponder::~InstanceResponder() {} -void InstanceResponder::Start(const std::string& host_full_name) { +void InstanceResponder::Start(const std::string& host_full_name, + inet::IpPort mdns_port) { FXL_DCHECK(!host_full_name.empty()); + MdnsAgent::Start(host_full_name, mdns_port); + host_full_name_ = host_full_name; Reannounce(); @@ -82,7 +85,8 @@ void InstanceResponder::SetSubtypes(std::vector<std::string> subtypes) { for (const std::string& subtype : subtypes_) { if (std::find(subtypes.begin(), subtypes.end(), subtype) == subtypes.end()) { - SendSubtypePtrRecord(subtype, 0); + SendSubtypePtrRecord(subtype, 0, + MdnsAddresses::V4MulticastReply(mdns_port())); } } @@ -99,10 +103,12 @@ void InstanceResponder::Reannounce() { } void InstanceResponder::SendAnnouncement() { - GetAndSendPublication(false); + GetAndSendPublication(false, "", + MdnsAddresses::V4MulticastReply(mdns_port())); for (const std::string& subtype : subtypes_) { - SendSubtypePtrRecord(subtype); + SendSubtypePtrRecord(subtype, DnsResource::kShortTimeToLive, + MdnsAddresses::V4MulticastReply(mdns_port())); } if (announcement_interval_ > kMaxAnnouncementInterval) { @@ -189,7 +195,8 @@ void InstanceResponder::SendGoodbye() const { publication.srv_ttl_seconds_ = 0; publication.txt_ttl_seconds_ = 0; - SendPublication(publication); + SendPublication(publication, "", + MdnsAddresses::V4MulticastReply(mdns_port())); } } // namespace mdns diff --git a/garnet/bin/mdns/service/instance_responder.h b/garnet/bin/mdns/service/instance_responder.h index c777fa16b3d26909dcaf51410e9a8b36f3bac036..dfd7e7e767e35e9f4fdbcbd4dda032a6238efbc6 100644 --- a/garnet/bin/mdns/service/instance_responder.h +++ b/garnet/bin/mdns/service/instance_responder.h @@ -28,7 +28,8 @@ class InstanceResponder : public MdnsAgent { ~InstanceResponder() override; // MdnsAgent overrides. - void Start(const std::string& host_full_name) override; + void Start(const std::string& host_full_name, + inet::IpPort mdns_port) override; void ReceiveQuestion(const DnsQuestion& question, const ReplyAddress& reply_address) override; @@ -60,21 +61,17 @@ class InstanceResponder : public MdnsAgent { // Gets an |Mdns::Publication| from |mdns_responder_| and, if not null, sends // it. An empty |subtype| indicates no subtype. - void GetAndSendPublication(bool query, const std::string& subtype = "", - const ReplyAddress& reply_address = - MdnsAddresses::kV4MulticastReply) const; + void GetAndSendPublication(bool query, const std::string& subtype, + const ReplyAddress& reply_address) const; // Sends a publication. An empty |subtype| indicates no subtype. void SendPublication(const Mdns::Publication& publication, - const std::string& subtype = "", - const ReplyAddress& reply_address = - MdnsAddresses::kV4MulticastReply) const; + const std::string& subtype, + const ReplyAddress& reply_address) const; // Sends a subtype PTR record for this instance. - void SendSubtypePtrRecord(const std::string& subtype, - uint32_t ttl = DnsResource::kShortTimeToLive, - const ReplyAddress& reply_address = - MdnsAddresses::kV4MulticastReply) const; + void SendSubtypePtrRecord(const std::string& subtype, uint32_t ttl, + const ReplyAddress& reply_address) const; // Sends a publication with zero ttls, indicating the service instance is // no longer published. diff --git a/garnet/bin/mdns/service/mdns.cc b/garnet/bin/mdns/service/mdns.cc index 0fa8564bc22f6b186a0c8544807fb7e736878d8d..c985e238327ef51856788389322f14064641f21f 100644 --- a/garnet/bin/mdns/service/mdns.cc +++ b/garnet/bin/mdns/service/mdns.cc @@ -37,8 +37,8 @@ void Mdns::SetVerbose(bool verbose) { } void Mdns::Start(fuchsia::netstack::NetstackPtr netstack, - const std::string& host_name, bool perform_address_probe, - fit::closure ready_callback) { + const std::string& host_name, inet::IpPort mdns_port, + bool perform_address_probe, fit::closure ready_callback) { FXL_DCHECK(!host_name.empty()); FXL_DCHECK(ready_callback); FXL_DCHECK(state_ == State::kNotStarted); @@ -47,6 +47,7 @@ void Mdns::Start(fuchsia::netstack::NetstackPtr netstack, state_ = State::kWaitingForInterfaces; original_host_name_ = host_name; + mdns_port_ = mdns_port; // Create a resource renewer agent to keep resources alive. resource_renewer_ = std::make_shared<ResourceRenewer>(this); @@ -55,7 +56,7 @@ void Mdns::Start(fuchsia::netstack::NetstackPtr netstack, AddAgent(std::make_shared<AddressResponder>(this)); transceiver_.Start( - std::move(netstack), + std::move(netstack), mdns_port, [this, perform_address_probe]() { // TODO(dalesat): Link changes that create host name conflicts. // Once we have a NIC and we've decided on a unique host name, we @@ -80,11 +81,11 @@ void Mdns::Start(fuchsia::netstack::NetstackPtr netstack, for (auto& question : message->questions_) { // We reply to questions using unicast if specifically requested in // the question or if the sender's port isn't 5353. - ReceiveQuestion(*question, (question->unicast_response_ || - reply_address.socket_address().port() != - MdnsAddresses::kMdnsPort) - ? reply_address - : MdnsAddresses::kV4MulticastReply); + ReceiveQuestion(*question, + (question->unicast_response_ || + reply_address.socket_address().port() != mdns_port_) + ? reply_address + : MdnsAddresses::V4MulticastReply(mdns_port_)); } for (auto& resource : message->answers_) { @@ -212,7 +213,7 @@ void Mdns::StartAddressProbe(const std::string& host_name) { // We don't use |AddAgent| here, because agents added that way don't // actually participate until we're done probing for host name conflicts. agents_.emplace(address_prober.get(), address_prober); - address_prober->Start(host_full_name_); + address_prober->Start(host_full_name_, mdns_port_); SendMessages(); } @@ -231,7 +232,7 @@ void Mdns::OnReady() { // |resource_renewer_| doesn't need to be started, but we do it // anyway in case that changes. - resource_renewer_->Start(host_full_name_); + resource_renewer_->Start(host_full_name_, mdns_port_); for (auto agent : agents_awaiting_start_) { AddAgent(agent); @@ -263,7 +264,8 @@ void Mdns::PostTaskForTime(MdnsAgent* agent, fit::closure task, void Mdns::SendQuestion(std::shared_ptr<DnsQuestion> question) { FXL_DCHECK(question); DnsMessage& message = - outbound_messages_by_reply_address_[MdnsAddresses::kV4MulticastReply]; + outbound_messages_by_reply_address_[MdnsAddresses::V4MulticastReply( + mdns_port_)]; message.questions_.push_back(question); } @@ -345,7 +347,7 @@ void Mdns::AddAgent(std::shared_ptr<MdnsAgent> agent) { if (state_ == State::kActive) { agents_.emplace(agent.get(), agent); FXL_DCHECK(!host_full_name_.empty()); - agent->Start(host_full_name_); + agent->Start(host_full_name_, mdns_port_); SendMessages(); } else { agents_awaiting_start_.push_back(agent); @@ -406,7 +408,7 @@ void Mdns::SendMessages() { #ifdef MDNS_TRACE if (verbose_) { - if (reply_address == MdnsAddresses::kV4MulticastReply) { + if (reply_address == MdnsAddresses::V4MulticastReply(mdns_port_)) { FXL_LOG(INFO) << "Outbound message (multicast): " << message; } else { FXL_LOG(INFO) << "Outbound message to " << reply_address << ":" diff --git a/garnet/bin/mdns/service/mdns.h b/garnet/bin/mdns/service/mdns.h index 9c7867b23e42b344a9463e790e99a6e96eba0477..21cd8100286d7760302b9096f4a21482d5c70aaf 100644 --- a/garnet/bin/mdns/service/mdns.h +++ b/garnet/bin/mdns/service/mdns.h @@ -144,7 +144,8 @@ class Mdns : public MdnsAgent::Host { // calls to |ResolveHostName|, |SubscribeToService| and // |PublishServiceInstance|. void Start(fuchsia::netstack::NetstackPtr, const std::string& host_name, - bool perform_address_probe, fit::closure ready_callback); + inet::IpPort mdns_port, bool perform_address_probe, + fit::closure ready_callback); // Stops the transceiver. void Stop(); @@ -278,6 +279,7 @@ class Mdns : public MdnsAgent::Host { async_dispatcher_t* dispatcher_; MdnsTransceiver transceiver_; std::string original_host_name_; + inet::IpPort mdns_port_; fit::closure ready_callback_; uint32_t next_host_name_deduplicator_ = 2; std::string host_name_; diff --git a/garnet/bin/mdns/service/mdns_addresses.cc b/garnet/bin/mdns/service/mdns_addresses.cc index 2369dfa5ac4c9978a154a83b8ff9bd12327b905c..a95beef4a7952191a5630a5bd7f112750ec8d98f 100644 --- a/garnet/bin/mdns/service/mdns_addresses.cc +++ b/garnet/bin/mdns/service/mdns_addresses.cc @@ -7,26 +7,32 @@ namespace mdns { // static -const inet::IpPort MdnsAddresses::kMdnsPort = inet::IpPort::From_uint16_t(5353); +const inet::IpPort MdnsAddresses::kDefaultMdnsPort = + inet::IpPort::From_uint16_t(5353); // static -const inet::SocketAddress MdnsAddresses::kV4Multicast(224, 0, 0, 251, - kMdnsPort); +inet::SocketAddress MdnsAddresses::V4Multicast(inet::IpPort port) { + return inet::SocketAddress(224, 0, 0, 251, port); +} // static -const inet::SocketAddress MdnsAddresses::kV6Multicast(0xff02, 0xfb, kMdnsPort); +inet::SocketAddress MdnsAddresses::V6Multicast(inet::IpPort port) { + return inet::SocketAddress(0xff02, 0xfb, port); +} // static -const inet::SocketAddress MdnsAddresses::kV4Bind(INADDR_ANY, kMdnsPort); +inet::SocketAddress MdnsAddresses::V4Bind(inet::IpPort port) { + return inet::SocketAddress(INADDR_ANY, port); +} // static -const inet::SocketAddress MdnsAddresses::kV6Bind(in6addr_any, kMdnsPort); +inet::SocketAddress MdnsAddresses::V6Bind(inet::IpPort port) { + return inet::SocketAddress(in6addr_any, port); +} // static -const ReplyAddress MdnsAddresses::kV4MulticastReply(MdnsAddresses::kV4Multicast, - inet::IpAddress()); +ReplyAddress MdnsAddresses::V4MulticastReply(inet::IpPort port) { + return ReplyAddress(V4Multicast(port), inet::IpAddress()); +} -// static -const ReplyAddress MdnsAddresses::kV6MulticastReply(MdnsAddresses::kV6Multicast, - inet::IpAddress()); } // namespace mdns diff --git a/garnet/bin/mdns/service/mdns_addresses.h b/garnet/bin/mdns/service/mdns_addresses.h index 9888315b4f502432dbbbb01087291876bf004b32..88d20326537ce0839bd4a469fdd427d024218bba 100644 --- a/garnet/bin/mdns/service/mdns_addresses.h +++ b/garnet/bin/mdns/service/mdns_addresses.h @@ -14,15 +14,14 @@ namespace mdns { struct MdnsAddresses { - static const inet::IpPort kMdnsPort; + static const inet::IpPort kDefaultMdnsPort; - static const inet::SocketAddress kV4Multicast; - static const inet::SocketAddress kV6Multicast; - static const inet::SocketAddress kV4Bind; - static const inet::SocketAddress kV6Bind; + static inet::SocketAddress V4Multicast(inet::IpPort port); + static inet::SocketAddress V6Multicast(inet::IpPort port); + static inet::SocketAddress V4Bind(inet::IpPort port); + static inet::SocketAddress V6Bind(inet::IpPort port); - static const ReplyAddress kV4MulticastReply; - static const ReplyAddress kV6MulticastReply; + static ReplyAddress V4MulticastReply(inet::IpPort port); }; } // namespace mdns diff --git a/garnet/bin/mdns/service/mdns_agent.h b/garnet/bin/mdns/service/mdns_agent.h index 08a54c87546bc0d168f8745ffb29ad92079954c8..ebe980ac020e99956df16b2537c09587de7880fe 100644 --- a/garnet/bin/mdns/service/mdns_agent.h +++ b/garnet/bin/mdns/service/mdns_agent.h @@ -5,10 +5,10 @@ #ifndef GARNET_BIN_MDNS_SERVICE_MDNS_AGENT_H_ #define GARNET_BIN_MDNS_SERVICE_MDNS_AGENT_H_ -#include <memory> - #include <lib/fit/function.h> +#include <memory> + #include "garnet/bin/mdns/service/dns_message.h" #include "garnet/bin/mdns/service/mdns_addresses.h" #include "garnet/lib/inet/socket_address.h" @@ -63,7 +63,11 @@ class MdnsAgent : public std::enable_shared_from_this<MdnsAgent> { // Starts the agent. This method is never called before a shared pointer to // the agent is created, so |shared_from_this| is safe to call. - virtual void Start(const std::string& host_full_name) {} + // Specializations should call this method first. + virtual void Start(const std::string& host_full_name, + inet::IpPort mdns_port) { + mdns_port_ = mdns_port; + } // Presents a received question. This agent must not call |RemoveSelf| during // a call to this method. @@ -86,6 +90,8 @@ class MdnsAgent : public std::enable_shared_from_this<MdnsAgent> { protected: MdnsAgent(Host* host) : host_(host) { FXL_DCHECK(host_); } + inet::IpPort mdns_port() const { return mdns_port_; } + // Posts a task to be executed at the specified time. Scheduled tasks posted // by agents that have since been removed are not executed. void PostTaskForTime(fit::closure task, fxl::TimePoint target_time) { @@ -97,22 +103,16 @@ class MdnsAgent : public std::enable_shared_from_this<MdnsAgent> { host_->SendQuestion(question); } - // Sends a resource to the specified address. The default |reply_address| - // |kV4MulticastReply| sends the resource to the V4 or V6 - // multicast address. + // Sends a resource to the specified address. void SendResource(std::shared_ptr<DnsResource> resource, MdnsResourceSection section, - const ReplyAddress& reply_address = - MdnsAddresses::kV4MulticastReply) const { + const ReplyAddress& reply_address) const { host_->SendResource(resource, section, reply_address); } - // Sends address resources to the specified address. The default - // |reply_address| |kV4MulticastReply| sends the addresses to the V4 or V6 - // multicast address. + // Sends address resources to the specified address. void SendAddresses(MdnsResourceSection section, - const ReplyAddress& reply_address = - MdnsAddresses::kV4MulticastReply) const { + const ReplyAddress& reply_address) const { host_->SendAddresses(section, reply_address); } @@ -137,6 +137,7 @@ class MdnsAgent : public std::enable_shared_from_this<MdnsAgent> { private: Host* host_; + inet::IpPort mdns_port_; }; } // namespace mdns diff --git a/garnet/bin/mdns/service/mdns_interface_transceiver.cc b/garnet/bin/mdns/service/mdns_interface_transceiver.cc index 7cfdf71ee1ed39f343aabf3d96f427bbfbe97c76..ea5ae792c2f27bd1a017b6096e3270aefabc70a2 100644 --- a/garnet/bin/mdns/service/mdns_interface_transceiver.cc +++ b/garnet/bin/mdns/service/mdns_interface_transceiver.cc @@ -10,8 +10,10 @@ #include <lib/async/default.h> #include <poll.h> #include <sys/socket.h> + #include <algorithm> #include <iostream> + #include "garnet/bin/mdns/service/dns_formatting.h" #include "garnet/bin/mdns/service/dns_reading.h" #include "garnet/bin/mdns/service/dns_writing.h" @@ -19,9 +21,9 @@ #include "garnet/bin/mdns/service/mdns_interface_transceiver_v4.h" #include "garnet/bin/mdns/service/mdns_interface_transceiver_v6.h" #include "lib/fostr/hex_dump.h" +#include "src/lib/files/unique_fd.h" #include "src/lib/fxl/logging.h" #include "src/lib/fxl/time/time_delta.h" -#include "src/lib/files/unique_fd.h" namespace mdns { @@ -46,12 +48,15 @@ MdnsInterfaceTransceiver::MdnsInterfaceTransceiver(inet::IpAddress address, MdnsInterfaceTransceiver::~MdnsInterfaceTransceiver() {} -bool MdnsInterfaceTransceiver::Start(InboundMessageCallback callback) { +bool MdnsInterfaceTransceiver::Start(inet::IpPort mdns_port, + InboundMessageCallback callback) { FXL_DCHECK(callback); FXL_DCHECK(!socket_fd_.is_valid()) << "Start called when already started."; + mdns_port_ = mdns_port; + std::cerr << "Starting mDNS on interface " << name_ << " " << address_ - << "\n"; + << " using port " << mdns_port_ << "\n"; socket_fd_ = fxl::UniqueFD(socket(address_.family(), SOCK_DGRAM, 0)); @@ -93,7 +98,7 @@ void MdnsInterfaceTransceiver::SendMessage(DnsMessage* message, FXL_DCHECK(message); FXL_DCHECK(address.is_valid()); FXL_DCHECK(address.family() == address_.family() || - address == MdnsAddresses::kV4Multicast); + address == MdnsAddresses::V4Multicast(mdns_port_)); FixUpAddresses(&message->answers_); FixUpAddresses(&message->authorities_); @@ -120,7 +125,7 @@ void MdnsInterfaceTransceiver::SendAddress(const std::string& host_full_name) { DnsMessage message; message.answers_.push_back(GetAddressResource(host_full_name)); - SendMessage(&message, MdnsAddresses::kV4Multicast); + SendMessage(&message, MdnsAddresses::V4Multicast(mdns_port_)); } void MdnsInterfaceTransceiver::SendAddressGoodbye( @@ -130,7 +135,7 @@ void MdnsInterfaceTransceiver::SendAddressGoodbye( message.answers_.push_back(MakeAddressResource(host_full_name, address_)); message.answers_.back()->time_to_live_ = 0; - SendMessage(&message, MdnsAddresses::kV4Multicast); + SendMessage(&message, MdnsAddresses::V4Multicast(mdns_port_)); } void MdnsInterfaceTransceiver::LogTraffic() { diff --git a/garnet/bin/mdns/service/mdns_interface_transceiver.h b/garnet/bin/mdns/service/mdns_interface_transceiver.h index f8784bf4a40973a0017885d9d3bf0adb90420f9d..fcb0d44393e94c2d4050bd6a15a1b0ac9359619b 100644 --- a/garnet/bin/mdns/service/mdns_interface_transceiver.h +++ b/garnet/bin/mdns/service/mdns_interface_transceiver.h @@ -5,18 +5,18 @@ #ifndef GARNET_BIN_MDNS_SERVICE_MDNS_INTERFACE_TRANSCEIVER_H_ #define GARNET_BIN_MDNS_SERVICE_MDNS_INTERFACE_TRANSCEIVER_H_ +#include <lib/fit/function.h> + #include <memory> #include <vector> -#include <lib/fit/function.h> - #include "garnet/bin/mdns/service/dns_message.h" #include "garnet/bin/mdns/service/reply_address.h" #include "garnet/lib/inet/ip_address.h" #include "garnet/lib/inet/socket_address.h" #include "lib/fsl/tasks/fd_waiter.h" -#include "src/lib/fxl/macros.h" #include "src/lib/files/unique_fd.h" +#include "src/lib/fxl/macros.h" namespace mdns { @@ -44,7 +44,7 @@ class MdnsInterfaceTransceiver { uint32_t index() const { return index_; } // Starts the interface transceiver. - bool Start(InboundMessageCallback callback); + bool Start(inet::IpPort mdns_port, InboundMessageCallback callback); // Stops the interface transceiver. void Stop(); @@ -53,8 +53,8 @@ class MdnsInterfaceTransceiver { void SetAlternateAddress(const inet::IpAddress& alternate_address); // Sends a message to the specified address. A V6 interface will send to - // |MdnsAddresses::kV6Multicast| if |reply_address| is - // |MdnsAddresses::kV4Multicast|. This method expects there to be at most two + // |MdnsAddresses::V6Multicast| if |reply_address| is + // |MdnsAddresses::V4Multicast|. This method expects there to be at most two // address records per record vector and, if there are two, that they are // adjacent. The same constraints will apply when this method returns. void SendMessage(DnsMessage* message, const inet::SocketAddress& address); @@ -77,6 +77,7 @@ class MdnsInterfaceTransceiver { uint32_t index); const fxl::UniqueFD& socket_fd() const { return socket_fd_; } + inet::IpPort mdns_port() const { return mdns_port_; } virtual int SetOptionDisableMulticastLoop() = 0; virtual int SetOptionJoinMulticastGroup() = 0; @@ -123,6 +124,7 @@ class MdnsInterfaceTransceiver { fsl::FDWaiter fd_waiter_; std::vector<uint8_t> inbound_buffer_; std::vector<uint8_t> outbound_buffer_; + inet::IpPort mdns_port_; InboundMessageCallback inbound_message_callback_; std::shared_ptr<DnsResource> address_resource_; std::shared_ptr<DnsResource> alternate_address_resource_; diff --git a/garnet/bin/mdns/service/mdns_interface_transceiver_v4.cc b/garnet/bin/mdns/service/mdns_interface_transceiver_v4.cc index 2e2cdc05638aad49064e6193ef1a84ae1d882b73..8439a7ec75b0fe69717546d9d0e1c28d27227dc0 100644 --- a/garnet/bin/mdns/service/mdns_interface_transceiver_v4.cc +++ b/garnet/bin/mdns/service/mdns_interface_transceiver_v4.cc @@ -35,7 +35,7 @@ int MdnsInterfaceTransceiverV4::SetOptionDisableMulticastLoop() { int MdnsInterfaceTransceiverV4::SetOptionJoinMulticastGroup() { ip_mreqn param; param.imr_multiaddr.s_addr = - MdnsAddresses::kV4Multicast.as_sockaddr_in().sin_addr.s_addr; + MdnsAddresses::V4Multicast(mdns_port()).as_sockaddr_in().sin_addr.s_addr; param.imr_address = address().as_in_addr(); param.imr_ifindex = index(); int result = setsockopt(socket_fd().get(), IPPROTO_IP, IP_ADD_MEMBERSHIP, @@ -95,8 +95,9 @@ int MdnsInterfaceTransceiverV4::SetOptionFamilySpecific() { } int MdnsInterfaceTransceiverV4::Bind() { - int result = bind(socket_fd().get(), MdnsAddresses::kV4Bind.as_sockaddr(), - MdnsAddresses::kV4Bind.socklen()); + int result = + bind(socket_fd().get(), MdnsAddresses::V4Bind(mdns_port()).as_sockaddr(), + MdnsAddresses::V4Bind(mdns_port()).socklen()); if (result < 0) { FXL_LOG(ERROR) << "Failed to bind socket to V4 address, " << strerror(errno); diff --git a/garnet/bin/mdns/service/mdns_interface_transceiver_v6.cc b/garnet/bin/mdns/service/mdns_interface_transceiver_v6.cc index b7e807f72e44367946a6ca30e70e4315f2f63044..d58cd4a119f14d264b1586890d6b689aca9a6d50 100644 --- a/garnet/bin/mdns/service/mdns_interface_transceiver_v6.cc +++ b/garnet/bin/mdns/service/mdns_interface_transceiver_v6.cc @@ -41,7 +41,7 @@ int MdnsInterfaceTransceiverV6::SetOptionDisableMulticastLoop() { int MdnsInterfaceTransceiverV6::SetOptionJoinMulticastGroup() { ipv6_mreq param; param.ipv6mr_multiaddr = - MdnsAddresses::kV6Multicast.as_sockaddr_in6().sin6_addr; + MdnsAddresses::V6Multicast(mdns_port()).as_sockaddr_in6().sin6_addr; param.ipv6mr_interface = index(); int result = setsockopt(socket_fd().get(), IPPROTO_IPV6, IPV6_JOIN_GROUP, ¶m, sizeof(param)); @@ -125,8 +125,9 @@ int MdnsInterfaceTransceiverV6::SetOptionFamilySpecific() { } int MdnsInterfaceTransceiverV6::Bind() { - int result = bind(socket_fd().get(), MdnsAddresses::kV6Bind.as_sockaddr(), - MdnsAddresses::kV6Bind.socklen()); + int result = + bind(socket_fd().get(), MdnsAddresses::V6Bind(mdns_port()).as_sockaddr(), + MdnsAddresses::V6Bind(mdns_port()).socklen()); if (result < 0) { FXL_LOG(ERROR) << "Failed to bind socket to V6 address, " << strerror(errno); @@ -137,10 +138,10 @@ int MdnsInterfaceTransceiverV6::Bind() { int MdnsInterfaceTransceiverV6::SendTo(const void* buffer, size_t size, const inet::SocketAddress& address) { - if (address == MdnsAddresses::kV4Multicast) { + if (address == MdnsAddresses::V4Multicast(mdns_port())) { return sendto(socket_fd().get(), buffer, size, 0, - MdnsAddresses::kV6Multicast.as_sockaddr(), - MdnsAddresses::kV6Multicast.socklen()); + MdnsAddresses::V6Multicast(mdns_port()).as_sockaddr(), + MdnsAddresses::V6Multicast(mdns_port()).socklen()); } return sendto(socket_fd().get(), buffer, size, 0, address.as_sockaddr(), diff --git a/garnet/bin/mdns/service/mdns_service_impl.cc b/garnet/bin/mdns/service/mdns_service_impl.cc index a3dae9e4c3e9419c0fa490a3e6697a3511036e0c..f015a374381f7733f6d08c2a028e2d1ad209dcc5 100644 --- a/garnet/bin/mdns/service/mdns_service_impl.cc +++ b/garnet/bin/mdns/service/mdns_service_impl.cc @@ -68,7 +68,7 @@ void MdnsServiceImpl::Start() { } mdns_.Start(component_context_->svc()->Connect<fuchsia::netstack::Netstack>(), - host_name, config_.perform_host_name_probe(), + host_name, config_.mdns_port(), config_.perform_host_name_probe(), fit::bind_member(this, &MdnsServiceImpl::OnReady)); } diff --git a/garnet/bin/mdns/service/mdns_transceiver.cc b/garnet/bin/mdns/service/mdns_transceiver.cc index 6dda06a806045227a5cac3e525fd9abaf1455db8..d7afd3892915db90e19c2f3d70adbdc5444bb749 100644 --- a/garnet/bin/mdns/service/mdns_transceiver.cc +++ b/garnet/bin/mdns/service/mdns_transceiver.cc @@ -7,6 +7,7 @@ #include <arpa/inet.h> #include <errno.h> #include <sys/socket.h> + #include "garnet/bin/mdns/service/mdns_addresses.h" #include "garnet/bin/mdns/service/mdns_fidl_util.h" #include "src/lib/files/unique_fd.h" @@ -19,6 +20,7 @@ MdnsTransceiver::MdnsTransceiver() {} MdnsTransceiver::~MdnsTransceiver() {} void MdnsTransceiver::Start(fuchsia::netstack::NetstackPtr netstack, + inet::IpPort mdns_port, fit::closure link_change_callback, InboundMessageCallback inbound_message_callback) { FXL_DCHECK(netstack); @@ -26,6 +28,7 @@ void MdnsTransceiver::Start(fuchsia::netstack::NetstackPtr netstack, FXL_DCHECK(inbound_message_callback); netstack_ = std::move(netstack); + mdns_port_ = mdns_port; link_change_callback_ = std::move(link_change_callback); inbound_message_callback_ = std::move(inbound_message_callback); @@ -54,7 +57,8 @@ void MdnsTransceiver::SendMessage(DnsMessage* message, const ReplyAddress& reply_address) { FXL_DCHECK(message); - if (reply_address.socket_address() == MdnsAddresses::kV4Multicast) { + if (reply_address.socket_address() == + MdnsAddresses::V4Multicast(mdns_port_)) { for (auto& [address, interface] : interface_transceivers_by_address_) { FXL_DCHECK(interface); interface->SendMessage(message, reply_address.socket_address()); @@ -179,7 +183,8 @@ bool MdnsTransceiver::EnsureInterfaceTransceiver( auto interface_transceiver = MdnsInterfaceTransceiver::Create(address, name, id); - if (!interface_transceiver->Start(inbound_message_callback_.share())) { + if (!interface_transceiver->Start(mdns_port_, + inbound_message_callback_.share())) { // Couldn't start the transceiver. return result_on_fail; } diff --git a/garnet/bin/mdns/service/mdns_transceiver.h b/garnet/bin/mdns/service/mdns_transceiver.h index 479b611ebe350a91b52877942fe410bb02b14073..c43383454392d0e4e854cf66bab8f189277b15b1 100644 --- a/garnet/bin/mdns/service/mdns_transceiver.h +++ b/garnet/bin/mdns/service/mdns_transceiver.h @@ -8,9 +8,11 @@ #include <fuchsia/netstack/cpp/fidl.h> #include <lib/fit/function.h> #include <netinet/in.h> + #include <memory> #include <unordered_map> #include <vector> + #include "garnet/bin/mdns/service/mdns_interface_transceiver.h" #include "src/lib/fxl/macros.h" @@ -27,7 +29,7 @@ class MdnsTransceiver { ~MdnsTransceiver(); // Starts the transceiver. - void Start(fuchsia::netstack::NetstackPtr netstack, + void Start(fuchsia::netstack::NetstackPtr netstack, inet::IpPort mdns_port, fit::closure link_change_callback, InboundMessageCallback inbound_message_callback); @@ -38,8 +40,8 @@ class MdnsTransceiver { bool has_interfaces() { return !interface_transceivers_by_address_.empty(); } // Sends a message to the specified address. A V6 interface will send to - // |MdnsAddresses::kV6Multicast| if |reply_address.socket_address()| is - // |MdnsAddresses::kV4Multicast|. + // |MdnsAddresses::V6Multicast| if |reply_address.socket_address()| is + // |MdnsAddresses::V4Multicast|. void SendMessage(DnsMessage* message, const ReplyAddress& reply_address); // Writes log messages describing lifetime traffic. @@ -64,6 +66,7 @@ class MdnsTransceiver { std::unique_ptr<MdnsInterfaceTransceiver>>* prev); fuchsia::netstack::NetstackPtr netstack_; + inet::IpPort mdns_port_; fit::closure link_change_callback_; InboundMessageCallback inbound_message_callback_; std::string host_full_name_; diff --git a/garnet/bin/mdns/service/prober.cc b/garnet/bin/mdns/service/prober.cc index eaef2ec6c1d4aa9596b461ffdbe67cbd9a07578b..ff6498f26c0c7abc32412a1d8063ae6ca0579a55 100644 --- a/garnet/bin/mdns/service/prober.cc +++ b/garnet/bin/mdns/service/prober.cc @@ -4,10 +4,11 @@ #include "garnet/bin/mdns/service/prober.h" +#include <zircon/syscalls.h> + #include "src/lib/fxl/logging.h" #include "src/lib/fxl/time/time_delta.h" #include "src/lib/fxl/time/time_point.h" -#include <zircon/syscalls.h> namespace mdns { @@ -22,8 +23,11 @@ Prober::Prober(MdnsAgent::Host* host, DnsType type, CompletionCallback callback) Prober::~Prober() {} -void Prober::Start(const std::string& host_full_name) { +void Prober::Start(const std::string& host_full_name, inet::IpPort mdns_port) { FXL_DCHECK(!host_full_name.empty()); + + MdnsAgent::Start(host_full_name, mdns_port); + host_full_name_ = host_full_name; question_ = std::make_shared<DnsQuestion>(ResourceName(), DnsType::kAny); @@ -57,8 +61,7 @@ void Prober::ReceiveResource(const DnsResource& resource, fxl::TimeDelta Prober::InitialDelay() { uint64_t random = 0; zx_cprng_draw(&random, sizeof(random)); - int64_t random_nonnegative_int64 = - static_cast<int64_t>(random >> 1); + int64_t random_nonnegative_int64 = static_cast<int64_t>(random >> 1); FXL_DCHECK(random_nonnegative_int64 >= 0); return fxl::TimeDelta::FromNanoseconds(random_nonnegative_int64 % kMaxProbeInterval.ToNanoseconds()); diff --git a/garnet/bin/mdns/service/prober.h b/garnet/bin/mdns/service/prober.h index 0209b87937d35769c23bd19aae2ec24b7a76f8c6..928135b3749e06f737af62fa18227ea17e8c3342 100644 --- a/garnet/bin/mdns/service/prober.h +++ b/garnet/bin/mdns/service/prober.h @@ -5,11 +5,11 @@ #ifndef GARNET_BIN_MDNS_SERVICE_PROBER_H_ #define GARNET_BIN_MDNS_SERVICE_PROBER_H_ +#include <lib/fit/function.h> + #include <memory> #include <string> -#include <lib/fit/function.h> - #include "garnet/bin/mdns/service/mdns_agent.h" #include "src/lib/fxl/time/time_delta.h" @@ -42,7 +42,7 @@ class Prober : public MdnsAgent { ~Prober() override; // MdnsAgent overrides. - void Start(const std::string& host_full_name) final; + void Start(const std::string& host_full_name, inet::IpPort mdns_port) final; void ReceiveResource(const DnsResource& resource, MdnsResourceSection section) final; diff --git a/garnet/bin/mdns/service/resource_renewer.cc b/garnet/bin/mdns/service/resource_renewer.cc index 412cca12ef57a43ca876186155e17b1b40149c49..bc19336c115bff240c2c286ef6bab7636cf786e3 100644 --- a/garnet/bin/mdns/service/resource_renewer.cc +++ b/garnet/bin/mdns/service/resource_renewer.cc @@ -74,7 +74,8 @@ void ResourceRenewer::SendRenewals() { std::shared_ptr<DnsResource> resource = std::make_shared<DnsResource>(entry->name_, entry->type_); resource->time_to_live_ = 0; - SendResource(resource, MdnsResourceSection::kExpired); + SendResource(resource, MdnsResourceSection::kExpired, + MdnsAddresses::V4MulticastReply(mdns_port())); EraseEntry(entry); } else { // Need to query. diff --git a/garnet/bin/mdns/service/test/config_test.cc b/garnet/bin/mdns/service/test/config_test.cc index 25245428960e4727fcc8ba6bcc91308a51f1379c..da9838474774a8d4de14adef4807bd563e025b65 100644 --- a/garnet/bin/mdns/service/test/config_test.cc +++ b/garnet/bin/mdns/service/test/config_test.cc @@ -45,6 +45,7 @@ TEST(ConfigTest, Empty) { under_test.ReadConfigFiles(kHostName, kTestDir); EXPECT_TRUE(under_test.valid()); EXPECT_EQ("", under_test.error()); + EXPECT_EQ(inet::IpPort::From_uint16_t(5353), under_test.mdns_port()); EXPECT_TRUE(under_test.perform_host_name_probe()); EXPECT_TRUE(under_test.publications().empty()); @@ -55,6 +56,7 @@ TEST(ConfigTest, Empty) { TEST(ConfigTest, OneValidFile) { EXPECT_TRUE(files::CreateDirectory(kTestDir)); EXPECT_TRUE(WriteFile("valid", R"({ + "port": 5454, "perform_host_name_probe": false, "publications" : [ {"service" : "_fuchsia._udp.", "port" : 5353, "perform_probe" : false, @@ -66,6 +68,7 @@ TEST(ConfigTest, OneValidFile) { under_test.ReadConfigFiles(kHostName, kTestDir); EXPECT_TRUE(under_test.valid()); EXPECT_EQ("", under_test.error()); + EXPECT_EQ(inet::IpPort::From_uint16_t(5454), under_test.mdns_port()); EXPECT_FALSE(under_test.perform_host_name_probe()); EXPECT_EQ(1u, under_test.publications().size()); EXPECT_TRUE( @@ -135,6 +138,7 @@ TEST(ConfigTest, TwoValidFiles) { under_test.ReadConfigFiles(kHostName, kTestDir); EXPECT_TRUE(under_test.valid()); EXPECT_EQ("", under_test.error()); + EXPECT_EQ(inet::IpPort::From_uint16_t(5353), under_test.mdns_port()); EXPECT_FALSE(under_test.perform_host_name_probe()); EXPECT_EQ(2u, under_test.publications().size());