mediasoup 3.12.8 → 3.12.9

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.
@@ -226,11 +226,11 @@ class Router extends EnhancedEventEmitter_1.EnhancedEventEmitter {
226
226
  transport.on('@producerclose', (producer) => this.#producers.delete(producer.id));
227
227
  transport.on('@newdataproducer', (dataProducer) => (this.#dataProducers.set(dataProducer.id, dataProducer)));
228
228
  transport.on('@dataproducerclose', (dataProducer) => (this.#dataProducers.delete(dataProducer.id)));
229
+ // Emit observer event.
230
+ this.#observer.safeEmit('newtransport', transport);
229
231
  if (webRtcServer) {
230
232
  webRtcServer.handleWebRtcTransport(transport);
231
233
  }
232
- // Emit observer event.
233
- this.#observer.safeEmit('newtransport', transport);
234
234
  return transport;
235
235
  }
236
236
  /**
@@ -90,7 +90,7 @@ class Worker extends EnhancedEventEmitter_1.EnhancedEventEmitter {
90
90
  // options
91
91
  {
92
92
  env: {
93
- MEDIASOUP_VERSION: '3.12.8',
93
+ MEDIASOUP_VERSION: '3.12.9',
94
94
  // Let the worker process inherit all environment variables, useful
95
95
  // if a custom and not in the path GCC is used so the user can set
96
96
  // LD_LIBRARY_PATH environment variable for runtime.
@@ -10,7 +10,7 @@ export { types };
10
10
  /**
11
11
  * Expose mediasoup version.
12
12
  */
13
- export declare const version = "3.12.8";
13
+ export declare const version = "3.12.9";
14
14
  /**
15
15
  * Expose parseScalabilityMode() function.
16
16
  */
package/node/lib/index.js CHANGED
@@ -12,7 +12,7 @@ exports.types = types;
12
12
  /**
13
13
  * Expose mediasoup version.
14
14
  */
15
- exports.version = '3.12.8';
15
+ exports.version = '3.12.9';
16
16
  /**
17
17
  * Expose parseScalabilityMode() function.
18
18
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasoup",
3
- "version": "3.12.8",
3
+ "version": "3.12.9",
4
4
  "description": "Cutting Edge WebRTC Video Conferencing",
5
5
  "contributors": [
6
6
  "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
@@ -89,7 +89,7 @@
89
89
  "dependencies": {
90
90
  "debug": "^4.3.4",
91
91
  "h264-profile-level-id": "^1.0.1",
92
- "node-fetch": "^3.3.1",
92
+ "node-fetch": "^3.3.2",
93
93
  "supports-color": "^9.4.0",
94
94
  "tar": "^6.1.15",
95
95
  "uuid": "^9.0.0"
@@ -98,14 +98,14 @@
98
98
  "@octokit/rest": "^20.0.1",
99
99
  "@types/debug": "^4.1.8",
100
100
  "@types/jest": "^29.5.3",
101
- "@types/node": "^20.4.2",
101
+ "@types/node": "^20.4.9",
102
102
  "@types/uuid": "^9.0.2",
103
- "@typescript-eslint/eslint-plugin": "^6.1.0",
104
- "@typescript-eslint/parser": "^6.1.0",
105
- "eslint": "^8.45.0",
103
+ "@typescript-eslint/eslint-plugin": "^6.3.0",
104
+ "@typescript-eslint/parser": "^6.3.0",
105
+ "eslint": "^8.46.0",
106
106
  "eslint-plugin-jest": "^27.2.3",
107
- "jest": "^29.6.1",
108
- "marked": "^5.1.1",
107
+ "jest": "^29.6.2",
108
+ "marked": "^7.0.1",
109
109
  "open-cli": "^7.2.0",
110
110
  "pick-port": "^1.0.1",
111
111
  "sctp": "^1.0.0",
@@ -121,6 +121,9 @@ namespace RTC
121
121
  size += item->GetSize();
122
122
  }
123
123
 
124
+ // Add the mandatory null octet.
125
+ ++size;
126
+
124
127
  // Consider pading to 32 bits (4 bytes) boundary.
125
128
  // http://stackoverflow.com/questions/11642210/computing-padding-required-for-n-byte-alignment
126
129
  return (size + 3) & ~3;
@@ -24,9 +24,9 @@ namespace Channel
24
24
  }
25
25
  }
26
26
 
27
- inline static void onClose(uv_handle_t* handle)
27
+ inline static void onCloseAsync(uv_handle_t* handle)
28
28
  {
29
- delete handle;
29
+ delete reinterpret_cast<uv_async_t*>(handle);
30
30
  }
31
31
 
32
32
  /* Instance methods. */
@@ -100,7 +100,8 @@ namespace Channel
100
100
 
101
101
  if (this->uvReadHandle)
102
102
  {
103
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvReadHandle), static_cast<uv_close_cb>(onClose));
103
+ uv_close(
104
+ reinterpret_cast<uv_handle_t*>(this->uvReadHandle), static_cast<uv_close_cb>(onCloseAsync));
104
105
  }
105
106
 
106
107
  if (this->consumerSocket)
@@ -11,9 +11,9 @@ thread_local uv_loop_t* DepLibUV::loop{ nullptr };
11
11
 
12
12
  /* Static methods for UV callbacks. */
13
13
 
14
- inline static void onClose(uv_handle_t* handle)
14
+ inline static void onCloseLoop(uv_handle_t* handle)
15
15
  {
16
- delete handle;
16
+ delete reinterpret_cast<uv_loop_t*>(handle);
17
17
  }
18
18
 
19
19
  inline static void onWalk(uv_handle_t* handle, void* /*arg*/)
@@ -27,7 +27,7 @@ inline static void onWalk(uv_handle_t* handle, void* /*arg*/)
27
27
  uv_has_ref(handle));
28
28
 
29
29
  if (!uv_is_closing(handle))
30
- uv_close(handle, onClose);
30
+ uv_close(handle, onCloseLoop);
31
31
  }
32
32
 
33
33
  /* Static methods. */
@@ -25,9 +25,9 @@ namespace PayloadChannel
25
25
  }
26
26
  }
27
27
 
