| Index: net/quic/quic_packet_reader.cc
|
| diff --git a/net/quic/quic_packet_reader.cc b/net/quic/quic_packet_reader.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5087870c2062e800cf8ad2c1213b63b10bcf6bfd
|
| --- /dev/null
|
| +++ b/net/quic/quic_packet_reader.cc
|
| @@ -0,0 +1,76 @@
|
| +// Copyright (c) 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.
|
| +
|
| +#include "net/quic/quic_packet_reader.h"
|
| +
|
| +#include "base/metrics/histogram.h"
|
| +#include "net/base/net_errors.h"
|
| +
|
| +namespace net {
|
| +
|
| +QuicPacketReader::QuicPacketReader(DatagramClientSocket* socket,
|
| + Visitor* visitor,
|
| + const BoundNetLog& net_log)
|
| + : socket_(socket),
|
| + visitor_(visitor),
|
| + read_pending_(false),
|
| + num_packets_read_(0),
|
| + read_buffer_(new IOBufferWithSize(kMaxPacketSize)),
|
| + net_log_(net_log),
|
| + weak_factory_(this) {
|
| +}
|
| +
|
| +QuicPacketReader::~QuicPacketReader() {
|
| +}
|
| +
|
| +void QuicPacketReader::StartReading() {
|
| + if (read_pending_)
|
| + return;
|
| +
|
| + DCHECK(socket_);
|
| + read_pending_ = true;
|
| + int rv = socket_->Read(read_buffer_.get(), read_buffer_->size(),
|
| + base::Bind(&QuicPacketReader::OnReadComplete,
|
| + weak_factory_.GetWeakPtr()));
|
| + UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.AsyncRead", rv == ERR_IO_PENDING);
|
| + if (rv == ERR_IO_PENDING) {
|
| + num_packets_read_ = 0;
|
| + return;
|
| + }
|
| +
|
| + if (++num_packets_read_ > 32) {
|
| + num_packets_read_ = 0;
|
| + // Data was read, process it.
|
| + // Schedule the work through the message loop to 1) prevent infinite
|
| + // recursion and 2) avoid blocking the thread for too long.
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE, base::Bind(&QuicPacketReader::OnReadComplete,
|
| + weak_factory_.GetWeakPtr(), rv));
|
| + } else {
|
| + OnReadComplete(rv);
|
| + }
|
| +}
|
| +
|
| +void QuicPacketReader::OnReadComplete(int result) {
|
| + read_pending_ = false;
|
| + if (result == 0)
|
| + result = ERR_CONNECTION_CLOSED;
|
| +
|
| + if (result < 0) {
|
| + visitor_->OnReadError(result);
|
| + return;
|
| + }
|
| +
|
| + QuicEncryptedPacket packet(read_buffer_->data(), result);
|
| + IPEndPoint local_address;
|
| + IPEndPoint peer_address;
|
| + socket_->GetLocalAddress(&local_address);
|
| + socket_->GetPeerAddress(&peer_address);
|
| + if (!visitor_->OnPacket(packet, local_address, peer_address))
|
| + return;
|
| +
|
| + StartReading();
|
| +}
|
| +
|
| +} // namespace net
|
|
|