@fails-components/webtransport 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,630 +21,712 @@
21
21
  #if defined(__linux__) && !defined(__ANDROID__)
22
22
  #define QUIC_UDP_SOCKET_SUPPORT_TTL 1
23
23
  #endif
24
- namespace quic {
25
- namespace {
24
+ namespace quic
25
+ {
26
+ namespace
27
+ {
26
28
 
27
29
  #if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
28
30
  #define QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING 1
29
- // This is the structure that SO_TIMESTAMPING fills into the cmsg header.
30
- // It is well-defined, but does not have a definition in a public header.
31
- // See https://www.kernel.org/doc/Documentation/networking/timestamping.txt
32
- // for more information.
33
- struct LinuxSoTimestamping {
34
- // The converted system time of the timestamp.
35
- struct timespec systime;
36
- // Deprecated; serves only as padding.
37
- struct timespec hwtimetrans;
38
- // The raw hardware timestamp.
39
- struct timespec hwtimeraw;
40
- };
41
- const size_t kCmsgSpaceForRecvTimestamp =
42
- CMSG_SPACE(sizeof(LinuxSoTimestamping));
31
+ // This is the structure that SO_TIMESTAMPING fills into the cmsg header.
32
+ // It is well-defined, but does not have a definition in a public header.
33
+ // See https://www.kernel.org/doc/Documentation/networking/timestamping.txt
34
+ // for more information.
35
+ struct LinuxSoTimestamping
36
+ {
37
+ // The converted system time of the timestamp.
38
+ struct timespec systime;
39
+ // Deprecated; serves only as padding.
40
+ struct timespec hwtimetrans;
41
+ // The raw hardware timestamp.
42
+ struct timespec hwtimeraw;
43
+ };
44
+ const size_t kCmsgSpaceForRecvTimestamp =
45
+ CMSG_SPACE(sizeof(LinuxSoTimestamping));
43
46
  #else
44
- const size_t kCmsgSpaceForRecvTimestamp = 0;
47
+ const size_t kCmsgSpaceForRecvTimestamp = 0;
45
48
  #endif
46
49
 
47
- const size_t kMinCmsgSpaceForRead =
48
- CMSG_SPACE(sizeof(uint32_t)) // Dropped packet count
49
- + CMSG_SPACE(sizeof(in_pktinfo)) // V4 Self IP
50
- + CMSG_SPACE(sizeof(in6_pktinfo)) // V6 Self IP
51
- + kCmsgSpaceForRecvTimestamp + CMSG_SPACE(sizeof(int)) // TTL
52
- + kCmsgSpaceForGooglePacketHeader;
53
-
54
- void SetV4SelfIpInControlMessage(const QuicIpAddress& self_address,
55
- cmsghdr* cmsg) {
56
- QUICHE_DCHECK(self_address.IsIPv4());
57
- in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(WSA_CMSG_DATA(cmsg));
58
- memset(pktinfo, 0, sizeof(in_pktinfo));
59
- pktinfo->ipi_ifindex = 0;
60
- std::string address_string = self_address.ToPackedString();
61
- memcpy(&pktinfo->ipi_addr, address_string.c_str(),
62
- address_string.length());
63
- }
64
-
65
- void SetV6SelfIpInControlMessage(const QuicIpAddress& self_address,
66
- cmsghdr* cmsg) {
67
- QUICHE_DCHECK(self_address.IsIPv6());
68
- in6_pktinfo* pktinfo = reinterpret_cast<in6_pktinfo*>(WSA_CMSG_DATA(cmsg));
69
- memset(pktinfo, 0, sizeof(in6_pktinfo));
70
- std::string address_string = self_address.ToPackedString();
71
- memcpy(&pktinfo->ipi6_addr, address_string.c_str(), address_string.length());
72
- }
73
-
74
- void PopulatePacketInfoFromControlMessage(struct cmsghdr* cmsg,
75
- QuicUdpPacketInfo* packet_info,
76
- BitMask64 packet_info_interested) {
77
- #if defined(__linux__) && defined(SO_RXQ_OVFL)
78
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL) {
79
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::DROPPED_PACKETS)) {
80
- packet_info->SetDroppedPackets(
81
- *(reinterpret_cast<uint32_t*> WSA_CMSG_DATA(cmsg)));
50
+ const size_t kMinCmsgSpaceForRead =
51
+ CMSG_SPACE(sizeof(uint32_t)) // Dropped packet count
52
+ + CMSG_SPACE(sizeof(in_pktinfo)) // V4 Self IP
53
+ + CMSG_SPACE(sizeof(in6_pktinfo)) // V6 Self IP
54
+ + kCmsgSpaceForRecvTimestamp + CMSG_SPACE(sizeof(int)) // TTL
55
+ + kCmsgSpaceForGooglePacketHeader;
56
+
57
+ void SetV4SelfIpInControlMessage(const QuicIpAddress &self_address,
58
+ cmsghdr *cmsg)
59
+ {
60
+ QUICHE_DCHECK(self_address.IsIPv4());
61
+ in_pktinfo *pktinfo = reinterpret_cast<in_pktinfo *>(WSA_CMSG_DATA(cmsg));
62
+ memset(pktinfo, 0, sizeof(in_pktinfo));
63
+ pktinfo->ipi_ifindex = 0;
64
+ std::string address_string = self_address.ToPackedString();
65
+ memcpy(&pktinfo->ipi_addr, address_string.c_str(),
66
+ address_string.length());
82
67
  }
83
- return;
84
- }
68
+
69
+ void SetV6SelfIpInControlMessage(const QuicIpAddress &self_address,
70
+ cmsghdr *cmsg)
71
+ {
72
+ QUICHE_DCHECK(self_address.IsIPv6());
73
+ in6_pktinfo *pktinfo = reinterpret_cast<in6_pktinfo *>(WSA_CMSG_DATA(cmsg));
74
+ memset(pktinfo, 0, sizeof(in6_pktinfo));
75
+ std::string address_string = self_address.ToPackedString();
76
+ memcpy(&pktinfo->ipi6_addr, address_string.c_str(), address_string.length());
77
+ }
78
+
79
+ void PopulatePacketInfoFromControlMessage(struct cmsghdr *cmsg,
80
+ QuicUdpPacketInfo *packet_info,
81
+ BitMask64 packet_info_interested)
82
+ {
83
+ #if defined(__linux__) && defined(SO_RXQ_OVFL)
84
+ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
85
+ {
86
+ if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::DROPPED_PACKETS))
87
+ {
88
+ packet_info->SetDroppedPackets(
89
+ *(reinterpret_cast<uint32_t *> WSA_CMSG_DATA(cmsg)));
90
+ }
91
+ return;
92
+ }
85
93
  #endif
86
94
 
87
95
  #if defined(QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING)
88
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPING) {
89
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::RECV_TIMESTAMP)) {
90
- LinuxSoTimestamping* linux_ts =
91
- reinterpret_cast<LinuxSoTimestamping*>(WSA_CMSG_DATA(cmsg));
92
- timespec* ts = &linux_ts->systime;
93
- int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) +
94
- (static_cast<int64_t>(ts->tv_nsec) / 1000);
95
- packet_info->SetReceiveTimestamp(
96
- QuicWallTime::FromUNIXMicroseconds(usec));
97
- }
98
- return;
99
- }
96
+ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPING)
97
+ {
98
+ if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::RECV_TIMESTAMP))
99
+ {
100
+ LinuxSoTimestamping *linux_ts =
101
+ reinterpret_cast<LinuxSoTimestamping *>(WSA_CMSG_DATA(cmsg));
102
+ timespec *ts = &linux_ts->systime;
103
+ int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) +
104
+ (static_cast<int64_t>(ts->tv_nsec) / 1000);
105
+ packet_info->SetReceiveTimestamp(
106
+ QuicWallTime::FromUNIXMicroseconds(usec));
107
+ }
108
+ return;
109
+ }
100
110
  #endif