28
- inline static void onClose(uv_handle_t* handle)
28
+ inline static void onCloseAsync(uv_handle_t* handle)
29
29
  {
30
- delete handle;
30
+ delete reinterpret_cast<uv_async_t*>(handle);
31
31
  }
32
32
 
33
33
  /* Instance methods. */
@@ -102,7 +102,8 @@ namespace PayloadChannel
102
102
 
103
103
  if (this->uvReadHandle)
104
104
  {
105
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvReadHandle), static_cast<uv_close_cb>(onClose));
105
+ uv_close(
106
+ reinterpret_cast<uv_handle_t*>(this->uvReadHandle), static_cast<uv_close_cb>(onCloseAsync));
106
107
  }
107
108
 
108
109
  if (this->consumerSocket)
@@ -12,9 +12,16 @@
12
12
 
13
13
  /* Static methods for UV callbacks. */
14
14
 
15
- static inline void onClose(uv_handle_t* handle)
15
+ // NOTE: We have different onCloseXxx() callbacks to avoid an ASAN warning by
16
+ // ensuring that we call `delete xxx` with same type as `new xxx` before.
17
+ static inline void onCloseUdp(uv_handle_t* handle)
16
18
  {
17
- delete handle;
19
+ delete reinterpret_cast<uv_udp_t*>(handle);
20
+ }
21
+
22
+ static inline void onCloseTcp(uv_handle_t* handle)
23
+ {
24
+ delete reinterpret_cast<uv_tcp_t*>(handle);
18
25
  }
19
26
 
20
27
  inline static void onFakeConnection(uv_stream_t* /*handle*/, int /*status*/)
@@ -161,30 +168,44 @@ namespace RTC
161
168
  switch (transport)
162
169
  {
163
170
  case Transport::UDP:
171
+ {
164
172
  uvHandle = reinterpret_cast<uv_handle_t*>(new uv_udp_t());
165
173
  err = uv_udp_init_ex(
166
174
  DepLibUV::GetLoop(), reinterpret_cast<uv_udp_t*>(uvHandle), UV_UDP_RECVMMSG);
175
+
167
176
  break;
177
+ }
168
178
 
169
179
  case Transport::TCP:
180
+ {
170
181
  uvHandle = reinterpret_cast<uv_handle_t*>(new uv_tcp_t());
171
182
  err = uv_tcp_init(DepLibUV::GetLoop(), reinterpret_cast<uv_tcp_t*>(uvHandle));
183
+
172
184
  break;
185
+ }
173
186
  }
174
187
 
175
188
  if (err != 0)
176
189
  {
177
- delete uvHandle;
178
-
179
190
  switch (transport)
180
191
  {
181
192
  case Transport::UDP:
193
+ {
194
+ delete reinterpret_cast<uv_udp_t*>(uvHandle);
195
+
182
196
  MS_THROW_ERROR("uv_udp_init_ex() failed: %s", uv_strerror(err));
197
+
183
198
  break;
199
+ }
184
200
 
185
201
  case Transport::TCP:
202
+ {
203
+ delete reinterpret_cast<uv_tcp_t*>(uvHandle);
204
+
186
205
  MS_THROW_ERROR("uv_tcp_init() failed: %s", uv_strerror(err));
206
+
187
207
  break;
208
+ }
188
209
  }
189
210
  }
190
211
 
@@ -259,7 +280,22 @@ namespace RTC
259
280
  break;
260
281
 
261
282
  // If it failed, close the handle and check the reason.
262
- uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onClose));
283
+ switch (transport)
284
+ {
285
+ case Transport::UDP:
286
+ {
287
+ uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onCloseUdp));
288
+
289
+ break;
290
+ };
291
+
292
+ case Transport::TCP:
293
+ {
294
+ uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onCloseTcp));
295
+
296
+ break;
297
+ }
298
+ }
263
299
 
264
300
  switch (err)
265
301
  {
@@ -400,17 +436,25 @@ namespace RTC
400
436
 
401
437
  if (err != 0)
402
438
  {
403
- delete uvHandle;
404
-
405
439
  switch (transport)
406
440
  {
407
441
  case Transport::UDP:
442
+ {
443
+ delete reinterpret_cast<uv_udp_t*>(uvHandle);
444
+
408
445
  MS_THROW_ERROR("uv_udp_init_ex() failed: %s", uv_strerror(err));
446
+
409
447
  break;
448
+ }
410
449
 
411
450
  case Transport::TCP:
451
+ {
452
+ delete reinterpret_cast<uv_tcp_t*>(uvHandle);
453
+
412
454
  MS_THROW_ERROR("uv_tcp_init() failed: %s", uv_strerror(err));
455
+
413
456
  break;
457
+ }
414
458
  }
415
459
  }
416
460
 
@@ -426,7 +470,7 @@ namespace RTC
426
470
  if (err != 0)
427
471
  {
428
472
  // If it failed, close the handle and check the reason.
429
- uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onClose));
473
+ uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onCloseUdp));
430
474
 
431
475
  MS_THROW_ERROR(
432
476
  "uv_udp_bind() failed [transport:%s, ip:'%s', port:%" PRIu16 "]: %s",
@@ -449,7 +493,7 @@ namespace RTC
449
493
  if (err != 0)
450
494
  {
451
495
  // If it failed, close the handle and check the reason.
452
- uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onClose));
496
+ uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onCloseTcp));
453
497
 
454
498
  MS_THROW_ERROR(
455
499
  "uv_tcp_bind() failed [transport:%s, ip:'%s', port:%" PRIu16 "]: %s",
@@ -469,7 +513,7 @@ namespace RTC
469
513
  if (err != 0)
470
514
  {
471
515
  // If it failed, close the handle and check the reason.
472
- uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onClose));
516
+ uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onCloseTcp));
473
517
 
