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