mediasoup 3.13.20 → 3.13.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasoup",
3
- "version": "3.13.20",
3
+ "version": "3.13.22",
4
4
  "description": "Cutting Edge WebRTC Video Conferencing",
5
5
  "contributors": [
6
6
  "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
@@ -152,8 +152,6 @@ namespace RTC
152
152
  return this->localRole;
153
153
  }
154
154
  void SendApplicationData(const uint8_t* data, size_t len);
155
- // This method must be public since it's called within an OpenSSL callback.
156
- void SendDtlsData(const uint8_t* data, size_t len);
157
155
 
158
156
  private:
159
157
  bool IsRunning() const
@@ -175,6 +173,7 @@ namespace RTC
175
173
  }
176
174
  void Reset();
177
175
  bool CheckStatus(int returnCode);
176
+ void SendPendingOutgoingDtlsData();
178
177
  bool SetTimeout();
179
178
  bool ProcessHandshake();
180
179
  bool CheckRemoteFingerprint();
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+
3
+ WORKER_PWD=${PWD}
4
+ DURATION_SEC=$1
5
+
6
+ current_dir_name=${WORKER_PWD##*/}
7
+ if [ "${current_dir_name}" != "worker" ] ; then
8
+ echo "run-fuzzer.sh [ERROR] $(basename $0) must be called from mediasoup/worker directory" >&2
9
+ exit 1
10
+ fi
11
+
12
+ if [ "$#" -eq 0 ] ; then
13
+ echo "run-fuzzer.sh [ERROR] duration (in seconds) must be fiven as argument" >&2
14
+ exit 1
15
+ fi
16
+
17
+ invoke fuzzer-run-all &
18
+
19
+ MEDIASOUP_WORKER_FUZZER_PID=$!
20
+
21
+ i=${DURATION_SEC}
22
+
23
+ until [ ${i} -eq 0 ]
24
+ do
25
+ echo "run-fuzzer.sh [INFO] ${i} seconds left"
26
+ if ! kill -0 ${MEDIASOUP_WORKER_FUZZER_PID} &> /dev/null ; then
27
+ echo "run-fuzzer.sh [ERROR] mediasoup-worker-fuzzer died" >&2
28
+ exit 1
29
+ else
30
+ ((i=i-1))
31
+ sleep 1
32
+ fi
33
+ done
34
+
35
+ echo "run-fuzzer.sh [INFO] mediasoup-worker-fuzzer is still running after given ${DURATION_SEC} seconds so no fuzzer issues so far"
36
+
37
+ kill -SIGTERM ${MEDIASOUP_WORKER_FUZZER_PID} &> /dev/null
38
+ exit 0
@@ -61,30 +61,6 @@ inline static unsigned int onSslDtlsTimer(SSL* /*ssl*/, unsigned int timerUs)
61
61
  }
62
62
  }
63
63
 
64
- inline static long onSslBioOut(
65
- BIO* bio,
66
- int operationType,
67
- const char* argp,
68
- size_t len,
69
- int /*argi*/,
70
- long /*argl*/,
71
- int ret,
72
- size_t* /*processed*/)
73
- {
74
- const long resultOfcallback = (operationType == BIO_CB_RETURN) ? static_cast<long>(ret) : 1;
75
-
76
- if (operationType == BIO_CB_WRITE && argp && len > 0)
77
- {
78
- MS_DEBUG_DEV("%zu bytes of DTLS data ready to be sent", len);
79
-
80
- auto* dtlsTransport = reinterpret_cast<RTC::DtlsTransport*>(BIO_get_callback_arg(bio));
81
-
82
- dtlsTransport->SendDtlsData(reinterpret_cast<const uint8_t*>(argp), len);
83
- }
84
-
85
- return resultOfcallback;
86
- }
87
-
88
64
  namespace RTC
89
65
  {
90
66
  /* Static. */
@@ -730,11 +706,12 @@ namespace RTC
730
706
  goto error;
731
707
  }
732
708
 
733
- BIO_set_callback_ex(this->sslBioToNetwork, onSslBioOut);
734
- BIO_set_callback_arg(this->sslBioToNetwork, reinterpret_cast<char*>(this));
735
709
  SSL_set_bio(this->ssl, this->sslBioFromNetwork, this->sslBioToNetwork);
736
710
 
737
- // Set the MTU so that we don't send packets that are too large with no fragmentation.
711
+ // Set the MTU so that we don't send packets that are too large with no
712
+ // fragmentation.
713
+ // TODO: This is not honored, see issue:
714
+ // https://github.com/versatica/mediasoup/issues/1100
738
715
  SSL_set_mtu(this->ssl, DtlsMtu);
