From 7ead1b7520b4b3e10ad9ee226bba3f3525c815f3 Mon Sep 17 00:00:00 2001 From: Damian Krolik Date: Wed, 3 Nov 2021 16:54:36 +0100 Subject: [PATCH] [avahi] Fix usage of searched address type The Avahi-based service resolver mixes two things up: - searched address type (A or AAAA record) - IP protocol version to be used for doing the query. The service browse callbacks uses the latter as the former. Consequently, if an IPv6 commissionable service is published only via IPv4 mDNS server, it can't be properly discovered. --- src/lib/dnssd/platform/Dnssd.h | 3 ++- src/platform/Linux/DnssdImpl.cpp | 41 ++++++++++++++------------------ src/platform/Linux/DnssdImpl.h | 4 +++- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/lib/dnssd/platform/Dnssd.h b/src/lib/dnssd/platform/Dnssd.h index 1da268e03b165b..d602ff6f640b38 100644 --- a/src/lib/dnssd/platform/Dnssd.h +++ b/src/lib/dnssd/platform/Dnssd.h @@ -66,7 +66,8 @@ struct DnssdService char mHostName[kHostNameMaxLength + 1] = ""; char mType[kDnssdTypeMaxSize + 1]; DnssdServiceProtocol mProtocol; - Inet::IPAddressType mAddressType; + Inet::IPAddressType mAddressType; // Address record type to query or publish (A or AAAA) + Inet::IPAddressType mTransportType; // Transport to use for the query. uint16_t mPort; chip::Inet::InterfaceId mInterface; TextEntry * mTextEntries; diff --git a/src/platform/Linux/DnssdImpl.cpp b/src/platform/Linux/DnssdImpl.cpp index b1d8589843f6c7..24ae0f42567d26 100644 --- a/src/platform/Linux/DnssdImpl.cpp +++ b/src/platform/Linux/DnssdImpl.cpp @@ -532,16 +532,17 @@ CHIP_ERROR MdnsAvahi::Browse(const char * type, DnssdServiceProtocol protocol, c BrowseContext * browseContext = chip::Platform::New(); AvahiIfIndex avahiInterface = static_cast(interface.GetPlatformInterface()); - browseContext->mInstance = this; - browseContext->mContext = context; - browseContext->mCallback = callback; + browseContext->mInstance = this; + browseContext->mContext = context; + browseContext->mCallback = callback; + browseContext->mAddressType = addressType; if (!interface.IsPresent()) { avahiInterface = AVAHI_IF_UNSPEC; } - browser = avahi_service_browser_new(mClient, avahiInterface, ToAvahiProtocol(addressType), GetFullType(type, protocol).c_str(), - nullptr, static_cast(0), HandleBrowse, browseContext); + browser = avahi_service_browser_new(mClient, avahiInterface, AVAHI_PROTO_UNSPEC, GetFullType(type, protocol).c_str(), nullptr, + static_cast(0), HandleBrowse, browseContext); // Otherwise the browser will be freed in the callback if (browser == nullptr) { @@ -613,9 +614,10 @@ void MdnsAvahi::HandleBrowse(AvahiServiceBrowser * browser, AvahiIfIndex interfa Platform::CopyString(service.mName, name); CopyTypeWithoutProtocol(service.mType, type); - service.mProtocol = GetProtocolInType(type); - service.mAddressType = ToAddressType(protocol); - service.mInterface = Inet::InterfaceId::Null(); + service.mProtocol = GetProtocolInType(type); + service.mAddressType = context->mAddressType; + service.mTransportType = ToAddressType(protocol); + service.mInterface = Inet::InterfaceId::Null(); if (interface != AVAHI_IF_UNSPEC) { service.mInterface = static_cast(interface); @@ -645,9 +647,9 @@ void MdnsAvahi::HandleBrowse(AvahiServiceBrowser * browser, AvahiIfIndex interfa } } -CHIP_ERROR MdnsAvahi::Resolve(const char * name, const char * type, DnssdServiceProtocol protocol, - chip::Inet::IPAddressType addressType, chip::Inet::InterfaceId interface, - DnssdResolveCallback callback, void * context) +CHIP_ERROR MdnsAvahi::Resolve(const char * name, const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType, + Inet::IPAddressType transportType, Inet::InterfaceId interface, DnssdResolveCallback callback, + void * context) { AvahiServiceResolver * resolver; AvahiIfIndex avahiInterface = static_cast(interface.GetPlatformInterface()); @@ -661,7 +663,8 @@ CHIP_ERROR MdnsAvahi::Resolve(const char * name, const char * type, DnssdService { avahiInterface = AVAHI_IF_UNSPEC; } - resolver = avahi_service_resolver_new(mClient, avahiInterface, ToAvahiProtocol(addressType), name, + + resolver = avahi_service_resolver_new(mClient, avahiInterface, ToAvahiProtocol(transportType), name, GetFullType(type, protocol).c_str(), nullptr, ToAvahiProtocol(addressType), static_cast(0), HandleResolve, resolveContext); // Otherwise the resolver will be freed in the callback @@ -813,18 +816,10 @@ CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, chip::Inet::InterfaceId void * context) { - CHIP_ERROR error; + VerifyOrReturnError(browseResult != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - if (browseResult != nullptr) - { - error = MdnsAvahi::GetInstance().Resolve(browseResult->mName, browseResult->mType, browseResult->mProtocol, - browseResult->mAddressType, interface, callback, context); - } - else - { - error = CHIP_ERROR_INVALID_ARGUMENT; - } - return error; + return MdnsAvahi::GetInstance().Resolve(browseResult->mName, browseResult->mType, browseResult->mProtocol, + browseResult->mAddressType, Inet::IPAddressType::kAny, interface, callback, context); } } // namespace Dnssd diff --git a/src/platform/Linux/DnssdImpl.h b/src/platform/Linux/DnssdImpl.h index ed18d81235e36b..9e74475cf53d94 100644 --- a/src/platform/Linux/DnssdImpl.h +++ b/src/platform/Linux/DnssdImpl.h @@ -111,7 +111,8 @@ class MdnsAvahi CHIP_ERROR Browse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context); CHIP_ERROR Resolve(const char * name, const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdResolveCallback callback, void * context); + chip::Inet::IPAddressType transportType, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, + void * context); Poller & GetPoller() { return mPoller; } @@ -123,6 +124,7 @@ class MdnsAvahi MdnsAvahi * mInstance; DnssdBrowseCallback mCallback; void * mContext; + Inet::IPAddressType mAddressType; std::vector mServices; };