1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/quic_server_packet_writer.h"
6
7 #include "base/location.h"
8 #include "base/logging.h"
9 #include "base/metrics/sparse_histogram.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
12
13 namespace net {
14
QuicServerPacketWriter()15 QuicServerPacketWriter::QuicServerPacketWriter() : weak_factory_(this) {
16 }
17
QuicServerPacketWriter(UDPServerSocket * socket)18 QuicServerPacketWriter::QuicServerPacketWriter(UDPServerSocket* socket)
19 : weak_factory_(this),
20 socket_(socket),
21 write_blocked_(false) {
22 }
23
~QuicServerPacketWriter()24 QuicServerPacketWriter::~QuicServerPacketWriter() {
25 }
26
WritePacket(const char * buffer,size_t buf_len,const net::IPAddressNumber & self_address,const net::IPEndPoint & peer_address)27 WriteResult QuicServerPacketWriter::WritePacket(
28 const char* buffer, size_t buf_len,
29 const net::IPAddressNumber& self_address,
30 const net::IPEndPoint& peer_address) {
31 scoped_refptr<StringIOBuffer> buf(
32 new StringIOBuffer(std::string(buffer, buf_len)));
33 DCHECK(!IsWriteBlocked());
34 int rv = socket_->SendTo(buf.get(),
35 buf_len,
36 peer_address,
37 base::Bind(&QuicServerPacketWriter::OnWriteComplete,
38 weak_factory_.GetWeakPtr()));
39 WriteStatus status = WRITE_STATUS_OK;
40 if (rv < 0) {
41 if (rv != ERR_IO_PENDING) {
42 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.WriteError", -rv);
43 status = WRITE_STATUS_ERROR;
44 } else {
45 status = WRITE_STATUS_BLOCKED;
46 write_blocked_ = true;
47 }
48 }
49
50 return WriteResult(status, rv);
51 }
52
IsWriteBlockedDataBuffered() const53 bool QuicServerPacketWriter::IsWriteBlockedDataBuffered() const {
54 // UDPServerSocket::SendTo buffers the data until the Write is permitted.
55 return true;
56 }
57
IsWriteBlocked() const58 bool QuicServerPacketWriter::IsWriteBlocked() const {
59 return write_blocked_;
60 }
61
SetWritable()62 void QuicServerPacketWriter::SetWritable() {
63 write_blocked_ = false;
64 }
65
OnWriteComplete(int rv)66 void QuicServerPacketWriter::OnWriteComplete(int rv) {
67 DCHECK_NE(rv, ERR_IO_PENDING);
68 write_blocked_ = false;
69 WriteResult result(rv < 0 ? WRITE_STATUS_ERROR : WRITE_STATUS_OK, rv);
70 connection_->OnPacketSent(result);
71 connection_->OnCanWrite();
72 }
73
74 } // namespace net
75