739
716
  DTLS_set_link_mtu(this->ssl, DtlsMtu);
740
717
 
@@ -778,6 +755,7 @@ namespace RTC
778
755
  {
779
756
  // Send close alert to the peer.
780
757
  SSL_shutdown(this->ssl);
758
+ SendPendingOutgoingDtlsData();
781
759
  }
782
760
 
783
761
  if (this->ssl)
@@ -900,6 +878,7 @@ namespace RTC
900
878
 
901
879
  SSL_set_connect_state(this->ssl);
902
880
  SSL_do_handshake(this->ssl);
881
+ SendPendingOutgoingDtlsData();
903
882
  SetTimeout();
904
883
 
905
884
  break;
@@ -970,6 +949,9 @@ namespace RTC
970
949
  // Must call SSL_read() to process received DTLS data.
971
950
  read = SSL_read(this->ssl, static_cast<void*>(DtlsTransport::sslReadBuffer), SslReadBufferSize);
972
951
 
952
+ // Send data if it's ready.
953
+ SendPendingOutgoingDtlsData();
954
+
973
955
  // Check SSL status and return if it is bad/closed.
974
956
  if (!CheckStatus(read))
975
957
  {
@@ -985,7 +967,8 @@ namespace RTC
985
967
  // Application data received. Notify to the listener.
986
968
  if (read > 0)
987
969
  {
988
- // It is allowed to receive DTLS data even before validating remote fingerprint.
970
+ // It is allowed to receive DTLS data even before validating remote
971
+ // fingerprint.
989
972
  if (!this->handshakeDone)
990
973
  {
991
974
  MS_WARN_TAG(dtls, "ignoring application data received while DTLS handshake not done");
@@ -1003,7 +986,8 @@ namespace RTC
1003
986
  {
1004
987
  MS_TRACE();
1005
988
 
1006
- // We cannot send data to the peer if its remote fingerprint is not validated.
989
+ // We cannot send data to the peer if its remote fingerprint is not
990
+ // validated.
1007
991
  if (this->state != DtlsState::CONNECTED)
1008
992
  {
1009
993
  MS_WARN_TAG(dtls, "cannot send application data while DTLS is not fully connected");
@@ -1036,14 +1020,9 @@ namespace RTC
1036
1020
  MS_WARN_TAG(
1037
1021
  dtls, "OpenSSL SSL_write() wrote less (%d bytes) than given data (%zu bytes)", written, len);
1038
1022
  }
1039
- }
1040
-
1041
- void DtlsTransport::SendDtlsData(const uint8_t* data, size_t len)
1042
- {
1043
- MS_TRACE();
1044
1023
 
1045
- // Notify the listener.
1046
- this->listener->OnDtlsTransportSendData(this, data, len);
1024
+ // Send data.
1025
+ SendPendingOutgoingDtlsData();
1047
1026
  }
1048
1027
 
1049
1028
  void DtlsTransport::Reset()
@@ -1062,8 +1041,9 @@ namespace RTC
1062
1041
  // Stop the DTLS timer.
1063
1042
  this->timer->Stop();
1064
1043
 
1065
- // NOTE: We need to reset the SSL instance so we need to "shutdown" it, but we
1066
- // don't want to send a Close Alert to the peer. However this is gonna happen.
1044
+ // NOTE: We need to reset the SSL instance so we need to "shutdown" it, but
1045
+ // we don't want to send a Close Alert to the peer, so just don't call
1046
+ // SendPendingOutgoingDTLSData().
1067
1047
  SSL_shutdown(this->ssl);
1068
1048
 
1069
1049
  this->localRole.reset();
@@ -1083,7 +1063,7 @@ namespace RTC
1083
1063
  }
1084
1064
  }
1085
1065
 
1086
- inline bool DtlsTransport::CheckStatus(int returnCode)
1066
+ bool DtlsTransport::CheckStatus(int returnCode)
1087
1067
  {
1088
1068
  MS_TRACE();
1089
1069
 
@@ -1200,7 +1180,37 @@ namespace RTC
1200
1180
  }
1201
1181
  }
1202
1182
 
