Sfoglia il codice sorgente

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

Harmonize MTU with fragment size
Paul-Louis Ageneau 4 anni fa
parent
commit
3c9c5bb37b

+ 6 - 4
include/rtc/common.hpp

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

+ 7 - 7
include/rtc/nalunit.hpp

@@ -62,11 +62,9 @@ private:
 /// Nal unit
 struct RTC_CPP_EXPORT NalUnit : binary {
 	NalUnit(const NalUnit &unit) = default;
-	NalUnit(size_t size, bool includingHeader = true)
-		: binary(size + (includingHeader ? 0 : 1)) {}
+	NalUnit(size_t size, bool includingHeader = true) : binary(size + (includingHeader ? 0 : 1)) {}
 
-	template <typename Iterator>
-	NalUnit(Iterator begin_, Iterator end_) : binary(begin_, end_) {}
+	template <typename Iterator> NalUnit(Iterator begin_, Iterator end_) : binary(begin_, end_) {}
 
 	NalUnit(binary &&data) : binary(std::move(data)) {}
 
@@ -101,9 +99,10 @@ struct RTC_CPP_EXPORT NalUnitFragmentA : NalUnit {
 	enum class FragmentType { Start, Middle, End };
 
 	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(); }
 
@@ -144,7 +143,8 @@ protected:
 
 class RTC_CPP_EXPORT NalUnits : public std::vector<std::shared_ptr<NalUnit>> {
 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);
 };
 

+ 0 - 1
include/rtc/peerconnection.hpp

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

+ 10 - 3
include/rtc/rtc.h

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

+ 10 - 2
include/rtc/rtc.hpp

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

+ 19 - 20
src/capi.cpp

@@ -16,16 +16,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "common.hpp"
-
 #include "rtc.h"
 
-#include "datachannel.hpp"
-#include "log.hpp"
-#include "peerconnection.hpp"
-#if RTC_ENABLE_WEBSOCKET
-#include "websocket.hpp"
-#endif
+#include "rtc.hpp"
 
 #include "plog/Formatters/FuncMessageFormatter.h"
 
