• 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 #include "net/dcsctp/rx/reassembly_queue.h"
11 
12 #include <stddef.h>
13 
14 #include <algorithm>
15 #include <array>
16 #include <cstdint>
17 #include <iterator>
18 #include <vector>
19 
20 #include "api/array_view.h"
21 #include "net/dcsctp/common/handover_testing.h"
22 #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
23 #include "net/dcsctp/packet/chunk/forward_tsn_common.h"
24 #include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h"
25 #include "net/dcsctp/packet/data.h"
26 #include "net/dcsctp/public/dcsctp_message.h"
27 #include "net/dcsctp/public/types.h"
28 #include "net/dcsctp/testing/data_generator.h"
29 #include "rtc_base/gunit.h"
30 #include "test/gmock.h"
31 
32 namespace dcsctp {
33 namespace {
34 using ::testing::ElementsAre;
35 using ::testing::SizeIs;
36 using ::testing::UnorderedElementsAre;
37 
38 // The default maximum size of the Reassembly Queue.
39 static constexpr size_t kBufferSize = 10000;
40 
41 static constexpr StreamID kStreamID(1);
42 static constexpr SSN kSSN(0);
43 static constexpr MID kMID(0);
44 static constexpr FSN kFSN(0);
45 static constexpr PPID kPPID(53);
46 
47 static constexpr std::array<uint8_t, 4> kShortPayload = {1, 2, 3, 4};
48 static constexpr std::array<uint8_t, 4> kMessage2Payload = {5, 6, 7, 8};
49 static constexpr std::array<uint8_t, 6> kSixBytePayload = {1, 2, 3, 4, 5, 6};
50 static constexpr std::array<uint8_t, 8> kMediumPayload1 = {1, 2, 3, 4,
51                                                            5, 6, 7, 8};
52 static constexpr std::array<uint8_t, 8> kMediumPayload2 = {9,  10, 11, 12,
53                                                            13, 14, 15, 16};
54 static constexpr std::array<uint8_t, 16> kLongPayload = {
55     1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
56 
57 MATCHER_P3(SctpMessageIs, stream_id, ppid, expected_payload, "") {
58   if (arg.stream_id() != stream_id) {
59     *result_listener << "the stream_id is " << *arg.stream_id();
60     return false;
61   }
62 
63   if (arg.ppid() != ppid) {
64     *result_listener << "the ppid is " << *arg.ppid();
65     return false;
66   }
67 
68   if (std::vector<uint8_t>(arg.payload().begin(), arg.payload().end()) !=
69       std::vector<uint8_t>(expected_payload.begin(), expected_payload.end())) {
70     *result_listener << "the payload is wrong";
71     return false;
72   }
73   return true;
74 }
75 
76 class ReassemblyQueueTest : public testing::Test {
77  protected:
ReassemblyQueueTest()78   ReassemblyQueueTest() {}
79   DataGenerator gen_;
80 };
81 
TEST_F(ReassemblyQueueTest,EmptyQueue)82 TEST_F(ReassemblyQueueTest, EmptyQueue) {
83   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
84   EXPECT_FALSE(reasm.HasMessages());
85   EXPECT_EQ(reasm.queued_bytes(), 0u);
86 }
87 
TEST_F(ReassemblyQueueTest,SingleUnorderedChunkMessage)88 TEST_F(ReassemblyQueueTest, SingleUnorderedChunkMessage) {
89   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
90   reasm.Add(TSN(10), gen_.Unordered({1, 2, 3, 4}, "BE"));
91   EXPECT_TRUE(reasm.HasMessages());
92   EXPECT_THAT(reasm.FlushMessages(),
93               ElementsAre(SctpMessageIs(kStreamID, kPPID, kShortPayload)));
94   EXPECT_EQ(reasm.queued_bytes(), 0u);
95 }
96 
TEST_F(ReassemblyQueueTest,LargeUnorderedChunkAllPermutations)97 TEST_F(ReassemblyQueueTest, LargeUnorderedChunkAllPermutations) {
98   std::vector<uint32_t> tsns = {10, 11, 12, 13};
99   rtc::ArrayView<const uint8_t> payload(kLongPayload);
100   do {
101     ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
102 
103     for (size_t i = 0; i < tsns.size(); i++) {
104       auto span = payload.subview((tsns[i] - 10) * 4, 4);
105       Data::IsBeginning is_beginning(tsns[i] == 10);
106       Data::IsEnd is_end(tsns[i] == 13);
107 
108       reasm.Add(TSN(tsns[i]),
109                 Data(kStreamID, kSSN, kMID, kFSN, kPPID,
110                      std::vector<uint8_t>(span.begin(), span.end()),
111                      is_beginning, is_end, IsUnordered(false)));
112       if (i < 3) {
113         EXPECT_FALSE(reasm.HasMessages());
114       } else {
115         EXPECT_TRUE(reasm.HasMessages());
116         EXPECT_THAT(reasm.FlushMessages(),
117                     ElementsAre(SctpMessageIs(kStreamID, kPPID, kLongPayload)));
118         EXPECT_EQ(reasm.queued_bytes(), 0u);
119       }
120     }
121   } while (std::next_permutation(std::begin(tsns), std::end(tsns)));
122 }
123 
TEST_F(ReassemblyQueueTest,SingleOrderedChunkMessage)124 TEST_F(ReassemblyQueueTest, SingleOrderedChunkMessage) {
125   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
126   reasm.Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE"));
127   EXPECT_EQ(reasm.queued_bytes(), 0u);
128   EXPECT_TRUE(reasm.HasMessages());
129   EXPECT_THAT(reasm.FlushMessages(),
130               ElementsAre(SctpMessageIs(kStreamID, kPPID, kShortPayload)));
131 }
132 
TEST_F(ReassemblyQueueTest,ManySmallOrderedMessages)133 TEST_F(ReassemblyQueueTest, ManySmallOrderedMessages) {
134   std::vector<uint32_t> tsns = {10, 11, 12, 13};
135   rtc::ArrayView<const uint8_t> payload(kLongPayload);
136   do {
137     ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
138     for (size_t i = 0; i < tsns.size(); i++) {
139       auto span = payload.subview((tsns[i] - 10) * 4, 4);
140       Data::IsBeginning is_beginning(true);
141       Data::IsEnd is_end(true);
142 
143       SSN ssn(static_cast<uint16_t>(tsns[i] - 10));
144       reasm.Add(TSN(tsns[i]),
145                 Data(kStreamID, ssn, kMID, kFSN, kPPID,
146                      std::vector<uint8_t>(span.begin(), span.end()),
147                      is_beginning, is_end, IsUnordered(false)));
148     }
149     EXPECT_THAT(
150         reasm.FlushMessages(),
151         ElementsAre(SctpMessageIs(kStreamID, kPPID, payload.subview(0, 4)),
152                     SctpMessageIs(kStreamID, kPPID, payload.subview(4, 4)),
153                     SctpMessageIs(kStreamID, kPPID, payload.subview(8, 4)),
154                     SctpMessageIs(kStreamID, kPPID, payload.subview(12, 4))));
155     EXPECT_EQ(reasm.queued_bytes(), 0u);
156   } while (std::next_permutation(std::begin(tsns), std::end(tsns)));
157 }
158 
TEST_F(ReassemblyQueueTest,RetransmissionInLargeOrdered)159 TEST_F(ReassemblyQueueTest, RetransmissionInLargeOrdered) {
160   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
161   reasm.Add(TSN(10), gen_.Ordered({1}, "B"));
162   reasm.Add(TSN(12), gen_.Ordered({3}));
163   reasm.Add(TSN(13), gen_.Ordered({4}));
164   reasm.Add(TSN(14), gen_.Ordered({5}));
165   reasm.Add(TSN(15), gen_.Ordered({6}));
166   reasm.Add(TSN(16), gen_.Ordered({7}));
167   reasm.Add(TSN(17), gen_.Ordered({8}));
168   EXPECT_EQ(reasm.queued_bytes(), 7u);
169 
170   // lost and retransmitted
171   reasm.Add(TSN(11), gen_.Ordered({2}));
172   reasm.Add(TSN(18), gen_.Ordered({9}));
173   reasm.Add(TSN(19), gen_.Ordered({10}));
174   EXPECT_EQ(reasm.queued_bytes(), 10u);
175   EXPECT_FALSE(reasm.HasMessages());
176 
177   reasm.Add(TSN(20), gen_.Ordered({11, 12, 13, 14, 15, 16}, "E"));
178   EXPECT_TRUE(reasm.HasMessages());
179   EXPECT_THAT(reasm.FlushMessages(),
180               ElementsAre(SctpMessageIs(kStreamID, kPPID, kLongPayload)));
181   EXPECT_EQ(reasm.queued_bytes(), 0u);
182 }
183 
TEST_F(ReassemblyQueueTest,ForwardTSNRemoveUnordered)184 TEST_F(ReassemblyQueueTest, ForwardTSNRemoveUnordered) {
185   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
186   reasm.Add(TSN(10), gen_.Unordered({1}, "B"));
187   reasm.Add(TSN(12), gen_.Unordered({3}));
188   reasm.Add(TSN(13), gen_.Unordered({4}, "E"));
189 
190   reasm.Add(TSN(14), gen_.Unordered({5}, "B"));
191   reasm.Add(TSN(15), gen_.Unordered({6}));
192   reasm.Add(TSN(17), gen_.Unordered({8}, "E"));
193   EXPECT_EQ(reasm.queued_bytes(), 6u);
194 
195   EXPECT_FALSE(reasm.HasMessages());
196 
197   reasm.Handle(ForwardTsnChunk(TSN(13), {}));
198   EXPECT_EQ(reasm.queued_bytes(), 3u);
199 
200   // The lost chunk comes, but too late.
201   reasm.Add(TSN(11), gen_.Unordered({2}));
202   EXPECT_FALSE(reasm.HasMessages());
203   EXPECT_EQ(reasm.queued_bytes(), 3u);
204 
205   // The second lost chunk comes, message is assembled.
206   reasm.Add(TSN(16), gen_.Unordered({7}));
207   EXPECT_TRUE(reasm.HasMessages());
208   EXPECT_EQ(reasm.queued_bytes(), 0u);
209 }
210 
TEST_F(ReassemblyQueueTest,ForwardTSNRemoveOrdered)211 TEST_F(ReassemblyQueueTest, ForwardTSNRemoveOrdered) {
212   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
213   reasm.Add(TSN(10), gen_.Ordered({1}, "B"));
214   reasm.Add(TSN(12), gen_.Ordered({3}));
215   reasm.Add(TSN(13), gen_.Ordered({4}, "E"));
216 
217   reasm.Add(TSN(14), gen_.Ordered({5}, "B"));
218   reasm.Add(TSN(15), gen_.Ordered({6}));
219   reasm.Add(TSN(16), gen_.Ordered({7}));
220   reasm.Add(TSN(17), gen_.Ordered({8}, "E"));
221   EXPECT_EQ(reasm.queued_bytes(), 7u);
222 
223   EXPECT_FALSE(reasm.HasMessages());
224 
225   reasm.Handle(ForwardTsnChunk(
226       TSN(13), {ForwardTsnChunk::SkippedStream(kStreamID, kSSN)}));
227   EXPECT_EQ(reasm.queued_bytes(), 0u);
228 
229   // The lost chunk comes, but too late.
230   EXPECT_TRUE(reasm.HasMessages());
231   EXPECT_THAT(reasm.FlushMessages(),
232               ElementsAre(SctpMessageIs(kStreamID, kPPID, kMessage2Payload)));
233 }
234 
TEST_F(ReassemblyQueueTest,ForwardTSNRemoveALotOrdered)235 TEST_F(ReassemblyQueueTest, ForwardTSNRemoveALotOrdered) {
236   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
237   reasm.Add(TSN(10), gen_.Ordered({1}, "B"));
238   reasm.Add(TSN(12), gen_.Ordered({3}));
239   reasm.Add(TSN(13), gen_.Ordered({4}, "E"));
240 
241   reasm.Add(TSN(15), gen_.Ordered({5}, "B"));
242   reasm.Add(TSN(16), gen_.Ordered({6}));
243   reasm.Add(TSN(17), gen_.Ordered({7}));
244   reasm.Add(TSN(18), gen_.Ordered({8}, "E"));
245   EXPECT_EQ(reasm.queued_bytes(), 7u);
246 
247   EXPECT_FALSE(reasm.HasMessages());
248 
249   reasm.Handle(ForwardTsnChunk(
250       TSN(13), {ForwardTsnChunk::SkippedStream(kStreamID, kSSN)}));
251   EXPECT_EQ(reasm.queued_bytes(), 0u);
252 
253   // The lost chunk comes, but too late.
254   EXPECT_TRUE(reasm.HasMessages());
255   EXPECT_THAT(reasm.FlushMessages(),
256               ElementsAre(SctpMessageIs(kStreamID, kPPID, kMessage2Payload)));
257 }
258 
TEST_F(ReassemblyQueueTest,ShouldntDeliverMessagesBeforeInitialTsn)259 TEST_F(ReassemblyQueueTest, ShouldntDeliverMessagesBeforeInitialTsn) {
260   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
261   reasm.Add(TSN(5), gen_.Unordered({1, 2, 3, 4}, "BE"));
262   EXPECT_EQ(reasm.queued_bytes(), 0u);
263   EXPECT_FALSE(reasm.HasMessages());
264 }
265 
TEST_F(ReassemblyQueueTest,ShouldntRedeliverUnorderedMessages)266 TEST_F(ReassemblyQueueTest, ShouldntRedeliverUnorderedMessages) {
267   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
268   reasm.Add(TSN(10), gen_.Unordered({1, 2, 3, 4}, "BE"));
269   EXPECT_EQ(reasm.queued_bytes(), 0u);
270   EXPECT_TRUE(reasm.HasMessages());
271   EXPECT_THAT(reasm.FlushMessages(),
272               ElementsAre(SctpMessageIs(kStreamID, kPPID, kShortPayload)));
273   reasm.Add(TSN(10), gen_.Unordered({1, 2, 3, 4}, "BE"));
274   EXPECT_EQ(reasm.queued_bytes(), 0u);
275   EXPECT_FALSE(reasm.HasMessages());
276 }
277 
TEST_F(ReassemblyQueueTest,ShouldntRedeliverUnorderedMessagesReallyUnordered)278 TEST_F(ReassemblyQueueTest, ShouldntRedeliverUnorderedMessagesReallyUnordered) {
279   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
280   reasm.Add(TSN(10), gen_.Unordered({1, 2, 3, 4}, "B"));
281   EXPECT_EQ(reasm.queued_bytes(), 4u);
282 
283   EXPECT_FALSE(reasm.HasMessages());
284 
285   reasm.Add(TSN(12), gen_.Unordered({1, 2, 3, 4}, "BE"));
286   EXPECT_EQ(reasm.queued_bytes(), 4u);
287   EXPECT_TRUE(reasm.HasMessages());
288 
289   EXPECT_THAT(reasm.FlushMessages(),
290               ElementsAre(SctpMessageIs(kStreamID, kPPID, kShortPayload)));
291   reasm.Add(TSN(12), gen_.Unordered({1, 2, 3, 4}, "BE"));
292   EXPECT_EQ(reasm.queued_bytes(), 4u);
293   EXPECT_FALSE(reasm.HasMessages());
294 }
295 
TEST_F(ReassemblyQueueTest,ShouldntDeliverBeforeForwardedTsn)296 TEST_F(ReassemblyQueueTest, ShouldntDeliverBeforeForwardedTsn) {
297   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
298   reasm.Handle(ForwardTsnChunk(TSN(12), {}));
299 
300   reasm.Add(TSN(12), gen_.Unordered({1, 2, 3, 4}, "BE"));
301   EXPECT_EQ(reasm.queued_bytes(), 0u);
302   EXPECT_FALSE(reasm.HasMessages());
303 }
304 
TEST_F(ReassemblyQueueTest,NotReadyForHandoverWhenDeliveredTsnsHaveGap)305 TEST_F(ReassemblyQueueTest, NotReadyForHandoverWhenDeliveredTsnsHaveGap) {
306   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
307   reasm.Add(TSN(10), gen_.Unordered({1, 2, 3, 4}, "B"));
308   EXPECT_FALSE(reasm.HasMessages());
309 
310   reasm.Add(TSN(12), gen_.Unordered({1, 2, 3, 4}, "BE"));
311   EXPECT_TRUE(reasm.HasMessages());
312   EXPECT_EQ(
313       reasm.GetHandoverReadiness(),
314       HandoverReadinessStatus()
315           .Add(HandoverUnreadinessReason::kReassemblyQueueDeliveredTSNsGap)
316           .Add(
317               HandoverUnreadinessReason::kUnorderedStreamHasUnassembledChunks));
318 
319   EXPECT_THAT(reasm.FlushMessages(),
320               ElementsAre(SctpMessageIs(kStreamID, kPPID, kShortPayload)));
321   EXPECT_EQ(
322       reasm.GetHandoverReadiness(),
323       HandoverReadinessStatus()
324           .Add(HandoverUnreadinessReason::kReassemblyQueueDeliveredTSNsGap)
325           .Add(
326               HandoverUnreadinessReason::kUnorderedStreamHasUnassembledChunks));
327 
328   reasm.Handle(ForwardTsnChunk(TSN(13), {}));
329   EXPECT_EQ(reasm.GetHandoverReadiness(), HandoverReadinessStatus());
330 }
331 
TEST_F(ReassemblyQueueTest,NotReadyForHandoverWhenResetStreamIsDeferred)332 TEST_F(ReassemblyQueueTest, NotReadyForHandoverWhenResetStreamIsDeferred) {
333   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
334   DataGeneratorOptions opts;
335   opts.message_id = MID(0);
336   reasm.Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE", opts));
337   opts.message_id = MID(1);
338   reasm.Add(TSN(11), gen_.Ordered({1, 2, 3, 4}, "BE", opts));
339   EXPECT_THAT(reasm.FlushMessages(), SizeIs(2));
340 
341   reasm.ResetStreams(
342       OutgoingSSNResetRequestParameter(
343           ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(13), {StreamID(1)}),
344       TSN(11));
345   EXPECT_EQ(reasm.GetHandoverReadiness(),
346             HandoverReadinessStatus().Add(
347                 HandoverUnreadinessReason::kStreamResetDeferred));
348 
349   opts.message_id = MID(3);
350   opts.ppid = PPID(3);
351   reasm.Add(TSN(13), gen_.Ordered({1, 2, 3, 4}, "BE", opts));
352   reasm.MaybeResetStreamsDeferred(TSN(11));
353 
354   opts.message_id = MID(2);
355   opts.ppid = PPID(2);
356   reasm.Add(TSN(13), gen_.Ordered({1, 2, 3, 4}, "BE", opts));
357   reasm.MaybeResetStreamsDeferred(TSN(15));
358   EXPECT_EQ(reasm.GetHandoverReadiness(),
359             HandoverReadinessStatus().Add(
360                 HandoverUnreadinessReason::kReassemblyQueueDeliveredTSNsGap));
361 
362   EXPECT_THAT(reasm.FlushMessages(), SizeIs(2));
363   EXPECT_EQ(reasm.GetHandoverReadiness(),
364             HandoverReadinessStatus().Add(
365                 HandoverUnreadinessReason::kReassemblyQueueDeliveredTSNsGap));
366 
367   reasm.Handle(ForwardTsnChunk(TSN(15), {}));
368   EXPECT_EQ(reasm.GetHandoverReadiness(), HandoverReadinessStatus());
369 }
370 
TEST_F(ReassemblyQueueTest,HandoverInInitialState)371 TEST_F(ReassemblyQueueTest, HandoverInInitialState) {
372   ReassemblyQueue reasm1("log: ", TSN(10), kBufferSize);
373 
374   EXPECT_EQ(reasm1.GetHandoverReadiness(), HandoverReadinessStatus());
375   DcSctpSocketHandoverState state;
376   reasm1.AddHandoverState(state);
377   g_handover_state_transformer_for_test(&state);
378   ReassemblyQueue reasm2("log: ", TSN(100), kBufferSize,
379                          /*use_message_interleaving=*/false);
380   reasm2.RestoreFromState(state);
381 
382   reasm2.Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE"));
383   EXPECT_THAT(reasm2.FlushMessages(), SizeIs(1));
384 }
385 
TEST_F(ReassemblyQueueTest,HandoverAfterHavingAssembedOneMessage)386 TEST_F(ReassemblyQueueTest, HandoverAfterHavingAssembedOneMessage) {
387   ReassemblyQueue reasm1("log: ", TSN(10), kBufferSize);
388   reasm1.Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE"));
389   EXPECT_THAT(reasm1.FlushMessages(), SizeIs(1));
390 
391   EXPECT_EQ(reasm1.GetHandoverReadiness(), HandoverReadinessStatus());
392   DcSctpSocketHandoverState state;
393   reasm1.AddHandoverState(state);
394   g_handover_state_transformer_for_test(&state);
395   ReassemblyQueue reasm2("log: ", TSN(100), kBufferSize,
396                          /*use_message_interleaving=*/false);
397   reasm2.RestoreFromState(state);
398 
399   reasm2.Add(TSN(11), gen_.Ordered({1, 2, 3, 4}, "BE"));
400   EXPECT_THAT(reasm2.FlushMessages(), SizeIs(1));
401 }
402 
TEST_F(ReassemblyQueueTest,HandleInconsistentForwardTSN)403 TEST_F(ReassemblyQueueTest, HandleInconsistentForwardTSN) {
404   // Found when fuzzing.
405   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize);
406   // Add TSN=43, SSN=7. Can't be reassembled as previous SSNs aren't known.
407   reasm.Add(TSN(43), Data(kStreamID, SSN(7), MID(0), FSN(0), kPPID,
408                           std::vector<uint8_t>(10), Data::IsBeginning(true),
409                           Data::IsEnd(true), IsUnordered(false)));
410 
411   // Invalid, as TSN=44 have to have SSN>=7, but peer says 6.
412   reasm.Handle(ForwardTsnChunk(
413       TSN(44), {ForwardTsnChunk::SkippedStream(kStreamID, SSN(6))}));
414 
415   // Don't assemble SSN=7, as that TSN is skipped.
416   EXPECT_FALSE(reasm.HasMessages());
417 }
418 
TEST_F(ReassemblyQueueTest,SingleUnorderedChunkMessageInRfc8260)419 TEST_F(ReassemblyQueueTest, SingleUnorderedChunkMessageInRfc8260) {
420   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize,
421                         /*use_message_interleaving=*/true);
422   reasm.Add(TSN(10), Data(StreamID(1), SSN(0), MID(0), FSN(0), kPPID,
423                           {1, 2, 3, 4}, Data::IsBeginning(true),
424                           Data::IsEnd(true), IsUnordered(true)));
425   EXPECT_EQ(reasm.queued_bytes(), 0u);
426   EXPECT_TRUE(reasm.HasMessages());
427   EXPECT_THAT(reasm.FlushMessages(),
428               ElementsAre(SctpMessageIs(kStreamID, kPPID, kShortPayload)));
429 }
430 
TEST_F(ReassemblyQueueTest,TwoInterleavedChunks)431 TEST_F(ReassemblyQueueTest, TwoInterleavedChunks) {
432   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize,
433                         /*use_message_interleaving=*/true);
434   reasm.Add(TSN(10), Data(StreamID(1), SSN(0), MID(0), FSN(0), kPPID,
435                           {1, 2, 3, 4}, Data::IsBeginning(true),
436                           Data::IsEnd(false), IsUnordered(true)));
437   reasm.Add(TSN(11), Data(StreamID(2), SSN(0), MID(0), FSN(0), kPPID,
438                           {9, 10, 11, 12}, Data::IsBeginning(true),
439                           Data::IsEnd(false), IsUnordered(true)));
440   EXPECT_EQ(reasm.queued_bytes(), 8u);
441   reasm.Add(TSN(12), Data(StreamID(1), SSN(0), MID(0), FSN(1), kPPID,
442                           {5, 6, 7, 8}, Data::IsBeginning(false),
443                           Data::IsEnd(true), IsUnordered(true)));
444   EXPECT_EQ(reasm.queued_bytes(), 4u);
445   reasm.Add(TSN(13), Data(StreamID(2), SSN(0), MID(0), FSN(1), kPPID,
446                           {13, 14, 15, 16}, Data::IsBeginning(false),
447                           Data::IsEnd(true), IsUnordered(true)));
448   EXPECT_EQ(reasm.queued_bytes(), 0u);
449   EXPECT_TRUE(reasm.HasMessages());
450   EXPECT_THAT(reasm.FlushMessages(),
451               ElementsAre(SctpMessageIs(StreamID(1), kPPID, kMediumPayload1),
452                           SctpMessageIs(StreamID(2), kPPID, kMediumPayload2)));
453 }
454 
TEST_F(ReassemblyQueueTest,UnorderedInterleavedMessagesAllPermutations)455 TEST_F(ReassemblyQueueTest, UnorderedInterleavedMessagesAllPermutations) {
456   std::vector<int> indexes = {0, 1, 2, 3, 4, 5};
457   TSN tsns[] = {TSN(10), TSN(11), TSN(12), TSN(13), TSN(14), TSN(15)};
458   StreamID stream_ids[] = {StreamID(1), StreamID(2), StreamID(1),
459                            StreamID(1), StreamID(2), StreamID(2)};
460   FSN fsns[] = {FSN(0), FSN(0), FSN(1), FSN(2), FSN(1), FSN(2)};
461   rtc::ArrayView<const uint8_t> payload(kSixBytePayload);
462   do {
463     ReassemblyQueue reasm("log: ", TSN(10), kBufferSize,
464                           /*use_message_interleaving=*/true);
465     for (int i : indexes) {
466       auto span = payload.subview(*fsns[i] * 2, 2);
467       Data::IsBeginning is_beginning(fsns[i] == FSN(0));
468       Data::IsEnd is_end(fsns[i] == FSN(2));
469       reasm.Add(tsns[i], Data(stream_ids[i], SSN(0), MID(0), fsns[i], kPPID,
470                               std::vector<uint8_t>(span.begin(), span.end()),
471                               is_beginning, is_end, IsUnordered(true)));
472     }
473     EXPECT_TRUE(reasm.HasMessages());
474     EXPECT_THAT(reasm.FlushMessages(),
475                 UnorderedElementsAre(
476                     SctpMessageIs(StreamID(1), kPPID, kSixBytePayload),
477                     SctpMessageIs(StreamID(2), kPPID, kSixBytePayload)));
478     EXPECT_EQ(reasm.queued_bytes(), 0u);
479   } while (std::next_permutation(std::begin(indexes), std::end(indexes)));
480 }
481 
TEST_F(ReassemblyQueueTest,IForwardTSNRemoveALotOrdered)482 TEST_F(ReassemblyQueueTest, IForwardTSNRemoveALotOrdered) {
483   ReassemblyQueue reasm("log: ", TSN(10), kBufferSize,
484                         /*use_message_interleaving=*/true);
485   reasm.Add(TSN(10), gen_.Ordered({1}, "B"));
486   gen_.Ordered({2}, "");
487   reasm.Add(TSN(12), gen_.Ordered({3}, ""));
488   reasm.Add(TSN(13), gen_.Ordered({4}, "E"));
489   reasm.Add(TSN(15), gen_.Ordered({5}, "B"));
490   reasm.Add(TSN(16), gen_.Ordered({6}, ""));
491   reasm.Add(TSN(17), gen_.Ordered({7}, ""));
492   reasm.Add(TSN(18), gen_.Ordered({8}, "E"));
493 
494   ASSERT_FALSE(reasm.HasMessages());
495   EXPECT_EQ(reasm.queued_bytes(), 7u);
496 
497   reasm.Handle(
498       IForwardTsnChunk(TSN(13), {IForwardTsnChunk::SkippedStream(
499                                     IsUnordered(false), kStreamID, MID(0))}));
500   EXPECT_EQ(reasm.queued_bytes(), 0u);
501 
502   // The lost chunk comes, but too late.
503   ASSERT_TRUE(reasm.HasMessages());
504   EXPECT_THAT(reasm.FlushMessages(),
505               ElementsAre(SctpMessageIs(kStreamID, kPPID, kMessage2Payload)));
506 }
507 
508 }  // namespace
509 }  // namespace dcsctp
510