Skip to content

Commit 6dd2514

Browse files
committed
more
1 parent f4406a2 commit 6dd2514

File tree

7 files changed

+172
-39
lines changed

7 files changed

+172
-39
lines changed

worker/include/RTC/SCTP/Packet.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ namespace RTC
203203
return GetBuffer() + Packet::CommonHeaderLength;
204204
}
205205

206-
virtual const uint8_t* GetEndPointer() const final
206+
virtual uint8_t* GetEndPointer() const final
207207
{
208-
return GetBuffer() + GetBufferLength();
208+
return const_cast<uint8_t*>(GetBuffer()) + GetLength();
209209
}
210210

211211
/**

worker/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ test_sources = [
387387
# TODO: Move to common_sources array once it's tested.
388388
if get_option('ms_sctp_stack')
389389
test_sources += [
390+
'test/src/RTC/SCTP/TestPacket.cpp',
390391
'test/src/RTC/TestSerializable.cpp',
391392
'test/src/RTC/TestSerializable/FooPacket.cpp',
392393
'test/src/RTC/TestSerializable/FooItem.cpp',

worker/src/RTC/SCTP/Packet.cpp

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ namespace RTC
5959
{
6060
// The remaining length in the buffer is the potential buffer length
6161
// of the chunk.
62-
size_t chunkBufferLength = packet->GetEndPointer() - ptr;
62+
size_t chunkBufferLength = bufferLength - (ptr - buffer);
6363

6464
// Here we must anticipate the type of each chunk to use its appropriate
6565
// parser.
@@ -128,7 +128,7 @@ namespace RTC
128128
// Ensure computed length matches the total given buffer length.
129129
if (computedLength != bufferLength)
130130
{
131-
MS_WARN_DEV("computed padded length != buffer length");
131+
MS_WARN_DEV("computed length != buffer length");
132132

133133
delete packet;
134134
return nullptr;
@@ -148,9 +148,22 @@ namespace RTC
148148
{
149149
MS_TRACE();
150150

151-
// TODO
151+
size_t computedLength = Packet::CommonHeaderLength;
152152

153-
return nullptr;
153+
// No space for common header.
154+
if (bufferLength < computedLength)
155+
{
156+
MS_THROW_TYPE_ERROR("no space for common header");
157+
}
158+
159+
auto* packet = new Packet(buffer, bufferLength);
160+
161+
packet->InitializeHeader();
162+
163+
// Must always invoke SetLength() after constructing a Serializable.
164+
packet->SetLength(computedLength);
165+
166+
return packet;
154167
}
155168

156169
/* Instance methods. */
@@ -164,11 +177,10 @@ namespace RTC
164177
{
165178
MS_TRACE();
166179

167-
// TODO
168-
// for (auto* chunk : this->chunks)
169-
// {
170-
// delete chunk;
171-
// }
180+
for (auto* chunk : this->chunks)
181+
{
182+
delete chunk;
183+
}
172184
}
173185

174186
void Packet::Dump() const
@@ -211,18 +223,17 @@ namespace RTC
211223
// Serialize each chunk into the new buffer.
212224
auto* ptr = buffer + chunksOffset;
213225

214-
// TODO
215-
// for (auto* chunk : this->chunks)
216-
// {
217-
// chunk->Serialize(ptr, chunk->GetLength());
226+
for (auto* chunk : this->chunks)
227+
{
228+
chunk->Serialize(ptr, chunk->GetLength());
218229

219-
// // After calling `Serialize()` on the chunk, its `frozen` flag is
220-
// // reverted to false, but we want it to remain set because it's a
221-
// // chunk within the packet.
222-
// chunk->Freeze();
230+
// After calling `Serialize()` on the chunk, its `frozen` flag is
231+
// reverted to false, but we want it to remain set because it's a
232+
// chunk within the packet.
233+
chunk->Freeze();
223234

224-
// ptr += chunk->GetLength();
225-
// }
235+
ptr += chunk->GetLength();
236+
}
226237

