LCOV - code coverage report
Current view: top level - source/extensions/network/dns_resolver/cares - dns_impl.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 13 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 3 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstdint>
       4             : #include <string>
       5             : 
       6             : #include "envoy/common/platform.h"
       7             : #include "envoy/event/dispatcher.h"
       8             : #include "envoy/event/file_event.h"
       9             : #include "envoy/network/dns.h"
      10             : #include "envoy/registry/registry.h"
      11             : 
      12             : #include "source/common/common/linked_object.h"
      13             : #include "source/common/common/logger.h"
      14             : #include "source/common/common/utility.h"
      15             : #include "source/common/network/dns_resolver/dns_factory_util.h"
      16             : 
      17             : #include "absl/container/node_hash_map.h"
      18             : #include "ares.h"
      19             : 
      20             : namespace Envoy {
      21             : namespace Network {
      22             : 
      23             : /**
      24             :  * All DNS stats. @see stats_macros.h
      25             :  */
      26             : #define ALL_CARES_DNS_RESOLVER_STATS(COUNTER, GAUGE)                                               \
      27           0 :   COUNTER(resolve_total)                                                                           \
      28           0 :   GAUGE(pending_resolutions, NeverImport)                                                          \
      29           0 :   COUNTER(not_found)                                                                               \
      30           0 :   COUNTER(get_addr_failure)                                                                        \
      31           0 :   COUNTER(timeouts)
      32             : 
      33             : /**
      34             :  * Struct definition for all DNS stats. @see stats_macros.h
      35             :  */
      36             : struct CaresDnsResolverStats {
      37             :   ALL_CARES_DNS_RESOLVER_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT)
      38             : };
      39             : 
      40             : class DnsResolverImplPeer;
      41             : 
      42             : /**
      43             :  * Implementation of DnsResolver that uses c-ares. All calls and callbacks are assumed to
      44             :  * happen on the thread that owns the creating dispatcher.
      45             :  */
      46             : class DnsResolverImpl : public DnsResolver, protected Logger::Loggable<Logger::Id::dns> {
      47             : public:
      48             :   DnsResolverImpl(
      49             :       const envoy::extensions::network::dns_resolver::cares::v3::CaresDnsResolverConfig& config,
      50             :       Event::Dispatcher& dispatcher,
      51             :       const std::vector<Network::Address::InstanceConstSharedPtr>& resolvers,
      52             :       Stats::Scope& root_scope);
      53             :   ~DnsResolverImpl() override;
      54             : 
      55             :   static CaresDnsResolverStats generateCaresDnsResolverStats(Stats::Scope& scope);
      56             : 
      57             :   // Network::DnsResolver
      58             :   ActiveDnsQuery* resolve(const std::string& dns_name, DnsLookupFamily dns_lookup_family,
      59             :                           ResolveCb callback) override;
      60           0 :   void resetNetworking() override {
      61             :     // Dirty the channel so that the next query will recreate it.
      62           0 :     dirty_channel_ = true;
      63           0 :   }
      64             : 
      65             : private:
      66             :   friend class DnsResolverImplPeer;
      67             :   class PendingResolution : public ActiveDnsQuery {
      68             :   public:
      69           0 :     void cancel(CancelReason reason) override {
      70             :       // c-ares only supports channel-wide cancellation, so we just allow the
      71             :       // network events to continue but don't invoke the callback on completion.
      72             :       // TODO(mattklein123): Potentially use timeout to destroy and recreate the channel.
      73           0 :       cancelled_ = true;
      74           0 :       cancel_reason_ = reason;
      75           0 :     }
      76             :     // Does the object own itself? Resource reclamation occurs via self-deleting
      77             :     // on query completion or error.
      78             :     bool owned_ = false;
      79             :     // Has the query completed? Only meaningful if !owned_;
      80             :     bool completed_ = false;
      81             : 
      82             :   protected:
      83             :     // Network::ActiveDnsQuery
      84             :     PendingResolution(DnsResolverImpl& parent, ResolveCb callback, Event::Dispatcher& dispatcher,
      85             :                       ares_channel channel, const std::string& dns_name)
      86             :         : parent_(parent), callback_(callback), dispatcher_(dispatcher), channel_(channel),
      87           0 :           dns_name_(dns_name) {}
      88             : 
      89             :     void finishResolve();
      90             : 
      91             :     DnsResolverImpl& parent_;
      92             :     // Caller supplied callback to invoke on query completion or error.
      93             :     const ResolveCb callback_;
      94             :     // Dispatcher to post any callback_ exceptions to.
      95             :     Event::Dispatcher& dispatcher_;
      96             :     // Was the query cancelled via cancel()?
      97             :     bool cancelled_ = false;
      98             :     const ares_channel channel_;
      99             :     const std::string dns_name_;
     100             :     CancelReason cancel_reason_;
     101             : 
     102             :     // Small wrapping struct to accumulate addresses from firings of the
     103             :     // onAresGetAddrInfoCallback callback.
     104             :     struct PendingResponse {
     105             :       ResolutionStatus status_;
     106             :       std::list<DnsResponse> address_list_;
     107             :     };
     108             : 
     109             :     // Note: pending_response_ is constructed with ResolutionStatus::Failure by default and
     110             :     // __only__ changed to ResolutionStatus::Success if there is an `ARES_SUCCESS` or `ARES_ENODATA`
     111             :     // or `ARES_ENOTFOUND`reply.
     112             :     // In the dual_resolution case __any__ ARES_SUCCESS reply will result in a
     113             :     // ResolutionStatus::Success callback.
     114             :     PendingResponse pending_response_{ResolutionStatus::Failure, {}};
     115             :   };
     116             : 
     117             :   class AddrInfoPendingResolution final : public PendingResolution {
     118             :   public:
     119             :     AddrInfoPendingResolution(DnsResolverImpl& parent, ResolveCb callback,
     120             :                               Event::Dispatcher& dispatcher, ares_channel channel,
     121             :                               const std::string& dns_name, DnsLookupFamily dns_lookup_family);
     122             :     ~AddrInfoPendingResolution() override;
     123             : 
     124             :     /**
     125             :      * ares_getaddrinfo query callback.
     126             :      * @param status return status of call to ares_getaddrinfo.
     127             :      * @param timeouts the number of times the request timed out.
     128             :      * @param addrinfo structure to store address info.
     129             :      */
     130             :     void onAresGetAddrInfoCallback(int status, int timeouts, ares_addrinfo* addrinfo);
     131             : 
     132             :     /**
     133             :      * wrapper function of call to ares_getaddrinfo.
     134             :      */
     135             :     void startResolution();
     136             : 
     137             :   private:
     138             :     void startResolutionImpl(int family);
     139             :     bool isResponseWithNoRecords(int status);
     140             : 
     141             :     // Holds the availability of non-loopback network interfaces for the system.
     142             :     struct AvailableInterfaces {
     143             :       bool v4_available_;
     144             :       bool v6_available_;
     145             :     };
     146             : 
     147             :     // Return the currently available network interfaces.
     148             :     // Note: this call uses syscalls.
     149             :     AvailableInterfaces availableInterfaces();
     150             : 
     151             :     // Perform a second resolution under certain conditions. If dns_lookup_family_ is V4Preferred
     152             :     // or Auto: perform a second resolution if the first one fails. If dns_lookup_family_ is All:
     153             :     // perform resolutions on both families concurrently.
     154             :     bool dual_resolution_ = false;
     155             :     // The number of outstanding pending resolutions. This should always be 0 or 1 for all lookup
     156             :     // types other than All. For all, this can be be 0-2 as both queries are issued in parallel.
     157             :     // This is used mostly for assertions but is used in the ARES_EDESTRUCTION path to make sure
     158             :     // all concurrent queries are unwound before cleaning up the resolution.
     159             :     uint32_t pending_resolutions_ = 0;
     160             :     int family_ = AF_INET;
     161             :     const DnsLookupFamily dns_lookup_family_;
     162             :     // Queried for at construction time.
     163             :     const AvailableInterfaces available_interfaces_;
     164             :   };
     165             : 
     166             :   struct AresOptions {
     167             :     ares_options options_;
     168             :     int optmask_;
     169             :   };
     170             : 
     171             :   static absl::optional<std::string>
     172             :   maybeBuildResolversCsv(const std::vector<Network::Address::InstanceConstSharedPtr>& resolvers);
     173             : 
     174             :   // Callback for events on sockets tracked in events_.
     175             :   void onEventCallback(os_fd_t fd, uint32_t events);
     176             :   // c-ares callback when a socket state changes, indicating that libevent
     177             :   // should listen for read/write events.
     178             :   void onAresSocketStateChange(os_fd_t fd, int read, int write);
     179             :   // Initialize the channel.
     180             :   void initializeChannel(ares_options* options, int optmask);
     181             :   // Check if the only nameserver available is the c-ares default.
     182             :   bool isCaresDefaultTheOnlyNameserver();
     183             :   // Update timer for c-ares timeouts.
     184             :   void updateAresTimer();
     185             :   // Return default AresOptions.
     186             :   AresOptions defaultAresOptions();
     187             : 
     188             :   void chargeGetAddrInfoErrorStats(int status, int timeouts);
     189             : 
     190             :   Event::Dispatcher& dispatcher_;
     191             :   Event::TimerPtr timer_;
     192             :   ares_channel channel_;
     193             :   bool dirty_channel_{};
     194             :   envoy::config::core::v3::DnsResolverOptions dns_resolver_options_;
     195             : 
     196             :   absl::node_hash_map<int, Event::FileEventPtr> events_;
     197             :   const bool use_resolvers_as_fallback_;
     198             :   const absl::optional<std::string> resolvers_csv_;
     199             :   const bool filter_unroutable_families_;
     200             :   Stats::ScopeSharedPtr scope_;
     201             :   CaresDnsResolverStats stats_;
     202             : };
     203             : 
     204             : DECLARE_FACTORY(CaresDnsResolverFactory);
     205             : 
     206             : } // namespace Network
     207             : } // namespace Envoy

Generated by: LCOV version 1.15