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