Line data Source code
1 : #pragma once 2 : 3 : #if !defined(__linux__) || defined(__ANDROID_API__) 4 : #define UDP_GSO_BATCH_WRITER_COMPILETIME_SUPPORT 0 5 : #else 6 : #define UDP_GSO_BATCH_WRITER_COMPILETIME_SUPPORT 1 7 : 8 : #include "envoy/network/udp_packet_writer_handler.h" 9 : 10 : #include "source/common/protobuf/utility.h" 11 : #include "source/common/runtime/runtime_protos.h" 12 : 13 : #include "quiche/quic/core/batch_writer/quic_gso_batch_writer.h" 14 : 15 : namespace Envoy { 16 : namespace Quic { 17 : 18 : /** 19 : * @brief The following can be used to collect statistics 20 : * related to UdpGsoBatchWriter. The stats maintained are 21 : * as follows: 22 : * 23 : * @total_bytes_sent: Maintains the count of total bytes 24 : * sent via the UdpGsoBatchWriter on the current ioHandle 25 : * via both WritePacket() and Flush() functions. 26 : * 27 : * @internal_buffer_size: Gauge value to keep a track of the 28 : * total bytes buffered to writer by UdpGsoBatchWriter. 29 : * Resets whenever the internal bytes are sent to the client. 30 : * 31 : * @pkts_sent_per_batch: Histogram to keep maintain stats of 32 : * total number of packets sent in each batch by UdpGsoBatchWriter 33 : * Provides summary count of batch-sizes within bucketed range, 34 : * and also provides sum and count stats. 35 : * 36 : * TODO(danzh): Add writer stats to QUIC Documentation when it is 37 : * created for QUIC/HTTP3 docs. Also specify in the documentation 38 : * that user has to compile in QUICHE to use UdpGsoBatchWriter. 39 : */ 40 : #define UDP_GSO_BATCH_WRITER_STATS(COUNTER, GAUGE, HISTOGRAM) \ 41 0 : COUNTER(total_bytes_sent) \ 42 0 : GAUGE(internal_buffer_size, NeverImport) \ 43 0 : HISTOGRAM(pkts_sent_per_batch, Unspecified) 44 : 45 : /** 46 : * Wrapper struct for udp gso batch writer stats. @see stats_macros.h 47 : */ 48 : struct UdpGsoBatchWriterStats { 49 : UDP_GSO_BATCH_WRITER_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT, 50 : GENERATE_HISTOGRAM_STRUCT) 51 : }; 52 : 53 : /** 54 : * UdpPacketWriter implementation based on quic::QuicGsoBatchWriter to send packets 55 : * in batches, using UDP socket's generic segmentation offload(GSO) capability. 56 : */ 57 : class UdpGsoBatchWriter : public quic::QuicGsoBatchWriter, public Network::UdpPacketWriter { 58 : public: 59 : UdpGsoBatchWriter(Network::IoHandle& io_handle, Stats::Scope& scope); 60 : 61 : // writePacket perform batched sends based on QuicGsoBatchWriter::WritePacket 62 : Api::IoCallUint64Result writePacket(const Buffer::Instance& buffer, 63 : const Network::Address::Ip* local_ip, 64 : const Network::Address::Instance& peer_address) override; 65 : 66 : // UdpPacketWriter Implementations 67 0 : bool isWriteBlocked() const override { return IsWriteBlocked(); } 68 0 : void setWritable() override { return SetWritable(); } 69 0 : bool isBatchMode() const override { return IsBatchMode(); } 70 : uint64_t getMaxPacketSize(const Network::Address::Instance& peer_address) const override; 71 : Network::UdpPacketWriterBuffer 72 : getNextWriteLocation(const Network::Address::Ip* local_ip, 73 : const Network::Address::Instance& peer_address) override; 74 : Api::IoCallUint64Result flush() override; 75 : 76 : private: 77 : /** 78 : * @brief Update stats_ field for the udp packet writer 79 : * @param quic_result is the result from Flush/WritePacket 80 : */ 81 : void updateUdpGsoBatchWriterStats(quic::WriteResult quic_result); 82 : 83 : /** 84 : * @brief Generate UdpGsoBatchWriterStats object from scope 85 : * @param scope for stats 86 : * @return UdpGsoBatchWriterStats for scope 87 : */ 88 : UdpGsoBatchWriterStats generateStats(Stats::Scope& scope); 89 : UdpGsoBatchWriterStats stats_; 90 : uint64_t gso_size_; 91 : }; 92 : 93 : class UdpGsoBatchWriterFactory : public Network::UdpPacketWriterFactory { 94 : public: 95 : Network::UdpPacketWriterPtr createUdpPacketWriter(Network::IoHandle& io_handle, 96 : Stats::Scope& scope) override; 97 : 98 : private: 99 : envoy::config::core::v3::RuntimeFeatureFlag enabled_; 100 : }; 101 : 102 : } // namespace Quic 103 : } // namespace Envoy 104 : 105 : #endif // defined(__linux__)