mediasoup 3.21.0 → 3.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1882 -0
- package/node/lib/test/test-Consumer.js +111 -0
- package/node/lib/test/test-Producer.js +54 -0
- package/npm-scripts.mjs +0 -5
- package/package.json +9 -8
- package/worker/fuzzer/src/RTC/SCTP/association/FuzzerStateCookie.cpp +4 -6
- package/worker/include/RTC/NEW_RTCP/packet/ByePacket.hpp +165 -0
- package/worker/include/RTC/NEW_RTCP/packet/CompoundPacket.hpp +183 -0
- package/worker/include/RTC/NEW_RTCP/packet/Packet.hpp +354 -0
- package/worker/include/RTC/NEW_RTCP/packet/TODO_NEW_RTCP.md +17 -0
- package/worker/include/RTC/RTP/Codecs/Tools.hpp +2 -0
- package/worker/include/RTC/Router.hpp +4 -4
- package/worker/include/RTC/SCTP/association/Capabilities.hpp +73 -0
- package/worker/include/RTC/SCTP/association/NegotiatedCapabilities.hpp +7 -9
- package/worker/include/RTC/SCTP/association/StateCookie.hpp +38 -28
- package/worker/include/RTC/SCTP/packet/Chunk.hpp +11 -7
- package/worker/include/RTC/SCTP/packet/ErrorCause.hpp +11 -4
- package/worker/include/RTC/SCTP/packet/Packet.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/Parameter.hpp +11 -4
- package/worker/include/RTC/SCTP/packet/TLV.hpp +2 -2
- package/worker/include/RTC/SCTP/packet/parameters/StateCookieParameter.hpp +2 -2
- package/worker/include/RTC/Transport.hpp +10 -10
- package/worker/include/Worker.hpp +4 -4
- package/worker/meson.build +7 -0
- package/worker/scripts/clang-scripts.mjs +54 -0
- package/worker/src/RTC/Consumer.cpp +22 -4
- package/worker/src/RTC/NEW_RTCP/packet/ByePacket.cpp +266 -0
- package/worker/src/RTC/NEW_RTCP/packet/CompoundPacket.cpp +219 -0
- package/worker/src/RTC/NEW_RTCP/packet/Packet.cpp +222 -0
- package/worker/src/RTC/RTP/Codecs/H264.cpp +3 -0
- package/worker/src/RTC/RTP/Codecs/VP8.cpp +3 -0
- package/worker/src/RTC/Router.cpp +14 -14
- package/worker/src/RTC/SCTP/association/Association.cpp +23 -11
- package/worker/src/RTC/SCTP/association/Capabilities.cpp +87 -0
- package/worker/src/RTC/SCTP/association/NegotiatedCapabilities.cpp +20 -40
- package/worker/src/RTC/SCTP/association/StateCookie.cpp +54 -32
- package/worker/src/RTC/SCTP/packet/Chunk.cpp +18 -18
- package/worker/src/RTC/SCTP/packet/ErrorCause.cpp +18 -18
- package/worker/src/RTC/SCTP/packet/Packet.cpp +2 -0
- package/worker/src/RTC/SCTP/packet/Parameter.cpp +18 -18
- package/worker/src/RTC/SCTP/packet/TLV.cpp +27 -25
- package/worker/src/RTC/SCTP/packet/parameters/StateCookieParameter.cpp +2 -2
- package/worker/src/RTC/SvcProducerStreamManager.cpp +4 -1
- package/worker/src/RTC/Transport.cpp +42 -30
- package/worker/src/Worker.cpp +10 -10
- package/worker/test/include/RTC/ICE/iceCommon.hpp +1 -1
- package/worker/test/include/RTC/RTCP/rtcpCommon.hpp +58 -0
- package/worker/test/include/RTC/RTP/rtpCommon.hpp +1 -1
- package/worker/test/src/RTC/NEW_RTCP/packet/TestByePacket.cpp +302 -0
- package/worker/test/src/RTC/NEW_RTCP/rtcpCommon.cpp +29 -0
- package/worker/test/src/RTC/RTP/TestPacket.cpp +17 -15
- package/worker/test/src/RTC/SCTP/association/TestAssociation.cpp +3 -3
- package/worker/test/src/RTC/SCTP/association/TestCapabilities.cpp +99 -0
- package/worker/test/src/RTC/SCTP/association/TestNegotiatedCapabilities.cpp +14 -16
- package/worker/test/src/RTC/SCTP/association/TestStateCookie.cpp +198 -102
- package/worker/test/src/RTC/SCTP/packet/parameters/TestStateCookieParameter.cpp +11 -10
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#define MS_CLASS "RTC::SCTP::Capabilities"
|
|
2
|
+
// #define MS_LOG_DEV_LEVEL 3
|
|
3
|
+
|
|
4
|
+
#include "RTC/SCTP/association/Capabilities.hpp"
|
|
5
|
+
#include "Logger.hpp"
|
|
6
|
+
#include "RTC/SCTP/packet/Chunk.hpp"
|
|
7
|
+
#include "RTC/SCTP/packet/parameters/ForwardTsnSupportedParameter.hpp"
|
|
8
|
+
#include "RTC/SCTP/packet/parameters/SupportedExtensionsParameter.hpp"
|
|
9
|
+
|
|
10
|
+
namespace RTC
|
|
11
|
+
{
|
|
12
|
+
namespace SCTP
|
|
13
|
+
{
|
|
14
|
+
/* Class methods. */
|
|
15
|
+
|
|
16
|
+
Capabilities Capabilities::Factory(const AnyInitChunk* remoteChunk)
|
|
17
|
+
{
|
|
18
|
+
MS_TRACE();
|
|
19
|
+
|
|
20
|
+
Capabilities capabilities{};
|
|
21
|
+
|
|
22
|
+
const auto* remoteSupportedExtensionsParameter =
|
|
23
|
+
remoteChunk->template GetFirstParameterOfType<SupportedExtensionsParameter>();
|
|
24
|
+
const auto* remoteForwardTsnSupportedParameter =
|
|
25
|
+
remoteChunk->template GetFirstParameterOfType<ForwardTsnSupportedParameter>();
|
|
26
|
+
const auto* remoteZeroChecksumAcceptableParameter =
|
|
27
|
+
remoteChunk->template GetFirstParameterOfType<ZeroChecksumAcceptableParameter>();
|
|
28
|
+
|
|
29
|
+
// Streams announced by the remote endpoint in its INIT or INIT-ACK chunk.
|
|
30
|
+
capabilities.maxOutboundStreams = remoteChunk->GetNumberOfOutboundStreams();
|
|
31
|
+
capabilities.maxInboundStreams = remoteChunk->GetNumberOfInboundStreams();
|
|
32
|
+
|
|
33
|
+
// Remote announces Partial Reliability Extension support via
|
|
34
|
+
// Forward-TSN-Supported parameter or via Supported Extensions parameter.
|
|
35
|
+
capabilities.partialReliability =
|
|
36
|
+
remoteForwardTsnSupportedParameter ||
|
|
37
|
+
(remoteSupportedExtensionsParameter &&
|
|
38
|
+
remoteSupportedExtensionsParameter->IncludesChunkType(Chunk::ChunkType::FORWARD_TSN));
|
|
39
|
+
|
|
40
|
+
// Remote announces Message Interleaving support via Supported Extensions
|
|
41
|
+
// parameter.
|
|
42
|
+
capabilities.messageInterleaving =
|
|
43
|
+
remoteSupportedExtensionsParameter &&
|
|
44
|
+
remoteSupportedExtensionsParameter->IncludesChunkType(Chunk::ChunkType::I_DATA) &&
|
|
45
|
+
remoteSupportedExtensionsParameter->IncludesChunkType(Chunk::ChunkType::I_FORWARD_TSN);
|
|
46
|
+
|
|
47
|
+
// Remote announces Stream Re-Configuration support via Supported
|
|
48
|
+
// Extensions parameter.
|
|
49
|
+
capabilities.reConfig =
|
|
50
|
+
remoteSupportedExtensionsParameter &&
|
|
51
|
+
remoteSupportedExtensionsParameter->IncludesChunkType(Chunk::ChunkType::RE_CONFIG);
|
|
52
|
+
|
|
53
|
+
// Alternate Error Detection Method for Zero Checksum announced by the
|
|
54
|
+
// remote endpoint (NONE if not announced).
|
|
55
|
+
capabilities.zeroChecksumAlternateErrorDetectionMethod =
|
|
56
|
+
remoteZeroChecksumAcceptableParameter
|
|
57
|
+
? remoteZeroChecksumAcceptableParameter->GetAlternateErrorDetectionMethod()
|
|
58
|
+
: ZeroChecksumAcceptableParameter::AlternateErrorDetectionMethod::NONE;
|
|
59
|
+
|
|
60
|
+
// NOTE: No need to std::move(). Copy elision (RVO) is used for free in GCC
|
|
61
|
+
// and clang in C++17 or higher.
|
|
62
|
+
return capabilities;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Instance methods. */
|
|
66
|
+
|
|
67
|
+
void Capabilities::Dump(int indentation) const
|
|
68
|
+
{
|
|
69
|
+
MS_TRACE();
|
|
70
|
+
|
|
71
|
+
MS_DUMP_CLEAN(indentation, "<SCTP::Capabilities>");
|
|
72
|
+
MS_DUMP_CLEAN(indentation, " max outbound streams: %" PRIu16, this->maxOutboundStreams);
|
|
73
|
+
MS_DUMP_CLEAN(indentation, " max inbound streams: %" PRIu16, this->maxInboundStreams);
|
|
74
|
+
MS_DUMP_CLEAN(indentation, " partial reliability: %s", this->partialReliability ? "yes" : "no");
|
|
75
|
+
MS_DUMP_CLEAN(
|
|
76
|
+
indentation, " message interleaving: %s", this->messageInterleaving ? "yes" : "no");
|
|
77
|
+
MS_DUMP_CLEAN(indentation, " re-config: %s", this->reConfig ? "yes" : "no");
|
|
78
|
+
MS_DUMP_CLEAN(
|
|
79
|
+
indentation,
|
|
80
|
+
" zero checksum alternate error detection method: %s",
|
|
81
|
+
ZeroChecksumAcceptableParameter::AlternateErrorDetectionMethodToString(
|
|
82
|
+
this->zeroChecksumAlternateErrorDetectionMethod)
|
|
83
|
+
.c_str());
|
|
84
|
+
MS_DUMP_CLEAN(indentation, "</SCTP::Capabilities>");
|
|
85
|
+
}
|
|
86
|
+
} // namespace SCTP
|
|
87
|
+
} // namespace RTC
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
#include "RTC/SCTP/association/NegotiatedCapabilities.hpp"
|
|
5
5
|
#include "Logger.hpp"
|
|
6
|
-
#include "RTC/SCTP/packet/parameters/ForwardTsnSupportedParameter.hpp"
|
|
7
|
-
#include "RTC/SCTP/packet/parameters/SupportedExtensionsParameter.hpp"
|
|
8
6
|
#include "RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp"
|
|
9
7
|
|
|
10
8
|
namespace RTC
|
|
@@ -14,55 +12,39 @@ namespace RTC
|
|
|
14
12
|
/* Class methods. */
|
|
15
13
|
|
|
16
14
|
NegotiatedCapabilities NegotiatedCapabilities::Factory(
|
|
17
|
-
const SctpOptions& sctpOptions, const
|
|
15
|
+
const SctpOptions& sctpOptions, const Capabilities& remoteCapabilities)
|
|
18
16
|
{
|
|
19
17
|
MS_TRACE();
|
|
20
18
|
|
|
21
19
|
NegotiatedCapabilities negotiatedCapabilities{};
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const auto* remoteForwardTsnSupportedParameter =
|
|
26
|
-
remoteChunk->template GetFirstParameterOfType<ForwardTsnSupportedParameter>();
|
|
27
|
-
const auto* remoteZeroChecksumAcceptableParameter =
|
|
28
|
-
remoteChunk->template GetFirstParameterOfType<ZeroChecksumAcceptableParameter>();
|
|
21
|
+
negotiatedCapabilities.maxOutboundStreams =
|
|
22
|
+
std::min(sctpOptions.announcedMaxOutboundStreams, remoteCapabilities.maxInboundStreams);
|
|
29
23
|
|
|
30
|
-
negotiatedCapabilities.
|
|
31
|
-
std::min(sctpOptions.
|
|
24
|
+
negotiatedCapabilities.maxInboundStreams =
|
|
25
|
+
std::min(sctpOptions.announcedMaxInboundStreams, remoteCapabilities.maxOutboundStreams);
|
|
32
26
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// Partial Reliability Extension is negotiated if we desire it and
|
|
37
|
-
// peer announces support via Forward-TSN-Supported Parameter or via
|
|
38
|
-
// Supported extensions parameter.
|
|
27
|
+
// Partial Reliability Extension is negotiated if we desire it and the
|
|
28
|
+
// remote announces support for it.
|
|
39
29
|
negotiatedCapabilities.partialReliability =
|
|
40
|
-
sctpOptions.enablePartialReliability &&
|
|
41
|
-
(remoteForwardTsnSupportedParameter ||
|
|
42
|
-
(remoteSupportedExtensionsParameter &&
|
|
43
|
-
remoteSupportedExtensionsParameter->IncludesChunkType(Chunk::ChunkType::FORWARD_TSN)));
|
|
30
|
+
sctpOptions.enablePartialReliability && remoteCapabilities.partialReliability;
|
|
44
31
|
|
|
45
|
-
// Message Interleaving is negotiated if we desire it and
|
|
46
|
-
// announces support
|
|
32
|
+
// Message Interleaving is negotiated if we desire it and the remote
|
|
33
|
+
// announces support for it.
|
|
47
34
|
negotiatedCapabilities.messageInterleaving =
|
|
48
|
-
sctpOptions.enableMessageInterleaving &&
|
|
49
|
-
remoteSupportedExtensionsParameter->IncludesChunkType(Chunk::ChunkType::I_DATA) &&
|
|
50
|
-
remoteSupportedExtensionsParameter->IncludesChunkType(Chunk::ChunkType::I_FORWARD_TSN);
|
|
35
|
+
sctpOptions.enableMessageInterleaving && remoteCapabilities.messageInterleaving;
|
|
51
36
|
|
|
52
|
-
// Stream Re-Configuration is negotiated if
|
|
53
|
-
//
|
|
54
|
-
negotiatedCapabilities.reConfig =
|
|
55
|
-
remoteSupportedExtensionsParameter &&
|
|
56
|
-
remoteSupportedExtensionsParameter->IncludesChunkType(Chunk::ChunkType::RE_CONFIG);
|
|
37
|
+
// Stream Re-Configuration is negotiated if the remote announces support
|
|
38
|
+
// for it.
|
|
39
|
+
negotiatedCapabilities.reConfig = remoteCapabilities.reConfig;
|
|
57
40
|
|
|
58
|
-
// Alternate Error Detection Method for Zero Checksum is negotiated
|
|
59
|
-
//
|
|
60
|
-
//
|
|
41
|
+
// Alternate Error Detection Method for Zero Checksum is negotiated if we
|
|
42
|
+
// desire it and the remote announces the same non-none alternate error
|
|
43
|
+
// detection method.
|
|
61
44
|
negotiatedCapabilities.zeroChecksum =
|
|
62
45
|
sctpOptions.zeroChecksumAlternateErrorDetectionMethod !=
|
|
63
46
|
ZeroChecksumAcceptableParameter::AlternateErrorDetectionMethod::NONE &&
|
|
64
|
-
|
|
65
|
-
remoteZeroChecksumAcceptableParameter->GetAlternateErrorDetectionMethod() ==
|
|
47
|
+
remoteCapabilities.zeroChecksumAlternateErrorDetectionMethod ==
|
|
66
48
|
sctpOptions.zeroChecksumAlternateErrorDetectionMethod;
|
|
67
49
|
|
|
68
50
|
return negotiatedCapabilities;
|
|
@@ -75,10 +57,8 @@ namespace RTC
|
|
|
75
57
|
MS_TRACE();
|
|
76
58
|
|
|
77
59
|
MS_DUMP_CLEAN(indentation, "<SCTP::NegotiatedCapabilities>");
|
|
78
|
-
MS_DUMP_CLEAN(
|
|
79
|
-
|
|
80
|
-
MS_DUMP_CLEAN(
|
|
81
|
-
indentation, " negotiated max inbound streams: %" PRIu16, this->negotiatedMaxInboundStreams);
|
|
60
|
+
MS_DUMP_CLEAN(indentation, " max outbound streams: %" PRIu16, this->maxOutboundStreams);
|
|
61
|
+
MS_DUMP_CLEAN(indentation, " max inbound streams: %" PRIu16, this->maxInboundStreams);
|
|
82
62
|
MS_DUMP_CLEAN(indentation, " partial reliability: %s", this->partialReliability ? "yes" : "no");
|
|
83
63
|
MS_DUMP_CLEAN(
|
|
84
64
|
indentation, " message interleaving: %s", this->messageInterleaving ? "yes" : "no");
|
|
@@ -24,6 +24,15 @@ namespace RTC
|
|
|
24
24
|
return nullptr;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// Reject cookies with a zero verification tag. A zero tag is never
|
|
28
|
+
// generated by us, so this limits the effect of a tampered/forged cookie.
|
|
29
|
+
if (Utils::Byte::Get4Bytes(buffer, 8) == 0 || Utils::Byte::Get4Bytes(buffer, 12) == 0)
|
|
30
|
+
{
|
|
31
|
+
MS_WARN_TAG(sctp, "invalid StateCookie, verification tag is zero");
|
|
32
|
+
|
|
33
|
+
return nullptr;
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
auto* stateCookie = new StateCookie(const_cast<uint8_t*>(buffer), bufferLength);
|
|
28
37
|
|
|
29
38
|
return stateCookie;
|
|
@@ -38,7 +47,7 @@ namespace RTC
|
|
|
38
47
|
uint32_t remoteInitialTsn,
|
|
39
48
|
uint32_t remoteAdvertisedReceiverWindowCredit,
|
|
40
49
|
uint64_t tieTag,
|
|
41
|
-
const
|
|
50
|
+
const Capabilities& remoteCapabilities,
|
|
42
51
|
uint64_t creationTimestampMs,
|
|
43
52
|
const uint8_t* macKey,
|
|
44
53
|
size_t macKeyLength)
|
|
@@ -55,7 +64,7 @@ namespace RTC
|
|
|
55
64
|
remoteInitialTsn,
|
|
56
65
|
remoteAdvertisedReceiverWindowCredit,
|
|
57
66
|
tieTag,
|
|
58
|
-
|
|
67
|
+
remoteCapabilities,
|
|
59
68
|
creationTimestampMs,
|
|
60
69
|
macKey,
|
|
61
70
|
macKeyLength);
|
|
@@ -75,7 +84,7 @@ namespace RTC
|
|
|
75
84
|
uint32_t remoteInitialTsn,
|
|
76
85
|
uint32_t remoteAdvertisedReceiverWindowCredit,
|
|
77
86
|
uint64_t tieTag,
|
|
78
|
-
const
|
|
87
|
+
const Capabilities& remoteCapabilities,
|
|
79
88
|
uint64_t creationTimestampMs,
|
|
80
89
|
const uint8_t* macKey,
|
|
81
90
|
size_t macKeyLength)
|
|
@@ -99,19 +108,19 @@ namespace RTC
|
|
|
99
108
|
Utils::Byte::Set4Bytes(buffer, 24, remoteAdvertisedReceiverWindowCredit);
|
|
100
109
|
Utils::Byte::Set8Bytes(buffer, 28, tieTag);
|
|
101
110
|
|
|
102
|
-
auto*
|
|
103
|
-
buffer + StateCookie::
|
|
111
|
+
auto* remoteCapabilitiesField =
|
|
112
|
+
reinterpret_cast<RemoteCapabilitiesField*>(buffer + StateCookie::RemoteCapabilitiesOffset);
|
|
104
113
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
remoteCapabilitiesField->reserved = 0;
|
|
115
|
+
remoteCapabilitiesField->bitA = remoteCapabilities.partialReliability;
|
|
116
|
+
remoteCapabilitiesField->bitB = remoteCapabilities.messageInterleaving;
|
|
117
|
+
remoteCapabilitiesField->bitC = remoteCapabilities.reConfig;
|
|
118
|
+
remoteCapabilitiesField->unusedBits = 0;
|
|
119
|
+
remoteCapabilitiesField->magic2 = htons(StateCookie::Magic2);
|
|
120
|
+
remoteCapabilitiesField->zeroChecksumAlternateErrorDetectionMethod =
|
|
121
|
+
htonl(static_cast<uint32_t>(remoteCapabilities.zeroChecksumAlternateErrorDetectionMethod));
|
|
122
|
+
remoteCapabilitiesField->maxOutboundStreams = htons(remoteCapabilities.maxOutboundStreams);
|
|
123
|
+
remoteCapabilitiesField->maxInboundStreams = htons(remoteCapabilities.maxInboundStreams);
|
|
115
124
|
|
|
116
125
|
if (!authenticate)
|
|
117
126
|
{
|
|
@@ -144,10 +153,10 @@ namespace RTC
|
|
|
144
153
|
return false;
|
|
145
154
|
}
|
|
146
155
|
|
|
147
|
-
auto*
|
|
148
|
-
|
|
156
|
+
const auto* remoteCapabilitiesField = reinterpret_cast<const RemoteCapabilitiesField*>(
|
|
157
|
+
buffer + StateCookie::RemoteCapabilitiesOffset);
|
|
149
158
|
|
|
150
|
-
if (ntohs(
|
|
159
|
+
if (ntohs(remoteCapabilitiesField->magic2) != StateCookie::Magic2)
|
|
151
160
|
{
|
|
152
161
|
return false;
|
|
153
162
|
}
|
|
@@ -228,9 +237,10 @@ namespace RTC
|
|
|
228
237
|
{
|
|
229
238
|
MS_TRACE();
|
|
230
239
|
|
|
231
|
-
auto
|
|
240
|
+
const auto remoteCapabilities = GetRemoteCapabilities();
|
|
232
241
|
|
|
233
242
|
MS_DUMP_CLEAN(indentation, "<SCTP::StateCookie>");
|
|
243
|
+
|
|
234
244
|
MS_DUMP_CLEAN(indentation, " length: %zu (buffer length: %zu)", GetLength(), GetBufferLength());
|
|
235
245
|
MS_DUMP_CLEAN(indentation, " local verification tag: %" PRIu32, GetLocalVerificationTag());
|
|
236
246
|
MS_DUMP_CLEAN(indentation, " remote verification tag: %" PRIu32, GetRemoteVerificationTag());
|
|
@@ -248,7 +258,9 @@ namespace RTC
|
|
|
248
258
|
MS_DUMP_CLEAN(indentation, " creation timestamp (ms): %" PRIu64, GetCreationTimestampMs());
|
|
249
259
|
}
|
|
250
260
|
|
|
251
|
-
|
|
261
|
+
MS_DUMP_CLEAN(indentation, " remote capabilities:");
|
|
262
|
+
remoteCapabilities.Dump(indentation + 1);
|
|
263
|
+
|
|
252
264
|
MS_DUMP_CLEAN(indentation, "</SCTP::StateCookie>");
|
|
253
265
|
}
|
|
254
266
|
|
|
@@ -263,26 +275,36 @@ namespace RTC
|
|
|
263
275
|
return clonedStateCookie;
|
|
264
276
|
}
|
|
265
277
|
|
|
266
|
-
|
|
278
|
+
Capabilities StateCookie::GetRemoteCapabilities() const
|
|
267
279
|
{
|
|
268
280
|
MS_TRACE();
|
|
269
281
|
|
|
270
|
-
auto*
|
|
282
|
+
const auto* remoteCapabilitiesField = GetRemoteCapabilitiesField();
|
|
283
|
+
|
|
284
|
+
Capabilities remoteCapabilities;
|
|
285
|
+
|
|
286
|
+
remoteCapabilities.maxOutboundStreams = ntohs(remoteCapabilitiesField->maxOutboundStreams);
|
|
287
|
+
remoteCapabilities.maxInboundStreams = ntohs(remoteCapabilitiesField->maxInboundStreams);
|
|
288
|
+
remoteCapabilities.partialReliability = remoteCapabilitiesField->bitA;
|
|
289
|
+
remoteCapabilities.messageInterleaving = remoteCapabilitiesField->bitB;
|
|
290
|
+
remoteCapabilities.reConfig = remoteCapabilitiesField->bitC;
|
|
271
291
|
|
|
272
|
-
|
|
292
|
+
// Only keep the zero checksum method if it's a value we know about.
|
|
293
|
+
// Anything else (unknown/future method or a tampered cookie) is treated
|
|
294
|
+
// as none.
|
|
295
|
+
const uint32_t zeroChecksumAlternateErrorDetectionMethod =
|
|
296
|
+
ntohl(remoteCapabilitiesField->zeroChecksumAlternateErrorDetectionMethod);
|
|
273
297
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
negotiatedCapabilities.reConfig = negotiatedCapabilitiesField->bitC;
|
|
281
|
-
negotiatedCapabilities.zeroChecksum = negotiatedCapabilitiesField->bitD;
|
|
298
|
+
remoteCapabilities.zeroChecksumAlternateErrorDetectionMethod =
|
|
299
|
+
zeroChecksumAlternateErrorDetectionMethod ==
|
|
300
|
+
static_cast<uint32_t>(
|
|
301
|
+
ZeroChecksumAcceptableParameter::AlternateErrorDetectionMethod::SCTP_OVER_DTLS)
|
|
302
|
+
? ZeroChecksumAcceptableParameter::AlternateErrorDetectionMethod::SCTP_OVER_DTLS
|
|
303
|
+
: ZeroChecksumAcceptableParameter::AlternateErrorDetectionMethod::NONE;
|
|
282
304
|
|
|
283
305
|
// NOTE: No need to std::move(). Copy elision (RVO) is used for free in GCC
|
|
284
306
|
// and clang in C++17 or higher.
|
|
285
|
-
return
|
|
307
|
+
return remoteCapabilities;
|
|
286
308
|
}
|
|
287
309
|
} // namespace SCTP
|
|
288
310
|
} // namespace RTC
|
|
@@ -70,6 +70,22 @@ namespace RTC
|
|
|
70
70
|
|
|
71
71
|
/* Class methods. */
|
|
72
72
|
|
|
73
|
+
const std::string& Chunk::ChunkTypeToString(ChunkType chunkType)
|
|
74
|
+
{
|
|
75
|
+
MS_TRACE();
|
|
76
|
+
|
|
77
|
+
static const std::string Unknown("UNKNOWN");
|
|
78
|
+
|
|
79
|
+
auto it = Chunk::ChunkType2String.find(chunkType);
|
|
80
|
+
|
|
81
|
+
if (it == Chunk::ChunkType2String.end())
|
|
82
|
+
{
|
|
83
|
+
return Unknown;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return it->second;
|
|
87
|
+
}
|
|
88
|
+
|
|
73
89
|
bool Chunk::IsChunk(
|
|
74
90
|
const uint8_t* buffer,
|
|
75
91
|
size_t bufferLength,
|
|
@@ -89,22 +105,6 @@ namespace RTC
|
|
|
89
105
|
return true;
|
|
90
106
|
}
|
|
91
107
|
|
|
92
|
-
const std::string& Chunk::ChunkTypeToString(ChunkType chunkType)
|
|
93
|
-
{
|
|
94
|
-
MS_TRACE();
|
|
95
|
-
|
|
96
|
-
static const std::string Unknown("UNKNOWN");
|
|
97
|
-
|
|
98
|
-
auto it = Chunk::ChunkType2String.find(chunkType);
|
|
99
|
-
|
|
100
|
-
if (it == Chunk::ChunkType2String.end())
|
|
101
|
-
{
|
|
102
|
-
return Unknown;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return it->second;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
108
|
/* Instance methods. */
|
|
109
109
|
|
|
110
110
|
Chunk::Chunk(uint8_t* buffer, size_t bufferLength) : TLV(buffer, bufferLength)
|
|
@@ -312,13 +312,13 @@ namespace RTC
|
|
|
312
312
|
chunk->SetLength(GetLength());
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
void Chunk::InitializeHeader(ChunkType chunkType, uint8_t flags, uint16_t
|
|
315
|
+
void Chunk::InitializeHeader(ChunkType chunkType, uint8_t flags, uint16_t length)
|
|
316
316
|
{
|
|
317
317
|
MS_TRACE();
|
|
318
318
|
|
|
319
319
|
SetType(chunkType);
|
|
320
320
|
SetFlags(flags);
|
|
321
|
-
InitializeTLVHeader(
|
|
321
|
+
InitializeTLVHeader(length);
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
bool Chunk::ParseParameters()
|
|
@@ -32,6 +32,22 @@ namespace RTC
|
|
|
32
32
|
|
|
33
33
|
/* Class methods. */
|
|
34
34
|
|
|
35
|
+
const std::string& ErrorCause::ErrorCauseCodeToString(ErrorCauseCode causeCode)
|
|
36
|
+
{
|
|
37
|
+
MS_TRACE();
|
|
38
|
+
|
|
39
|
+
static const std::string Unknown("UNKNOWN");
|
|
40
|
+
|
|
41
|
+
auto it = ErrorCause::ErrorCauseCode2String.find(causeCode);
|
|
42
|
+
|
|
43
|
+
if (it == ErrorCause::ErrorCauseCode2String.end())
|
|
44
|
+
{
|
|
45
|
+
return Unknown;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return it->second;
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
bool ErrorCause::IsErrorCause(
|
|
36
52
|
const uint8_t* buffer,
|
|
37
53
|
size_t bufferLength,
|
|
@@ -51,22 +67,6 @@ namespace RTC
|
|
|
51
67
|
return true;
|
|
52
68
|
}
|
|
53
69
|
|
|
54
|
-
const std::string& ErrorCause::ErrorCauseCodeToString(ErrorCauseCode causeCode)
|
|
55
|
-
{
|
|
56
|
-
MS_TRACE();
|
|
57
|
-
|
|
58
|
-
static const std::string Unknown("UNKNOWN");
|
|
59
|
-
|
|
60
|
-
auto it = ErrorCause::ErrorCauseCode2String.find(causeCode);
|
|
61
|
-
|
|
62
|
-
if (it == ErrorCause::ErrorCauseCode2String.end())
|
|
63
|
-
{
|
|
64
|
-
return Unknown;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return it->second;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
70
|
/* Instance methods. */
|
|
71
71
|
|
|
72
72
|
ErrorCause::ErrorCause(uint8_t* buffer, size_t bufferLength) : TLV(buffer, bufferLength)
|
|
@@ -107,12 +107,12 @@ namespace RTC
|
|
|
107
107
|
SetBuffer(const_cast<uint8_t*>(buffer));
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
void ErrorCause::InitializeHeader(ErrorCauseCode causeCode, uint16_t
|
|
110
|
+
void ErrorCause::InitializeHeader(ErrorCauseCode causeCode, uint16_t length)
|
|
111
111
|
{
|
|
112
112
|
MS_TRACE();
|
|
113
113
|
|
|
114
114
|
SetCode(causeCode);
|
|
115
|
-
InitializeTLVHeader(
|
|
115
|
+
InitializeTLVHeader(length);
|
|
116
116
|
}
|
|
117
117
|
} // namespace SCTP
|
|
118
118
|
} // namespace RTC
|
|
@@ -35,6 +35,22 @@ namespace RTC
|
|
|
35
35
|
|
|
36
36
|
/* Class methods. */
|
|
37
37
|
|
|
38
|
+
const std::string& Parameter::ParameterTypeToString(ParameterType parameterType)
|
|
39
|
+
{
|
|
40
|
+
MS_TRACE();
|
|
41
|
+
|
|
42
|
+
static const std::string Unknown("UNKNOWN");
|
|
43
|
+
|
|
44
|
+
auto it = Parameter::ParameterType2String.find(parameterType);
|
|
45
|
+
|
|
46
|
+
if (it == Parameter::ParameterType2String.end())
|
|
47
|
+
{
|
|
48
|
+
return Unknown;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return it->second;
|
|
52
|
+
}
|
|
53
|
+
|
|
38
54
|
bool Parameter::IsParameter(
|
|
39
55
|
const uint8_t* buffer,
|
|
40
56
|
size_t bufferLength,
|
|
@@ -54,22 +70,6 @@ namespace RTC
|
|
|
54
70
|
return true;
|
|
55
71
|
}
|
|
56
72
|
|
|
57
|
-
const std::string& Parameter::ParameterTypeToString(ParameterType parameterType)
|
|
58
|
-
{
|
|
59
|
-
MS_TRACE();
|
|
60
|
-
|
|
61
|
-
static const std::string Unknown("UNKNOWN");
|
|
62
|
-
|
|
63
|
-
auto it = Parameter::ParameterType2String.find(parameterType);
|
|
64
|
-
|
|
65
|
-
if (it == Parameter::ParameterType2String.end())
|
|
66
|
-
{
|
|
67
|
-
return Unknown;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return it->second;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
73
|
/* Instance methods. */
|
|
74
74
|
|
|
75
75
|
Parameter::Parameter(uint8_t* buffer, size_t bufferLength) : TLV(buffer, bufferLength)
|
|
@@ -110,12 +110,12 @@ namespace RTC
|
|
|
110
110
|
SetBuffer(const_cast<uint8_t*>(buffer));
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
void Parameter::InitializeHeader(ParameterType parameterType, uint16_t
|
|
113
|
+
void Parameter::InitializeHeader(ParameterType parameterType, uint16_t length)
|
|
114
114
|
{
|
|
115
115
|
MS_TRACE();
|
|
116
116
|
|
|
117
117
|
SetType(parameterType);
|
|
118
|
-
InitializeTLVHeader(
|
|
118
|
+
InitializeTLVHeader(length);
|
|
119
119
|
}
|
|
120
120
|
} // namespace SCTP
|
|
121
121
|
} // namespace RTC
|
|
@@ -80,31 +80,22 @@ namespace RTC
|
|
|
80
80
|
GetBufferLength());
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
void TLV::InitializeTLVHeader(uint16_t
|
|
83
|
+
void TLV::InitializeTLVHeader(uint16_t length)
|
|
84
84
|
{
|
|
85
85
|
MS_TRACE();
|
|
86
86
|
|
|
87
|
-
SetLengthField(
|
|
87
|
+
SetLengthField(length);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
void TLV::
|
|
90
|
+
void TLV::SetVariableLengthValue(const uint8_t* value, size_t valueLength)
|
|
91
91
|
{
|
|
92
92
|
MS_TRACE();
|
|
93
93
|
|
|
94
|
-
if (
|
|
94
|
+
if (value == nullptr && valueLength > 0)
|
|
95
95
|
{
|
|
96
|
-
MS_THROW_TYPE_ERROR("
|
|
96
|
+
MS_THROW_TYPE_ERROR("value cannot be nullptr if valueLength is > 0");
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
Utils::Byte::Set2Bytes(const_cast<uint8_t*>(GetBuffer()), 2, lengthField);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
void TLV::SetVariableLengthValue(const uint8_t* value, size_t valueLength)
|
|
103
|
-
{
|
|
104
|
-
MS_TRACE();
|
|
105
|
-
|
|
106
|
-
MS_ASSERT(value != nullptr || valueLength == 0, "value cannot be nullptr if valueLength is > 0");
|
|
107
|
-
|
|
108
99
|
// NOTE: This can throw.
|
|
109
100
|
SetVariableLengthValueLength(valueLength);
|
|
110
101
|
|
|
@@ -118,12 +109,12 @@ namespace RTC
|
|
|
118
109
|
{
|
|
119
110
|
MS_TRACE();
|
|
120
111
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
const size_t previousLength = GetLength();
|
|
113
|
+
const uint16_t previousLengthField = GetLengthField();
|
|
114
|
+
const uint16_t previousValueLength = GetVariableLengthValueLength();
|
|
115
|
+
const size_t newNotPaddedLength =
|
|
125
116
|
size_t{ previousLengthField } - size_t{ previousValueLength } + valueLength;
|
|
126
|
-
|
|
117
|
+
const size_t newPaddedLength = Utils::Byte::PadTo4Bytes(newNotPaddedLength);
|
|
127
118
|
|
|
128
119
|
try
|
|
129
120
|
{
|
|
@@ -134,6 +125,10 @@ namespace RTC
|
|
|
134
125
|
// Update length field.
|
|
135
126
|
// NOTE: This will throw if computed value is too big.
|
|
136
127
|
SetLengthField(newNotPaddedLength);
|
|
128
|
+
|
|
129
|
+
// Fill padding bytes with zero.
|
|
130
|
+
// NOTE: This may throw.
|
|
131
|
+
FillPadding(newPaddedLength - newNotPaddedLength);
|
|
137
132
|
}
|
|
138
133
|
catch (const MediaSoupError& error)
|
|
139
134
|
{
|
|
@@ -143,17 +138,13 @@ namespace RTC
|
|
|
143
138
|
|
|
144
139
|
throw;
|
|
145
140
|
}
|
|
146
|
-
|
|
147
|
-
// Fill padding bytes with zero.
|
|
148
|
-
FillPadding(newPaddedLength - newNotPaddedLength);
|
|
149
141
|
}
|
|
150
142
|
|
|
151
143
|
void TLV::AddItem(const TLV* item)
|
|
152
144
|
{
|
|
153
145
|
MS_TRACE();
|
|
154
146
|
|
|
155
|
-
|
|
156
|
-
auto previousLengthField = GetLengthField();
|
|
147
|
+
const size_t previousLength = GetLength();
|
|
157
148
|
|
|
158
149
|
try
|
|
159
150
|
{
|
|
@@ -169,10 +160,21 @@ namespace RTC
|
|
|
169
160
|
{
|
|
170
161
|
// Rollback.
|
|
171
162
|
SetLength(previousLength);
|
|
172
|
-
SetLengthField(previousLengthField);
|
|
173
163
|
|
|
174
164
|
throw;
|
|
175
165
|
}
|
|
176
166
|
}
|
|
167
|
+
|
|
168
|
+
void TLV::SetLengthField(size_t length)
|
|
169
|
+
{
|
|
170
|
+
MS_TRACE();
|
|
171
|
+
|
|
172
|
+
if (length > std::numeric_limits<uint16_t>::max())
|
|
173
|
+
{
|
|
174
|
+
MS_THROW_TYPE_ERROR("length (%zu bytes) cannot be greater than 65535", length);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
Utils::Byte::Set2Bytes(const_cast<uint8_t*>(GetBuffer()), 2, length);
|
|
178
|
+
}
|
|
177
179
|
} // namespace SCTP
|
|
178
180
|
} // namespace RTC
|
|
@@ -122,7 +122,7 @@ namespace RTC
|
|
|
122
122
|
uint32_t remoteInitialTsn,
|
|
123
123
|
uint32_t remoteAdvertisedReceiverWindowCredit,
|
|
124
124
|
uint64_t tieTag,
|
|
125
|
-
const
|
|
125
|
+
const Capabilities& remoteCapabilities,
|
|
126
126
|
uint64_t creationTimestampMs,
|
|
127
127
|
const uint8_t* macKey,
|
|
128
128
|
size_t macKeyLength)
|
|
@@ -147,7 +147,7 @@ namespace RTC
|
|
|
147
147
|
remoteInitialTsn,
|
|
148
148
|
remoteAdvertisedReceiverWindowCredit,
|
|
149
149
|
tieTag,
|
|
150
|
-
|
|
150
|
+
remoteCapabilities,
|
|
151
151
|
creationTimestampMs,
|
|
152
152
|
macKey,
|
|
153
153
|
macKeyLength);
|
|
@@ -447,7 +447,10 @@ namespace RTC
|
|
|
447
447
|
|
|
448
448
|
auto previousLayers = this->encodingContext->GetCurrentLayers();
|
|
449
449
|
|
|
450
|
-
|
|
450
|
+
// Preserve the original marker bit. ProcessPayload may update it (VP9/AV1
|
|
451
|
+
// overwrite it based on spatial-layer end-of-frame; VP8/H264 do not, so the
|
|
452
|
+
// original packet marker must survive).
|
|
453
|
+
bool marker{ packet->HasMarker() };
|
|
451
454
|
|
|
452
455
|
if (!packet->ProcessPayload(this->encodingContext.get(), marker))
|
|
453
456
|
{
|