11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file. 41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/quic/quic_default_packet_writer.h" 61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/location.h" 81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/logging.h" 91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/metrics/sparse_histogram.h" 101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/base/io_buffer.h" 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/base/net_errors.h" 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace net { 141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)QuicDefaultPacketWriter::QuicDefaultPacketWriter() : weak_factory_(this) { 161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)QuicDefaultPacketWriter::QuicDefaultPacketWriter(DatagramClientSocket* socket) 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : socket_(socket), 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci write_blocked_(false), 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this) { 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)QuicDefaultPacketWriter::~QuicDefaultPacketWriter() {} 251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)WriteResult QuicDefaultPacketWriter::WritePacket( 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const char* buffer, size_t buf_len, 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const net::IPAddressNumber& self_address, 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::IPEndPoint& peer_address) { 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<StringIOBuffer> buf( 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new StringIOBuffer(std::string(buffer, buf_len))); 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!IsWriteBlocked()); 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int rv = socket_->Write(buf.get(), 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) buf_len, 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&QuicDefaultPacketWriter::OnWriteComplete, 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_factory_.GetWeakPtr())); 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteStatus status = WRITE_STATUS_OK; 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (rv < 0) { 391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (rv != ERR_IO_PENDING) { 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.WriteError", -rv); 411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) status = WRITE_STATUS_ERROR; 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) status = WRITE_STATUS_BLOCKED; 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) write_blocked_ = true; 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WriteResult(status, rv); 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool QuicDefaultPacketWriter::IsWriteBlockedDataBuffered() const { 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Chrome sockets' Write() methods buffer the data until the Write is 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // permitted. 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicDefaultPacketWriter::IsWriteBlocked() const { 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return write_blocked_; 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicDefaultPacketWriter::SetWritable() { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) write_blocked_ = false; 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void QuicDefaultPacketWriter::OnWriteComplete(int rv) { 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_NE(rv, ERR_IO_PENDING); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) write_blocked_ = false; 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (rv < 0) { 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) connection_->OnWriteError(rv); 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) connection_->OnCanWrite(); 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} // namespace net 75