Matter SDK Coverage Report
Current view: top level - lib/dnssd/minimal_mdns - AddressPolicy_DefaultImpl.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 89.9 % 69 62
Test Date: 2025-01-17 19:00:11 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          128 : bool IsCurrentInterfaceUsable(T & iterator)
      29              : {
      30          128 :     if (!iterator.IsUp())
      31              :     {
      32            0 :         return false; // not a usable interface
      33              :     }
      34              :     char name[chip::Inet::InterfaceId::kMaxIfNameLength];
      35          128 :     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          128 :     if (strncmp(name, "lo", 2) == 0)
      50              :     {
      51              :         /// local loopback interface is not usable by MDNS
      52           64 :         return false;
      53              :     }
      54           64 :     return true;
      55              : }
      56              : 
      57              : class AllInterfaces : public mdns::Minimal::ListenIterator
      58              : {
      59              : public:
      60           64 :     AllInterfaces() { SkipToFirstValidInterface(); }
      61              : 
      62          192 :     bool Next(chip::Inet::InterfaceId * id, chip::Inet::IPAddressType * type) override
      63              :     {
      64          192 :         if (!mIterator.HasCurrent())
      65              :         {
      66           64 :             return false;
      67              :         }
      68              : 
      69              : #if INET_CONFIG_ENABLE_IPV4
      70          128 :         if (mState == State::kIpV4)
      71              :         {
      72           64 :             mState = State::kIpV6;
      73              : 
      74           64 :             if (CurrentInterfaceHasAddressOfType(chip::Inet::IPAddressType::kIPv4))
      75              :             {
      76           64 :                 *id   = mIterator.GetInterfaceId();
      77           64 :                 *type = chip::Inet::IPAddressType::kIPv4;
      78           64 :                 return true;
      79              :             }
      80              :         }
      81              : #endif
      82              : 
      83              : #if INET_CONFIG_ENABLE_IPV4
      84           64 :         mState = State::kIpV4;
      85              : #endif
      86              : 
      87           64 :         bool haveResult = CurrentInterfaceHasAddressOfType(chip::Inet::IPAddressType::kIPv6);
      88           64 :         if (haveResult)
      89              :         {
      90           64 :             *id   = mIterator.GetInterfaceId();
      91           64 :             *type = chip::Inet::IPAddressType::kIPv6;
      92              :         }
      93              : 
      94           64 :         for (mIterator.Next(); SkipCurrentInterface(); mIterator.Next())
      95              :         {
      96              :         }
      97              : 
      98           64 :         if (haveResult)
      99              :         {
     100           64 :             return true;
     101              :         }
     102              : 
     103            0 :         return Next(id, type);
     104              :     }
     105              : 
     106              : private:
     107              : #if INET_CONFIG_ENABLE_IPV4
     108              :     enum class State
     109              :     {
     110              :         kIpV4,
     111              :         kIpV6,
     112              :     };
     113              :     State mState = State::kIpV4;
     114              : #endif
     115              :     chip::Inet::InterfaceIterator mIterator;
     116              : 
     117          128 :     void SkipToFirstValidInterface()
     118              :     {
     119              :         do
     120              :         {
     121          128 :             if (!SkipCurrentInterface())
     122              :             {
     123           64 :                 break;
     124              :             }
     125           64 :         } while (mIterator.Next());
     126           64 :     }
     127              : 
     128          192 :     bool SkipCurrentInterface()
     129              :     {
     130          192 :         if (!mIterator.HasCurrent())
     131              :         {
     132           64 :             return false; // nothing to try.
     133              :         }
     134              : 
     135          128 :         return !IsCurrentInterfaceUsable(mIterator);
     136              :     }
     137              : 
     138              :     bool CurrentInterfaceHasAddressOfType(chip::Inet::IPAddressType type);
     139              : };
     140              : 
     141              : class AllAddressesIterator : public mdns::Minimal::IpAddressIterator
     142              : {
     143              : public:
     144          400 :     AllAddressesIterator(chip::Inet::InterfaceId interfaceId, chip::Inet::IPAddressType addrType) :
     145          400 :         mInterfaceIdFilter(interfaceId), mAddrType(addrType)
     146          400 :     {}
     147              : 
     148         1244 :     bool Next(chip::Inet::IPAddress & dest)
     149              :     {
     150              :         while (true)
     151              :         {
     152         1244 :             if (!mIterator.HasCurrent())
     153              :             {
     154          438 :                 return false;
     155              :             }
     156              : 
     157         1072 :             if (mIterator.GetInterfaceId() != mInterfaceIdFilter)
     158              :             {
     159          604 :                 mIterator.Next();
     160          604 :                 continue;
     161              :             }
     162              : 
     163          468 :             CHIP_ERROR err = mIterator.GetAddress(dest);
     164          468 :             mIterator.Next();
     165              : 
     166          468 :             if (mAddrType != chip::Inet::IPAddressType::kAny)
     167              :             {
     168          468 :                 if (dest.Type() != mAddrType)
     169              :                 {
     170          202 :                     continue;
     171              :                 }
     172              :             }
     173              : 
     174          266 :             if (err != CHIP_NO_ERROR)
     175              :             {
     176            0 :                 ChipLogError(Discovery, "Failed to fetch interface IP address: %" CHIP_ERROR_FORMAT, err.Format());
     177            0 :                 continue;
     178              :             }
     179              : 
     180          266 :             return true;
     181          806 :         }
     182              :     }
     183              : 
     184              : private:
     185              :     const chip::Inet::InterfaceId mInterfaceIdFilter;
     186              :     const chip::Inet::IPAddressType mAddrType;
     187              :     chip::Inet::InterfaceAddressIterator mIterator;
     188              : };
     189              : 
     190          128 : bool AllInterfaces::CurrentInterfaceHasAddressOfType(chip::Inet::IPAddressType type)
     191              : {
     192              :     // mIterator.HasCurrent() must be true here.
     193          128 :     AllAddressesIterator addressIter(mIterator.GetInterfaceId(), type);
     194              :     chip::Inet::IPAddress addr;
     195          128 :     if (addressIter.Next(addr))
     196              :     {
     197          128 :         return true;
     198              :     }
     199              : 
     200            0 :     return false;
     201          128 : }
     202              : 
     203              : class DefaultAddressPolicy : public AddressPolicy
     204              : {
     205              : public:
     206           64 :     chip::Platform::UniquePtr<ListenIterator> GetListenEndpoints() override
     207              :     {
     208           64 :         return chip::Platform::UniquePtr<ListenIterator>(chip::Platform::New<AllInterfaces>());
     209              :     }
     210              : 
     211          272 :     chip::Platform::UniquePtr<IpAddressIterator> GetIpAddressesForEndpoint(chip::Inet::InterfaceId interfaceId,
     212              :                                                                            chip::Inet::IPAddressType type) override
     213              :     {
     214          272 :         return chip::Platform::UniquePtr<IpAddressIterator>(chip::Platform::New<AllAddressesIterator>(interfaceId, type));
     215              :     }
     216              : };
     217              : 
     218              : DefaultAddressPolicy gDefaultAddressPolicy;
     219              : 
     220              : } // namespace
     221              : 
     222           65 : void SetDefaultAddressPolicy()
     223              : {
     224           65 :     SetAddressPolicy(&gDefaultAddressPolicy);
     225           65 : }
     226              : 
     227              : } // namespace Minimal
     228              : } // namespace mdns
        

Generated by: LCOV version 2.0-1