From a81e1799791da328c868176c258fe493bf9810e4 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Thu, 11 Nov 2021 14:08:46 -0500 Subject: [PATCH] Multiple IP address support in ResolvedNodeData structure and cache (#11149) * Add multiple addresses to ResolvedNodeData * Use ResolvedNodeData directly for cache. Added expiry time to ResolvedNodeId, which the resolvers should set as appropriate from the TTL. Using ResolvedNodeData for the DNS-SD cache directly means we don't need to copy everything over, which is becoming more cumbersome as we add support for more addresses. Also change test to use test time structure. * Update src/lib/dnssd/DnssdCache.h Co-authored-by: Boris Zbarsky * Address review comments. * Reduce mdns cache size for platforms. Maintaining size for darwin, linux and android, other have the cache size called out explicitly in the platform config so the platform maintainers can set this as appropriate. * Restyled by whitespace Co-authored-by: Boris Zbarsky Co-authored-by: Restyled.io --- .../chip-tool/commands/discover/Commands.h | 10 ++- src/controller/CHIPDeviceController.cpp | 6 +- .../python/chip/discovery/NodeResolution.cpp | 14 +-- src/lib/dnssd/Discovery_ImplPlatform.cpp | 44 ++++----- src/lib/dnssd/DnssdCache.h | 89 ++++++++----------- src/lib/dnssd/Resolver.h | 18 ++-- src/lib/dnssd/Resolver_ImplMinimalMdns.cpp | 8 +- src/lib/dnssd/platform/Dnssd.h | 3 + src/lib/dnssd/tests/TestDnssdCache.cpp | 80 +++++++++++------ src/lib/dnssd/tests/TestTxtFields.cpp | 2 +- src/lib/shell/commands/Dns.cpp | 5 +- src/platform/Ameba/SystemPlatformConfig.h | 1 + src/platform/EFR32/SystemPlatformConfig.h | 2 + src/platform/ESP32/SystemPlatformConfig.h | 2 + src/platform/Linux/DnssdImpl.cpp | 2 + src/platform/Linux/SystemPlatformConfig.h | 2 + src/platform/P6/SystemPlatformConfig.h | 2 + src/platform/Tizen/SystemPlatformConfig.h | 2 + .../cc13x2_26x2/SystemPlatformConfig.h | 3 +- src/platform/mbed/SystemPlatformConfig.h | 2 + .../nrfconnect/SystemPlatformConfig.h | 2 + .../nxp/k32w/k32w0/SystemPlatformConfig.h | 2 + src/platform/qpg/SystemPlatformConfig.h | 2 + src/platform/telink/SystemPlatformConfig.h | 2 + 24 files changed, 175 insertions(+), 130 deletions(-) diff --git a/examples/chip-tool/commands/discover/Commands.h b/examples/chip-tool/commands/discover/Commands.h index 697750fb052408..5f74b42ca82037 100644 --- a/examples/chip-tool/commands/discover/Commands.h +++ b/examples/chip-tool/commands/discover/Commands.h @@ -42,10 +42,14 @@ class Resolve : public DiscoverCommand, public chip::Dnssd::ResolverDelegate void OnNodeIdResolved(const chip::Dnssd::ResolvedNodeData & nodeData) override { char addrBuffer[chip::Transport::PeerAddress::kMaxToStringSize]; - nodeData.mAddress.ToString(addrBuffer); - ChipLogProgress(chipTool, "NodeId Resolution: %" PRIu64 " Address: %s, Port: %" PRIu16, nodeData.mPeerId.GetNodeId(), - addrBuffer, nodeData.mPort); + + ChipLogProgress(chipTool, "NodeId Resolution: %" PRIu64 " Port: %" PRIu16, nodeData.mPeerId.GetNodeId(), nodeData.mPort); ChipLogProgress(chipTool, " Hostname: %s", nodeData.mHostName); + for (size_t i = 0; i < nodeData.mNumIPs; ++i) + { + nodeData.mAddress[i].ToString(addrBuffer); + ChipLogProgress(chipTool, " addr %zu: %s", i, addrBuffer); + } auto retryInterval = nodeData.GetMrpRetryIntervalIdle(); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 4916878f6f9fcd..2e80a0a66a7176 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -580,12 +580,14 @@ Transport::PeerAddress DeviceController::ToPeerAddress(const chip::Dnssd::Resolv // For all other addresses, we should rely on the device's routing table to route messages sent. // Forcing messages down an InterfaceId might fail. For example, in bridged networks like Thread, // mDNS advertisements are not usually received on the same interface the peer is reachable on. - if (nodeData.mAddress.IsIPv6LinkLocal()) + // TODO: Right now, just use addr0, but we should really push all the addresses and interfaces to + // the device and allow it to make a proper decision about which addresses are preferred and reachable. + if (nodeData.mAddress[0].IsIPv6LinkLocal()) { interfaceId = nodeData.mInterfaceId; } - return Transport::PeerAddress::UDP(nodeData.mAddress, nodeData.mPort, interfaceId); + return Transport::PeerAddress::UDP(nodeData.mAddress[0], nodeData.mPort, interfaceId); } void DeviceController::OnNodeIdResolved(const chip::Dnssd::ResolvedNodeData & nodeData) diff --git a/src/controller/python/chip/discovery/NodeResolution.cpp b/src/controller/python/chip/discovery/NodeResolution.cpp index b36ad6d3033d28..301b384d5dd88d 100644 --- a/src/controller/python/chip/discovery/NodeResolution.cpp +++ b/src/controller/python/chip/discovery/NodeResolution.cpp @@ -42,12 +42,14 @@ class PythonResolverDelegate : public ResolverDelegate { char ipAddressBuffer[128]; - mSuccessCallback( // - nodeData.mPeerId.GetCompressedFabricId(), // - nodeData.mPeerId.GetNodeId(), // - nodeData.mInterfaceId.GetPlatformInterface(), // - nodeData.mAddress.ToString(ipAddressBuffer, sizeof(ipAddressBuffer)), // - nodeData.mPort // + // TODO: For now, just provide addr 0, but this should really provide all and + // allow the caller to choose. + mSuccessCallback( // + nodeData.mPeerId.GetCompressedFabricId(), // + nodeData.mPeerId.GetNodeId(), // + nodeData.mInterfaceId.GetPlatformInterface(), // + nodeData.mAddress[0].ToString(ipAddressBuffer, sizeof(ipAddressBuffer)), // + nodeData.mPort // ); } else diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index 8a289a82fa75d4..c021e3d7ef7841 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -459,23 +459,11 @@ CHIP_ERROR DiscoveryImplPlatform::ResolveNodeId(const PeerId & peerId, Inet::IPA ReturnErrorOnFailure(InitImpl()); #if CHIP_CONFIG_MDNS_CACHE_SIZE > 0 - Inet::IPAddress addr; - uint16_t port; - Inet::InterfaceId iface; - /* see if the entry is cached and use it.... */ - - if (sDnssdCache.Lookup(peerId, addr, port, iface) == CHIP_NO_ERROR) + ResolvedNodeData nodeData; + if (sDnssdCache.Lookup(peerId, nodeData) == CHIP_NO_ERROR) { - ResolvedNodeData nodeData; - - nodeData.mInterfaceId = iface; - nodeData.mPort = port; - nodeData.mAddress = addr; - nodeData.mPeerId = peerId; - mResolverDelegate->OnNodeIdResolved(nodeData); - return CHIP_NO_ERROR; } #endif @@ -587,22 +575,16 @@ void DiscoveryImplPlatform::HandleNodeIdResolve(void * context, DnssdService * r return; } -#if CHIP_CONFIG_MDNS_CACHE_SIZE > 0 - // TODO -- define appropriate TTL, for now use 2000 msec (rfc default) - // figure out way to use TTL value from mDNS packet in future update - error = mgr->sDnssdCache.Insert(nodeData.mPeerId, result->mAddress.Value(), result->mPort, result->mInterface, - System::Clock::Seconds16(2)); - - if (CHIP_NO_ERROR != error) - { - ChipLogError(Discovery, "DnssdCache insert failed with %s", chip::ErrorStr(error)); - } -#endif - + // TODO: Expand the results to include all the addresses. Platform::CopyString(nodeData.mHostName, result->mHostName); nodeData.mInterfaceId = result->mInterface; - nodeData.mAddress = result->mAddress.ValueOr({}); + nodeData.mAddress[0] = result->mAddress.ValueOr({}); nodeData.mPort = result->mPort; + nodeData.mNumIPs = 1; + // TODO: Use seconds? + const System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); + + nodeData.mExpiryTime = currentTime + System::Clock::Seconds16(result->mTtlSeconds); for (size_t i = 0; i < result->mTextEntrySize; ++i) { @@ -612,6 +594,14 @@ void DiscoveryImplPlatform::HandleNodeIdResolve(void * context, DnssdService * r } nodeData.LogNodeIdResolved(); +#if CHIP_CONFIG_MDNS_CACHE_SIZE > 0 + error = mgr->sDnssdCache.Insert(nodeData); + + if (CHIP_NO_ERROR != error) + { + ChipLogError(Discovery, "DnssdCache insert failed with %s", chip::ErrorStr(error)); + } +#endif mgr->mResolverDelegate->OnNodeIdResolved(nodeData); } diff --git a/src/lib/dnssd/DnssdCache.h b/src/lib/dnssd/DnssdCache.h index 99990d6cc76b26..a55136d087b4de 100644 --- a/src/lib/dnssd/DnssdCache.h +++ b/src/lib/dnssd/DnssdCache.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include // set MDNS_LOGGING to enable logging -- sometimes used in debug/test programs -- traces the behavior @@ -43,7 +43,7 @@ class DnssdCache public: DnssdCache() : elementsUsed(CACHE_SIZE) { - for (DnssdCacheEntry & e : mLookupTable) + for (ResolvedNodeData & e : mLookupTable) { // each unused entry decrements the count MarkEntryUnused(e); @@ -55,31 +55,23 @@ class DnssdCache // return error if cache is full // TODO: have an eviction policy so if the cache is full, an entry may be deleted. // One policy may be Least-time-to-live - CHIP_ERROR Insert(PeerId peerId, const Inet::IPAddress & addr, uint16_t port, Inet::InterfaceId iface, - System::Clock::Timestamp TTL) + CHIP_ERROR Insert(const ResolvedNodeData & nodeData) { - const System::Clock::Timestamp currentTime = mTimeSource.GetMonotonicTimestamp(); + const System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); - DnssdCacheEntry * entry; + ResolvedNodeData * entry; - entry = FindPeerId(peerId, currentTime); + entry = FindPeerId(nodeData.mPeerId, currentTime); if (entry) { - // update timeout if found entry - entry->expiryTime = currentTime + TTL; - entry->TTL = TTL; // in case it changes */ + *entry = nodeData; return CHIP_NO_ERROR; } VerifyOrReturnError(entry = findSlot(currentTime), CHIP_ERROR_TOO_MANY_KEYS); // have a free slot for this entry - entry->peerId = peerId; - entry->ipAddr = addr; - entry->port = port; - entry->ifaceId = iface; - entry->TTL = TTL; - entry->expiryTime = currentTime + TTL; + *entry = nodeData; elementsUsed++; return CHIP_NO_ERROR; @@ -87,8 +79,8 @@ class DnssdCache CHIP_ERROR Delete(PeerId peerId) { - DnssdCacheEntry * pentry; - const System::Clock::Timestamp currentTime = mTimeSource.GetMonotonicTimestamp(); + ResolvedNodeData * pentry; + const System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); VerifyOrReturnError(pentry = FindPeerId(peerId, currentTime), CHIP_ERROR_KEY_NOT_FOUND); @@ -97,16 +89,14 @@ class DnssdCache } // given a peerId, find the parameters if its in the cache, or return error - CHIP_ERROR Lookup(PeerId peerId, Inet::IPAddress & addr, uint16_t & port, Inet::InterfaceId & iface) + CHIP_ERROR Lookup(PeerId peerId, ResolvedNodeData & nodeData) { - DnssdCacheEntry * pentry; - const System::Clock::Timestamp currentTime = mTimeSource.GetMonotonicTimestamp(); + ResolvedNodeData * pentry; + const System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); VerifyOrReturnError(pentry = FindPeerId(peerId, currentTime), CHIP_ERROR_KEY_NOT_FOUND); - addr = pentry->ipAddr; - port = pentry->port; - iface = pentry->ifaceId; + nodeData = *pentry; return CHIP_NO_ERROR; } @@ -117,48 +107,41 @@ class DnssdCache int i = 0; MdnsLogProgress(Discovery, "cache size = %d", elementsUsed); - for (DnssdCacheEntry & e : mLookupTable) + for (ResolvedNodeData & e : mLookupTable) { - if (e.peerId == nullPeerId) + if (e.mPeerId == nullPeerId) { MdnsLogProgress(Discovery, "Entry %d unused", i); } else { - char address[100]; - - e.ipAddr.ToString(address, sizeof address); - MdnsLogProgress(Discovery, "Entry %d: node %lx fabric %lx, port = %d, address = %s", i, e.peerId.GetNodeId(), - e.peerId.GetFabricId(), e.port, address); + MdnsLogProgress(Discovery, "Entry %d: node %lx fabric %lx, port = %d", i, e.mPeerId.GetNodeId(), + e.peerId.GetFabricId(), e.port); + for (size_t j = 0; j < e.mNumIPs; ++j) + { + char address[Inet::IPAddress::kMaxStringLength]; + e.mAddress[i].ToString(address); + MdnsLogProgress(Discovery, " address %d: %s", j, address); + } } i++; } } private: - struct DnssdCacheEntry - { - PeerId peerId; - Inet::IPAddress ipAddr; - uint16_t port; - Inet::InterfaceId ifaceId; - System::Clock::Timestamp TTL; - System::Clock::Timestamp expiryTime; - }; PeerId nullPeerId; // indicates a cache entry is unused int elementsUsed; // running count of how many entries are used -- for a sanity check - DnssdCacheEntry mLookupTable[CACHE_SIZE]; - Time::TimeSource mTimeSource; + ResolvedNodeData mLookupTable[CACHE_SIZE]; - DnssdCacheEntry * findSlot(System::Clock::Timestamp currentTime) + ResolvedNodeData * findSlot(System::Clock::Timestamp currentTime) { - for (DnssdCacheEntry & entry : mLookupTable) + for (ResolvedNodeData & entry : mLookupTable) { - if (entry.peerId == nullPeerId) + if (entry.mPeerId == nullPeerId) return &entry; - if (entry.expiryTime <= currentTime) + if (entry.mExpiryTime <= currentTime) { MarkEntryUnused(entry); return &entry; @@ -167,13 +150,13 @@ class DnssdCache return nullptr; } - DnssdCacheEntry * FindPeerId(PeerId peerId, System::Clock::Timestamp current_time) + ResolvedNodeData * FindPeerId(PeerId peerId, System::Clock::Timestamp current_time) { - for (DnssdCacheEntry & entry : mLookupTable) + for (ResolvedNodeData & entry : mLookupTable) { - if (entry.peerId == peerId) + if (entry.mPeerId == peerId) { - if (entry.expiryTime < current_time) + if (entry.mExpiryTime < current_time) { MarkEntryUnused(entry); break; // return nullptr @@ -181,7 +164,7 @@ class DnssdCache else return &entry; } - if (entry.peerId != nullPeerId && entry.expiryTime < current_time) + if (entry.mPeerId != nullPeerId && entry.mExpiryTime < current_time) { MarkEntryUnused(entry); } @@ -191,9 +174,9 @@ class DnssdCache } // have a method to mark ununused -- so its easy to change - void MarkEntryUnused(DnssdCacheEntry & pentry) + void MarkEntryUnused(ResolvedNodeData & pentry) { - pentry.peerId = nullPeerId; + pentry.mPeerId = nullPeerId; elementsUsed--; } }; diff --git a/src/lib/dnssd/Resolver.h b/src/lib/dnssd/Resolver.h index 73ab5120f39024..91d99445070148 100644 --- a/src/lib/dnssd/Resolver.h +++ b/src/lib/dnssd/Resolver.h @@ -37,15 +37,21 @@ constexpr uint32_t kUndefinedRetryInterval = std::numeric_limits::max( struct ResolvedNodeData { + // TODO: use pool to allow dynamic + static constexpr int kMaxIPAddresses = 5; void LogNodeIdResolved() { #if CHIP_PROGRESS_LOGGING char addrBuffer[Inet::IPAddress::kMaxStringLength]; - mAddress.ToString(addrBuffer); + // Would be nice to log the interface id, but sorting out how to do so // across our differnet InterfaceId implementations is a pain. - ChipLogProgress(Discovery, "Node ID resolved for 0x" ChipLogFormatX64 " to [%s]:%" PRIu16, - ChipLogValueX64(mPeerId.GetNodeId()), addrBuffer, mPort); + ChipLogProgress(Discovery, "Node ID resolved for 0x" ChipLogFormatX64, ChipLogValueX64(mPeerId.GetNodeId())); + for (size_t i = 0; i < mNumIPs; ++i) + { + mAddress[i].ToString(addrBuffer); + ChipLogProgress(Discovery, " Addr %zu: [%s]:%" PRIu16, i, addrBuffer, mPort); + } #endif // CHIP_PROGRESS_LOGGING } @@ -62,13 +68,15 @@ struct ResolvedNodeData } PeerId mPeerId; - Inet::IPAddress mAddress = Inet::IPAddress::Any; - Inet::InterfaceId mInterfaceId = Inet::InterfaceId::Null(); + size_t mNumIPs = 0; + Inet::InterfaceId mInterfaceId; + Inet::IPAddress mAddress[kMaxIPAddresses]; uint16_t mPort = 0; char mHostName[kHostNameMaxLength + 1] = {}; bool mSupportsTcp = false; uint32_t mMrpRetryIntervalIdle = kUndefinedRetryInterval; uint32_t mMrpRetryIntervalActive = kUndefinedRetryInterval; + System::Clock::Timestamp mExpiryTime; }; constexpr size_t kMaxDeviceNameLen = 32; diff --git a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp index 6bc0aa2df2b817..9ad68881a74a71 100644 --- a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp @@ -74,8 +74,7 @@ class PacketDataReporter : public ParserDelegate mDelegate(delegate), mDiscoveryType(discoveryType), mPacketRange(packet) { - mInterfaceId = interfaceId; - mNodeData.mInterfaceId = interfaceId; + mInterfaceId = interfaceId; } // ParserDelegate implementation @@ -177,8 +176,9 @@ void PacketDataReporter::OnOperationalIPAddress(const chip::Inet::IPAddress & ad // This code assumes that all entries in the mDNS packet relate to the // same entity. This may not be correct if multiple servers are reported // (if multi-admin decides to use unique ports for every ecosystem). - mNodeData.mAddress = addr; - mHasIP = true; + mNodeData.mAddress[mDiscoveredNodeData.numIPs++] = addr; + mNodeData.mInterfaceId = mInterfaceId; + mHasIP = true; } void PacketDataReporter::OnDiscoveredNodeIPAddress(const chip::Inet::IPAddress & addr) diff --git a/src/lib/dnssd/platform/Dnssd.h b/src/lib/dnssd/platform/Dnssd.h index d602ff6f640b38..756bd4752fec2f 100644 --- a/src/lib/dnssd/platform/Dnssd.h +++ b/src/lib/dnssd/platform/Dnssd.h @@ -34,6 +34,7 @@ #include #include #include +#include namespace chip { namespace Dnssd { @@ -75,6 +76,8 @@ struct DnssdService const char ** mSubTypes; size_t mSubTypeSize; Optional mAddress; + // Time to live in seconds. Per rfc6762 section 10, because we have a hostname, our default TTL is 120 seconds + uint32_t mTtlSeconds = 120; }; /** diff --git a/src/lib/dnssd/tests/TestDnssdCache.cpp b/src/lib/dnssd/tests/TestDnssdCache.cpp index 38c50795a407ac..a254a14d7b4b59 100644 --- a/src/lib/dnssd/tests/TestDnssdCache.cpp +++ b/src/lib/dnssd/tests/TestDnssdCache.cpp @@ -38,6 +38,18 @@ using namespace chip; using namespace chip::Dnssd; +namespace { +class FakeClock : public System::Clock::ClockBase +{ +public: + System::Clock::Microseconds64 GetMonotonicMicroseconds64() override { return mTime; } + System::Clock::Milliseconds64 GetMonotonicMilliseconds64() override { return mTime; } + System::Clock::Milliseconds64 mTime = System::Clock::kZero; +}; +FakeClock fakeClock; +System::Clock::ClockBase * realClock; +} // namespace + void TestCreate(nlTestSuite * inSuite, void * inContext) { DnssdCache<10> tDnssdCache; @@ -49,29 +61,28 @@ void TestInsert(nlTestSuite * inSuite, void * inContext) const int sizeOfCache = 5; DnssdCache tDnssdCache; PeerId peerId; - int64_t id = 0x100; - uint16_t port = 2000; - constexpr Inet::InterfaceId iface = Inet::InterfaceId::Null(); - - Inet::IPAddress addr; - Inet::IPAddress addrV6; + int64_t id = 0x100; + uint16_t port = 2000; const System::Clock::Timestamp ttl = System::Clock::Seconds16(2); - Inet::InterfaceId iface_out; - Inet::IPAddress addr_out; - uint16_t port_out; - const uint64_t KNOWN_FABRIC = 0x100; + const uint64_t KNOWN_FABRIC = 0x100; + ResolvedNodeData nodeData; + ResolvedNodeData nodeDataOut; + + Inet::IPAddress::FromString("1.0.0.1", nodeData.mAddress[nodeData.mNumIPs++]); - Inet::IPAddress::FromString("1.0.0.1", addr); + nodeData.mInterfaceId = Inet::InterfaceId::Null(); + nodeData.mExpiryTime = fakeClock.mTime + ttl; peerId.SetCompressedFabricId(KNOWN_FABRIC); + nodeData.mPeerId.SetCompressedFabricId(KNOWN_FABRIC); for (uint16_t i = 0; i < 10; i++) { CHIP_ERROR result; - - // ml -- why doesn't adding 2 uint16_t give a uint16_t? - peerId.SetNodeId((NodeId) id + i); - result = tDnssdCache.Insert(peerId, addr, (uint16_t)(port + i), iface, ttl); + nodeData.mPeerId.SetNodeId(static_cast(id + i)); + // Need to re-cast to uint16_t because of integer type promotion + nodeData.mPort = static_cast(port + i); + result = tDnssdCache.Insert(nodeData); if (i < sizeOfCache) { NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR); @@ -83,15 +94,18 @@ void TestInsert(nlTestSuite * inSuite, void * inContext) } tDnssdCache.DumpCache(); - usleep(static_cast(std::chrono::microseconds(ttl + System::Clock::Seconds16(1)).count())); + fakeClock.mTime = nodeData.mExpiryTime + ttl + System::Clock::Seconds16(1); + nodeData.mExpiryTime = fakeClock.mTime + ttl; + id = 0x200; port = 3000; for (uint16_t i = 0; i < sizeOfCache; i++) { CHIP_ERROR result; - peerId.SetNodeId((NodeId) id + i); - result = tDnssdCache.Insert(peerId, addr, (uint16_t)(port + i), iface, ttl); + nodeData.mPeerId.SetNodeId(static_cast(id + i)); + nodeData.mPort = static_cast(port + i); + result = tDnssdCache.Insert(nodeData); NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR); } tDnssdCache.DumpCache(); @@ -99,8 +113,7 @@ void TestInsert(nlTestSuite * inSuite, void * inContext) for (uint16_t i = 0; i < sizeOfCache; i++) { CHIP_ERROR result; - - peerId.SetNodeId((NodeId) id + i); + peerId.SetNodeId(static_cast(id + i)); result = tDnssdCache.Delete(peerId); NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR); } @@ -108,29 +121,44 @@ void TestInsert(nlTestSuite * inSuite, void * inContext) tDnssdCache.DumpCache(); // ipv6 inserts - Inet::IPAddress::FromString("::1", addrV6); + Inet::IPAddress::FromString("::1", nodeData.mAddress[nodeData.mNumIPs++]); port = 4000; for (uint16_t i = 0; i < sizeOfCache; i++) { CHIP_ERROR result; - peerId.SetNodeId((NodeId) id + i); - result = tDnssdCache.Insert(peerId, addrV6, (uint16_t)(port + i), iface, ttl); + nodeData.mPeerId.SetNodeId(static_cast(id + i)); + nodeData.mPort = static_cast(port + i); + + result = tDnssdCache.Insert(nodeData); NL_TEST_ASSERT(inSuite, result == CHIP_NO_ERROR); } tDnssdCache.DumpCache(); - NL_TEST_ASSERT(inSuite, tDnssdCache.Lookup(peerId, addr_out, port_out, iface_out) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, tDnssdCache.Lookup(peerId, nodeDataOut) == CHIP_NO_ERROR); peerId.SetCompressedFabricId(KNOWN_FABRIC + 1); - NL_TEST_ASSERT(inSuite, tDnssdCache.Lookup(peerId, addr_out, port_out, iface_out) != CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, tDnssdCache.Lookup(peerId, nodeDataOut) != CHIP_NO_ERROR); } static const nlTest sTests[] = { NL_TEST_DEF_FN(TestCreate), NL_TEST_DEF_FN(TestInsert), NL_TEST_SENTINEL() }; +static int TestSetup(void * inContext) +{ + realClock = &System::SystemClock(); + System::Clock::Internal::SetSystemClockForTesting(&fakeClock); + return SUCCESS; +} + +static int TestTeardown(void * inContext) +{ + System::Clock::Internal::SetSystemClockForTesting(realClock); + return SUCCESS; +} + int TestDnssdCache(void) { - nlTestSuite theSuite = { "MDNS Cache Creation", &sTests[0], nullptr, nullptr }; + nlTestSuite theSuite = { "MDNS Cache Creation", &sTests[0], TestSetup, TestTeardown }; nlTestRunner(&theSuite, nullptr); return nlTestRunnerStats(&theSuite); diff --git a/src/lib/dnssd/tests/TestTxtFields.cpp b/src/lib/dnssd/tests/TestTxtFields.cpp index 74e24ccc852fe1..68140d4b3f9a55 100644 --- a/src/lib/dnssd/tests/TestTxtFields.cpp +++ b/src/lib/dnssd/tests/TestTxtFields.cpp @@ -380,7 +380,7 @@ void TestFillDiscoveredNodeDataFromTxt(nlTestSuite * inSuite, void * inContext) bool NodeDataIsEmpty(const ResolvedNodeData & nodeData) { - return nodeData.mPeerId == PeerId{} && nodeData.mAddress == Inet::IPAddress::Any && nodeData.mPort == 0 && + return nodeData.mPeerId == PeerId{} && nodeData.mNumIPs == 0 && nodeData.mPort == 0 && nodeData.mMrpRetryIntervalIdle == kUndefinedRetryInterval && nodeData.mMrpRetryIntervalActive == kUndefinedRetryInterval && !nodeData.mSupportsTcp; } diff --git a/src/lib/shell/commands/Dns.cpp b/src/lib/shell/commands/Dns.cpp index 7d02012f49827e..5512b5258f76be 100644 --- a/src/lib/shell/commands/Dns.cpp +++ b/src/lib/shell/commands/Dns.cpp @@ -45,7 +45,10 @@ class DnsShellResolverDelegate : public Dnssd::ResolverDelegate streamer_printf(streamer_get(), "DNS resolve for " ChipLogFormatX64 "-" ChipLogFormatX64 " succeeded:\r\n", ChipLogValueX64(nodeData.mPeerId.GetCompressedFabricId()), ChipLogValueX64(nodeData.mPeerId.GetNodeId())); streamer_printf(streamer_get(), " Hostname: %s\r\n", nodeData.mHostName); - streamer_printf(streamer_get(), " IP address: %s\r\n", nodeData.mAddress.ToString(ipAddressBuf)); + for (size_t i = 0; i < nodeData.mNumIPs; ++i) + { + streamer_printf(streamer_get(), " IP address: %s\r\n", nodeData.mAddress[i].ToString(ipAddressBuf)); + } streamer_printf(streamer_get(), " Port: %" PRIu16 "\r\n", nodeData.mPort); auto retryInterval = nodeData.GetMrpRetryIntervalIdle(); diff --git a/src/platform/Ameba/SystemPlatformConfig.h b/src/platform/Ameba/SystemPlatformConfig.h index 61fb892a58acb6..e5ad3b3ebade61 100755 --- a/src/platform/Ameba/SystemPlatformConfig.h +++ b/src/platform/Ameba/SystemPlatformConfig.h @@ -61,3 +61,4 @@ struct ChipDeviceEvent; #define CHIP_SYSTEM_CONFIG_USE_SOCKETS 0 #define CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK 0 #define CHIP_SYSTEM_CONFIG_POSIX_LOCKING 0 +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/EFR32/SystemPlatformConfig.h b/src/platform/EFR32/SystemPlatformConfig.h index c85ea31df45f83..6f5a1ebed34ed7 100644 --- a/src/platform/EFR32/SystemPlatformConfig.h +++ b/src/platform/EFR32/SystemPlatformConfig.h @@ -42,3 +42,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/ESP32/SystemPlatformConfig.h b/src/platform/ESP32/SystemPlatformConfig.h index 8606c505279516..6838379fc15932 100644 --- a/src/platform/ESP32/SystemPlatformConfig.h +++ b/src/platform/ESP32/SystemPlatformConfig.h @@ -47,3 +47,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS CONFIG_NUM_TIMERS #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/Linux/DnssdImpl.cpp b/src/platform/Linux/DnssdImpl.cpp index 24ae0f42567d26..62f5713f0b369f 100644 --- a/src/platform/Linux/DnssdImpl.cpp +++ b/src/platform/Linux/DnssdImpl.cpp @@ -704,6 +704,8 @@ void MdnsAvahi::HandleResolve(AvahiServiceResolver * resolver, AvahiIfIndex inte result.mPort = port; result.mAddressType = ToAddressType(protocol); result.mInterface = Inet::InterfaceId::Null(); + // It's not clear if we can get the actual value from avahi, so just assume default. + result.mTtlSeconds = AVAHI_DEFAULT_TTL_HOST_NAME; if (interface != AVAHI_IF_UNSPEC) { result.mInterface = static_cast(interface); diff --git a/src/platform/Linux/SystemPlatformConfig.h b/src/platform/Linux/SystemPlatformConfig.h index 9d4d02f92fc83d..2794184ca8e0a3 100644 --- a/src/platform/Linux/SystemPlatformConfig.h +++ b/src/platform/Linux/SystemPlatformConfig.h @@ -45,3 +45,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/P6/SystemPlatformConfig.h b/src/platform/P6/SystemPlatformConfig.h index deba3447ffcf67..1a1cda338b6dca 100644 --- a/src/platform/P6/SystemPlatformConfig.h +++ b/src/platform/P6/SystemPlatformConfig.h @@ -54,3 +54,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/Tizen/SystemPlatformConfig.h b/src/platform/Tizen/SystemPlatformConfig.h index f895bff0b9c972..69fa7d72f37f8d 100644 --- a/src/platform/Tizen/SystemPlatformConfig.h +++ b/src/platform/Tizen/SystemPlatformConfig.h @@ -47,3 +47,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/cc13x2_26x2/SystemPlatformConfig.h b/src/platform/cc13x2_26x2/SystemPlatformConfig.h index 5f4f85f37083c3..76bb84bce8e462 100644 --- a/src/platform/cc13x2_26x2/SystemPlatformConfig.h +++ b/src/platform/cc13x2_26x2/SystemPlatformConfig.h @@ -38,5 +38,4 @@ struct ChipDeviceEvent; #define CHIP_SYSTEM_CONFIG_EVENT_OBJECT_TYPE const struct ::chip::DeviceLayer::ChipDeviceEvent * // ========== Platform-specific Configuration Overrides ========= - -/* none yet */ +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/mbed/SystemPlatformConfig.h b/src/platform/mbed/SystemPlatformConfig.h index 9d4a520f7cf07c..a8891d351305b9 100644 --- a/src/platform/mbed/SystemPlatformConfig.h +++ b/src/platform/mbed/SystemPlatformConfig.h @@ -47,3 +47,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/nrfconnect/SystemPlatformConfig.h b/src/platform/nrfconnect/SystemPlatformConfig.h index ec4ba9e2f1ea90..9882917b1cf08c 100644 --- a/src/platform/nrfconnect/SystemPlatformConfig.h +++ b/src/platform/nrfconnect/SystemPlatformConfig.h @@ -56,3 +56,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h b/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h index d1b09b1f70c58f..3a3c439d2ead70 100644 --- a/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h +++ b/src/platform/nxp/k32w/k32w0/SystemPlatformConfig.h @@ -43,3 +43,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/qpg/SystemPlatformConfig.h b/src/platform/qpg/SystemPlatformConfig.h index 70f20518c77909..8ec4376d3bab36 100644 --- a/src/platform/qpg/SystemPlatformConfig.h +++ b/src/platform/qpg/SystemPlatformConfig.h @@ -41,3 +41,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 diff --git a/src/platform/telink/SystemPlatformConfig.h b/src/platform/telink/SystemPlatformConfig.h index f81b07573b378d..c2e51709232a8a 100644 --- a/src/platform/telink/SystemPlatformConfig.h +++ b/src/platform/telink/SystemPlatformConfig.h @@ -56,3 +56,5 @@ struct ChipDeviceEvent; #ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS #define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 #endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4