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
1148
  COUNTER(total_bytes_sent)                                                                        \
42
1148
  GAUGE(internal_buffer_size, NeverImport)                                                         \
43
1148
  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
7
  bool isWriteBlocked() const override { return IsWriteBlocked(); }
68
2
  void setWritable() override { return SetWritable(); }
69
4
  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
96
  createUdpPacketWriter(Network::IoHandle& io_handle, Stats::Scope& scope,
97
                        Envoy::Event::Dispatcher& dispatcher,
98
                        absl::AnyInvocable<void() &&> on_can_write_cb) override;
99

            
100
private:
101
  envoy::config::core::v3::RuntimeFeatureFlag enabled_;
102
};
103

            
104
} // namespace Quic
105
} // namespace Envoy
106

            
107
#endif // defined(__linux__)