227238
// Manually update buffer and buffer length.
228239
SetBuffer(buffer);
@@ -236,9 +247,40 @@ namespace RTC
236247
{
237248
MS_TRACE();
238249

239-
// TODO
250+
if (bufferLength < GetLength())
251+
{
252+
MS_THROW_TYPE_ERROR(
253+
"bufferLength (%zu bytes) is lower than current length (%zu bytes)",
254+
bufferLength,
255+
GetLength());
256+
}
257+
258+
size_t chunksOffset = GetChunksPointer() - GetBuffer();
259+
260+
// Copy all bytes from beginning of the buffer until the position of the
261+
// chunks.
262+
std::memcpy(buffer, GetBuffer(), chunksOffset);
263+
264+
auto* clonedPacket = new Packet(buffer, bufferLength);
265+
266+
// Clone each Chunk into the new buffer.
267+
auto* ptr = buffer + chunksOffset;
268+
269+
for (const auto* chunk : this->chunks)
270+
{
271+
auto* clonedChunk = chunk->Clone(ptr, chunk->GetLength());
272+
273+
clonedPacket->AddParsedChunk(clonedChunk);
274+
275+
ptr += chunk->GetLength();
276+
}
277+
278+
// Need to manually set Serializable length.
279+
clonedPacket->SetLength(GetLength());
240280

241-
return nullptr;
281+
// NOTE: The `frozen` flag will be false in the cloned packet by default.
282+
283+
return clonedPacket;
242284
}
243285

244286
void Packet::AddChunk(const Chunk* chunk)
@@ -247,7 +289,18 @@ namespace RTC
247289

248290
AssertNotFrozen();
249291

250-
// TODO
292+
size_t length = GetLength() + chunk->GetLength();
293+
294+
// Let's append the chunk at the end of existing chunks.
295+
auto* clonedChunk = chunk->Clone(GetEndPointer(), chunk->GetLength());
296+
297+
// Freeze the cloned chunk.
298+
clonedChunk->Freeze();
299+
300+
this->chunks.push_back(clonedChunk);
301+
302+
// Update Serializable length.
303+
SetLength(length);
251304
}
252305

253306
void Packet::InitializeHeader()

worker/test/include/RTC/TestSerializable/FooItem.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ class FooItem : public Serializable
175175
return const_cast<uint8_t*>(GetBuffer()) + FooItem::ItemHeaderLength;
176176
}
177177

