Merge pull request #349 from paullouisageneau/fix-fragment-size

Harmonize MTU with fragment size
This commit is contained in:
Paul-Louis Ageneau
2021-03-02 18:59:28 +01:00
committed by GitHub
17 changed files with 116 additions and 80 deletions

View File

@ -19,14 +19,14 @@
#ifndef RTC_COMMON_H #ifndef RTC_COMMON_H
#define RTC_COMMON_H #define RTC_COMMON_H
#ifndef RTC_ENABLE_MEDIA
#define RTC_ENABLE_MEDIA 1
#endif
#ifndef RTC_ENABLE_WEBSOCKET #ifndef RTC_ENABLE_WEBSOCKET
#define RTC_ENABLE_WEBSOCKET 1 #define RTC_ENABLE_WEBSOCKET 1
#endif #endif
#ifndef RTC_ENABLE_MEDIA
#define RTC_ENABLE_MEDIA 1
#endif
#ifdef _WIN32 #ifdef _WIN32
#define RTC_CPP_EXPORT __declspec(dllexport) #define RTC_CPP_EXPORT __declspec(dllexport)
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
@ -39,6 +39,8 @@
#define RTC_CPP_EXPORT #define RTC_CPP_EXPORT
#endif #endif
#include "rtc.h" // for C API defines
#include "log.hpp" #include "log.hpp"
#include "utils.hpp" #include "utils.hpp"

View File

