| // Copyright (c) 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_ |
| #define QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_ |
| |
| #include <cstdint> |
| |
| #include "net/third_party/quiche/src/quic/core/quic_time.h" |
| #include "net/third_party/quiche/src/quic/core/quic_types.h" |
| #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" |
| #include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h" |
| #include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" |
| #include "net/third_party/quiche/src/quic/quartc/quartc_endpoint.h" |
| #include "net/third_party/quiche/src/quic/quartc/quartc_session.h" |
| #include "net/third_party/quiche/src/quic/quartc/quartc_stream.h" |
| |
| namespace quic { |
| |
| class QuartcMultiplexer; |
| |
| // A single, multiplexed send channel within a Quartc session. A send channel |
| // wraps send-side operations with an outgoing multiplex id. |
| class QuartcSendChannel { |
| public: |
| class Delegate { |
| public: |
| virtual ~Delegate() = default; |
| |
| // Called when a message with |datagram_id| is sent by this channel. |
| virtual void OnMessageSent(int64_t datagram_id) = 0; |
| |
| // Called when a message sent on this channel with |datagram_id| is acked. |
| // |receive_timestamp| indicates when the peer received this message, |
| // according to the peer's clock. |
| virtual void OnMessageAcked(int64_t datagram_id, |
| QuicTime receive_timestamp) = 0; |
| |
| // Called when a message sent on this channel with |datagram_id| is lost. |
| virtual void OnMessageLost(int64_t datagram_id) = 0; |
| }; |
| |
| QuartcSendChannel(QuartcMultiplexer* multiplexer, |
| uint64_t id, |
| QuicBufferAllocator* allocator, |
| Delegate* delegate); |
| virtual ~QuartcSendChannel() = default; |
| |
| // Creates a new, outgoing stream on this channel. |
| // |
| // Automatically writes the channel id to the start of the stream. The caller |
| // SHOULD create a |ScopedPacketFlusher| before calling this function to |
| // prevent the channel id from being sent by itself. |
| QuartcStream* CreateOutgoingBidirectionalStream(); |
| |
| // Writes |message| to the session. Prepends the channel's send id before any |
| // following message data. |
| bool SendOrQueueMessage(QuicMemSliceSpan message, int64_t datagram_id); |
| |
| // Gets the current largest message payload for this channel. Returns the |
| // largest payload size supported by the session minus overhead required to |
| // encode this channel's send id. |
| QuicPacketLength GetCurrentLargestMessagePayload() const; |
| |
| // The following are called by the multiplexer to deliver message |
| // notifications. The |datagram_id| passed to these is unique per-message, |
| // and must be translated back to the sender's chosen datagram_id. |
| void OnMessageSent(int64_t datagram_id); |
| void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp); |
| void OnMessageLost(int64_t datagram_id); |
| void OnSessionCreated(QuartcSession* session); |
| |
| private: |
| // Creates a mem slice containing a varint-62 encoded channel id. |
| QuicMemSlice EncodeChannelId(); |
| |
| QuartcMultiplexer* const multiplexer_; |
| const uint64_t id_; |
| const QuicVariableLengthIntegerLength encoded_length_; |
| QuicBufferAllocator* const allocator_; |
| Delegate* const delegate_; |
| |
| QuartcSession* session_; |
| |
| // Map of multiplexer-chosen to user/caller-specified datagram ids. The user |
| // may specify any number as a datagram's id. This number does not have to be |
| // unique across channels (nor even within a single channel). In order |
| // to demux sent, acked, and lost messages, the multiplexer assigns a globally |
| // unique id to each message. This map is used to restore the original caller |
| // datagram id before issuing callbacks. |
| QuicUnorderedMap<int64_t, int64_t> multiplexer_to_user_datagram_ids_; |
| }; |
| |
| // A single, multiplexed receive channel within a Quartc session. A receive |
| // channel is a delegate which accepts incoming streams and datagrams on one (or |
| // more) channel ids. |
| class QuartcReceiveChannel { |
| public: |
| virtual ~QuartcReceiveChannel() = default; |
| |
| // Called when a new incoming stream arrives on this channel. |
| virtual void OnIncomingStream(uint64_t channel_id, QuartcStream* stream) = 0; |
| |
| // Called when a message is recieved by this channel. |
| virtual void OnMessageReceived(uint64_t channel_id, |
| QuicStringPiece message) = 0; |
| }; |
| |
| // Delegate for session-wide events. |
| class QuartcSessionEventDelegate { |
| public: |
| virtual ~QuartcSessionEventDelegate() = default; |
| |
| virtual void OnSessionCreated(QuartcSession* session) = 0; |
| virtual void OnCryptoHandshakeComplete() = 0; |
| virtual void OnConnectionWritable() = 0; |
| virtual void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, |
| QuicBandwidth pacing_rate, |
| QuicTime::Delta latest_rtt) = 0; |
| virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame, |
| ConnectionCloseSource source) = 0; |
| }; |
| |
| // A multiplexer capable of sending and receiving data on multiple channels. |
| class QuartcMultiplexer : public QuartcEndpoint::Delegate, |
| public QuartcStream::Delegate { |
| public: |
| // Creates a new multiplexer. |session_delegate| handles all session-wide |
| // events, while |default_receive_channel| handles incoming data on unknown |
| // or unregistered channel ids. Neither |session_delegate| nor |
| // |default_receive_channel| may be nullptr, and both must outlive the |
| // multiplexer. |
| QuartcMultiplexer(QuicBufferAllocator* allocator, |
| QuartcSessionEventDelegate* session_delegate, |
| QuartcReceiveChannel* default_receive_channel); |
| |
| // Creates a new send channel. The channel is owned by the multiplexer, and |
| // references to it must not outlive the multiplexer. |
| QuartcSendChannel* CreateSendChannel(uint64_t channel_id, |
| QuartcSendChannel::Delegate* delegate); |
| |
| // Registers a receiver for incoming data on |channel_id|. |
| void RegisterReceiveChannel(uint64_t channel_id, |
| QuartcReceiveChannel* channel); |
| |
| // Allocates a datagram id to |channel|. |
| int64_t AllocateDatagramId(QuartcSendChannel* channel); |
| |
| // QuartcEndpoint::Delegate overrides. |
| void OnSessionCreated(QuartcSession* session) override; |
| |
| // QuartcSession::Delegate overrides. |
| void OnCryptoHandshakeComplete() override; |
| void OnConnectionWritable() override; |
| void OnIncomingStream(QuartcStream* stream) override; |
| void OnCongestionControlChange(QuicBandwidth bandwidth_estimate, |
| QuicBandwidth pacing_rate, |
| QuicTime::Delta latest_rtt) override; |
| void OnConnectionClosed(const QuicConnectionCloseFrame& frame, |
| ConnectionCloseSource source) override; |
| void OnMessageReceived(QuicStringPiece message) override; |
| void OnMessageSent(int64_t datagram_id) override; |
| void OnMessageAcked(int64_t datagram_id, QuicTime receive_timestamp) override; |
| void OnMessageLost(int64_t datagram_id) override; |
| |
| // QuartcStream::Delegate overrides. |
| size_t OnReceived(QuartcStream* stream, |
| iovec* iov, |
| size_t iov_length, |
| bool fin) override; |
| void OnClose(QuartcStream* stream) override; |
| void OnBufferChanged(QuartcStream* stream) override; |
| |
| private: |
| QuicBufferAllocator* const allocator_; |
| QuartcSessionEventDelegate* const session_delegate_; |
| |
| QuartcSession* session_ = nullptr; |
| std::vector<std::unique_ptr<QuartcSendChannel>> send_channels_; |
| QuicUnorderedMap<uint64_t, QuartcReceiveChannel*> receive_channels_; |
| QuartcReceiveChannel* default_receive_channel_ = nullptr; |
| |
| int64_t next_datagram_id_ = 1; |
| QuicUnorderedMap<int64_t, QuartcSendChannel*> send_channels_by_datagram_id_; |
| }; |
| |
| } // namespace quic |
| |
| #endif // QUICHE_QUIC_QUARTC_QUARTC_MULTIPLEXER_H_ |