![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /usr/local/lib/node_modules/mediasoup/worker/src/ |
Upload File : |
#define MS_CLASS "DepUsrSCTP" // #define MS_LOG_DEV_LEVEL 3 #include "DepUsrSCTP.hpp" #include "DepLibUV.hpp" #include "Logger.hpp" #include <usrsctp.h> /* Static. */ static constexpr size_t CheckerInterval{ 10u }; // In ms. /* Static methods for usrsctp global callbacks. */ inline static int onSendSctpData(void* addr, void* data, size_t len, uint8_t /*tos*/, uint8_t /*setDf*/) { auto* sctpAssociation = DepUsrSCTP::RetrieveSctpAssociation(reinterpret_cast<uintptr_t>(addr)); if (!sctpAssociation) { MS_WARN_TAG(sctp, "no SctpAssociation found"); return -1; } sctpAssociation->OnUsrSctpSendSctpData(data, len); // NOTE: Must not free data, usrsctp lib does it. return 0; } // Static method for printing usrsctp debug. inline static void sctpDebug(const char* format, ...) { char buffer[10000]; va_list ap; va_start(ap, format); vsprintf(buffer, format, ap); // Remove the artificial carriage return set by usrsctp. buffer[std::strlen(buffer) - 1] = '\0'; MS_DEBUG_TAG(sctp, "%s", buffer); va_end(ap); } /* Static variables. */ DepUsrSCTP::Checker* DepUsrSCTP::checker{ nullptr }; uint64_t DepUsrSCTP::numSctpAssociations{ 0u }; uintptr_t DepUsrSCTP::nextSctpAssociationId{ 0u }; std::unordered_map<uintptr_t, RTC::SctpAssociation*> DepUsrSCTP::mapIdSctpAssociation; /* Static methods. */ void DepUsrSCTP::ClassInit() { MS_TRACE(); MS_DEBUG_TAG(info, "usrsctp"); usrsctp_init_nothreads(0, onSendSctpData, sctpDebug); // Disable explicit congestion notifications (ecn). usrsctp_sysctl_set_sctp_ecn_enable(0); #ifdef SCTP_DEBUG usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_ALL); #endif DepUsrSCTP::checker = new DepUsrSCTP::Checker(); } void DepUsrSCTP::ClassDestroy() { MS_TRACE(); usrsctp_finish(); delete DepUsrSCTP::checker; } uintptr_t DepUsrSCTP::GetNextSctpAssociationId() { MS_TRACE(); // NOTE: usrsctp_connect() fails with a value of 0. if (DepUsrSCTP::nextSctpAssociationId == 0u) ++DepUsrSCTP::nextSctpAssociationId; // In case we've wrapped around and need to find an empty spot from a removed // SctpAssociation. Assumes we'll never be full. while (DepUsrSCTP::mapIdSctpAssociation.find(DepUsrSCTP::nextSctpAssociationId) != DepUsrSCTP::mapIdSctpAssociation.end()) { ++DepUsrSCTP::nextSctpAssociationId; if (DepUsrSCTP::nextSctpAssociationId == 0u) ++DepUsrSCTP::nextSctpAssociationId; } return DepUsrSCTP::nextSctpAssociationId++; } void DepUsrSCTP::RegisterSctpAssociation(RTC::SctpAssociation* sctpAssociation) { MS_TRACE(); auto it = DepUsrSCTP::mapIdSctpAssociation.find(sctpAssociation->id); MS_ASSERT( it == DepUsrSCTP::mapIdSctpAssociation.end(), "the id of the SctpAssociation is already in the map"); DepUsrSCTP::mapIdSctpAssociation[sctpAssociation->id] = sctpAssociation; if (++DepUsrSCTP::numSctpAssociations == 1u) DepUsrSCTP::checker->Start(); } void DepUsrSCTP::DeregisterSctpAssociation(RTC::SctpAssociation* sctpAssociation) { MS_TRACE(); auto found = DepUsrSCTP::mapIdSctpAssociation.erase(sctpAssociation->id); MS_ASSERT(found > 0, "SctpAssociation not found"); MS_ASSERT(DepUsrSCTP::numSctpAssociations > 0u, "numSctpAssociations was not higher than 0"); if (--DepUsrSCTP::numSctpAssociations == 0u) DepUsrSCTP::checker->Stop(); } RTC::SctpAssociation* DepUsrSCTP::RetrieveSctpAssociation(uintptr_t id) { MS_TRACE(); auto it = DepUsrSCTP::mapIdSctpAssociation.find(id); if (it == DepUsrSCTP::mapIdSctpAssociation.end()) return nullptr; return it->second; } /* DepUsrSCTP::Checker instance methods. */ DepUsrSCTP::Checker::Checker() { MS_TRACE(); this->timer = new Timer(this); } DepUsrSCTP::Checker::~Checker() { MS_TRACE(); delete this->timer; } void DepUsrSCTP::Checker::Start() { MS_TRACE(); MS_DEBUG_TAG(sctp, "usrsctp periodic check started"); this->lastCalledAtMs = 0u; this->timer->Start(CheckerInterval, CheckerInterval); } void DepUsrSCTP::Checker::Stop() { MS_TRACE(); MS_DEBUG_TAG(sctp, "usrsctp periodic check stopped"); this->lastCalledAtMs = 0u; this->timer->Stop(); } void DepUsrSCTP::Checker::OnTimer(Timer* /*timer*/) { MS_TRACE(); auto nowMs = DepLibUV::GetTimeMs(); int elapsedMs = this->lastCalledAtMs ? static_cast<int>(nowMs - this->lastCalledAtMs) : 0; usrsctp_handle_timers(elapsedMs); this->lastCalledAtMs = nowMs; }