From b683fec02f6764d25d4eb2d99c8a47bfac1c9f7b Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 16 Feb 2022 02:21:29 -0500 Subject: [PATCH] Change the ChipDnssdResolve API to be able to provide multiple IPs. --- src/lib/dnssd/Discovery_ImplPlatform.cpp | 46 +++++++++++++++---- src/lib/dnssd/platform/Dnssd.h | 5 +- src/platform/Darwin/DnssdImpl.cpp | 6 +-- src/platform/Linux/DnssdImpl.cpp | 8 ++-- ...nericThreadStackManagerImpl_OpenThread.cpp | 3 +- src/platform/Tizen/DnssdImpl.cpp | 4 +- src/platform/android/DnssdImpl.cpp | 2 +- src/platform/tests/TestDnssd.cpp | 3 +- 8 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index 741660bdf1e465..019fd7c8c75dcf 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -42,7 +42,7 @@ namespace { static DnssdCache sDnssdCache; #endif -static void HandleNodeResolve(void * context, DnssdService * result, CHIP_ERROR error) +static void HandleNodeResolve(void * context, DnssdService * result, const Span & extraIPs, CHIP_ERROR error) { ResolverDelegateProxy * proxy = static_cast(context); @@ -57,17 +57,27 @@ static void HandleNodeResolve(void * context, DnssdService * result, CHIP_ERROR Platform::CopyString(nodeData.hostName, result->mHostName); Platform::CopyString(nodeData.instanceName, result->mName); + size_t addressesFound = 0; if (result->mAddress.HasValue()) { - nodeData.ipAddress[0] = result->mAddress.Value(); - nodeData.interfaceId = result->mInterface; - nodeData.numIPs = 1; + nodeData.ipAddress[addressesFound] = result->mAddress.Value(); + nodeData.interfaceId = result->mInterface; + ++addressesFound; } - else + + for (auto & ip : extraIPs) { - nodeData.numIPs = 0; + if (addressesFound == ArraySize(nodeData.ipAddress)) + { + // Out of space. + break; + } + nodeData.ipAddress[addressesFound] = ip; + ++addressesFound; } + nodeData.numIPs = addressesFound; + nodeData.port = result->mPort; for (size_t i = 0; i < result->mTextEntrySize; ++i) @@ -81,7 +91,7 @@ static void HandleNodeResolve(void * context, DnssdService * result, CHIP_ERROR proxy->Release(); } -static void HandleNodeIdResolve(void * context, DnssdService * result, CHIP_ERROR error) +static void HandleNodeIdResolve(void * context, DnssdService * result, const Span & extraIPs, CHIP_ERROR error) { ResolverDelegateProxy * proxy = static_cast(context); if (CHIP_NO_ERROR != error) @@ -116,15 +126,31 @@ static void HandleNodeIdResolve(void * context, DnssdService * result, CHIP_ERRO ResolvedNodeData nodeData; Platform::CopyString(nodeData.mHostName, result->mHostName); nodeData.mInterfaceId = result->mInterface; - nodeData.mAddress[0] = result->mAddress.ValueOr({}); nodeData.mPort = result->mPort; - nodeData.mNumIPs = 1; nodeData.mPeerId = peerId; // TODO: Use seconds? const System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); nodeData.mExpiryTime = currentTime + System::Clock::Seconds16(result->mTtlSeconds); + size_t addressesFound = 0; + if (result->mAddress.HasValue()) + { + nodeData.mAddress[addressesFound] = result->mAddress.Value(); + ++addressesFound; + } + for (auto & ip : extraIPs) + { + if (addressesFound == ArraySize(nodeData.mAddress)) + { + // Out of space. + break; + } + nodeData.mAddress[addressesFound] = ip; + ++addressesFound; + } + nodeData.mNumIPs = addressesFound; + for (size_t i = 0; i < result->mTextEntrySize; ++i) { ByteSpan key(reinterpret_cast(result->mTextEntries[i].mKey), strlen(result->mTextEntries[i].mKey)); @@ -155,7 +181,7 @@ static void HandleNodeBrowse(void * context, DnssdService * services, size_t ser } else { - HandleNodeResolve(context, &services[i], error); + HandleNodeResolve(context, &services[i], Span(), error); } } proxy->Release(); diff --git a/src/lib/dnssd/platform/Dnssd.h b/src/lib/dnssd/platform/Dnssd.h index add47b59bd65bb..719835d7ecc172 100644 --- a/src/lib/dnssd/platform/Dnssd.h +++ b/src/lib/dnssd/platform/Dnssd.h @@ -88,10 +88,13 @@ struct DnssdService * * @param[in] context The context passed to ChipDnssdBrowse or ChipDnssdResolve. * @param[in] result The mdns resolve result, can be nullptr if error happens. + * @param[in] extraIPs IP addresses, in addition to the one in "result", for + * the same hostname. Can be empty. * @param[in] error The error code. * */ -using DnssdResolveCallback = void (*)(void * context, DnssdService * result, CHIP_ERROR error); +using DnssdResolveCallback = void (*)(void * context, DnssdService * result, const Span & extraIPs, + CHIP_ERROR error); /** * The callback function for mDNS browse. diff --git a/src/platform/Darwin/DnssdImpl.cpp b/src/platform/Darwin/DnssdImpl.cpp index 186cde4fe47bda..f892d03a6f8411 100644 --- a/src/platform/Darwin/DnssdImpl.cpp +++ b/src/platform/Darwin/DnssdImpl.cpp @@ -248,12 +248,12 @@ bool CheckForSuccess(GenericContext * context, const char * name, DNSServiceErro } case ContextType::Resolve: { ResolveContext * resolveContext = reinterpret_cast(context); - resolveContext->callback(resolveContext->context, nullptr, CHIP_ERROR_INTERNAL); + resolveContext->callback(resolveContext->context, nullptr, Span(), CHIP_ERROR_INTERNAL); break; } case ContextType::GetAddrInfo: { GetAddrInfoContext * resolveContext = reinterpret_cast(context); - resolveContext->callback(resolveContext->context, nullptr, CHIP_ERROR_INTERNAL); + resolveContext->callback(resolveContext->context, nullptr, Span(), CHIP_ERROR_INTERNAL); break; } } @@ -414,7 +414,7 @@ static void OnGetAddrInfo(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t i Platform::CopyString(service.mHostName, hostname); service.mInterface = Inet::InterfaceId(sdCtx->interfaceId); - sdCtx->callback(sdCtx->context, &service, status); + sdCtx->callback(sdCtx->context, &service, Span(), status); MdnsContexts::GetInstance().Remove(sdCtx); } diff --git a/src/platform/Linux/DnssdImpl.cpp b/src/platform/Linux/DnssdImpl.cpp index 5c25004fbd62e9..5fbb617490fef0 100644 --- a/src/platform/Linux/DnssdImpl.cpp +++ b/src/platform/Linux/DnssdImpl.cpp @@ -714,13 +714,13 @@ void MdnsAvahi::HandleResolve(AvahiServiceResolver * resolver, AvahiIfIndex inte if (resolver == nullptr) { ChipLogError(DeviceLayer, "Avahi resolve failed on retry"); - context->mCallback(context->mContext, nullptr, CHIP_ERROR_INTERNAL); + context->mCallback(context->mContext, nullptr, Span(), CHIP_ERROR_INTERNAL); chip::Platform::Delete(context); } return; } ChipLogError(DeviceLayer, "Avahi resolve failed"); - context->mCallback(context->mContext, nullptr, CHIP_ERROR_INTERNAL); + context->mCallback(context->mContext, nullptr, Span(), CHIP_ERROR_INTERNAL); break; case AVAHI_RESOLVER_FOUND: DnssdService result = {}; @@ -797,11 +797,11 @@ void MdnsAvahi::HandleResolve(AvahiServiceResolver * resolver, AvahiIfIndex inte if (result_err == CHIP_NO_ERROR) { - context->mCallback(context->mContext, &result, CHIP_NO_ERROR); + context->mCallback(context->mContext, &result, Span(), CHIP_NO_ERROR); } else { - context->mCallback(context->mContext, nullptr, result_err); + context->mCallback(context->mContext, nullptr, Span(), result_err); } break; } diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp index b35d586f821456..2a8e83773ceda5 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp @@ -2283,7 +2283,8 @@ template void GenericThreadStackManagerImpl_OpenThread::DispatchResolve(intptr_t context) { auto * dnsResult = reinterpret_cast(context); - ThreadStackMgrImpl().mDnsResolveCallback(dnsResult->context, &(dnsResult->mMdnsService), dnsResult->error); + ThreadStackMgrImpl().mDnsResolveCallback(dnsResult->context, &(dnsResult->mMdnsService, Span(), + dnsResult->error); Platform::Delete(dnsResult); } diff --git a/src/platform/Tizen/DnssdImpl.cpp b/src/platform/Tizen/DnssdImpl.cpp index 00b9177e1ba374..8b19100c5c94af 100644 --- a/src/platform/Tizen/DnssdImpl.cpp +++ b/src/platform/Tizen/DnssdImpl.cpp @@ -459,12 +459,12 @@ void OnResolve(dnssd_error_e result, dnssd_service_h service, void * data) if (validIP) { mdnsService.mAddress.SetValue(ipStr); - rCtx->callback(rCtx->cbContext, &mdnsService, CHIP_NO_ERROR); + rCtx->callback(rCtx->cbContext, &mdnsService, chip::Span(), CHIP_NO_ERROR); StopResolve(rCtx); } else { - rCtx->callback(rCtx->cbContext, nullptr, CHIP_ERROR_INTERNAL); + rCtx->callback(rCtx->cbContext, nullptr, chip::Span(), CHIP_ERROR_INTERNAL); RemoveContext(rCtx); } diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index 429ff609bf6dd2..52d20525e8ca04 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -220,7 +220,7 @@ void HandleResolve(jstring instanceName, jstring serviceType, jstring address, j const auto dispatch = [callbackHandle, contextHandle](CHIP_ERROR error, DnssdService * service = nullptr) { DeviceLayer::StackLock lock; DnssdResolveCallback callback = reinterpret_cast(callbackHandle); - callback(reinterpret_cast(contextHandle), service, error); + callback(reinterpret_cast(contextHandle), service, Span(), error); }; VerifyOrReturn(address != nullptr && port != 0, dispatch(CHIP_ERROR_UNKNOWN_RESOURCE_ID)); diff --git a/src/platform/tests/TestDnssd.cpp b/src/platform/tests/TestDnssd.cpp index 5a252f8ee1ca17..22ec8370a71d55 100644 --- a/src/platform/tests/TestDnssd.cpp +++ b/src/platform/tests/TestDnssd.cpp @@ -14,7 +14,8 @@ using chip::Dnssd::DnssdService; using chip::Dnssd::DnssdServiceProtocol; using chip::Dnssd::TextEntry; -static void HandleResolve(void * context, DnssdService * result, CHIP_ERROR error) +static void HandleResolve(void * context, DnssdService * result, const chip::Span & extraIPs, + CHIP_ERROR error) { char addrBuf[100]; nlTestSuite * suite = static_cast(context);