Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_packet_reader.h b/quic/core/quic_packet_reader.h
new file mode 100644
index 0000000..9767c39
--- /dev/null
+++ b/quic/core/quic_packet_reader.h
@@ -0,0 +1,91 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A class to read incoming QUIC packets from the UDP socket.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
+#define QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_
+
+#include <netinet/in.h>
+// Include here to guarantee this header gets included (for MSG_WAITFORONE)
+// regardless of how the below transitive header include set may change.
+#include <sys/socket.h>
+
+#include "base/macros.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_process_packet_interface.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_clock.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/quic/platform/impl/quic_socket_utils.h"
+
+namespace quic {
+
+#if MMSG_MORE
+// Read in larger batches to minimize recvmmsg overhead.
+const int kNumPacketsPerReadMmsgCall = 16;
+#endif
+
+class QuicPacketReader {
+ public:
+  QuicPacketReader();
+  QuicPacketReader(const QuicPacketReader&) = delete;
+  QuicPacketReader& operator=(const QuicPacketReader&) = delete;
+
+  virtual ~QuicPacketReader();
+
+  // Reads a number of packets from the given fd, and then passes them off to
+  // the PacketProcessInterface.  Returns true if there may be additional
+  // packets available on the socket.
+  // Populates |packets_dropped| if it is non-null and the socket is configured
+  // to track dropped packets and some packets are read.
+  // If the socket has timestamping enabled, the per packet timestamps will be
+  // passed to the processor. Otherwise, |clock| will be used.
+  virtual bool ReadAndDispatchPackets(int fd,
+                                      int port,
+                                      const QuicClock& clock,
+                                      ProcessPacketInterface* processor,
+                                      QuicPacketCount* packets_dropped);
+
+ private:
+  // Initialize the internal state of the reader.
+  void Initialize();
+
+  // Reads and dispatches many packets using recvmmsg.
+  bool ReadAndDispatchManyPackets(int fd,
+                                  int port,
+                                  const QuicClock& clock,
+                                  ProcessPacketInterface* processor,
+                                  QuicPacketCount* packets_dropped);
+
+  // Reads and dispatches a single packet using recvmsg.
+  static bool ReadAndDispatchSinglePacket(int fd,
+                                          int port,
+                                          const QuicClock& clock,
+                                          ProcessPacketInterface* processor,
+                                          QuicPacketCount* packets_dropped);
+
+#if MMSG_MORE
+  // Storage only used when recvmmsg is available.
+  // TODO(danzh): change it to be a pointer to avoid the allocation on the stack
+  // from exceeding maximum allowed frame size.
+  // packets_ and mmsg_hdr_ are used to supply cbuf and buf to the recvmmsg
+  // call.
+  struct PacketData {
+    iovec iov;
+    // raw_address is used for address information provided by the recvmmsg
+    // call on the packets.
+    struct sockaddr_storage raw_address;
+    // cbuf is used for ancillary data from the kernel on recvmmsg.
+    char cbuf[kCmsgSpaceForReadPacket];
+    // buf is used for the data read from the kernel on recvmmsg.
+    char buf[kMaxV4PacketSize];
+  };
+  PacketData packets_[kNumPacketsPerReadMmsgCall];
+  mmsghdr mmsg_hdr_[kNumPacketsPerReadMmsgCall];
+#endif
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_READER_H_