blob: 667254faf3351bdb2ad7edb59d5381e3b74af0c7 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright 2013 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#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
6#define QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_
7
8#include <cstddef>
9
10#include "net/third_party/quiche/src/quic/core/quic_packets.h"
11#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
14
15namespace quic {
16
17struct WriteResult;
18
19struct QUIC_EXPORT_PRIVATE PerPacketOptions {
20 virtual ~PerPacketOptions() {}
21
22 // Returns a heap-allocated copy of |this|.
23 //
24 // The subclass implementation of this method should look like this:
25 // return QuicMakeUnique<MyAwesomePerPacketOptions>(*this);
26 //
27 // This method is declared pure virtual in order to ensure the subclasses
28 // would not forget to override it.
29 virtual std::unique_ptr<PerPacketOptions> Clone() const = 0;
30
31 // Specifies release time delay for this packet.
32 QuicTime::Delta release_time_delay = QuicTime::Delta::Zero();
33};
34
35// An interface between writers and the entity managing the
36// socket (in our case the QuicDispatcher). This allows the Dispatcher to
37// control writes, and manage any writers who end up write blocked.
38// A concrete writer works in one of the two modes:
39// - PassThrough mode. This is the default mode. Caller calls WritePacket with
40// caller-allocated packet buffer. Unless the writer is blocked, each call to
41// WritePacket triggers a write using the underlying socket API.
42//
43// - Batch mode. In this mode, a call to WritePacket may not cause a packet to
44// be sent using the underlying socket API. Instead, multiple packets are
45// saved in the writer's internal buffer until they are flushed. The flush can
46// be explicit, by calling Flush, or implicit, e.g. by calling
47// WritePacket when the internal buffer is near full.
48//
49// Buffer management:
50// In Batch mode, a writer manages an internal buffer, which is large enough to
51// hold multiple packets' data. If the caller calls WritePacket with a
52// caller-allocated packet buffer, the writer will memcpy the buffer into the
53// internal buffer. Caller can also avoid this memcpy by:
54// 1. Call GetNextWriteLocation to get a pointer P into the internal buffer.
55// 2. Serialize the packet directly to P.
56// 3. Call WritePacket with P as the |buffer|.
57class QUIC_EXPORT_PRIVATE QuicPacketWriter {
58 public:
59 virtual ~QuicPacketWriter() {}
60
61 // PassThrough mode:
62 // Sends the packet out to the peer, with some optional per-packet options.
63 // If the write succeeded, the result's status is WRITE_STATUS_OK and
64 // bytes_written is populated. If the write failed, the result's status is
65 // WRITE_STATUS_BLOCKED or WRITE_STATUS_ERROR and error_code is populated.
66 //
67 // Batch mode:
68 // If the writer is blocked, return WRITE_STATUS_BLOCKED immediately.
69 // If the packet can be batched with other buffered packets, save the packet
70 // to the internal buffer.
71 // If the packet can not be batched, or the internal buffer is near full after
72 // it is buffered, the internal buffer is flushed to free up space.
73 // Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) on success. When
74 // <bytes_flushed> is zero, it means the packet is buffered and not flushed.
75 // Return WRITE_STATUS_BLOCKED if the packet is not buffered and the socket is
76 // blocked while flushing.
77 // Otherwise return an error status.
78 //
79 // Options must be either null, or created for the particular QuicPacketWriter
80 // implementation. Options may be ignored, depending on the implementation.
81 virtual WriteResult WritePacket(const char* buffer,
82 size_t buf_len,
83 const QuicIpAddress& self_address,
84 const QuicSocketAddress& peer_address,
85 PerPacketOptions* options) = 0;
86
87 // Returns true if the network socket is not writable.
88 virtual bool IsWriteBlocked() const = 0;
89
90 // Records that the socket has become writable, for example when an EPOLLOUT
91 // is received or an asynchronous write completes.
92 virtual void SetWritable() = 0;
93
94 // Returns the maximum size of the packet which can be written using this
95 // writer for the supplied peer address. This size may actually exceed the
96 // size of a valid QUIC packet.
97 virtual QuicByteCount GetMaxPacketSize(
98 const QuicSocketAddress& peer_address) const = 0;
99
100 // Returns true if the socket supports release timestamp.
101 virtual bool SupportsReleaseTime() const = 0;
102
103 // True=Batch mode. False=PassThrough mode.
104 virtual bool IsBatchMode() const = 0;
105
106 // PassThrough mode: Return nullptr.
107 //
108 // Batch mode:
109 // Return the starting address for the next packet's data. A minimum of
dschinazi66dea072019-04-09 11:41:06 -0700110 // kMaxOutgoingPacketSize is guaranteed to be available from the returned
111 // address. If the internal buffer does not have enough space, nullptr is
112 // returned. All arguments should be identical to the follow-up call to
113 // |WritePacket|, they are here to allow advanced packet memory management in
114 // packet writers, e.g. one packet buffer pool per |peer_address|.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115 virtual char* GetNextWriteLocation(const QuicIpAddress& self_address,
116 const QuicSocketAddress& peer_address) = 0;
117
118 // PassThrough mode: Return WriteResult(WRITE_STATUS_OK, 0).
119 //
120 // Batch mode:
121 // Try send all buffered packets.
122 // - Return WriteResult(WRITE_STATUS_OK, <bytes_flushed>) if all buffered
123 // packets were sent successfully.
124 // - Return WRITE_STATUS_BLOCKED, or an error status, if the underlying socket
125 // is blocked or returned an error while sending. Some packets may have been
126 // sent, packets not sent will stay in the internal buffer.
127 virtual WriteResult Flush() = 0;
128};
129
130} // namespace quic
131
132#endif // QUICHE_QUIC_CORE_QUIC_PACKET_WRITER_H_