1203
- inline bool DtlsTransport::SetTimeout()
1183
+ void DtlsTransport::SendPendingOutgoingDtlsData()
1184
+ {
1185
+ MS_TRACE();
1186
+
1187
+ if (BIO_eof(this->sslBioToNetwork))
1188
+ {
1189
+ return;
1190
+ }
1191
+
1192
+ int64_t read;
1193
+ char* data{ nullptr };
1194
+
1195
+ read = BIO_get_mem_data(this->sslBioToNetwork, &data); // NOLINT
1196
+
1197
+ if (read <= 0)
1198
+ {
1199
+ return;
1200
+ }
1201
+
1202
+ MS_DEBUG_DEV("%" PRIu64 " bytes of DTLS data ready to sent to the peer", read);
1203
+
1204
+ // Notify the listener.
1205
+ this->listener->OnDtlsTransportSendData(
1206
+ this, reinterpret_cast<uint8_t*>(data), static_cast<size_t>(read));
1207
+
1208
+ // Clear the BIO buffer.
1209
+ // NOTE: the (void) avoids the -Wunused-value warning.
1210
+ (void)BIO_reset(this->sslBioToNetwork);
1211
+ }
1212
+
1213
+ bool DtlsTransport::SetTimeout()
1204
1214
  {
1205
1215
  MS_TRACE();
1206
1216
 
@@ -1235,7 +1245,8 @@ namespace RTC
1235
1245
 
1236
1246
  return true;
1237
1247
  }
1238
- // NOTE: Don't start the timer again if the timeout is greater than 30 seconds.
1248
+ // NOTE: Don't start the timer again if the timeout is greater than 30
1249
+ // seconds.
1239
1250
  else
1240
1251
  {
1241
1252
  MS_WARN_TAG(dtls, "DTLS timeout too high (%" PRIu64 "ms), resetting DLTS", timeoutMs);
@@ -1250,7 +1261,7 @@ namespace RTC
1250
1261
  }
1251
1262
  }
1252
1263
 
1253
- inline bool DtlsTransport::ProcessHandshake()
1264
+ bool DtlsTransport::ProcessHandshake()
1254
1265
  {
1255
1266
  MS_TRACE();
1256
1267
 
@@ -1292,7 +1303,7 @@ namespace RTC
1292
1303
  return false;
1293
1304
  }
1294
1305
 
1295
- inline bool DtlsTransport::CheckRemoteFingerprint()
1306
+ bool DtlsTransport::CheckRemoteFingerprint()
1296
1307
  {
1297
1308
  MS_TRACE();
1298
1309
 
@@ -1386,8 +1397,8 @@ namespace RTC
1386
1397
  BIO* bio = BIO_new(BIO_s_mem());
1387
1398
 
1388
1399
  // Ensure the underlying BUF_MEM structure is also freed.
1389
- // NOTE: Avoid stupid "warning: value computed is not used [-Wunused-value]" since
1390
- // BIO_set_close() always returns 1.
1400
+ // NOTE: Avoid stupid "warning: value computed is not used [-Wunused-value]"
1401
+ // since BIO_set_close() always returns 1.
1391
1402
  (void)BIO_set_close(bio, BIO_CLOSE);
1392
1403
 
1393
1404
  ret = PEM_write_bio_X509(bio, certificate);
@@ -1424,7 +1435,7 @@ namespace RTC
1424
1435
  return true;
1425
1436
  }
1426
1437
 
1427
- inline void DtlsTransport::ExtractSrtpKeys(RTC::SrtpSession::CryptoSuite srtpCryptoSuite)
1438
+ void DtlsTransport::ExtractSrtpKeys(RTC::SrtpSession::CryptoSuite srtpCryptoSuite)
1428
1439
  {
1429
1440
  MS_TRACE();
1430
1441
 
@@ -1529,7 +1540,7 @@ namespace RTC
1529
1540
  delete[] srtpRemoteMasterKey;
1530
1541
  }
1531
1542
 
1532
- inline std::optional<RTC::SrtpSession::CryptoSuite> DtlsTransport::GetNegotiatedSrtpCryptoSuite()
1543
+ std::optional<RTC::SrtpSession::CryptoSuite> DtlsTransport::GetNegotiatedSrtpCryptoSuite()
1533
1544
  {
1534
1545
  MS_TRACE();
1535
1546
 
@@ -1563,7 +1574,7 @@ namespace RTC
1563
1574
  return negotiatedSrtpCryptoSuite;
1564
1575
  }
1565
1576
 
1566
- inline void DtlsTransport::OnSslInfo(int where, int ret)
1577
+ void DtlsTransport::OnSslInfo(int where, int ret)
1567
1578
  {
1568
1579
  MS_TRACE();
1569
1580
 
@@ -1646,11 +1657,12 @@ namespace RTC
1646
1657
  this->handshakeDoneNow = true;
1647
1658
  }
