Line data Source code
1 : #pragma once 2 : 3 : #include <cstdint> 4 : #include <memory> 5 : 6 : #include "envoy/api/io_error.h" 7 : #include "envoy/buffer/buffer.h" 8 : #include "envoy/common/optref.h" 9 : #include "envoy/config/core/v3/extension.pb.h" 10 : #include "envoy/config/typed_config.h" 11 : #include "envoy/config/typed_metadata.h" 12 : #include "envoy/network/address.h" 13 : #include "envoy/network/socket.h" 14 : #include "envoy/stats/scope.h" 15 : #include "envoy/stats/stats_macros.h" 16 : 17 : namespace Envoy { 18 : namespace Network { 19 : 20 : /** 21 : * Max v6 packet size, excluding IP and UDP headers. 22 : */ 23 : constexpr uint64_t UdpMaxOutgoingPacketSize = 1452; 24 : 25 : /** 26 : * UdpPacketWriterBuffer bundles a buffer and a function that 27 : * releases it. 28 : */ 29 : struct UdpPacketWriterBuffer { 30 0 : UdpPacketWriterBuffer() = default; 31 : UdpPacketWriterBuffer(uint8_t* buffer, size_t length, 32 : std::function<void(const char*)> release_buffer) 33 0 : : buffer_(buffer), length_(length), release_buffer_(std::move(release_buffer)) {} 34 : 35 : uint8_t* buffer_ = nullptr; 36 : size_t length_ = 0; 37 : std::function<void(const char*)> release_buffer_; 38 : }; 39 : 40 : class UdpPacketWriter { 41 : public: 42 91 : virtual ~UdpPacketWriter() = default; 43 : 44 : /** 45 : * @brief Sends a packet via given UDP socket with specific source address. 46 : * 47 : * @param buffer points to the buffer containing the packet 48 : * @param local_ip is the source address to be used to send. If it is null, 49 : * picks up the default network interface ip address. 50 : * @param peer_address is the destination address to send to. 51 : * @return result with number of bytes written, and write status 52 : */ 53 : virtual Api::IoCallUint64Result writePacket(const Buffer::Instance& buffer, 54 : const Address::Ip* local_ip, 55 : const Address::Instance& peer_address) PURE; 56 : 57 : /** 58 : * @returns true if the network socket is not writable. 59 : */ 60 : virtual bool isWriteBlocked() const PURE; 61 : 62 : /** 63 : * @brief mark the socket as writable when the socket is unblocked. 64 : */ 65 : virtual void setWritable() PURE; 66 : 67 : /** 68 : * @brief Get the maximum size of the packet which can be written using this 69 : * writer for the supplied peer address. 70 : * 71 : * @param peer_address is the destination address to send to. 72 : * @return the max packet size 73 : */ 74 : virtual uint64_t getMaxPacketSize(const Address::Instance& peer_address) const PURE; 75 : 76 : /** 77 : * @return true if Batch Mode 78 : * @return false if PassThroughMode 79 : */ 80 : virtual bool isBatchMode() const PURE; 81 : 82 : /** 83 : * @brief Get pointer to the next write location in internal buffer, 84 : * it should be called iff the caller does not call writePacket 85 : * for the returned buffer. The caller is expected to call writePacket 86 : * with the buffer returned from this function to save a memcpy. 87 : * 88 : * @param local_ip is the source address to be used to send. 89 : * @param peer_address is the destination address to send to. 90 : * @return { char* to the next write location, 91 : * func to release buffer } 92 : */ 93 : virtual UdpPacketWriterBuffer getNextWriteLocation(const Address::Ip* local_ip, 94 : const Address::Instance& peer_address) PURE; 95 : 96 : /** 97 : * @brief Batch Mode: Try to send all buffered packets 98 : * PassThrough Mode: NULL operation 99 : * 100 : * @return Api::IoCallUint64Result 101 : */ 102 : virtual Api::IoCallUint64Result flush() PURE; 103 : }; 104 : 105 : using UdpPacketWriterPtr = std::unique_ptr<UdpPacketWriter>; 106 : 107 : class UdpPacketWriterFactory { 108 : public: 109 126 : virtual ~UdpPacketWriterFactory() = default; 110 : 111 : /** 112 : * Creates an UdpPacketWriter object for the given Udp Socket 113 : * @param socket UDP socket used to send packets. 114 : * @return the UdpPacketWriter created. 115 : */ 116 : virtual UdpPacketWriterPtr createUdpPacketWriter(Network::IoHandle& io_handle, 117 : Stats::Scope& scope) PURE; 118 : }; 119 : 120 : using UdpPacketWriterFactoryPtr = std::unique_ptr<UdpPacketWriterFactory>; 121 : 122 : /** 123 : * UdpPacketWriterFactoryFactory adds an extra layer of indirection In order to 124 : * support a UdpPacketWriterFactory whose behavior depends on the 125 : * TypedConfig for that factory. The UdpPacketWriterFactoryFactory is created 126 : * with a no-arg constructor based on the type of the config. Then this 127 : * `createUdpPacketWriterFactory1 can be called with the config to 128 : * create an actual UdpPacketWriterFactory. 129 : */ 130 : class UdpPacketWriterFactoryFactory : public Envoy::Config::TypedFactory { 131 : public: 132 0 : ~UdpPacketWriterFactoryFactory() override = default; 133 : 134 : /** 135 : * Creates an UdpPacketWriterFactory based on the specified config. 136 : * @return the UdpPacketWriterFactory created. 137 : */ 138 : virtual UdpPacketWriterFactoryPtr 139 : createUdpPacketWriterFactory(const envoy::config::core::v3::TypedExtensionConfig& config) PURE; 140 : 141 39 : std::string category() const override { return "envoy.udp_packet_writer"; } 142 : }; 143 : 144 : } // namespace Network 145 : } // namespace Envoy