mediasoup 3.19.21 → 3.20.0

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.
Files changed (649) hide show
  1. package/node/lib/ActiveSpeakerObserver.js +34 -1
  2. package/node/lib/AudioLevelObserver.js +35 -2
  3. package/node/lib/Channel.d.ts.map +1 -1
  4. package/node/lib/Channel.js +37 -5
  5. package/node/lib/Consumer.js +39 -6
  6. package/node/lib/DataConsumer.d.ts.map +1 -1
  7. package/node/lib/DataConsumer.js +39 -5
  8. package/node/lib/DataConsumerTypes.d.ts +1 -0
  9. package/node/lib/DataConsumerTypes.d.ts.map +1 -1
  10. package/node/lib/DataProducer.js +37 -4
  11. package/node/lib/DirectTransport.js +37 -4
  12. package/node/lib/DirectTransportTypes.d.ts +7 -2
  13. package/node/lib/DirectTransportTypes.d.ts.map +1 -1
  14. package/node/lib/Logger.js +4 -1
  15. package/node/lib/PipeTransport.d.ts +3 -1
  16. package/node/lib/PipeTransport.d.ts.map +1 -1
  17. package/node/lib/PipeTransport.js +56 -5
  18. package/node/lib/PipeTransportTypes.d.ts +28 -8
  19. package/node/lib/PipeTransportTypes.d.ts.map +1 -1
  20. package/node/lib/PlainTransport.d.ts +3 -1
  21. package/node/lib/PlainTransport.d.ts.map +1 -1
  22. package/node/lib/PlainTransport.js +54 -3
  23. package/node/lib/PlainTransportTypes.d.ts +27 -7
  24. package/node/lib/PlainTransportTypes.d.ts.map +1 -1
  25. package/node/lib/Producer.js +40 -7
  26. package/node/lib/Router.d.ts +5 -5
  27. package/node/lib/Router.d.ts.map +1 -1
  28. package/node/lib/Router.js +81 -36
  29. package/node/lib/RouterTypes.d.ts +25 -3
  30. package/node/lib/RouterTypes.d.ts.map +1 -1
  31. package/node/lib/RtpObserver.js +36 -3
  32. package/node/lib/Transport.d.ts +3 -1
  33. package/node/lib/Transport.d.ts.map +1 -1
  34. package/node/lib/Transport.js +74 -22
  35. package/node/lib/TransportTypes.d.ts +2 -1
  36. package/node/lib/TransportTypes.d.ts.map +1 -1
  37. package/node/lib/WebRtcServer.js +36 -3
  38. package/node/lib/WebRtcTransport.d.ts +3 -1
  39. package/node/lib/WebRtcTransport.d.ts.map +1 -1
  40. package/node/lib/WebRtcTransport.js +55 -4
  41. package/node/lib/WebRtcTransportTypes.d.ts +27 -7
  42. package/node/lib/WebRtcTransportTypes.d.ts.map +1 -1
  43. package/node/lib/Worker.d.ts +2 -1
  44. package/node/lib/Worker.d.ts.map +1 -1
  45. package/node/lib/Worker.js +71 -25
  46. package/node/lib/WorkerTypes.d.ts +0 -4
  47. package/node/lib/WorkerTypes.d.ts.map +1 -1
  48. package/node/lib/enhancedEvents.d.ts +2 -2
  49. package/node/lib/enhancedEvents.d.ts.map +1 -1
  50. package/node/lib/enhancedEvents.js +0 -2
  51. package/node/lib/fbs/active-speaker-observer/active-speaker-observer-options.js +34 -1
  52. package/node/lib/fbs/active-speaker-observer/dominant-speaker-notification.js +34 -1
  53. package/node/lib/fbs/audio-level-observer/audio-level-observer-options.js +34 -1
  54. package/node/lib/fbs/audio-level-observer/volume.js +34 -1
  55. package/node/lib/fbs/audio-level-observer/volumes-notification.js +34 -1
  56. package/node/lib/fbs/common/string-string-array.js +34 -1
  57. package/node/lib/fbs/common/string-string.js +34 -1
  58. package/node/lib/fbs/common/string-uint8.js +34 -1
  59. package/node/lib/fbs/common/uint16-string.js +34 -1
  60. package/node/lib/fbs/common/uint32-string.js +34 -1
  61. package/node/lib/fbs/consumer/base-consumer-dump.js +34 -1
  62. package/node/lib/fbs/consumer/consumer-dump.js +34 -1
  63. package/node/lib/fbs/consumer/consumer-layers.js +34 -1
  64. package/node/lib/fbs/consumer/consumer-score.js +34 -1
  65. package/node/lib/fbs/consumer/dump-response.js +34 -1
  66. package/node/lib/fbs/consumer/enable-trace-event-request.js +34 -1
  67. package/node/lib/fbs/consumer/fir-trace-info.js +34 -1
  68. package/node/lib/fbs/consumer/get-stats-response.js +34 -1
  69. package/node/lib/fbs/consumer/key-frame-trace-info.js +34 -1
  70. package/node/lib/fbs/consumer/layers-change-notification.js +34 -1
  71. package/node/lib/fbs/consumer/pli-trace-info.js +34 -1
  72. package/node/lib/fbs/consumer/rtp-notification.js +34 -1
  73. package/node/lib/fbs/consumer/rtp-trace-info.js +34 -1
  74. package/node/lib/fbs/consumer/score-notification.js +34 -1
  75. package/node/lib/fbs/consumer/set-preferred-layers-request.js +34 -1
  76. package/node/lib/fbs/consumer/set-preferred-layers-response.js +34 -1
  77. package/node/lib/fbs/consumer/set-priority-request.js +34 -1
  78. package/node/lib/fbs/consumer/set-priority-response.js +34 -1
  79. package/node/lib/fbs/consumer/trace-notification.js +34 -1
  80. package/node/lib/fbs/data-consumer/add-subchannel-request.js +34 -1
  81. package/node/lib/fbs/data-consumer/add-subchannel-response.js +34 -1
  82. package/node/lib/fbs/data-consumer/buffered-amount-low-notification.js +34 -1
  83. package/node/lib/fbs/data-consumer/dump-response.d.ts +5 -2
  84. package/node/lib/fbs/data-consumer/dump-response.d.ts.map +1 -1
  85. package/node/lib/fbs/data-consumer/dump-response.js +60 -16
  86. package/node/lib/fbs/data-consumer/get-buffered-amount-response.js +34 -1
  87. package/node/lib/fbs/data-consumer/get-stats-response.js +34 -1
  88. package/node/lib/fbs/data-consumer/message-notification.js +34 -1
  89. package/node/lib/fbs/data-consumer/remove-subchannel-request.js +34 -1
  90. package/node/lib/fbs/data-consumer/remove-subchannel-response.js +34 -1
  91. package/node/lib/fbs/data-consumer/send-request.js +34 -1
  92. package/node/lib/fbs/data-consumer/set-buffered-amount-low-threshold-request.js +34 -1
  93. package/node/lib/fbs/data-consumer/set-subchannels-request.js +34 -1
  94. package/node/lib/fbs/data-consumer/set-subchannels-response.js +34 -1
  95. package/node/lib/fbs/data-consumer/type.d.ts +5 -0
  96. package/node/lib/fbs/data-consumer/type.d.ts.map +1 -0
  97. package/node/lib/fbs/data-consumer/type.js +10 -0
  98. package/node/lib/fbs/data-consumer.d.ts +1 -0
  99. package/node/lib/fbs/data-consumer.d.ts.map +1 -1
  100. package/node/lib/fbs/data-consumer.js +3 -1
  101. package/node/lib/fbs/data-producer/dump-response.js +34 -1
  102. package/node/lib/fbs/data-producer/get-stats-response.js +34 -1
  103. package/node/lib/fbs/data-producer/send-notification.js +34 -1
  104. package/node/lib/fbs/direct-transport/direct-transport-options.js +34 -1
  105. package/node/lib/fbs/direct-transport/dump-response.js +34 -1
  106. package/node/lib/fbs/direct-transport/get-stats-response.js +34 -1
  107. package/node/lib/fbs/direct-transport/rtcp-notification.js +34 -1
  108. package/node/lib/fbs/lib-uring/dump.js +34 -1
  109. package/node/lib/fbs/log/log.js +34 -1
  110. package/node/lib/fbs/message/message.js +34 -1
  111. package/node/lib/fbs/notification/body.d.ts +24 -22
  112. package/node/lib/fbs/notification/body.d.ts.map +1 -1
  113. package/node/lib/fbs/notification/body.js +24 -20
  114. package/node/lib/fbs/notification/event.d.ts +27 -26
  115. package/node/lib/fbs/notification/event.d.ts.map +1 -1
  116. package/node/lib/fbs/notification/event.js +27 -26
  117. package/node/lib/fbs/notification/notification.d.ts +3 -2
  118. package/node/lib/fbs/notification/notification.d.ts.map +1 -1
  119. package/node/lib/fbs/notification/notification.js +34 -1
  120. package/node/lib/fbs/pipe-transport/connect-request.js +34 -1
  121. package/node/lib/fbs/pipe-transport/connect-response.js +34 -1
  122. package/node/lib/fbs/pipe-transport/dump-response.js +34 -1
  123. package/node/lib/fbs/pipe-transport/get-stats-response.js +34 -1
  124. package/node/lib/fbs/pipe-transport/pipe-transport-options.js +34 -1
  125. package/node/lib/fbs/plain-transport/connect-request.js +34 -1
  126. package/node/lib/fbs/plain-transport/connect-response.js +34 -1
  127. package/node/lib/fbs/plain-transport/dump-response.js +34 -1
  128. package/node/lib/fbs/plain-transport/get-stats-response.js +34 -1
  129. package/node/lib/fbs/plain-transport/plain-transport-options.js +34 -1
  130. package/node/lib/fbs/plain-transport/rtcp-tuple-notification.js +34 -1
  131. package/node/lib/fbs/plain-transport/tuple-notification.js +34 -1
  132. package/node/lib/fbs/producer/dump-response.js +34 -1
  133. package/node/lib/fbs/producer/enable-trace-event-request.js +34 -1
  134. package/node/lib/fbs/producer/fir-trace-info.js +34 -1
  135. package/node/lib/fbs/producer/get-stats-response.js +34 -1
  136. package/node/lib/fbs/producer/key-frame-trace-info.js +34 -1
  137. package/node/lib/fbs/producer/pli-trace-info.js +34 -1
  138. package/node/lib/fbs/producer/rtp-trace-info.js +34 -1
  139. package/node/lib/fbs/producer/score-notification.js +34 -1
  140. package/node/lib/fbs/producer/score.js +34 -1
  141. package/node/lib/fbs/producer/send-notification.js +34 -1
  142. package/node/lib/fbs/producer/sr-trace-info.js +34 -1
  143. package/node/lib/fbs/producer/trace-notification.js +34 -1
  144. package/node/lib/fbs/producer/video-orientation-change-notification.js +34 -1
  145. package/node/lib/fbs/request/request.js +34 -1
  146. package/node/lib/fbs/response/response.js +34 -1
  147. package/node/lib/fbs/router/close-rtp-observer-request.js +34 -1
  148. package/node/lib/fbs/router/close-transport-request.js +34 -1
  149. package/node/lib/fbs/router/create-active-speaker-observer-request.js +34 -1
  150. package/node/lib/fbs/router/create-audio-level-observer-request.js +34 -1
  151. package/node/lib/fbs/router/create-direct-transport-request.js +34 -1
  152. package/node/lib/fbs/router/create-pipe-transport-request.js +34 -1
  153. package/node/lib/fbs/router/create-plain-transport-request.js +34 -1
  154. package/node/lib/fbs/router/create-web-rtc-transport-request.js +34 -1
  155. package/node/lib/fbs/router/dump-response.js +34 -1
  156. package/node/lib/fbs/rtp-observer/add-producer-request.js +34 -1
  157. package/node/lib/fbs/rtp-observer/remove-producer-request.js +34 -1
  158. package/node/lib/fbs/rtp-packet/dump.js +34 -1
  159. package/node/lib/fbs/rtp-parameters/boolean.js +34 -1
  160. package/node/lib/fbs/rtp-parameters/codec-mapping.js +34 -1
  161. package/node/lib/fbs/rtp-parameters/double.js +34 -1
  162. package/node/lib/fbs/rtp-parameters/encoding-mapping.js +34 -1
  163. package/node/lib/fbs/rtp-parameters/integer32-array.js +34 -1
  164. package/node/lib/fbs/rtp-parameters/integer32.js +34 -1
  165. package/node/lib/fbs/rtp-parameters/parameter.js +34 -1
  166. package/node/lib/fbs/rtp-parameters/rtcp-feedback.js +34 -1
  167. package/node/lib/fbs/rtp-parameters/rtcp-parameters.js +34 -1
  168. package/node/lib/fbs/rtp-parameters/rtp-codec-parameters.js +34 -1
  169. package/node/lib/fbs/rtp-parameters/rtp-encoding-parameters.js +34 -1
  170. package/node/lib/fbs/rtp-parameters/rtp-header-extension-parameters.js +34 -1
  171. package/node/lib/fbs/rtp-parameters/rtp-mapping.js +34 -1
  172. package/node/lib/fbs/rtp-parameters/rtp-parameters.js +34 -1
  173. package/node/lib/fbs/rtp-parameters/rtx.js +34 -1
  174. package/node/lib/fbs/rtp-parameters/string.js +34 -1
  175. package/node/lib/fbs/rtp-stream/base-stats.js +34 -1
  176. package/node/lib/fbs/rtp-stream/bitrate-by-layer.js +34 -1
  177. package/node/lib/fbs/rtp-stream/dump.js +34 -1
  178. package/node/lib/fbs/rtp-stream/params.js +34 -1
  179. package/node/lib/fbs/rtp-stream/recv-stats.js +34 -1
  180. package/node/lib/fbs/rtp-stream/send-stats.js +34 -1
  181. package/node/lib/fbs/rtp-stream/stats.js +34 -1
  182. package/node/lib/fbs/rtx-stream/params.js +34 -1
  183. package/node/lib/fbs/rtx-stream/rtx-dump.js +34 -1
  184. package/node/lib/fbs/sctp-association/sctp-negotiated-capabilities.d.ts +24 -0
  185. package/node/lib/fbs/sctp-association/sctp-negotiated-capabilities.d.ts.map +1 -0
  186. package/node/lib/fbs/sctp-association/sctp-negotiated-capabilities.js +102 -0
  187. package/node/lib/fbs/sctp-association.d.ts +1 -0
  188. package/node/lib/fbs/sctp-association.d.ts.map +1 -1
  189. package/node/lib/fbs/sctp-association.js +4 -1
  190. package/node/lib/fbs/sctp-parameters/num-sctp-streams.js +34 -1
  191. package/node/lib/fbs/sctp-parameters/sctp-parameters.d.ts +14 -14
  192. package/node/lib/fbs/sctp-parameters/sctp-parameters.d.ts.map +1 -1
  193. package/node/lib/fbs/sctp-parameters/sctp-parameters.js +73 -40
  194. package/node/lib/fbs/sctp-parameters/sctp-stream-parameters.js +34 -1
  195. package/node/lib/fbs/sctp-parameters.d.ts +0 -1
  196. package/node/lib/fbs/sctp-parameters.d.ts.map +1 -1
  197. package/node/lib/fbs/sctp-parameters.js +1 -4
  198. package/node/lib/fbs/srtp-parameters/srtp-parameters.js +34 -1
  199. package/node/lib/fbs/transport/bwe-trace-info.js +34 -1
  200. package/node/lib/fbs/transport/close-consumer-request.js +34 -1
  201. package/node/lib/fbs/transport/close-data-consumer-request.js +34 -1
  202. package/node/lib/fbs/transport/close-data-producer-request.js +34 -1
  203. package/node/lib/fbs/transport/close-producer-request.js +34 -1
  204. package/node/lib/fbs/transport/consume-data-request.d.ts +1 -1
  205. package/node/lib/fbs/transport/consume-data-request.js +35 -2
  206. package/node/lib/fbs/transport/consume-request.js +34 -1
  207. package/node/lib/fbs/transport/consume-response.js +34 -1
  208. package/node/lib/fbs/transport/dump.d.ts +7 -4
  209. package/node/lib/fbs/transport/dump.d.ts.map +1 -1
  210. package/node/lib/fbs/transport/dump.js +66 -22
  211. package/node/lib/fbs/transport/enable-trace-event-request.js +34 -1
  212. package/node/lib/fbs/transport/listen-info.js +34 -1
  213. package/node/lib/fbs/transport/options.d.ts +14 -14
  214. package/node/lib/fbs/transport/options.d.ts.map +1 -1
  215. package/node/lib/fbs/transport/options.js +92 -51
  216. package/node/lib/fbs/transport/port-range.js +34 -1
  217. package/node/lib/fbs/transport/produce-data-request.js +34 -1
  218. package/node/lib/fbs/transport/produce-request.js +34 -1
  219. package/node/lib/fbs/transport/produce-response.js +34 -1
  220. package/node/lib/fbs/transport/recv-rtp-header-extensions.js +34 -1
  221. package/node/lib/fbs/transport/restart-ice-response.js +34 -1
  222. package/node/lib/fbs/transport/rtp-listener.js +34 -1
  223. package/node/lib/fbs/transport/sctp-listener.js +34 -1
  224. package/node/lib/fbs/transport/sctp-negotiated-capabilities-notification.d.ts +22 -0
  225. package/node/lib/fbs/transport/sctp-negotiated-capabilities-notification.d.ts.map +1 -0
  226. package/node/lib/fbs/transport/sctp-negotiated-capabilities-notification.js +93 -0
  227. package/node/lib/fbs/transport/sctp-state-change-notification.js +34 -1
  228. package/node/lib/fbs/transport/send-rtcp-notification.js +34 -1
  229. package/node/lib/fbs/transport/set-max-incoming-bitrate-request.js +34 -1
  230. package/node/lib/fbs/transport/set-max-outgoing-bitrate-request.js +34 -1
  231. package/node/lib/fbs/transport/set-min-outgoing-bitrate-request.js +34 -1
  232. package/node/lib/fbs/transport/socket-flags.js +34 -1
  233. package/node/lib/fbs/transport/stats.js +34 -1
  234. package/node/lib/fbs/transport/trace-notification.js +34 -1
  235. package/node/lib/fbs/transport/tuple.js +34 -1
  236. package/node/lib/fbs/transport.d.ts +1 -0
  237. package/node/lib/fbs/transport.d.ts.map +1 -1
  238. package/node/lib/fbs/transport.js +5 -2
  239. package/node/lib/fbs/web-rtc-server/dump-response.js +34 -1
  240. package/node/lib/fbs/web-rtc-server/ice-user-name-fragment.js +34 -1
  241. package/node/lib/fbs/web-rtc-server/ip-port.js +34 -1
  242. package/node/lib/fbs/web-rtc-server/tuple-hash.js +34 -1
  243. package/node/lib/fbs/web-rtc-transport/connect-request.js +34 -1
  244. package/node/lib/fbs/web-rtc-transport/connect-response.js +34 -1
  245. package/node/lib/fbs/web-rtc-transport/dtls-parameters.js +34 -1
  246. package/node/lib/fbs/web-rtc-transport/dtls-state-change-notification.js +34 -1
  247. package/node/lib/fbs/web-rtc-transport/dump-response.js +34 -1
  248. package/node/lib/fbs/web-rtc-transport/fingerprint.js +34 -1
  249. package/node/lib/fbs/web-rtc-transport/get-stats-response.js +34 -1
  250. package/node/lib/fbs/web-rtc-transport/ice-candidate.js +34 -1
  251. package/node/lib/fbs/web-rtc-transport/ice-parameters.js +34 -1
  252. package/node/lib/fbs/web-rtc-transport/ice-selected-tuple-change-notification.js +34 -1
  253. package/node/lib/fbs/web-rtc-transport/ice-state-change-notification.js +34 -1
  254. package/node/lib/fbs/web-rtc-transport/listen-individual.js +34 -1
  255. package/node/lib/fbs/web-rtc-transport/listen-server.js +34 -1
  256. package/node/lib/fbs/web-rtc-transport/web-rtc-transport-options.js +34 -1
  257. package/node/lib/fbs/worker/channel-message-handlers.js +34 -1
  258. package/node/lib/fbs/worker/close-router-request.js +34 -1
  259. package/node/lib/fbs/worker/close-web-rtc-server-request.js +34 -1
  260. package/node/lib/fbs/worker/create-router-request.js +34 -1
  261. package/node/lib/fbs/worker/create-web-rtc-server-request.js +34 -1
  262. package/node/lib/fbs/worker/dump-response.js +34 -1
  263. package/node/lib/fbs/worker/resource-usage-response.js +34 -1
  264. package/node/lib/fbs/worker/update-settings-request.js +34 -1
  265. package/node/lib/index.d.ts +1 -1
  266. package/node/lib/index.d.ts.map +1 -1
  267. package/node/lib/index.js +37 -5
  268. package/node/lib/ortc.js +36 -3
  269. package/node/lib/rtpParametersFbsUtils.js +34 -1
  270. package/node/lib/rtpStreamStatsFbsUtils.js +35 -2
  271. package/node/lib/sctpParametersFbsUtils.d.ts +2 -2
  272. package/node/lib/sctpParametersFbsUtils.d.ts.map +1 -1
  273. package/node/lib/sctpParametersFbsUtils.js +44 -7
  274. package/node/lib/sctpParametersTypes.d.ts +10 -46
  275. package/node/lib/sctpParametersTypes.d.ts.map +1 -1
  276. package/node/lib/srtpParametersFbsUtils.js +34 -1
  277. package/node/lib/test/test-ActiveSpeakerObserver.js +35 -2
  278. package/node/lib/test/test-AudioLevelObserver.js +35 -2
  279. package/node/lib/test/test-Consumer.js +37 -4
  280. package/node/lib/test/test-DataConsumer.js +35 -2
  281. package/node/lib/test/test-DataProducer.js +35 -2
  282. package/node/lib/test/test-DirectTransport.js +36 -8
  283. package/node/lib/test/test-PipeTransport.js +35 -2
  284. package/node/lib/test/test-PlainTransport.js +45 -12
  285. package/node/lib/test/test-Producer.js +37 -4
  286. package/node/lib/test/test-Router.js +35 -2
  287. package/node/lib/test/test-WebRtcServer.js +34 -1
  288. package/node/lib/test/test-WebRtcTransport.js +51 -22
  289. package/node/lib/test/test-Worker.js +37 -4
  290. package/node/lib/test/test-mediasoup.js +36 -3
  291. package/node/lib/test/test-multiopus.js +35 -2
  292. package/node/lib/test/test-ortc.js +34 -1
  293. package/node/lib/test/test-werift-sctp.js +39 -5
  294. package/npm-scripts.mjs +2 -2
  295. package/package.json +13 -11
  296. package/worker/deps/libwebrtc/LICENSE +5 -0
  297. package/worker/deps/libwebrtc/README.md +3 -3
  298. package/worker/deps/libwebrtc/libwebrtc/mediasoup_helpers.h +13 -10
  299. package/worker/fbs/dataConsumer.fbs +7 -2
  300. package/worker/fbs/dataProducer.fbs +1 -0
  301. package/worker/fbs/notification.fbs +2 -0
  302. package/worker/fbs/sctpAssociation.fbs +4 -0
  303. package/worker/fbs/sctpParameters.fbs +5 -12
  304. package/worker/fbs/transport.fbs +12 -8
  305. package/worker/fuzzer/src/RTC/FuzzerDtlsTransport.cpp +13 -3
  306. package/worker/fuzzer/src/RTC/FuzzerRateCalculator.cpp +2 -2
  307. package/worker/fuzzer/src/RTC/FuzzerSeqManager.cpp +1 -1
  308. package/worker/fuzzer/src/RTC/FuzzerTrendCalculator.cpp +5 -5
  309. package/worker/fuzzer/src/RTC/ICE/FuzzerStunPacket.cpp +9 -6
  310. package/worker/fuzzer/src/RTC/RTP/FuzzerRetransmissionBuffer.cpp +1 -1
  311. package/worker/fuzzer/src/RTC/RTP/FuzzerRtpStreamSend.cpp +14 -2
  312. package/worker/fuzzer/src/RTC/SCTP/association/FuzzerStateCookie.cpp +1 -1
  313. package/worker/fuzzer/src/RTC/SCTP/packet/FuzzerPacket.cpp +5 -2
  314. package/worker/fuzzer/src/fuzzer.cpp +3 -10
  315. package/worker/include/Channel/ChannelMessageRegistrator.hpp +39 -0
  316. package/worker/include/Channel/ChannelMessageRegistratorInterface.hpp +32 -0
  317. package/worker/include/Channel/ChannelRequest.hpp +1 -1
  318. package/worker/include/Channel/ChannelSocket.hpp +1 -1
  319. package/worker/include/DepLibUV.hpp +1 -1
  320. package/worker/include/DepLibUring.hpp +3 -3
  321. package/worker/include/Logger.hpp +4 -4
  322. package/worker/include/MediaSoupErrors.hpp +1 -1
  323. package/worker/include/RTC/ActiveSpeakerObserver.hpp +11 -9
  324. package/worker/include/RTC/AudioLevelObserver.hpp +7 -7
  325. package/worker/include/RTC/Consumer.hpp +3 -3
  326. package/worker/include/RTC/DataConsumer.hpp +13 -17
  327. package/worker/include/RTC/DataProducer.hpp +6 -9
  328. package/worker/include/RTC/DirectTransport.hpp +4 -6
  329. package/worker/include/RTC/DtlsTransport.hpp +13 -11
  330. package/worker/include/RTC/ICE/IceServer.hpp +8 -5
  331. package/worker/include/RTC/ICE/StunPacket.hpp +1 -1
  332. package/worker/include/RTC/KeyFrameRequestManager.hpp +15 -12
  333. package/worker/include/RTC/NackGenerator.hpp +8 -6
  334. package/worker/include/RTC/PipeConsumer.hpp +1 -2
  335. package/worker/include/RTC/PipeTransport.hpp +4 -6
  336. package/worker/include/RTC/PlainTransport.hpp +4 -6
  337. package/worker/include/RTC/PortManager.hpp +1 -1
  338. package/worker/include/RTC/Producer.hpp +3 -3
  339. package/worker/include/RTC/RTCP/FeedbackPs.hpp +1 -1
  340. package/worker/include/RTC/RTCP/FeedbackRtp.hpp +1 -1
  341. package/worker/include/RTC/RTCP/FeedbackRtpNack.hpp +1 -1
  342. package/worker/include/RTC/RTCP/ReceiverReport.hpp +1 -1
  343. package/worker/include/RTC/RTP/Packet.hpp +2 -2
  344. package/worker/include/RTC/RTP/RtpStream.hpp +17 -12
  345. package/worker/include/RTC/RTP/RtpStreamRecv.hpp +8 -6
  346. package/worker/include/RTC/RTP/RtpStreamSend.hpp +4 -1
  347. package/worker/include/RTC/RTP/RtxStream.hpp +3 -1
  348. package/worker/include/RTC/RTP/SharedPacket.hpp +1 -1
  349. package/worker/include/RTC/RateCalculator.hpp +5 -2
  350. package/worker/include/RTC/Router.hpp +7 -8
  351. package/worker/include/RTC/RtpObserver.hpp +3 -3
  352. package/worker/include/RTC/SCTP/association/Association.hpp +53 -19
  353. package/worker/include/RTC/SCTP/association/AssociationListenerDeferrer.hpp +14 -6
  354. package/worker/include/RTC/SCTP/association/HeartbeatHandler.hpp +18 -14
  355. package/worker/include/RTC/SCTP/association/PacketSender.hpp +3 -3
  356. package/worker/include/RTC/SCTP/association/StateCookie.hpp +1 -1
  357. package/worker/include/RTC/SCTP/association/StreamResetHandler.hpp +49 -35
  358. package/worker/include/RTC/SCTP/association/TransmissionControlBlock.hpp +114 -31
  359. package/worker/include/RTC/SCTP/association/{TCBContext.hpp → TransmissionControlBlockContextInterface.hpp} +14 -8
  360. package/worker/include/RTC/SCTP/packet/Chunk.hpp +3 -3
  361. package/worker/include/RTC/SCTP/packet/TLV.hpp +1 -1
  362. package/worker/include/RTC/SCTP/packet/UserData.hpp +61 -17
  363. package/worker/include/RTC/SCTP/packet/chunks/AnyDataChunk.hpp +1 -1
  364. package/worker/include/RTC/SCTP/packet/chunks/AnyForwardTsnChunk.hpp +9 -9
  365. package/worker/include/RTC/SCTP/packet/chunks/AnyInitChunk.hpp +1 -1
  366. package/worker/include/RTC/SCTP/packet/chunks/DataChunk.hpp +4 -2
  367. package/worker/include/RTC/SCTP/packet/chunks/ForwardTsnChunk.hpp +3 -3
  368. package/worker/include/RTC/SCTP/packet/chunks/IDataChunk.hpp +4 -2
  369. package/worker/include/RTC/SCTP/packet/chunks/IForwardTsnChunk.hpp +3 -3
  370. package/worker/include/RTC/SCTP/packet/chunks/InitAckChunk.hpp +1 -1
  371. package/worker/include/RTC/SCTP/packet/chunks/InitChunk.hpp +1 -1
  372. package/worker/include/RTC/SCTP/packet/chunks/SackChunk.hpp +10 -3
  373. package/worker/include/RTC/SCTP/packet/chunks/ShutdownChunk.hpp +1 -1
  374. package/worker/include/RTC/SCTP/packet/errorCauses/InvalidStreamIdentifierErrorCause.hpp +1 -1
  375. package/worker/include/RTC/SCTP/packet/errorCauses/MissingMandatoryParameterErrorCause.hpp +1 -1
  376. package/worker/include/RTC/SCTP/packet/errorCauses/NoUserDataErrorCause.hpp +1 -1
  377. package/worker/include/RTC/SCTP/packet/errorCauses/StaleCookieErrorCause.hpp +1 -1
  378. package/worker/include/RTC/SCTP/packet/parameters/AddIncomingStreamsRequestParameter.hpp +1 -1
  379. package/worker/include/RTC/SCTP/packet/parameters/AddOutgoingStreamsRequestParameter.hpp +1 -1
  380. package/worker/include/RTC/SCTP/packet/parameters/CookiePreservativeParameter.hpp +1 -1
  381. package/worker/include/RTC/SCTP/packet/parameters/IncomingSsnResetRequestParameter.hpp +1 -1
  382. package/worker/include/RTC/SCTP/packet/parameters/OutgoingSsnResetRequestParameter.hpp +1 -1
  383. package/worker/include/RTC/SCTP/packet/parameters/ReconfigurationResponseParameter.hpp +1 -1
  384. package/worker/include/RTC/SCTP/packet/parameters/SsnTsnResetRequestParameter.hpp +1 -1
  385. package/worker/include/RTC/SCTP/packet/parameters/SupportedAddressTypesParameter.hpp +1 -1
  386. package/worker/include/RTC/SCTP/packet/parameters/SupportedExtensionsParameter.hpp +1 -1
  387. package/worker/include/RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp +1 -1
  388. package/worker/include/RTC/SCTP/public/AssociationInterface.hpp +22 -2
  389. package/worker/include/RTC/SCTP/public/{AssociationListener.hpp → AssociationListenerInterface.hpp} +5 -5
  390. package/worker/include/RTC/SCTP/public/Message.hpp +26 -10
  391. package/worker/include/RTC/SCTP/public/SctpOptions.hpp +28 -19
  392. package/worker/include/RTC/SCTP/public/SctpTypes.hpp +21 -0
  393. package/worker/include/RTC/SCTP/rx/DataTracker.hpp +277 -0
  394. package/worker/include/RTC/SCTP/rx/InterleavedReassemblyStreams.hpp +116 -0
  395. package/worker/include/RTC/SCTP/rx/ReassemblyQueue.hpp +202 -0
  396. package/worker/include/RTC/SCTP/rx/ReassemblyStreamsInterface.hpp +83 -0
  397. package/worker/include/RTC/SCTP/rx/TraditionalReassemblyStreams.hpp +183 -0
  398. package/worker/include/RTC/SCTP/tx/OutstandingData.hpp +595 -0
  399. package/worker/include/RTC/SCTP/tx/RetransmissionErrorCounter.hpp +3 -3
  400. package/worker/include/RTC/SCTP/tx/RetransmissionQueue.hpp +329 -0
  401. package/worker/include/RTC/SCTP/tx/RetransmissionTimeout.hpp +11 -10
  402. package/worker/include/RTC/SCTP/tx/RoundRobinSendQueue.hpp +356 -0
  403. package/worker/include/RTC/SCTP/tx/SendQueueInterface.hpp +180 -0
  404. package/worker/include/RTC/SCTP/tx/StreamScheduler.hpp +235 -0
  405. package/worker/include/RTC/SenderBandwidthEstimator.hpp +5 -1
  406. package/worker/include/RTC/Serializable.hpp +11 -3
  407. package/worker/include/RTC/SimpleConsumer.hpp +1 -2
  408. package/worker/include/RTC/SimulcastConsumer.hpp +1 -2
  409. package/worker/include/RTC/SvcConsumer.hpp +1 -2
  410. package/worker/include/RTC/TcpServer.hpp +2 -2
  411. package/worker/include/RTC/Transport.hpp +65 -86
  412. package/worker/include/RTC/TransportCongestionControlClient.hpp +8 -5
  413. package/worker/include/RTC/TransportCongestionControlServer.hpp +8 -5
  414. package/worker/include/RTC/TransportTuple.hpp +1 -1
  415. package/worker/include/RTC/UdpSocket.hpp +1 -1
  416. package/worker/include/RTC/WebRtcServer.hpp +3 -3
  417. package/worker/include/RTC/WebRtcTransport.hpp +5 -7
  418. package/worker/include/Settings.hpp +2 -3
  419. package/worker/include/Shared.hpp +64 -0
  420. package/worker/include/SharedInterface.hpp +77 -0
  421. package/worker/include/Utils/UnwrappedSequenceNumber.hpp +270 -0
  422. package/worker/include/Utils.hpp +10 -4
  423. package/worker/include/Worker.hpp +6 -6
  424. package/worker/include/common.hpp +12 -12
  425. package/worker/include/handles/BackoffTimerHandle.hpp +28 -67
  426. package/worker/include/handles/BackoffTimerHandleInterface.hpp +123 -0
  427. package/worker/include/handles/TimerHandle.hpp +29 -20
  428. package/worker/include/handles/TimerHandleInterface.hpp +43 -0
  429. package/worker/meson.build +45 -29
  430. package/worker/meson_options.txt +2 -1
  431. package/worker/mocks/include/Channel/MockChannelMessageRegistrator.hpp +45 -0
  432. package/worker/mocks/include/MockShared.hpp +90 -0
  433. package/worker/mocks/include/RTC/SCTP/association/MockAssociationListener.hpp +308 -0
  434. package/worker/mocks/include/RTC/SCTP/association/MockTransmissionControlBlockContext.hpp +183 -0
  435. package/worker/mocks/include/RTC/SCTP/tx/MockSendQueue.hpp +262 -0
  436. package/worker/mocks/include/handles/MockBackoffTimerHandle.hpp +153 -0
  437. package/worker/mocks/include/handles/MockTimerHandle.hpp +74 -0
  438. package/worker/mocks/include/mockTypes.hpp +15 -0
  439. package/worker/mocks/src/Channel/MockChannelMessageRegistrator.cpp +128 -0
  440. package/worker/mocks/src/MockShared.cpp +46 -0
  441. package/worker/mocks/src/RTC/SCTP/association/MockTransmissionControlBlockContext.cpp +39 -0
  442. package/worker/mocks/src/handles/MockBackoffTimerHandle.cpp +127 -0
  443. package/worker/scripts/clang-scripts.mjs +5 -1
  444. package/worker/scripts/package-lock.json +6 -7
  445. package/worker/src/Channel/ChannelMessageRegistrator.cpp +125 -0
  446. package/worker/src/Channel/ChannelSocket.cpp +3 -4
  447. package/worker/src/DepLibUV.cpp +1 -1
  448. package/worker/src/DepLibUring.cpp +3 -1
  449. package/worker/src/Logger.cpp +1 -1
  450. package/worker/src/MediaSoupErrors.cpp +2 -0
  451. package/worker/src/RTC/ActiveSpeakerObserver.cpp +14 -14
  452. package/worker/src/RTC/AudioLevelObserver.cpp +12 -10
  453. package/worker/src/RTC/Consumer.cpp +28 -26
  454. package/worker/src/RTC/DataConsumer.cpp +61 -71
  455. package/worker/src/RTC/DataProducer.cpp +16 -11
  456. package/worker/src/RTC/DirectTransport.cpp +21 -20
  457. package/worker/src/RTC/DtlsTransport.cpp +4 -4
  458. package/worker/src/RTC/ICE/IceServer.cpp +6 -5
  459. package/worker/src/RTC/ICE/StunPacket.cpp +1 -1
  460. package/worker/src/RTC/KeyFrameRequestManager.cpp +15 -15
  461. package/worker/src/RTC/NackGenerator.cpp +6 -6
  462. package/worker/src/RTC/PipeConsumer.cpp +6 -5
  463. package/worker/src/RTC/PipeTransport.cpp +9 -22
  464. package/worker/src/RTC/PlainTransport.cpp +16 -28
  465. package/worker/src/RTC/Producer.cpp +40 -39
  466. package/worker/src/RTC/RTCP/FeedbackPsAfb.cpp +1 -1
  467. package/worker/src/RTC/RTCP/FeedbackPsRpsi.cpp +1 -2
  468. package/worker/src/RTC/RTCP/FeedbackRtpTransport.cpp +1 -1
  469. package/worker/src/RTC/RTCP/XR.cpp +1 -1
  470. package/worker/src/RTC/RTP/Packet.cpp +3 -1
  471. package/worker/src/RTC/RTP/ProbationGenerator.cpp +4 -4
  472. package/worker/src/RTC/RTP/RetransmissionBuffer.cpp +1 -1
  473. package/worker/src/RTC/RTP/RtpStream.cpp +17 -10
  474. package/worker/src/RTC/RTP/RtpStreamRecv.cpp +16 -14
  475. package/worker/src/RTC/RTP/RtpStreamSend.cpp +12 -9
  476. package/worker/src/RTC/RTP/RtxStream.cpp +7 -7
  477. package/worker/src/RTC/RTP/SharedPacket.cpp +3 -3
  478. package/worker/src/RTC/RateCalculator.cpp +1 -2
  479. package/worker/src/RTC/Router.cpp +61 -38
  480. package/worker/src/RTC/RtpDictionaries/RtpCodecMimeType.cpp +1 -1
  481. package/worker/src/RTC/RtpObserver.cpp +2 -1
  482. package/worker/src/RTC/SCTP/LICENSE +44 -0
  483. package/worker/src/RTC/SCTP/association/Association.cpp +417 -411
  484. package/worker/src/RTC/SCTP/association/AssociationListenerDeferrer.cpp +46 -13
  485. package/worker/src/RTC/SCTP/association/HeartbeatHandler.cpp +47 -43
  486. package/worker/src/RTC/SCTP/association/PacketSender.cpp +8 -8
  487. package/worker/src/RTC/SCTP/association/StreamResetHandler.cpp +113 -101
  488. package/worker/src/RTC/SCTP/association/TransmissionControlBlock.cpp +291 -62
  489. package/worker/src/RTC/SCTP/packet/Chunk.cpp +5 -1
  490. package/worker/src/RTC/SCTP/packet/Packet.cpp +8 -1
  491. package/worker/src/RTC/SCTP/packet/chunks/DataChunk.cpp +17 -0
  492. package/worker/src/RTC/SCTP/packet/chunks/ForwardTsnChunk.cpp +4 -4
  493. package/worker/src/RTC/SCTP/packet/chunks/IDataChunk.cpp +25 -0
  494. package/worker/src/RTC/SCTP/packet/chunks/IForwardTsnChunk.cpp +10 -7
  495. package/worker/src/RTC/SCTP/packet/chunks/SackChunk.cpp +21 -4
  496. package/worker/src/RTC/SCTP/packet/chunks/ShutdownCompleteChunk.cpp +1 -1
  497. package/worker/src/RTC/SCTP/packet/errorCauses/NoUserDataErrorCause.cpp +1 -1
  498. package/worker/src/RTC/SCTP/packet/errorCauses/ProtocolViolationErrorCause.cpp +2 -2
  499. package/worker/src/RTC/SCTP/packet/errorCauses/UserInitiatedAbortErrorCause.cpp +1 -1
  500. package/worker/src/RTC/SCTP/public/Message.cpp +8 -0
  501. package/worker/src/RTC/SCTP/public/SctpOptions.cpp +90 -0
  502. package/worker/src/RTC/SCTP/rx/DataTracker.cpp +471 -0
  503. package/worker/src/RTC/SCTP/rx/InterleavedReassemblyStreams.cpp +327 -0
  504. package/worker/src/RTC/SCTP/rx/ReassemblyQueue.cpp +288 -0
  505. package/worker/src/RTC/SCTP/rx/TraditionalReassemblyStreams.cpp +453 -0
  506. package/worker/src/RTC/SCTP/tx/OutstandingData.cpp +912 -0
  507. package/worker/src/RTC/SCTP/tx/RetransmissionQueue.cpp +786 -0
  508. package/worker/src/RTC/SCTP/tx/RetransmissionTimeout.cpp +2 -2
  509. package/worker/src/RTC/SCTP/tx/RoundRobinSendQueue.cpp +752 -0
  510. package/worker/src/RTC/SCTP/tx/StreamScheduler.cpp +257 -0
  511. package/worker/src/RTC/SenderBandwidthEstimator.cpp +7 -5
  512. package/worker/src/RTC/SimpleConsumer.cpp +11 -11
  513. package/worker/src/RTC/SimulcastConsumer.cpp +16 -16
  514. package/worker/src/RTC/SrtpSession.cpp +1 -1
  515. package/worker/src/RTC/SvcConsumer.cpp +16 -16
  516. package/worker/src/RTC/TcpConnection.cpp +1 -1
  517. package/worker/src/RTC/Transport.cpp +497 -563
  518. package/worker/src/RTC/TransportCongestionControlClient.cpp +9 -8
  519. package/worker/src/RTC/TransportCongestionControlServer.cpp +5 -5
  520. package/worker/src/RTC/WebRtcServer.cpp +5 -4
  521. package/worker/src/RTC/WebRtcTransport.cpp +44 -39
  522. package/worker/src/Settings.cpp +9 -28
  523. package/worker/src/Shared.cpp +35 -0
  524. package/worker/src/Utils/Crypto.cpp +1 -1
  525. package/worker/src/Utils/String.cpp +1 -1
  526. package/worker/src/Worker.cpp +19 -48
  527. package/worker/src/handles/BackoffTimerHandle.cpp +34 -21
  528. package/worker/src/handles/TimerHandle.cpp +5 -4
  529. package/worker/src/handles/UdpSocketHandle.cpp +1 -1
  530. package/worker/src/lib.cpp +17 -16
  531. package/worker/subprojects/catch2.wrap +6 -6
  532. package/worker/tasks.py +1 -1
  533. package/worker/test/include/RTC/ICE/iceCommon.hpp +8 -7
  534. package/worker/test/include/RTC/RTP/rtpCommon.hpp +7 -6
  535. package/worker/test/include/RTC/SCTP/sctpCommon.hpp +16 -10
  536. package/worker/test/include/catch2Macros.hpp +31 -0
  537. package/worker/test/src/RTC/ICE/TestStunPacket.cpp +3 -3
  538. package/worker/test/src/RTC/ICE/iceCommon.cpp +2 -2
  539. package/worker/test/src/RTC/RTP/Codecs/TestVP8.cpp +1 -1
  540. package/worker/test/src/RTC/RTP/Codecs/TestVP9.cpp +1 -1
  541. package/worker/test/src/RTC/RTP/TestPacket.cpp +3 -3
  542. package/worker/test/src/RTC/RTP/TestRtpStreamRecv.cpp +16 -9
  543. package/worker/test/src/RTC/RTP/TestRtpStreamSend.cpp +38 -23
  544. package/worker/test/src/RTC/RTP/TestSharedPacket.cpp +1 -1
  545. package/worker/test/src/RTC/RTP/rtpCommon.cpp +2 -2
  546. package/worker/test/src/RTC/SCTP/association/TestHeartbeatHandler.cpp +292 -0
  547. package/worker/test/src/RTC/SCTP/association/TestNegotiatedCapabilities.cpp +1 -1
  548. package/worker/test/src/RTC/SCTP/association/TestStateCookie.cpp +1 -1
  549. package/worker/test/src/RTC/SCTP/association/TestTransmissionControlBlock.cpp +99 -0
  550. package/worker/test/src/RTC/SCTP/packet/TestChunk.cpp +1 -1
  551. package/worker/test/src/RTC/SCTP/packet/TestPacket.cpp +1 -1
  552. package/worker/test/src/RTC/SCTP/packet/chunks/TestAbortAssociationChunk.cpp +1 -1
  553. package/worker/test/src/RTC/SCTP/packet/chunks/TestCookieAckChunk.cpp +1 -1
  554. package/worker/test/src/RTC/SCTP/packet/chunks/TestCookieEchoChunk.cpp +1 -1
  555. package/worker/test/src/RTC/SCTP/packet/chunks/TestDataChunk.cpp +77 -7
  556. package/worker/test/src/RTC/SCTP/packet/chunks/TestForwardTsnChunk.cpp +35 -26
  557. package/worker/test/src/RTC/SCTP/packet/chunks/TestHeartbeatAckChunk.cpp +1 -1
  558. package/worker/test/src/RTC/SCTP/packet/chunks/TestHeartbeatRequestChunk.cpp +1 -1
  559. package/worker/test/src/RTC/SCTP/packet/chunks/TestIDataChunk.cpp +77 -7
  560. package/worker/test/src/RTC/SCTP/packet/chunks/TestIForwardTsnChunk.cpp +59 -27
  561. package/worker/test/src/RTC/SCTP/packet/chunks/TestInitAckChunk.cpp +1 -1
  562. package/worker/test/src/RTC/SCTP/packet/chunks/TestInitChunk.cpp +1 -1
  563. package/worker/test/src/RTC/SCTP/packet/chunks/TestOperationErrorChunk.cpp +1 -1
  564. package/worker/test/src/RTC/SCTP/packet/chunks/TestReConfigChunk.cpp +1 -1
  565. package/worker/test/src/RTC/SCTP/packet/chunks/TestSackChunk.cpp +73 -35
  566. package/worker/test/src/RTC/SCTP/packet/chunks/TestShutdownAckChunk.cpp +1 -1
  567. package/worker/test/src/RTC/SCTP/packet/chunks/TestShutdownChunk.cpp +1 -1
  568. package/worker/test/src/RTC/SCTP/packet/chunks/TestShutdownCompleteChunk.cpp +1 -1
  569. package/worker/test/src/RTC/SCTP/packet/chunks/TestUnknownChunk.cpp +1 -1
  570. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestCookieReceivedWhileShuttingDownErrorCause.cpp +1 -1
  571. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestInvalidMandatoryParameterErrorCause.cpp +1 -1
  572. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestInvalidStreamIdentifierErrorCause.cpp +1 -1
  573. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestMissingMandatoryParameterErrorCause.cpp +1 -1
  574. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestNoUserDataErrorCause.cpp +1 -1
  575. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestOutOfResourceErrorCause.cpp +1 -1
  576. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestProtocolViolationErrorCause.cpp +1 -1
  577. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestRestartOfAnAssociationWithNewAddressesErrorCause.cpp +1 -1
  578. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestStaleCookieErrorCause.cpp +1 -1
  579. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestUnknownErrorCause.cpp +1 -1
  580. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestUnrecognizedChunkTypeErrorCause.cpp +1 -1
  581. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestUnrecognizedParametersErrorCause.cpp +1 -1
  582. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestUnresolvableAddressErrorCause.cpp +1 -1
  583. package/worker/test/src/RTC/SCTP/packet/errorCauses/TestUserInitiatedAbortErrorCause.cpp +1 -1
  584. package/worker/test/src/RTC/SCTP/packet/parameters/TestAddIncomingStreamsRequestParameter.cpp +1 -1
  585. package/worker/test/src/RTC/SCTP/packet/parameters/TestAddOutgoingStreamsRequestParameter.cpp +1 -1
  586. package/worker/test/src/RTC/SCTP/packet/parameters/TestCookiePreservativeParameter.cpp +1 -1
  587. package/worker/test/src/RTC/SCTP/packet/parameters/TestForwardTsnSupportedParameter.cpp +1 -1
  588. package/worker/test/src/RTC/SCTP/packet/parameters/TestHeartbeatInfoParameter.cpp +1 -1
  589. package/worker/test/src/RTC/SCTP/packet/parameters/TestIPv4AddressParameter.cpp +1 -1
  590. package/worker/test/src/RTC/SCTP/packet/parameters/TestIPv6AddressParameter.cpp +1 -1
  591. package/worker/test/src/RTC/SCTP/packet/parameters/TestIncomingSsnResetRequestParameter.cpp +1 -1
  592. package/worker/test/src/RTC/SCTP/packet/parameters/TestOutgoingSsnResetRequestParameter.cpp +1 -1
  593. package/worker/test/src/RTC/SCTP/packet/parameters/TestReconfigurationResponseParameter.cpp +1 -1
  594. package/worker/test/src/RTC/SCTP/packet/parameters/TestSsnTsnResetRequestParameter.cpp +1 -1
  595. package/worker/test/src/RTC/SCTP/packet/parameters/TestStateCookieParameter.cpp +1 -1
  596. package/worker/test/src/RTC/SCTP/packet/parameters/TestSupportedAddressTypesParameter.cpp +1 -1
  597. package/worker/test/src/RTC/SCTP/packet/parameters/TestSupportedExtensionsParameter.cpp +1 -1
  598. package/worker/test/src/RTC/SCTP/packet/parameters/TestUnknownParameter.cpp +1 -1
  599. package/worker/test/src/RTC/SCTP/packet/parameters/TestUnrecognizedParameterParameter.cpp +1 -1
  600. package/worker/test/src/RTC/SCTP/packet/parameters/TestZeroChecksumAcceptableParameter.cpp +1 -1
  601. package/worker/test/src/RTC/SCTP/rx/TestDataTracker.cpp +1117 -0
  602. package/worker/test/src/RTC/SCTP/rx/TestInterleavedReassemblyStreams.cpp +565 -0
  603. package/worker/test/src/RTC/SCTP/rx/TestReassemblyQueue.cpp +557 -0
  604. package/worker/test/src/RTC/SCTP/rx/TestTraditionalReassemblyStreams.cpp +555 -0
  605. package/worker/test/src/RTC/SCTP/sctpCommon.cpp +2 -2
  606. package/worker/test/src/RTC/SCTP/tx/TestOutstandingData.cpp +1248 -0
  607. package/worker/test/src/RTC/SCTP/tx/TestRetransmissionErrorCounter.cpp +4 -0
  608. package/worker/test/src/RTC/SCTP/tx/TestRetransmissionQueue.cpp +2218 -0
  609. package/worker/test/src/RTC/SCTP/tx/TestRetransmissionTimeout.cpp +33 -33
  610. package/worker/test/src/RTC/SCTP/tx/TestRoundRobinSendQueue.cpp +1130 -0
  611. package/worker/test/src/RTC/SCTP/tx/TestStreamScheduler.cpp +721 -0
  612. package/worker/test/src/RTC/TestKeyFrameRequestManager.cpp +20 -30
  613. package/worker/test/src/RTC/TestNackGenerator.cpp +11 -8
  614. package/worker/test/src/RTC/TestRateCalculator.cpp +6 -7
  615. package/worker/test/src/RTC/TestSimpleConsumer.cpp +11 -11
  616. package/worker/test/src/RTC/TestTransportCongestionControlServer.cpp +15 -3
  617. package/worker/test/src/Utils/TestByte.cpp +98 -0
  618. package/worker/test/src/{RTC/SCTP/common → Utils}/TestUnwrappedSequenceNumber.cpp +2 -2
  619. package/worker/test/src/testHelpers.cpp +1 -1
  620. package/worker/test/src/tests.cpp +0 -12
  621. package/node/lib/fbs/consumer/degrade-request.d.ts +0 -30
  622. package/node/lib/fbs/consumer/degrade-request.d.ts.map +0 -1
  623. package/node/lib/fbs/consumer/degrade-request.js +0 -91
  624. package/node/lib/fbs/consumer/enable-delay-and-loss-request.d.ts +0 -24
  625. package/node/lib/fbs/consumer/enable-delay-and-loss-request.d.ts.map +0 -1
  626. package/node/lib/fbs/consumer/enable-delay-and-loss-request.js +0 -69
  627. package/node/lib/fbs/producer/degrade-request.d.ts +0 -30
  628. package/node/lib/fbs/producer/degrade-request.d.ts.map +0 -1
  629. package/node/lib/fbs/producer/degrade-request.js +0 -91
  630. package/node/lib/fbs/worker/close-notification.d.ts +0 -18
  631. package/node/lib/fbs/worker/close-notification.d.ts.map +0 -1
  632. package/node/lib/fbs/worker/close-notification.js +0 -45
  633. package/node/lib/fbs/worker/close-request.d.ts +0 -18
  634. package/node/lib/fbs/worker/close-request.d.ts.map +0 -1
  635. package/node/lib/fbs/worker/close-request.js +0 -45
  636. package/node/lib/fbs/worker/close-worker-notification.d.ts +0 -18
  637. package/node/lib/fbs/worker/close-worker-notification.d.ts.map +0 -1
  638. package/node/lib/fbs/worker/close-worker-notification.js +0 -45
  639. package/worker/include/ChannelMessageRegistrator.hpp +0 -30
  640. package/worker/include/DepUsrSCTP.hpp +0 -48
  641. package/worker/include/RTC/SCTP/TODO_SCTP.md +0 -43
  642. package/worker/include/RTC/SCTP/common/UnwrappedSequenceNumber.hpp +0 -274
  643. package/worker/include/RTC/SctpAssociation.hpp +0 -147
  644. package/worker/include/RTC/Shared.hpp +0 -23
  645. package/worker/src/ChannelMessageRegistrator.cpp +0 -119
  646. package/worker/src/DepUsrSCTP.cpp +0 -277
  647. package/worker/src/RTC/SctpAssociation.cpp +0 -1175
  648. package/worker/src/RTC/Shared.cpp +0 -23
  649. package/worker/subprojects/usrsctp.wrap +0 -8
