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