| // 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 "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" |
| #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.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 quiche::QuicheStringPiece 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_ |