@@ -1,12 +1,8 @@
1
1
  #define MS_CLASS "RTC::SCTP::Association"
2
- // TODO: SCTP: COMMENT
3
- #define MS_LOG_DEV_LEVEL 3
2
+ // #define MS_LOG_DEV_LEVEL 3
4
3
 
5
4
  #include "RTC/SCTP/association/Association.hpp"
6
- #include "DepLibUV.hpp"
7
5
  #include "Logger.hpp"
8
- #include "Utils.hpp"
9
- #include "RTC/Consts.hpp"
10
6
  #include "RTC/SCTP/packet/errorCauses/CookieReceivedWhileShuttingDownErrorCause.hpp"
11
7
  #include "RTC/SCTP/packet/errorCauses/NoUserDataErrorCause.hpp"
12
8
  #include "RTC/SCTP/packet/errorCauses/OutOfResourceErrorCause.hpp"
@@ -17,6 +13,7 @@
17
13
  #include "RTC/SCTP/packet/parameters/StateCookieParameter.hpp"
18
14
  #include "RTC/SCTP/packet/parameters/SupportedExtensionsParameter.hpp"
19
15
  #include "RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp"
16
+ #include "Utils.hpp"
20
17
  #include <limits> // std::numeric_limits()
21
18
  #include <sstream> // std::ostringstream
