LCOV - code coverage report
Current view: top level - envoy/network - io_handle.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 2 2 100.0 %
Date: 2024-01-05 06:35:25 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <chrono>
       4             : #include <memory>
       5             : 
       6             : #include "envoy/api/io_error.h"
       7             : #include "envoy/api/os_sys_calls_common.h"
       8             : #include "envoy/common/platform.h"
       9             : #include "envoy/common/pure.h"
      10             : #include "envoy/event/file_event.h"
      11             : #include "envoy/network/address.h"
      12             : 
      13             : #include "absl/container/fixed_array.h"
      14             : #include "absl/types/optional.h"
      15             : 
      16             : namespace Envoy {
      17             : namespace Buffer {
      18             : struct RawSlice;
      19             : class Instance;
      20             : } // namespace Buffer
      21             : 
      22             : namespace Event {
      23             : class Dispatcher;
      24             : } // namespace Event
      25             : 
      26             : using RawSliceArrays = absl::FixedArray<absl::FixedArray<Buffer::RawSlice>>;
      27             : 
      28             : namespace Network {
      29             : 
      30             : struct Win32RedirectRecords {
      31             :   // The size of the buffer is selected based on:
      32             :   // https://docs.microsoft.com/en-us/windows-hardware/drivers/network/sio-query-wfp-connection-redirect-records
      33             :   uint8_t buf_[2048];
      34             :   unsigned long buf_size_;
      35             : };
      36             : 
      37             : /**
      38             :  * IoHandle: an abstract interface for all I/O operations
      39             :  */
      40             : class IoHandle {
      41             : public:
      42        8019 :   virtual ~IoHandle() = default;
      43             : 
      44             :   /**
      45             :    * NOTE: Must NOT be used for new use cases!
      46             :    *
      47             :    * This is most probably not the function you are looking for. IoHandle has wrappers for most of
      48             :    * the POSIX socket api functions so there should be no need to interact with the internal fd by
      49             :    * means of syscalls. Moreover, depending on the IoHandle implementation, the fd might not be an
      50             :    * underlying OS file descriptor. If any api function is missing, a wrapper for it should be added
      51             :    * to the IoHandle interface.
      52             :    *
      53             :    * Return data associated with IoHandle. It is not necessarily a file descriptor.
      54             :    */
      55             :   virtual os_fd_t fdDoNotUse() const PURE;
      56             : 
      57             :   /**
      58             :    * Clean up IoHandle resources
      59             :    */
      60             :   virtual Api::IoCallUint64Result close() PURE;
      61             : 
      62             :   /**
      63             :    * Return true if close() hasn't been called.
      64             :    */
      65             :   virtual bool isOpen() const PURE;
      66             : 
      67             :   /**
      68             :    * Read data into given slices.
      69             :    * @param max_length supplies the maximum length to read.
      70             :    * @param slices points to the output location.
      71             :    * @param num_slice indicates the number of slices |slices| contains.
      72             :    * @return a Api::IoCallUint64Result with err_ = an Api::IoError instance or
      73             :    * err_ = nullptr and rc_ = the bytes read for success.
      74             :    */
      75             :   virtual Api::IoCallUint64Result readv(uint64_t max_length, Buffer::RawSlice* slices,
      76             :                                         uint64_t num_slice) PURE;
      77             : 
      78             :   /**
      79             :    * Read from a io handle directly into buffer.
      80             :    * @param buffer supplies the buffer to read into.
      81             :    * @param max_length supplies the maximum length to read. A value of absl::nullopt means to read
      82             :    *   as much data as possible, within the constraints of available buffer size.
      83             :    * @return a IoCallUint64Result with err_ = nullptr and rc_ = the number of bytes
      84             :    * read if successful, or err_ = some IoError for failure. If call failed, rc_ shouldn't be used.
      85             :    */
      86             :   virtual Api::IoCallUint64Result read(Buffer::Instance& buffer,
      87             :                                        absl::optional<uint64_t> max_length) PURE;
      88             : 
      89             :   /**
      90             :    * Write the data in slices out.
      91             :    * @param slices points to the location of data to be written.
      92             :    * @param num_slice indicates number of slices |slices| contains.
      93             :    * @return a Api::IoCallUint64Result with err_ = an Api::IoError instance or
      94             :    * err_ = nullptr and rc_ = the bytes written for success.
      95             :    */
      96             :   virtual Api::IoCallUint64Result writev(const Buffer::RawSlice* slices, uint64_t num_slice) PURE;
      97             : 
      98             :   /**
      99             :    * Write the contents of the buffer out to a file descriptor. Bytes that were successfully written
     100             :    * are drained from the buffer.
     101             :    * @param buffer supplies the buffer to write from.
     102             :    * @return a IoCallUint64Result with err_ = nullptr and rc_ = if successful, the number of bytes
     103             :    * written and drained from the buffer, or err_ = some IoError for failure. If call failed, rc_
     104             :    * shouldn't be used.
     105             :    */
     106             :   virtual Api::IoCallUint64Result write(Buffer::Instance& buffer) PURE;
     107             : 
     108             :   /**
     109             :    * Send a message to the address.
     110             :    * @param slices points to the location of data to be sent.
     111             :    * @param num_slice indicates number of slices |slices| contains.
     112             :    * @param flags flags to pass to the underlying sendmsg function (see man 2 sendmsg).
     113             :    * @param self_ip is the source address whose port should be ignored. Nullptr
     114             :    * if caller wants kernel to select source address.
     115             :    * @param peer_address is the destination address.
     116             :    * @return a Api::IoCallUint64Result with err_ = an Api::IoError instance or
     117             :    * err_ = nullptr and rc_ = the bytes written for success.
     118             :    */
     119             :   virtual Api::IoCallUint64Result sendmsg(const Buffer::RawSlice* slices, uint64_t num_slice,
     120             :                                           int flags, const Address::Ip* self_ip,
     121             :                                           const Address::Instance& peer_address) PURE;
     122             : 
     123             :   struct RecvMsgPerPacketInfo {
     124             :     // The destination address from transport header.
     125             :     Address::InstanceConstSharedPtr local_address_;
     126             :     // The source address from transport header.
     127             :     Address::InstanceConstSharedPtr peer_address_;
     128             :     // The payload length of this packet.
     129             :     unsigned int msg_len_{0};
     130             :     // The gso_size, if specified in the transport header
     131             :     unsigned int gso_size_{0};
     132             :     // If true indicates a successful syscall, but the packet was dropped due to truncation. We do
     133             :     // not support receiving truncated packets.
     134             :     bool truncated_and_dropped_{false};
     135             :   };
     136             : 
     137             :   /**
     138             :    * The output parameter type for recvmsg and recvmmsg.
     139             :    */
     140             :   struct RecvMsgOutput {
     141             :     /*
     142             :      * @param num_packets_per_call is the max number of packets allowed per
     143             :      * recvmmsg call. For recvmsg call, any value larger than 0 is allowed, but
     144             :      * only one packet will be returned.
     145             :      * @param dropped_packets points to a variable to store how many packets are
     146             :      * dropped so far. If nullptr, recvmsg() won't try to get this information
     147             :      * from transport header.
     148             :      */
     149             :     RecvMsgOutput(size_t num_packets_per_call, uint32_t* dropped_packets)
     150         504 :         : dropped_packets_(dropped_packets), msg_(num_packets_per_call) {}
     151             : 
     152             :     // If not nullptr, its value is the total number of packets dropped. recvmsg() will update it
     153             :     // when more packets are dropped.
     154             :     uint32_t* dropped_packets_;
     155             : 
     156             :     // Packet headers for each received packet. It's populated according to packet receive order.
     157             :     // Only the first entry is used to return per packet information by recvmsg.
     158             :     absl::FixedArray<RecvMsgPerPacketInfo> msg_;
     159             :   };
     160             : 
     161             :   /**
     162             :    * Receive a message into given slices, output overflow, source/destination
     163             :    * addresses via passed-in parameters upon success.
     164             :    * @param slices points to the location of receiving buffer.
     165             :    * @param num_slice indicates number of slices |slices| contains.
     166             :    * @param self_port the port this handle is assigned to. This is used to populate
     167             :    * local_address because local port can't be retrieved from control message.
     168             :    * @param output modified upon each call to return fields requested in it.
     169             :    * @return a Api::IoCallUint64Result with err_ = an Api::IoError instance or
     170             :    * err_ = nullptr and rc_ = the bytes received for success.
     171             :    */
     172             :   virtual Api::IoCallUint64Result recvmsg(Buffer::RawSlice* slices, const uint64_t num_slice,
     173             :                                           uint32_t self_port, RecvMsgOutput& output) PURE;
     174             : 
     175             :   /**
     176             :    * If the platform supports, receive multiple messages into given slices, output overflow,
     177             :    * source/destination addresses per message via passed-in parameters upon success.
     178             :    * @param slices are the receive buffers for the messages. Each message
     179             :    * received are stored in an individual entry of |slices|.
     180             :    * @param self_port is the same as the one in recvmsg().
     181             :    * @param output is modified upon each call and each message received.
     182             :    */
     183             :   virtual Api::IoCallUint64Result recvmmsg(RawSliceArrays& slices, uint32_t self_port,
     184             :                                            RecvMsgOutput& output) PURE;
     185             : 
     186             :   /**
     187             :    * Read data into given buffer for connected handles
     188             :    * @param buffer buffer to read the data into
     189             :    * @param length buffer length
     190             :    * @param flags flags to pass to the underlying recv function (see man 2 recv)
     191             :    */
     192             :   virtual Api::IoCallUint64Result recv(void* buffer, size_t length, int flags) PURE;
     193             : 
     194             :   /**
     195             :    * return true if the platform supports recvmmsg() and sendmmsg().
     196             :    */
     197             :   virtual bool supportsMmsg() const PURE;
     198             : 
     199             :   /**
     200             :    * return true if the platform supports udp_gro
     201             :    */
     202             :   virtual bool supportsUdpGro() const PURE;
     203             : 
     204             :   /**
     205             :    * Bind to address. The handle should have been created with a call to socket()
     206             :    * @param address address to bind to.
     207             :    * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
     208             :    *   is successful, errno_ shouldn't be used.
     209             :    */
     210             :   virtual Api::SysCallIntResult bind(Address::InstanceConstSharedPtr address) PURE;
     211             : 
     212             :   /**
     213             :    * Listen on bound handle.
     214             :    * @param backlog maximum number of pending connections for listener
     215             :    * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
     216             :    *   is successful, errno_ shouldn't be used.
     217             :    */
     218             :   virtual Api::SysCallIntResult listen(int backlog) PURE;
     219             : 
     220             :   /**
     221             :    * Accept on listening handle
     222             :    * @param addr remote address to be returned
     223             :    * @param addrlen remote address length
     224             :    * @return accepted IoHandlePtr
     225             :    */
     226             :   virtual std::unique_ptr<IoHandle> accept(struct sockaddr* addr, socklen_t* addrlen) PURE;
     227             : 
     228             :   /**
     229             :    * Connect to address. The handle should have been created with a call to socket()
     230             :    * on this object.
     231             :    * @param address remote address to connect to.
     232             :    * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
     233             :    *   is successful, errno_ shouldn't be used.
     234             :    */
     235             :   virtual Api::SysCallIntResult connect(Address::InstanceConstSharedPtr address) PURE;
     236             : 
     237             :   /**
     238             :    * Set option (see man 2 setsockopt)
     239             :    */
     240             :   virtual Api::SysCallIntResult setOption(int level, int optname, const void* optval,
     241             :                                           socklen_t optlen) PURE;
     242             : 
     243             :   /**
     244             :    * Get option (see man 2 getsockopt)
     245             :    */
     246             :   virtual Api::SysCallIntResult getOption(int level, int optname, void* optval,
     247             :                                           socklen_t* optlen) PURE;
     248             : 
     249             :   /**
     250             :    * @see MSDN WSAIoctl. Controls the mode of a socket.
     251             :    */
     252             :   virtual Api::SysCallIntResult ioctl(unsigned long control_code, void* in_buffer,
     253             :                                       unsigned long in_buffer_len, void* out_buffer,
     254             :                                       unsigned long out_buffer_len,
     255             :                                       unsigned long* bytes_returned) PURE;
     256             :   /**
     257             :    * Toggle blocking behavior
     258             :    * @param blocking flag to set/unset blocking state
     259             :    * @return a Api::SysCallIntResult with rc_ = 0 for success and rc_ = -1 for failure. If the call
     260             :    * is successful, errno_ shouldn't be used.
     261             :    */
     262             :   virtual Api::SysCallIntResult setBlocking(bool blocking) PURE;
     263             : 
     264             :   /**
     265             :    * @return the domain used by underlying socket (see man 2 socket)
     266             :    */
     267             :   virtual absl::optional<int> domain() PURE;
     268             : 
     269             :   /**
     270             :    * Get local address (ip:port pair)
     271             :    * @return local address as @ref Address::InstanceConstSharedPtr
     272             :    */
     273             :   virtual Address::InstanceConstSharedPtr localAddress() PURE;
     274             : 
     275             :   /**
     276             :    * Get peer's address (ip:port pair)
     277             :    * @return peer's address as @ref Address::InstanceConstSharedPtr
     278             :    */
     279             :   virtual Address::InstanceConstSharedPtr peerAddress() PURE;
     280             : 
     281             :   /**
     282             :    * Duplicates the handle. This is intended to be used only on listener sockets. (see man dup)
     283             :    * @return a pointer to the new handle.
     284             :    */
     285             :   virtual std::unique_ptr<IoHandle> duplicate() PURE;
     286             : 
     287             :   /**
     288             :    * Initializes the internal file event that will signal when the io handle is readable, writable
     289             :    * or closed. Each handle is allowed to have only a single file event. The internal file event is
     290             :    * managed by the handle and it is turned on and off when the socket would block. Calls to this
     291             :    * function must be paired with calls to reset the file event or close the socket.
     292             :    * @param dispatcher dispatcher to be used to allocate the file event.
     293             :    * @param cb supplies the callback to fire when the handle is ready.
     294             :    * @param trigger specifies whether to edge or level trigger.
     295             :    * @param events supplies a logical OR of @ref Event::FileReadyType events that the file event
     296             :    *               should initially listen on.
     297             :    */
     298             :   virtual void initializeFileEvent(Event::Dispatcher& dispatcher, Event::FileReadyCb cb,
     299             :                                    Event::FileTriggerType trigger, uint32_t events) PURE;
     300             : 
     301             :   /**
     302             :    * Activates file events for the current underlying fd.
     303             :    * @param events events that will be activated.
     304             :    */
     305             :   virtual void activateFileEvents(uint32_t events) PURE;
     306             : 
     307             :   /**
     308             :    * Enables file events for the current underlying fd.
     309             :    * @param events events that will be enabled.
     310             :    */
     311             :   virtual void enableFileEvents(uint32_t events) PURE;
     312             : 
     313             :   /**
     314             :    * Resets the file event.
     315             :    */
     316             :   virtual void resetFileEvents() PURE;
     317             : 
     318             :   /**
     319             :    * Shut down part of a full-duplex connection (see man 2 shutdown)
     320             :    */
     321             :   virtual Api::SysCallIntResult shutdown(int how) PURE;
     322             : 
     323             :   /**
     324             :    *  @return absl::optional<std::chrono::milliseconds> An optional of the most recent round-trip
     325             :    *  time of the connection. If the platform does not support this, then an empty optional is
     326             :    *  returned.
     327             :    */
     328             :   virtual absl::optional<std::chrono::milliseconds> lastRoundTripTime() PURE;
     329             : 
     330             :   /**
     331             :    * @return the current congestion window in bytes, or unset if not available or not
     332             :    * congestion-controlled.
     333             :    * @note some congestion controller's cwnd is measured in number of packets, in that case the
     334             :    * return value is cwnd(in packets) times the connection's MSS.
     335             :    */
     336             :   virtual absl::optional<uint64_t> congestionWindowInBytes() const PURE;
     337             : 
     338             :   /**
     339             :    * @return the interface name for the socket, if the OS supports it. Otherwise, absl::nullopt.
     340             :    */
     341             :   virtual absl::optional<std::string> interfaceName() PURE;
     342             : };
     343             : 
     344             : using IoHandlePtr = std::unique_ptr<IoHandle>;
     345             : 
     346             : } // namespace Network
     347             : } // namespace Envoy

Generated by: LCOV version 1.15