diff --git a/src/lib/dnssd/minimal_mdns/BUILD.gn b/src/lib/dnssd/minimal_mdns/BUILD.gn index 669628be8a1ca5..a9df17520598f1 100644 --- a/src/lib/dnssd/minimal_mdns/BUILD.gn +++ b/src/lib/dnssd/minimal_mdns/BUILD.gn @@ -14,6 +14,31 @@ import("//build_overrides/chip.gni") +declare_args() { + # Makes unicast queries use a separate UDP endpoint that have an ephemeral port + # + # In practice this means unicast replies will be received on a dedicated port + # and will work even if competing mdns servers (including other chip apps) + # run on the same machine. + # + # Downside is that replies sent to a port other than 5353 are considered + # LEGACY by mDNS and will include the query section in them (i.e. larger + # payloads) and clients need to allocate more resources for this (need one + # more UDP socket and corresponding code for the unicast query sending) + chip_use_ephemeral_port_for_mdns_unicast_query = + current_os == "mac" || current_os == "linux" || current_os == "android" +} + +config("config") { + defines = [] + + if (chip_use_ephemeral_port_for_mdns_unicast_query) { + defines += [ "CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT=1" ] + } else { + defines += [ "CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT=0" ] + } +} + static_library("minimal_mdns") { sources = [ "ActiveResolveAttempts.cpp", @@ -39,4 +64,6 @@ static_library("minimal_mdns") { "${chip_root}/src/lib/dnssd/minimal_mdns/responders", "${chip_root}/src/platform", ] + + public_configs = [ ":config" ] } diff --git a/src/lib/dnssd/minimal_mdns/Server.cpp b/src/lib/dnssd/minimal_mdns/Server.cpp index bb06078fbc24a0..9bfb9d15c0ebb3 100644 --- a/src/lib/dnssd/minimal_mdns/Server.cpp +++ b/src/lib/dnssd/minimal_mdns/Server.cpp @@ -57,6 +57,8 @@ class ListenSocketPickerDelegate : public ServerBase::BroadcastSendDelegate chip::Inet::UDPEndPoint * Accept(ServerBase::EndpointInfo * info) override { return info->listen_udp; } }; +#if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT + /** * Extracts the Querying UDP Endpoint from an underlying ServerBase::EndpointInfo */ @@ -66,6 +68,12 @@ class QuerySocketPickerDelegate : public ServerBase::BroadcastSendDelegate chip::Inet::UDPEndPoint * Accept(ServerBase::EndpointInfo * info) override { return info->unicast_query_udp; } }; +#else + +using QuerySocketPickerDelegate = ListenSocketPickerDelegate; + +#endif + /** * Validates that an endpoint belongs to a specific interface/ip address type before forwarding the * endpoint accept logic to another BroadcastSendDelegate. @@ -180,11 +188,13 @@ void ShutdownEndpoint(mdns::Minimal::ServerBase::EndpointInfo & aEndpoint) aEndpoint.listen_udp = nullptr; } +#if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT if (aEndpoint.unicast_query_udp != nullptr) { aEndpoint.unicast_query_udp->Free(); aEndpoint.unicast_query_udp = nullptr; } +#endif } } // namespace @@ -254,6 +264,7 @@ CHIP_ERROR ServerBase::Listen(chip::Inet::InetLayer * inetLayer, ListenIterator endpointIndex++; } +#if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT // Separate UDP endpoint for unicast queries, bound to 0 (i.e. pick random ephemeral port) // - helps in not having conflicts on port 5353, will receive unicast replies directly // - has a *DRAWBACK* of unicast queries being considered LEGACY by mdns since they do @@ -261,6 +272,7 @@ CHIP_ERROR ServerBase::Listen(chip::Inet::InetLayer * inetLayer, ListenIterator ReturnErrorOnFailure(inetLayer->NewUDPEndPoint(&info->unicast_query_udp)); ReturnErrorOnFailure(info->unicast_query_udp->Bind(addressType, chip::Inet::IPAddress::Any, 0, interfaceId)); ReturnErrorOnFailure(info->unicast_query_udp->Listen(OnUdpPacketReceived, nullptr /*OnReceiveError*/, this)); +#endif } return autoShutdown.ReturnSuccess(); diff --git a/src/lib/dnssd/minimal_mdns/Server.h b/src/lib/dnssd/minimal_mdns/Server.h index 7c83a61a47c4f5..1c43e785ab2d5f 100644 --- a/src/lib/dnssd/minimal_mdns/Server.h +++ b/src/lib/dnssd/minimal_mdns/Server.h @@ -79,8 +79,10 @@ class ServerBase { chip::Inet::InterfaceId interfaceId = chip::Inet::InterfaceId::Null(); chip::Inet::IPAddressType addressType; - chip::Inet::UDPEndPoint * listen_udp = nullptr; + chip::Inet::UDPEndPoint * listen_udp = nullptr; +#if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT chip::Inet::UDPEndPoint * unicast_query_udp = nullptr; +#endif }; /** @@ -103,8 +105,10 @@ class ServerBase { for (size_t i = 0; i < mEndpointCount; i++) { - mEndpoints[i].listen_udp = nullptr; + mEndpoints[i].listen_udp = nullptr; +#if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT mEndpoints[i].unicast_query_udp = nullptr; +#endif } BroadcastIpAddresses::GetIpv6Into(mIpv6BroadcastAddress);