@ -62,11 +62,9 @@ private:
/// Nal unit /// Nal unit
struct RTC_CPP_EXPORT NalUnit : binary { struct RTC_CPP_EXPORT NalUnit : binary {
NalUnit(const NalUnit &unit) = default; NalUnit(const NalUnit &unit) = default;
NalUnit(size_t size, bool includingHeader = true) NalUnit(size_t size, bool includingHeader = true) : binary(size + (includingHeader ? 0 : 1)) {}
: binary(size + (includingHeader ? 0 : 1)) {}
template <typename Iterator> template <typename Iterator> NalUnit(Iterator begin_, Iterator end_) : binary(begin_, end_) {}
NalUnit(Iterator begin_, Iterator end_) : binary(begin_, end_) {}
NalUnit(binary &&data) : binary(std::move(data)) {} NalUnit(binary &&data) : binary(std::move(data)) {}
@ -101,9 +99,10 @@ struct RTC_CPP_EXPORT NalUnitFragmentA : NalUnit {
enum class FragmentType { Start, Middle, End }; enum class FragmentType { Start, Middle, End };
NalUnitFragmentA(FragmentType type, bool forbiddenBit, uint8_t nri, uint8_t unitType, NalUnitFragmentA(FragmentType type, bool forbiddenBit, uint8_t nri, uint8_t unitType,
binary data); binary data);
static std::vector<std::shared_ptr<NalUnitFragmentA>> fragmentsFrom(std::shared_ptr<NalUnit> nalu, uint16_t maximumFragmentSize); static std::vector<std::shared_ptr<NalUnitFragmentA>>
fragmentsFrom(std::shared_ptr<NalUnit> nalu, uint16_t maximumFragmentSize);
uint8_t unitType() { return fragmentHeader()->unitType(); } uint8_t unitType() { return fragmentHeader()->unitType(); }
@ -144,7 +143,8 @@ protected:
class RTC_CPP_EXPORT NalUnits : public std::vector<std::shared_ptr<NalUnit>> { class RTC_CPP_EXPORT NalUnits : public std::vector<std::shared_ptr<NalUnit>> {
public: public:
static const uint16_t defaultMaximumFragmentSize = 1400; static const uint16_t defaultMaximumFragmentSize =
uint16_t(RTC_DEFAULT_MTU - 12 - 8 - 40); // SRTP/UDP/IPv6
std::vector<std::shared_ptr<binary>> generateFragments(uint16_t maximumFragmentSize); std::vector<std::shared_ptr<binary>> generateFragments(uint16_t maximumFragmentSize);
}; };

View File

@ -27,7 +27,6 @@
#include "init.hpp" #include "init.hpp"
#include "message.hpp" #include "message.hpp"
#include "reliability.hpp" #include "reliability.hpp"
#include "rtc.hpp"
#include "track.hpp" #include "track.hpp"
#include <chrono> #include <chrono>

View File

@ -39,8 +39,14 @@ extern "C" {
#define RTC_ENABLE_WEBSOCKET 1 #define RTC_ENABLE_WEBSOCKET 1
#endif #endif
#ifndef RTC_ENABLE_MEDIA
#define RTC_ENABLE_MEDIA 1
#endif
#define RTC_DEFAULT_MTU 1280 // IPv6 minimum guaranteed MTU
#if RTC_ENABLE_MEDIA #if RTC_ENABLE_MEDIA
#define RTC_DEFAULT_MAXIMUM_FRAGMENT_SIZE ((uint16_t)1400) #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) #define RTC_DEFAULT_MAXIMUM_PACKET_COUNT_FOR_NACK_CACHE ((unsigned)512)
#endif #endif
@ -116,13 +122,14 @@ typedef struct {
bool enableIceTcp; bool enableIceTcp;
uint16_t portRangeBegin; uint16_t portRangeBegin;
uint16_t portRangeEnd; uint16_t portRangeEnd;
int mtu; // <= 0 means automatic
} rtcConfiguration; } rtcConfiguration;
typedef struct { typedef struct {
bool unordered; bool unordered;
bool unreliable; bool unreliable;
unsigned int maxPacketLifeTime; // ignored if reliable int maxPacketLifeTime; // ignored if reliable
unsigned int maxRetransmits; // ignored if reliable int maxRetransmits; // ignored if reliable
} rtcReliability; } rtcReliability;
typedef struct { typedef struct {

View File

@ -16,15 +16,25 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
// C API
#include "rtc.h"
// C++ API // C++ API
#include "common.hpp" #include "common.hpp"
#include "init.hpp" // for rtc::Cleanup() #include "init.hpp" // for rtc::Cleanup()
#include "log.hpp" #include "log.hpp"
// //
#include "datachannel.hpp" #include "datachannel.hpp"
#include "track.hpp"
#include "peerconnection.hpp" #include "peerconnection.hpp"
#if RTC_ENABLE_WEBSOCKET
// WebSocket
#include "websocket.hpp" #include "websocket.hpp"
#endif // RTC_ENABLE_WEBSOCKET
#if RTC_ENABLE_MEDIA #if RTC_ENABLE_MEDIA
// Media handling // Media handling
@ -39,5 +49,3 @@
#endif // RTC_ENABLE_MEDIA #endif // RTC_ENABLE_MEDIA
// C API
#include "rtc.h"

View File

@ -16,16 +16,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "common.hpp"
#include "rtc.h" #include "rtc.h"
#include "datachannel.hpp" #include "rtc.hpp"
#include "log.hpp"
#include "peerconnection.hpp"
#if RTC_ENABLE_WEBSOCKET
#include "websocket.hpp"
#endif
#include "plog/Formatters/FuncMessageFormatter.h" #include "plog/Formatters/FuncMessageFormatter.h"
@ -359,12 +352,16 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) {
for (int i = 0; i < config->iceServersCount; ++i) for (int i = 0; i < config->iceServersCount; ++i)
c.iceServers.emplace_back(string(config->iceServers[i])); c.iceServers.emplace_back(string(config->iceServers[i]));
if (config->portRangeBegin || config->portRangeEnd) { c.enableIceTcp = config->enableIceTcp;
if (config->portRangeBegin > 0 || config->portRangeEnd > 0) {
c.portRangeBegin = config->portRangeBegin; c.portRangeBegin = config->portRangeBegin;
c.portRangeEnd = config->portRangeEnd; c.portRangeEnd = config->portRangeEnd;
} }
c.enableIceTcp = config->enableIceTcp; if(config->mtu > 0)
c.mtu = size_t(config->mtu);
return emplacePeerConnection(std::make_shared<PeerConnection>(c)); return emplacePeerConnection(std::make_shared<PeerConnection>(c));
}); });
} }
@ -398,7 +395,7 @@ int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *ini
dci.reliability.rexmit = milliseconds(reliability->maxPacketLifeTime); dci.reliability.rexmit = milliseconds(reliability->maxPacketLifeTime);
} else { } else {
dci.reliability.type = Reliability::Type::Rexmit; dci.reliability.type = Reliability::Type::Rexmit;
dci.reliability.rexmit = int(reliability->maxRetransmits); dci.reliability.rexmit = reliability->maxRetransmits;
} }
} else { } else {
dci.reliability.type = Reliability::Type::Reliable; dci.reliability.type = Reliability::Type::Reliable;
@ -447,7 +444,8 @@ int rtcDeleteDataChannel(int dc) {
#if RTC_ENABLE_MEDIA #if RTC_ENABLE_MEDIA
void setSSRC(Description::Media *description, uint32_t ssrc, const char *_name, const char *_msid, const char *_trackID) { void setSSRC(Description::Media *description, uint32_t ssrc, const char *_name, const char *_msid,
const char *_trackID) {
optional<string> name = nullopt; optional<string> name = nullopt;
if (_name) { if (_name) {
@ -468,7 +466,8 @@ void setSSRC(Description::Media *description, uint32_t ssrc, const char *_name,
} }
int rtcAddTrackEx(int pc, rtcCodec codec, int payloadType, uint32_t ssrc, const char *_mid, 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) { rtcDirection _direction, const char *_name, const char *_msid,
const char *_trackID) {
return wrap([&] { return wrap([&] {
auto peerConnection = getPeerConnection(pc); auto peerConnection = getPeerConnection(pc);
@ -545,13 +544,13 @@ int rtcAddTrackEx(int pc, rtcCodec codec, int payloadType, uint32_t ssrc, const
} }
int rtcSetH264PacketizationHandler(int tr, uint32_t ssrc, const char *cname, uint8_t payloadType, int rtcSetH264PacketizationHandler(int tr, uint32_t ssrc, const char *cname, uint8_t payloadType,
uint32_t clockRate, uint16_t maxFragmentSize, uint16_t sequenceNumber, uint32_t clockRate, uint16_t maxFragmentSize,
uint32_t timestamp) { uint16_t sequenceNumber, uint32_t timestamp) {
return wrap([&] { return wrap([&] {
auto track = getTrack(tr); auto track = getTrack(tr);
// create RTP configuration // create RTP configuration
auto rtpConfig = getNewRtpPacketizationConfig(ssrc, cname, payloadType, clockRate, auto rtpConfig = getNewRtpPacketizationConfig(ssrc, cname, payloadType, clockRate,
sequenceNumber, timestamp); sequenceNumber, timestamp);
// create packetizer // create packetizer
auto packetizer = std::make_shared<H264RtpPacketizer>(rtpConfig, maxFragmentSize); auto packetizer = std::make_shared<H264RtpPacketizer>(rtpConfig, maxFragmentSize);
// create H264 handler // create H264 handler
@ -576,7 +575,7 @@ int rtcSetOpusPacketizationHandler(int tr, uint32_t ssrc, const char *cname, uin
auto packetizer = std::make_shared<OpusRtpPacketizer>(rtpConfig); auto packetizer = std::make_shared<OpusRtpPacketizer>(rtpConfig);
// create Opus handler // create Opus handler
auto opusHandler = std::make_shared<OpusPacketizationHandler>(packetizer); auto opusHandler = std::make_shared<OpusPacketizationHandler>(packetizer);
emplaceMediaChainableHandler(opusHandler, tr); emplaceMediaChainableHandler(opusHandler, tr);
emplaceRTPConfig(rtpConfig, tr); emplaceRTPConfig(rtpConfig, tr);
// set handler // set handler
track->setRtcpHandler(opusHandler); track->setRtcpHandler(opusHandler);
@ -674,7 +673,7 @@ int rtcGetPreviousTrackSenderReportTimestamp(int id, uint32_t *timestamp) {
} }
int rtcSetNeedsToSendRtcpSr(int id) { int rtcSetNeedsToSendRtcpSr(int id) {
return wrap([id]{ return wrap([id] {
auto sender = getRtcpSrReporter(id); auto sender = getRtcpSrReporter(id);
sender->setNeedsToReport(); sender->setNeedsToReport();
return RTC_ERR_SUCCESS; return RTC_ERR_SUCCESS;
@ -1012,10 +1011,10 @@ int rtcGetDataChannelReliability(int dc, rtcReliability *reliability) {
reliability->unordered = dcr.unordered; reliability->unordered = dcr.unordered;
if (dcr.type == Reliability::Type::Timed) { if (dcr.type == Reliability::Type::Timed) {
reliability->unreliable = true; reliability->unreliable = true;
reliability->maxPacketLifeTime = unsigned(std::get<milliseconds>(dcr.rexmit).count()); reliability->maxPacketLifeTime = int(std::get<milliseconds>(dcr.rexmit).count());
} else if (dcr.type == Reliability::Type::Rexmit) { } else if (dcr.type == Reliability::Type::Rexmit) {
reliability->unreliable = true; reliability->unreliable = true;
reliability->maxRetransmits = unsigned(std::get<int>(dcr.rexmit)); reliability->maxRetransmits = std::get<int>(dcr.rexmit);
} else { } else {
reliability->unreliable = false; reliability->unreliable = false;
} }

View File

@ -34,7 +34,7 @@ const size_t RECV_QUEUE_LIMIT = 1024 * 1024; // Max per-channel queue size
const int THREADPOOL_SIZE = 4; // Number of threads in the global thread pool (>= 2) const int THREADPOOL_SIZE = 4; // Number of threads in the global thread pool (>= 2)
const size_t DEFAULT_IPV4_MTU = 1200; // IPv4 safe MTU value recommended by RFC 8261 const size_t DEFAULT_MTU = RTC_DEFAULT_MTU; // defined in rtc.h
} // namespace rtc } // namespace rtc

View File

@ -17,8 +17,8 @@
*/ */
#include "datachannel.hpp" #include "datachannel.hpp"
#include "globals.hpp"
#include "common.hpp" #include "common.hpp"
#include "globals.hpp"
#include "logcounter.hpp" #include "logcounter.hpp"
#include "peerconnection.hpp" #include "peerconnection.hpp"
#include "sctptransport.hpp" #include "sctptransport.hpp"
@ -255,13 +255,12 @@ void DataChannel::incoming(message_ptr message) {
} }
} }
NegotiatedDataChannel::NegotiatedDataChannel(std::weak_ptr<impl::PeerConnection> pc, NegotiatedDataChannel::NegotiatedDataChannel(std::weak_ptr<PeerConnection> pc, uint16_t stream,
uint16_t stream, string label, string protocol, string label, string protocol, Reliability reliability)
Reliability reliability)
: DataChannel(pc, stream, std::move(label), std::move(protocol), std::move(reliability)) {} : DataChannel(pc, stream, std::move(label), std::move(protocol), std::move(reliability)) {}
NegotiatedDataChannel::NegotiatedDataChannel(std::weak_ptr<impl::PeerConnection> pc, NegotiatedDataChannel::NegotiatedDataChannel(std::weak_ptr<PeerConnection> pc,
std::weak_ptr<impl::SctpTransport> transport, std::weak_ptr<SctpTransport> transport,
uint16_t stream) uint16_t stream)
: DataChannel(pc, stream, "", "", {}) { : DataChannel(pc, stream, "", "", {}) {
mSctpTransport = transport; mSctpTransport = transport;
@ -269,7 +268,7 @@ NegotiatedDataChannel::NegotiatedDataChannel(std::weak_ptr<impl::PeerConnection>
NegotiatedDataChannel::~NegotiatedDataChannel() {} NegotiatedDataChannel::~NegotiatedDataChannel() {}
void NegotiatedDataChannel::open(shared_ptr<impl::SctpTransport> transport) { void NegotiatedDataChannel::open(shared_ptr<SctpTransport> transport) {
std::unique_lock lock(mMutex); std::unique_lock lock(mMutex);
mSctpTransport = transport; mSctpTransport = transport;
@ -278,7 +277,7 @@ void NegotiatedDataChannel::open(shared_ptr<impl::SctpTransport> transport) {
switch (mReliability->type) { switch (mReliability->type) {
case Reliability::Type::Rexmit: case Reliability::Type::Rexmit:
channelType = CHANNEL_PARTIAL_RELIABLE_REXMIT; channelType = CHANNEL_PARTIAL_RELIABLE_REXMIT;
reliabilityParameter = uint32_t(std::get<int>(mReliability->rexmit)); reliabilityParameter = uint32_t(std::max(std::get<int>(mReliability->rexmit), 0));
break; break;
case Reliability::Type::Timed: case Reliability::Type::Timed:

View File

@ -34,7 +34,7 @@ namespace rtc::impl {
struct PeerConnection; struct PeerConnection;
struct DataChannel : Channel, std::enable_shared_from_this<DataChannel> { struct DataChannel : Channel, std::enable_shared_from_this<DataChannel> {
DataChannel(weak_ptr<impl::PeerConnection> pc, uint16_t stream, string label, string protocol, DataChannel(weak_ptr<PeerConnection> pc, uint16_t stream, string label, string protocol,
Reliability reliability); Reliability reliability);
~DataChannel(); ~DataChannel();
@ -79,13 +79,13 @@ protected:
}; };
struct NegotiatedDataChannel final : public DataChannel { struct NegotiatedDataChannel final : public DataChannel {
NegotiatedDataChannel(weak_ptr<impl::PeerConnection> pc, uint16_t stream, string label, NegotiatedDataChannel(weak_ptr<PeerConnection> pc, uint16_t stream, string label,
string protocol, Reliability reliability); string protocol, Reliability reliability);
NegotiatedDataChannel(weak_ptr<impl::PeerConnection> pc, NegotiatedDataChannel(weak_ptr<PeerConnection> pc,
weak_ptr<impl::SctpTransport> transport, uint16_t stream); weak_ptr<SctpTransport> transport, uint16_t stream);
~NegotiatedDataChannel(); ~NegotiatedDataChannel();
void open(impl_ptr<impl::SctpTransport> transport) override; void open(impl_ptr<SctpTransport> transport) override;
void processOpenMessage(message_ptr message) override; void processOpenMessage(message_ptr message) override;
}; };

View File

@ -159,7 +159,7 @@ void DtlsTransport::runRecvLoop() {
try { try {
changeState(State::Connecting); changeState(State::Connecting);
size_t mtu = mMtu.value_or(DEFAULT_IPV4_MTU + 20) - 8 - 40; // UDP/IPv6 size_t mtu = mMtu.value_or(DEFAULT_MTU) - 8 - 40; // UDP/IPv6
gnutls_dtls_set_mtu(mSession, static_cast<unsigned int>(mtu)); gnutls_dtls_set_mtu(mSession, static_cast<unsigned int>(mtu));
PLOG_VERBOSE << "SSL MTU set to " << mtu; PLOG_VERBOSE << "SSL MTU set to " << mtu;
@ -445,7 +445,7 @@ void DtlsTransport::runRecvLoop() {
try { try {
changeState(State::Connecting); changeState(State::Connecting);
size_t mtu = mMtu.value_or(DEFAULT_IPV4_MTU + 20) - 8 - 40; // UDP/IPv6 size_t mtu = mMtu.value_or(DEFAULT_MTU) - 8 - 40; // UDP/IPv6
SSL_set_mtu(mSsl, static_cast<unsigned int>(mtu)); SSL_set_mtu(mSsl, static_cast<unsigned int>(mtu));
PLOG_VERBOSE << "SSL MTU set to " << mtu; PLOG_VERBOSE << "SSL MTU set to " << mtu;

View File

@ -19,10 +19,10 @@
#include "peerconnection.hpp" #include "peerconnection.hpp"
#include "certificate.hpp" #include "certificate.hpp"
#include "common.hpp"
#include "dtlstransport.hpp" #include "dtlstransport.hpp"
#include "globals.hpp" #include "globals.hpp"
#include "icetransport.hpp" #include "icetransport.hpp"
#include "common.hpp"
#include "logcounter.hpp" #include "logcounter.hpp"
#include "peerconnection.hpp" #include "peerconnection.hpp"
#include "processor.hpp" #include "processor.hpp"
@ -393,7 +393,7 @@ void PeerConnection::forwardMessage(message_ptr message) {
stream % 2 == remoteParity) { stream % 2 == remoteParity) {
channel = channel =
std::make_shared<NegotiatedDataChannel>(shared_from_this(), sctpTransport, stream); std::make_shared<NegotiatedDataChannel>(weak_from_this(), sctpTransport, stream);
channel->openCallback = weak_bind(&PeerConnection::triggerDataChannel, this, channel->openCallback = weak_bind(&PeerConnection::triggerDataChannel, this,
weak_ptr<DataChannel>{channel}); weak_ptr<DataChannel>{channel});
@ -562,9 +562,9 @@ shared_ptr<DataChannel> PeerConnection::emplaceDataChannel(Description::Role rol
// If the DataChannel is user-negotiated, do not negociate it here // If the DataChannel is user-negotiated, do not negociate it here
auto channel = auto channel =
init.negotiated init.negotiated
? std::make_shared<DataChannel>(shared_from_this(), stream, std::move(label), ? std::make_shared<DataChannel>(weak_from_this(), stream, std::move(label),
std::move(init.protocol), std::move(init.reliability)) std::move(init.protocol), std::move(init.reliability))
: std::make_shared<NegotiatedDataChannel>(shared_from_this(), stream, std::move(label), : std::make_shared<NegotiatedDataChannel>(weak_from_this(), stream, std::move(label),
std::move(init.protocol), std::move(init.protocol),
std::move(init.reliability)); std::move(init.reliability));
mDataChannels.emplace(std::make_pair(stream, channel)); mDataChannels.emplace(std::make_pair(stream, channel));
@ -647,7 +647,7 @@ shared_ptr<Track> PeerConnection::emplaceTrack(Description::Media description) {
track->setDescription(std::move(description)); track->setDescription(std::move(description));
if (!track) { if (!track) {
track = std::make_shared<Track>(std::move(description)); track = std::make_shared<Track>(weak_from_this(), std::move(description));
mTracks.emplace(std::make_pair(track->mid(), track)); mTracks.emplace(std::make_pair(track->mid(), track));
mTrackLines.emplace_back(track); mTrackLines.emplace_back(track);
} }
@ -663,7 +663,7 @@ void PeerConnection::incomingTrack(Description::Media description) {
} }
#endif #endif
if (mTracks.find(description.mid()) == mTracks.end()) { if (mTracks.find(description.mid()) == mTracks.end()) {
auto track = std::make_shared<Track>(std::move(description)); auto track = std::make_shared<Track>(weak_from_this(), std::move(description));
mTracks.emplace(std::make_pair(track->mid(), track)); mTracks.emplace(std::make_pair(track->mid(), track));
mTrackLines.emplace_back(track); mTrackLines.emplace_back(track);
triggerTrack(track); triggerTrack(track);

View File

@ -19,15 +19,21 @@
#ifndef RTC_IMPL_PEER_CONNECTION_H #ifndef RTC_IMPL_PEER_CONNECTION_H
#define RTC_IMPL_PEER_CONNECTION_H #define RTC_IMPL_PEER_CONNECTION_H
#include "common.hpp"
#include "datachannel.hpp" #include "datachannel.hpp"
#include "dtlstransport.hpp" #include "dtlstransport.hpp"
#include "icetransport.hpp" #include "icetransport.hpp"
#include "common.hpp"
#include "sctptransport.hpp" #include "sctptransport.hpp"
#include "track.hpp" #include "track.hpp"
#include "rtc/peerconnection.hpp" #include "rtc/peerconnection.hpp"
#include <mutex>
#include <optional>
#include <shared_mutex>
#include <unordered_map>
#include <vector>
namespace rtc::impl { namespace rtc::impl {
struct PeerConnection : std::enable_shared_from_this<PeerConnection> { struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
@ -43,12 +49,12 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
std::optional<Description> localDescription() const; std::optional<Description> localDescription() const;
std::optional<Description> remoteDescription() const; std::optional<Description> remoteDescription() const;
std::shared_ptr<IceTransport> initIceTransport(); shared_ptr<IceTransport> initIceTransport();
std::shared_ptr<DtlsTransport> initDtlsTransport(); shared_ptr<DtlsTransport> initDtlsTransport();
std::shared_ptr<SctpTransport> initSctpTransport(); shared_ptr<SctpTransport> initSctpTransport();
std::shared_ptr<IceTransport> getIceTransport() const; shared_ptr<IceTransport> getIceTransport() const;
std::shared_ptr<DtlsTransport> getDtlsTransport() const; shared_ptr<DtlsTransport> getDtlsTransport() const;
std::shared_ptr<SctpTransport> getSctpTransport() const; shared_ptr<SctpTransport> getSctpTransport() const;
void closeTransports(); void closeTransports();
void endLocalCandidates(); void endLocalCandidates();
@ -63,7 +69,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
DataChannelInit init); DataChannelInit init);
shared_ptr<DataChannel> findDataChannel(uint16_t stream); shared_ptr<DataChannel> findDataChannel(uint16_t stream);
void shiftDataChannels(); void shiftDataChannels();
void iterateDataChannels(std::function<void(std::shared_ptr<DataChannel> channel)> func); void iterateDataChannels(std::function<void(shared_ptr<DataChannel> channel)> func);
void openDataChannels(); void openDataChannels();
void closeDataChannels(); void closeDataChannels();
void remoteCloseDataChannels(); void remoteCloseDataChannels();
@ -80,7 +86,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
string localBundleMid() const; string localBundleMid() const;
void triggerDataChannel(std::weak_ptr<DataChannel> weakDataChannel); void triggerDataChannel(std::weak_ptr<DataChannel> weakDataChannel);
void triggerTrack(std::shared_ptr<Track> track); void triggerTrack(shared_ptr<Track> track);
bool changeState(State newState); bool changeState(State newState);
bool changeGatheringState(GatheringState newState); bool changeGatheringState(GatheringState newState);
bool changeSignalingState(SignalingState newState); bool changeSignalingState(SignalingState newState);
@ -95,26 +101,26 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
std::atomic<SignalingState> signalingState = SignalingState::Stable; std::atomic<SignalingState> signalingState = SignalingState::Stable;
std::atomic<bool> negotiationNeeded = false; std::atomic<bool> negotiationNeeded = false;
synchronized_callback<std::shared_ptr<rtc::DataChannel>> dataChannelCallback; synchronized_callback<shared_ptr<rtc::DataChannel>> dataChannelCallback;
synchronized_callback<Description> localDescriptionCallback; synchronized_callback<Description> localDescriptionCallback;
synchronized_callback<Candidate> localCandidateCallback; synchronized_callback<Candidate> localCandidateCallback;
synchronized_callback<State> stateChangeCallback; synchronized_callback<State> stateChangeCallback;
synchronized_callback<GatheringState> gatheringStateChangeCallback; synchronized_callback<GatheringState> gatheringStateChangeCallback;
synchronized_callback<SignalingState> signalingStateChangeCallback; synchronized_callback<SignalingState> signalingStateChangeCallback;
synchronized_callback<std::shared_ptr<rtc::Track>> trackCallback; synchronized_callback<shared_ptr<rtc::Track>> trackCallback;
private: private:
const init_token mInitToken = Init::Token(); const init_token mInitToken = Init::Token();
const future_certificate_ptr mCertificate; const future_certificate_ptr mCertificate;
const std::unique_ptr<Processor> mProcessor; const unique_ptr<Processor> mProcessor;
std::optional<Description> mLocalDescription, mRemoteDescription; std::optional<Description> mLocalDescription, mRemoteDescription;
std::optional<Description> mCurrentLocalDescription; std::optional<Description> mCurrentLocalDescription;
mutable std::mutex mLocalDescriptionMutex, mRemoteDescriptionMutex; mutable std::mutex mLocalDescriptionMutex, mRemoteDescriptionMutex;
std::shared_ptr<IceTransport> mIceTransport; shared_ptr<IceTransport> mIceTransport;
std::shared_ptr<DtlsTransport> mDtlsTransport; shared_ptr<DtlsTransport> mDtlsTransport;
std::shared_ptr<SctpTransport> mSctpTransport; shared_ptr<SctpTransport> mSctpTransport;
std::unordered_map<uint16_t, std::weak_ptr<DataChannel>> mDataChannels; // by stream ID std::unordered_map<uint16_t, std::weak_ptr<DataChannel>> mDataChannels; // by stream ID
std::unordered_map<string, std::weak_ptr<Track>> mTracks; // by mid std::unordered_map<string, std::weak_ptr<Track>> mTracks; // by mid

View File

@ -193,7 +193,7 @@ SctpTransport::SctpTransport(std::shared_ptr<Transport> lower, uint16_t port,
spp.spp_flags |= SPP_PMTUD_DISABLE; spp.spp_flags |= SPP_PMTUD_DISABLE;
// The MTU value provided specifies the space available for chunks in the // The MTU value provided specifies the space available for chunks in the
// packet, so we also subtract the SCTP header size. // packet, so we also subtract the SCTP header size.
size_t pmtu = mtu.value_or(DEFAULT_IPV4_MTU + 20) - 12 - 37 - 8 - 40; // SCTP/DTLS/UDP/IPv6 size_t pmtu = mtu.value_or(DEFAULT_MTU) - 12 - 37 - 8 - 40; // SCTP/DTLS/UDP/IPv6
spp.spp_pathmtu = uint32_t(pmtu); spp.spp_pathmtu = uint32_t(pmtu);
PLOG_VERBOSE << "Path MTU discovery disabled, SCTP MTU set to " << pmtu; PLOG_VERBOSE << "Path MTU discovery disabled, SCTP MTU set to " << pmtu;
} }

View File

@ -19,6 +19,7 @@
#include "track.hpp" #include "track.hpp"
#include "globals.hpp" #include "globals.hpp"
#include "logcounter.hpp" #include "logcounter.hpp"
#include "peerconnection.hpp"
namespace rtc::impl { namespace rtc::impl {
@ -27,8 +28,9 @@ static LogCounter COUNTER_MEDIA_BAD_DIRECTION(plog::warning,
static LogCounter COUNTER_QUEUE_FULL(plog::warning, static LogCounter COUNTER_QUEUE_FULL(plog::warning,
"Number of media packets dropped due to a full queue"); "Number of media packets dropped due to a full queue");
Track::Track(Description::Media description) Track::Track(weak_ptr<PeerConnection> pc, Description::Media description)
: mMediaDescription(std::move(description)), mRecvQueue(RECV_QUEUE_LIMIT, message_size_func) {} : mPeerConnection(pc), mMediaDescription(std::move(description)),
mRecvQueue(RECV_QUEUE_LIMIT, message_size_func) {}
string Track::mid() const { string Track::mid() const {
std::shared_lock lock(mMutex); std::shared_lock lock(mMutex);
@ -74,6 +76,8 @@ std::optional<message_variant> Track::peek() {
return nullopt; return nullopt;
} }
size_t Track::availableAmount() const { return mRecvQueue.amount(); }
bool Track::isOpen(void) const { bool Track::isOpen(void) const {
#if RTC_ENABLE_MEDIA #if RTC_ENABLE_MEDIA
std::shared_lock lock(mMutex); std::shared_lock lock(mMutex);
@ -85,7 +89,13 @@ bool Track::isOpen(void) const {
bool Track::isClosed(void) const { return mIsClosed; } bool Track::isClosed(void) const { return mIsClosed; }
size_t Track::availableAmount() const { return mRecvQueue.amount(); } size_t Track::maxMessageSize() const {
std::optional<size_t> mtu;
if (auto pc = mPeerConnection.lock())
mtu = pc->config.mtu;
return mtu.value_or(DEFAULT_MTU) - 12 - 8 - 40; // SRTP/UDP/IPv6
}
#if RTC_ENABLE_MEDIA #if RTC_ENABLE_MEDIA
void Track::open(shared_ptr<DtlsSrtpTransport> transport) { void Track::open(shared_ptr<DtlsSrtpTransport> transport) {

View File

@ -35,9 +35,11 @@
namespace rtc::impl { namespace rtc::impl {
struct PeerConnection;
class Track final : public std::enable_shared_from_this<Track>, public Channel { class Track final : public std::enable_shared_from_this<Track>, public Channel {
public: public:
Track(Description::Media description); Track(weak_ptr<PeerConnection> pc, Description::Media description);
~Track() = default; ~Track() = default;
void close(); void close();
@ -50,6 +52,7 @@ public:
bool isOpen() const; bool isOpen() const;
bool isClosed() const; bool isClosed() const;
size_t maxMessageSize() const;
string mid() const; string mid() const;
Description::Direction direction() const; Description::Direction direction() const;
@ -66,6 +69,7 @@ public:
private: private:
bool transportSend(message_ptr message); bool transportSend(message_ptr message);
const weak_ptr<PeerConnection> mPeerConnection;
#if RTC_ENABLE_MEDIA #if RTC_ENABLE_MEDIA
weak_ptr<DtlsSrtpTransport> mDtlsSrtpTransport; weak_ptr<DtlsSrtpTransport> mDtlsSrtpTransport;
#endif #endif

View File

@ -19,6 +19,8 @@
#if RTC_ENABLE_MEDIA #if RTC_ENABLE_MEDIA
#include "nalunit.hpp" #include "nalunit.hpp"
#include "globals.hpp"
#include <cmath> #include <cmath>
namespace rtc { namespace rtc {

View File

@ -47,7 +47,7 @@ bool Track::isOpen(void) const { return impl()->isOpen(); }
bool Track::isClosed(void) const { return impl()->isClosed(); } bool Track::isClosed(void) const { return impl()->isClosed(); }
size_t Track::maxMessageSize() const { size_t Track::maxMessageSize() const {
return DEFAULT_IPV4_MTU - 12 - 8 - 20; // SRTP/UDP/IPv4 return impl()->maxMessageSize();
} }
void Track::setRtcpHandler(std::shared_ptr<MediaHandler> handler) { void Track::setRtcpHandler(std::shared_ptr<MediaHandler> handler) {