101
111
 
102
- if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
103
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V6_SELF_IP)) {
104
- const in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>(WSA_CMSG_DATA(cmsg));
105
- const char* addr_data = reinterpret_cast<const char*>(&info->ipi6_addr);
106
- int addr_len = sizeof(in6_addr);
107
- QuicIpAddress self_v6_ip;
108
- if (self_v6_ip.FromPackedString(addr_data, addr_len)) {
109
- packet_info->SetSelfV6Ip(self_v6_ip);
110
- } else {
111
- QUIC_BUG(quic_bug_10751_1) << "QuicIpAddress::FromPackedString failed";
112
+ if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO)
113
+ {
114
+ if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V6_SELF_IP))
115
+ {
116
+ const in6_pktinfo *info = reinterpret_cast<in6_pktinfo *>(WSA_CMSG_DATA(cmsg));
117
+ const char *addr_data = reinterpret_cast<const char *>(&info->ipi6_addr);
118
+ int addr_len = sizeof(in6_addr);
119
+ QuicIpAddress self_v6_ip;
120
+ if (self_v6_ip.FromPackedString(addr_data, addr_len))
121
+ {
122
+ packet_info->SetSelfV6Ip(self_v6_ip);
123
+ }
124
+ else
125
+ {
126
+ QUIC_BUG(quic_bug_10751_1) << "QuicIpAddress::FromPackedString failed";
127
+ }
128
+ }
129
+ return;
112
130
  }
113
- }
114
- return;
115
- }
116
131
 
117
- if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
118
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V4_SELF_IP)) {
119
- const in_pktinfo* info = reinterpret_cast<in_pktinfo*>(WSA_CMSG_DATA(cmsg));
120
- const char* addr_data = reinterpret_cast<const char*>(&info->ipi_addr);
121
- int addr_len = sizeof(in_addr);
122
- QuicIpAddress self_v4_ip;
123
- if (self_v4_ip.FromPackedString(addr_data, addr_len)) {
124
- packet_info->SetSelfV4Ip(self_v4_ip);
125
- } else {
126
- QUIC_BUG(quic_bug_10751_2) << "QuicIpAddress::FromPackedString failed";
132
+ if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
133
+ {
134
+ if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::V4_SELF_IP))
135
+ {
136
+ const in_pktinfo *info = reinterpret_cast<in_pktinfo *>(WSA_CMSG_DATA(cmsg));
137
+ const char *addr_data = reinterpret_cast<const char *>(&info->ipi_addr);
138
+ int addr_len = sizeof(in_addr);
139
+ QuicIpAddress self_v4_ip;
140
+ if (self_v4_ip.FromPackedString(addr_data, addr_len))
141
+ {
142
+ packet_info->SetSelfV4Ip(self_v4_ip);
143
+ }
144
+ else
145
+ {
146
+ QUIC_BUG(quic_bug_10751_2) << "QuicIpAddress::FromPackedString failed";
147
+ }
148
+ }
149
+ return;
127
150
  }
128
- }
129
- return;
130
- }
131
151
 
132
- if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
133
- (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT)) {
134
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::TTL)) {
135
- packet_info->SetTtl(*(reinterpret_cast<int*>(WSA_CMSG_DATA(cmsg))));
136
- }
137
- return;
138
- }
152
+ if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) ||
153
+ (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_HOPLIMIT))
154
+ {
155
+ if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::TTL))
156
+ {
157
+ packet_info->SetTtl(*(reinterpret_cast<int *>(WSA_CMSG_DATA(cmsg))));
158
+ }
159
+ return;
160
+ }
139
161
 
140
- if (packet_info_interested.IsSet(
141
- QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
142
- BufferSpan google_packet_headers;
143
- if (GetGooglePacketHeadersFromControlMessage(
144
- cmsg, &google_packet_headers.buffer,
145
- &google_packet_headers.buffer_len)) {
146
- packet_info->SetGooglePacketHeaders(google_packet_headers);
162
+ if (packet_info_interested.IsSet(
163
+ QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER))
164
+ {
165
+ BufferSpan google_packet_headers;
166
+ if (GetGooglePacketHeadersFromControlMessage(
167
+ cmsg, &google_packet_headers.buffer,
168
+ &google_packet_headers.buffer_len))
169
+ {
170
+ packet_info->SetGooglePacketHeaders(google_packet_headers);
171
+ }
172
+ }
147
173
  }
148
- }
149
- }
150
-
151
- bool NextCmsg(WSAMSG* hdr, char* control_buffer, size_t control_buffer_len,
152
- int cmsg_level, int cmsg_type, size_t data_size,
153
- cmsghdr** cmsg /*in, out*/) {
154
- // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
155
- // return nullptr.
156
- hdr->Control.len += CMSG_SPACE(data_size);
157
- if (hdr->Control.len > control_buffer_len) {
158
- return false;
159
- }
160
-
161
- if ((*cmsg) == nullptr) {
162
- QUICHE_DCHECK_EQ(nullptr, hdr->Control.buf);
163
- memset(control_buffer, 0, control_buffer_len);
164
- hdr->Control.buf = control_buffer;
165
- (*cmsg) = CMSG_FIRSTHDR(hdr);
166
- } else {
167
- QUICHE_DCHECK_NE(nullptr, hdr->Control.buf);
168
- (*cmsg) = CMSG_NXTHDR(hdr, (*cmsg));
169
- }
170
174
 
171
- if (nullptr == (*cmsg)) {
172
- return false;
173
- }
175
+ bool NextCmsg(WSAMSG *hdr, char *control_buffer, size_t control_buffer_len,
176
+ int cmsg_level, int cmsg_type, size_t data_size,
177
+ cmsghdr **cmsg /*in, out*/)
178
+ {
179
+ // msg_controllen needs to be increased first, otherwise CMSG_NXTHDR will
180
+ // return nullptr.
181
+ hdr->Control.len += CMSG_SPACE(data_size);
182
+ if (hdr->Control.len > control_buffer_len)
183
+ {
184
+ return false;
185
+ }
174
186
 
175
- (*cmsg)->cmsg_len = CMSG_LEN(data_size);
176
- (*cmsg)->cmsg_level = cmsg_level;
177
- (*cmsg)->cmsg_type = cmsg_type;
187
+ if ((*cmsg) == nullptr)
188
+ {
189
+ QUICHE_DCHECK_EQ(nullptr, hdr->Control.buf);
190
+ memset(control_buffer, 0, control_buffer_len);
191
+ hdr->Control.buf = control_buffer;
192
+ (*cmsg) = CMSG_FIRSTHDR(hdr);
193
+ }
194
+ else
195
+ {
196
+ QUICHE_DCHECK_NE(nullptr, hdr->Control.buf);
197
+ (*cmsg) = CMSG_NXTHDR(hdr, (*cmsg));
198
+ }
178
199
 
179
- return true;
180
- }
181
- } // namespace
200
+ if (nullptr == (*cmsg))
201
+ {
202
+ return false;
203
+ }
182
204
 
