LCOV - code coverage report
Current view: top level - lib/dnssd/minimal_mdns - Server.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 23 23 100.0 %
Date: 2024-02-15 08:20:41 Functions: 9 12 75.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2020 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             : 
      18             : #pragma once
      19             : 
      20             : #include <inet/IPAddress.h>
      21             : #include <inet/InetInterface.h>
      22             : #include <inet/UDPEndPoint.h>
      23             : #include <lib/core/CHIPError.h>
      24             : #include <lib/support/PoolWrapper.h>
      25             : 
      26             : #include <lib/dnssd/minimal_mdns/ListenIterator.h>
      27             : #include <lib/dnssd/minimal_mdns/core/BytesRange.h>
      28             : 
      29             : namespace mdns {
      30             : namespace Minimal {
      31             : 
      32             : namespace BroadcastIpAddresses {
      33             : 
      34             : // Get standard mDNS Broadcast addresses
      35             : chip::Inet::IPAddress Get(chip::Inet::IPAddressType addressType);
      36             : 
      37             : } // namespace BroadcastIpAddresses
      38             : 
      39             : /// Handles mDNS Server Callbacks
      40             : class ServerDelegate
      41             : {
      42             : public:
      43          30 :     virtual ~ServerDelegate() {}
      44             : 
      45             :     // Callback of when a query is received
      46             :     virtual void OnQuery(const BytesRange & data, const chip::Inet::IPPacketInfo * info) = 0;
      47             : 
      48             :     // Callback of when a response is received
      49             :     virtual void OnResponse(const BytesRange & data, const chip::Inet::IPPacketInfo * info) = 0;
      50             : };
      51             : 
      52             : // Defines an mDNS server that listens on one or more interfaces.
      53             : //
      54             : // I can send and receive mDNS packets (requests/replies)
      55             : class ServerBase
      56             : {
      57             : public:
      58             :     class EndpointInfo
      59             :     {
      60             :     public:
      61             :         struct EndPointDeletor
      62             :         {
      63           4 :             void operator()(chip::Inet::UDPEndPoint * e) { e->Free(); }
      64             :         };
      65             : 
      66             : #if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT
      67          32 :         EndpointInfo(chip::Inet::InterfaceId interfaceId, chip::Inet::IPAddressType addressType,
      68             :                      std::unique_ptr<chip::Inet::UDPEndPoint, EndPointDeletor> && listenUdp,
      69          32 :                      std::unique_ptr<chip::Inet::UDPEndPoint, EndPointDeletor> && unicastQueryUdp) :
      70          32 :             mInterfaceId(interfaceId),
      71          32 :             mAddressType(addressType), mListenUdp(listenUdp.release()), mUnicastQueryUdp(unicastQueryUdp.release())
      72          32 :         {}
      73             : #else
      74             :         EndpointInfo(chip::Inet::InterfaceId interfaceId, chip::Inet::IPAddressType addressType,
      75             :                      std::unique_ptr<chip::Inet::UDPEndPoint, EndPointDeletor> && listenUdp) :
      76             :             mInterfaceId(interfaceId),
      77             :             mAddressType(addressType), mListenUdp(listenUdp.release())
      78             :         {}
      79             : #endif
      80             : 
      81          32 :         ~EndpointInfo()
      82             :         {
      83          32 :             if (mListenUdp != nullptr)
      84             :             {
      85          32 :                 mListenUdp->Free();
      86             :             }
      87             : 
      88             : #if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT
      89          32 :             if (mUnicastQueryUdp != nullptr)
      90             :             {
      91          32 :                 mUnicastQueryUdp->Free();
      92             :             }
      93             : #endif
      94          32 :         }
      95             : 
      96             :         const chip::Inet::InterfaceId mInterfaceId;
      97             :         const chip::Inet::IPAddressType mAddressType;
      98             :         chip::Inet::UDPEndPoint * const mListenUdp;
      99             : #if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT
     100             :         chip::Inet::UDPEndPoint * const mUnicastQueryUdp;
     101             : #endif
     102             :     };
     103             : 
     104             :     /**
     105             :      * Helps implement a generic broadcast implementation:
     106             :      *    - provides the ability to determine what udp endpoint to use  to broadcast
     107             :      *      a packet for the given endpoint info
     108             :      */
     109             :     class BroadcastSendDelegate
     110             :     {
     111             :     public:
     112         156 :         virtual ~BroadcastSendDelegate() = default;
     113             : 
     114             :         /**
     115             :          * Returns non-null UDPEndpoint IFF a broadcast should be performed for the given EndpointInfo
     116             :          */
     117             :         virtual chip::Inet::UDPEndPoint * Accept(ServerBase::EndpointInfo * info) = 0;
     118             :     };
     119             : 
     120             : #if CHIP_MINMDNS_USE_EPHEMERAL_UNICAST_PORT
     121             :     using EndpointInfoPoolType = chip::PoolInterface<EndpointInfo, chip::Inet::InterfaceId, chip::Inet::IPAddressType,
     122             :                                                      std::unique_ptr<chip::Inet::UDPEndPoint, EndpointInfo::EndPointDeletor> &&,
     123             :                                                      std::unique_ptr<chip::Inet::UDPEndPoint, EndpointInfo::EndPointDeletor> &&>;
     124             : #else
     125             :     using EndpointInfoPoolType = chip::PoolInterface<EndpointInfo, chip::Inet::InterfaceId, chip::Inet::IPAddressType,
     126             :                                                      std::unique_ptr<chip::Inet::UDPEndPoint, EndpointInfo::EndPointDeletor> &&>;
     127             : #endif
     128             : 
     129          29 :     ServerBase(EndpointInfoPoolType & pool) : mEndpoints(pool)
     130             :     {
     131          29 :         mIpv6BroadcastAddress = BroadcastIpAddresses::Get(chip::Inet::IPAddressType::kIPv6);
     132             : #if INET_CONFIG_ENABLE_IPV4
     133          29 :         mIpv4BroadcastAddress = BroadcastIpAddresses::Get(chip::Inet::IPAddressType::kIPv4);
     134             : #endif
     135          29 :     }
     136             :     virtual ~ServerBase();
     137             : 
     138             :     /// Closes all currently open endpoints and resets the 'initialized' flag
     139             :     void Shutdown();
     140             : 
     141             :     void ShutdownEndpoints();
     142             :     void ShutdownEndpoint(EndpointInfo & aEndpoint);
     143             : 
     144             :     /// Listen on the given interfaces/address types.
     145             :     ///
     146             :     /// Since mDNS uses link-local addresses, one generally wants to listen on all
     147             :     /// non-loopback interfaces.
     148             :     CHIP_ERROR Listen(chip::Inet::EndPointManager<chip::Inet::UDPEndPoint> * udpEndPointManager, ListenIterator * it,
     149             :                       uint16_t port);
     150             : 
     151             :     /// Send the specified packet to a destination IP address over the specified address
     152             :     virtual CHIP_ERROR DirectSend(chip::System::PacketBufferHandle && data, const chip::Inet::IPAddress & addr, uint16_t port,
     153             :                                   chip::Inet::InterfaceId interface);
     154             : 
     155             :     /// Send out a broadcast query, may use an ephemeral port to receive replies.
     156             :     /// Ephemeral ports will make replies be marked as 'LEGACY' and replies will include a query secion.
     157             :     virtual CHIP_ERROR BroadcastUnicastQuery(chip::System::PacketBufferHandle && data, uint16_t port);
     158             : 
     159             :     /// Send a specific packet broadcast to a specific interface using a specific address type
     160             :     /// May use an ephemeral port to receive replies.
     161             :     /// Ephemeral ports will make replies be marked as 'LEGACY' and replies will include a query secion.
     162             :     virtual CHIP_ERROR BroadcastUnicastQuery(chip::System::PacketBufferHandle && data, uint16_t port,
     163             :                                              chip::Inet::InterfaceId interface, chip::Inet::IPAddressType addressType);
     164             : 
     165             :     /// Send a specific packet broadcast to all interfaces
     166             :     virtual CHIP_ERROR BroadcastSend(chip::System::PacketBufferHandle && data, uint16_t port);
     167             : 
     168             :     /// Send a specific packet broadcast to a specific interface using a specific address type
     169             :     virtual CHIP_ERROR BroadcastSend(chip::System::PacketBufferHandle && data, uint16_t port, chip::Inet::InterfaceId interface,
     170             :                                      chip::Inet::IPAddressType addressType);
     171             : 
     172          30 :     ServerBase & SetDelegate(ServerDelegate * d)
     173             :     {
     174          30 :         mDelegate = d;
     175          30 :         return *this;
     176             :     }
     177             : 
     178             :     /// A server is considered listening if any UDP endpoint is active.
     179             :     ///
     180             :     /// This is expected to return false after any Shutdown() and will
     181             :     /// return true IFF lListen was called and the listen iterator successfully
     182             :     /// found a valid listening interface.
     183             :     bool IsListening() const;
     184             : 
     185             : private:
     186             :     CHIP_ERROR BroadcastImpl(chip::System::PacketBufferHandle && data, uint16_t port, BroadcastSendDelegate * delegate);
     187             : 
     188             :     static void OnUdpPacketReceived(chip::Inet::UDPEndPoint * endPoint, chip::System::PacketBufferHandle && buffer,
     189             :                                     const chip::Inet::IPPacketInfo * info);
     190             : 
     191             :     EndpointInfoPoolType & mEndpoints; // possible endpoints, to listen on multiple interfaces
     192             :     ServerDelegate * mDelegate = nullptr;
     193             : 
     194             :     // Broadcast IP addresses are cached to not require a string parse every time
     195             :     // Ideally we should be able to constexpr these
     196             :     chip::Inet::IPAddress mIpv6BroadcastAddress;
     197             : #if INET_CONFIG_ENABLE_IPV4
     198             :     chip::Inet::IPAddress mIpv4BroadcastAddress;
     199             : #endif
     200             :     bool mIsInitialized = false;
     201             : };
     202             : 
     203             : // The PoolImpl impl is used as a base class because its destructor must be called after ServerBase's destructor.
     204             : template <size_t kCount>
     205             : class Server : private chip::PoolImpl<ServerBase::EndpointInfo, kCount, chip::ObjectPoolMem::kInline,
     206             :                                       ServerBase::EndpointInfoPoolType::Interface>,
     207             :                public ServerBase
     208             : {
     209             : public:
     210          30 :     Server() : ServerBase(*static_cast<ServerBase::EndpointInfoPoolType *>(this)) {}
     211          30 :     ~Server() override {}
     212             : };
     213             : 
     214             : } // namespace Minimal
     215             : } // namespace mdns

Generated by: LCOV version 1.14