22
19
  #include <string>
@@ -28,7 +25,7 @@ namespace RTC
28
25
  {
29
26
  /* Static. */
30
27
 
31
- alignas(4) thread_local static uint8_t PacketFactoryBuffer[RTC::Consts::MaxSafeMtuSizeForSctp];
28
+ alignas(4) static thread_local uint8_t PacketFactoryBuffer[65536];
32
29
  // @see https://tools.ietf.org/html/rfc9260#section-5.1
33
30
  constexpr uint32_t MinVerificationTag{ 1 };
34
31
  constexpr uint32_t MaxVerificationTag{ std::numeric_limits<uint32_t>::max() };
@@ -39,33 +36,49 @@ namespace RTC
39
36
 
40
37
  /* Instance methods. */
41
38
 
42
- Association::Association(const SctpOptions& sctpOptions, AssociationListener* listener)
39
+ Association::Association(
40
+ const SctpOptions& sctpOptions,
41
+ AssociationListenerInterface* listener,
42
+ SharedInterface* shared,
43
+ bool isDataChannel)
43
44
  : sctpOptions(sctpOptions),
44
45
  // Our `listener` member is a `AssociationListenerDeferrer` which takes
45
- // `AssociationListener` as constructor argument.
46
- listener(listener),
47
- packetSender(this, this->listener),
48
- t1InitTimer(
49
- std::make_unique<BackoffTimerHandle>(
50
- /*listener*/ this,
51
- /*baseTimeoutMs*/ sctpOptions.t1InitTimeoutMs,
52
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::EXPONENTIAL,
53
- /*maxBackoffTimeoutMs*/ sctpOptions.timerMaxBackoffTimeoutMs,
54
- /*maxRestarts*/ sctpOptions.maxInitRetransmissions)),
55
- t1CookieTimer(
56
- std::make_unique<BackoffTimerHandle>(
57
- /*listener*/ this,
58
- /*baseTimeoutMs*/ sctpOptions.t1CookieTimeoutMs,
59
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::EXPONENTIAL,
60
- /*maxBackoffTimeoutMs*/ sctpOptions.timerMaxBackoffTimeoutMs,
61
- /*maxRestarts*/ sctpOptions.maxInitRetransmissions)),
62
- t2ShutdownTimer(
63
- std::make_unique<BackoffTimerHandle>(
64
- /*listener*/ this,
65
- /*baseTimeoutMs*/ sctpOptions.t2ShutdownTimeoutMs,
66
- /*backoffAlgorithm*/ BackoffTimerHandle::BackoffAlgorithm::EXPONENTIAL,
67
- /*maxBackoffTimeoutMs*/ sctpOptions.timerMaxBackoffTimeoutMs,
68
- /*maxRestarts*/ sctpOptions.maxRetransmissions))
46
+ // `listener` argument as constructor argument.
47
+ associationListenerDeferrer(listener),
48
+ shared(shared),
49
+ packetSender(this, this->associationListenerDeferrer),
50
+ sendQueue(
51
+ this->associationListenerDeferrer,
52
+ sctpOptions.mtu,
53
+ sctpOptions.defaultStreamPriority,
54
+ sctpOptions.totalBufferedAmountLowThreshold),
55
+ t1InitTimer(this->shared->CreateBackoffTimer(
56
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
57
+ .listener = this,
58
+ .label = "sctp-t1-init",
59
+ .baseTimeoutMs = sctpOptions.t1InitTimeoutMs,
60
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::EXPONENTIAL,
61
+ .maxBackoffTimeoutMs = sctpOptions.timerMaxBackoffTimeoutMs,
62
+ .maxRestarts = sctpOptions.maxInitRetransmissions,
63
+ })),
64
+ t1CookieTimer(this->shared->CreateBackoffTimer(
65
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
66
+ .listener = this,
67
+ .label = "sctp-t1-cookie",
68
+ .baseTimeoutMs = sctpOptions.t1CookieTimeoutMs,
69
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::EXPONENTIAL,
70
+ .maxBackoffTimeoutMs = sctpOptions.timerMaxBackoffTimeoutMs,
71
+ .maxRestarts = sctpOptions.maxInitRetransmissions })),
72
+ t2ShutdownTimer(this->shared->CreateBackoffTimer(
73
+ BackoffTimerHandleInterface::BackoffTimerHandleOptions{
74
+ .listener = this,
75
+ .label = "sctp-t2-shutdown",
76
+ .baseTimeoutMs = sctpOptions.t2ShutdownTimeoutMs,
77
+ .backoffAlgorithm = BackoffTimerHandleInterface::BackoffAlgorithm::EXPONENTIAL,
78
+ .maxBackoffTimeoutMs = sctpOptions.timerMaxBackoffTimeoutMs,
79
+ .maxRestarts = sctpOptions.maxRetransmissions })),
80
+ maxPacketLength(Utils::Byte::PadDownTo4Bytes(this->sctpOptions.mtu)),
81
+ isDataChannel(isDataChannel)
69
82
  {
70
83
  MS_TRACE();
71
84
  }