205
+ (*cmsg)->cmsg_len = CMSG_LEN(data_size);
206
+ (*cmsg)->cmsg_level = cmsg_level;
207
+ (*cmsg)->cmsg_type = cmsg_type;
183
208
 
184
- LPFN_WSARECVMSG WSARecvMsg = nullptr;
185
- LPFN_WSASENDMSG WSASendMsg = nullptr;
209
+ return true;
210
+ }
211
+ } // namespace
186
212
 
187
- WSADATA WSAData;
213
+ LPFN_WSARECVMSG WSARecvMsg = nullptr;
214
+ LPFN_WSASENDMSG WSASendMsg = nullptr;
188
215
 
189
- bool initSockets()
190
- {
191
- int res;
216
+ WSADATA WSAData;
192
217
 
193
- // Initialize Winsock
194
- res = WSAStartup(MAKEWORD(2, 2), &WSAData);
195
- if (res != 0)
218
+ bool initSockets()
196
219
  {
197
- QUIC_LOG_FIRST_N(ERROR, 100)
198
- << "WSAStartup failed: %d\n"
199
- << res;
200
- return false;
201
- }
220
+ int res;
202
221
 
203
- SOCKET sock = INVALID_SOCKET;
204
- sock = socket(AF_INET, SOCK_DGRAM, 0);
222
+ // Initialize Winsock
223
+ res = WSAStartup(MAKEWORD(2, 2), &WSAData);
224
+ if (res != 0)
225
+ {
226
+ QUIC_LOG_FIRST_N(ERROR, 100)
227
+ << "WSAStartup failed: %d\n"
228
+ << res;
229
+ return false;
230
+ }
205
231
 
206
- // should we buffer this somewhere? Does it take time...
207
- GUID grv = WSAID_WSARECVMSG;
208
- DWORD dwBytesReturned = 0;
209
- if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &grv, sizeof(grv), &WSARecvMsg, sizeof(WSARecvMsg),
210
- &dwBytesReturned, NULL, NULL) != 0)
211
- {
212
- QUIC_LOG_FIRST_N(ERROR, 100)
213
- << "WSARecvMsg is not available ";
214
- return false;
215
- }
232
+ SOCKET sock = INVALID_SOCKET;
233
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
216
234
 
217
- // should we buffer this somewhere? Does it take time...
218
- GUID gsnd = WSAID_WSASENDMSG;
219
- if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &gsnd, sizeof(gsnd), &WSASendMsg, sizeof(WSASendMsg),
220
- &dwBytesReturned, NULL, NULL) != 0)
221
- {
222
- QUIC_LOG_FIRST_N(ERROR, 100)
223
- << "WSASendMsg is not available ";
224
- return false;
225
- }
226
- closesocket(sock);
227
- return true;
228
- }
235
+ // should we buffer this somewhere? Does it take time...
236
+ GUID grv = WSAID_WSARECVMSG;
237
+ DWORD dwBytesReturned = 0;
238
+ if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &grv, sizeof(grv), &WSARecvMsg, sizeof(WSARecvMsg),
239
+ &dwBytesReturned, NULL, NULL) != 0)
240
+ {
241
+ QUIC_LOG_FIRST_N(ERROR, 100)
242
+ << "WSARecvMsg is not available ";
243
+ return false;
244
+ }
229
245
 
230
- bool destroySockets()
231
- {
232
- WSACleanup();
233
- return true;
234
- }
235
-
236
- QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
237
- int receive_buffer_size,
238
- int send_buffer_size, bool ipv6_only) {
239
- // QUICHE_DCHECK here so the program exits early(before reading packets) in
240
- // debug mode. This should have been a static_assert, however it can't be done
241
- // on ios/osx because CMSG_SPACE isn't a constant expression there.
242
- QUICHE_DCHECK_GE(kDefaultUdpPacketControlBufferSize, kMinCmsgSpaceForRead);
243
-
244
- absl::StatusOr<SocketFd> socket =
245
- socket_api::CreateSocket(FromPlatformAddressFamily(address_family),
246
- socket_api::SocketProtocol::kUdp,
247
- /*blocking=*/false);
248
-
249
- if (!socket.ok()) {
250
- QUIC_LOG_FIRST_N(ERROR, 100)
251
- << "UDP non-blocking socket creation for address_family="
252
- << address_family << " failed: " << socket.status();
253
- return kQuicInvalidSocketFd;
246
+ // should we buffer this somewhere? Does it take time...
247
+ GUID gsnd = WSAID_WSASENDMSG;
248
+ if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &gsnd, sizeof(gsnd), &WSASendMsg, sizeof(WSASendMsg),
249
+ &dwBytesReturned, NULL, NULL) != 0)
250
+ {
251
+ QUIC_LOG_FIRST_N(ERROR, 100)
252
+ << "WSASendMsg is not available ";
253
+ return false;
254
+ }
255
+ closesocket(sock);
256
+ return true;
254
257
  }
255
258
 
256
- SetGoogleSocketOptions(socket.value());
257
-
258
- if (!SetupSocket(socket.value(), address_family, receive_buffer_size,
259
- send_buffer_size, ipv6_only)) {
260
- Destroy(socket.value());
261
- return kQuicInvalidSocketFd;
259
+ bool destroySockets()
260
+ {
261
+ WSACleanup();
262
+ return true;
262
263
  }
263
264
 
264
- return socket.value();
265
- }
265
+ QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
266
+ int receive_buffer_size,
267
+ int send_buffer_size, bool ipv6_only)
268
+ {
269
+ // QUICHE_DCHECK here so the program exits early(before reading packets) in
270
+ // debug mode. This should have been a static_assert, however it can't be done
271
+ // on ios/osx because CMSG_SPACE isn't a constant expression there.
272
+ QUICHE_DCHECK_GE(kDefaultUdpPacketControlBufferSize, kMinCmsgSpaceForRead);
273
+
274
+ absl::StatusOr<SocketFd> socket =
275
+ socket_api::CreateSocket(quiche::FromPlatformAddressFamily(address_family),
276
+ socket_api::SocketProtocol::kUdp,
277
+ /*blocking=*/false);
278
+
279
+ if (!socket.ok())
280
+ {
281
+ QUIC_LOG_FIRST_N(ERROR, 100)
282
+ << "UDP non-blocking socket creation for address_family="
283
+ << address_family << " failed: " << socket.status();
284
+ return kQuicInvalidSocketFd;
285
+ }
266
286
 
267
- bool QuicUdpSocketApi::SetupSocket(QuicUdpSocketFd fd, int address_family,
268
- int receive_buffer_size,
269
- int send_buffer_size, bool ipv6_only) {
270
- // Receive buffer size.
271
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<const char*>(&receive_buffer_size),
272
- sizeof(receive_buffer_size)) != 0) {
273
- QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket recv size";
274
- return false;
275
- }
287
+ SetGoogleSocketOptions(socket.value());
276
288
 
