• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #ifndef NET_DCSCTP_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_
11 #define NET_DCSCTP_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_
12 
13 #include <cstdint>
14 #include <map>
15 #include <string>
16 #include <utility>
17 
18 #include "absl/strings/string_view.h"
19 #include "api/array_view.h"
20 #include "net/dcsctp/common/sequence_numbers.h"
21 #include "net/dcsctp/packet/chunk/forward_tsn_common.h"
22 #include "net/dcsctp/packet/data.h"
23 #include "net/dcsctp/rx/reassembly_streams.h"
24 
25 namespace dcsctp {
26 
27 // Handles reassembly of incoming data when interleaved message sending is
28 // enabled on the association, i.e. when RFC8260 is in use.
29 class InterleavedReassemblyStreams : public ReassemblyStreams {
30  public:
31   InterleavedReassemblyStreams(absl::string_view log_prefix,
32                                OnAssembledMessage on_assembled_message);
33 
34   int Add(UnwrappedTSN tsn, Data data) override;
35 
36   size_t HandleForwardTsn(
37       UnwrappedTSN new_cumulative_ack_tsn,
38       rtc::ArrayView<const AnyForwardTsnChunk::SkippedStream> skipped_streams)
39       override;
40 
41   void ResetStreams(rtc::ArrayView<const StreamID> stream_ids) override;
42 
43   HandoverReadinessStatus GetHandoverReadiness() const override;
44   void AddHandoverState(DcSctpSocketHandoverState& state) override;
45   void RestoreFromState(const DcSctpSocketHandoverState& state) override;
46 
47  private:
48   struct FullStreamId {
49     const IsUnordered unordered;
50     const StreamID stream_id;
51 
FullStreamIdFullStreamId52     FullStreamId(IsUnordered unordered, StreamID stream_id)
53         : unordered(unordered), stream_id(stream_id) {}
54 
55     friend bool operator<(FullStreamId a, FullStreamId b) {
56       return a.unordered < b.unordered ||
57              (!(a.unordered < b.unordered) && (a.stream_id < b.stream_id));
58     }
59   };
60 
61   class Stream {
62    public:
63     Stream(FullStreamId stream_id,
64            InterleavedReassemblyStreams* parent,
65            MID next_mid = MID(0))
stream_id_(stream_id)66         : stream_id_(stream_id),
67           parent_(*parent),
68           next_mid_(mid_unwrapper_.Unwrap(next_mid)) {}
69     int Add(UnwrappedTSN tsn, Data data);
70     size_t EraseTo(MID message_id);
Reset()71     void Reset() {
72       mid_unwrapper_.Reset();
73       next_mid_ = mid_unwrapper_.Unwrap(MID(0));
74     }
has_unassembled_chunks()75     bool has_unassembled_chunks() const { return !chunks_by_mid_.empty(); }
76     void AddHandoverState(DcSctpSocketHandoverState& state) const;
77 
78    private:
79     using ChunkMap = std::map<FSN, std::pair<UnwrappedTSN, Data>>;
80 
81     // Try to assemble one message identified by `mid`.
82     // Returns the number of bytes assembled if a message was assembled.
83     size_t TryToAssembleMessage(UnwrappedMID mid);
84     size_t AssembleMessage(const ChunkMap& tsn_chunks);
85     // Try to assemble one or several messages in order from the stream.
86     // Returns the number of bytes assembled if one or more messages were
87     // assembled.
88     size_t TryToAssembleMessages();
89 
90     const FullStreamId stream_id_;
91     InterleavedReassemblyStreams& parent_;
92     std::map<UnwrappedMID, ChunkMap> chunks_by_mid_;
93     UnwrappedMID::Unwrapper mid_unwrapper_;
94     UnwrappedMID next_mid_;
95   };
96 
97   Stream& GetOrCreateStream(const FullStreamId& stream_id);
98 
99   const std::string log_prefix_;
100 
101   // Callback for when a message has been assembled.
102   const OnAssembledMessage on_assembled_message_;
103 
104   // All unordered and ordered streams, managing not-yet-assembled data.
105   std::map<FullStreamId, Stream> streams_;
106 };
107 
108 }  // namespace dcsctp
109 
110 #endif  // NET_DCSCTP_RX_INTERLEAVED_REASSEMBLY_STREAMS_H_
111