mirror of
https://github.com/mii443/libdatachannel.git
synced 2025-08-22 15:15:28 +00:00
Merge pull request #400 from paullouisageneau/sctp-settings
Add SCTP settings API
This commit is contained in:
@ -43,7 +43,7 @@ set(LIBDATACHANNEL_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/configuration.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/datachannel.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/description.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/init.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/global.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/log.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/message.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/peerconnection.cpp
|
||||
@ -75,7 +75,7 @@ set(LIBDATACHANNEL_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/mediahandler.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/rtcpreceivingsession.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/common.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/init.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/global.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/log.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/message.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/peerconnection.hpp
|
||||
@ -107,6 +107,7 @@ set(LIBDATACHANNEL_IMPL_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/dtlssrtptransport.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/dtlstransport.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/icetransport.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/init.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/peerconnection.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/logcounter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/sctptransport.cpp
|
||||
@ -129,6 +130,8 @@ set(LIBDATACHANNEL_IMPL_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/dtlssrtptransport.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/dtlstransport.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/icetransport.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/init.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/internals.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/peerconnection.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/queue.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/logcounter.hpp
|
||||
|
@ -70,6 +70,7 @@ using binary = std::vector<byte>;
|
||||
using binary_ptr = std::shared_ptr<binary>;
|
||||
|
||||
using std::size_t;
|
||||
using std::ptrdiff_t;
|
||||
using std::uint16_t;
|
||||
using std::uint32_t;
|
||||
using std::uint64_t;
|
||||
|
44
include/rtc/global.hpp
Normal file
44
include/rtc/global.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_GLOBAL_H
|
||||
#define RTC_GLOBAL_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
RTC_EXPORT void Preload();
|
||||
RTC_EXPORT void Cleanup();
|
||||
|
||||
struct SctpSettings {
|
||||
optional<size_t> recvBufferSize;
|
||||
optional<size_t> sendBufferSize;
|
||||
optional<size_t> maxChunksOnQueue;
|
||||
optional<size_t> initialCongestionWindow;
|
||||
optional<unsigned int> congestionControlModule;
|
||||
optional<std::chrono::milliseconds> delayedSackTime;
|
||||
};
|
||||
|
||||
RTC_EXPORT void SetSctpSettings(SctpSettings s);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
@ -24,7 +24,6 @@
|
||||
#include "datachannel.hpp"
|
||||
#include "description.hpp"
|
||||
#include "common.hpp"
|
||||
#include "init.hpp"
|
||||
#include "message.hpp"
|
||||
#include "reliability.hpp"
|
||||
#include "track.hpp"
|
||||
|
@ -46,7 +46,8 @@ extern "C" {
|
||||
#define RTC_DEFAULT_MTU 1280 // IPv6 minimum guaranteed MTU
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
#define RTC_DEFAULT_MAXIMUM_FRAGMENT_SIZE ((uint16_t)(RTC_DEFAULT_MTU - 12 - 8 - 40)) // SRTP/UDP/IPv6
|
||||
#define RTC_DEFAULT_MAXIMUM_FRAGMENT_SIZE \
|
||||
((uint16_t)(RTC_DEFAULT_MTU - 12 - 8 - 40)) // SRTP/UDP/IPv6
|
||||
#define RTC_DEFAULT_MAXIMUM_PACKET_COUNT_FOR_NACK_CACHE ((unsigned)512)
|
||||
#endif
|
||||
|
||||
@ -97,21 +98,21 @@ typedef enum {
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
typedef enum {
|
||||
// video
|
||||
RTC_CODEC_H264 = 0,
|
||||
RTC_CODEC_VP8 = 1,
|
||||
RTC_CODEC_VP9 = 2,
|
||||
// video
|
||||
RTC_CODEC_H264 = 0,
|
||||
RTC_CODEC_VP8 = 1,
|
||||
RTC_CODEC_VP9 = 2,
|
||||
|
||||
// audio
|
||||
RTC_CODEC_OPUS = 128
|
||||
// audio
|
||||
RTC_CODEC_OPUS = 128
|
||||
} rtcCodec;
|
||||
|
||||
typedef enum {
|
||||
RTC_DIRECTION_UNKNOWN = 0,
|
||||
RTC_DIRECTION_SENDONLY = 1,
|
||||
RTC_DIRECTION_RECVONLY = 2,
|
||||
RTC_DIRECTION_SENDRECV = 3,
|
||||
RTC_DIRECTION_INACTIVE = 4
|
||||
RTC_DIRECTION_UNKNOWN = 0,
|
||||
RTC_DIRECTION_SENDONLY = 1,
|
||||
RTC_DIRECTION_RECVONLY = 2,
|
||||
RTC_DIRECTION_SENDRECV = 3,
|
||||
RTC_DIRECTION_INACTIVE = 4
|
||||
} rtcDirection;
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
@ -130,7 +131,7 @@ typedef struct {
|
||||
bool disableAutoNegotiation;
|
||||
uint16_t portRangeBegin;
|
||||
uint16_t portRangeEnd;
|
||||
int mtu; // <= 0 means automatic
|
||||
int mtu; // <= 0 means automatic
|
||||
int maxMessageSize; // <= 0 means default
|
||||
} rtcConfiguration;
|
||||
|
||||
@ -172,7 +173,7 @@ RTC_EXPORT void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb);
|
||||
|
||||
// User pointer
|
||||
RTC_EXPORT void rtcSetUserPointer(int id, void *ptr);
|
||||
RTC_EXPORT void * rtcGetUserPointer(int i);
|
||||
RTC_EXPORT void *rtcGetUserPointer(int i);
|
||||
|
||||
// PeerConnection
|
||||
RTC_EXPORT int rtcCreatePeerConnection(const rtcConfiguration *config); // returns pc id
|
||||
@ -219,6 +220,19 @@ RTC_EXPORT int rtcDeleteTrack(int tr);
|
||||
|
||||
RTC_EXPORT int rtcGetTrackDescription(int tr, char *buffer, int size);
|
||||
|
||||
// SCTP settings
|
||||
typedef struct {
|
||||
int recvBufferSize; // <= 0 means optimized default
|
||||
int sendBufferSize; // <= 0 means optimized default
|
||||
int maxChunksOnQueue; // <= 0 means optimized default
|
||||
int initialCongestionWindow; // <= 0 means optimized default
|
||||
int congestionControlModule; // <= 0 means default (0: RFC2581, 1: HSTCP, 2: H-TCP, 3: RTCC)
|
||||
int delayedSackTimeMs; // <= 0 means optimized default
|
||||
} rtcSctpSettings;
|
||||
|
||||
// Note: SCTP settings apply to newly-created PeerConnections only
|
||||
RTC_EXPORT int rtcSetSctpSettings(const rtcSctpSettings *settings);
|
||||
|
||||
// Media
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
@ -233,7 +247,9 @@ RTC_EXPORT int rtcGetTrackDescription(int tr, char *buffer, int size);
|
||||
/// @param _msid MSID (optional)
|
||||
/// @param _trackID Track ID used in MSID (optional)
|
||||
/// @returns Track id
|
||||
RTC_EXPORT int rtcAddTrackEx(int pc, rtcCodec codec, int payloadType, uint32_t ssrc, const char *_mid, rtcDirection direction, const char *_name, const char *_msid, const char *_trackID);
|
||||
RTC_EXPORT int rtcAddTrackEx(int pc, rtcCodec codec, int payloadType, uint32_t ssrc,
|
||||
const char *_mid, rtcDirection direction, const char *_name,
|
||||
const char *_msid, const char *_trackID);
|
||||
|
||||
/// Set H264PacketizationHandler for track
|
||||
/// @param tr Track id
|
||||
@ -244,7 +260,10 @@ RTC_EXPORT int rtcAddTrackEx(int pc, rtcCodec codec, int payloadType, uint32_t s
|
||||
/// @param maxFragmentSize Maximum NALU fragment size
|
||||
/// @param sequenceNumber Sequence number
|
||||
/// @param timestamp Timestamp
|
||||
RTC_EXPORT int rtcSetH264PacketizationHandler(int tr, uint32_t ssrc, const char * cname, uint8_t payloadType, uint32_t clockRate, uint16_t maxFragmentSize, uint16_t sequenceNumber, uint32_t timestamp);
|
||||
RTC_EXPORT int rtcSetH264PacketizationHandler(int tr, uint32_t ssrc, const char *cname,
|
||||
uint8_t payloadType, uint32_t clockRate,
|
||||
uint16_t maxFragmentSize, uint16_t sequenceNumber,
|
||||
uint32_t timestamp);
|
||||
|
||||
/// Set OpusPacketizationHandler for track
|
||||
/// @param tr Track id
|
||||
@ -254,7 +273,9 @@ RTC_EXPORT int rtcSetH264PacketizationHandler(int tr, uint32_t ssrc, const char
|
||||
/// @param clockRate Clock rate
|
||||
/// @param _sequenceNumber Sequence number
|
||||
/// @param _timestamp Timestamp
|
||||
RTC_EXPORT int rtcSetOpusPacketizationHandler(int tr, uint32_t ssrc, const char * cname, uint8_t payloadType, uint32_t clockRate, uint16_t _sequenceNumber, uint32_t _timestamp);
|
||||
RTC_EXPORT int rtcSetOpusPacketizationHandler(int tr, uint32_t ssrc, const char *cname,
|
||||
uint8_t payloadType, uint32_t clockRate,
|
||||
uint16_t _sequenceNumber, uint32_t _timestamp);
|
||||
|
||||
/// Chain RtcpSrReporter to handler chain for given track
|
||||
/// @param tr Track id
|
||||
@ -267,9 +288,11 @@ int rtcChainRtcpNackResponder(int tr, unsigned maxStoredPacketsCount);
|
||||
|
||||
/// Set start time for RTP stream
|
||||
/// @param startTime_s Start time in seconds
|
||||
/// @param timeIntervalSince1970 Set true if `startTime_s` is time interval since 1970, false if `startTime_s` is time interval since 1900
|
||||
/// @param timeIntervalSince1970 Set true if `startTime_s` is time interval since 1970, false if
|
||||
/// `startTime_s` is time interval since 1900
|
||||
/// @param _timestamp Start timestamp
|
||||
int rtcSetRtpConfigurationStartTime(int id, double startTime_s, bool timeIntervalSince1970, uint32_t _timestamp);
|
||||
int rtcSetRtpConfigurationStartTime(int id, double startTime_s, bool timeIntervalSince1970,
|
||||
uint32_t _timestamp);
|
||||
|
||||
/// Start stats recording for RTCP Sender Reporter
|
||||
/// @param id Track identifier
|
||||
@ -279,23 +302,23 @@ int rtcStartRtcpSenderReporterRecording(int id);
|
||||
/// @param id Track id
|
||||
/// @param seconds Seconds
|
||||
/// @param timestamp Pointer to result
|
||||
int rtcTransformSecondsToTimestamp(int id, double seconds, uint32_t * timestamp);
|
||||
int rtcTransformSecondsToTimestamp(int id, double seconds, uint32_t *timestamp);
|
||||
|
||||
/// Transform timestamp to seconds using track's clock rate
|
||||
/// @param id Track id
|
||||
/// @param timestamp Timestamp
|
||||
/// @param seconds Pointer for result
|
||||
int rtcTransformTimestampToSeconds(int id, uint32_t timestamp, double * seconds);
|
||||
int rtcTransformTimestampToSeconds(int id, uint32_t timestamp, double *seconds);
|
||||
|
||||
/// Get current timestamp
|
||||
/// @param id Track id
|
||||
/// @param timestamp Pointer for result
|
||||
int rtcGetCurrentTrackTimestamp(int id, uint32_t * timestamp);
|
||||
int rtcGetCurrentTrackTimestamp(int id, uint32_t *timestamp);
|
||||
|
||||
/// Get start timestamp for track identified by given id
|
||||
/// @param id Track id
|
||||
/// @param timestamp Pointer for result
|
||||
int rtcGetTrackStartTimestamp(int id, uint32_t * timestamp);
|
||||
int rtcGetTrackStartTimestamp(int id, uint32_t *timestamp);
|
||||
|
||||
/// Set RTP timestamp for track identified by given id
|
||||
/// @param id Track id
|
||||
@ -305,7 +328,7 @@ int rtcSetTrackRTPTimestamp(int id, uint32_t timestamp);
|
||||
/// Get timestamp of previous RTCP SR
|
||||
/// @param id Track id
|
||||
/// @param timestamp Pointer for result
|
||||
int rtcGetPreviousTrackSenderReportTimestamp(int id, uint32_t * timestamp);
|
||||
int rtcGetPreviousTrackSenderReportTimestamp(int id, uint32_t *timestamp);
|
||||
|
||||
/// Set `NeedsToReport` flag in RtcpSrReporter handler identified by given track id
|
||||
/// @param id Track id
|
||||
|
@ -21,12 +21,12 @@
|
||||
|
||||
// C++ API
|
||||
#include "common.hpp"
|
||||
#include "init.hpp" // for rtc::Cleanup()
|
||||
#include "global.hpp"
|
||||
#include "log.hpp"
|
||||
//
|
||||
#include "datachannel.hpp"
|
||||
#include "track.hpp"
|
||||
#include "peerconnection.hpp"
|
||||
#include "track.hpp"
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
@ -38,14 +38,13 @@
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
// Media handling
|
||||
#include "rtcpreceivingsession.hpp"
|
||||
#include "mediachainablehandler.hpp"
|
||||
#include "rtcpsrreporter.hpp"
|
||||
#include "rtcpnackresponder.hpp"
|
||||
#include "rtcpreceivingsession.hpp"
|
||||
#include "rtcpsrreporter.hpp"
|
||||
|
||||
// Opus/h264 streaming
|
||||
#include "h264packetizationhandler.hpp"
|
||||
#include "opuspacketizationhandler.hpp"
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
|
@ -17,7 +17,8 @@
|
||||
*/
|
||||
|
||||
#include "candidate.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
#include "impl/internals.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
27
src/capi.cpp
27
src/capi.cpp
@ -715,6 +715,33 @@ int rtcGetTrackDescription(int tr, char *buffer, int size) {
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetSctpSettings(const rtcSctpSettings *settings) {
|
||||
return wrap([&] {
|
||||
SctpSettings s = {};
|
||||
|
||||
if (settings->recvBufferSize > 0)
|
||||
s.recvBufferSize = size_t(settings->recvBufferSize);
|
||||
|
||||
if (settings->sendBufferSize > 0)
|
||||
s.sendBufferSize = size_t(settings->sendBufferSize);
|
||||
|
||||
if (settings->maxChunksOnQueue > 0)
|
||||
s.maxChunksOnQueue = size_t(settings->maxChunksOnQueue);
|
||||
|
||||
if (settings->initialCongestionWindow > 0)
|
||||
s.initialCongestionWindow = size_t(settings->initialCongestionWindow);
|
||||
|
||||
if (settings->congestionControlModule >= 0)
|
||||
s.congestionControlModule = unsigned(settings->congestionControlModule);
|
||||
|
||||
if (settings->delayedSackTimeMs > 0)
|
||||
s.delayedSackTime = std::chrono::milliseconds(settings->delayedSackTimeMs);
|
||||
|
||||
SetSctpSettings(std::move(s));
|
||||
return RTC_ERR_SUCCESS;
|
||||
});
|
||||
}
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
int rtcCreateWebSocket(const char *url) {
|
||||
return wrap([&] {
|
||||
|
@ -17,8 +17,8 @@
|
||||
*/
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
#include "impl/internals.hpp"
|
||||
#include "impl/channel.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
@ -17,11 +17,11 @@
|
||||
*/
|
||||
|
||||
#include "datachannel.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "common.hpp"
|
||||
#include "peerconnection.hpp"
|
||||
|
||||
#include "impl/datachannel.hpp"
|
||||
#include "impl/internals.hpp"
|
||||
#include "impl/peerconnection.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
31
src/global.cpp
Normal file
31
src/global.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "global.hpp"
|
||||
|
||||
#include "impl/init.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
void Preload() { Init::Preload(); }
|
||||
void Cleanup() { Init::Cleanup(); }
|
||||
|
||||
void SetSctpSettings(SctpSettings s) { Init::SetSctpSettings(std::move(s)); }
|
||||
|
||||
} // namespace rtc
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "datachannel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
#include "logcounter.hpp"
|
||||
#include "peerconnection.hpp"
|
||||
#include "sctptransport.hpp"
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "dtlstransport.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
#include "icetransport.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "icetransport.hpp"
|
||||
#include "configuration.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
#include "transport.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "init.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
|
||||
#include "impl/certificate.hpp"
|
||||
#include "impl/dtlstransport.hpp"
|
||||
@ -42,7 +42,6 @@ namespace rtc {
|
||||
namespace {
|
||||
|
||||
void doInit() {
|
||||
PLOG_DEBUG << "Global initialization";
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
@ -69,8 +68,6 @@ void doInit() {
|
||||
}
|
||||
|
||||
void doCleanup() {
|
||||
PLOG_DEBUG << "Global cleanup";
|
||||
|
||||
impl::ThreadPool::Instance().join();
|
||||
|
||||
impl::SctpTransport::Cleanup();
|
||||
@ -92,6 +89,7 @@ void doCleanup() {
|
||||
weak_ptr<void> Init::Weak;
|
||||
shared_ptr<void> *Init::Global = nullptr;
|
||||
bool Init::Initialized = false;
|
||||
SctpSettings Init::CurrentSctpSettings = {};
|
||||
std::recursive_mutex Init::Mutex;
|
||||
|
||||
init_token Init::Token() {
|
||||
@ -118,10 +116,20 @@ void Init::Cleanup() {
|
||||
Global = nullptr;
|
||||
}
|
||||
|
||||
void Init::SetSctpSettings(SctpSettings s) {
|
||||
auto token = Token();
|
||||
std::unique_lock lock(Mutex);
|
||||
impl::SctpTransport::SetSettings(s);
|
||||
CurrentSctpSettings = std::move(s); // store for next init
|
||||
}
|
||||
|
||||
Init::Init() {
|
||||
// Mutex is locked by Token() here
|
||||
if (!std::exchange(Initialized, true))
|
||||
if (!std::exchange(Initialized, true)) {
|
||||
PLOG_DEBUG << "Global initialization";
|
||||
doInit();
|
||||
impl::SctpTransport::SetSettings(CurrentSctpSettings);
|
||||
}
|
||||
}
|
||||
|
||||
Init::~Init() {
|
||||
@ -130,8 +138,11 @@ Init::~Init() {
|
||||
std::unique_lock lock(Mutex);
|
||||
if (Global)
|
||||
return;
|
||||
if (std::exchange(Initialized, false))
|
||||
|
||||
if (std::exchange(Initialized, false)) {
|
||||
PLOG_DEBUG << "Global cleanup";
|
||||
doCleanup();
|
||||
}
|
||||
});
|
||||
t.detach();
|
||||
}
|
@ -16,22 +16,25 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_INIT_H
|
||||
#define RTC_INIT_H
|
||||
#ifndef RTC_IMPL_INIT_H
|
||||
#define RTC_IMPL_INIT_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include "global.hpp" // for SctpSettings
|
||||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
using init_token = shared_ptr<void>;
|
||||
|
||||
class RTC_CPP_EXPORT Init {
|
||||
class Init {
|
||||
public:
|
||||
static init_token Token();
|
||||
static void Preload();
|
||||
static void Cleanup();
|
||||
static void SetSctpSettings(SctpSettings s);
|
||||
|
||||
~Init();
|
||||
|
||||
@ -41,12 +44,10 @@ private:
|
||||
static weak_ptr<void> Weak;
|
||||
static shared_ptr<void> *Global;
|
||||
static bool Initialized;
|
||||
static SctpSettings CurrentSctpSettings;
|
||||
static std::recursive_mutex Mutex;
|
||||
};
|
||||
|
||||
inline void Preload() { Init::Preload(); }
|
||||
inline void Cleanup() { Init::Cleanup(); }
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
@ -16,8 +16,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_GLOBALS_H
|
||||
#define RTC_GLOBALS_H
|
||||
#ifndef RTC_IMPL_INTERNALS_H
|
||||
#define RTC_IMPL_INTERNALS_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
@ -26,7 +26,7 @@ namespace rtc {
|
||||
const size_t MAX_NUMERICNODE_LEN = 48; // Max IPv6 string representation length
|
||||
const size_t MAX_NUMERICSERV_LEN = 6; // Max port string representation length
|
||||
|
||||
const uint16_t DEFAULT_SCTP_PORT = 5000; // SCTP port to use by default
|
||||
const uint16_t DEFAULT_SCTP_PORT = 5000; // SCTP port to use by default
|
||||
|
||||
const size_t DEFAULT_LOCAL_MAX_MESSAGE_SIZE = 256 * 1024; // Default local max message size
|
||||
const size_t DEFAULT_MAX_MESSAGE_SIZE = 65536; // Remote max message size if not specified in SDP
|
@ -21,7 +21,7 @@
|
||||
#include "certificate.hpp"
|
||||
#include "common.hpp"
|
||||
#include "dtlstransport.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
#include "icetransport.hpp"
|
||||
#include "logcounter.hpp"
|
||||
#include "peerconnection.hpp"
|
||||
|
@ -18,12 +18,13 @@
|
||||
|
||||
#include "sctptransport.hpp"
|
||||
#include "dtlstransport.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
#include "logcounter.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
@ -54,6 +55,26 @@
|
||||
using namespace std::chrono_literals;
|
||||
using namespace std::chrono;
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T> uint16_t to_uint16(T i) {
|
||||
if (i >= 0 && static_cast<typename std::make_unsigned<T>::type>(i) <=
|
||||
std::numeric_limits<uint16_t>::max())
|
||||
return static_cast<uint16_t>(i);
|
||||
else
|
||||
throw std::invalid_argument("Integer out of range");
|
||||
}
|
||||
|
||||
template <typename T> uint32_t to_uint32(T i) {
|
||||
if (i >= 0 && static_cast<typename std::make_unsigned<T>::type>(i) <=
|
||||
std::numeric_limits<uint32_t>::max())
|
||||
return static_cast<uint32_t>(i);
|
||||
else
|
||||
throw std::invalid_argument("Integer out of range");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace rtc::impl {
|
||||
|
||||
static LogCounter COUNTER_UNKNOWN_PPID(plog::warning,
|
||||
@ -69,7 +90,8 @@ std::shared_mutex SctpTransport::InstancesMutex;
|
||||
|
||||
void SctpTransport::Init() {
|
||||
usrsctp_init(0, &SctpTransport::WriteCallback, nullptr);
|
||||
usrsctp_sysctl_set_sctp_ecn_enable(0);
|
||||
usrsctp_sysctl_set_sctp_pr_enable(1); // Enable Partial Reliability Extension (RFC 3758)
|
||||
usrsctp_sysctl_set_sctp_ecn_enable(0); // Disable Explicit Congestion Notification
|
||||
usrsctp_sysctl_set_sctp_init_rtx_max_default(5);
|
||||
usrsctp_sysctl_set_sctp_path_rtx_max_default(5);
|
||||
usrsctp_sysctl_set_sctp_assoc_rtx_max_default(5); // single path
|
||||
@ -78,21 +100,28 @@ void SctpTransport::Init() {
|
||||
usrsctp_sysctl_set_sctp_rto_initial_default(1 * 1000); // ms
|
||||
usrsctp_sysctl_set_sctp_init_rto_max_default(10 * 1000); // ms
|
||||
usrsctp_sysctl_set_sctp_heartbeat_interval_default(10 * 1000); // ms
|
||||
}
|
||||
|
||||
usrsctp_sysctl_set_sctp_max_chunks_on_queue(10 * 1024);
|
||||
void SctpTransport::SetSettings(const SctpSettings &s) {
|
||||
// The send and receive window size of usrsctp is 256KiB, which is too small for realistic RTTs,
|
||||
// therefore we increase it to 1MiB by default for better performance.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1051685
|
||||
usrsctp_sysctl_set_sctp_recvspace(to_uint32(s.recvBufferSize.value_or(1024 * 1024)));
|
||||
usrsctp_sysctl_set_sctp_sendspace(to_uint32(s.sendBufferSize.value_or(1024 * 1024)));
|
||||
|
||||
// Use default congestion control (RFC 4960)
|
||||
// Increase maximum chunks number on queue to 10K by default
|
||||
usrsctp_sysctl_set_sctp_max_chunks_on_queue(to_uint32(s.maxChunksOnQueue.value_or(10 * 1024)));
|
||||
|
||||
// Increase initial congestion window size to 10 MTUs (RFC 6928) by default
|
||||
usrsctp_sysctl_set_sctp_initial_cwnd(to_uint32(s.initialCongestionWindow.value_or(10)));
|
||||
|
||||
// Use standard SCTP congestion control (RFC 4960) by default
|
||||
// See https://github.com/paullouisageneau/libdatachannel/issues/354
|
||||
usrsctp_sysctl_set_sctp_default_cc_module(0);
|
||||
usrsctp_sysctl_set_sctp_default_cc_module(to_uint32(s.congestionControlModule.value_or(0)));
|
||||
|
||||
// Enable Partial Reliability Extension (RFC 3758)
|
||||
usrsctp_sysctl_set_sctp_pr_enable(1);
|
||||
|
||||
// Increase the initial window size to 10 MTUs (RFC 6928)
|
||||
usrsctp_sysctl_set_sctp_initial_cwnd(10);
|
||||
|
||||
// Reduce SACK delay from the default 200ms to 20ms
|
||||
usrsctp_sysctl_set_sctp_delayed_sack_time_default(20); // ms
|
||||
// Reduce SACK delay to 20ms by default
|
||||
usrsctp_sysctl_set_sctp_delayed_sack_time_default(
|
||||
to_uint32(s.delayedSackTime.value_or(20ms).count()));
|
||||
}
|
||||
|
||||
void SctpTransport::Cleanup() {
|
||||
@ -195,7 +224,7 @@ SctpTransport::SctpTransport(shared_ptr<Transport> lower, const Configuration &c
|
||||
// The MTU value provided specifies the space available for chunks in the
|
||||
// packet, so we also subtract the SCTP header size.
|
||||
size_t pmtu = config.mtu.value_or(DEFAULT_MTU) - 12 - 37 - 8 - 40; // SCTP/DTLS/UDP/IPv6
|
||||
spp.spp_pathmtu = uint32_t(pmtu);
|
||||
spp.spp_pathmtu = to_uint32(pmtu);
|
||||
PLOG_VERBOSE << "Path MTU discovery disabled, SCTP MTU set to " << pmtu;
|
||||
}
|
||||
|
||||
@ -222,18 +251,28 @@ SctpTransport::SctpTransport(shared_ptr<Transport> lower, const Configuration &c
|
||||
throw std::runtime_error("Could not disable SCTP fragmented interleave, errno=" +
|
||||
std::to_string(errno));
|
||||
|
||||
// The default send and receive window size of usrsctp is 256KiB, which is too small for
|
||||
// realistic RTTs, therefore we increase it to at least 1MiB for better performance.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1051685
|
||||
const size_t minBufferSize = 1024 * 1024;
|
||||
int rcvBuf = 0;
|
||||
socklen_t rcvBufLen = sizeof(rcvBuf);
|
||||
if (usrsctp_getsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &rcvBuf, &rcvBufLen))
|
||||
throw std::runtime_error("Could not get SCTP recv buffer size, errno=" +
|
||||
std::to_string(errno));
|
||||
int sndBuf = 0;
|
||||
socklen_t sndBufLen = sizeof(sndBuf);
|
||||
if (usrsctp_getsockopt(mSock, SOL_SOCKET, SO_SNDBUF, &sndBuf, &sndBufLen))
|
||||
throw std::runtime_error("Could not get SCTP send buffer size, errno=" +
|
||||
std::to_string(errno));
|
||||
|
||||
// Ensure the buffer is also large enough to accomodate the largest messages
|
||||
const size_t maxMessageSize = config.maxMessageSize.value_or(DEFAULT_LOCAL_MAX_MESSAGE_SIZE);
|
||||
const int bufferSize = int(std::max(minBufferSize, maxMessageSize * 2)); // usrsctp reads as int
|
||||
if (usrsctp_setsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)))
|
||||
const int minBuf = int(std::min(maxMessageSize, size_t(std::numeric_limits<int>::max())));
|
||||
rcvBuf = std::max(rcvBuf, minBuf);
|
||||
sndBuf = std::max(sndBuf, minBuf);
|
||||
|
||||
if (usrsctp_setsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &rcvBuf, sizeof(rcvBuf)))
|
||||
throw std::runtime_error("Could not set SCTP recv buffer size, errno=" +
|
||||
std::to_string(errno));
|
||||
if (usrsctp_setsockopt(mSock, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)))
|
||||
|
||||
if (usrsctp_setsockopt(mSock, SOL_SOCKET, SO_SNDBUF, &sndBuf, sizeof(sndBuf)))
|
||||
throw std::runtime_error("Could not set SCTP send buffer size, errno=" +
|
||||
std::to_string(errno));
|
||||
}
|
||||
@ -336,7 +375,7 @@ bool SctpTransport::send(message_ptr message) {
|
||||
return true;
|
||||
|
||||
mSendQueue.push(message);
|
||||
updateBufferedAmount(uint16_t(message->stream), long(message_size_func(message)));
|
||||
updateBufferedAmount(to_uint16(message->stream), ptrdiff_t(message_size_func(message)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -353,7 +392,7 @@ bool SctpTransport::flush() {
|
||||
}
|
||||
|
||||
void SctpTransport::closeStream(unsigned int stream) {
|
||||
send(make_message(0, Message::Reset, uint16_t(stream)));
|
||||
send(make_message(0, Message::Reset, to_uint16(stream)));
|
||||
}
|
||||
|
||||
void SctpTransport::incoming(message_ptr message) {
|
||||
@ -458,7 +497,7 @@ bool SctpTransport::trySendQueue() {
|
||||
if (!trySendMessage(message))
|
||||
return false;
|
||||
mSendQueue.pop();
|
||||
updateBufferedAmount(uint16_t(message->stream), -long(message_size_func(message)));
|
||||
updateBufferedAmount(to_uint16(message->stream), -ptrdiff_t(message_size_func(message)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -511,12 +550,12 @@ bool SctpTransport::trySendMessage(message_ptr message) {
|
||||
case Reliability::Type::Rexmit:
|
||||
spa.sendv_flags |= SCTP_SEND_PRINFO_VALID;
|
||||
spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_RTX;
|
||||
spa.sendv_prinfo.pr_value = uint32_t(std::get<int>(reliability.rexmit));
|
||||
spa.sendv_prinfo.pr_value = to_uint32(std::get<int>(reliability.rexmit));
|
||||
break;
|
||||
case Reliability::Type::Timed:
|
||||
spa.sendv_flags |= SCTP_SEND_PRINFO_VALID;
|
||||
spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_TTL;
|
||||
spa.sendv_prinfo.pr_value = uint32_t(std::get<milliseconds>(reliability.rexmit).count());
|
||||
spa.sendv_prinfo.pr_value = to_uint32(std::get<milliseconds>(reliability.rexmit).count());
|
||||
break;
|
||||
default:
|
||||
spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_NONE;
|
||||
@ -548,10 +587,10 @@ bool SctpTransport::trySendMessage(message_ptr message) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SctpTransport::updateBufferedAmount(uint16_t streamId, long delta) {
|
||||
void SctpTransport::updateBufferedAmount(uint16_t streamId, ptrdiff_t delta) {
|
||||
// Requires mSendMutex to be locked
|
||||
auto it = mBufferedAmount.insert(std::make_pair(streamId, 0)).first;
|
||||
size_t amount = size_t(std::max(long(it->second) + delta, long(0)));
|
||||
size_t amount = size_t(std::max(ptrdiff_t(it->second) + delta, ptrdiff_t(0)));
|
||||
if (amount == 0)
|
||||
mBufferedAmount.erase(it);
|
||||
else
|
||||
|
@ -39,6 +39,7 @@ namespace rtc::impl {
|
||||
class SctpTransport final : public Transport {
|
||||
public:
|
||||
static void Init();
|
||||
static void SetSettings(const SctpSettings &s);
|
||||
static void Cleanup();
|
||||
|
||||
using amount_callback = std::function<void(uint16_t streamId, size_t amount)>;
|
||||
@ -83,7 +84,7 @@ private:
|
||||
void doFlush();
|
||||
bool trySendQueue();
|
||||
bool trySendMessage(message_ptr message);
|
||||
void updateBufferedAmount(uint16_t streamId, long delta);
|
||||
void updateBufferedAmount(uint16_t streamId, ptrdiff_t delta);
|
||||
void triggerBufferedAmount(uint16_t streamId, size_t amount);
|
||||
void sendReset(uint16_t streamId);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "tcptransport.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "track.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
#include "logcounter.hpp"
|
||||
#include "peerconnection.hpp"
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
#include "websocket.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "internals.hpp"
|
||||
#include "common.hpp"
|
||||
#include "threadpool.hpp"
|
||||
|
||||
|
@ -19,7 +19,8 @@
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "nalunit.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
#include "impl/internals.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
@ -17,8 +17,8 @@
|
||||
*/
|
||||
|
||||
#include "track.hpp"
|
||||
#include "globals.hpp"
|
||||
|
||||
#include "impl/internals.hpp"
|
||||
#include "impl/track.hpp"
|
||||
|
||||
namespace rtc {
|
||||
@ -46,9 +46,7 @@ bool Track::isOpen(void) const { return impl()->isOpen(); }
|
||||
|
||||
bool Track::isClosed(void) const { return impl()->isClosed(); }
|
||||
|
||||
size_t Track::maxMessageSize() const {
|
||||
return impl()->maxMessageSize();
|
||||
}
|
||||
size_t Track::maxMessageSize() const { return impl()->maxMessageSize(); }
|
||||
|
||||
void Track::setMediaHandler(shared_ptr<MediaHandler> handler) {
|
||||
impl()->setMediaHandler(std::move(handler));
|
||||
|
@ -19,10 +19,10 @@
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
#include "websocket.hpp"
|
||||
#include "globals.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
#include "impl/websocket.hpp"
|
||||
#include "impl/internals.hpp"
|
||||
|
||||
#include <regex>
|
||||
|
||||
|
Reference in New Issue
Block a user