277
- // Send buffer size.
278
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const char*>(&send_buffer_size),
279
- sizeof(send_buffer_size)) != 0) {
280
- QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket send size";
281
- return false;
289
+ if (!SetupSocket(socket.value(), address_family, receive_buffer_size,
290
+ send_buffer_size, ipv6_only))
291
+ {
292
+ Destroy(socket.value());
293
+ return kQuicInvalidSocketFd;
294
+ }
295
+
296
+ return socket.value();
282
297
  }
283
298
 
284
- if (!(address_family == AF_INET6 && ipv6_only)) {
285
- if (!EnableReceiveSelfIpAddressForV4(fd)) {
286
- QUIC_LOG_FIRST_N(ERROR, 100)
287
- << "Failed to enable receiving of self v4 ip";
299
+ bool QuicUdpSocketApi::SetupSocket(QuicUdpSocketFd fd, int address_family,
300
+ int receive_buffer_size,
301
+ int send_buffer_size, bool ipv6_only)
302
+ {
303
+ // Receive buffer size.
304
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<const char *>(&receive_buffer_size),
305
+ sizeof(receive_buffer_size)) != 0)
306
+ {
307
+ QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket recv size";
288
308
  return false;
289
309
  }
290
- }
291
310
 
292
- if (address_family == AF_INET6) {
293
- if (!EnableReceiveSelfIpAddressForV6(fd)) {
294
- QUIC_LOG_FIRST_N(ERROR, 100)
295
- << "Failed to enable receiving of self v6 ip";
311
+ // Send buffer size.
312
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const char *>(&send_buffer_size),
313
+ sizeof(send_buffer_size)) != 0)
314
+ {
315
+ QUIC_LOG_FIRST_N(ERROR, 100) << "Failed to set socket send size";
296
316
  return false;
297
317
  }
298
- }
299
318
 
300
- return true;
301
- }
319
+ if (!(address_family == AF_INET6 && ipv6_only))
320
+ {
321
+ if (!EnableReceiveSelfIpAddressForV4(fd))
322
+ {
323
+ QUIC_LOG_FIRST_N(ERROR, 100)
324
+ << "Failed to enable receiving of self v4 ip";
325
+ return false;
326
+ }
327
+ }
302
328
 
303
- void QuicUdpSocketApi::Destroy(QuicUdpSocketFd fd) {
304
- if (fd != kQuicInvalidSocketFd) {
305
- absl::Status result = socket_api::Close(fd);
306
- if (!result.ok()) {
307
- QUIC_LOG_FIRST_N(WARNING, 100)
308
- << "Failed to close UDP socket with error " << result;
329
+ if (address_family == AF_INET6)
330
+ {
331
+ if (!EnableReceiveSelfIpAddressForV6(fd))
332
+ {
333
+ QUIC_LOG_FIRST_N(ERROR, 100)
334
+ << "Failed to enable receiving of self v6 ip";
335
+ return false;
336
+ }
309
337
  }
338
+
339
+ return true;
310
340
  }
311
- }
312
341
 
313
- bool QuicUdpSocketApi::Bind(QuicUdpSocketFd fd, QuicSocketAddress address) {
314
- sockaddr_storage addr = address.generic_address();
315
- int addr_len =
316
- address.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
317
- return 0 == bind(fd, reinterpret_cast<sockaddr*>(&addr), addr_len);
318
- }
342
+ void QuicUdpSocketApi::Destroy(QuicUdpSocketFd fd)
343
+ {
344
+ if (fd != kQuicInvalidSocketFd)
345
+ {
346
+ absl::Status result = socket_api::Close(fd);
347
+ if (!result.ok())
348
+ {
349
+ QUIC_LOG_FIRST_N(WARNING, 100)
350
+ << "Failed to close UDP socket with error " << result;
351
+ }
352
+ }
353
+ }
354
+
355
+ bool QuicUdpSocketApi::Bind(QuicUdpSocketFd fd, QuicSocketAddress address)
356
+ {
357
+ sockaddr_storage addr = address.generic_address();
358
+ int addr_len =
359
+ address.host().IsIPv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
360
+ return 0 == bind(fd, reinterpret_cast<sockaddr *>(&addr), addr_len);
361
+ }
319
362
 
320
- bool QuicUdpSocketApi::EnableDroppedPacketCount(QuicUdpSocketFd fd) {
363
+ bool QuicUdpSocketApi::EnableDroppedPacketCount(QuicUdpSocketFd fd)
364
+ {
321
365
  #if defined(__linux__) && defined(SO_RXQ_OVFL)
322
- int get_overflow = 1;
323
- return 0 == setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
324
- sizeof(get_overflow));
366
+ int get_overflow = 1;
367
+ return 0 == setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow,
368
+ sizeof(get_overflow));
325
369
  #else
326
- (void)fd;
327
- return false;
370
+ (void)fd;
371
+ return false;
328
372
  #endif
329
- }
330
-
331
- bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd) {
332
- int get_self_ip = 1;
333
- return 0 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, reinterpret_cast<const char*>(&get_self_ip),
334
- sizeof(get_self_ip));
335
- }
336
-
337
- bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd) {
338
- int get_self_ip = 1;
339
- // was IPV6_RECVPKTINFO
340
- return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, reinterpret_cast<const char*>(&get_self_ip),
341
- sizeof(get_self_ip));
342
- }
343
-
344
- bool QuicUdpSocketApi::EnableReceiveTimestamp(QuicUdpSocketFd fd) {
373
+ }
374
+
375
+ bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd)
376
+ {
377
+ int get_self_ip = 1;
378
+ return 0 == setsockopt(fd, IPPROTO_IP, IP_PKTINFO, reinterpret_cast<const char *>(&get_self_ip),
379
+ sizeof(get_self_ip));
380
+ }
381
+
382
+ bool QuicUdpSocketApi::EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd)
383
+ {
384
+ int get_self_ip = 1;
385
+ // was IPV6_RECVPKTINFO
386
+ return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, reinterpret_cast<const char *>(&get_self_ip),
387
+ sizeof(get_self_ip));
388
+ }
389
+
390
+ bool QuicUdpSocketApi::EnableReceiveTimestamp(QuicUdpSocketFd fd)
391
+ {
345
392
  #if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
346
- int timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
347
- return 0 == setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &timestamping,
348
- sizeof(timestamping));
393
+ int timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
394
+ return 0 == setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &timestamping,
395
+ sizeof(timestamping));
349
396
  #else
