| // 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 NET_TOOLS_QUIC_QUIC_PACKET_READER_H_ | 
 | #define NET_TOOLS_QUIC_QUIC_PACKET_READER_H_ | 
 |  | 
 | #include <netinet/in.h> | 
 | #include <sys/socket.h> | 
 |  | 
 | #include "base/macros.h" | 
 | #include "net/quic/quic_clock.h" | 
 | #include "net/quic/quic_protocol.h" | 
 | #include "net/tools/quic/quic_process_packet_interface.h" | 
 | #include "net/tools/quic/quic_socket_utils.h" | 
 |  | 
 | #define MMSG_MORE 0 | 
 |  | 
 | namespace net { | 
 |  | 
 | #if MMSG_MORE | 
 | // Read in larger batches to minimize recvmmsg overhead. | 
 | const int kNumPacketsPerReadMmsgCall = 16; | 
 | #endif | 
 |  | 
 | namespace test { | 
 | class QuicServerPeer; | 
 | }  // namespace test | 
 |  | 
 | class QuicDispatcher; | 
 |  | 
 | class QuicPacketReader { | 
 |  public: | 
 |   QuicPacketReader(); | 
 |  | 
 |   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); | 
 |  | 
 |   // Storage only used when recvmmsg is available. | 
 |  | 
 | #if MMSG_MORE | 
 |   // 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[QuicSocketUtils::kSpaceForCmsg]; | 
 |     // buf is used for the data read from the kernel on recvmmsg. | 
 |     char buf[kMaxPacketSize]; | 
 |   }; | 
 |   PacketData packets_[kNumPacketsPerReadMmsgCall]; | 
 |   mmsghdr mmsg_hdr_[kNumPacketsPerReadMmsgCall]; | 
 | #endif | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(QuicPacketReader); | 
 | }; | 
 |  | 
 | }  // namespace net | 
 |  | 
 | #endif  // NET_TOOLS_QUIC_QUIC_PACKET_READER_H_ |