| Index: net/quic/quic_client_session.cc | 
| diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc | 
| index e5fdba734e838e5c9b84f7925176f96a31eca2df..0625f08077d30c5c7c62a77e5668a72b8ee1c2d6 100644 | 
| --- a/net/quic/quic_client_session.cc | 
| +++ b/net/quic/quic_client_session.cc | 
| @@ -166,16 +166,14 @@ QuicClientSession::QuicClientSession( | 
| require_confirmation_(false), | 
| stream_factory_(stream_factory), | 
| socket_(socket.Pass()), | 
| -      read_buffer_(new IOBufferWithSize(kMaxPacketSize)), | 
| transport_security_state_(transport_security_state), | 
| server_info_(server_info.Pass()), | 
| -      read_pending_(false), | 
| num_total_streams_(0), | 
| task_runner_(task_runner), | 
| net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_QUIC_SESSION)), | 
| +      packet_reader_(socket_.get(), this, net_log_), | 
| dns_resolution_end_time_(dns_resolution_end_time), | 
| logger_(new QuicConnectionLogger(this, connection_description, net_log_)), | 
| -      num_packets_read_(0), | 
| going_away_(false), | 
| weak_factory_(this) { | 
| connection->set_debug_visitor(logger_.get()); | 
| @@ -767,32 +765,7 @@ void QuicClientSession::OnProofVerifyDetailsAvailable( | 
| } | 
|  | 
| void QuicClientSession::StartReading() { | 
| -  if (read_pending_) { | 
| -    return; | 
| -  } | 
| -  read_pending_ = true; | 
| -  int rv = socket_->Read(read_buffer_.get(), | 
| -                         read_buffer_->size(), | 
| -                         base::Bind(&QuicClientSession::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(&QuicClientSession::OnReadComplete, | 
| -                   weak_factory_.GetWeakPtr(), rv)); | 
| -  } else { | 
| -    OnReadComplete(rv); | 
| -  } | 
| +  packet_reader_.StartReading(); | 
| } | 
|  | 
| void QuicClientSession::CloseSessionOnError(int error) { | 
| @@ -874,33 +847,23 @@ base::WeakPtr<QuicClientSession> QuicClientSession::GetWeakPtr() { | 
| return weak_factory_.GetWeakPtr(); | 
| } | 
|  | 
| -void QuicClientSession::OnReadComplete(int result) { | 
| -  read_pending_ = false; | 
| -  if (result == 0) | 
| -    result = ERR_CONNECTION_CLOSED; | 
| - | 
| -  if (result < 0) { | 
| -    DVLOG(1) << "Closing session on read error: " << result; | 
| -    UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ReadError", -result); | 
| -    NotifyFactoryOfSessionGoingAway(); | 
| -    CloseSessionOnErrorInner(result, QUIC_PACKET_READ_ERROR); | 
| -    NotifyFactoryOfSessionClosedLater(); | 
| -    return; | 
| -  } | 
| +void QuicClientSession::OnReadError(int result) { | 
| +  DVLOG(1) << "Closing session on read error: " << result; | 
| +  UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ReadError", -result); | 
| +  NotifyFactoryOfSessionGoingAway(); | 
| +  CloseSessionOnErrorInner(result, QUIC_PACKET_READ_ERROR); | 
| +  NotifyFactoryOfSessionClosedLater(); | 
| +} | 
|  | 
| -  QuicEncryptedPacket packet(read_buffer_->data(), result); | 
| -  IPEndPoint local_address; | 
| -  IPEndPoint peer_address; | 
| -  socket_->GetLocalAddress(&local_address); | 
| -  socket_->GetPeerAddress(&peer_address); | 
| -  // ProcessUdpPacket might result in |this| being deleted, so we | 
| -  // use a weak pointer to be safe. | 
| +bool QuicClientSession::OnPacket(const QuicEncryptedPacket& packet, | 
| +                                 IPEndPoint local_address, | 
| +                                 IPEndPoint peer_address) { | 
| connection()->ProcessUdpPacket(local_address, peer_address, packet); | 
| if (!connection()->connected()) { | 
| NotifyFactoryOfSessionClosedLater(); | 
| -    return; | 
| +    return false; | 
| } | 
| -  StartReading(); | 
| +  return true; | 
| } | 
|  | 
| void QuicClientSession::NotifyFactoryOfSessionGoingAway() { | 
|  |