350
- (void)fd;
351
- return false;
397
+ (void)fd;
398
+ return false;
352
399
  #endif
353
- }
400
+ }
354
401
 
355
- bool QuicUdpSocketApi::EnableReceiveTtlForV4(QuicUdpSocketFd fd) {
402
+ bool QuicUdpSocketApi::EnableReceiveTtlForV4(QuicUdpSocketFd fd)
403
+ {
356
404
  #if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
357
- int get_ttl = 1;
358
- return 0 == setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &get_ttl, sizeof(get_ttl));
405
+ int get_ttl = 1;
406
+ return 0 == setsockopt(fd, IPPROTO_IP, IP_RECVTTL, &get_ttl, sizeof(get_ttl));
359
407
  #else
360
- (void)fd;
361
- return false;
408
+ (void)fd;
409
+ return false;
362
410
  #endif
363
- }
411
+ }
364
412
 
365
- bool QuicUdpSocketApi::EnableReceiveTtlForV6(QuicUdpSocketFd fd) {
413
+ bool QuicUdpSocketApi::EnableReceiveTtlForV6(QuicUdpSocketFd fd)
414
+ {
366
415
  #if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
367
- int get_ttl = 1;
368
- return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &get_ttl,
369
- sizeof(get_ttl));
416
+ int get_ttl = 1;
417
+ return 0 == setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &get_ttl,
418
+ sizeof(get_ttl));
370
419
  #else
371
- (void)fd;
372
- return false;
420
+ (void)fd;
421
+ return false;
373
422
  #endif
