| // Copyright (c) 2019 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_ | 
 | #define QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_ | 
 |  | 
 | #include <netinet/icmp6.h> | 
 |  | 
 | #include "absl/strings/string_view.h" | 
 | #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" | 
 | #include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h" | 
 | #include "net/third_party/quiche/src/quic/qbone/bonnet/icmp_reachable_interface.h" | 
 | #include "net/third_party/quiche/src/quic/qbone/platform/kernel_interface.h" | 
 |  | 
 | namespace quic { | 
 |  | 
 | extern const char kUnknownSource[]; | 
 | extern const char kNoSource[]; | 
 |  | 
 | // IcmpReachable schedules itself with an EpollServer, periodically sending | 
 | // ICMPv6 Echo Requests to the given |destination| on the interface that the | 
 | // given |source| is bound to. Echo Requests are sent once every |timeout|. | 
 | // On Echo Replies, timeouts, and I/O errors, the given |stats| object will | 
 | // be called back with details of the event. | 
 | class IcmpReachable : public IcmpReachableInterface { | 
 |  public: | 
 |   enum Status { REACHABLE, UNREACHABLE }; | 
 |  | 
 |   struct ReachableEvent { | 
 |     Status status; | 
 |     absl::Duration response_time; | 
 |     std::string source; | 
 |   }; | 
 |  | 
 |   class StatsInterface { | 
 |    public: | 
 |     StatsInterface() = default; | 
 |  | 
 |     StatsInterface(const StatsInterface&) = delete; | 
 |     StatsInterface& operator=(const StatsInterface&) = delete; | 
 |  | 
 |     StatsInterface(StatsInterface&&) = delete; | 
 |     StatsInterface& operator=(StatsInterface&&) = delete; | 
 |  | 
 |     virtual ~StatsInterface() = default; | 
 |  | 
 |     virtual void OnEvent(ReachableEvent event) = 0; | 
 |  | 
 |     virtual void OnReadError(int error) = 0; | 
 |  | 
 |     virtual void OnWriteError(int error) = 0; | 
 |   }; | 
 |  | 
 |   // |source| is the IPv6 address bound to the interface that IcmpReachable will | 
 |   //          send Echo Requests on. | 
 |   // |destination| is the IPv6 address of the destination of the Echo Requests. | 
 |   // |timeout| is the duration IcmpReachable will wait between Echo Requests. | 
 |   //           If no Echo Response is received by the next Echo Request, it will | 
 |   //           be considered a timeout. | 
 |   // |kernel| is not owned, but should outlive this instance. | 
 |   // |epoll_server| is not owned, but should outlive this instance. | 
 |   //                IcmpReachable's Init() must be called from within the Epoll | 
 |   //                Server's thread. | 
 |   // |stats| is not owned, but should outlive this instance. It will be called | 
 |   //         back on Echo Replies, timeouts, and I/O errors. | 
 |   IcmpReachable(QuicIpAddress source, | 
 |                 QuicIpAddress destination, | 
 |                 absl::Duration timeout, | 
 |                 KernelInterface* kernel, | 
 |                 QuicEpollServer* epoll_server, | 
 |                 StatsInterface* stats); | 
 |  | 
 |   ~IcmpReachable() override; | 
 |  | 
 |   // Initializes this reachability probe. Must be called from within the | 
 |   // |epoll_server|'s thread. | 
 |   bool Init() QUIC_LOCKS_EXCLUDED(header_lock_) override; | 
 |  | 
 |   int64 /* allow-non-std-int */ OnAlarm() | 
 |       QUIC_LOCKS_EXCLUDED(header_lock_) override; | 
 |  | 
 |   static absl::string_view StatusName(Status status); | 
 |  | 
 |  private: | 
 |   class EpollCallback : public QuicEpollCallbackInterface { | 
 |    public: | 
 |     explicit EpollCallback(IcmpReachable* reachable) : reachable_(reachable) {} | 
 |  | 
 |     EpollCallback(const EpollCallback&) = delete; | 
 |     EpollCallback& operator=(const EpollCallback&) = delete; | 
 |  | 
 |     EpollCallback(EpollCallback&&) = delete; | 
 |     EpollCallback& operator=(EpollCallback&&) = delete; | 
 |  | 
 |     void OnRegistration(QuicEpollServer* eps, | 
 |                         int fd, | 
 |                         int event_mask) override{}; | 
 |  | 
 |     void OnModification(int fd, int event_mask) override{}; | 
 |  | 
 |     void OnEvent(int fd, QuicEpollEvent* event) override; | 
 |  | 
 |     void OnUnregistration(int fd, bool replaced) override{}; | 
 |  | 
 |     void OnShutdown(QuicEpollServer* eps, int fd) override; | 
 |  | 
 |     std::string Name() const override; | 
 |  | 
 |    private: | 
 |     IcmpReachable* reachable_; | 
 |   }; | 
 |  | 
 |   bool OnEvent(int fd) QUIC_LOCKS_EXCLUDED(header_lock_); | 
 |  | 
 |   const absl::Duration timeout_; | 
 |  | 
 |   EpollCallback cb_; | 
 |  | 
 |   sockaddr_in6 src_{}; | 
 |   sockaddr_in6 dst_{}; | 
 |  | 
 |   KernelInterface* kernel_; | 
 |   QuicEpollServer* epoll_server_; | 
 |  | 
 |   StatsInterface* stats_; | 
 |  | 
 |   int send_fd_; | 
 |   int recv_fd_; | 
 |  | 
 |   QuicMutex header_lock_; | 
 |   icmp6_hdr icmp_header_ QUIC_GUARDED_BY(header_lock_){}; | 
 |  | 
 |   absl::Time start_ = absl::InfinitePast(); | 
 |   absl::Time end_ = absl::InfinitePast(); | 
 | }; | 
 |  | 
 | }  // namespace quic | 
 |  | 
 | #endif  // QUICHE_QUIC_QBONE_BONNET_ICMP_REACHABLE_H_ |