474
518
  MS_THROW_ERROR(
475
519
  "uv_listen() failed [transport:%s, ip:'%s', port:%" PRIu16 "]: %s",
@@ -36,17 +36,21 @@ namespace RTC
36
36
  // Get the header.
37
37
  auto* header = const_cast<Header*>(reinterpret_cast<const Header*>(data));
38
38
 
39
+ // If item type is 0, there is no need for length field (unless padding
40
+ // is needed).
41
+ if (len > 0 && header->type == SdesItem::Type::END)
42
+ {
43
+ return nullptr;
44
+ }
45
+
39
46
  // data size must be >= header + length value.
40
- if (len < HeaderSize || len < (1u * 2) + header->length)
47
+ if (len < HeaderSize || len < HeaderSize + header->length)
41
48
  {
42
49
  MS_WARN_TAG(rtcp, "not enough space for SDES item, discarded");
43
50
 
44
51
  return nullptr;
45
52
  }
46
53
 
47
- if (header->type == SdesItem::Type::END)
48
- return nullptr;
49
-
50
54
  return new SdesItem(header);
51
55
  }
52
56
 
@@ -57,7 +61,9 @@ namespace RTC
57
61
  auto it = SdesItem::type2String.find(type);
58
62
 
59
63
  if (it == SdesItem::type2String.end())
64
+ {
60
65
  return Unknown;
66
+ }
61
67
 
62
68
  return it->second;
63
69
  }
@@ -123,19 +129,77 @@ namespace RTC
123
129
 
124
130
  std::unique_ptr<SdesChunk> chunk(new SdesChunk(ssrc));
125
131
 
126
- size_t offset = 4u /* ssrc */;
132
+ size_t offset{ 4u }; /* ssrc */
133
+ size_t chunkLength{ 4u };
127
134
 
128
135
  while (len > offset)
129
136
  {
130
- SdesItem* item = SdesItem::Parse(data + offset, len - offset);
137
+ auto* item = SdesItem::Parse(data + offset, len - offset);
131
138
 
132
139
  if (!item)
140
+ {
133
141
  break;
142
+ }
134
143
 
135
144
  chunk->AddItem(item);
145
+ chunkLength += item->GetSize();
136
146
  offset += item->GetSize();
137
147
  }
138
148
 
149
+ // Once all items have been parsed, there must be 1, 2, 3 or 4 null octets
150
+ // (this is mandatory). The first one (AKA item type 0) means "end of
151
+ // items", and the others maybe needed for padding the chunk to 4 bytes.
152
+
153
+ // First ensure that there is at least one null octet.
154
+ if (offset == len || (offset < len && Utils::Byte::Get1Byte(data, offset) != 0u))
155
+ {
156
+ MS_WARN_TAG(rtcp, "invalid SDES chunk (missing mandatory null octet), discarded");
157
+
158
+ return nullptr;
159
+ }
160
+
161
+ // So we have the mandatory null octet.
162
+ ++chunkLength;
163
+ ++offset;
164
+
165
+ // Then check that there are 0, 1, 2 or 3 (no more) null octets that pad
166
+ // the chunk to 4 bytes.
167
+ uint16_t neededAdditionalNullOctets =
168
+ Utils::Byte::PadTo4Bytes(static_cast<uint16_t>(chunkLength)) -
169
+ static_cast<uint16_t>(chunkLength);
170
+ uint16_t foundAdditionalNullOctets{ 0u };
171
+
172
+ for (uint16_t i{ 0u }; len > offset && i < neededAdditionalNullOctets; ++i)
173
+ {
174
+ if (Utils::Byte::Get1Byte(data, offset) != 0u)
175
+ {
176
+ MS_WARN_TAG(
177
+ rtcp,
178
+ "invalid SDES chunk (missing additional null octets [needed:%" PRIu16 ", found:%" PRIu16
179
+ "]), discarded",
180
+ neededAdditionalNullOctets,
181
+ foundAdditionalNullOctets);
182
+
183
+ return nullptr;
184
+ }
185
+
186
+ ++foundAdditionalNullOctets;
187
+ ++chunkLength;
188
+ ++offset;
189
+ }
190
+
191
+ if (foundAdditionalNullOctets != neededAdditionalNullOctets)
192
+ {
193
+ MS_WARN_TAG(
194
+ rtcp,
195
+ "invalid SDES chunk (missing additional null octets [needed:%" PRIu16 ", found:%" PRIu16
196
+ "]), discarded",
197
+ neededAdditionalNullOctets,
198
+ foundAdditionalNullOctets);
199
+
200
+ return nullptr;
201
+ }
202
+
139
203
  return chunk.release();
140
204
  }
141
205
 
@@ -155,10 +219,15 @@ namespace RTC
155
219
  offset += item->Serialize(buffer + offset);
156
220
  }
157
221
 
222
+ // Add the mandatory null octet.
223
+ buffer[offset] = 0;
224
+
225
+ ++offset;
226
+
158
227
  // 32 bits padding.
159
228
  const size_t padding = (-offset) & 3;
160
229
 
161
- for (size_t i{ 0 }; i < padding; ++i)
230
+ for (size_t i{ 0u }; i < padding; ++i)
162
231
  {
163
232
  buffer[offset + i] = 0;
164
233
  }
@@ -195,9 +264,9 @@ namespace RTC
195
264
  size_t offset = Packet::CommonHeaderSize;
196
265
  uint8_t count = header->count;
197
266
 
198
- while ((count-- != 0u) && (len > offset))
267
+ while (count-- && (len > offset))
199
268
  {
200
- SdesChunk* chunk = SdesChunk::Parse(data + offset, len - offset);
269
+ auto* chunk = SdesChunk::Parse(data + offset, len - offset);
201
270
 
202
271
  if (chunk != nullptr)
203
272
  {
@@ -206,10 +275,17 @@ namespace RTC
206
275
  }
207
276
  else
208
277
  {
209
- return packet.release();
278
+ break;
210
279
  }
211
280
  }
212
281
 
282
+ if (packet->GetCount() != header->count)
283
+ {
284
+ MS_WARN_TAG(rtcp, "RTCP count value doesn't match found number of chunks, discarded");
285
+
286
+ return nullptr;
287
+ }
288
+
213
289
  return packet.release();
214
290
  }
215
291
 
@@ -223,7 +299,7 @@ namespace RTC
223
299
  size_t length = 0;
224
300
  uint8_t* header = { nullptr };
225
301
 