@@ -92,12 +105,14 @@ namespace RTC
92
105
  static_cast<int>(stateStringView.size()),
93
106
  stateStringView.data());
94
107
 
108
+ this->sctpOptions.Dump();
109
+
95
110
  if (this->tcb)
96
111
  {
97
112
  this->tcb->Dump(indentation + 1);
98
113
  }
99
114
 
100
- const auto metrics = GetMetrics();
115
+ const auto metrics = MakeMetrics();
101
116
 
102
117
  if (metrics.has_value())
103
118
  {
@@ -114,26 +129,13 @@ namespace RTC
114
129
 
115
130
  return FBS::SctpParameters::CreateSctpParameters(
116
131
  builder,
117
- // Add port.
118
- this->sctpOptions.sourcePort,
119
- // Add OS.
120
- // TODO: SCTP: We should put here current value which may be different after
121
- // negotiation with peer and reconfig.
122
- this->sctpOptions.announcedMaxOutboundStreams,
123
- // Add MIS.
124
- // TODO: SCTP: We should put here current value which may be different after
125
- // negotiation with peer and reconfig.
126
- this->sctpOptions.announcedMaxInboundStreams,
127
- // Add maxMessageSize.
128
- this->sctpOptions.maxSendMessageSize,
129
- // Add sendBufferSize.
130
- this->sctpOptions.maxSendBufferSize,
131
- // Add sctpBufferedAmountLowThreshold.
132
- this->sctpOptions.totalBufferedAmountLowThreshold,
133
- // Add isDataChannel.
134
- // TODO: SCTP: Have a member for this.
135
- // TODO: SCTP: So remove this hardcoded `true`.
136
- /*isDataChannel*/ true);
132
+ /*port*/ this->sctpOptions.sourcePort,
133
+ /*maxSendMessageSize*/ this->sctpOptions.maxSendMessageSize,
134
+ /*maxReceiveMessageSize*/ this->sctpOptions.maxReceiveMessageSize,
135
+ /*sctpSendBufferSize*/ this->sctpOptions.maxSendBufferSize,
136
+ /*sctpPerStreamSendQueueLimit*/ this->sctpOptions.perStreamSendQueueLimit,
137
+ /*sctpMaxReceiverWindowBufferSize*/ this->sctpOptions.maxReceiverWindowBufferSize,
138
+ /*isDataChannel*/ this->isDataChannel);
137
139
  }
138
140
 
139
141
  Types::AssociationState Association::GetAssociationState() const
@@ -191,7 +193,7 @@ namespace RTC
191
193
 
192
194
  // If we haven't received any SCTP packet yet and the transport is not
193
195
  // ready for SCTP traffic, don't do anything.
