gfe-relnote: Introduce kDefaultUdpPacketControlBufferSize and use it in QuicPacketReader as the control buffer size. No behavior change, not protected.
Why? I need to remove kCmsgSpaceForReadPacket, which is defined in quic_socket_utils.h.
Merge note: Please define kCmsgSpaceForGooglePacketHeaderImpl=0 in Chromium's quic_udp_socket_platform_impl.h.
PiperOrigin-RevId: 291940730
Change-Id: I0e7d9652e42218b06ce535b2d7297dda88971341
diff --git a/quic/core/quic_packet_reader.h b/quic/core/quic_packet_reader.h
index 623f01b..e4961b9 100644
--- a/quic/core/quic_packet_reader.h
+++ b/quic/core/quic_packet_reader.h
@@ -94,7 +94,8 @@
#endif
struct QUIC_EXPORT_PRIVATE ReadBuffer {
QUIC_CACHELINE_ALIGNED char
- control_buffer[kCmsgSpaceForReadPacket]; // For ancillary data.
+ control_buffer[kDefaultUdpPacketControlBufferSize]; // For ancillary
+ // data.
QUIC_CACHELINE_ALIGNED char packet_buffer[kMaxIncomingPacketSize];
};
// Latched value of --quic_remove_quic_socket_utils_from_packet_reader.
diff --git a/quic/core/quic_udp_socket.h b/quic/core/quic_udp_socket.h
index 8be9e57..04f8435 100644
--- a/quic/core/quic_udp_socket.h
+++ b/quic/core/quic_udp_socket.h
@@ -25,6 +25,8 @@
const QuicUdpSocketFd kQuicInvalidSocketFd = -1;
#endif
+const size_t kDefaultUdpPacketControlBufferSize = 512;
+
enum class QuicUdpPacketInfoBit : uint8_t {
DROPPED_PACKETS = 0, // Read
V4_SELF_IP, // Read
@@ -205,7 +207,8 @@
// |result->packet_buffer.buffer_len| is set to the
// packet length on a successful return.
// result->control_buffer: The control buffer, used by ReadPacket internally.
- // It is recommended to be at least 512 bytes.
+ // It is recommended to be
+ // |kDefaultUdpPacketControlBufferSize| bytes.
// result->ok: True iff a packet is successfully received.
//
// If |*result| is reused for subsequent ReadPacket() calls, caller needs to
diff --git a/quic/core/quic_udp_socket_posix.cc b/quic/core/quic_udp_socket_posix.cc
index 1141c1c..b6c58cd 100644
--- a/quic/core/quic_udp_socket_posix.cc
+++ b/quic/core/quic_udp_socket_posix.cc
@@ -29,6 +29,34 @@
namespace quic {
namespace {
+
+#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
+#define QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING 1
+// This is the structure that SO_TIMESTAMPING fills into the cmsg header.
+// It is well-defined, but does not have a definition in a public header.
+// See https://www.kernel.org/doc/Documentation/networking/timestamping.txt
+// for more information.
+struct LinuxSoTimestamping {
+ // The converted system time of the timestamp.
+ struct timespec systime;
+ // Deprecated; serves only as padding.
+ struct timespec hwtimetrans;
+ // The raw hardware timestamp.
+ struct timespec hwtimeraw;
+};
+const size_t kCmsgSpaceForRecvTimestamp =
+ CMSG_SPACE(sizeof(LinuxSoTimestamping));
+#else
+const size_t kCmsgSpaceForRecvTimestamp = 0;
+#endif
+
+const size_t kMinCmsgSpaceForRead =
+ CMSG_SPACE(sizeof(uint32_t)) // Dropped packet count
+ + CMSG_SPACE(sizeof(in_pktinfo)) // V4 Self IP
+ + CMSG_SPACE(sizeof(in6_pktinfo)) // V6 Self IP
+ + kCmsgSpaceForRecvTimestamp + CMSG_SPACE(sizeof(int)) // TTL
+ + kCmsgSpaceForGooglePacketHeader;
+
QuicUdpSocketFd CreateNonblockingSocket(int address_family) {
#if defined(__linux__) && defined(SOCK_NONBLOCK)
@@ -109,24 +137,11 @@
}
#endif
-#if defined(__linux__) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21)
+#if defined(QUIC_UDP_SOCKET_SUPPORT_LINUX_TIMESTAMPING)
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPING) {
- // This is the structure that SO_TIMESTAMPING fills into the cmsg header.
- // It is well-defined, but does not have a definition in a public header.
- // See https://www.kernel.org/doc/Documentation/networking/timestamping.txt
- // for more information.
- struct LinuxTimestamping {
- // The converted system time of the timestamp.
- struct timespec systime;
- // Deprecated; serves only as padding.
- struct timespec hwtimetrans;
- // The raw hardware timestamp.
- struct timespec hwtimeraw;
- };
-
if (packet_info_interested.IsSet(QuicUdpPacketInfoBit::RECV_TIMESTAMP)) {
- LinuxTimestamping* linux_ts =
- reinterpret_cast<LinuxTimestamping*>(CMSG_DATA(cmsg));
+ LinuxSoTimestamping* linux_ts =
+ reinterpret_cast<LinuxSoTimestamping*>(CMSG_DATA(cmsg));
timespec* ts = &linux_ts->systime;
int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) +
(static_cast<int64_t>(ts->tv_nsec) / 1000);
@@ -225,6 +240,10 @@
QuicUdpSocketFd QuicUdpSocketApi::Create(int address_family,
int receive_buffer_size,
int send_buffer_size) {
+ // DCHECK here so the program exits early(before reading packets) in debug
+ // mode. This should have been a static_assert, however it can't be done on
+ // ios/osx because CMSG_SPACE isn't a constant expression there.
+ DCHECK_GE(kDefaultUdpPacketControlBufferSize, kMinCmsgSpaceForRead);
QuicUdpSocketFd fd = CreateNonblockingSocket(address_family);
if (fd == kQuicInvalidSocketFd) {
@@ -359,6 +378,8 @@
BufferSpan& control_buffer = result->control_buffer;
QuicUdpPacketInfo* packet_info = &result->packet_info;
+ DCHECK_GE(control_buffer.buffer_len, kMinCmsgSpaceForRead);
+
struct iovec iov = {packet_buffer.buffer, packet_buffer.buffer_len};
struct sockaddr_storage raw_peer_address;
@@ -461,6 +482,8 @@
hdr->msg_flags = 0;
hdr->msg_control = (*results)[i].control_buffer.buffer;
hdr->msg_controllen = (*results)[i].control_buffer.buffer_len;
+
+ DCHECK_GE(hdr->msg_controllen, kMinCmsgSpaceForRead);
}
// If MSG_TRUNC is set on Linux, recvmmsg will return the real packet size in
// |hdrs[i].msg_len| even if packet buffer is too small to receive it.
diff --git a/quic/platform/api/quic_udp_socket_platform_api.h b/quic/platform/api/quic_udp_socket_platform_api.h
index 78d35f8..2b1f9c3 100644
--- a/quic/platform/api/quic_udp_socket_platform_api.h
+++ b/quic/platform/api/quic_udp_socket_platform_api.h
@@ -9,6 +9,9 @@
namespace quic {
+const size_t kCmsgSpaceForGooglePacketHeader =
+ kCmsgSpaceForGooglePacketHeaderImpl;
+
inline bool GetGooglePacketHeadersFromControlMessage(
struct ::cmsghdr* cmsg,
char** packet_headers,