226
- for (size_t i = 0; i < this->GetCount(); i++)
302
+ for (size_t i{ 0u }; i < this->GetCount(); ++i)
227
303
  {
228
304
  // Create a new SDES packet header for each 31 chunks.
229
305
  if (i % MaxChunksPerPacket == 0)
@@ -13,9 +13,9 @@ inline static void onSignal(uv_signal_t* handle, int signum)
13
13
  static_cast<SignalsHandler*>(handle->data)->OnUvSignal(signum);
14
14
  }
15
15
 
16
- inline static void onClose(uv_handle_t* handle)
16
+ inline static void onCloseSignal(uv_handle_t* handle)
17
17
  {
18
- delete handle;
18
+ delete reinterpret_cast<uv_signal_t*>(handle);
19
19
  }
20
20
 
21
21
  /* Instance methods. */
@@ -44,7 +44,7 @@ void SignalsHandler::Close()
44
44
 
45
45
  for (auto* uvHandle : this->uvHandles)
46
46
  {
47
- uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onClose));
47
+ uv_close(reinterpret_cast<uv_handle_t*>(uvHandle), static_cast<uv_close_cb>(onCloseSignal));
48
48
  }
49
49
  }
50
50
 
@@ -40,9 +40,16 @@ inline static void onWrite(uv_write_t* req, int status)
40
40
  delete writeData;
41
41
  }
42
42
 
43
- inline static void onClose(uv_handle_t* handle)
43
+ // NOTE: We have different onCloseXxx() callbacks to avoid an ASAN warning by
44
+ // ensuring that we call `delete xxx` with same type as `new xxx` before.
45
+ inline static void onCloseTcp(uv_handle_t* handle)
44
46
  {
45
- delete handle;
47
+ delete reinterpret_cast<uv_tcp_t*>(handle);
48
+ }
49
+
50
+ inline static void onCloseShutdown(uv_handle_t* handle)
51
+ {
52
+ delete reinterpret_cast<uv_shutdown_t*>(handle);
46
53
  }
47
54
 
48
55
  inline static void onShutdown(uv_shutdown_t* req, int /*status*/)
@@ -52,7 +59,7 @@ inline static void onShutdown(uv_shutdown_t* req, int /*status*/)
52
59
  delete req;
53
60
 
54
61
  // Now do close the handle.
55
- uv_close(reinterpret_cast<uv_handle_t*>(handle), static_cast<uv_close_cb>(onClose));
62
+ uv_close(reinterpret_cast<uv_handle_t*>(handle), static_cast<uv_close_cb>(onCloseShutdown));
56
63
  }
57
64
 
58
65
  /* Instance methods. */
@@ -114,7 +121,7 @@ void TcpConnectionHandler::Close()
114
121
  // Otherwise directly close the socket.
115
122
  else
116
123
  {
117
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
124
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseTcp));
118
125
  }
119
126
  }
120
127
 
@@ -20,9 +20,9 @@ inline static void onConnection(uv_stream_t* handle, int status)
20
20
  server->OnUvConnection(status);
21
21
  }
22
22
 
23
- inline static void onClose(uv_handle_t* handle)
23
+ inline static void onCloseTcp(uv_handle_t* handle)
24
24
  {
25
- delete handle;
25
+ delete reinterpret_cast<uv_tcp_t*>(handle);
26
26
  }
27
27
 
28
28
  /* Instance methods. */
@@ -43,7 +43,7 @@ TcpServerHandler::TcpServerHandler(uv_tcp_t* uvHandle) : uvHandle(uvHandle)
43
43
 
44
44
  if (err != 0)
45
45
  {
46
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
46
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseTcp));
47
47
 
48
48
  MS_THROW_ERROR("uv_listen() failed: %s", uv_strerror(err));
49
49
  }
@@ -51,7 +51,7 @@ TcpServerHandler::TcpServerHandler(uv_tcp_t* uvHandle) : uvHandle(uvHandle)
51
51
  // Set local address.
52
52
  if (!SetLocalAddress())
53
53
  {
54
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
54
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseTcp));
55
55
 
56
56
  MS_THROW_ERROR("error setting local IP and port");
57
57
  }
@@ -84,7 +84,7 @@ void TcpServerHandler::Close()
84
84
  delete connection;
85
85
  }
86
86
 
87
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
87
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseTcp));
88
88
  }
89
89
 
90
90
  void TcpServerHandler::Dump() const
@@ -13,9 +13,9 @@ inline static void onTimer(uv_timer_t* handle)
13
13
  static_cast<Timer*>(handle->data)->OnUvTimer();
14
14
  }
15
15
 
16
- inline static void onClose(uv_handle_t* handle)
16
+ inline static void onCloseTimer(uv_handle_t* handle)
17
17
  {
18
- delete handle;
18
+ delete reinterpret_cast<uv_timer_t*>(handle);
19
19
  }
20
20
 
21
21
  /* Instance methods. */
@@ -59,7 +59,7 @@ void Timer::Close()
59
59
 
60
60
  this->closed = true;
61
61
 
62
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
62
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseTimer));
63
63
  }
64
64
 
65
65
  void Timer::Start(uint64_t timeout, uint64_t repeat)
@@ -45,9 +45,9 @@ inline static void onSend(uv_udp_send_t* req, int status)
45
45
  delete sendData;
46
46
  }
47
47
 
48
- inline static void onClose(uv_handle_t* handle)
48
+ inline static void onCloseUdp(uv_handle_t* handle)
49
49
  {
50
- delete handle;
50
+ delete reinterpret_cast<uv_udp_t*>(handle);
51
51
  }
52
52
 
53
53
  /* Instance methods. */
@@ -66,7 +66,7 @@ UdpSocketHandler::UdpSocketHandler(uv_udp_t* uvHandle) : uvHandle(uvHandle)
66
66
 
67
67
  if (err != 0)
68
68
  {
69
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
69
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseUdp));
70
70
 
71
71
  MS_THROW_ERROR("uv_udp_recv_start() failed: %s", uv_strerror(err));
72
72
  }
@@ -74,7 +74,7 @@ UdpSocketHandler::UdpSocketHandler(uv_udp_t* uvHandle) : uvHandle(uvHandle)
74
74
  // Set local address.
75
75
  if (!SetLocalAddress())