194
- if (this->privateMetrics.rxPacketsCount == 0 && !this->listener.OnAssociationIsTransportReadyForSctp())
196
+ if (this->privateMetrics.rxPacketsCount == 0 && !this->associationListenerDeferrer.OnAssociationIsTransportReadyForSctp())
195
197
  {
196
198
  MS_DEBUG_DEV(
197
199
  "no SCTP data has been received yet and transport is not ready for SCTP traffic, ignoring");
@@ -223,7 +225,7 @@ namespace RTC
223
225
  return;
224
226
  }
225
227
 
226
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
228
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
227
229
 
228
230
  this->preTcb.localVerificationTag =
229
231
  Utils::Crypto::GetRandomUInt<uint32_t>(MinVerificationTag, MaxVerificationTag);
@@ -236,9 +238,9 @@ namespace RTC
236
238
 
237
239
  SetState(State::COOKIE_WAIT, "Connect() called");
238
240
 
239
- AssertStateIsConsistent();
241
+ AssertIsConsistent();
240
242
 
241
- this->listener.OnAssociationConnecting();
243
+ this->associationListenerDeferrer.OnAssociationConnecting();
242
244
  }
243
245
 
244
246
  void Association::Shutdown()
@@ -247,12 +249,12 @@ namespace RTC
247
249
 
248
250
  if (this->state == State::NEW || this->state == State::CLOSED)
249
251
  {
250
- AssertStateIsConsistent();
252
+ AssertIsConsistent();
251
253
 
252
254
  return;
253
255
  }
254
256
 
255
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
257
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
256
258
 
257
259
  // https://datatracker.ietf.org/doc/html/rfc9260#section-9.2
258
260
  //
@@ -287,7 +289,7 @@ namespace RTC
287
289
  InternalClose(Types::ErrorKind::SUCCESS, "");
288
290
  }
289
291
 
290
- AssertStateIsConsistent();
292
+ AssertIsConsistent();
291
293
  }
292
294
 
293
295
  void Association::Close()
@@ -296,12 +298,12 @@ namespace RTC
296
298
 
297
299
  if (this->state == State::NEW || this->state == State::CLOSED)
298
300
  {
299
- AssertStateIsConsistent();
301
+ AssertIsConsistent();
300
302
 
301
303
  return;
302
304
  }
303
305
 
304
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
306
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
305
307
 
306
308
  if (this->tcb)
307
309
  {
@@ -323,33 +325,33 @@ namespace RTC
323
325
  }
324
326
 
325
327
  InternalClose(Types::ErrorKind::SUCCESS, "");
326
- AssertStateIsConsistent();
328
+
329
+ AssertIsConsistent();
327
330
  }
328
331
 
329
- std::optional<AssociationMetrics> Association::GetMetrics() const
332
+ std::optional<AssociationMetrics> Association::MakeMetrics() const
330
333
  {
331
334
  if (!this->tcb)
332
335
  {
333
336
  return std::nullopt;
334
337
  }
335
338
 
336
- // const size_t packetPayloadLength =
337
- // this->sctpOptions.mtu - Packet::CommonHeaderLength - DataChunk::DataChunkHeaderLength;
339
+ const size_t packetPayloadLength =
340
+ this->sctpOptions.mtu - Packet::CommonHeaderLength - DataChunk::DataChunkHeaderLength;
338
341
 
339
- // TODO: SCTP: Implement missing fields.
340
342
  AssociationMetrics metrics{
341
343
  .txPacketsCount = this->privateMetrics.txPacketsCount,
342
344
  .txMessagesCount = this->privateMetrics.txMessagesCount,
343
345
  .rxPacketsCount = this->privateMetrics.rxPacketsCount,
344
346
  .rxMessagesCount = this->privateMetrics.rxMessagesCount,
345
- // .rtxPacketsCount = this->tcb->GetRetransmissionQueue().GetRtxPacketsCount(),
346
- // .rtxBytesCount = this->tcb->GetRetransmissionQueue().GetRtxBytesCount(),
347
- // .cwndBytes = this->tcb->GetCwnd(),
348
- .srttMs = this->tcb->GetCurrentSrttMs(),
349
- // .unackDataCount =
350
- // this->tcb->GetRetransmissionQueue().GetUnackedItems() +
351
- // (this->sendQueue.GetTotalBufferedAmount() + packetPayloadLength - 1) / packetPayloadLength,
352
- // .peerRwndBytes = this->tcb->GetRetransmissionQueue().GetRwnd(),
347
+ .rtxPacketsCount = this->tcb->GetRetransmissionQueue().GetRtxPacketsCount(),
348
+ .rtxBytesCount = this->tcb->GetRetransmissionQueue().GetRtxBytesCount(),
349
+ .cwndBytes = this->tcb->GetCwnd(),
350
+ .srttMs = this->tcb->GetCurrentSrttMs(),
351
+ .unackDataCount = this->tcb->GetRetransmissionQueue().GetUnackedItems() +
352
+ ((this->sendQueue.GetTotalBufferedAmount() + packetPayloadLength - 1) /
353
+ packetPayloadLength),
354
+ .peerRwndBytes = static_cast<uint32_t>(this->tcb->GetRetransmissionQueue().GetRwnd()),
353
355
  .peerImplementation = this->privateMetrics.peerImplementation,
354
356
  .negotiatedMaxOutboundStreams = this->privateMetrics.negotiatedMaxOutboundStreams,
355
357
  .negotiatedMaxInboundStreams = this->privateMetrics.negotiatedMaxInboundStreams,
@@ -363,23 +365,18 @@ namespace RTC
363
365
  return metrics;
364
366
  }
365
367
 
366
- uint16_t Association::GetStreamPriority(uint16_t /*streamId*/) const
368
+ uint16_t Association::GetStreamPriority(uint16_t streamId) const
367
369
  {
368
370
  MS_TRACE();
369
371
 
370
- // TODO: SCTP: Implement it.
371
- // return this->sendQueue.GetStreamPriority(streamId);
372
-
373
- // TODO: SCTP: Remove.
374
- return 0;
372
+ return this->sendQueue.GetStreamPriority(streamId);
375
373
  }
376
374
 
377
- void Association::SetStreamPriority(uint16_t /*streamId*/, uint16_t /*priority*/)
375
+ void Association::SetStreamPriority(uint16_t streamId, uint16_t priority)
378
376
  {
379
377
  MS_TRACE();
380
378
 
381
- // TODO: SCTP: Implement it.
382
- // this->sendQueue.SetStreamPriority(streamId, priority);
379
+ this->sendQueue.SetStreamPriority(streamId, priority);
383
380
  }
384
381
 
385
382
  void Association::SetMaxSendMessageSize(size_t maxMessageSize)
@@ -389,45 +386,43 @@ namespace RTC
389
386
  this->sctpOptions.maxSendMessageSize = maxMessageSize;
390
387
  }
391
388
 
392
- size_t Association::GetStreamBufferedAmount(uint16_t /*streamId*/) const
389
+ size_t Association::GetTotalBufferedAmount() const
393
390
  {
394
391
  MS_TRACE();
395
392
 
396
- // TODO: SCTP: Implement it.
397
- // return this->sendQueue.GetStreamBufferedAmount(streamId);
398
-
399
- // TODO: SCTP: Remove.
400
- return 0;
393
+ return this->sendQueue.GetTotalBufferedAmount();
401
394
  }
402
395
 
403
- size_t Association::GetStreamBufferedAmountLowThreshold(uint16_t /*streamId*/) const
396
+ size_t Association::GetStreamBufferedAmount(uint16_t streamId) const
404
397
  {
405
398
  MS_TRACE();
406
399
 
407
- // TODO: SCTP: Implement it.
408
- // return this->sendQueue.GetStreamBufferedAmountLowThreshold(streamId);
400
+ return this->sendQueue.GetStreamBufferedAmount(streamId);
401
+ }
402
+
403
+ size_t Association::GetStreamBufferedAmountLowThreshold(uint16_t streamId) const
404
+ {
405
+ MS_TRACE();
409
406
 
410
- // TODO: SCTP: Remove.
411
- return 0;
407
+ return this->sendQueue.GetStreamBufferedAmountLowThreshold(streamId);
412
408
  }
413
409
 
414
- void Association::SetBufferedAmountLowThreshold(uint16_t /*streamId*/, size_t /*bytes*/)
410
+ void Association::SetStreamBufferedAmountLowThreshold(uint16_t streamId, size_t bytes)
415
411
  {
416
412
  MS_TRACE();
417
413
 
418
- // TODO: SCTP: Implement it.
419
- // this->sendQueue.SetBufferedAmountLowThreshold(streamId, bytes);
414
+ this->sendQueue.SetStreamBufferedAmountLowThreshold(streamId, bytes);
420
415
  }
421
416
 
