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