374
- }
375
-
376
- bool QuicUdpSocketApi::WaitUntilReadable(QuicUdpSocketFd fd,
377
- QuicTime::Delta timeout) {
378
- fd_set read_fds;
379
- FD_ZERO(&read_fds);
380
- FD_SET(fd, &read_fds);
381
-
382
- timeval select_timeout;
383
- select_timeout.tv_sec = timeout.ToSeconds();
384
- select_timeout.tv_usec = timeout.ToMicroseconds() % 1000000;
385
-
386
- return 1 == select(1 + fd, &read_fds, nullptr, nullptr, &select_timeout);
387
- }
388
-
389
- void QuicUdpSocketApi::ReadPacket(QuicUdpSocketFd fd,
390
- BitMask64 packet_info_interested,
391
- ReadPacketResult* result) {
392
- result->ok = false;
393
- BufferSpan& packet_buffer = result->packet_buffer;
394
- BufferSpan& control_buffer = result->control_buffer;
395
- QuicUdpPacketInfo* packet_info = &result->packet_info;
396
-
397
- QUICHE_DCHECK_GE(control_buffer.buffer_len, kMinCmsgSpaceForRead);
398
-
399
- ULONG bufferlen = packet_buffer.buffer_len;
400
- WSABUF iov = { bufferlen, const_cast<char*>(packet_buffer.buffer)};
401
- struct sockaddr_storage raw_peer_address;
402
-
403
- if (control_buffer.buffer_len > 0) {
404
- reinterpret_cast<struct cmsghdr*>(control_buffer.buffer)->cmsg_len =
405
- control_buffer.buffer_len;
406
423
  }
407
424
 
408
- WSAMSG hdr;
409
- hdr.name = reinterpret_cast<LPSOCKADDR> (&raw_peer_address);
410
- hdr.namelen = sizeof(raw_peer_address);
411
- hdr.lpBuffers = &iov;
412
- hdr.dwBufferCount = 1;
413
- hdr.dwFlags = 0;
414
- hdr.Control.buf = control_buffer.buffer;
415
- hdr.Control.len = control_buffer.buffer_len;
416
-
417
-
425
+ bool QuicUdpSocketApi::WaitUntilReadable(QuicUdpSocketFd fd,
426
+ QuicTime::Delta timeout)
427
+ {
428
+ fd_set read_fds;
429
+ FD_ZERO(&read_fds);
430
+ FD_SET(fd, &read_fds);
418
431
 
419
- DWORD bytes_read = 0;
432
+ timeval select_timeout;
433
+ select_timeout.tv_sec = timeout.ToSeconds();
434
+ select_timeout.tv_usec = timeout.ToMicroseconds() % 1000000;
420
435
 
421
- int ret = WSARecvMsg(fd, &hdr, &bytes_read, nullptr, nullptr);
422
- if (ret == SOCKET_ERROR) {
423
- const int error_num = WSAGetLastError();
424
- if (error_num != WSAEWOULDBLOCK) {
425
- QUIC_LOG_FIRST_N(ERROR, 100)
426
- << "Error reading packet: " << error_num;
427
- }
428
- return;
436
+ return 1 == select(1 + fd, &read_fds, nullptr, nullptr, &select_timeout);
429
437
  }
430
438
 
431
- if (ABSL_PREDICT_FALSE(hdr.dwFlags & MSG_CTRUNC)) {
432
- QUIC_BUG(quic_bug_10751_3)
433
- << "Control buffer too small. size:" << control_buffer.buffer_len;
434
- return;
435
- }
439
+ void QuicUdpSocketApi::ReadPacket(QuicUdpSocketFd fd,
440
+ BitMask64 packet_info_interested,
441
+ ReadPacketResult *result)
442
+ {
443
+ result->ok = false;
444
+ BufferSpan &packet_buffer = result->packet_buffer;
445
+ BufferSpan &control_buffer = result->control_buffer;
446
+ QuicUdpPacketInfo *packet_info = &result->packet_info;
436
447
 
437
- if (ABSL_PREDICT_FALSE(hdr.dwFlags & MSG_TRUNC) ||
438
- // Normally "bytes_read > packet_buffer.buffer_len" implies the MSG_TRUNC
439
- // bit is set, but it is not the case if tested with config=android_arm64.
440
- static_cast<size_t>(bytes_read) > packet_buffer.buffer_len) {
441
- QUIC_LOG_FIRST_N(WARNING, 100)
442
- << "Received truncated QUIC packet: buffer size:"
443
- << packet_buffer.buffer_len << " packet size:" << bytes_read;
444
- return;
445
- }
448
+ QUICHE_DCHECK_GE(control_buffer.buffer_len, kMinCmsgSpaceForRead);
446
449
 
447
- packet_buffer.buffer_len = bytes_read;
448
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
449
- packet_info->SetPeerAddress(QuicSocketAddress(raw_peer_address));
450
- }
450
+ ULONG bufferlen = packet_buffer.buffer_len;
451
+ WSABUF iov = {bufferlen, const_cast<char *>(packet_buffer.buffer)};
452
+ struct sockaddr_storage raw_peer_address;
451
453
 
452
- if (hdr.Control.len > 0) {
453
- for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
454
- cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
455
- BitMask64 prior_bitmask = packet_info->bitmask();
456
- PopulatePacketInfoFromControlMessage(cmsg, packet_info,
457
- packet_info_interested);
458
- if (packet_info->bitmask() == prior_bitmask) {
459
- QUIC_DLOG(INFO) << "Ignored cmsg_level:" << cmsg->cmsg_level
460
- << ", cmsg_type:" << cmsg->cmsg_type;
461
- }
454
+ if (control_buffer.buffer_len > 0)
455
+ {
456
+ reinterpret_cast<struct cmsghdr *>(control_buffer.buffer)->cmsg_len =
457
+ control_buffer.buffer_len;
462
458
  }
463
- }
464
-
465
- result->ok = true;
466
- }
467
459
 
468
- size_t QuicUdpSocketApi::ReadMultiplePackets(QuicUdpSocketFd fd,
469
- BitMask64 packet_info_interested,
470
- ReadPacketResults* results) {
471
- // Potential TODO WinSock supports similar stuff
472
- #if defined(__linux__) && !defined(__ANDROID__)
473
- // Use recvmmsg.
474
- size_t hdrs_size = sizeof(mmsghdr) * results->size();
475
- mmsghdr* hdrs = static_cast<mmsghdr*>(alloca(hdrs_size));
476
- memset(hdrs, 0, hdrs_size);
477
-
478
- struct TempPerPacketData {
479
- iovec iov;
480
- sockaddr_storage raw_peer_address;
481
- };
482
- TempPerPacketData* packet_data_array = static_cast<TempPerPacketData*>(
483
- alloca(sizeof(TempPerPacketData) * results->size()));
484
-
485
- for (size_t i = 0; i < results->size(); ++i) {
486
- (*results)[i].ok = false;
487
-
488
- msghdr* hdr = &hdrs[i].msg_hdr;
489
- TempPerPacketData* packet_data = &packet_data_array[i];
490
- packet_data->iov.iov_base = (*results)[i].packet_buffer.buffer;
491
- packet_data->iov.iov_len = (*results)[i].packet_buffer.buffer_len;
492
-
493
- hdr->msg_name = &packet_data->raw_peer_address;
494
- hdr->msg_namelen = sizeof(sockaddr_storage);
495
- hdr->msg_iov = &packet_data->iov;
496
- hdr->msg_iovlen = 1;
497
- hdr->msg_flags = 0;
498
- hdr->msg_control = (*results)[i].control_buffer.buffer;
499
- hdr->msg_controllen = (*results)[i].control_buffer.buffer_len;
500
-
501
- QUICHE_DCHECK_GE(hdr->msg_controllen, kMinCmsgSpaceForRead);
502
- }
503
- // If MSG_TRUNC is set on Linux, recvmmsg will return the real packet size in
504
- // |hdrs[i].msg_len| even if packet buffer is too small to receive it.
505
- int packets_read = recvmmsg(fd, hdrs, results->size(), MSG_TRUNC, nullptr);
506
- if (packets_read <= 0) {
507
- const int error_num = errno;
508
- if (error_num != EAGAIN) {
509
- QUIC_LOG_FIRST_N(ERROR, 100)
510
- << "Error reading packets: " << strerror(error_num);
511
- }
512
- return 0;
513
- }
514
-
515
- for (int i = 0; i < packets_read; ++i) {
516
- if (hdrs[i].msg_len == 0) {
517
- continue;
460
+ WSAMSG hdr;
461
+ hdr.name = reinterpret_cast<LPSOCKADDR>(&raw_peer_address);
462
+ hdr.namelen = sizeof(raw_peer_address);
463
+ hdr.lpBuffers = &iov;
464
+ hdr.dwBufferCount = 1;
465
+ hdr.dwFlags = 0;
466
+ hdr.Control.buf = control_buffer.buffer;
467
+ hdr.Control.len = control_buffer.buffer_len;
468
+
469
+ DWORD bytes_read = 0;
470
+
471
+ int ret = WSARecvMsg(fd, &hdr, &bytes_read, nullptr, nullptr);
472
+ if (ret == SOCKET_ERROR)
473
+ {
474
+ const int error_num = WSAGetLastError();
475
+ if (error_num != WSAEWOULDBLOCK)
476
+ {
477
+ QUIC_LOG_FIRST_N(ERROR, 100)
478
+ << "Error reading packet: " << error_num;
479
+ }
480
+ return;
518
481
  }
519
482
 
520
- msghdr& hdr = hdrs[i].msg_hdr;
521
- if (ABSL_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC)) {
522
- QUIC_BUG(quic_bug_10751_4) << "Control buffer too small. size:"
523
- << (*results)[i].control_buffer.buffer_len
524
- << ", need:" << hdr.msg_controllen;
525
- continue;
483
+ if (ABSL_PREDICT_FALSE(hdr.dwFlags & MSG_CTRUNC))
484
+ {
485
+ QUIC_BUG(quic_bug_10751_3)
486
+ << "Control buffer too small. size:" << control_buffer.buffer_len;
487
+ return;
526
488
  }
527
489
 
528
- if (ABSL_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC)) {
490
+ if (ABSL_PREDICT_FALSE(hdr.dwFlags & MSG_TRUNC) ||
491
+ // Normally "bytes_read > packet_buffer.buffer_len" implies the MSG_TRUNC
492
+ // bit is set, but it is not the case if tested with config=android_arm64.
493
+ static_cast<size_t>(bytes_read) > packet_buffer.buffer_len)
494
+ {
529
495
  QUIC_LOG_FIRST_N(WARNING, 100)
530
496
  << "Received truncated QUIC packet: buffer size:"
531
- << (*results)[i].packet_buffer.buffer_len
532
- << " packet size:" << hdrs[i].msg_len;
533
- continue;
497
+ << packet_buffer.buffer_len << " packet size:" << bytes_read;
498
+ return;
534
499
  }
535
500
 
536
- (*results)[i].ok = true;
537
- (*results)[i].packet_buffer.buffer_len = hdrs[i].msg_len;
538
-
539
- QuicUdpPacketInfo* packet_info = &(*results)[i].packet_info;
540
- if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
541
- packet_info->SetPeerAddress(
542
- QuicSocketAddress(packet_data_array[i].raw_peer_address));
501
+ packet_buffer.buffer_len = bytes_read;
502
+ if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS))
503
+ {
504
+ packet_info->SetPeerAddress(QuicSocketAddress(raw_peer_address));
543
505
  }
544
506
 
545
- if (hdr.msg_controllen > 0) {
546
- for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
547
- cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
507
+ if (hdr.Control.len > 0)
508
+ {
509
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
510
+ cmsg = CMSG_NXTHDR(&hdr, cmsg))
511
+ {
512
+ BitMask64 prior_bitmask = packet_info->bitmask();
548
513
  PopulatePacketInfoFromControlMessage(cmsg, packet_info,
549
514
  packet_info_interested);
515
+ if (packet_info->bitmask() == prior_bitmask)
516
+ {
517
+ QUIC_DLOG(INFO) << "Ignored cmsg_level:" << cmsg->cmsg_level
518
+ << ", cmsg_type:" << cmsg->cmsg_type;
519
+ }
550
520
  }
551
521
  }
522
+
523
+ result->ok = true;
552
524
  }
553
- return packets_read;
525
+
526
+ size_t QuicUdpSocketApi::ReadMultiplePackets(QuicUdpSocketFd fd,
527
+ BitMask64 packet_info_interested,
528
+ ReadPacketResults *results)
529
+ {
530
+ // Potential TODO WinSock supports similar stuff
531
+ #if defined(__linux__) && !defined(__ANDROID__)
532
+ // Use recvmmsg.
533
+ size_t hdrs_size = sizeof(mmsghdr) * results->size();
534
+ mmsghdr *hdrs = static_cast<mmsghdr *>(alloca(hdrs_size));
535
+ memset(hdrs, 0, hdrs_size);
536
+
537
+ struct TempPerPacketData
538
+ {
539
+ iovec iov;
540
+ sockaddr_storage raw_peer_address;
541
+ };
542
+ TempPerPacketData *packet_data_array = static_cast<TempPerPacketData *>(
543
+ alloca(sizeof(TempPerPacketData) * results->size()));
544
+
545
+ for (size_t i = 0; i < results->size(); ++i)
546
+ {
547
+ (*results)[i].ok = false;
548
+
549
+ msghdr *hdr = &hdrs[i].msg_hdr;
550
+ TempPerPacketData *packet_data = &packet_data_array[i];
551
+ packet_data->iov.iov_base = (*results)[i].packet_buffer.buffer;
552
+ packet_data->iov.iov_len = (*results)[i].packet_buffer.buffer_len;
553
+
554
+ hdr->msg_name = &packet_data->raw_peer_address;
555
+ hdr->msg_namelen = sizeof(sockaddr_storage);
556
+ hdr->msg_iov = &packet_data->iov;
557
+ hdr->msg_iovlen = 1;
558
+ hdr->msg_flags = 0;
559
+ hdr->msg_control = (*results)[i].control_buffer.buffer;
560
+ hdr->msg_controllen = (*results)[i].control_buffer.buffer_len;
561
+
562
+ QUICHE_DCHECK_GE(hdr->msg_controllen, kMinCmsgSpaceForRead);
563
+ }
564
+ // If MSG_TRUNC is set on Linux, recvmmsg will return the real packet size in
565
+ // |hdrs[i].msg_len| even if packet buffer is too small to receive it.
566
+ int packets_read = recvmmsg(fd, hdrs, results->size(), MSG_TRUNC, nullptr);
567
+ if (packets_read <= 0)
568
+ {
569
+ const int error_num = errno;
570
+ if (error_num != EAGAIN)
571
+ {
572
+ QUIC_LOG_FIRST_N(ERROR, 100)
573
+ << "Error reading packets: " << strerror(error_num);
574
+ }
575
+ return 0;
576
+ }
577
+
578
+ for (int i = 0; i < packets_read; ++i)
579
+ {
580
+ if (hdrs[i].msg_len == 0)
581
+ {
582
+ continue;
583
+ }
584
+
585
+ msghdr &hdr = hdrs[i].msg_hdr;
586
+ if (ABSL_PREDICT_FALSE(hdr.msg_flags & MSG_CTRUNC))
587
+ {
588
+ QUIC_BUG(quic_bug_10751_4) << "Control buffer too small. size:"
589
+ << (*results)[i].control_buffer.buffer_len
590
+ << ", need:" << hdr.msg_controllen;
591
+ continue;
592
+ }
593
+
594
+ if (ABSL_PREDICT_FALSE(hdr.msg_flags & MSG_TRUNC))
595
+ {
596
+ QUIC_LOG_FIRST_N(WARNING, 100)
597
+ << "Received truncated QUIC packet: buffer size:"
598
+ << (*results)[i].packet_buffer.buffer_len
599
+ << " packet size:" << hdrs[i].msg_len;
600
+ continue;
601
+ }
602
+
603
+ (*results)[i].ok = true;
604
+ (*results)[i].packet_buffer.buffer_len = hdrs[i].msg_len;
605
+
606
+ QuicUdpPacketInfo *packet_info = &(*results)[i].packet_info;
607
+ if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::PEER_ADDRESS))
608
+ {
609
+ packet_info->SetPeerAddress(
610
+ QuicSocketAddress(packet_data_array[i].raw_peer_address));
611
+ }
612
+
613
+ if (hdr.msg_controllen > 0)
614
+ {
615
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
616
+ cmsg = CMSG_NXTHDR(&hdr, cmsg))
617
+ {
618
+ PopulatePacketInfoFromControlMessage(cmsg, packet_info,
619
+ packet_info_interested);
620
+ }
621
+ }
622
+ }
623
+ return packets_read;
554
624
  #else