178-
virtual const uint8_t* GetEndPointer() const final
178+
virtual uint8_t* GetEndPointer() const final
179179
{
180-
return GetBuffer() + FooItem::ItemHeaderLength + GetValueLength();
180+
return const_cast<uint8_t*>(GetBuffer()) + FooItem::ItemHeaderLength + GetValueLength();
181181
}
182182
};
183183

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include "common.hpp"
2+
#include "MediaSoupErrors.hpp"
3+
#include "Utils.hpp"
4+
#include "helpers.hpp"
5+
#include "RTC/SCTP/Packet.hpp"
6+
#include <catch2/catch_test_macros.hpp>
7+
#include <cstring> // std::memset()
8+
9+
using namespace RTC::SCTP;
10+
11+
SCENARIO("parse empty SCTP Packet", "[sctp][serializable]")
12+
{
13+
// clang-format off
14+
uint8_t buffer[] =
15+
{
16+
// Source Port: 10000, Destination Port: 15999
17+
0x27, 0x10, 0x3E, 0x7F,
18+
// Verification Tag: 4294967285
19+
0xFF, 0xFF, 0xFF, 0xF5,
20+
// Checksum: 5
21+
0x00, 0x00, 0x00, 0x05
22+
};
23+
// clang-format on
24+
25+
REQUIRE(Packet::IsPacket(buffer, sizeof(buffer)) == true);
26+
27+
auto* packet = Packet::Parse(buffer, sizeof(buffer));
28+
29+
REQUIRE(sizeof(buffer) == 12);
30+
REQUIRE(packet);
31+
REQUIRE(packet->GetBuffer() == buffer);
32+
REQUIRE(packet->GetBufferLength() == 12);
33+
REQUIRE(packet->GetLength() == 12);
34+
REQUIRE(packet->IsFrozen() == true);
35+
REQUIRE(Utils::Byte::IsPaddedTo4Bytes(packet->GetLength()) == true);
36+
REQUIRE(packet->GetSourcePort() == 10000);
37+
REQUIRE(packet->GetDestinationPort() == 15999);
38+
REQUIRE(packet->GetVerificationTag() == 4294967285);
39+
REQUIRE(packet->GetChecksum() == 5);
40+
REQUIRE(packet->HasChunks() == false);
41+
REQUIRE(packet->GetChunksCount() == 0);
42+
REQUIRE(helpers::areBuffersEqual(packet->GetBuffer(), packet->GetLength(), buffer, 12) == true);
43+
44+
// Must throw if we try to modify the packet since Parse() returns a frozen
45+
// Packet.
46+
REQUIRE_THROWS_AS(packet->SetSourcePort(10), MediaSoupError);
47+
REQUIRE_THROWS_AS(packet->SetDestinationPort(99), MediaSoupError);
48+
REQUIRE_THROWS_AS(packet->SetVerificationTag(12345), MediaSoupError);
49+
REQUIRE_THROWS_AS(packet->SetChecksum(666), MediaSoupError);
50+
REQUIRE_THROWS_AS(packet->AddChunk(nullptr), MediaSoupError);
51+
52+
delete packet;
53+
}
54+
55+
SCENARIO("create and modify SCTP Packet", "[sctp][serializable]")
56+
{
57+
uint8_t buffer[256];
58+
59+
std::memset(buffer, 0xFF, sizeof(buffer));
60+
61+
auto* packet = Packet::Factory(buffer, sizeof(buffer));
62+
63+
REQUIRE(sizeof(buffer) == 256);
64+
REQUIRE(packet);
65+
REQUIRE(packet->GetBuffer() == buffer);
66+
REQUIRE(packet->GetBufferLength() == 256);
67+
REQUIRE(packet->GetLength() == 12);
68+
REQUIRE(packet->IsFrozen() == false);
69+
REQUIRE(Utils::Byte::IsPaddedTo4Bytes(packet->GetLength()) == true);
70+
REQUIRE(packet->GetSourcePort() == 0);
71+
REQUIRE(packet->GetDestinationPort() == 0);
72+
REQUIRE(packet->GetVerificationTag() == 0);
73+
REQUIRE(packet->GetChecksum() == 0);
74+
REQUIRE(packet->HasChunks() == false);
75+
REQUIRE(packet->GetChunksCount() == 0);
76+
REQUIRE(helpers::areBuffersEqual(packet->GetBuffer(), packet->GetLength(), buffer, 12) == true);
77+
78+
delete packet;
79+
}

worker/test/src/RTC/TestSerializable.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
using namespace RTC;
1616

17-
SCENARIO("parse FooPacket", "[rtc][serializable]")
17+
SCENARIO("parse FooPacket", "[serializable]")
1818
{
1919
// clang-format off
2020
uint8_t buffer[] =
@@ -104,7 +104,7 @@ SCENARIO("parse FooPacket", "[rtc][serializable]")
104104
delete fooPacket;
105105
}
106106

