summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/net/dcsctp/rx/interleaved_reassembly_streams.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/net/dcsctp/rx/interleaved_reassembly_streams.h')
-rw-r--r--third_party/libwebrtc/net/dcsctp/rx/interleaved_reassembly_streams.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/third_party/libwebrtc/net/dcsctp/rx/interleaved_reassembly_streams.h b/third_party/libwebrtc/net/dcsctp/rx/interleaved_reassembly_streams.h
new file mode 100644
index 0000000000..a7b67707e9
--- /dev/null
+++ b/third_party/libwebrtc/net/dcsctp/rx/interleaved_reassembly_streams.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef NET_DCSCTP_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_
+#define NET_DCSCTP_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "net/dcsctp/common/sequence_numbers.h"
+#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
+#include "net/dcsctp/packet/data.h"
+#include "net/dcsctp/rx/reassembly_streams.h"
+
+namespace dcsctp {
+
+// Handles reassembly of incoming data when interleaved message sending is
+// enabled on the association, i.e. when RFC8260 is in use.
+class InterleavedReassemblyStreams : public ReassemblyStreams {
+ public:
+ InterleavedReassemblyStreams(absl::string_view log_prefix,
+ OnAssembledMessage on_assembled_message);
+
+ int Add(UnwrappedTSN tsn, Data data) override;
+
+ size_t HandleForwardTsn(
+ UnwrappedTSN new_cumulative_ack_tsn,
+ rtc::ArrayView<const AnyForwardTsnChunk::SkippedStream> skipped_streams)
+ override;
+
+ void ResetStreams(rtc::ArrayView<const StreamID> stream_ids) override;
+
+ HandoverReadinessStatus GetHandoverReadiness() const override;
+ void AddHandoverState(DcSctpSocketHandoverState& state) override;
+ void RestoreFromState(const DcSctpSocketHandoverState& state) override;
+
+ private:
+ struct FullStreamId {
+ const IsUnordered unordered;
+ const StreamID stream_id;
+
+ FullStreamId(IsUnordered unordered, StreamID stream_id)
+ : unordered(unordered), stream_id(stream_id) {}
+
+ friend bool operator<(FullStreamId a, FullStreamId b) {
+ return a.unordered < b.unordered ||
+ (!(a.unordered < b.unordered) && (a.stream_id < b.stream_id));
+ }
+ };
+
+ class Stream {
+ public:
+ Stream(FullStreamId stream_id,
+ InterleavedReassemblyStreams* parent,
+ MID next_mid = MID(0))
+ : stream_id_(stream_id),
+ parent_(*parent),
+ next_mid_(mid_unwrapper_.Unwrap(next_mid)) {}
+ int Add(UnwrappedTSN tsn, Data data);
+ size_t EraseTo(MID message_id);
+ void Reset() {
+ mid_unwrapper_.Reset();
+ next_mid_ = mid_unwrapper_.Unwrap(MID(0));
+ }
+ bool has_unassembled_chunks() const { return !chunks_by_mid_.empty(); }
+ void AddHandoverState(DcSctpSocketHandoverState& state) const;
+
+ private:
+ using ChunkMap = std::map<FSN, std::pair<UnwrappedTSN, Data>>;
+
+ // Try to assemble one message identified by `mid`.
+ // Returns the number of bytes assembled if a message was assembled.
+ size_t TryToAssembleMessage(UnwrappedMID mid);
+ size_t AssembleMessage(const ChunkMap& tsn_chunks);
+ // Try to assemble one or several messages in order from the stream.
+ // Returns the number of bytes assembled if one or more messages were
+ // assembled.
+ size_t TryToAssembleMessages();
+
+ const FullStreamId stream_id_;
+ InterleavedReassemblyStreams& parent_;
+ std::map<UnwrappedMID, ChunkMap> chunks_by_mid_;
+ UnwrappedMID::Unwrapper mid_unwrapper_;
+ UnwrappedMID next_mid_;
+ };
+
+ Stream& GetOrCreateStream(const FullStreamId& stream_id);
+
+ const std::string log_prefix_;
+
+ // Callback for when a message has been assembled.
+ const OnAssembledMessage on_assembled_message_;
+
+ // All unordered and ordered streams, managing not-yet-assembled data.
+ std::map<FullStreamId, Stream> streams_;
+};
+
+} // namespace dcsctp
+
+#endif // NET_DCSCTP_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_