555
- size_t num_packets = 0;
556
- for (ReadPacketResult& result : *results) {
557
- result.ok = false;
558
- }
559
- for (ReadPacketResult& result : *results) {
560
- ReadPacket(fd, packet_info_interested, &result);
561
- if (!result.ok && WSAGetLastError() == WSAEWOULDBLOCK) {
562
- break;
625
+ size_t num_packets = 0;
626
+ for (ReadPacketResult &result : *results)
627
+ {
628
+ result.ok = false;
563
629
  }
564
- ++num_packets;
565
- }
566
- return num_packets;
630
+ for (ReadPacketResult &result : *results)
631
+ {
632
+ ReadPacket(fd, packet_info_interested, &result);
633
+ if (!result.ok && WSAGetLastError() == WSAEWOULDBLOCK)
634
+ {
635
+ break;
636
+ }
637
+ ++num_packets;
638
+ }
639
+ return num_packets;
567
640
  #endif
568
- }
569
-
570
- WriteResult QuicUdpSocketApi::WritePacket(
571
- QuicUdpSocketFd fd, const char* packet_buffer, size_t packet_buffer_len,
572
- const QuicUdpPacketInfo& packet_info) {
573
- if (!packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
574
- return WriteResult(WRITE_STATUS_ERROR, EINVAL);
575
641
  }
576
642
 
577
- char control_buffer[512];
578
- sockaddr_storage raw_peer_address =
579
- packet_info.peer_address().generic_address();
580
- ULONG bufferlen = packet_buffer_len;
581
- WSABUF iov = {bufferlen, const_cast<char*>(packet_buffer)};
582
-
583
- WSAMSG hdr;
584
- hdr.name = reinterpret_cast<LPSOCKADDR> (&raw_peer_address);
585
- hdr.namelen = packet_info.peer_address().host().IsIPv4()
586
- ? sizeof(sockaddr_in)
587
- : sizeof(sockaddr_in6);
588
- hdr.lpBuffers = &iov;
589
- hdr.dwBufferCount = 1;
590
- hdr.dwFlags = 0;
591
- hdr.Control.buf = nullptr;
592
- hdr.Control.len = 0;
593
-
594
-
595
- cmsghdr* cmsg = nullptr;
596
-
597
- // Set self IP.
598
- if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP) &&
599
- packet_info.self_v4_ip().IsInitialized()) {
600
- if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IP,
601
- IP_PKTINFO, sizeof(in_pktinfo), &cmsg)) {
602
- QUIC_LOG_FIRST_N(ERROR, 100)
603
- << "Not enough buffer to set self v4 ip address.";
643
+ WriteResult QuicUdpSocketApi::WritePacket(
644
+ QuicUdpSocketFd fd, const char *packet_buffer, size_t packet_buffer_len,
645
+ const QuicUdpPacketInfo &packet_info)
646
+ {
647
+ if (!packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS))
648
+ {
604
649
  return WriteResult(WRITE_STATUS_ERROR, EINVAL);
605
650
  }
606
- SetV4SelfIpInControlMessage(packet_info.self_v4_ip(), cmsg);
607
- } else if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP) &&
608
- packet_info.self_v6_ip().IsInitialized()) {
609
- if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IPV6,
610
- IPV6_PKTINFO, sizeof(in6_pktinfo), &cmsg)) {
611
- QUIC_LOG_FIRST_N(ERROR, 100)
612
- << "Not enough buffer to set self v6 ip address.";
613
- return WriteResult(WRITE_STATUS_ERROR, EINVAL);
651
+
652
+ char control_buffer[512];
653
+ sockaddr_storage raw_peer_address =
654
+ packet_info.peer_address().generic_address();
655
+ ULONG bufferlen = packet_buffer_len;
656
+ WSABUF iov = {bufferlen, const_cast<char *>(packet_buffer)};
657
+
658
+ WSAMSG hdr;
659
+ hdr.name = reinterpret_cast<LPSOCKADDR>(&raw_peer_address);
660
+ hdr.namelen = packet_info.peer_address().host().IsIPv4()
661
+ ? sizeof(sockaddr_in)
662
+ : sizeof(sockaddr_in6);
663
+ hdr.lpBuffers = &iov;
664
+ hdr.dwBufferCount = 1;
665
+ hdr.dwFlags = 0;
666
+ hdr.Control.buf = nullptr;
667
+ hdr.Control.len = 0;
668
+
669
+ cmsghdr *cmsg = nullptr;
670
+
671
+ // Set self IP.
672
+ if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP) &&
673
+ packet_info.self_v4_ip().IsInitialized())
674
+ {
675
+ if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IP,
676
+ IP_PKTINFO, sizeof(in_pktinfo), &cmsg))
677
+ {
678
+ QUIC_LOG_FIRST_N(ERROR, 100)
679
+ << "Not enough buffer to set self v4 ip address.";
680
+ return WriteResult(WRITE_STATUS_ERROR, EINVAL);
681
+ }
682
+ SetV4SelfIpInControlMessage(packet_info.self_v4_ip(), cmsg);
683
+ }
684
+ else if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP) &&
685
+ packet_info.self_v6_ip().IsInitialized())
686
+ {
687
+ if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), IPPROTO_IPV6,
688
+ IPV6_PKTINFO, sizeof(in6_pktinfo), &cmsg))
689
+ {
690
+ QUIC_LOG_FIRST_N(ERROR, 100)
691
+ << "Not enough buffer to set self v6 ip address.";
692
+ return WriteResult(WRITE_STATUS_ERROR, EINVAL);
693
+ }
694
+ SetV6SelfIpInControlMessage(packet_info.self_v6_ip(), cmsg);
614
695
  }
