1 // Copyright 2015 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.
5 #include "net/tools/quic/quic_packet_reader.h"
9 // This is a GNU header that is not present in /usr/include on MacOS
13 #include <sys/epoll.h>
15 #include "base/logging.h"
16 #include "net/base/ip_endpoint.h"
17 #include "net/tools/quic/quic_dispatcher.h"
18 #include "net/tools/quic/quic_socket_utils.h"
23 #define SO_RXQ_OVFL 40
30 QuicPacketReader::QuicPacketReader() {
34 void QuicPacketReader::Initialize() {
35 // Zero initialize uninitialized memory.
36 memset(cbuf_
, 0, arraysize(cbuf_
));
37 memset(buf_
, 0, arraysize(buf_
));
38 memset(raw_address_
, 0, sizeof(raw_address_
));
39 memset(mmsg_hdr_
, 0, sizeof(mmsg_hdr_
));
41 for (int i
= 0; i
< kNumPacketsPerReadMmsgCall
; ++i
) {
42 iov_
[i
].iov_base
= buf_
+ (2 * kMaxPacketSize
* i
);
43 iov_
[i
].iov_len
= 2 * kMaxPacketSize
;
45 msghdr
* hdr
= &mmsg_hdr_
[i
].msg_hdr
;
46 hdr
->msg_name
= &raw_address_
[i
];
47 hdr
->msg_namelen
= sizeof(sockaddr_storage
);
48 hdr
->msg_iov
= &iov_
[i
];
51 hdr
->msg_control
= cbuf_
+ kSpaceForOverflowAndIp
* i
;
52 hdr
->msg_controllen
= kSpaceForOverflowAndIp
;
56 QuicPacketReader::~QuicPacketReader() {
59 bool QuicPacketReader::ReadAndDispatchPackets(
62 ProcessPacketInterface
* processor
,
63 QuicPacketCount
* packets_dropped
) {
65 // Re-set the length fields in case recvmmsg has changed them.
66 for (int i
= 0; i
< kNumPacketsPerReadMmsgCall
; ++i
) {
67 iov_
[i
].iov_len
= 2 * kMaxPacketSize
;
68 mmsg_hdr_
[i
].msg_len
= 0;
69 msghdr
* hdr
= &mmsg_hdr_
[i
].msg_hdr
;
70 hdr
->msg_namelen
= sizeof(sockaddr_storage
);
72 hdr
->msg_controllen
= kSpaceForOverflowAndIp
;
76 recvmmsg(fd
, mmsg_hdr_
, kNumPacketsPerReadMmsgCall
, 0, nullptr);
78 if (packets_read
<= 0) {
79 return false; // recvmmsg failed.
82 for (int i
= 0; i
< packets_read
; ++i
) {
83 if (mmsg_hdr_
[i
].msg_len
== 0) {
87 IPEndPoint client_address
= IPEndPoint(raw_address_
[i
]);
88 IPAddressNumber server_ip
=
89 QuicSocketUtils::GetAddressFromMsghdr(&mmsg_hdr_
[i
].msg_hdr
);
90 if (!IsInitializedAddress(server_ip
)) {
91 LOG(DFATAL
) << "Unable to get server address.";
95 QuicEncryptedPacket
packet(reinterpret_cast<char*>(iov_
[i
].iov_base
),
96 mmsg_hdr_
[i
].msg_len
, false);
97 IPEndPoint
server_address(server_ip
, port
);
98 processor
->ProcessPacket(server_address
, client_address
, packet
);
101 if (packets_dropped
!= nullptr) {
102 QuicSocketUtils::GetOverflowFromMsghdr(&mmsg_hdr_
[0].msg_hdr
,
108 LOG(FATAL
) << "Unsupported";
114 bool QuicPacketReader::ReadAndDispatchSinglePacket(
117 ProcessPacketInterface
* processor
,
118 QuicPacketCount
* packets_dropped
) {
119 // Allocate some extra space so we can send an error if the packet is larger
120 // than kMaxPacketSize.
121 char buf
[2 * kMaxPacketSize
];
123 IPEndPoint client_address
;
124 IPAddressNumber server_ip
;
125 int bytes_read
= QuicSocketUtils::ReadPacket(
126 fd
, buf
, arraysize(buf
), packets_dropped
, &server_ip
, &client_address
);
128 if (bytes_read
< 0) {
129 return false; // ReadPacket failed.
132 QuicEncryptedPacket
packet(buf
, bytes_read
, false);
133 IPEndPoint
server_address(server_ip
, port
);
134 processor
->ProcessPacket(server_address
, client_address
, packet
);
136 // The socket read was successful, so return true even if packet dispatch