forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathquic_chromium_packet_writer.h
136 lines (112 loc) · 5.13 KB
/
quic_chromium_packet_writer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2013 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.
#ifndef NET_QUIC_QUIC_CHROMIUM_PACKET_WRITER_H_
#define NET_QUIC_QUIC_CHROMIUM_PACKET_WRITER_H_
#include <stddef.h>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "net/base/completion_repeating_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_export.h"
#include "net/socket/datagram_client_socket.h"
#include "net/third_party/quiche/src/quic/core/quic_connection.h"
#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
namespace net {
// Chrome specific packet writer which uses a datagram Socket for writing data.
class NET_EXPORT_PRIVATE QuicChromiumPacketWriter
: public quic::QuicPacketWriter {
public:
// Define a specific IO buffer that can be allocated once, but be
// assigned new contents and reused, avoiding the alternative of
// repeated memory allocations. This packet writer only ever has a
// single write in flight, a constraint inherited from the interface
// of the underlying datagram Socket.
class NET_EXPORT_PRIVATE ReusableIOBuffer : public IOBuffer {
public:
explicit ReusableIOBuffer(size_t capacity);
size_t capacity() const { return capacity_; }
size_t size() const { return size_; }
// Does memcpy from |buffer| into this->data(). |buf_len <=
// capacity()| must be true, |HasOneRef()| must be true.
void Set(const char* buffer, size_t buf_len);
private:
~ReusableIOBuffer() override;
size_t capacity_;
size_t size_;
};
// Delegate interface which receives notifications on socket write events.
class NET_EXPORT_PRIVATE Delegate {
public:
// Called when a socket write attempt results in a failure, so
// that the delegate may recover from it by perhaps rewriting the
// packet to a different socket. An implementation must return the
// return value from the rewrite attempt if there is one, and
// |error_code| otherwise.
virtual int HandleWriteError(
int error_code,
scoped_refptr<ReusableIOBuffer> last_packet) = 0;
// Called to propagate the final write error to the delegate.
virtual void OnWriteError(int error_code) = 0;
// Called when the writer is unblocked due to a write completion.
virtual void OnWriteUnblocked() = 0;
};
QuicChromiumPacketWriter();
// |socket| and |task_runner| must outlive writer.
QuicChromiumPacketWriter(DatagramClientSocket* socket,
base::SequencedTaskRunner* task_runner);
~QuicChromiumPacketWriter() override;
// |delegate| must outlive writer.
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
// This method may unblock the packet writer if |force_write_blocked| is
// false.
void set_force_write_blocked(bool force_write_blocked);
// Writes |packet| to the socket and handles write result if the write
// completes synchronously.
void WritePacketToSocket(scoped_refptr<ReusableIOBuffer> packet);
// quic::QuicPacketWriter
quic::WriteResult WritePacket(const char* buffer,
size_t buf_len,
const quic::QuicIpAddress& self_address,
const quic::QuicSocketAddress& peer_address,
quic::PerPacketOptions* options) override;
bool IsWriteBlocked() const override;
void SetWritable() override;
quic::QuicByteCount GetMaxPacketSize(
const quic::QuicSocketAddress& peer_address) const override;
bool SupportsReleaseTime() const override;
bool IsBatchMode() const override;
quic::QuicPacketBuffer GetNextWriteLocation(
const quic::QuicIpAddress& self_address,
const quic::QuicSocketAddress& peer_address) override;
quic::WriteResult Flush() override;
void OnWriteComplete(int rv);
private:
void SetPacket(const char* buffer, size_t buf_len);
bool MaybeRetryAfterWriteError(int rv);
void RetryPacketAfterNoBuffers();
quic::WriteResult WritePacketToSocketImpl();
DatagramClientSocket* socket_; // Unowned.
Delegate* delegate_; // Unowned.
// Reused for every packet write for the lifetime of the writer. Is
// moved to the delegate in the case of a write error.
scoped_refptr<ReusableIOBuffer> packet_;
// Whether a write is currently in progress: true if an asynchronous write is
// in flight, or a retry of a previous write is in progress, or session is
// handling write error of a previous write.
bool write_in_progress_;
// If ture, IsWriteBlocked() will return true regardless of
// |write_in_progress_|.
bool force_write_blocked_;
int retry_count_;
// Timer set when a packet should be retried after ENOBUFS.
base::OneShotTimer retry_timer_;
CompletionRepeatingCallback write_callback_;
base::WeakPtrFactory<QuicChromiumPacketWriter> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(QuicChromiumPacketWriter);
};
} // namespace net
#endif // NET_QUIC_QUIC_CHROMIUM_PACKET_WRITER_H_