blob: 04f84357dabb54a1968887f7200852cd5b4b16ac [file] [log] [blame]
wubcfddec82020-01-13 07:45:27 -08001// 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
11#include <type_traits>
12
13#include "net/third_party/quiche/src/quic/core/quic_types.h"
14#include "net/third_party/quiche/src/quic/core/quic_utils.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
17
18namespace quic {
19
20#if defined(_WIN32)
21using QuicUdpSocketFd = SOCKET;
22const QuicUdpSocketFd kQuicInvalidSocketFd = INVALID_SOCKET;
23#else
24using QuicUdpSocketFd = int;
25const QuicUdpSocketFd kQuicInvalidSocketFd = -1;
26#endif
27
wuba27a3c92020-01-28 08:43:21 -080028const size_t kDefaultUdpPacketControlBufferSize = 512;
29
wubcfddec82020-01-13 07:45:27 -080030enum class QuicUdpPacketInfoBit : uint8_t {
31 DROPPED_PACKETS = 0, // Read
32 V4_SELF_IP, // Read
33 V6_SELF_IP, // Read
34 PEER_ADDRESS, // Read & Write
35 RECV_TIMESTAMP, // Read
36 TTL, // Read & Write
37 GOOGLE_PACKET_HEADER, // Read
38 NUM_BITS,
39};
40static_assert(static_cast<size_t>(QuicUdpPacketInfoBit::NUM_BITS) <=
41 BitMask64::NumBits(),
42 "BitMask64 not wide enough to hold all bits.");
43
44// BufferSpan points to an unowned buffer, copying this structure only copies
45// the pointer and length, not the buffer itself.
46struct QUIC_EXPORT_PRIVATE BufferSpan {
47 BufferSpan(char* buffer, size_t buffer_len)
48 : buffer(buffer), buffer_len(buffer_len) {}
49
50 BufferSpan() = default;
51 BufferSpan(const BufferSpan& other) = default;
52 BufferSpan& operator=(const BufferSpan& other) = default;
53
54 char* buffer = nullptr;
55 size_t buffer_len = 0;
56};
57
58// QuicUdpPacketInfo contains per-packet information used for sending and
59// receiving.
60class QUIC_EXPORT_PRIVATE QuicUdpPacketInfo {
61 public:
62 BitMask64 bitmask() const { return bitmask_; }
63
wub1dc01cf2020-01-27 13:04:14 -080064 void Reset() { bitmask_.ClearAll(); }
65
wubcfddec82020-01-13 07:45:27 -080066 bool HasValue(QuicUdpPacketInfoBit bit) const { return bitmask_.IsSet(bit); }
67
68 QuicPacketCount dropped_packets() const {
69 DCHECK(HasValue(QuicUdpPacketInfoBit::DROPPED_PACKETS));
70 return dropped_packets_;
71 }
72
73 void SetDroppedPackets(QuicPacketCount dropped_packets) {
74 dropped_packets_ = dropped_packets;
75 bitmask_.Set(QuicUdpPacketInfoBit::DROPPED_PACKETS);
76 }
77
78 const QuicIpAddress& self_v4_ip() const {
79 DCHECK(HasValue(QuicUdpPacketInfoBit::V4_SELF_IP));
80 return self_v4_ip_;
81 }
82
83 void SetSelfV4Ip(QuicIpAddress self_v4_ip) {
84 self_v4_ip_ = self_v4_ip;
85 bitmask_.Set(QuicUdpPacketInfoBit::V4_SELF_IP);
86 }
87
88 const QuicIpAddress& self_v6_ip() const {
89 DCHECK(HasValue(QuicUdpPacketInfoBit::V6_SELF_IP));
90 return self_v6_ip_;
91 }
92
93 void SetSelfV6Ip(QuicIpAddress self_v6_ip) {
94 self_v6_ip_ = self_v6_ip;
95 bitmask_.Set(QuicUdpPacketInfoBit::V6_SELF_IP);
96 }
97
98 void SetSelfIp(QuicIpAddress self_ip) {
99 if (self_ip.IsIPv4()) {
100 SetSelfV4Ip(self_ip);
101 } else {
102 SetSelfV6Ip(self_ip);
103 }
104 }
105
106 const QuicSocketAddress& peer_address() const {
107 DCHECK(HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
108 return peer_address_;
109 }
110
111 void SetPeerAddress(QuicSocketAddress peer_address) {
112 peer_address_ = peer_address;
113 bitmask_.Set(QuicUdpPacketInfoBit::PEER_ADDRESS);
114 }
115
116 QuicWallTime receive_timestamp() const {
117 DCHECK(HasValue(QuicUdpPacketInfoBit::RECV_TIMESTAMP));
118 return receive_timestamp_;
119 }
120
121 void SetReceiveTimestamp(QuicWallTime receive_timestamp) {
122 receive_timestamp_ = receive_timestamp;
123 bitmask_.Set(QuicUdpPacketInfoBit::RECV_TIMESTAMP);
124 }
125
126 int ttl() const {
127 DCHECK(HasValue(QuicUdpPacketInfoBit::TTL));
128 return ttl_;
129 }
130
131 void SetTtl(int ttl) {
132 ttl_ = ttl;
133 bitmask_.Set(QuicUdpPacketInfoBit::TTL);
134 }
135
wub1dc01cf2020-01-27 13:04:14 -0800136 BufferSpan google_packet_headers() const {
137 DCHECK(HasValue(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER));
138 return google_packet_headers_;
139 }
140
wubcfddec82020-01-13 07:45:27 -0800141 void SetGooglePacketHeaders(BufferSpan google_packet_headers) {
142 google_packet_headers_ = google_packet_headers;
143 bitmask_.Set(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER);
144 }
145
146 private:
147 BitMask64 bitmask_;
148 QuicPacketCount dropped_packets_;
149 QuicIpAddress self_v4_ip_;
150 QuicIpAddress self_v6_ip_;
151 QuicSocketAddress peer_address_;
152 QuicWallTime receive_timestamp_ = QuicWallTime::Zero();
153 int ttl_;
154 BufferSpan google_packet_headers_;
155};
156
157// QuicUdpSocketApi provides a minimal set of apis for sending and receiving
158// udp packets. The low level udp socket apis differ between kernels and kernel
159// versions, the goal of QuicUdpSocketApi is to hide such differences.
160// We use non-static functions because it is easier to be mocked in tests when
161// needed.
162class QUIC_EXPORT_PRIVATE QuicUdpSocketApi {
163 public:
164 // Creates a non-blocking udp socket, sets the receive/send buffer and enable
165 // receiving of self ip addresses on read.
166 // Return kQuicInvalidSocketFd if failed.
167 QuicUdpSocketFd Create(int address_family,
168 int receive_buffer_size,
169 int send_buffer_size);
170
171 // Closes |fd|. No-op if |fd| equals to kQuicInvalidSocketFd.
172 void Destroy(QuicUdpSocketFd fd);
173
174 // Bind |fd| to |address|. If |address|'s port number is 0, kernel will choose
175 // a random port to bind to. Caller can use QuicSocketAddress::FromSocket(fd)
176 // to get the bound random port.
177 bool Bind(QuicUdpSocketFd fd, QuicSocketAddress address);
178
179 // Enable receiving of various per-packet information. Return true if the
180 // corresponding information can be received on read.
181 bool EnableDroppedPacketCount(QuicUdpSocketFd fd);
182 bool EnableReceiveTimestamp(QuicUdpSocketFd fd);
183 bool EnableReceiveTtlForV4(QuicUdpSocketFd fd);
184 bool EnableReceiveTtlForV6(QuicUdpSocketFd fd);
185
186 // Wait for |fd| to become readable, up to |timeout|.
187 // Return true if |fd| is readable upon return.
188 bool WaitUntilReadable(QuicUdpSocketFd fd, QuicTime::Delta timeout);
189
190 struct QUIC_EXPORT_PRIVATE ReadPacketResult {
191 bool ok = false;
192 QuicUdpPacketInfo packet_info;
193 BufferSpan packet_buffer;
194 BufferSpan control_buffer;
wub1dc01cf2020-01-27 13:04:14 -0800195
196 void Reset(size_t packet_buffer_length) {
197 ok = false;
198 packet_info.Reset();
199 packet_buffer.buffer_len = packet_buffer_length;
200 }
wubcfddec82020-01-13 07:45:27 -0800201 };
202 // Read a packet from |fd|:
203 // packet_info_interested: Bitmask indicating what information caller wants to
204 // receive into |result->packet_info|.
205 // result->packet_info: Received per packet information.
206 // result->packet_buffer: The packet buffer, to be filled with packet data.
wub1dc01cf2020-01-27 13:04:14 -0800207 // |result->packet_buffer.buffer_len| is set to the
208 // packet length on a successful return.
wubcfddec82020-01-13 07:45:27 -0800209 // result->control_buffer: The control buffer, used by ReadPacket internally.
wuba27a3c92020-01-28 08:43:21 -0800210 // It is recommended to be
211 // |kDefaultUdpPacketControlBufferSize| bytes.
wubcfddec82020-01-13 07:45:27 -0800212 // result->ok: True iff a packet is successfully received.
wub1dc01cf2020-01-27 13:04:14 -0800213 //
214 // If |*result| is reused for subsequent ReadPacket() calls, caller needs to
215 // call result->Reset() before each ReadPacket().
wubcfddec82020-01-13 07:45:27 -0800216 void ReadPacket(QuicUdpSocketFd fd,
217 BitMask64 packet_info_interested,
218 ReadPacketResult* result);
219
220 using ReadPacketResults = std::vector<ReadPacketResult>;
221 // Read up to |results->size()| packets from |fd|. The meaning of each element
222 // in |*results| has been documented on top of |ReadPacket|.
wub77cd0a32020-01-21 12:53:24 -0800223 // Return the number of elements populated into |*results|, note it is
224 // possible for some of the populated elements to have ok=false.
wubcfddec82020-01-13 07:45:27 -0800225 size_t ReadMultiplePackets(QuicUdpSocketFd fd,
226 BitMask64 packet_info_interested,
227 ReadPacketResults* results);
228
229 // Write a packet to |fd|.
230 // packet_buffer, packet_buffer_len: The packet buffer to write.
231 // packet_info: The per packet information to set.
232 WriteResult WritePacket(QuicUdpSocketFd fd,
233 const char* packet_buffer,
234 size_t packet_buffer_len,
235 const QuicUdpPacketInfo& packet_info);
236
237 protected:
238 bool SetupSocket(QuicUdpSocketFd fd,
239 int address_family,
240 int receive_buffer_size,
241 int send_buffer_size);
242 bool EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd);
243 bool EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd);
244};
245
246} // namespace quic
247
248#endif // QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_