107-
SCENARIO("parse invalid FooPacket with buffer not padded to 4 bytes", "[rtc][serializable]")
107+
SCENARIO("parse invalid FooPacket with buffer not padded to 4 bytes", "[serializable]")
108108
{
109109
// clang-format off
110110
uint8_t buffer[] =
@@ -130,7 +130,7 @@ SCENARIO("parse invalid FooPacket with buffer not padded to 4 bytes", "[rtc][ser
130130
REQUIRE(!fooPacket);
131131
}
132132

133-
SCENARIO("create and modify FooPacket", "[rtc][serializable]")
133+
SCENARIO("create and modify FooPacket", "[serializable]")
134134
{
135135
uint8_t buffer[256];
136136
uint8_t itemBuffer[17];
@@ -600,7 +600,7 @@ SCENARIO("create and modify FooPacket", "[rtc][serializable]")
600600
delete clonedItem1;
601601
}
602602

603-
SCENARIO("parse FooNumericItem", "[rtc][serializable]")
603+
SCENARIO("parse FooNumericItem", "[serializable]")
604604
{
605605
// clang-format off
606606
uint8_t buffer[] =
@@ -627,7 +627,7 @@ SCENARIO("parse FooNumericItem", "[rtc][serializable]")
627627
delete item;
628628
}
629629

630-
SCENARIO("parse FooNumericItem by passing a buffer larger than the length of the item", "[rtc][serializable]")
630+
SCENARIO("parse FooNumericItem by passing a buffer larger than the length of the item", "[serializable]")
631631
{
632632
// Item length is 4 but given buffer is 6 bytes. Not a problem.
633633
// clang-format off
@@ -656,7 +656,7 @@ SCENARIO("parse FooNumericItem by passing a buffer larger than the length of the
656656
delete item;
657657
}
658658

659-
SCENARIO("parse invalid FooNumericItem with too small buffer", "[rtc][serializable]")
659+
SCENARIO("parse invalid FooNumericItem with too small buffer", "[serializable]")
660660
{
661661
// Item length should be 4 but given buffer is only 3 bytes.
662662
// clang-format off
@@ -673,7 +673,7 @@ SCENARIO("parse invalid FooNumericItem with too small buffer", "[rtc][serializab
673673
REQUIRE(!item);
674674
}
675675

676-
SCENARIO("parse invalid FooNumericItem with wrong value length", "[rtc][serializable]")
676+
SCENARIO("parse invalid FooNumericItem with wrong value length", "[serializable]")
677677
{
678678
// clang-format off
679679
uint8_t buffer[] =
@@ -690,7 +690,7 @@ SCENARIO("parse invalid FooNumericItem with wrong value length", "[rtc][serializ
690690
REQUIRE(!item);
691691
}
692692

693-
SCENARIO("parse invalid FooNumericItem with wrong id", "[rtc][serializable]")
693+
SCENARIO("parse invalid FooNumericItem with wrong id", "[serializable]")
694694
{
695695
// clang-format off
696696
uint8_t buffer[] =
@@ -706,7 +706,7 @@ SCENARIO("parse invalid FooNumericItem with wrong id", "[rtc][serializable]")
706706
REQUIRE(!item);
707707
}
708708

709-
SCENARIO("create and modify FooNumericItem", "[rtc][serializable]")
709+
SCENARIO("create and modify FooNumericItem", "[serializable]")
710710
{
711711
// Max length of a FooItem is 17 bytes.
712712
uint8_t buffer[17];
@@ -820,7 +820,7 @@ SCENARIO("create and modify FooNumericItem", "[rtc][serializable]")
820820
delete clonedItem;
821821
}
822822

823-
SCENARIO("create and modify FooTextItem", "[rtc][serializable]")
823+
SCENARIO("create and modify FooTextItem", "[serializable]")
824824
{
825825
uint8_t buffer[40];
826826
std::string text = "Iñaki"; // 6 bytes.

worker/test/src/RTC/TestSerializable/FooPacket.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ FooPacket* FooPacket::Parse(const uint8_t* buffer, size_t bufferLength)
147147
ptr += item->GetLength();
148148
}
149149

150-
// We should be in the potential padding position.
150+
// We should be at the potential padding position.
151151
if (ptr != packet->GetPaddingPointer())
152152
{
153153
MS_WARN_DEV("we should be in the padding but we are not");
@@ -192,10 +192,10 @@ FooPacket* FooPacket::Factory(uint8_t* buffer, size_t bufferLength, uint8_t type
192192

193193
auto* packet = new FooPacket(buffer, bufferLength);
194194

195-
packet->InitializeHeader(type, FooPacket::HeaderLength);
195+
packet->InitializeHeader(type, computedLength);
196196

197197
// Must always invoke SetLength() after constructing a Serializable.
198-
packet->SetLength(FooPacket::HeaderLength);
198+
packet->SetLength(computedLength);
199199

200200
return packet;
201201
}

0 commit comments

Comments
 (0)