@@ -359,12 +352,16 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) {
 		for (int i = 0; i < config->iceServersCount; ++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.portRangeEnd = config->portRangeEnd;
 		}
 
-		c.enableIceTcp = config->enableIceTcp;
+		if(config->mtu > 0)
+			c.mtu = size_t(config->mtu);
+
 		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);
 				} else {
 					dci.reliability.type = Reliability::Type::Rexmit;
-					dci.reliability.rexmit = int(reliability->maxRetransmits);
+					dci.reliability.rexmit = reliability->maxRetransmits;
 				}
 			} else {
 				dci.reliability.type = Reliability::Type::Reliable;
@@ -447,7 +444,8 @@ int rtcDeleteDataChannel(int dc) {
 
 #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;
 	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,
-				  rtcDirection _direction, const char *_name, const char *_msid, const char *_trackID) {
+                  rtcDirection _direction, const char *_name, const char *_msid,
+                  const char *_trackID) {
 	return wrap([&] {
 		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,
-                                   uint32_t clockRate, uint16_t maxFragmentSize, uint16_t sequenceNumber,
-                                   uint32_t timestamp) {
+                                   uint32_t clockRate, uint16_t maxFragmentSize,
+                                   uint16_t sequenceNumber, uint32_t timestamp) {
 	return wrap([&] {
 		auto track = getTrack(tr);
 		// create RTP configuration
 		auto rtpConfig = getNewRtpPacketizationConfig(ssrc, cname, payloadType, clockRate,
-													  sequenceNumber, timestamp);
+		                                              sequenceNumber, timestamp);
 		// create packetizer
 		auto packetizer = std::make_shared<H264RtpPacketizer>(rtpConfig, maxFragmentSize);
 		// 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);
 		// create Opus handler
 		auto opusHandler = std::make_shared<OpusPacketizationHandler>(packetizer);
-        emplaceMediaChainableHandler(opusHandler, tr);
+		emplaceMediaChainableHandler(opusHandler, tr);
 		emplaceRTPConfig(rtpConfig, tr);
 		// set handler
 		track->setRtcpHandler(opusHandler);
@@ -674,7 +673,7 @@ int rtcGetPreviousTrackSenderReportTimestamp(int id, uint32_t *timestamp) {
 }
 
 int rtcSetNeedsToSendRtcpSr(int id) {
-	return wrap([id]{
+	return wrap([id] {
 		auto sender = getRtcpSrReporter(id);
 		sender->setNeedsToReport();
 		return RTC_ERR_SUCCESS;
@@ -1012,10 +1011,10 @@ int rtcGetDataChannelReliability(int dc, rtcReliability *reliability) {
 		reliability->unordered = dcr.unordered;
 		if (dcr.type == Reliability::Type::Timed) {
 			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) {
 			reliability->unreliable = true;
-			reliability->maxRetransmits = unsigned(std::get<int>(dcr.rexmit));
+			reliability->maxRetransmits = std::get<int>(dcr.rexmit);
 		} else {
 			reliability->unreliable = false;
 		}

+ 1 - 1
src/globals.hpp

@@ -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 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
 

+ 7 - 8
src/impl/datachannel.cpp

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

+ 5 - 5
src/impl/datachannel.hpp

@@ -34,7 +34,7 @@ namespace rtc::impl {
 struct PeerConnection;
 
 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);
 	~DataChannel();
 
@@ -79,13 +79,13 @@ protected:
 };
 
 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);
-	NegotiatedDataChannel(weak_ptr<impl::PeerConnection> pc,
-	                      weak_ptr<impl::SctpTransport> transport, uint16_t stream);
+	NegotiatedDataChannel(weak_ptr<PeerConnection> pc,
+	                      weak_ptr<SctpTransport> transport, uint16_t stream);
 	~NegotiatedDataChannel();
 
-	void open(impl_ptr<impl::SctpTransport> transport) override;
+	void open(impl_ptr<SctpTransport> transport) override;
 	void processOpenMessage(message_ptr message) override;
 };
 

+ 2 - 2
src/impl/dtlstransport.cpp

@@ -159,7 +159,7 @@ void DtlsTransport::runRecvLoop() {
 	try {
 		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));
 		PLOG_VERBOSE << "SSL MTU set to " << mtu;
 
@@ -445,7 +445,7 @@ void DtlsTransport::runRecvLoop() {
 	try {
 		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));
 		PLOG_VERBOSE << "SSL MTU set to " << mtu;
 

+ 6 - 6
src/impl/peerconnection.cpp

@@ -19,10 +19,10 @@
 
 #include "peerconnection.hpp"
 #include "certificate.hpp"
+#include "common.hpp"
 #include "dtlstransport.hpp"
 #include "globals.hpp"
 #include "icetransport.hpp"
-#include "common.hpp"
 #include "logcounter.hpp"
 #include "peerconnection.hpp"
 #include "processor.hpp"
@@ -393,7 +393,7 @@ void PeerConnection::forwardMessage(message_ptr message) {
 		    stream % 2 == remoteParity) {
 
 			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,
 			                                  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
 	auto channel =
 	    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::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.reliability));
 	mDataChannels.emplace(std::make_pair(stream, channel));
@@ -647,7 +647,7 @@ shared_ptr<Track> PeerConnection::emplaceTrack(Description::Media description) {
 			track->setDescription(std::move(description));
 
 	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));
 		mTrackLines.emplace_back(track);
 	}
@@ -663,7 +663,7 @@ void PeerConnection::incomingTrack(Description::Media description) {
 	}
 #endif
 	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));
 		mTrackLines.emplace_back(track);
 		triggerTrack(track);

+ 21 - 15
src/impl/peerconnection.hpp

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

+ 1 - 1
src/impl/sctptransport.cpp

@@ -193,7 +193,7 @@ SctpTransport::SctpTransport(std::shared_ptr<Transport> lower, uint16_t port,
 		spp.spp_flags |= SPP_PMTUD_DISABLE;
 		// The MTU value provided specifies the space available for chunks in the
 		// 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);
 		PLOG_VERBOSE << "Path MTU discovery disabled, SCTP MTU set to " << pmtu;
 	}

+ 13 - 3
src/impl/track.cpp

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

+ 5 - 1
src/impl/track.hpp

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

+ 2 - 0
src/nalunit.cpp

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

+ 1 - 1
src/track.cpp

@@ -47,7 +47,7 @@ bool Track::isOpen(void) const { return impl()->isOpen(); }
 bool Track::isClosed(void) const { return impl()->isClosed(); }
 
 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) {