1 // Copyright (c) 2019 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_QUARTC_QUARTC_MULTIPLEXER_H_
6 #define QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_
7 
8 #include <cstdint>
9 
10 #include "net/third_party/quiche/src/quic/core/quic_time.h"
11 #include "net/third_party/quiche/src/quic/core/quic_types.h"
12 #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
13 #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h"
14 #include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h"
15 #include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
16 #include "net/third_party/quiche/src/quic/quartc/quartc_stream.h"
17 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
18 
19 namespace quic {
20 
21 class QuartcMultiplexer;
22 
23 // A single, multiplexed send channel within a Quartc session.  A send channel
24 // wraps send-side operations with an outgoing multiplex id.
25 class QuartcSendChannel {
26  public:
27   class Delegate {
28    public:
29     virtual ~Delegate() = default;
30 
31     // Called when a message with |datagram_id| is sent by this channel.
32     virtual void OnMessageSent(int64_t datagram_id) = 0;
33 
34     // Called when a message sent on this channel with |datagram_id| is acked.
35     // |receive_timestamp| indicates when the peer received this message,
36     // according to the peer's clock.
37     virtual void OnMessageAcked(int64_t datagram_id,
38                                 QuicTime receive_timestamp) = 0;
39 
40     // Called when a message sent on this channel with |datagram_id| is lost.
41     virtual void OnMessageLost(int64_t datagram_id) = 0;
42   };
43 
44   QuartcSendChannel(QuartcMultiplexer* multiplexer,
45                     uint64_t id,
46                     QuicBufferAllocator* allocator,
47                     Delegate* delegate);
48   virtual ~QuartcSendChannel() = default;
49 
50   // Creates a new, outgoing stream on this channel.
51   //
52   // Automatically writes the channel id to the start of the stream.  The caller
53   // SHOULD create a |ScopedPacketFlusher| before calling this function to
54   // prevent the channel id from being sent by itself.
55   QuartcStream* CreateOutgoingBidirectionalStream();
56 
57   // Writes |message| to the session.  Prepends the channel's send id before any
58   // following message data.
59   bool SendOrQueueMessage(QuicMemSliceSpan message, int64_t datagram_id);
60 
61   // Gets the current largest message payload for this channel.  Returns the
62   // largest payload size supported by the session minus overhead required to
63   // encode this channel's send id.
64   QuicPacketLength GetCurrentLargestMessagePayload() const;
65 
66   // The following are called by the multiplexer to deliver message
67   // notifications.  The |datagram_id| passed to these is unique per-message,
68   // and must be translated back to the sender's chosen datagram_id.
69   void OnMessageSent(int64_t datagram_id);
70   void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp);
71   void OnMessageLost(int64_t datagram_id);
72   void OnSessionCreated(QuartcSession* session);
73 
74  private:
75   // Creates a mem slice containing a varint-62 encoded channel id.
76   QuicMemSlice EncodeChannelId();
77 
78   QuartcMultiplexer* const multiplexer_;
79   const uint64_t id_;
80   const QuicVariableLengthIntegerLength encoded_length_;
81   QuicBufferAllocator* const allocator_;
82   Delegate* const delegate_;
83 
84   QuartcSession* session_;
85 
86   // Map of multiplexer-chosen to user/caller-specified datagram ids.  The user
87   // may specify any number as a datagram's id.  This number does not have to be
88   // unique across channels (nor even within a single channel).  In order
89   // to demux sent, acked, and lost messages, the multiplexer assigns a globally
90   // unique id to each message.  This map is used to restore the original caller
91   // datagram id before issuing callbacks.
92   QuicUnorderedMap<int64_t, int64_t> multiplexer_to_user_datagram_ids_;
93 };
94 
95 // A single, multiplexed receive channel within a Quartc session.  A receive
96 // channel is a delegate which accepts incoming streams and datagrams on one (or
97 // more) channel ids.
98 class QuartcReceiveChannel {
99  public:
100   virtual ~QuartcReceiveChannel() = default;
101 
102   // Called when a new incoming stream arrives on this channel.
103   virtual void OnIncomingStream(uint64_t channel_id, QuartcStream* stream) = 0;
104 
105   // Called when a message is recieved by this channel.
106   virtual void OnMessageReceived(uint64_t channel_id,
107                                  quiche::QuicheStringPiece message) = 0;
108 };
109 
110 // Delegate for session-wide events.
111 class QuartcSessionEventDelegate {
112  public:
113   virtual ~QuartcSessionEventDelegate() = default;
114 
115   virtual void OnSessionCreated(QuartcSession* session) = 0;
116   virtual void OnCryptoHandshakeComplete() = 0;
117   virtual void OnConnectionWritable() = 0;
118   virtual void OnCongestionControlChange(QuicBandwidth bandwidth_estimate,
119                                          QuicBandwidth pacing_rate,
120                                          QuicTime::Delta latest_rtt) = 0;
121   virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
122                                   ConnectionCloseSource source) = 0;
123 };
124 
125 // A multiplexer capable of sending and receiving data on multiple channels.
126 class QuartcMultiplexer : public QuartcEndpoint::Delegate,
127                           public QuartcStream::Delegate {
128  public:
129   // Creates a new multiplexer.  |session_delegate| handles all session-wide
130   // events, while |default_receive_channel| handles incoming data on unknown
131   // or unregistered channel ids.  Neither |session_delegate| nor
132   // |default_receive_channel| may be nullptr, and both must outlive the
133   // multiplexer.
134   QuartcMultiplexer(QuicBufferAllocator* allocator,
135                     QuartcSessionEventDelegate* session_delegate,
136                     QuartcReceiveChannel* default_receive_channel);
137 
138   // Creates a new send channel.  The channel is owned by the multiplexer, and
139   // references to it must not outlive the multiplexer.
140   QuartcSendChannel* CreateSendChannel(uint64_t channel_id,
141                                        QuartcSendChannel::Delegate* delegate);
142 
143   // Registers a receiver for incoming data on |channel_id|.
144   void RegisterReceiveChannel(uint64_t channel_id,
145                               QuartcReceiveChannel* channel);
146 
147   // Allocates a datagram id to |channel|.
148   int64_t AllocateDatagramId(QuartcSendChannel* channel);
149 
150   // QuartcEndpoint::Delegate overrides.
151   void OnSessionCreated(QuartcSession* session) override;
152 
153   // QuartcSession::Delegate overrides.
154   void OnCryptoHandshakeComplete() override;
155   void OnConnectionWritable() override;
156   void OnIncomingStream(QuartcStream* stream) override;
157   void OnCongestionControlChange(QuicBandwidth bandwidth_estimate,
158                                  QuicBandwidth pacing_rate,
159                                  QuicTime::Delta latest_rtt) override;
160   void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
161                           ConnectionCloseSource source) override;
162   void OnMessageReceived(quiche::QuicheStringPiece message) override;
163   void OnMessageSent(int64_t datagram_id) override;
164   void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp) override;
165   void OnMessageLost(int64_t datagram_id) override;
166 
167   // QuartcStream::Delegate overrides.
168   size_t OnReceived(QuartcStream* stream,
169                     iovec* iov,
170                     size_t iov_length,
171                     bool fin) override;
172   void OnClose(QuartcStream* stream) override;
173   void OnBufferChanged(QuartcStream* stream) override;
174 
175  private:
176   QuicBufferAllocator* const allocator_;
177   QuartcSessionEventDelegate* const session_delegate_;
178 
179   QuartcSession* session_ = nullptr;
180   std::vector<std::unique_ptr<QuartcSendChannel>> send_channels_;
181   QuicUnorderedMap<uint64_t, QuartcReceiveChannel*> receive_channels_;
182   QuartcReceiveChannel* default_receive_channel_ = nullptr;
183 
184   int64_t next_datagram_id_ = 1;
185   QuicUnorderedMap<int64_t, QuartcSendChannel*> send_channels_by_datagram_id_;
186 };
187 
188 }  // namespace quic
189 
190 #endif  // QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_
191