615
- SetV6SelfIpInControlMessage(packet_info.self_v6_ip(), cmsg);
616
- }
617
696
 
618
697
  #if defined(QUIC_UDP_SOCKET_SUPPORT_TTL)
619
- // Set ttl.
620
- if (packet_info.HasValue(QuicUdpPacketInfoBit::TTL)) {
621
- int cmsg_level =
622
- packet_info.peer_address().host().IsIPv4() ? IPPROTO_IP : IPPROTO_IPV6;
623
- int cmsg_type =
624
- packet_info.peer_address().host().IsIPv4() ? IP_TTL : IPV6_HOPLIMIT;
625
- if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), cmsg_level,
626
- cmsg_type, sizeof(int), &cmsg)) {
627
- QUIC_LOG_FIRST_N(ERROR, 100) << "Not enough buffer to set ttl.";
628
- return WriteResult(WRITE_STATUS_ERROR, EINVAL);
698
+ // Set ttl.
699
+ if (packet_info.HasValue(QuicUdpPacketInfoBit::TTL))
700
+ {
701
+ int cmsg_level =
702
+ packet_info.peer_address().host().IsIPv4() ? IPPROTO_IP : IPPROTO_IPV6;
703
+ int cmsg_type =
704
+ packet_info.peer_address().host().IsIPv4() ? IP_TTL : IPV6_HOPLIMIT;
705
+ if (!NextCmsg(&hdr, control_buffer, sizeof(control_buffer), cmsg_level,
706
+ cmsg_type, sizeof(int), &cmsg))
707
+ {
708
+ QUIC_LOG_FIRST_N(ERROR, 100) << "Not enough buffer to set ttl.";
709
+ return WriteResult(WRITE_STATUS_ERROR, EINVAL);
710
+ }
711
+ *reinterpret_cast<int *>(WSA_CMSG_DATA(cmsg)) = packet_info.ttl();
629
712
  }
630
- *reinterpret_cast<int*>(WSA_CMSG_DATA(cmsg)) = packet_info.ttl();
631
- }
632
713
  #endif
633
714
 
634
-
635
- int rc;
636
- DWORD bytessend;
637
- do {
638
- rc = WSASendMsg(fd, &hdr, 0, &bytessend, nullptr, nullptr);
639
- } while (rc == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
640
- if (bytessend >= 0) {
641
- return WriteResult(WRITE_STATUS_OK, bytessend);
715
+ int rc;
716
+ DWORD bytessend;
717
+ do
718
+ {
719
+ rc = WSASendMsg(fd, &hdr, 0, &bytessend, nullptr, nullptr);
720
+ } while (rc == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
721
+ if (bytessend >= 0)
722
+ {
723
+ return WriteResult(WRITE_STATUS_OK, bytessend);
724
+ }
725
+ int error = WSAGetLastError();
726
+ return WriteResult((error == WSAEWOULDBLOCK)
727
+ ? WRITE_STATUS_BLOCKED
728
+ : WRITE_STATUS_ERROR,
729
+ error);
642
730
  }
643
- int error = WSAGetLastError();
644
- return WriteResult(( error == WSAEWOULDBLOCK )
645
- ? WRITE_STATUS_BLOCKED
646
- : WRITE_STATUS_ERROR,
647
- error);
648
- }
649
-
650
- } // namespace quic
731
+
732
+ } // namespace quic