blob: 60130a0e211c2f18f8e00036fd87951951c61947 [file] [log] [blame]
Andrew Top0d1858f2019-05-15 22:01:47 -07001// 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/tools/quic/quic_simple_server_packet_writer.h"
6
7#include "base/callback_helpers.h"
8#include "base/location.h"
9#include "base/logging.h"
10#include "base/metrics/histogram_functions.h"
11#include "net/base/io_buffer.h"
12#include "net/base/net_errors.h"
13#include "net/socket/udp_server_socket.h"
14#include "net/third_party/quic/core/quic_dispatcher.h"
15
16namespace net {
17
18QuicSimpleServerPacketWriter::QuicSimpleServerPacketWriter(
19 UDPServerSocket* socket,
20 quic::QuicDispatcher* dispatcher)
21 : socket_(socket),
22 dispatcher_(dispatcher),
23 write_blocked_(false),
24 weak_factory_(this) {}
25
26QuicSimpleServerPacketWriter::~QuicSimpleServerPacketWriter() = default;
27
28quic::WriteResult QuicSimpleServerPacketWriter::WritePacketWithCallback(
29 const char* buffer,
30 size_t buf_len,
31 const quic::QuicIpAddress& self_address,
32 const quic::QuicSocketAddress& peer_address,
33 quic::PerPacketOptions* options,
34 WriteCallback callback) {
35 DCHECK(callback_.is_null());
36 callback_ = callback;
37 quic::WriteResult result =
38 WritePacket(buffer, buf_len, self_address, peer_address, options);
39 if (result.status != quic::WRITE_STATUS_BLOCKED) {
40 callback_.Reset();
41 }
42 return result;
43}
44
45void QuicSimpleServerPacketWriter::OnWriteComplete(int rv) {
46 DCHECK_NE(rv, ERR_IO_PENDING);
47 write_blocked_ = false;
48 quic::WriteResult result(
49 rv < 0 ? quic::WRITE_STATUS_ERROR : quic::WRITE_STATUS_OK, rv);
50 if (!callback_.is_null()) {
51 base::ResetAndReturn(&callback_).Run(result);
52 }
53 dispatcher_->OnCanWrite();
54}
55
Chad Duffinac9ac062019-07-23 10:06:45 -070056#if !defined(COBALT_QUIC46)
Andrew Top0d1858f2019-05-15 22:01:47 -070057bool QuicSimpleServerPacketWriter::IsWriteBlockedDataBuffered() const {
58 // UDPServerSocket::SendTo buffers the data until the Write is permitted.
59 return true;
60}
Chad Duffinac9ac062019-07-23 10:06:45 -070061#endif
Andrew Top0d1858f2019-05-15 22:01:47 -070062
63bool QuicSimpleServerPacketWriter::IsWriteBlocked() const {
64 return write_blocked_;
65}
66
67void QuicSimpleServerPacketWriter::SetWritable() {
68 write_blocked_ = false;
69}
70
71quic::WriteResult QuicSimpleServerPacketWriter::WritePacket(
72 const char* buffer,
73 size_t buf_len,
74 const quic::QuicIpAddress& self_address,
75 const quic::QuicSocketAddress& peer_address,
76 quic::PerPacketOptions* options) {
77 scoped_refptr<StringIOBuffer> buf =
78 base::MakeRefCounted<StringIOBuffer>(std::string(buffer, buf_len));
79 DCHECK(!IsWriteBlocked());
80 int rv;
81 if (buf_len <= static_cast<size_t>(std::numeric_limits<int>::max())) {
82 rv = socket_->SendTo(
83 buf.get(), static_cast<int>(buf_len),
84 peer_address.impl().socket_address(),
85 base::Bind(&QuicSimpleServerPacketWriter::OnWriteComplete,
86 weak_factory_.GetWeakPtr()));
87 } else {
88 rv = ERR_MSG_TOO_BIG;
89 }
90 quic::WriteStatus status = quic::WRITE_STATUS_OK;
91 if (rv < 0) {
92 if (rv != ERR_IO_PENDING) {
93 base::UmaHistogramSparse("Net.quic::QuicSession.WriteError", -rv);
94 status = quic::WRITE_STATUS_ERROR;
95 } else {
96 status = quic::WRITE_STATUS_BLOCKED;
97 write_blocked_ = true;
98 }
99 }
100 return quic::WriteResult(status, rv);
101}
102
103quic::QuicByteCount QuicSimpleServerPacketWriter::GetMaxPacketSize(
104 const quic::QuicSocketAddress& peer_address) const {
105 return quic::kMaxPacketSize;
106}
107
108bool QuicSimpleServerPacketWriter::SupportsReleaseTime() const {
109 return false;
110}
111
112bool QuicSimpleServerPacketWriter::IsBatchMode() const {
113 return false;
114}
115
116char* QuicSimpleServerPacketWriter::GetNextWriteLocation(
117 const quic::QuicIpAddress& self_address,
118 const quic::QuicSocketAddress& peer_address) {
119 return nullptr;
120}
121
122quic::WriteResult QuicSimpleServerPacketWriter::Flush() {
123 return quic::WriteResult(quic::WRITE_STATUS_OK, 0);
124}
125
126} // namespace net