76
76
  {
77
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
77
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseUdp));
78
78
 
79
79
  MS_THROW_ERROR("error setting local IP and port");
80
80
  }
@@ -106,7 +106,7 @@ void UdpSocketHandler::Close()
106
106
  if (err != 0)
107
107
  MS_ABORT("uv_udp_recv_stop() failed: %s", uv_strerror(err));
108
108
 
109
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
109
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseUdp));
110
110
  }
111
111
 
112
112
  void UdpSocketHandler::Dump() const
@@ -44,9 +44,16 @@ inline static void onWrite(uv_write_t* req, int status)
44
44
  delete writeData;
45
45
  }
46
46
 
47
- inline static void onClose(uv_handle_t* handle)
47
+ // NOTE: We have different onCloseXxx() callbacks to avoid an ASAN warning by
48
+ // ensuring that we call `delete xxx` with same type as `new xxx` before.
49
+ inline static void onClosePipe(uv_handle_t* handle)
48
50
  {
49
- delete handle;
51
+ delete reinterpret_cast<uv_pipe_t*>(handle);
52
+ }
53
+
54
+ inline static void onCloseShutdown(uv_handle_t* handle)
55
+ {
56
+ delete reinterpret_cast<uv_shutdown_t*>(handle);
50
57
  }
51
58
 
52
59
  inline static void onShutdown(uv_shutdown_t* req, int /*status*/)
@@ -56,7 +63,7 @@ inline static void onShutdown(uv_shutdown_t* req, int /*status*/)
56
63
  delete req;
57
64
 
58
65
  // Now do close the handle.
59
- uv_close(reinterpret_cast<uv_handle_t*>(handle), static_cast<uv_close_cb>(onClose));
66
+ uv_close(reinterpret_cast<uv_handle_t*>(handle), static_cast<uv_close_cb>(onCloseShutdown));
60
67
  }
61
68
 
62
69
  /* Instance methods. */
@@ -85,7 +92,7 @@ UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, UnixStreamSocket::
85
92
 
86
93
  if (err != 0)
87
94
  {
88
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
95
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClosePipe));
89
96
 
90
97
  MS_THROW_ERROR_STD("uv_pipe_open() failed: %s", uv_strerror(err));
91
98
  }
@@ -100,7 +107,7 @@ UnixStreamSocket::UnixStreamSocket(int fd, size_t bufferSize, UnixStreamSocket::
100
107
 
101
108
  if (err != 0)
102
109
  {
103
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
110
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClosePipe));
104
111
 
105
112
  MS_THROW_ERROR_STD("uv_read_start() failed: %s", uv_strerror(err));
106
113
  }
@@ -157,7 +164,7 @@ void UnixStreamSocket::Close()
157
164
  // Otherwise directly close the socket.
158
165
  else
159
166
  {
160
- uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClose));
167
+ uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onClosePipe));
161
168
  }
162
169
  }
163
170
 
@@ -11,68 +11,378 @@ namespace TestSdes
11
11
  // RTCP Sdes Packet.
12
12
 
13
13
  // clang-format off
14
- uint8_t buffer[] =
14
+ uint8_t buffer1[] =
15
15
  {
16
16
  0x81, 0xca, 0x00, 0x06, // Type: 202 (SDES), Count: 1, Length: 6
17
17
  0x9f, 0x65, 0xe7, 0x42, // SSRC: 0x9f65e742
18
+ // Chunk 1
18
19
  0x01, 0x10, 0x74, 0x37, // Item Type: 1 (CNAME), Length: 16, Value: t7mkYnCm46OcINy/
19
20
  0x6d, 0x6b, 0x59, 0x6e,
20
21
  0x43, 0x6d, 0x34, 0x36,
21
22
  0x4f, 0x63, 0x49, 0x4e,
22
- 0x79, 0x2f, 0x00, 0x00
23
+ 0x79, 0x2f, 0x00, 0x00 // 2 null octets
23
24
  };
24
25
  // clang-format on
25
26
 
26
- uint8_t* chunkBuffer = buffer + Packet::CommonHeaderSize;
27
+ // First chunk (chunk 1).
28
+ uint32_t ssrc1{ 0x9f65e742 };
29
+ // First item (item 1).
30
+ SdesItem::Type item1Type{ SdesItem::Type::CNAME };
31
+ std::string item1Value{ "t7mkYnCm46OcINy/" };
32
+ size_t item1Length{ 16u };
27
33
 
28
- // SDES values.
29
- uint32_t ssrc{ 0x9f65e742 };
30
- SdesItem::Type type{ SdesItem::Type::CNAME };
31
- std::string value{ "t7mkYnCm46OcINy/" };
32
- size_t length = 16;
33
-
34
- void verify(SdesChunk* chunk)
34
+ // clang-format off
35
+ uint8_t buffer2[] =
35
36
  {
36
- REQUIRE(chunk->GetSsrc() == ssrc);
37
+ 0xa2, 0xca, 0x00, 0x0d, // Padding, Type: 202 (SDES), Count: 2, Length: 13
38
+ // Chunk 2
39
+ 0x00, 0x00, 0x04, 0xd2, // SSRC: 1234
40
+ 0x01, 0x06, 0x71, 0x77, // Item Type: 1 (CNAME), Length: 6, Text: "qwerty"
41
+ 0x65, 0x72, 0x74, 0x79,
42
+ 0x06, 0x06, 0x69, 0xc3, // Item Type: 6 (TOOL), Length: 6, Text: "iñaki"
43
+ 0xb1, 0x61, 0x6b, 0x69,
44
+ 0x00, 0x00, 0x00, 0x00, // 4 null octets
45
+ // Chunk 3
46
+ 0x00, 0x00, 0x16, 0x2e, // SSRC: 5678
47
+ 0x05, 0x11, 0x73, 0x6f, // Item Type: 5 (LOC), Length: 17, Text: "somewhere œæ€"
48
+ 0x6d, 0x65, 0x77, 0x68,
49
+ 0x65, 0x72, 0x65, 0x20,
50
+ 0xc5, 0x93, 0xc3, 0xa6,
51
+ 0xe2, 0x82, 0xac, 0x00, // 1 null octet
52
+ 0x00, 0x00, 0x00, 0x00 // Pading (4 bytes)
53
+ };
54
+ // clang-format on
37
55
 
