QUICHE team | 335e56f | 2019-07-29 15:06:31 -0700 | [diff] [blame] | 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" |
QUICHE team | 335e56f | 2019-07-29 15:06:31 -0700 | [diff] [blame] | 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" |
dmcardle | c60e87a | 2019-12-12 09:43:19 -0800 | [diff] [blame] | 17 | #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" |
QUICHE team | 335e56f | 2019-07-29 15:06:31 -0700 | [diff] [blame] | 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, |
dmcardle | c60e87a | 2019-12-12 09:43:19 -0800 | [diff] [blame] | 107 | quiche::QuicheStringPiece message) = 0; |
QUICHE team | 335e56f | 2019-07-29 15:06:31 -0700 | [diff] [blame] | 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; |
dmcardle | c60e87a | 2019-12-12 09:43:19 -0800 | [diff] [blame] | 162 | void OnMessageReceived(quiche::QuicheStringPiece message) override; |
QUICHE team | 335e56f | 2019-07-29 15:06:31 -0700 | [diff] [blame] | 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 | |
QUICHE team | 6dde48a | 2019-08-05 09:06:46 -0700 | [diff] [blame] | 179 | QuartcSession* session_ = nullptr; |
QUICHE team | 335e56f | 2019-07-29 15:06:31 -0700 | [diff] [blame] | 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_ |