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,354 @@
|
|
|
1
|
+
#ifndef MS_RTC_NEW_RTCP_PACKET_HPP
|
|
2
|
+
#define MS_RTC_NEW_RTCP_PACKET_HPP
|
|
3
|
+
|
|
4
|
+
#include "common.hpp"
|
|
5
|
+
#include "RTC/Serializable.hpp"
|
|
6
|
+
#include "Utils.hpp"
|
|
7
|
+
#include <ankerl/unordered_dense.h>
|
|
8
|
+
#include <cstdint>
|
|
9
|
+
#include <string>
|
|
10
|
+
|
|
11
|
+
namespace RTC
|
|
12
|
+
{
|
|
13
|
+
namespace NEW_RTCP
|
|
14
|
+
{
|
|
15
|
+
/**
|
|
16
|
+
* RTCP Packet.
|
|
17
|
+
*
|
|
18
|
+
* @see RFC 3550.
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* - This class represents a single RTCP packet and not a compound packet.
|
|
22
|
+
*/
|
|
23
|
+
class Packet : public Serializable
|
|
24
|
+
{
|
|
25
|
+
// We need that CompoundPacket calls protected and private methods in this
|
|
26
|
+
// class.
|
|
27
|
+
friend class CompoundPacket;
|
|
28
|
+
|
|
29
|
+
public:
|
|
30
|
+
/**
|
|
31
|
+
* RTCP Packet Type.
|
|
32
|
+
*/
|
|
33
|
+
enum class PacketType : uint8_t
|
|
34
|
+
{
|
|
35
|
+
/**
|
|
36
|
+
* Extended Jitter Report.
|
|
37
|
+
*/
|
|
38
|
+
IJ = 195,
|
|
39
|
+
/**
|
|
40
|
+
* RTCP Sender Report.
|
|
41
|
+
*/
|
|
42
|
+
SR = 200,
|
|
43
|
+
/**
|
|
44
|
+
* RTCP Receiver Report.
|
|
45
|
+
*/
|
|
46
|
+
RR = 201,
|
|
47
|
+
/**
|
|
48
|
+
* RTCP Sender Report.
|
|
49
|
+
*/
|
|
50
|
+
SDES = 202,
|
|
51
|
+
/**
|
|
52
|
+
* RTCP BYE.
|
|
53
|
+
*/
|
|
54
|
+
BYE = 203,
|
|
55
|
+
/**
|
|
56
|
+
* RTCP APP.
|
|
57
|
+
*/
|
|
58
|
+
APP = 204,
|
|
59
|
+
/**
|
|
60
|
+
* RTCP Transport Layer Feedback.
|
|
61
|
+
*/
|
|
62
|
+
RTPFB = 205,
|
|
63
|
+
/**
|
|
64
|
+
* RTCP Payload Specific Feedback.
|
|
65
|
+
*/
|
|
66
|
+
PSFB = 206,
|
|
67
|
+
/**
|
|
68
|
+
* RTCP Extended Report.
|
|
69
|
+
*/
|
|
70
|
+
XR = 207,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* RTCP Packet (RTCP Common Header + Value).
|
|
75
|
+
*
|
|
76
|
+
* @see RFC 3550.
|
|
77
|
+
*
|
|
78
|
+
* 0 1 2 3
|
|
79
|
+
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
80
|
+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
81
|
+
* |V=2|P| Count | PT | Length |
|
|
82
|
+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
83
|
+
* \ \
|
|
84
|
+
* / Value /
|
|
85
|
+
* \ \
|
|
86
|
+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
87
|
+
*
|
|
88
|
+
* - Version (2 bits): RTP/RTCP version. Always 2.
|
|
89
|
+
* - Padding (1 bit): If set, the packet contains padding bytes at the
|
|
90
|
+
* end that are not part of the value. The last padding byte indicates
|
|
91
|
+
* how many padding bytes must be ignored, including itself (it will be
|
|
92
|
+
* a multiple of four).
|
|
93
|
+
* - Count (5 bits): Field whose meaning depends on the packet type
|
|
94
|
+
* (PT). RFC 3550 does not assign it a single name because it varies
|
|
95
|
+
* per packet: in Sender/Receiver Report it is the reception report
|
|
96
|
+
* block count (RC), in SDES and BYE it is the source count (SC), and
|
|
97
|
+
* in APP it acts as an application-defined subtype. It is treated
|
|
98
|
+
* generically as a 5-bit value specific to each packet type.
|
|
99
|
+
* - Packet type (8 bits): Identifies the RTCP packet type. Common
|
|
100
|
+
* values: 200 (SR), 201 (RR), 202 (SDES), 203 (BYE), 204 (APP).
|
|
101
|
+
* - Length (16 bits): Length of the RTCP packet in 32-bit words minus
|
|
102
|
+
* one, including the Common Header and any padding. Therefore the
|
|
103
|
+
* total size in bytes is (Length + 1) * 4.
|
|
104
|
+
* - Value (variable length): Packet content, whose format depends on
|
|
105
|
+
* the packet type (PT).
|
|
106
|
+
*
|
|
107
|
+
* @remarks
|
|
108
|
+
* - This struct is guaranteed to be aligned to 4 bytes.
|
|
109
|
+
* - The padding mechanism is not implemented since it's only used when
|
|
110
|
+
* encrypting the compound packet by following the section 9.1 of RFC
|
|
111
|
+
* 3550 which absolutely nobody does (SRTCP is used instead). So
|
|
112
|
+
* packets with Padding bit set to 1 are considered invalid and
|
|
113
|
+
* rejected.
|
|
114
|
+
*/
|
|
115
|
+
struct CommonHeader
|
|
116
|
+
{
|
|
117
|
+
#if defined(MS_LITTLE_ENDIAN)
|
|
118
|
+
uint8_t count : 5;
|
|
119
|
+
uint8_t padding : 1;
|
|
120
|
+
uint8_t version : 2;
|
|
121
|
+
#elif defined(MS_BIG_ENDIAN)
|
|
122
|
+
uint8_t version : 2;
|
|
123
|
+
uint8_t padding : 1;
|
|
124
|
+
uint8_t count : 5;
|
|
125
|
+
#endif
|
|
126
|
+
PacketType packetType;
|
|
127
|
+
uint16_t length;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
public:
|
|
131
|
+
/**
|
|
132
|
+
* Length (in bytes) of the RTCP Common Header.
|
|
133
|
+
*/
|
|
134
|
+
static constexpr size_t CommonHeaderLength{ 4 };
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Whether given buffer could be a valid RTCP packet.
|
|
138
|
+
*/
|
|
139
|
+
static bool IsRtcp(const uint8_t* buffer, size_t bufferLength);
|
|
140
|
+
|
|
141
|
+
static const std::string& PacketTypeToString(PacketType packetType);
|
|
142
|
+
|
|
143
|
+
protected:
|
|
144
|
+
/**
|
|
145
|
+
* Whether given buffer could be a a valid RTCP packet.
|
|
146
|
+
*
|
|
147
|
+
* @param buffer
|
|
148
|
+
* @param bufferLength - Can be greater than real packet length.
|
|
149
|
+
* @param packetType - If given buffer is a valid packet then `packetType`
|
|
150
|
+
* is rewritten to parsed PacketType.
|
|
151
|
+
* @param packetLength - If given buffer is a valid packet then
|
|
152
|
+
* `packetLength` is rewritten to the computed length of the packet.
|
|
153
|
+
*
|
|
154
|
+
* @remarks
|
|
155
|
+
* - Packets with Padding bit set to 1 are not supported (see note above)
|
|
156
|
+
* and hence this function returns false if it's set.
|
|
157
|
+
*/
|
|
158
|
+
static bool IsPacket(
|
|
159
|
+
const uint8_t* buffer, size_t bufferLength, PacketType& packetType, size_t& packetLength);
|
|
160
|
+
|
|
161
|
+
private:
|
|
162
|
+
static const ankerl::unordered_dense::map<PacketType, std::string> PacketType2String;
|
|
163
|
+
|
|
164
|
+
protected:
|
|
165
|
+
/**
|
|
166
|
+
* Constructor is protected because we only want to create packets
|
|
167
|
+
* instances via Parse() and Factory() in subclasses.
|
|
168
|
+
*/
|
|
169
|
+
Packet(uint8_t* buffer, size_t bufferLength);
|
|
170
|
+
|
|
171
|
+
public:
|
|
172
|
+
~Packet() override;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Must be overridden by each subclass.
|
|
176
|
+
*/
|
|
177
|
+
void Dump(int indentation = 0) const override = 0;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Must be overridden by each subclass.
|
|
181
|
+
*/
|
|
182
|
+
Packet* Clone(uint8_t* buffer, size_t bufferLength) const override = 0;
|
|
183
|
+
|
|
184
|
+
uint8_t GetVersion() const
|
|
185
|
+
{
|
|
186
|
+
return GetCommonHeaderPointer()->version;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
PacketType GetType() const
|
|
190
|
+
{
|
|
191
|
+
return GetCommonHeaderPointer()->packetType;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* False by default. UnknownPacket class overrides this method to return
|
|
196
|
+
* true instead.
|
|
197
|
+
*/
|
|
198
|
+
virtual bool HasUnknownType() const
|
|
199
|
+
{
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Whether the Padding bit is set to 1.
|
|
205
|
+
*
|
|
206
|
+
* @remarks
|
|
207
|
+
* - The padding mechanism is not implemented since it's only used when
|
|
208
|
+
* encrypting the compound packet by following the section 9.1 of RFC
|
|
209
|
+
* 3550 which absolutely nobody does (SRTCP is used instead). So
|
|
210
|
+
* packets with Padding bit set to 1 are considered invalid and
|
|
211
|
+
* rejected.
|
|
212
|
+
*/
|
|
213
|
+
bool HasPadding() const
|
|
214
|
+
{
|
|
215
|
+
return GetCommonHeaderPointer()->padding;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
protected:
|
|
219
|
+
/**
|
|
220
|
+
* Subclasses must invoke this method within their Dump() method.
|
|
221
|
+
*/
|
|
222
|
+
void DumpCommon(int indentation) const;
|
|
223
|
+
|
|
224
|
+
virtual void SoftSerialize(const uint8_t* buffer) final;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Can be overridden by each subclass.
|
|
228
|
+
*/
|
|
229
|
+
virtual Packet* SoftClone(const uint8_t* buffer) const = 0;
|
|
230
|
+
|
|
231
|
+
virtual void SoftCloneInto(Packet* packet) const final;
|
|
232
|
+
|
|
233
|
+
virtual void InitializeHeader(PacketType packetType, uint16_t length) final;
|
|
234
|
+
|
|
235
|
+
virtual uint8_t GetCount() const final
|
|
236
|
+
{
|
|
237
|
+
return GetCommonHeaderPointer()->count;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
virtual void SetCount(uint8_t count) final
|
|
241
|
+
{
|
|
242
|
+
GetCommonHeaderPointer()->count = count;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Value of the Length field, which is the length of the RTCP packet in
|
|
247
|
+
* 32-bit words minus one, including the Common Header and any padding.
|
|
248
|
+
* Therefore the total size in bytes is (Length + 1) * 4.
|
|
249
|
+
*/
|
|
250
|
+
virtual uint16_t GetLengthField() const final
|
|
251
|
+
{
|
|
252
|
+
return Utils::Byte::Get2Bytes(GetBuffer(), 2);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Computed value (in bytes) of the Length field.
|
|
257
|
+
*/
|
|
258
|
+
virtual size_t GetLengthFieldComputed() const final
|
|
259
|
+
{
|
|
260
|
+
return (static_cast<size_t>(GetLengthField()) + 1) * 4;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Set the Length field given the total packet length in bytes. It
|
|
265
|
+
* encodes it as 32-bit words minus one as required by the RTCP Length
|
|
266
|
+
* field.
|
|
267
|
+
*
|
|
268
|
+
* @throw MediaSoupTypeError - If given `length` is higher than the maximum
|
|
269
|
+
* representable packet length (262144 bytes).
|
|
270
|
+
*/
|
|
271
|
+
virtual void SetLengthField(size_t length) final;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* A pointer to the position in the buffer where the variable-length value
|
|
275
|
+
* (if any) starts or should start.
|
|
276
|
+
*/
|
|
277
|
+
virtual uint8_t* GetVariableLengthValuePointer() const final
|
|
278
|
+
{
|
|
279
|
+
return const_cast<uint8_t*>(GetBuffer()) + Packet::CommonHeaderLength;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Whether this packet contains a variable-length value.
|
|
284
|
+
*
|
|
285
|
+
* @see GetVariableLengthValue()
|
|
286
|
+
*/
|
|
287
|
+
virtual bool HasVariableLengthValue() const final
|
|
288
|
+
{
|
|
289
|
+
return GetLengthFieldComputed() > Packet::CommonHeaderLength;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Variable-length value of this packet.
|
|
294
|
+
*/
|
|
295
|
+
virtual const uint8_t* GetVariableLengthValue() const final
|
|
296
|
+
{
|
|
297
|
+
if (!HasVariableLengthValue())
|
|
298
|
+
{
|
|
299
|
+
return nullptr;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return GetVariableLengthValuePointer();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Set the variable-length value. It copies the given value into the
|
|
307
|
+
* the variable-length value of the packet and updates both the length of
|
|
308
|
+
* the Serializable and the length field.
|
|
309
|
+
*
|
|
310
|
+
* @throw MediaSoupTypeError - If given `valueLength` is higher than
|
|
311
|
+
* available length.
|
|
312
|
+
*
|
|
313
|
+
* @see GetVariableLengthValue()
|
|
314
|
+
*/
|
|
315
|
+
virtual void SetVariableLengthValue(const uint8_t* value, size_t valueLength) final;
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* The length of the variable-length value.
|
|
319
|
+
*/
|
|
320
|
+
virtual size_t GetVariableLengthValueLength() const final
|
|
321
|
+
{
|
|
322
|
+
if (!HasVariableLengthValue())
|
|
323
|
+
{
|
|
324
|
+
return 0u;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return GetLengthFieldComputed() - Packet::CommonHeaderLength;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Set the length of the variable-length value. It doesn't copy any value
|
|
332
|
+
* into the variable-length value. This method is used in packets that
|
|
333
|
+
* have variable-length value but it doesn't consist on a buffer + length,
|
|
334
|
+
* but instead is an structure with fields (with variable length).
|
|
335
|
+
*
|
|
336
|
+
* @see GetVariableLengthValue()
|
|
337
|
+
*/
|
|
338
|
+
virtual void SetVariableLengthValueLength(size_t valueLength) final;
|
|
339
|
+
|
|
340
|
+
private:
|
|
341
|
+
/**
|
|
342
|
+
* @remarks
|
|
343
|
+
* - Returns CommonHeader* instead of const CommonHeader* since we may want
|
|
344
|
+
* to modify its fields.
|
|
345
|
+
*/
|
|
346
|
+
CommonHeader* GetCommonHeaderPointer() const
|
|
347
|
+
{
|
|
348
|
+
return reinterpret_cast<CommonHeader*>(const_cast<uint8_t*>(GetBuffer()));
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
} // namespace NEW_RTCP
|
|
352
|
+
} // namespace RTC
|
|
353
|
+
|
|
354
|
+
#endif
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# TODO NEW RTCP
|
|
2
|
+
|
|
3
|
+
- Remove `NEW_` prefix in folders.
|
|
4
|
+
|
|
5
|
+
- Remove `NEW_` prefix in C++ `NEW_RTCP` namespace.
|
|
6
|
+
|
|
7
|
+
- Remove `NEW_` prefix in `#ifndef` in `.hpp` files.
|
|
8
|
+
|
|
9
|
+
- We are not implementing `NeedsConsolidation()` in `Packet` class (only in `CompoundPacket` class). For now it's ok. Let's see.
|
|
10
|
+
|
|
11
|
+
- `Packet`: Check if we need all those `Get/SetVariableLengthXxxxxx()` methods.
|
|
12
|
+
|
|
13
|
+
- All the `TODO` comments.
|
|
14
|
+
|
|
15
|
+
- Tests for `Packet` and `CompoundPacket`.
|
|
16
|
+
|
|
17
|
+
- Fuzzer for `Packet` and `CompoundPacket`.
|
|
@@ -159,7 +159,9 @@ namespace RTC
|
|
|
159
159
|
{
|
|
160
160
|
switch (mimeType.subtype)
|
|
161
161
|
{
|
|
162
|
+
case RTC::RtpCodecMimeType::Subtype::VP8:
|
|
162
163
|
case RTC::RtpCodecMimeType::Subtype::VP9:
|
|
164
|
+
case RTC::RtpCodecMimeType::Subtype::H264:
|
|
163
165
|
case RTC::RtpCodecMimeType::Subtype::AV1:
|
|
164
166
|
{
|
|
165
167
|
return true;
|
|
@@ -49,11 +49,11 @@ namespace RTC
|
|
|
49
49
|
|
|
50
50
|
private:
|
|
51
51
|
RTC::Transport* AssertAndGetTransportById(
|
|
52
|
-
const std::string& transportId, const std::string&
|
|
52
|
+
const std::string& transportId, const std::string& method) const;
|
|
53
53
|
RTC::RtpObserver* AssertAndGetRtpObserverById(
|
|
54
|
-
const std::string& rtpObserverId, const std::string&
|
|
55
|
-
void CheckNoTransport(const std::string& transportId, const std::string&
|
|
56
|
-
void CheckNoRtpObserver(const std::string& rtpObserverId, const std::string&
|
|
54
|
+
const std::string& rtpObserverId, const std::string& method) const;
|
|
55
|
+
void CheckNoTransport(const std::string& transportId, const std::string& method) const;
|
|
56
|
+
void CheckNoRtpObserver(const std::string& rtpObserverId, const std::string& method) const;
|
|
57
57
|
|
|
58
58
|
/* Pure virtual methods inherited from RTC::Transport::Listener. */
|
|
59
59
|
public:
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#ifndef MS_RTC_SCTP_CAPABILITIES_HPP
|
|
2
|
+
#define MS_RTC_SCTP_CAPABILITIES_HPP
|
|
3
|
+
|
|
4
|
+
#include "common.hpp"
|
|
5
|
+
#include "RTC/SCTP/packet/chunks/AnyInitChunk.hpp"
|
|
6
|
+
#include "RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp"
|
|
7
|
+
|
|
8
|
+
namespace RTC
|
|
9
|
+
{
|
|
10
|
+
namespace SCTP
|
|
11
|
+
{
|
|
12
|
+
/**
|
|
13
|
+
* Those are the raw SCTP capabilities announced by an endpoint in its INIT
|
|
14
|
+
* or INIT-ACK chunk, before any negotiation against local options takes
|
|
15
|
+
* place.
|
|
16
|
+
*/
|
|
17
|
+
struct Capabilities
|
|
18
|
+
{
|
|
19
|
+
/**
|
|
20
|
+
* Create a Capabilities struct holding the capabilities announced by
|
|
21
|
+
* the remote endpoint. No local option is applied here.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* - Given `remoteChunk` must be an INIT or an INIT-ACK chunk.
|
|
25
|
+
*/
|
|
26
|
+
static Capabilities Factory(const AnyInitChunk* remoteChunk);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Maximum number of outbound streams (OS).
|
|
30
|
+
*/
|
|
31
|
+
uint16_t maxOutboundStreams{ 0 };
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Maximum number of inbound streams (MIS).
|
|
35
|
+
*/
|
|
36
|
+
uint16_t maxInboundStreams{ 0 };
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Partial Reliability Extension.
|
|
40
|
+
*
|
|
41
|
+
* @see RFC 3758.
|
|
42
|
+
*/
|
|
43
|
+
bool partialReliability{ false };
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Stream Schedulers and User Message Interleaving (I-DATA chunks).
|
|
47
|
+
*
|
|
48
|
+
* @see RFC 8260.
|
|
49
|
+
*/
|
|
50
|
+
bool messageInterleaving{ false };
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Stream Re-Configuration.
|
|
54
|
+
*
|
|
55
|
+
* @see RFC 6525.
|
|
56
|
+
*/
|
|
57
|
+
bool reConfig{ false };
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Alternate Error Detection Method for Zero Checksum.
|
|
61
|
+
*
|
|
62
|
+
* @see RFC 9653.
|
|
63
|
+
*/
|
|
64
|
+
ZeroChecksumAcceptableParameter::AlternateErrorDetectionMethod zeroChecksumAlternateErrorDetectionMethod{
|
|
65
|
+
ZeroChecksumAcceptableParameter::AlternateErrorDetectionMethod::NONE
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
void Dump(int indentation = 0) const;
|
|
69
|
+
};
|
|
70
|
+
} // namespace SCTP
|
|
71
|
+
} // namespace RTC
|
|
72
|
+
|
|
73
|
+
#endif
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#define MS_RTC_SCTP_NEGOTIATED_CAPABILITIES_HPP
|
|
3
3
|
|
|
4
4
|
#include "common.hpp"
|
|
5
|
-
#include "RTC/SCTP/
|
|
5
|
+
#include "RTC/SCTP/association/Capabilities.hpp"
|
|
6
6
|
#include "RTC/SCTP/public/SctpOptions.hpp"
|
|
7
7
|
|
|
8
8
|
namespace RTC
|
|
@@ -17,24 +17,22 @@ namespace RTC
|
|
|
17
17
|
struct NegotiatedCapabilities
|
|
18
18
|
{
|
|
19
19
|
/**
|
|
20
|
-
* Create a NegotiatedCapabilities struct
|
|
21
|
-
* the
|
|
22
|
-
*
|
|
23
|
-
* @remarks
|
|
24
|
-
* - Given `remoteChunk` must be an INIT or an INIT-ACK chunk.
|
|
20
|
+
* Create a NegotiatedCapabilities struct by negotiating the capabilities
|
|
21
|
+
* announced by the remote endpoint against our local options. Intended
|
|
22
|
+
* to be used during the SCTP association handshake flow.
|
|
25
23
|
*/
|
|
26
24
|
static NegotiatedCapabilities Factory(
|
|
27
|
-
const SctpOptions& sctpOptions, const
|
|
25
|
+
const SctpOptions& sctpOptions, const Capabilities& remoteCapabilities);
|
|
28
26
|
|
|
29
27
|
/**
|
|
30
28
|
* Negotiated maximum number of outbound streams (OS).
|
|
31
29
|
*/
|
|
32
|
-
uint16_t
|
|
30
|
+
uint16_t maxOutboundStreams{ 0 };
|
|
33
31
|
|
|
34
32
|
/**
|
|
35
33
|
* Negotiated maximum number of inbound streams (MIS).
|
|
36
34
|
*/
|
|
37
|
-
uint16_t
|
|
35
|
+
uint16_t maxInboundStreams{ 0 };
|
|
38
36
|
|
|
39
37
|
/**
|
|
40
38
|
* Partial Reliability Extension.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#define MS_RTC_SCTP_STATE_COOKIE_HPP
|
|
3
3
|
|
|
4
4
|
#include "common.hpp"
|
|
5
|
-
#include "RTC/SCTP/association/
|
|
5
|
+
#include "RTC/SCTP/association/Capabilities.hpp"
|
|
6
6
|
#include "RTC/SCTP/public/SctpTypes.hpp"
|
|
7
7
|
#include "RTC/Serializable.hpp"
|
|
8
8
|
#include "Utils.hpp"
|
|
@@ -38,30 +38,41 @@ namespace RTC
|
|
|
38
38
|
* | |
|
|
39
39
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
40
40
|
* \ \
|
|
41
|
-
* /
|
|
41
|
+
* / Remote Capabilities /
|
|
42
42
|
* \ \
|
|
43
43
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
44
44
|
*
|
|
45
|
-
*
|
|
45
|
+
* The Remote Capabilities are the raw capabilities announced by the remote
|
|
46
|
+
* endpoint in its INIT or INIT-ACK chunk (before being negotiated against
|
|
47
|
+
* our local options). Storing the raw remote capabilities (instead of the
|
|
48
|
+
* already negotiated ones) limits the effect of a tampered/forged cookie:
|
|
49
|
+
* when the COOKIE-ECHO is received they are re-negotiated against our local
|
|
50
|
+
* options, so an attacker can never enable an extension we didn't signal
|
|
51
|
+
* nor raise the stream limits above what we announced.
|
|
52
|
+
*
|
|
53
|
+
* Remote Capabilities are serialized as follows:
|
|
46
54
|
*
|
|
47
55
|
* 0 1 2 3
|
|
48
56
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
49
57
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
50
|
-
* | (Reserved) |
|
|
58
|
+
* | (Reserved) | |C|B|A| Magic 2 |
|
|
59
|
+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
60
|
+
* | Zero Checksum Alternate Error Detection Method |
|
|
51
61
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
52
62
|
* | Max Outbound Streams | Max Inbound Streams |
|
|
53
63
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
54
64
|
*
|
|
55
65
|
* - Flag A (partialReliability): Partial Reliability Extension.
|
|
56
66
|
* - Flag B (messageInterleaving): Stream Schedulers and User Message
|
|
57
|
-
*
|
|
58
|
-
* - Flag C (
|
|
59
|
-
* -
|
|
67
|
+
* Interleaving (I-DATA).
|
|
68
|
+
* - Flag C (reConfig): Stream Reconfiguration.
|
|
69
|
+
* - Zero Checksum Alternate Error Detection Method: the method announced
|
|
70
|
+
* by the remote endpoint (0 means none).
|
|
60
71
|
*
|
|
61
72
|
* When State Cookie authentication is enabled (see
|
|
62
73
|
* `SctpOptions::requireAuthenticatedCookie`), two extra fields are appended
|
|
63
|
-
* after the
|
|
64
|
-
*
|
|
74
|
+
* after the Remote Capabilities so the receiver can verify that the cookie
|
|
75
|
+
* was generated by itself and is not stale:
|
|
65
76
|
*
|
|
66
77
|
* 0 1 2 3
|
|
67
78
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
@@ -83,39 +94,37 @@ namespace RTC
|
|
|
83
94
|
class StateCookie : public Serializable
|
|
84
95
|
{
|
|
85
96
|
private:
|
|
86
|
-
struct
|
|
97
|
+
struct RemoteCapabilitiesField
|
|
87
98
|
{
|
|
88
99
|
uint8_t reserved;
|
|
89
100
|
#if defined(MS_LITTLE_ENDIAN)
|
|
90
101
|
uint8_t bitA : 1;
|
|
91
102
|
uint8_t bitB : 1;
|
|
92
103
|
uint8_t bitC : 1;
|
|
93
|
-
uint8_t
|
|
94
|
-
uint8_t unusedBits : 4;
|
|
104
|
+
uint8_t unusedBits : 5;
|
|
95
105
|
#elif defined(MS_BIG_ENDIAN)
|
|
96
|
-
uint8_t unusedBits :
|
|
97
|
-
uint8_t bitD : 1;
|
|
106
|
+
uint8_t unusedBits : 5;
|
|
98
107
|
uint8_t bitC : 1;
|
|
99
108
|
uint8_t bitB : 1;
|
|
100
109
|
uint8_t bitA : 1;
|
|
101
110
|
#endif
|
|
102
111
|
uint16_t magic2;
|
|
103
|
-
|
|
104
|
-
uint16_t
|
|
112
|
+
uint32_t zeroChecksumAlternateErrorDetectionMethod;
|
|
113
|
+
uint16_t maxOutboundStreams;
|
|
114
|
+
uint16_t maxInboundStreams;
|
|
105
115
|
};
|
|
106
116
|
|
|
107
117
|
public:
|
|
108
118
|
// Fixed length of our generated State Cookies when authentication is
|
|
109
119
|
// disabled.
|
|
110
|
-
static constexpr size_t StateCookieLength{
|
|
111
|
-
// Offset in the State Cookie where the
|
|
112
|
-
|
|
113
|
-
static constexpr size_t NegotiatedCapabilitiesOffset{ 36 };
|
|
120
|
+
static constexpr size_t StateCookieLength{ 48 };
|
|
121
|
+
// Offset in the State Cookie where the Remote Capabilities are located.
|
|
122
|
+
static constexpr size_t RemoteCapabilitiesOffset{ 36 };
|
|
114
123
|
// Magic value we prefix the State Cookie with. Note that it is
|
|
115
124
|
// "msworker" in ASCII bytes.
|
|
116
125
|
static constexpr uint64_t Magic1{ 0x6D73776F726B6572 };
|
|
117
126
|
static constexpr size_t Magic1Length{ 8 };
|
|
118
|
-
// Magic value used within the
|
|
127
|
+
// Magic value used within the Remote Capabilities block.
|
|
119
128
|
static constexpr uint16_t Magic2{ 0xAD81 };
|
|
120
129
|
// Offset of the creation timestamp present in authenticated State
|
|
121
130
|
// Cookies.
|
|
@@ -165,7 +174,7 @@ namespace RTC
|
|
|
165
174
|
uint32_t remoteInitialTsn,
|
|
166
175
|
uint32_t remoteAdvertisedReceiverWindowCredit,
|
|
167
176
|
uint64_t tieTag,
|
|
168
|
-
const
|
|
177
|
+
const Capabilities& remoteCapabilities,
|
|
169
178
|
uint64_t creationTimestampMs = 0,
|
|
170
179
|
const uint8_t* macKey = nullptr,
|
|
171
180
|
size_t macKeyLength = 0);
|
|
@@ -187,7 +196,7 @@ namespace RTC
|
|
|
187
196
|
uint32_t remoteInitialTsn,
|
|
188
197
|
uint32_t remoteAdvertisedReceiverWindowCredit,
|
|
189
198
|
uint64_t tieTag,
|
|
190
|
-
const
|
|
199
|
+
const Capabilities& remoteCapabilities,
|
|
191
200
|
uint64_t creationTimestampMs = 0,
|
|
192
201
|
const uint8_t* macKey = nullptr,
|
|
193
202
|
size_t macKeyLength = 0);
|
|
@@ -287,9 +296,10 @@ namespace RTC
|
|
|
287
296
|
}
|
|
288
297
|
|
|
289
298
|
/**
|
|
290
|
-
*
|
|
299
|
+
* Raw capabilities announced by the remote endpoint (before being
|
|
300
|
+
* negotiated against our local options).
|
|
291
301
|
*/
|
|
292
|
-
|
|
302
|
+
Capabilities GetRemoteCapabilities() const;
|
|
293
303
|
|
|
294
304
|
/**
|
|
295
305
|
* Whether this is an authenticated StateCookie (i.e. it carries a
|
|
@@ -312,10 +322,10 @@ namespace RTC
|
|
|
312
322
|
}
|
|
313
323
|
|
|
314
324
|
private:
|
|
315
|
-
|
|
325
|
+
RemoteCapabilitiesField* GetRemoteCapabilitiesField() const
|
|
316
326
|
{
|
|
317
|
-
return reinterpret_cast<
|
|
318
|
-
const_cast<uint8_t*>(GetBuffer()) + StateCookie::
|
|
327
|
+
return reinterpret_cast<RemoteCapabilitiesField*>(
|
|
328
|
+
const_cast<uint8_t*>(GetBuffer()) + StateCookie::RemoteCapabilitiesOffset);
|
|
319
329
|
}
|
|
320
330
|
};
|
|
321
331
|
} // namespace SCTP
|