38
- SdesItem* item = *(chunk->Begin());
56
+ // First chunk (chunk 2).
57
+ uint32_t ssrc2{ 1234 };
58
+ // First item (item 2).
59
+ SdesItem::Type item2Type{ SdesItem::Type::CNAME };
60
+ std::string item2Value{ "qwerty" };
61
+ size_t item2Length{ 6u };
62
+ // First item (item 3).
63
+ SdesItem::Type item3Type{ SdesItem::Type::TOOL };
64
+ std::string item3Value{ "iñaki" };
65
+ size_t item3Length{ 6u };
66
+
67
+ // Second chunk (chunk 3).
68
+ uint32_t ssrc3{ 5678 };
69
+ // First item (item 4).
70
+ SdesItem::Type item4Type{ SdesItem::Type::LOC };
71
+ std::string item4Value{ "somewhere œæ€" };
72
+ size_t item4Length{ 17u };
39
73
 
40
- REQUIRE(item->GetType() == type);
41
- REQUIRE(item->GetLength() == length);
42
- REQUIRE(std::string(item->GetValue(), length) == value);
43
- }
74
+ // clang-format off
75
+ uint8_t buffer3[] =
76
+ {
77
+ 0x81, 0xca, 0x00, 0x03, // Type: 202 (SDES), Count: 1, Length: 3
78
+ // Chunk
79
+ 0x11, 0x22, 0x33, 0x44, // SSRC: 0x11223344
80
+ 0x05, 0x02, 0x61, 0x62, // Item Type: 5 (LOC), Length: 2, Text: "ab"
81
+ 0x00, 0x00, 0x00, 0x00 // 4 null octets
82
+ };
83
+ // clang-format on
84
+
85
+ // First chunk (chunk 4).
86
+ uint32_t ssrc4{ 0x11223344 };
87
+ // First item (item 5).
88
+ SdesItem::Type item5Type{ SdesItem::Type::LOC };
89
+ std::string item5Value{ "ab" };
90
+ size_t item5Length{ 2u };
44
91
  } // namespace TestSdes
45
92
 
46
93
  using namespace TestSdes;
47
94
 
48
95
  SCENARIO("RTCP SDES parsing", "[parser][rtcp][sdes]")