1648
1659
 
1649
- // NOTE: checking SSL_get_shutdown(this->ssl) & SSL_RECEIVED_SHUTDOWN here upon
1650
- // receipt of a close alert does not work (the flag is set after this callback).
1660
+ // NOTE: checking SSL_get_shutdown(this->ssl) & SSL_RECEIVED_SHUTDOWN here
1661
+ // upon receipt of a close alert does not work (the flag is set after this
1662
+ // callback).
1651
1663
  }
1652
1664
 
1653
- inline void DtlsTransport::OnTimer(TimerHandle* /*timer*/)
1665
+ void DtlsTransport::OnTimer(TimerHandle* /*timer*/)
1654
1666
  {
1655
1667
  MS_TRACE();
1656
1668
 
@@ -1670,6 +1682,9 @@ namespace RTC
1670
1682
 
1671
1683
  if (ret == 1)
1672
1684
  {
1685
+ // If required, send DTLS data.
1686
+ SendPendingOutgoingDtlsData();
1687
+
1673
1688
  // Set the DTLS timer again.
1674
1689
  SetTimeout();
1675
1690
  }
package/worker/tasks.py CHANGED
@@ -23,7 +23,7 @@ import os;
23
23
  import inspect;
24
24
  import shutil;
25
25
  # We import this from a custom location and pylint doesn't know.
26
- from invoke import task; # pylint: disable=import-error
26
+ from invoke import task, call; # pylint: disable=import-error
27
27
 
28
28
  MEDIASOUP_BUILDTYPE = os.getenv('MEDIASOUP_BUILDTYPE') or 'Release';
29
29
  WORKER_DIR = os.path.dirname(os.path.abspath(
@@ -135,14 +135,14 @@ def meson_ninja(ctx):
135
135
 
136
136
 
137
137
  @task(pre=[meson_ninja])
138
- def setup(ctx):
138
+ def setup(ctx, meson_args=MESON_ARGS):
139
139
  """
140
140
  Run meson setup
141
141
  """
142
142
  if MEDIASOUP_BUILDTYPE == 'Release':
143
143
  with ctx.cd(f'"{WORKER_DIR}"'):
144
144
  ctx.run(
145
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype release -Db_ndebug=true {MESON_ARGS} "{BUILD_DIR}"',
145
+ f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype release -Db_ndebug=true {meson_args} "{BUILD_DIR}"',
146
146
  echo=True,
147
147
  pty=PTY_SUPPORTED,
148
148
  shell=SHELL
@@ -150,7 +150,7 @@ def setup(ctx):
150
150
  elif MEDIASOUP_BUILDTYPE == 'Debug':
151
151
  with ctx.cd(f'"{WORKER_DIR}"'):
152
152
  ctx.run(
153
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype debug {MESON_ARGS} "{BUILD_DIR}"',
153
+ f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype debug {meson_args} "{BUILD_DIR}"',
154
154
  echo=True,
155
155
  pty=PTY_SUPPORTED,
156
156
  shell=SHELL
@@ -158,7 +158,7 @@ def setup(ctx):
158
158
  else:
159
159
  with ctx.cd(f'"{WORKER_DIR}"'):
160
160
  ctx.run(
161
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype {MEDIASOUP_BUILDTYPE} -Db_ndebug=if-release {MESON_ARGS} "{BUILD_DIR}"',
161
+ f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype {MEDIASOUP_BUILDTYPE} -Db_ndebug=if-release {meson_args} "{BUILD_DIR}"',
162
162
  echo=True,
163
163
  pty=PTY_SUPPORTED,
164
164
  shell=SHELL
@@ -464,11 +464,15 @@ def tidy(ctx):
464
464
  );
465
465
 
466
466
 
467
- @task(pre=[setup, flatc])
467
+ @task(pre=[call(setup, meson_args=MESON_ARGS + ' -Db_sanitize=address'), flatc])
468
468
  def fuzzer(ctx):
469
469
  """
470
470
  Build the mediasoup-worker-fuzzer binary (which uses libFuzzer)
471
471
  """
472
+
473
+ # NOTE: We need to pass '-Db_sanitize=address' to enable fuzzer in all Meson
474
+ # subprojects, so we pass it to the setup() task.
475
+
472
476
  with ctx.cd(f'"{WORKER_DIR}"'):
473
477
  ctx.run(
474
478
  f'"{MESON}" compile -C "{BUILD_DIR}" -j {NUM_CORES} mediasoup-worker-fuzzer',