422
- Types::ResetStreamsStatus Association::ResetStreams(std::span<const uint16_t> /*outboundStreamIds*/)
417
+ Types::ResetStreamsStatus Association::ResetStreams(std::span<const uint16_t> outboundStreamIds)
423
418
  {
424
419
  MS_TRACE();
425
420
 
426
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
421
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
427
422
 
428
423
  if (!this->tcb)
429
424
  {
430
- this->listener.OnAssociationError(
425
+ this->associationListenerDeferrer.OnAssociationError(
431
426
  Types::ErrorKind::WRONG_SEQUENCE,
432
427
  "cannot reset outbound streams as the association is not connected");
433
428
 
@@ -436,18 +431,18 @@ namespace RTC
436
431
 
437
432
  if (!this->tcb->GetNegotiatedCapabilities().reConfig)
438
433
  {
439
- this->listener.OnAssociationError(
434
+ this->associationListenerDeferrer.OnAssociationError(
440
435
  Types::ErrorKind::UNSUPPORTED_OPERATION,
441
436
  "cannot reset outbound streams as the remote doesn't support it");
442
437
 
443
438
  return Types::ResetStreamsStatus::NOT_SUPPORTED;
444
439
  }
445
440
 
446
- // TODO: SCTP: Implement it.
447
- // this->tcb->GetStreamResetHandler().ResetStreams(outboundStreamIds);
441
+ this->tcb->GetStreamResetHandler().ResetStreams(outboundStreamIds);
448
442
 
449
443
  MaySendResetStreamsRequest();
450
- AssertStateIsConsistent();
444
+
445
+ AssertIsConsistent();
451
446
 
452
447
  return Types::ResetStreamsStatus::PERFORMED;
453
448
  }
@@ -457,30 +452,27 @@ namespace RTC
457
452
  {
458
453
  MS_TRACE();
459
454
 
460
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
455
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
461
456
 
462
- const auto status = InternalSendMessage(message, sendMessageOptions);
457
+ const auto status = InternalSendMessageCheck(message, sendMessageOptions);
463
458
 
464
459
  if (status != Types::SendMessageStatus::SUCCESS)
465
460
  {
466
461
  return status;
467
462
  }
468
463
 
469
- // TODO: SCTP: Uncomment.
470
- // const uint64_t now = DepLibUV::GetTimeMs();
464
+ const uint64_t nowMs = this->shared->GetTimeMs();
471
465
 
472
466
  this->privateMetrics.txMessagesCount++;
473
467
 
474
- // TODO: SCTP: Implement it.
475
- // this->sendQueue.AddMessage(now, std::move(message), sendMessageOptions);
468
+ this->sendQueue.AddMessage(nowMs, std::move(message), sendMessageOptions);
476
469
 
477
470
  if (this->tcb)
478
471
  {
479
- // TODO: SCTP: Implement it.
480
- // this->tcb->SendBufferedPackets(now);
472
+ this->tcb->SendBufferedPackets(nowMs);
481
473
  }
482
474
 
483
- AssertStateIsConsistent();
475
+ AssertIsConsistent();
484
476
 
485
477
  return Types::SendMessageStatus::SUCCESS;
486
478
  }
@@ -490,17 +482,17 @@ namespace RTC
490
482
  {
491
483
  MS_TRACE();
492
484
 
493
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
485
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
486
+
487
+ const uint64_t nowMs = this->shared->GetTimeMs();
494
488
 
495
- // TODO: SCTP: Uncomment.
496
- // const uint64_t now = DepLibUV::GetTimeMs();
497
489
  std::vector<Types::SendMessageStatus> statuses;
498
490
 
499
491
  statuses.reserve(messages.size());
500
492
 
501
- for (const auto& message : messages)
493
+ for (auto& message : messages)
502
494
  {
503
- const auto status = InternalSendMessage(message, sendMessageOptions);
495
+ const auto status = InternalSendMessageCheck(message, sendMessageOptions);
504
496
 
505
497
  statuses.push_back(status);
506
498
 
@@ -511,17 +503,15 @@ namespace RTC
511
503
 
512
504
  this->privateMetrics.txMessagesCount++;
513
505
 
514
- // TODO: SCTP: Implement it.
515
- // this->sendQueue.AddMessage(now, std::move(message), sendMessageOptions);
506
+ this->sendQueue.AddMessage(nowMs, std::move(message), sendMessageOptions);
516
507
  }
517
508
 
518
509
  if (this->tcb)
519
510
  {
520
- // TODO: SCTP: Implement it.
521
- // this->tcb->SendBufferedPackets(now);
511
+ this->tcb->SendBufferedPackets(nowMs);
522
512
  }
523
513
 
524
- AssertStateIsConsistent();
514
+ AssertIsConsistent();
525
515
 
526
516
  return statuses;
527
517
  }
@@ -530,23 +520,23 @@ namespace RTC
530
520
  {
531
521
  MS_TRACE();
532
522
 
533
- // TODO: SCTP: For testing purposes. Must be removed.
523
+ // For debugging purposes.
524
+ #if MS_LOG_DEV_LEVEL == 3
525
+ const auto* packet = RTC::SCTP::Packet::Parse(data, len);
526
+
527
+ if (packet)
534
528
  {
535
529
  MS_DUMP("<<< received SCTP packet:");
536
530
 
537
- const auto* packet = RTC::SCTP::Packet::Parse(data, len);
538
-
539
- if (packet)
540
- {
541
- packet->Dump();
531
+ packet->Dump();
542
532
 
543
- delete packet;
544
- }
545
- else
546
- {
547
- MS_ABORT("RTC::SCTP::Packet::Parse() failed to parse received SCTP data");
548
- }
533
+ delete packet;
549
534
  }
535
+ else
536
+ {
537
+ MS_ERROR("RTC::SCTP::Packet::Parse() failed to parse received SCTP data");
538
+ }
539
+ #endif
550
540
 
551
541
  this->privateMetrics.rxPacketsCount++;
552
542
 
@@ -557,7 +547,7 @@ namespace RTC
557
547
  // NOTE: It's important to create the deferrer here, otherwise it may
558
548
  // happen that MayConnect() ends calling to Connect() so we end with two
559
549
  // nested deferreds (and hence an assertion).
560
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
550
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
561
551
 
562
552
  std::unique_ptr<Packet> receivedPacket{ Packet::Parse(data, len) };
563
553
 
@@ -565,10 +555,10 @@ namespace RTC
565
555
  {
566
556
  MS_WARN_TAG(sctp, "failed to parse received SCTP packet");
567
557
 
568
- this->listener.OnAssociationError(
558
+ this->associationListenerDeferrer.OnAssociationError(
569
559
  Types::ErrorKind::PARSE_FAILED, "failed to parse received SCTP packet");
570
560
 
571
- AssertStateIsConsistent();
561
+ AssertIsConsistent();
572
562
 
573
563
  return;
574
564
  }
@@ -594,12 +584,47 @@ namespace RTC
594
584
 
595
585
  if (this->tcb)
596
586
  {
597
- // TODO: SCTP: Implement it.
598
- // this->tcb->GetDadaTracker().ObservePacketEnd();
587
+ this->tcb->GetDataTracker().ObservePacketEnd();
599
588
  this->tcb->MaySendSackChunk();
600
589
  }
601
590
 
602
- AssertStateIsConsistent();
591
+ AssertIsConsistent();
592
+ }
593
+
594
+ uint16_t Association::GetNegotiatedMaxOutboundStreams() const
595
+ {
596
+ MS_TRACE();
597
+
598
+ if (this->tcb)
599
+ {
600
+ return this->tcb->GetNegotiatedCapabilities().negotiatedMaxOutboundStreams;
601
+ }
602
+ else
603
+ {
604
+ MS_WARN_TAG(
605
+ sctp,
606
+ "calling Association::GetNegotiatedMaxOutboundStreams() before TCB is created returns 0");
607
+
608
+ return 0;
609
+ }
610
+ }
611
+
612
+ uint16_t Association::GetNegotiatedMaxInboundStreams() const
613
+ {
614
+ MS_TRACE();
615
+
616
+ if (this->tcb)
617
+ {
618
+ return this->tcb->GetNegotiatedCapabilities().negotiatedMaxInboundStreams;
619
+ }
620
+ else
621
+ {
622
+ MS_WARN_TAG(
623
+ sctp,
624
+ "calling Association::GetNegotiatedMaxInboundStreams() before TCB is created returns 0");
625
+
626
+ return 0;
627
+ }
603
628
  }
604
629
 
605
630
  void Association::InternalClose(Types::ErrorKind errorKind, const std::string_view& message)
@@ -623,16 +648,16 @@ namespace RTC
623
648
  {
624
649
  if (errorKind == Types::ErrorKind::SUCCESS)
625
650
  {
626
- this->listener.OnAssociationClosed(errorKind, message);
651
+ this->associationListenerDeferrer.OnAssociationClosed(errorKind, message);
627
652
  }
628
653
  else
629
654
  {
630
- this->listener.OnAssociationFailed(errorKind, message);
655
+ this->associationListenerDeferrer.OnAssociationFailed(errorKind, message);
631
656
  }
632
657
  }
633
658
  else
634
659
  {
635
- this->listener.OnAssociationClosed(errorKind, message);
660
+ this->associationListenerDeferrer.OnAssociationClosed(errorKind, message);
636
661
  }
637
662
  }
638
663
 
@@ -724,8 +749,10 @@ namespace RTC
724
749
  MS_TRACE();
725
750
 
726
751
  this->tcb = std::make_unique<TransmissionControlBlock>(
727
- this->listener,
752
+ this->associationListenerDeferrer,
728
753
  this->sctpOptions,
754
+ this->shared,
755
+ this->sendQueue,
729
756
  this->packetSender,
730
757
  localVerificationTag,
731
758
  remoteVerificationTag,
@@ -734,6 +761,7 @@ namespace RTC
734
761
  remoteAdvertisedReceiverWindowCredit,
735
762
  tieTag,
736
763
  negotiatedCapabilities,
764
+ this->maxPacketLength,
737
765
  [this]()
738
766
  {
739
767
  return this->state == State::ESTABLISHED;
@@ -761,7 +789,7 @@ namespace RTC
761
789
  MS_TRACE();
762
790
 
763
791
  auto packet =
764
- std::unique_ptr<Packet>(Packet::Factory(PacketFactoryBuffer, sizeof(PacketFactoryBuffer)));
792
+ std::unique_ptr<Packet>{ Packet::Factory(PacketFactoryBuffer, this->maxPacketLength) };
765
793
 
766
794
  packet->SetSourcePort(this->sctpOptions.sourcePort);
767
795
  packet->SetDestinationPort(this->sctpOptions.destinationPort);
@@ -803,11 +831,10 @@ namespace RTC
803
831
 
804
832
  AssertHasTcb();
805
833
 
806
- auto packet = this->tcb->CreatePacket();
807
- const auto* shutdownChunk = packet->BuildChunkInPlace<ShutdownChunk>();
834
+ auto packet = this->tcb->CreatePacket();
835
+ auto* shutdownChunk = packet->BuildChunkInPlace<ShutdownChunk>();
808
836
 
809
- // TODO: SCTP: Implement it.
810
- // shutdownChunk->SetCumulativeTsnAck(this->tcb->GetDataTracker().GetLastCumulativeAckedTsn());
837
+ shutdownChunk->SetCumulativeTsnAck(this->tcb->GetDataTracker().GetLastCumulativeAckedTsn());
811
838
  shutdownChunk->Consolidate();
812
839
 
813
840
  this->packetSender.SendPacket(packet.get());
@@ -836,10 +863,10 @@ namespace RTC
836
863
 
837
864
  AssertHasTcb();
838
865
 
839
- // TODO: SCTP: Implement it.
840
- // if (this->tcb->GetRetransmissionQueue().GetUnackedItems() != 0) {
841
- // return;
842
- // }
866
+ if (this->tcb->GetRetransmissionQueue().GetUnackedItems() != 0)
867
+ {
868
+ return;
869
+ }
843
870
 
844
871
  // https://datatracker.ietf.org/doc/html/rfc9260#section-9.2
845
872
  //
@@ -913,37 +940,13 @@ namespace RTC
913
940
 
914
941
  AssertHasTcb();
915
942
 
916
- // TODO: SCTP: I don't like this. I don't want to use Packet::AddChunk() (which
917
- // clones the given Chunk). I want to use Packet::BuildChunkInPlace() so
918
- // we need that `tcb->GetStreamResetHandler().MakeStreamResetRequest()`
919
- // doesn't return a `ReConfigChunk` but something different such as the
920
- // Re-configuration Request Parameter(s) (OutgoingSSNResetRequestParameter):
921
- // https://datatracker.ietf.org/doc/html/rfc6525#section-8.2
922
- // Mmmm, but not even that because we also want to use
923
- // ReConfigChunk::BuildParameterInPlace() instead of AddParameter() for
924
- // same reasons... Ok, let's see.
925
- // NOTE: What about if we do some std::move() somewhere?
926
-
927
- // const auto* reConfigChunk =
928
- // this->tcb->GetStreamResetHandler().MakeStreamResetRequest();
929
- // const auto* outgoingSSNResetRequestParameter =
930
- // this->tcb->GetStreamResetHandler().MakeOutgoingSSNResetRequestParameter();
931
-
932
- // if (!outgoingSSNResetRequestParameter)
933
- // {
934
- // return;
935
- // }
936
-
937
- // auto packet = this->tcb->CreatePacket();
938
- // auto* reConfigChunk = packet->BuildChunkInPlace<ReConfigChunk>();
939
-
940
- // reConfigChunk->AddParameter(outgoingSSNResetRequestParameter);
941
-
942
- // delete outgoingSSNResetRequestParameter;
943
-
944
- // reConfigChunk->Consolidate();
943
+ if (this->tcb->GetStreamResetHandler().ShouldSendStreamResetRequest())
944
+ {
945
+ auto packet = this->tcb->CreatePacket();
945
946
 
946
- // this->packetSender.SendPacket(packet.get());
947
+ this->tcb->GetStreamResetHandler().AddStreamResetRequest(packet.get());
948
+ this->packetSender.SendPacket(packet.get());
949
+ }
947
950
  }
948
951
 
949
952
  void Association::MayDeliverMessages()
@@ -952,15 +955,26 @@ namespace RTC
952
955
 
953
956
  AssertHasTcb();
954
957
 
955
- // TODO: SCTP: Implement it.
956
- // while (std::optional<Message> message = this->tcb->GetReassemblyQueue().GetNextMessage())
957
- // {
958
- // this->privateMetrics.rxMessagesCount++;
959
- // this->listener.OnAssociationMessageReceived(*std::move(message));
960
- // }
958
+ while (std::optional<Message> message = this->tcb->GetReassemblyQueue().GetNextMessage())
959
+ {
960
+ this->privateMetrics.rxMessagesCount++;
961
+
962
+ if (message->GetPayloadLength() > this->sctpOptions.maxReceiveMessageSize)
963
+ {
964
+ MS_WARN_TAG(
965
+ sctp,
966
+ "dropping too large received message [messageByteLength:%zu, maxReceiveMessageSize:%zu]",
967
+ message->GetPayloadLength(),
968
+ this->sctpOptions.maxReceiveMessageSize);
969
+
970
+ break;
971
+ }
972
+
973
+ this->associationListenerDeferrer.OnAssociationMessageReceived(*std::move(message));
974
+ }
961
975
  }
962
976
 
963
- Types::SendMessageStatus Association::InternalSendMessage(
977
+ Types::SendMessageStatus Association::InternalSendMessageCheck(
964
978
  const Message& message, const SendMessageOptions& sendMessageOptions)
965
979
  {
966
980
  MS_TRACE();
@@ -971,10 +985,10 @@ namespace RTC
971
985
  {
972
986
  if (lifecycleId.has_value())
973
987
  {
974
- this->listener.OnAssociationLifecycleMessageEnd(lifecycleId.value());
988
+ this->associationListenerDeferrer.OnAssociationLifecycleMessageEnd(lifecycleId.value());
975
989
  }
976
990
 
977
- this->listener.OnAssociationError(
991
+ this->associationListenerDeferrer.OnAssociationError(
978
992
  Types::ErrorKind::PROTOCOL_VIOLATION, "cannot send empty message");
979
993
 
980
994
  return Types::SendMessageStatus::ERROR_MESSAGE_EMPTY;
@@ -983,10 +997,10 @@ namespace RTC
983
997
  {
984
998
  if (lifecycleId.has_value())
985
999
  {
986
- this->listener.OnAssociationLifecycleMessageEnd(lifecycleId.value());
1000
+ this->associationListenerDeferrer.OnAssociationLifecycleMessageEnd(lifecycleId.value());
987
1001
  }
988
1002
 
989
- this->listener.OnAssociationError(
1003
+ this->associationListenerDeferrer.OnAssociationError(
990
1004
  Types::ErrorKind::PROTOCOL_VIOLATION, "cannot send too large message");
991
1005
 
992
1006
  return Types::SendMessageStatus::ERROR_MESSAGE_TOO_LARGE;
@@ -1002,31 +1016,30 @@ namespace RTC
1002
1016
  {
1003
1017
  if (lifecycleId.has_value())
1004
1018
  {
1005
- this->listener.OnAssociationLifecycleMessageEnd(lifecycleId.value());
1019
+ this->associationListenerDeferrer.OnAssociationLifecycleMessageEnd(lifecycleId.value());
1006
1020
  }
1007
1021
 
1008
- this->listener.OnAssociationError(
1022
+ this->associationListenerDeferrer.OnAssociationError(
1009
1023
  Types::ErrorKind::WRONG_SEQUENCE,
1010
1024
  "cannot send message as the association is shutting down");
1011
1025
 
1012
1026
  return Types::SendMessageStatus::ERROR_SHUTTING_DOWN;
1013
1027
  }
1014
- // TODO: SCTP: Implement it.
1015
- // else if (
1016
- // this->sendQueue.GetTotalBufferedAmount() >= this->sctpOptions.maxSendBufferSize ||
1017
- // this->sendQueue.GetStreamBufferedAmount(message.GetStreamId()) >=
1018
- // this->sctpOptions.perStreamSendQueueLimit)
1019
- // {
1020
- // if (lifecycleId.has_value())
1021
- // {
1022
- // this->listener.OnAssociationLifecycleMessageEnd(lifecycleId.value());
1023
- // }
1028
+ else if (
1029
+ this->sendQueue.GetTotalBufferedAmount() >= this->sctpOptions.maxSendBufferSize ||
1030
+ this->sendQueue.GetStreamBufferedAmount(message.GetStreamId()) >=
1031
+ this->sctpOptions.perStreamSendQueueLimit)
1032
+ {
1033
+ if (lifecycleId.has_value())
1034
+ {
1035
+ this->associationListenerDeferrer.OnAssociationLifecycleMessageEnd(lifecycleId.value());
1036
+ }
1024
1037
 
1025
- // this->listener.OnAssociationError(
1026
- // Types::ErrorKind::RESOURCE_EXHAUSTION, "cannot send message as the send queue is full");
1038
+ this->associationListenerDeferrer.OnAssociationError(
1039
+ Types::ErrorKind::RESOURCE_EXHAUSTION, "cannot send message as the send queue is full");
1027
1040
 
1028
- // return Types::SendMessageStatus::ERROR_RESOURCE_EXHAUSTION;
1029
- // }
1041
+ return Types::SendMessageStatus::ERROR_RESOURCE_EXHAUSTION;
1042
+ }
1030
1043
 
1031
1044
  return Types::SendMessageStatus::SUCCESS;
1032
1045
  }
@@ -1054,7 +1067,7 @@ namespace RTC
1054
1067
  sctp,
1055
1068
  "Packet with Verification Tag 0 must have a single Chunk and it must be an INIT Chunk, packet discarded");
1056
1069
 
1057
- this->listener.OnAssociationError(
1070
+ this->associationListenerDeferrer.OnAssociationError(
1058
1071
  Types::ErrorKind::PARSE_FAILED,
1059
1072
  "packet with Verification Tag 0 must have a single chunk and it must be an INIT chunk");
1060
1073
 
@@ -1094,7 +1107,7 @@ namespace RTC
1094
1107
  "ABORT Chunk Verification Tag %" PRIu32 " is wrong, packet discarded",
1095
1108
  receivedPacket->GetVerificationTag());
1096
1109
 
1097
- this->listener.OnAssociationError(
1110
+ this->associationListenerDeferrer.OnAssociationError(
1098
1111
  Types::ErrorKind::PARSE_FAILED, "packet with ABORT chunk has invalid Verification Tag");
1099
1112
 
1100
1113
  return false;
@@ -1115,7 +1128,7 @@ namespace RTC
1115
1128
  receivedPacket->GetVerificationTag(),
1116
1129
  this->preTcb.localVerificationTag);
1117
1130
 
1118
- this->listener.OnAssociationError(
1131
+ this->associationListenerDeferrer.OnAssociationError(
1119
1132
  Types::ErrorKind::PARSE_FAILED,
1120
1133
  "packet with INIT_ACK chunk has invalid Verification Tag");
1121
1134
 
@@ -1163,7 +1176,7 @@ namespace RTC
1163
1176
  "SHUTDOWN_COMPLETE Chunk Verification Tag %" PRIu32 " is wrong, packet discarded",
1164
1177
  receivedPacket->GetVerificationTag());
1165
1178
 
1166
- this->listener.OnAssociationError(
1179
+ this->associationListenerDeferrer.OnAssociationError(
1167
1180
  Types::ErrorKind::PARSE_FAILED,
1168
1181
  "packet with SHUTDOWN_COMPLETE chunk has invalid Verification Tag");
1169
1182
 
@@ -1191,7 +1204,7 @@ namespace RTC
1191
1204
  receivedPacket->GetVerificationTag(),
1192
1205
  localVerificationTag);
1193
1206
 
1194
- this->listener.OnAssociationError(
1207
+ this->associationListenerDeferrer.OnAssociationError(
1195
1208
  Types::ErrorKind::PARSE_FAILED, "packet has invalid Verification Tag");
1196
1209
 
1197
1210
  return false;
@@ -1594,8 +1607,7 @@ namespace RTC
1594
1607
  // partly sent message is re-sent in full. The same is true when the
1595
1608
  // Association is closed and later re-opened, which never happens in
1596
1609
  // WebRTC, but is a valid operation on the SCTP level.
1597
- // TODO: SCTP: Implement it.
1598
- // this->sendQueue.Reset();
1610
+ this->sendQueue.Reset();
1599
1611
 
1600
1612
  CreateTransmissionControlBlock(
1601
1613
  this->preTcb.localVerificationTag,
@@ -1616,14 +1628,12 @@ namespace RTC
1616
1628
 
1617
1629
  this->tcb->SetRemoteStateCookie(std::move(remoteStateCookie));
1618
1630
 
1619
- // TODO: SCTP: Implement it.
1620
- // TODO: SCTP: tcb->SendBufferedPackets() must check that the remote state cookie
1621
- // is set in TCB and must send a COOKIE_ECHO Chunk before potentially
1622
- // buffered messages.
1623
- // this->tcb->SendBufferedPackets(callbacks_.Now());
1631
+ const uint64_t nowMs = this->shared->GetTimeMs();
1624
1632
 
1633
+ this->tcb->SendBufferedPackets(nowMs);
1625
1634
  this->t1CookieTimer->Start();
1626
- this->listener.OnAssociationConnecting();
1635
+
1636
+ this->associationListenerDeferrer.OnAssociationConnecting();
1627
1637
  }
1628
1638
 
1629
1639
  void Association::HandleReceivedCookieEchoChunk(
@@ -1635,7 +1645,7 @@ namespace RTC
1635
1645
  {
1636
1646
  MS_WARN_TAG(sctp, "ignoring received COOKIE_ECHO Chunk without Cookie");
1637
1647
 
1638
- this->listener.OnAssociationError(
1648
+ this->associationListenerDeferrer.OnAssociationError(
1639
1649
  Types::ErrorKind::PARSE_FAILED, "received COOKIE_ECHO Chunk without Cookie");
1640
1650
 
1641
1651
  return;
@@ -1648,7 +1658,7 @@ namespace RTC
1648
1658
  {
1649
1659
  MS_WARN_TAG(sctp, "failed to parse Cookie in received COOKIE_ECHO Chunk");
1650
1660
 
1651
- this->listener.OnAssociationError(
1661
+ this->associationListenerDeferrer.OnAssociationError(
1652
1662
  Types::ErrorKind::PARSE_FAILED, "received COOKIE_ECHO Chunk with invalid Cookie");
1653
1663
 
1654
1664
  return;
@@ -1667,7 +1677,7 @@ namespace RTC
1667
1677
  {
1668
1678
  MS_WARN_TAG(sctp, "received COOKIE_ECHO Chunk with invalid Verification Tag");
1669
1679
 
1670
- this->listener.OnAssociationError(
1680
+ this->associationListenerDeferrer.OnAssociationError(
1671
1681
  Types::ErrorKind::PARSE_FAILED,
1672
1682
  "received COOKIE_ECHO Chunk with invalid Verification Tag");
1673
1683
 
@@ -1687,7 +1697,7 @@ namespace RTC
1687
1697
 
1688
1698
  SetState(State::ESTABLISHED, "COOKIE_ECHO received");
1689
1699
 
1690
- this->listener.OnAssociationConnected();
1700
+ this->associationListenerDeferrer.OnAssociationConnected();
1691
1701
  }
1692
1702
 
1693
1703
  if (!this->tcb)
@@ -1697,8 +1707,7 @@ namespace RTC
1697
1707
  // partly sent message is re-sent in full. The same is true when the
1698
1708
  // Association is closed and later re-opened, which never happens in
1699
1709
  // WebRTC, but is a valid operation on the SCTP level.
1700
- // TODO: SCTP: Implement it.
1701
- // this->sendQueue.Reset();
1710
+ this->sendQueue.Reset();
1702
1711
 
1703
1712
  CreateTransmissionControlBlock(
1704
1713
  cookie->GetLocalVerificationTag(),
@@ -1710,23 +1719,14 @@ namespace RTC
1710
1719
  cookie->GetNegotiatedCapabilities());
1711
1720
  }
1712
1721
 
1713
- auto packet = this->tcb->CreatePacket();
1714
- const auto* cookieAckChunk = packet->BuildChunkInPlace<CookieAckChunk>();
1715
-
1716
- cookieAckChunk->Consolidate();
1717
-
1718
1722
  // https://datatracker.ietf.org/doc/html/rfc9260#section-5.1
1719
1723
  //
1720
1724
  // "A COOKIE ACK chunk MAY be bundled with any pending DATA chunks (and/or
1721
1725
  // SACK chunks), but the COOKIE ACK chunk MUST be the first chunk in the
1722
1726
  // packet."
1723
- // TODO: SCTP: Implement it. Note that we pass Packet as argument!
1724
- // this->tcb->SendBufferedPackets(packet.get(), callbacks_.Now());
1727
+ const uint64_t nowMs = this->shared->GetTimeMs();
1725
1728
 
1726
- // TODO: SCTP: Remove this since COOKIE_ACK must be sent by
1727
- // tcb->SendBufferedPackets() call above.
1728
- MS_DUMP("TODO: REMOVE");
1729
- this->packetSender.SendPacket(packet.get());
1729
+ this->tcb->SendBufferedPackets(nowMs, /*addCookieAckChunk*/ true);
1730
1730
  }
1731
1731
 
1732
1732
  bool Association::HandleReceivedCookieEchoChunkWithTcb(
@@ -1768,8 +1768,7 @@ namespace RTC
1768
1768
  operationErrorChunk->Consolidate();
1769
1769
 
1770
1770
  this->packetSender.SendPacket(packet.get());
1771
-
1772
- this->listener.OnAssociationError(
1771
+ this->associationListenerDeferrer.OnAssociationError(
1773
1772
  Types::ErrorKind::WRONG_SEQUENCE, "received COOKIE_ECHO while shutting down");
1774
1773
 
1775
1774
  return false;
@@ -1778,7 +1777,7 @@ namespace RTC
1778
1777
  MS_DEBUG_DEV("received COOKIE_ECHO indicating a restarted peer");
1779
1778
 
1780
1779
  this->tcb = nullptr;
1781
- this->listener.OnAssociationRestarted();
1780
+ this->associationListenerDeferrer.OnAssociationRestarted();
1782
1781
  }
1783
1782
  // "B) In this case, both sides might be attempting to start an association
1784
1783
  // at about the same time, but the peer endpoint sent its INIT chunk after
@@ -1844,10 +1843,11 @@ namespace RTC
1844
1843
 
1845
1844
  SetState(State::ESTABLISHED, "COOKIE_ACK received");
1846
1845
 
1847
- // TODO: SCTP: Implement this.
1848
- // this->tcb->SendBufferedPackets(callbacks_.Now());
1846
+ const uint64_t nowMs = this->shared->GetTimeMs();
1847
+
1848
+ this->tcb->SendBufferedPackets(nowMs);
1849
1849
 
1850
- this->listener.OnAssociationConnected();
1850
+ this->associationListenerDeferrer.OnAssociationConnected();
1851
1851
  }
1852
1852
 
1853
1853
  void Association::HandleReceivedShutdownChunk(
@@ -2032,7 +2032,8 @@ namespace RTC
2032
2032
 
2033
2033
  MS_WARN_TAG(sctp, "received OPERATION_ERROR Chunk: %s", errorCausesStr.c_str());
2034
2034
 
2035
- this->listener.OnAssociationError(Types::ErrorKind::PEER_REPORTED, errorCausesStr);
2035
+ this->associationListenerDeferrer.OnAssociationError(
2036
+ Types::ErrorKind::PEER_REPORTED, errorCausesStr);
2036
2037
  }
2037
2038
 
2038
2039
  void Association::HandleReceivedAbortAssociationChunk(
@@ -2101,7 +2102,7 @@ namespace RTC
2101
2102
  }
2102
2103
 
2103
2104
  void Association::HandleReceivedReConfigChunk(
2104
- const Packet* /*receivedPacket*/, const ReConfigChunk* /*receivedReConfigChunk*/)
2105
+ const Packet* /*receivedPacket*/, const ReConfigChunk* receivedReConfigChunk)
2105
2106
  {
2106
2107
  MS_TRACE();
2107
2108
 
@@ -2110,8 +2111,7 @@ namespace RTC
2110
2111
  return;
2111
2112
  }
2112
2113
 
2113
- // TODO: SCTP: Implement it.
2114
- // this->tcb->GetStreamResetHandler().HandleReConfig(*std::move(receivedReConfigChunk));
2114
+ this->tcb->GetStreamResetHandler().HandleReceivedReConfigChunk(receivedReConfigChunk);
2115
2115
 
2116
2116
  // Handling this response may result in outgoing stream resets finishing
2117
2117
  // (either successfully or with failure). If there still are pending
@@ -2121,8 +2121,9 @@ namespace RTC
2121
2121
 
2122
2122
  // If a response was processed, pending to-be-reset streams may now have
2123
2123
  // become unpaused. Try to send more DATA/I_DATA chunks.
2124
- // TODO: SCTP: Implement it.
2125
- // this->tcb->SendBufferedPackets(callbacks_.Now());
2124
+ const uint64_t nowMs = this->shared->GetTimeMs();
2125
+
2126
+ this->tcb->SendBufferedPackets(nowMs);
2126
2127
 
2127
2128
  // If it leaves "deferred reset processing", there may be chunks to
2128
2129
  // deliver that were queued while waiting for the stream to reset.
@@ -2146,7 +2147,7 @@ namespace RTC
2146
2147
  }
2147
2148
 
2148
2149
  void Association::HandleReceivedAnyForwardTsnChunk(
2149
- const Packet* /*receivedPacket*/, const AnyForwardTsnChunk* /*receivedAnyForwardTsnChunk*/)
2150
+ const Packet* /*receivedPacket*/, const AnyForwardTsnChunk* receivedAnyForwardTsnChunk)
2150
2151
  {
2151
2152
  MS_TRACE();
2152
2153
 
@@ -2167,28 +2168,26 @@ namespace RTC
2167
2168
  abortAssociationChunk->BuildErrorCauseInPlace<ProtocolViolationErrorCause>();
2168
2169
 
2169
2170
  protocolViolationErrorCause->SetAdditionalInformation(
2170
- "FORWARD_TSN or I_FORWARD_TSN-TSN chunk received but partial reliability is not negotiated");
2171
+ "FORWARD-TSN or I_FORWARD-TSN chunk received but partial reliability is not negotiated");
2171
2172
 
2172
2173
  protocolViolationErrorCause->Consolidate();
2173
2174
  abortAssociationChunk->Consolidate();
2174
2175
 
2175
2176
  this->packetSender.SendPacket(packet.get());
2176
2177
 
2177
- this->listener.OnAssociationError(
2178
+ this->associationListenerDeferrer.OnAssociationError(
2178
2179
  Types::ErrorKind::PROTOCOL_VIOLATION,
2179
- "received FORWARD_TSN or I_FORWARD_TSN-TSN chunk but partial reliability is not negotiated");
2180
+ "received FORWARD-TSN or I-FORWARD-TSN chunk but partial reliability is not negotiated");
2180
2181
 
2181
2182
  return;
2182
2183
  }
2183
2184
 
2184
- // TODO: SCTP: Implement it.
2185
- // if
2186
- // (this->tcb->GetDataTracker().HandleForwardTsn(receivedAnyForwardTsnChunk->GetNewCumulativeTsn()))
2187
- // {
2188
- // this->tcb->GetReassemblyQueue().HandleForwardTsn(
2189
- // receivedAnyForwardTsnChunk->GetNewCumulativeTsn(),
2190
- // receivedAnyForwardTsnChunk->GetSkippedStreams());
2191
- // }
2185
+ if (this->tcb->GetDataTracker().HandleForwardTsn(receivedAnyForwardTsnChunk->GetNewCumulativeTsn()))
2186
+ {
2187
+ this->tcb->GetReassemblyQueue().HandleForwardTsn(
2188
+ receivedAnyForwardTsnChunk->GetNewCumulativeTsn(),
2189
+ receivedAnyForwardTsnChunk->GetSkippedStreams());
2190
+ }
2192
2191
 
2193
2192
  // A forward TSN (for ordered streams) may allow messages to be delivered.
2194
2193
  MayDeliverMessages();
@@ -2220,9 +2219,8 @@ namespace RTC
2220
2219
  return;
2221
2220
  }
2222
2221
 
2223
- const uint32_t tsn = receivedAnyDataChunk->GetTsn();
2224
- // TODO: SCTP: Uncomment.
2225
- // const bool immediateAck = receivedAnyDataChunk->GetI();
2222
+ const uint32_t tsn = receivedAnyDataChunk->GetTsn();
2223
+ const bool immediateAck = receivedAnyDataChunk->GetI();
2226
2224
 
2227
2225
  if (receivedAnyDataChunk->GetUserDataPayloadLength() == 0)
2228
2226
  {
@@ -2237,99 +2235,95 @@ namespace RTC
2237
2235
 
2238
2236
  this->packetSender.SendPacket(packet.get());
2239
2237
 
2240
- this->listener.OnAssociationError(
2241
- Types::ErrorKind::PROTOCOL_VIOLATION, "received DATA or I_DATA chunk with no user data");
2238
+ this->associationListenerDeferrer.OnAssociationError(
2239
+ Types::ErrorKind::PROTOCOL_VIOLATION, "received DATA or I-DATA chunk with no user data");
2242
2240
 
2243
2241
  return;
2244
2242
  }
2245
2243
 
2246
- // TODO: SCTP: Implement it.
2247
- // MS_DEBUG_DEV("data received [data length:%" PRIu16 ", queue size:%zu, watermark:%zu,
2248
- // full:%s, above:%s]", receivedAnyDataChunk->GetUserDataLength(),
2249
- // this->tcb->GetReassemblyQueue()->GetQueuedBytes(),
2250
- // this->tcb->GetReassemblyQueue()->GetWaterMarkBytes(),
2251
- // this->tcb->GetReassemblyQueue()->IsFull(),
2252
- // this->tcb->GetReassemblyQueue()->IsAboveWatermark(),
2253
- // );
2254
-
2255
- // TODO: SCTP: Implement it.
2256
- // if (this->tcb->GetReassemblyQueue()->IsFull())
2257
- // {
2258
- // // If the reassembly queue is full but there are assembled messages
2259
- // // waiting to be pulled, we can't do anything with this data except drop
2260
- // // it, and hope the upper layer drains the accumulated messages soon.
2261
- // if (this->tcb->GetReassemblyQueue()->HasMessages())
2262
- // {
2263
- // MS_WARN_TAG(sctp, "received data rejected because reassembly queue is full");
2264
-
2265
- // return;
2266
- // }
2267
- // // If the reassembly queue is full and there's no messages waiting,
2268
- // // there is nothing that can be done. The specification only allows
2269
- // // dropping gap-ack-blocks, and that's not likely to help as the
2270
- // // Association has been trying to fill gaps since the watermark was
2271
- // // reached.
2272
- // else
2273
- // {
2274
- // auto packet = this->tcb->CreatePacket();
2275
- // auto* abortAssociationChunk = packet->BuildChunkInPlace<AbortAssociationChunk>();
2276
-
2277
- // // NOTE: Don't set bit T in the ABORT chunk since TCB knows the
2278
- // // Verification Tag expected by the remote.
2279
-
2280
- // auto* outOfResourceErrorCause =
2281
- // abortAssociationChunk->BuildErrorCauseInPlace<OutOfResourceErrorCause>();
2282
-
2283
- // outOfResourceErrorCause->Consolidate();
2284
- // abortAssociationChunk->Consolidate();
2285
-
2286
- // this->packetSender.SendPacket(packet.get());
2287
-
2288
- // InternalClose(Types::ErrorKind::RESOURCE_EXHAUSTION, "reassembly queue is exhausted");
2289
-
2290
- // return;
2291
- // }
2292
- // }
2244
+ MS_DEBUG_DEV(
2245
+ "data received [data length:%" PRIu16 ", queue size:%zu, watermark:%zu, full:%s, above:%s]",
2246
+ receivedAnyDataChunk->GetUserDataPayloadLength(),
2247
+ this->tcb->GetReassemblyQueue().GetQueuedBytes(),
2248
+ this->tcb->GetReassemblyQueue().GetWatermarkBytes(),
2249
+ this->tcb->GetReassemblyQueue().IsFull() ? "yes" : "no",
2250
+ this->tcb->GetReassemblyQueue().IsAboveWatermark() ? "yes" : "no");
2251
+
2252
+ if (this->tcb->GetReassemblyQueue().IsFull())
2253
+ {
2254
+ // If the reassembly queue is full but there are assembled messages
2255
+ // waiting to be pulled, we can't do anything with this data except drop
2256
+ // it, and hope the upper layer drains the accumulated messages soon.
2257
+ if (this->tcb->GetReassemblyQueue().HasMessages())
2258
+ {
2259
+ MS_WARN_TAG(sctp, "received data rejected because reassembly queue is full");
2260
+
2261
+ return;
2262
+ }
2263
+ // If the reassembly queue is full and there's no messages waiting,
2264
+ // there is nothing that can be done. The specification only allows
2265
+ // dropping gap-ack-blocks, and that's not likely to help as the
2266
+ // Association has been trying to fill gaps since the watermark was
2267
+ // reached.
2268
+ else
2269
+ {
2270
+ auto packet = this->tcb->CreatePacket();
2271
+ auto* abortAssociationChunk = packet->BuildChunkInPlace<AbortAssociationChunk>();
2272
+
2273
+ // NOTE: Don't set bit T in the ABORT chunk since TCB knows the
2274
+ // Verification Tag expected by the remote.
2275
+
2276
+ auto* outOfResourceErrorCause =
2277
+ abortAssociationChunk->BuildErrorCauseInPlace<OutOfResourceErrorCause>();
2278
+
2279
+ outOfResourceErrorCause->Consolidate();
2280
+ abortAssociationChunk->Consolidate();
2281
+
2282
+ this->packetSender.SendPacket(packet.get());
2283
+
2284
+ InternalClose(Types::ErrorKind::RESOURCE_EXHAUSTION, "reassembly queue is exhausted");
2285
+
2286
+ return;
2287
+ }
2288
+ }
2293
2289
 
2294
2290
  // If the reassembly queue is above its high watermark, only accept data
2295
2291
  // chunks that increase its cumulative ack tsn in an attempt to fill gaps
2296
2292
  // to deliver messages.
2297
- // TODO: SCTP: Implement it.
2298
- // if (this->tcb->GetReassemblyQueue()->IsAboveWatermark())
2299
- // {
2300
- // MS_WARN_TAG(sctp, "reassembly queue is above watermark");
2293
+ if (this->tcb->GetReassemblyQueue().IsAboveWatermark())
2294
+ {
2295
+ MS_WARN_TAG(sctp, "reassembly queue is above watermark");
2301
2296
 
2302
- // if (this->tcb->GetDataTracker()->WillIncreaseCumAckTsn(tsn))
2303
- // {
2304
- // MS_WARN_TAG(sctp, "reassembly queue is above watermark");
2297
+ if (!this->tcb->GetDataTracker().WillIncreaseCumAckTsn(tsn))
2298
+ {
2299
+ MS_WARN_TAG(sctp, "reassembly queue is above watermark");
2305
2300
 
2306
- // this->tcb->GetDataTracker()->ForceImmediateSack();
2301
+ this->tcb->GetDataTracker().ForceImmediateSack();
2307
2302
 
2308
- // return;
2309
- // }
2310
- // }
2303
+ return;
2304
+ }
2305
+ }
2311
2306
 
2312
- // TODO: SCTP: Implement it.
2313
- // if (this->tcb->GetDataTracker()->IsTsnValid(tsn))
2314
- // {
2315
- // MS_WARN_TAG(sctp, "data rejected because of failing TSN validity");
2307
+ if (!this->tcb->GetDataTracker().IsTsnValid(tsn))
2308
+ {
2309
+ MS_WARN_TAG(sctp, "data rejected because of failing TSN validity");
2316
2310
 
2317
- // return;
2318
- // }
2311
+ return;
2312
+ }
2319
2313
 
2320
- // TODO: SCTP: Implement it.
2321
- // if (this->tcb->GetDataTracker()->Observe(tsn, immediateAck))
2322
- // {
2323
- // // TODO: SCTP: Here we should have a std::vector<uint8_t> holding the data so
2324
- // // we can move it.
2325
- // this->tcb->GetReassemblyQueue()->Add(tsn, std::move(data));
2314
+ if (this->tcb->GetDataTracker().Observe(tsn, immediateAck))
2315
+ {
2316
+ // NOTE: Here we are passing an UserData r-value created and returned by
2317
+ // receivedAnyDataChunk->MakeUserData() so there is only one copy here.
2318
+ // And ReassemblyQueue::AddData() will std::move() it internally.
2319
+ this->tcb->GetReassemblyQueue().AddData(tsn, receivedAnyDataChunk->MakeUserData());
2326
2320
 
2327
- // MayDeliverMessages();
2328
- // }
2321
+ MayDeliverMessages();
2322
+ }
2329
2323
  }
2330
2324
 
2331
2325
  void Association::HandleReceivedSackChunk(
2332
- const Packet* /*receivedPacket*/, const SackChunk* /*receivedSackChunk*/)
2326
+ const Packet* /*receivedPacket*/, const SackChunk* receivedSackChunk)
2333
2327
  {
2334
2328
  MS_TRACE();
2335
2329
 
@@ -2338,37 +2332,36 @@ namespace RTC
2338
2332
  return;
2339
2333
  }
2340
2334
 
2341
- // TODO: SCTP: Implement it.
2342
- // if (this->tcb->GetRetransmissionQueue()->HandleReceivedSack(receivedSackChunk))
2343
- // {
2344
- // MaySendShutdownOrShutdownAckChunk();
2345
-
2346
- // // Receiving an ACK may make the Association go into fast recovery mode.
2347
- // //
2348
- // // https://datatracker.ietf.org/doc/html/rfc9260#section-7.2.4
2349
- // //
2350
- // // "If not in Fast Recovery, determine how many of the earliest (i.e.,
2351
- // // lowest TSN) DATA chunks marked for retransmission will fit into a
2352
- // // single packet, subject to constraint of the PMTU of the destination
2353
- // // transport address to which the packet is being sent. Call this value
2354
- // // K. Retransmit those K DATA chunks in a single packet. When a Fast
2355
- // // Retransmit is being performed, the sender SHOULD ignore the value of
2356
- // // cwnd and SHOULD NOT delay retransmission for this single packet."
2357
- // this->tcb->MaySendFastRetransmit();
2358
-
2359
- // // Receiving an ACK will decrease outstanding bytes (maybe now below
2360
- // // cwnd?) or indicate packet loss that may result in sending FORWARD-TSN.
2361
- // const uint64_t now = DepLibUV::GetTimeMs();
2362
-
2363
- // this->tcb->SendBufferedPackets(now);
2364
- // }
2365
- // else
2366
- // {
2367
- // MS_WARN_TAG(
2368
- // sctp,
2369
- // "dropping received out-of-order SACK [TSN:%" PRIu32 "]",
2370
- // receivedSackChunk->GetCumulativeTsnAck());
2371
- // }
2335
+ const uint64_t nowMs = this->shared->GetTimeMs();
2336
+
2337
+ if (this->tcb->GetRetransmissionQueue().HandleReceivedSackChunk(nowMs, receivedSackChunk))
2338
+ {
2339
+ MaySendShutdownOrShutdownAckChunk();
2340
+
2341
+ // Receiving an ACK may make the Association go into fast recovery mode.
2342
+ //
2343
+ // https://datatracker.ietf.org/doc/html/rfc9260#section-7.2.4
2344
+ //
2345
+ // "If not in Fast Recovery, determine how many of the earliest (i.e.,
2346
+ // lowest TSN) DATA chunks marked for retransmission will fit into a
2347
+ // single packet, subject to constraint of the PMTU of the destination
2348
+ // transport address to which the packet is being sent. Call this value
2349
+ // K. Retransmit those K DATA chunks in a single packet. When a Fast
2350
+ // Retransmit is being performed, the sender SHOULD ignore the value of
2351
+ // cwnd and SHOULD NOT delay retransmission for this single packet."
2352
+ this->tcb->MaySendFastRetransmit();
2353
+
2354
+ // Receiving an ACK will decrease outstanding bytes (maybe now below
2355
+ // cwnd?) or indicate packet loss that may result in sending FORWARD-TSN.
2356
+ this->tcb->SendBufferedPackets(nowMs);
2357
+ }
2358
+ else
2359
+ {
2360
+ MS_WARN_TAG(
2361
+ sctp,
2362
+ "dropping received out-of-order SACK [TSN:%" PRIu32 "]",
2363
+ receivedSackChunk->GetCumulativeTsnAck());
2364
+ }
2372
2365
  }
2373
2366
 
2374
2367
  bool Association::HandleReceivedUnknownChunk(
@@ -2400,7 +2393,7 @@ namespace RTC
2400
2393
 
2401
2394
  if (reportError)
2402
2395
  {
2403
- this->listener.OnAssociationError(
2396
+ this->associationListenerDeferrer.OnAssociationError(
2404
2397
  Types::ErrorKind::PARSE_FAILED, "unknown chunk with type indicating it should be reported");
2405
2398
 
2406
2399
  // If there is TCB (we need correct remote verification tag) send an
@@ -2429,15 +2422,7 @@ namespace RTC
2429
2422
  {
2430
2423
  MS_TRACE();
2431
2424
 
2432
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
2433
-
2434
- const auto maxRestarts = this->t1InitTimer->GetMaxRestarts();
2435
-
2436
- MS_DEBUG_TAG(
2437
- sctp,
2438
- "T1-init timer has expired %zu/%s]",
2439
- this->t1InitTimer->GetExpirationCount(),
2440
- maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
2425
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
2441
2426
 
2442
2427
  AssertState(State::COOKIE_WAIT);
2443
2428
 
@@ -2450,36 +2435,29 @@ namespace RTC
2450
2435
  InternalClose(Types::ErrorKind::TOO_MANY_RETRIES, "no INIT_ACK chunk received");
2451
2436
  }
2452
2437
 
2453
- AssertStateIsConsistent();
2438
+ AssertIsConsistent();
2454
2439
  }
2455
2440
 
2456
2441
  void Association::OnT1CookieTimer(uint64_t& /*baseTimeoutMs*/, bool& /*stop*/)
2457
2442
  {
2458
2443
  MS_TRACE();
2459
2444
 
2460
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
2461
-
2462
- const auto maxRestarts = this->t1CookieTimer->GetMaxRestarts();
2463
-
2464
- MS_DEBUG_TAG(
2465
- sctp,
2466
- "T1-cookie timer has expired %zu/%s]",
2467
- this->t1CookieTimer->GetExpirationCount(),
2468
- maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
2445
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
2469
2446
 
2470
2447
  AssertState(State::COOKIE_ECHOED);
2471
2448
 
2472
2449
  if (this->t1CookieTimer->IsRunning())
2473
2450
  {
2474
- // TODO: SCTP: Implement it.
2475
- // this->tcb->SendBufferedPackets(now);
2451
+ const uint64_t nowMs = this->shared->GetTimeMs();
2452
+
2453
+ this->tcb->SendBufferedPackets(nowMs);
2476
2454
  }
2477
2455
  else
2478
2456
  {
2479
2457
  InternalClose(Types::ErrorKind::TOO_MANY_RETRIES, "no COOKIE_ACK chunk received");
2480
2458
  }
2481
2459
 
2482
- AssertStateIsConsistent();
2460
+ AssertIsConsistent();
2483
2461
  }
2484
2462
 
2485
2463
  void Association::OnT2ShutdownTimer(uint64_t& baseTimeoutMs, bool& /*stop*/)
@@ -2489,15 +2467,7 @@ namespace RTC
2489
2467
  AssertState(State::SHUTDOWN_SENT, State::SHUTDOWN_ACK_SENT);
2490
2468
  AssertHasTcb();
2491
2469
 
2492
- const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->listener);
2493
-
2494
- const auto maxRestarts = this->t2ShutdownTimer->GetMaxRestarts();
2495
-
2496
- MS_DEBUG_TAG(
2497
- sctp,
2498
- "T2-shutdown timer has expired %zu/%s]",
2499
- this->t2ShutdownTimer->GetExpirationCount(),
2500
- maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
2470
+ const AssociationListenerDeferrer::ScopedDeferrer deferrer(this->associationListenerDeferrer);
2501
2471
 
2502
2472
  // https://datatracker.ietf.org/doc/html/rfc9260#section-9.2
2503
2473
  //
@@ -2526,7 +2496,8 @@ namespace RTC
2526
2496
  this->packetSender.SendPacket(packet.get());
2527
2497
 
2528
2498
  InternalClose(Types::ErrorKind::TOO_MANY_RETRIES, "no SHUTDOWN_ACK chunk received");
2529
- AssertStateIsConsistent();
2499
+
2500
+ AssertIsConsistent();
2530
2501
 
2531
2502
  return;
2532
2503
  }
@@ -2550,7 +2521,7 @@ namespace RTC
2550
2521
  SendShutdownChunk();
2551
2522
  }
2552
2523
 
2553
- AssertStateIsConsistent();
2524
+ AssertIsConsistent();
2554
2525
 
2555
2526
  baseTimeoutMs = this->tcb->GetCurrentRtoMs();
2556
2527
  }
@@ -2626,7 +2597,7 @@ namespace RTC
2626
2597
  return true;
2627
2598
  }
2628
2599
 
2629
- this->listener.OnAssociationError(
2600
+ this->associationListenerDeferrer.OnAssociationError(
2630
2601
  Types::ErrorKind::NOT_CONNECTED,
2631
2602
  "received unexpected commands on association that is not connected");
2632
2603
 
@@ -2643,10 +2614,23 @@ namespace RTC
2643
2614
  }
2644
2615
  }
2645
2616
 
2646
- void Association::AssertStateIsConsistent() const
2617
+ void Association::AssertIsConsistent() const
2647
2618
  {
2648
2619
  MS_TRACE();
2649
2620
 
2621
+ // NOTE: This assertion is present in dcsctp but we are removing it because
2622
+ // it's dangerous. Depending on where `AssertIsConsistent()` is called from,
2623
+ // it may legitimately happen that tere are SCTP full messages stored in
2624
+ // the reassembly queue. `ReassemblyQueue::HasMessages()` can legitimately
2625
+ // return `true` during stream deferred reset processing, which is a valid
2626
+ // state where the reassembly queue intentionally retains messages while
2627
+ // waiting for the TSN marked by the peer as the "Sender's Last Assigned
2628
+ // TSN". There is no point in the code where we can guarantee that this
2629
+ // state is not active.
2630
+ // MS_ASSERT(
2631
+ // !(this->tcb && this->tcb->GetReassemblyQueue().HasMessages()),
2632
+ // "this->tcb && this->tcb->GetReassemblyQueue().HasMessages()");
2633
+
2650
2634
  switch (this->state)
2651
2635
  {
2652
2636
  case State::NEW:
@@ -2796,21 +2780,43 @@ namespace RTC
2796
2780
  }
2797
2781
  }
2798
2782
 
2783
+ #if MS_LOG_DEV_LEVEL == 3
2784
+ void Association::OnPacketSenderPacketSent(
2785
+ PacketSender* /*packetSender*/, const Packet* packet, bool sent)
2786
+ #else
2799
2787
  void Association::OnPacketSenderPacketSent(
2800
2788
  PacketSender* /*packetSender*/, const Packet* /*packet*/, bool sent)
2789
+ #endif
2801
2790
  {
2802
2791
  MS_TRACE();
2803
2792
 
2793
+ // For debugging purposes.
2794
+ #if MS_LOG_DEV_LEVEL == 3
2795
+ MS_DUMP(">>> SCTP packet sent [sent:%s]", sent ? "yes" : "no");
2796
+
2797
+ packet->Dump();
2798
+ #endif
2799
+
2804
2800
  if (sent)
2805
2801
  {
2806
2802
  this->privateMetrics.txPacketsCount++;
2807
2803
  }
2808
2804
  }
2809
2805
 
2810
- void Association::OnTimer(BackoffTimerHandle* backoffTimer, uint64_t& baseTimeoutMs, bool& stop)
2806
+ void Association::OnBackoffTimer(
2807
+ BackoffTimerHandleInterface* backoffTimer, uint64_t& baseTimeoutMs, bool& stop)
2811
2808
  {
2812
2809
  MS_TRACE();
2813
2810
 
2811
+ const auto maxRestarts = backoffTimer->GetMaxRestarts();
2812
+
2813
+ MS_DEBUG_TAG(
2814
+ sctp,
2815
+ "%s timer has expired [expìrations:%zu/%s]",
2816
+ backoffTimer->GetLabel().c_str(),
2817
+ backoffTimer->GetExpirationCount(),
2818
+ maxRestarts ? std::to_string(maxRestarts.value()).c_str() : "Infinite");
2819
+
2814
2820
  if (backoffTimer == this->t1InitTimer.get())
2815
2821
  {
2816
2822
  OnT1InitTimer(baseTimeoutMs, stop);