49
96
  {
50
- SECTION("parse packet")
97
+ SECTION("parse packet 1")
51
98
  {
52
- SdesPacket* packet = SdesPacket::Parse(buffer, sizeof(buffer));
53
- SdesChunk* chunk = *(packet->Begin());
54
-
55
- auto* header = reinterpret_cast<RTC::RTCP::Packet::CommonHeader*>(buffer);
99
+ SdesPacket* packet = SdesPacket::Parse(buffer1, sizeof(buffer1));
100
+ auto* header = reinterpret_cast<RTC::RTCP::Packet::CommonHeader*>(buffer1);
56
101
 
102
+ REQUIRE(packet);
57
103
  REQUIRE(ntohs(header->length) == 6);
58
- REQUIRE(chunk);
104
+ REQUIRE(packet->GetSize() == 28);
105
+ REQUIRE(packet->GetCount() == 1);
106
+
107
+ size_t chunkIdx{ 0u };
108
+
109
+ for (auto it = packet->Begin(); it != packet->End(); ++it, ++chunkIdx)
110
+ {
111
+ auto* chunk = *it;
112
+
113
+ switch (chunkIdx)
114
+ {
115
+ /* First chunk (chunk 1). */
116
+ case 0:
117
+ {
118
+ // Chunk size must be 24 bytes (including 4 null octets).
119
+ REQUIRE(chunk->GetSize() == 24);
120
+ REQUIRE(chunk->GetSsrc() == ssrc1);
121
+
122
+ size_t itemIdx{ 0u };
123
+
124
+ for (auto it2 = chunk->Begin(); it2 != chunk->End(); ++it2, ++itemIdx)
125
+ {
126
+ auto* item = *it2;
127
+
128
+ switch (itemIdx)
129
+ {
130
+ /* First item (item 1). */
131
+ case 0:
132
+ {
133
+ REQUIRE(item->GetType() == item1Type);
134
+ REQUIRE(item->GetLength() == item1Length);
135
+ REQUIRE(std::string(item->GetValue(), item1Length) == item1Value);
136
+
137
+ break;
138
+ }
139
+ }
140
+ }
141
+
142
+ // There is 1 item.
143
+ REQUIRE(itemIdx == 1);
144
+
145
+ break;
146
+ }
147
+ }
148
+ }
59
149
 
60
- verify(chunk);
150
+ // There is 1 chunk.
151
+ REQUIRE(chunkIdx == 1);
61
152
 
62
153
  SECTION("serialize SdesChunk instance")
63
154
  {
64
- uint8_t serialized[sizeof(buffer) - Packet::CommonHeaderSize] = { 0 };
155
+ auto it = packet->Begin();
156
+ auto* chunk1 = *it;
157
+ uint8_t* chunk1Buffer = buffer1 + Packet::CommonHeaderSize;
65
158
 
66
- chunk->Serialize(serialized);
159
+ // NOTE: Length of first chunk (including null octets) is 24.
160
+ uint8_t serialized1[24] = { 0 };
67
161
 
68
- SECTION("compare serialized SdesChunk with original buffer")
162
+ chunk1->Serialize(serialized1);
163
+
164
+ REQUIRE(std::memcmp(chunk1Buffer, serialized1, 24) == 0);
165
+ }
166
+
167
+ delete packet;
168
+ }
169
+
170
+ SECTION("parse packet 2")
171
+ {
172
+ SdesPacket* packet = SdesPacket::Parse(buffer2, sizeof(buffer2));
173
+ auto* header = reinterpret_cast<RTC::RTCP::Packet::CommonHeader*>(buffer2);
174
+
175
+ REQUIRE(packet);
176
+ REQUIRE(ntohs(header->length) == 13);
177
+ // Despite total buffer size is 56 bytes, our GetSize() method doesn't not
178
+ // consider RTCP padding (4 bytes in this case).
179
+ REQUIRE(packet->GetSize() == 52);
180
+ REQUIRE(packet->GetCount() == 2);
181
+
182
+ size_t chunkIdx{ 0u };
183
+
184
+ for (auto it = packet->Begin(); it != packet->End(); ++it, ++chunkIdx)
185
+ {
186
+ auto* chunk = *it;
187
+
188
+ switch (chunkIdx)
69
189
  {
70
- REQUIRE(std::memcmp(chunkBuffer, serialized, sizeof(buffer) - Packet::CommonHeaderSize) == 0);
190
+ /* First chunk (chunk 2). */
191
+ case 0:
192
+ {
193
+ // Chunk size must be 24 bytes (including 4 null octets).
194
+ REQUIRE(chunk->GetSize() == 24);
195
+ REQUIRE(chunk->GetSsrc() == ssrc2);
196
+
197
+ size_t itemIdx{ 0u };
198
+
199
+ for (auto it2 = chunk->Begin(); it2 != chunk->End(); ++it2, ++itemIdx)
200
+ {
201
+ auto* item = *it2;
202
+
203
+ switch (itemIdx)
204
+ {
205
+ /* First item (item 2). */
206
+ case 0:
207
+ {
208
+ REQUIRE(item->GetType() == item2Type);
209
+ REQUIRE(item->GetLength() == item2Length);
210
+ REQUIRE(std::string(item->GetValue(), item2Length) == item2Value);
211
+
212
+ break;
213
+ }
214
+
215
+ /* Second item (item 3). */
216
+ case 1:
217
+ {
218
+ REQUIRE(item->GetType() == item3Type);
219
+ REQUIRE(item->GetLength() == item3Length);
220
+ REQUIRE(std::string(item->GetValue(), item3Length) == item3Value);
221
+
222
+ break;
223
+ }
224
+ }
225
+ }
226
+
227
+ // There are 2 items.
228
+ REQUIRE(itemIdx == 2);
229
+
230
+ break;
231
+ }
232
+
233
+ /* Second chunk (chunk 3). */
234
+ case 1:
235
+ {
236
+ // Chunk size must be 24 bytes (including 1 null octet).
237
+ REQUIRE(chunk->GetSize() == 24);
238
+ REQUIRE(chunk->GetSsrc() == ssrc3);
239
+
240
+ size_t itemIdx{ 0u };
241
+
242
+ for (auto it2 = chunk->Begin(); it2 != chunk->End(); ++it2, ++itemIdx)
243
+ {
244
+ auto* item = *it2;
245
+
246
+ switch (itemIdx)
247
+ {
248
+ /* First item (item 4). */
249
+ case 0:
250
+ {
251
+ REQUIRE(item->GetType() == item4Type);
252
+ REQUIRE(item->GetLength() == item4Length);
253
+ REQUIRE(std::string(item->GetValue(), item4Length) == item4Value);
254
+
255
+ break;
256
+ }
257
+ }
258
+ }
259
+
260
+ // There is 1 item.
261
+ REQUIRE(itemIdx == 1);
262
+
263
+ break;
264
+ }
71
265
  }
72
266
  }
267
+
268
+ // There are 2 chunks.
269
+ REQUIRE(chunkIdx == 2);
270
+
271
+ SECTION("serialize SdesChunk instances")
272
+ {
273
+ auto it = packet->Begin();
274
+ auto* chunk1 = *it;
275
+ uint8_t* chunk1Buffer = buffer2 + Packet::CommonHeaderSize;
276
+
277
+ // NOTE: Length of first chunk (including null octets) is 24.
278
+ uint8_t serialized1[24] = { 0 };
279
+
280
+ chunk1->Serialize(serialized1);
281
+
282
+ REQUIRE(std::memcmp(chunk1Buffer, serialized1, 24) == 0);
283
+
284
+ auto* chunk2 = *(++it);
285
+ uint8_t* chunk2Buffer = buffer2 + Packet::CommonHeaderSize + 24;
286
+
287
+ // NOTE: Length of second chunk (including null octets) is 24.
288
+ uint8_t serialized2[24] = { 0 };
289
+
290
+ chunk2->Serialize(serialized2);
291
+
292
+ REQUIRE(std::memcmp(chunk2Buffer, serialized2, 24) == 0);
293
+ }
294
+
295
+ delete packet;
296
+ }
297
+
298
+ SECTION("parse packet 3")
299
+ {
300
+ SdesPacket* packet = SdesPacket::Parse(buffer3, sizeof(buffer3));
301
+ auto* header = reinterpret_cast<RTC::RTCP::Packet::CommonHeader*>(buffer3);
302
+
303
+ REQUIRE(packet);
304
+ REQUIRE(ntohs(header->length) == 3);
305
+ REQUIRE(packet->GetSize() == 16);
306
+ REQUIRE(packet->GetCount() == 1);
307
+
308
+ size_t chunkIdx{ 0u };
309
+
310
+ for (auto it = packet->Begin(); it != packet->End(); ++it, ++chunkIdx)
311
+ {
312
+ auto* chunk = *it;
313
+
314
+ switch (chunkIdx)
315
+ {
316
+ /* First chunk (chunk 4). */
317
+ case 0:
318
+ {
319
+ REQUIRE(chunk->GetSize() == 12);
320
+ REQUIRE(chunk->GetSsrc() == ssrc4);
321
+
322
+ size_t itemIdx{ 0u };
323
+
324
+ for (auto it2 = chunk->Begin(); it2 != chunk->End(); ++it2, ++itemIdx)
325
+ {
326
+ auto* item = *it2;
327
+
328
+ switch (itemIdx)
329
+ {
330
+ /* First item (item 5). */
331
+ case 0:
332
+ {
333
+ REQUIRE(item->GetType() == item5Type);
334
+ REQUIRE(item->GetLength() == item5Length);
335
+ REQUIRE(std::string(item->GetValue(), item5Length) == item5Value);
336
+
337
+ break;
338
+ }
339
+ }
340
+ }
341
+
342
+ // There is 1 item.
343
+ REQUIRE(itemIdx == 1);
344
+
345
+ break;
346
+ }
347
+ }
348
+ }
349
+
350
+ // There is 1 chunk.
351
+ REQUIRE(chunkIdx == 1);
352
+
353
+ SECTION("serialize SdesChunk instance")
354
+ {
355
+ auto it = packet->Begin();
356
+ auto* chunk1 = *it;
357
+ uint8_t* chunk1Buffer = buffer3 + Packet::CommonHeaderSize;
358
+
359
+ // NOTE: Length of first chunk (including null octets) is 12.
360
+ uint8_t serialized1[12] = { 0 };
361
+
362
+ chunk1->Serialize(serialized1);
363
+
364
+ REQUIRE(std::memcmp(chunk1Buffer, serialized1, 12) == 0);
365
+ }
366
+
73
367
  delete packet;
74
368
  }
75
369
 
370
+ SECTION("parsing a packet with missing null octects fails")
371
+ {
372
+ // clang-format off
373
+ uint8_t buffer[] =
374
+ {
375
+ 0x81, 0xca, 0x00, 0x02, // Type: 202 (SDES), Count: 1, Length: 2
376
+ // Chunk
377
+ 0x11, 0x22, 0x33, 0x44, // SSRC: 0x11223344
378
+ 0x08, 0x02, 0x61, 0x62 // Item Type: 8 (PRIV), Length: 2, Text: "ab"
379
+ };
380
+
381
+ SdesPacket* packet = SdesPacket::Parse(buffer, sizeof(buffer));
382
+
383
+ REQUIRE(!packet);
384
+ }
385
+
76
386
  SECTION("create SDES packet with more than 31 chunks")
77
387
  {
78
388
  const size_t count = 33;
@@ -82,23 +392,24 @@ SCENARIO("RTCP SDES parsing", "[parser][rtcp][sdes]")
82
392
  for (auto i = 1; i <= count; i++)
83
393
  {
84
394
  // Create chunk and add to packet.
85
- SdesChunk* chunk = new SdesChunk(i /*ssrc*/);
395
+ SdesChunk* chunk1 = new SdesChunk(i /*ssrc*/);
86
396
 
87
- auto* item = new RTC::RTCP::SdesItem(SdesItem::Type::CNAME, value.size(), value.c_str());
397
+ auto* item1 =
398
+ new RTC::RTCP::SdesItem(SdesItem::Type::CNAME, item1Value.size(), item1Value.c_str());
88
399
 
89
- chunk->AddItem(item);
400
+ chunk1->AddItem(item1);
90
401
 
91
- packet.AddChunk(chunk);
402
+ packet.AddChunk(chunk1);
92
403
  }
93
404
 
94
405
  REQUIRE(packet.GetCount() == count);
95
406
 
96
- uint8_t buffer[1500] = { 0 };
407
+ uint8_t buffer1[1500] = { 0 };
97
408
 
98
409
  // Serialization must contain 2 RR packets since report count exceeds 31.
99
- packet.Serialize(buffer);
410
+ packet.Serialize(buffer1);
100
411
 
101
- auto* packet2 = static_cast<SdesPacket*>(Packet::Parse(buffer, sizeof(buffer)));
412
+ auto* packet2 = static_cast<SdesPacket*>(Packet::Parse(buffer1, sizeof(buffer1)));
102
413
 
103
414
  REQUIRE(packet2 != nullptr);
104
415
  REQUIRE(packet2->GetCount() == 31);
@@ -114,8 +425,8 @@ SCENARIO("RTCP SDES parsing", "[parser][rtcp][sdes]")
114
425
  auto* item = *(chunk->Begin());
115
426
 
116
427
  REQUIRE(item->GetType() == SdesItem::Type::CNAME);
117
- REQUIRE(item->GetSize() == 2 + value.size());
118
- REQUIRE(std::string(item->GetValue()) == value);
428
+ REQUIRE(item->GetSize() == 2 + item1Value.size());
429
+ REQUIRE(std::string(item->GetValue()) == item1Value);
119
430
  }
120
431
 
121
432
  SdesPacket* packet3 = static_cast<SdesPacket*>(packet2->GetNext());
@@ -134,8 +445,8 @@ SCENARIO("RTCP SDES parsing", "[parser][rtcp][sdes]")
134
445
  auto* item = *(chunk->Begin());
135
446
 
136
447
  REQUIRE(item->GetType() == SdesItem::Type::CNAME);
137
- REQUIRE(item->GetSize() == 2 + value.size());
138
- REQUIRE(std::string(item->GetValue()) == value);
448
+ REQUIRE(item->GetSize() == 2 + item1Value.size());
449
+ REQUIRE(std::string(item->GetValue()) == item1Value);
139
450
  }
