xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_udp_socket.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
6 #define QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 #include <type_traits>
11 
12 #include "quiche/quic/core/io/socket.h"
13 #include "quiche/quic/core/quic_types.h"
14 #include "quiche/quic/core/quic_utils.h"
15 #include "quiche/quic/platform/api/quic_ip_address.h"
16 #include "quiche/quic/platform/api/quic_socket_address.h"
17 
18 #ifndef UDP_GRO
19 #define UDP_GRO 104
20 #endif
21 
22 namespace quic {
23 
24 using QuicUdpSocketFd = SocketFd;
25 inline constexpr QuicUdpSocketFd kQuicInvalidSocketFd = kInvalidSocketFd;
26 
27 inline constexpr size_t kDefaultUdpPacketControlBufferSize = 512;
28 
29 enum class QuicUdpPacketInfoBit : uint8_t {
30   DROPPED_PACKETS = 0,   // Read
31   V4_SELF_IP,            // Read
32   V6_SELF_IP,            // Read
33   PEER_ADDRESS,          // Read & Write
34   RECV_TIMESTAMP,        // Read
35   TTL,                   // Read & Write
36   ECN,                   // Read
37   GOOGLE_PACKET_HEADER,  // Read
38   IS_GRO,                // Read
39 
40   // Must be the last value.
41   NUM_BITS
42 };
43 using QuicUdpPacketInfoBitMask = BitMask<QuicUdpPacketInfoBit>;
44 static_assert(static_cast<size_t>(QuicUdpPacketInfoBit::NUM_BITS) <=
45                   QuicUdpPacketInfoBitMask::NumBits(),
46               "QuicUdpPacketInfoBitMask not wide enough to hold all bits.");
47 
48 // BufferSpan points to an unowned buffer, copying this structure only copies
49 // the pointer and length, not the buffer itself.
50 struct QUICHE_EXPORT BufferSpan {
BufferSpanBufferSpan51   BufferSpan(char* buffer, size_t buffer_len)
52       : buffer(buffer), buffer_len(buffer_len) {}
53 
54   BufferSpan() = default;
55   BufferSpan(const BufferSpan& other) = default;
56   BufferSpan& operator=(const BufferSpan& other) = default;
57 
58   char* buffer = nullptr;
59   size_t buffer_len = 0;
60 };
61 
62 // QuicUdpPacketInfo contains per-packet information used for sending and
63 // receiving.
64 class QUICHE_EXPORT QuicUdpPacketInfo {
65  public:
bitmask()66   QuicUdpPacketInfoBitMask bitmask() const { return bitmask_; }
67 
Reset()68   void Reset() { bitmask_.ClearAll(); }
69 
HasValue(QuicUdpPacketInfoBit bit)70   bool HasValue(QuicUdpPacketInfoBit bit) const { return bitmask_.IsSet(bit); }
71 
dropped_packets()72   QuicPacketCount dropped_packets() const {
73     QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::DROPPED_PACKETS));
74     return dropped_packets_;
75   }
76 
SetDroppedPackets(QuicPacketCount dropped_packets)77   void SetDroppedPackets(QuicPacketCount dropped_packets) {
78     dropped_packets_ = dropped_packets;
79     bitmask_.Set(QuicUdpPacketInfoBit::DROPPED_PACKETS);
80   }
81 
set_gso_size(size_t gso_size)82   void set_gso_size(size_t gso_size) {
83     gso_size_ = gso_size;
84     bitmask_.Set(QuicUdpPacketInfoBit::IS_GRO);
85   }
86 
gso_size()87   size_t gso_size() { return gso_size_; }
88 
self_v4_ip()89   const QuicIpAddress& self_v4_ip() const {
90     QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V4_SELF_IP));
91     return self_v4_ip_;
92   }
93 
SetSelfV4Ip(QuicIpAddress self_v4_ip)94   void SetSelfV4Ip(QuicIpAddress self_v4_ip) {
95     self_v4_ip_ = self_v4_ip;
96     bitmask_.Set(QuicUdpPacketInfoBit::V4_SELF_IP);
97   }
98 
self_v6_ip()99   const QuicIpAddress& self_v6_ip() const {
100     QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::V6_SELF_IP));
101     return self_v6_ip_;
102   }
103 
SetSelfV6Ip(QuicIpAddress self_v6_ip)104   void SetSelfV6Ip(QuicIpAddress self_v6_ip) {
105     self_v6_ip_ = self_v6_ip;
106     bitmask_.Set(QuicUdpPacketInfoBit::V6_SELF_IP);
107   }
108 
SetSelfIp(QuicIpAddress self_ip)109   void SetSelfIp(QuicIpAddress self_ip) {
110     if (self_ip.IsIPv4()) {
111       SetSelfV4Ip(self_ip);
112     } else {
113       SetSelfV6Ip(self_ip);
114     }
115   }
116 
peer_address()117   const QuicSocketAddress& peer_address() const {
118     QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
119     return peer_address_;
120   }
121 
SetPeerAddress(QuicSocketAddress peer_address)122   void SetPeerAddress(QuicSocketAddress peer_address) {
123     peer_address_ = peer_address;
124     bitmask_.Set(QuicUdpPacketInfoBit::PEER_ADDRESS);
125   }
126 
receive_timestamp()127   QuicWallTime receive_timestamp() const {
128     QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::RECV_TIMESTAMP));
129     return receive_timestamp_;
130   }
131 
SetReceiveTimestamp(QuicWallTime receive_timestamp)132   void SetReceiveTimestamp(QuicWallTime receive_timestamp) {
133     receive_timestamp_ = receive_timestamp;
134     bitmask_.Set(QuicUdpPacketInfoBit::RECV_TIMESTAMP);
135   }
136 
ttl()137   int ttl() const {
138     QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::TTL));
139     return ttl_;
140   }
141 
SetTtl(int ttl)142   void SetTtl(int ttl) {
143     ttl_ = ttl;
144     bitmask_.Set(QuicUdpPacketInfoBit::TTL);
145   }
146 
google_packet_headers()147   BufferSpan google_packet_headers() const {
148     QUICHE_DCHECK(HasValue(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER));
149     return google_packet_headers_;
150   }
151 
SetGooglePacketHeaders(BufferSpan google_packet_headers)152   void SetGooglePacketHeaders(BufferSpan google_packet_headers) {
153     google_packet_headers_ = google_packet_headers;
154     bitmask_.Set(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER);
155   }
156 
ecn_codepoint()157   QuicEcnCodepoint ecn_codepoint() const { return ecn_codepoint_; }
158 
SetEcnCodepoint(const QuicEcnCodepoint ecn_codepoint)159   void SetEcnCodepoint(const QuicEcnCodepoint ecn_codepoint) {
160     ecn_codepoint_ = ecn_codepoint;
161     bitmask_.Set(QuicUdpPacketInfoBit::ECN);
162   }
163 
164  private:
165   QuicUdpPacketInfoBitMask bitmask_;
166   QuicPacketCount dropped_packets_;
167   QuicIpAddress self_v4_ip_;
168   QuicIpAddress self_v6_ip_;
169   QuicSocketAddress peer_address_;
170   QuicWallTime receive_timestamp_ = QuicWallTime::Zero();
171   int ttl_;
172   BufferSpan google_packet_headers_;
173   size_t gso_size_ = 0;
174   QuicEcnCodepoint ecn_codepoint_ = ECN_NOT_ECT;
175 };
176 
177 // QuicUdpSocketApi provides a minimal set of apis for sending and receiving
178 // udp packets. The low level udp socket apis differ between kernels and kernel
179 // versions, the goal of QuicUdpSocketApi is to hide such differences.
180 // We use non-static functions because it is easier to be mocked in tests when
181 // needed.
182 class QUICHE_EXPORT QuicUdpSocketApi {
183  public:
184   // Creates a non-blocking udp socket, sets the receive/send buffer and enable
185   // receiving of self ip addresses on read.
186   // If address_family == AF_INET6 and ipv6_only is true, receiving of IPv4 self
187   // addresses is disabled. This is only necessary for IPv6 sockets on iOS - all
188   // other platforms can ignore this parameter. Return kQuicInvalidSocketFd if
189   // failed.
190   QuicUdpSocketFd Create(int address_family, int receive_buffer_size,
191                          int send_buffer_size, bool ipv6_only = false);
192 
193   // Closes |fd|. No-op if |fd| equals to kQuicInvalidSocketFd.
194   void Destroy(QuicUdpSocketFd fd);
195 
196   // Bind |fd| to |address|. If |address|'s port number is 0, kernel will choose
197   // a random port to bind to. Caller can use QuicSocketAddress::FromSocket(fd)
198   // to get the bound random port.
199   bool Bind(QuicUdpSocketFd fd, QuicSocketAddress address);
200 
201   // Bind |fd| to |interface_name|. Returns true if the setsockopt call
202   // succeeded. Returns false if |interface_name| is empty, its length exceeds
203   // IFNAMSIZ, or setsockopt experienced an error. Only implemented for
204   // non-Android Linux.
205   bool BindInterface(QuicUdpSocketFd fd, const std::string& interface_name);
206 
207   // Enable receiving of various per-packet information. Return true if the
208   // corresponding information can be received on read.
209   bool EnableDroppedPacketCount(QuicUdpSocketFd fd);
210   bool EnableReceiveTimestamp(QuicUdpSocketFd fd);
211   bool EnableReceiveTtlForV4(QuicUdpSocketFd fd);
212   bool EnableReceiveTtlForV6(QuicUdpSocketFd fd);
213 
214   // Wait for |fd| to become readable, up to |timeout|.
215   // Return true if |fd| is readable upon return.
216   bool WaitUntilReadable(QuicUdpSocketFd fd, QuicTime::Delta timeout);
217 
218   struct QUICHE_EXPORT ReadPacketResult {
219     bool ok = false;
220     QuicUdpPacketInfo packet_info;
221     BufferSpan packet_buffer;
222     BufferSpan control_buffer;
223 
ResetReadPacketResult224     void Reset(size_t packet_buffer_length) {
225       ok = false;
226       packet_info.Reset();
227       packet_buffer.buffer_len = packet_buffer_length;
228     }
229   };
230   // Read a packet from |fd|:
231   // packet_info_interested: Bitmask indicating what information caller wants to
232   //                         receive into |result->packet_info|.
233   // result->packet_info:    Received per packet information.
234   // result->packet_buffer:  The packet buffer, to be filled with packet data.
235   //                         |result->packet_buffer.buffer_len| is set to the
236   //                         packet length on a successful return.
237   // result->control_buffer: The control buffer, used by ReadPacket internally.
238   //                         It is recommended to be
239   //                         |kDefaultUdpPacketControlBufferSize| bytes.
240   // result->ok:             True iff a packet is successfully received.
241   //
242   // If |*result| is reused for subsequent ReadPacket() calls, caller needs to
243   // call result->Reset() before each ReadPacket().
244   void ReadPacket(QuicUdpSocketFd fd,
245                   QuicUdpPacketInfoBitMask packet_info_interested,
246                   ReadPacketResult* result);
247 
248   using ReadPacketResults = std::vector<ReadPacketResult>;
249   // Read up to |results->size()| packets from |fd|. The meaning of each element
250   // in |*results| has been documented on top of |ReadPacket|.
251   // Return the number of elements populated into |*results|, note it is
252   // possible for some of the populated elements to have ok=false.
253   size_t ReadMultiplePackets(QuicUdpSocketFd fd,
254                              QuicUdpPacketInfoBitMask packet_info_interested,
255                              ReadPacketResults* results);
256 
257   // Write a packet to |fd|.
258   // packet_buffer, packet_buffer_len:  The packet buffer to write.
259   // packet_info:                       The per packet information to set.
260   WriteResult WritePacket(QuicUdpSocketFd fd, const char* packet_buffer,
261                           size_t packet_buffer_len,
262                           const QuicUdpPacketInfo& packet_info);
263 
264  protected:
265   bool SetupSocket(QuicUdpSocketFd fd, int address_family,
266                    int receive_buffer_size, int send_buffer_size,
267                    bool ipv6_only);
268   bool EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd);
269   bool EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd);
270 };
271 
272 }  // namespace quic
273 
274 #endif  // QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
275