Matter SDK Coverage Report
Current view: top level - lib/dnssd/minimal_mdns - AddressPolicy_DefaultImpl.cpp (source / functions) Coverage Total Hit
Test: SHA:209dc18e4021e7d0dff8120ccc585909391dd862 Lines: 88.7 % 71 63
Test Date: 2026-06-16 07:34:53 Functions: 100.0 % 11 11

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2022 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : #include <lib/dnssd/minimal_mdns/AddressPolicy.h>
      18              : 
      19              : #include <lib/support/logging/CHIPLogging.h>
      20              : 
      21              : namespace mdns {
      22              : namespace Minimal {
      23              : namespace {
      24              : 
      25              : /// Checks if the current interface is powered on
      26              : /// and not local loopback.
      27              : template <typename T>
      28          214 : bool IsCurrentInterfaceUsable(T & iterator)
      29              : {
      30          214 :     if (!iterator.IsUp())
      31              :     {
      32            0 :         return false; // not a usable interface
      33              :     }
      34              :     char name[chip::Inet::InterfaceId::kMaxIfNameLength];
      35          428 :     if (iterator.GetInterfaceName(name, sizeof(name)) != CHIP_NO_ERROR)
      36              :     {
      37            0 :         ChipLogError(Discovery, "Failed to get interface name.");
      38            0 :         return false;
      39              :     }
      40              : 
      41              :     // TODO: need a better way to ignore local loopback interfaces/addresses
      42              :     // We do not want to listen on local loopback even though they are up and
      43              :     // support multicast
      44              :     //
      45              :     // Some way to detect 'is local looback' that is smarter (e.g. at least
      46              :     // strict string compare on linux instead of substring) would be better.
      47              :     //
      48              :     // This would reject likely valid interfaces like 'lollipop' or 'lostinspace'
      49          214 :     if (strncmp(name, "lo", 2) == 0)
      50              :     {
      51              :         /// local loopback interface is not usable by MDNS
      52          107 :         return false;
      53              :     }
      54              : 
      55              :     // skip IEEE 802.15.4 / Thread interfaces — not suitable for mDNS
      56          107 :     if (strncmp(name, "wpan", 4) == 0)
      57              :     {
      58            0 :         return false;
      59              :     }
      60              : 
      61          107 :     return true;
      62              : }
      63              : 
      64              : class AllInterfaces : public mdns::Minimal::ListenIterator
      65              : {
      66              : public:
      67          107 :     AllInterfaces() { SkipToFirstValidInterface(); }
      68              : 
      69          321 :     bool Next(chip::Inet::InterfaceId * id, chip::Inet::IPAddressType * type) override
      70              :     {
      71          321 :         if (!mIterator.HasCurrent())
      72              :         {
      73          107 :             return false;
      74              :         }
      75              : 
      76              : #if INET_CONFIG_ENABLE_IPV4
      77          214 :         if (mState == State::kIpV4)
      78              :         {
      79          107 :             mState = State::kIpV6;
      80              : 
      81          107 :             if (CurrentInterfaceHasAddressOfType(chip::Inet::IPAddressType::kIPv4))
      82              :             {
      83          107 :                 *id   = mIterator.GetInterfaceId();
      84          107 :                 *type = chip::Inet::IPAddressType::kIPv4;
      85          107 :                 return true;
      86              :             }
      87              :         }
      88              : #endif
      89              : 
      90              : #if INET_CONFIG_ENABLE_IPV4
      91          107 :         mState = State::kIpV4;
      92              : #endif
      93              : 
      94          107 :         bool haveResult = CurrentInterfaceHasAddressOfType(chip::Inet::IPAddressType::kIPv6);
      95          107 :         if (haveResult)
      96              :         {
      97          107 :             *id   = mIterator.GetInterfaceId();
      98          107 :             *type = chip::Inet::IPAddressType::kIPv6;
      99              :         }
     100              : 
     101          107 :         for (mIterator.Next(); SkipCurrentInterface(); mIterator.Next())
     102              :         {
     103              :         }
     104              : 
     105          107 :         if (haveResult)
     106              :         {
     107          107 :             return true;
     108              :         }
     109              : 
     110            0 :         return Next(id, type);
     111              :     }
     112              : 
     113              : private:
     114              : #if INET_CONFIG_ENABLE_IPV4
     115              :     enum class State
     116              :     {
     117              :         kIpV4,
     118              :         kIpV6,
     119              :     };
     120              :     State mState = State::kIpV4;
     121              : #endif
     122              :     chip::Inet::InterfaceIterator mIterator;
     123              : 
     124          214 :     void SkipToFirstValidInterface()
     125              :     {
     126              :         do
     127              :         {
     128          214 :             if (!SkipCurrentInterface())
     129              :             {
     130          107 :                 break;
     131              :             }
     132          107 :         } while (mIterator.Next());
     133          107 :     }
     134              : 
     135          321 :     bool SkipCurrentInterface()
     136              :     {
     137          321 :         if (!mIterator.HasCurrent())
     138              :         {
     139          107 :             return false; // nothing to try.
     140              :         }
     141              : 
     142          214 :         return !IsCurrentInterfaceUsable(mIterator);
     143              :     }
     144              : 
     145              :     bool CurrentInterfaceHasAddressOfType(chip::Inet::IPAddressType type);
     146              : };
     147              : 
     148              : class AllAddressesIterator : public mdns::Minimal::IpAddressIterator
     149              : {
     150              : public:
     151          528 :     AllAddressesIterator(chip::Inet::InterfaceId interfaceId, chip::Inet::IPAddressType addrType) :
     152          528 :         mInterfaceIdFilter(interfaceId), mAddrType(addrType)
     153          528 :     {}
     154              : 
     155         1412 :     bool Next(chip::Inet::IPAddress & dest)
     156              :     {
     157              :         while (true)
     158              :         {
     159         1412 :             if (!mIterator.HasCurrent())
     160              :             {
     161          488 :                 return false;
     162              :             }
     163              : 
     164         1258 :             if (mIterator.GetInterfaceId() != mInterfaceIdFilter)
     165              :             {
     166          697 :                 mIterator.Next();
     167          697 :                 continue;
     168              :             }
     169              : 
     170          561 :             CHIP_ERROR err = mIterator.GetAddress(dest);
     171          561 :             mIterator.Next();
     172              : 
     173          561 :             if (mAddrType != chip::Inet::IPAddressType::kAny)
     174              :             {
     175          561 :                 if (dest.Type() != mAddrType)
     176              :                 {
     177          227 :                     continue;
     178              :                 }
     179              :             }
     180              : 
     181          668 :             if (err != CHIP_NO_ERROR)
     182              :             {
     183            0 :                 ChipLogError(Discovery, "Failed to fetch interface IP address: %" CHIP_ERROR_FORMAT, err.Format());
     184            0 :                 continue;
     185              :             }
     186              : 
     187          334 :             return true;
     188          924 :         }
     189              :     }
     190              : 
     191              : private:
     192              :     const chip::Inet::InterfaceId mInterfaceIdFilter;
     193              :     const chip::Inet::IPAddressType mAddrType;
     194              :     chip::Inet::InterfaceAddressIterator mIterator;
     195              : };
     196              : 
     197          214 : bool AllInterfaces::CurrentInterfaceHasAddressOfType(chip::Inet::IPAddressType type)
     198              : {
     199              :     // mIterator.HasCurrent() must be true here.
     200          214 :     AllAddressesIterator addressIter(mIterator.GetInterfaceId(), type);
     201              :     chip::Inet::IPAddress addr;
     202          214 :     if (addressIter.Next(addr))
     203              :     {
     204          214 :         return true;
     205              :     }
     206              : 
     207            0 :     return false;
     208          214 : }
     209              : 
     210              : class DefaultAddressPolicy : public AddressPolicy
     211              : {
     212              : public:
     213          107 :     chip::Platform::UniquePtr<ListenIterator> GetListenEndpoints() override
     214              :     {
     215          107 :         return chip::Platform::UniquePtr<ListenIterator>(chip::Platform::New<AllInterfaces>());
     216              :     }
     217              : 
     218          314 :     chip::Platform::UniquePtr<IpAddressIterator> GetIpAddressesForEndpoint(chip::Inet::InterfaceId interfaceId,
     219              :                                                                            chip::Inet::IPAddressType type) override
     220              :     {
     221          314 :         return chip::Platform::UniquePtr<IpAddressIterator>(chip::Platform::New<AllAddressesIterator>(interfaceId, type));
     222              :     }
     223              : };
     224              : 
     225              : DefaultAddressPolicy gDefaultAddressPolicy;
     226              : 
     227              : } // namespace
     228              : 
     229          183 : void SetDefaultAddressPolicy()
     230              : {
     231          183 :     SetAddressPolicy(&gDefaultAddressPolicy);
     232          183 : }
     233              : 
     234              : } // namespace Minimal
     235              : } // namespace mdns
        

Generated by: LCOV version 2.0-1