140
451
 
141
452
  delete packet2;
@@ -144,13 +455,19 @@ SCENARIO("RTCP SDES parsing", "[parser][rtcp][sdes]")
144
455
 
145
456
  SECTION("create SdesChunk")
146
457
  {
147
- auto* item = new SdesItem(type, length, value.c_str());
458
+ auto* item = new SdesItem(item1Type, item1Length, item1Value.c_str());
148
459
 
149
460
  // Create sdes chunk.
150
- SdesChunk chunk(ssrc);
461
+ SdesChunk chunk(ssrc1);
151
462
 
152
463
  chunk.AddItem(item);
153
464
 
154
- verify(&chunk);
465
+ REQUIRE(chunk.GetSsrc() == ssrc1);
466
+
467
+ SdesItem* item1 = *(chunk.Begin());
468
+
469
+ REQUIRE(item1->GetType() == item1Type);
470
+ REQUIRE(item1->GetLength() == item1Length);
471
+ REQUIRE(std::string(item1->GetValue(), item1Length) == item1Value);
155
472
  }
156
473
  }
@@ -40,6 +40,10 @@ int main(int argc, char* argv[])
40
40
  {
41
41
  Settings::configuration.logTags.rtp = true;
42
42
  }
43
+ if (std::getenv("MS_TEST_LOG_TAG_RTCP"))
44
+ {
45
+ Settings::configuration.logTags.rtcp = true;
46
+ }
43
47
 
44
48
  // Initialize static stuff.
45
49
  DepLibUV::ClassInit();