Add SetMaxMessageSize and GetMaxMessageSize methods. r?jesup
draft
Add SetMaxMessageSize and GetMaxMessageSize methods. r?jesup
* Add SetMaxMessageSize method for late-applying those signalling parameters
when a data channel has been created before the remote SDP was available.
* Limit remote maximum message size and add a GetMaxMessageSize method for a
future implementation of RTCSctpTransport.maxMessageSize.
MozReview-Commit-ID: JofnMeGfJEq
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -1090,19 +1090,17 @@ PeerConnectionImpl::EnsureDataConnection
uint16_t aNumstreams,
uint32_t aMaxMessageSize,
bool aMMSSet)
{
PC_AUTO_ENTER_API_CALL(false);
if (mDataConnection) {
CSFLogDebug(logTag,"%s DataConnection already connected",__FUNCTION__);
- // Ignore the request to connect when already connected. This entire
- // implementation is temporary. Ignore aNumstreams as it's merely advisory
- // and we increase the number of streams dynamically as needed.
+ mDataConnection->SetMaxMessageSize(aMMSSet, aMaxMessageSize);
return NS_OK;
}
nsCOMPtr<nsIEventTarget> target = mWindow
? mWindow->EventTargetFor(TaskCategory::Other)
: nullptr;
mDataConnection = new DataChannelConnection(this, target);
if (!mDataConnection->Init(aLocalPort, aNumstreams, aMMSSet, aMaxMessageSize)) {
--- a/netwerk/sctp/datachannel/DataChannel.cpp
+++ b/netwerk/sctp/datachannel/DataChannel.cpp
@@ -346,51 +346,24 @@ DataChannelConnection::Init(unsigned sho
SCTP_SHUTDOWN_EVENT,
SCTP_ADAPTATION_INDICATION,
SCTP_PARTIAL_DELIVERY_EVENT,
SCTP_SEND_FAILED_EVENT,
SCTP_STREAM_RESET_EVENT,
SCTP_STREAM_CHANGE_EVENT};
{
ASSERT_WEBRTC(NS_IsMainThread());
+ // MutexAutoLock lock(mLock); Not needed since we're on mainthread always
+
mSendInterleaved = false;
mPpidFragmentation = false;
- mMaxMessageSizeSet = aMaxMessageSizeSet;
- mMaxMessageSize = aMaxMessageSize;
-
- nsresult rv;
- nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
- if (!NS_WARN_IF(NS_FAILED(rv))) {
- nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
-
- if (branch) {
- if (!NS_FAILED(branch->GetBoolPref(
- "media.peerconnection.sctp.force_ppid_fragmentation", &mPpidFragmentation))) {
- // Ensure that forced on/off PPID fragmentation does not get overridden when Firefox has
- // been detected.
- mMaxMessageSizeSet = true;
- }
-
- int32_t temp;
- if (!NS_FAILED(branch->GetIntPref(
- "media.peerconnection.sctp.force_maximum_message_size", &temp))) {
- if (temp >= 0) {
- mMaxMessageSize = (uint64_t)temp;
- }
- }
- }
- }
-
- LOG(("Use PPID-based fragmentation/reassembly: %s", mPpidFragmentation ? "yes" : "no"));
- LOG(("Maximum message size (outgoing data): %" PRIu64 " (set=%s)",
- mMaxMessageSize, mMaxMessageSizeSet ? "yes" : "no"));
-
- // MutexAutoLock lock(mLock); Not needed since we're on mainthread always
+ SetMaxMessageSize(aMaxMessageSizeSet, aMaxMessageSize);
+
if (!sctp_initialized) {
- LOG(("sctp_init(DTLS)"));
+ LOG(("sctp_init"));
#ifdef MOZ_PEERCONNECTION
usrsctp_init(0,
DataChannelConnection::SctpDtlsOutput,
debug_printf
);
#else
MOZ_CRASH("Trying to use SCTP/DTLS without mtransport");
#endif
@@ -537,16 +510,72 @@ DataChannelConnection::Init(unsigned sho
return true;
error_cleanup:
usrsctp_close(mMasterSocket);
mMasterSocket = nullptr;
return false;
}
+void
+DataChannelConnection::SetMaxMessageSize(bool aMaxMessageSizeSet, uint64_t aMaxMessageSize)
+{
+ MutexAutoLock lock(mLock); // TODO: Needed?
+
+ mMaxMessageSizeSet = aMaxMessageSizeSet;
+ mMaxMessageSize = aMaxMessageSize;
+
+ bool ppidFragmentationEnforced = false;
+ nsresult rv;
+ nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
+ if (!NS_WARN_IF(NS_FAILED(rv))) {
+ nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
+
+ if (branch) {
+ if (!NS_FAILED(branch->GetBoolPref(
+ "media.peerconnection.sctp.force_ppid_fragmentation", &mPpidFragmentation))) {
+ // Ensure that forced on/off PPID fragmentation does not get overridden when Firefox has
+ // been detected.
+ mMaxMessageSizeSet = true;
+ ppidFragmentationEnforced = true;
+ }
+
+ int32_t temp;
+ if (!NS_FAILED(branch->GetIntPref(
+ "media.peerconnection.sctp.force_maximum_message_size", &temp))) {
+ if (temp >= 0) {
+ mMaxMessageSize = (uint64_t)temp;
+ }
+ }
+ }
+ }
+
+ // Fix remote MMS. This code exists, so future implementations of RTCSctpTransport.maxMessageSize
+ // can simply provide that value from GetMaxMessageSize.
+
+ // TODO: Bug 1382779, once resolved, can be increased to min(Uint8ArrayMaxSize, UINT32_MAX)
+ // TODO: Bug 1381146, once resolved, can be increased to whatever we support then (hopefully
+ // SIZE_MAX)
+ if (mMaxMessageSize == 0 || mMaxMessageSize > WEBRTC_DATACHANNEL_MAX_MESSAGE_SIZE_REMOTE) {
+ mMaxMessageSize = WEBRTC_DATACHANNEL_MAX_MESSAGE_SIZE_REMOTE;
+ }
+
+ LOG(("Use PPID-based fragmentation/reassembly: %s (enforced=%s)",
+ mPpidFragmentation ? "yes" : "no", ppidFragmentationEnforced ? "yes" : "no"));
+ LOG(("Maximum message size (outgoing data): %" PRIu64 " (set=%s, enforced=%s)",
+ mMaxMessageSize, mMaxMessageSizeSet ? "yes" : "no",
+ aMaxMessageSize != mMaxMessageSize ? "yes" : "no"));
+}
+
+uint64_t
+DataChannelConnection::GetMaxMessageSize()
+{
+ return mMaxMessageSize;
+}
+
#ifdef MOZ_PEERCONNECTION
void
DataChannelConnection::SetEvenOdd()
{
ASSERT_WEBRTC(IsSTSThread());
TransportLayerDtls *dtls = static_cast<TransportLayerDtls *>(
mTransportFlow->GetLayer(TransportLayerDtls::ID()));
@@ -1708,17 +1737,17 @@ DataChannelConnection::HandleAssociation
break;
}
LOG(("Association change: streams (in/out) = (%u/%u)",
sac->sac_inbound_streams, sac->sac_outbound_streams));
if (NS_WARN_IF(!sac)) {
return;
}
-
+
n = sac->sac_length - sizeof(*sac);
if ((sac->sac_state == SCTP_COMM_UP) || (sac->sac_state == SCTP_RESTART)) {
if (n > 0) {
for (i = 0; i < n; ++i) {
switch (sac->sac_info[i]) {
case SCTP_ASSOC_SUPPORTS_PR:
LOG(("Supports: PR"));
break;
--- a/netwerk/sctp/datachannel/DataChannel.h
+++ b/netwerk/sctp/datachannel/DataChannel.h
@@ -140,21 +140,25 @@ public:
virtual void NotifyDataChannel(already_AddRefed<DataChannel> channel) = 0;
};
explicit DataChannelConnection(DataConnectionListener *listener,
nsIEventTarget *aTarget);
bool Init(unsigned short aPort, uint16_t aNumStreams, bool aMaxMessageSizeSet,
uint64_t aMaxMessageSize);
+
void Destroy(); // So we can spawn refs tied to runnables in shutdown
// Finish Destroy on STS to avoid SCTP race condition with ABORT from far end
void DestroyOnSTS(struct socket *aMasterSocket,
struct socket *aSocket);
+ void SetMaxMessageSize(bool aMaxMessageSizeSet, uint64_t aMaxMessageSize);
+ uint64_t GetMaxMessageSize();
+
#ifdef ALLOW_DIRECT_SCTP_LISTEN_CONNECT
// These block; they require something to decide on listener/connector
// (though you can do simultaneous Connect()). Do not call these from
// the main thread!
bool Listen(unsigned short port);
bool Connect(const char *addr, unsigned short port);
#endif
--- a/netwerk/sctp/datachannel/DataChannelProtocol.h
+++ b/netwerk/sctp/datachannel/DataChannelProtocol.h
@@ -18,16 +18,20 @@
#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 256
// Do not change this value!
#define WEBRTC_DATACHANNEL_STREAMS_OLDER_FIREFOX 256
#define WEBRTC_DATACHANNEL_PORT_DEFAULT 5000
// TODO: Bug 1381146, change once we resolve the nsCString limitation
#define WEBRTC_DATACHANNEL_MAX_MESSAGE_SIZE_LOCAL 1073741823
#define WEBRTC_DATACHANNEL_MAX_MESSAGE_SIZE_REMOTE_DEFAULT 65535
+// TODO: Bug 1382779, once resolved, can be increased to min(Uint8ArrayMaxSize, UINT32_MAX)
+// TODO: Bug 1381146, once resolved, can be increased to whatever we support then (hopefully
+// SIZE_MAX) or be removed
+#define WEBRTC_DATACHANNEL_MAX_MESSAGE_SIZE_REMOTE 2147483637
#define DATA_CHANNEL_PPID_CONTROL 50
#define DATA_CHANNEL_PPID_BINARY_PARTIAL 52
#define DATA_CHANNEL_PPID_BINARY 53
#define DATA_CHANNEL_PPID_DOMSTRING_PARTIAL 54
#define DATA_CHANNEL_PPID_DOMSTRING 51
#define DATA_CHANNEL_MAX_BINARY_FRAGMENT 0x4000
@@ -44,17 +48,17 @@
#define DATA_CHANNEL_BUFFER_MESSAGE_FLAGS_COMPLETE 0x04
#define INVALID_STREAM (0xFFFF)
// max is 0xFFFF: Streams 0 to 0xFFFE = 0xFFFF streams
#define MAX_NUM_STREAMS (2048)
struct rtcweb_datachannel_open_request {
uint8_t msg_type; // DATA_CHANNEL_OPEN
- uint8_t channel_type;
+ uint8_t channel_type;
int16_t priority;
uint32_t reliability_param;
uint16_t label_length;
uint16_t protocol_length;
char label[1]; // (and protocol) keep VC++ happy...
} SCTP_PACKED;
struct rtcweb_datachannel_ack {