9f8552fab5
* gnu/packages/patches/icecat-CVE-2014-1587-bug-1042567.patch, gnu/packages/patches/icecat-CVE-2014-1587-bug-1072847.patch, gnu/packages/patches/icecat-CVE-2014-1587-bug-1079729.patch, gnu/packages/patches/icecat-CVE-2014-1587-bug-1080312.patch, gnu/packages/patches/icecat-CVE-2014-1587-bug-1089207.patch, gnu/packages/patches/icecat-CVE-2014-1590.patch, gnu/packages/patches/icecat-CVE-2014-1592.patch, gnu/packages/patches/icecat-CVE-2014-1593.patch, gnu/packages/patches/icecat-CVE-2014-1594.patch: New files. * gnu-system.am (dist_patch_DATA): Add them. * gnu/packages/gnuzilla.scm (icecat): Add them.
192 lines
8.7 KiB
Diff
192 lines
8.7 KiB
Diff
commit 5de6730cc26744b9efcf4d4adb4a4c45023ef8a0
|
|
Author: Randell Jesup <rjesup@jesup.org>
|
|
Date: Tue Oct 28 11:06:00 2014 -0400
|
|
|
|
Bug 1079729: Fix handling of increasing number of SCTP channels used by DataChannels r=tuexen a=lsblakk
|
|
|
|
Modified media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h
|
|
diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h
|
|
index ba8e1ff..8d964f1 100755
|
|
--- a/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h
|
|
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h
|
|
@@ -225,7 +225,7 @@ typedef struct fsmdef_media_t_ {
|
|
/*
|
|
* Data Channel properties
|
|
*/
|
|
-#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 16
|
|
+#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 256
|
|
uint32 datachannel_streams;
|
|
char datachannel_protocol[SDP_MAX_STRING_LEN + 1];
|
|
|
|
Modified netwerk/sctp/datachannel/DataChannel.cpp
|
|
diff --git a/netwerk/sctp/datachannel/DataChannel.cpp b/netwerk/sctp/datachannel/DataChannel.cpp
|
|
index 414e3db..a00d938 100644
|
|
--- a/netwerk/sctp/datachannel/DataChannel.cpp
|
|
+++ b/netwerk/sctp/datachannel/DataChannel.cpp
|
|
@@ -910,10 +910,12 @@ DataChannelConnection::RequestMoreStreams(int32_t aNeeded)
|
|
uint32_t outStreamsNeeded;
|
|
socklen_t len;
|
|
|
|
- if (aNeeded + mStreams.Length() > MAX_NUM_STREAMS)
|
|
+ if (aNeeded + mStreams.Length() > MAX_NUM_STREAMS) {
|
|
aNeeded = MAX_NUM_STREAMS - mStreams.Length();
|
|
- if (aNeeded <= 0)
|
|
+ }
|
|
+ if (aNeeded <= 0) {
|
|
return false;
|
|
+ }
|
|
|
|
len = (socklen_t)sizeof(struct sctp_status);
|
|
if (usrsctp_getsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_STATUS, &status, &len) < 0) {
|
|
@@ -922,19 +924,25 @@ DataChannelConnection::RequestMoreStreams(int32_t aNeeded)
|
|
}
|
|
outStreamsNeeded = aNeeded; // number to add
|
|
|
|
- memset(&sas, 0, sizeof(struct sctp_add_streams));
|
|
+ // Note: if multiple channel opens happen when we don't have enough space,
|
|
+ // we'll call RequestMoreStreams() multiple times
|
|
+ memset(&sas, 0, sizeof(sas));
|
|
sas.sas_instrms = 0;
|
|
sas.sas_outstrms = (uint16_t)outStreamsNeeded; /* XXX error handling */
|
|
// Doesn't block, we get an event when it succeeds or fails
|
|
if (usrsctp_setsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_ADD_STREAMS, &sas,
|
|
(socklen_t) sizeof(struct sctp_add_streams)) < 0) {
|
|
- if (errno == EALREADY)
|
|
+ if (errno == EALREADY) {
|
|
+ LOG(("Already have %u output streams", outStreamsNeeded));
|
|
return true;
|
|
+ }
|
|
|
|
LOG(("***failed: setsockopt ADD errno=%d", errno));
|
|
return false;
|
|
}
|
|
LOG(("Requested %u more streams", outStreamsNeeded));
|
|
+ // We add to mStreams when we get a SCTP_STREAM_CHANGE_EVENT and the
|
|
+ // values are larger than mStreams.Length()
|
|
return true;
|
|
}
|
|
|
|
@@ -1050,6 +1058,13 @@ DataChannelConnection::SendDeferredMessages()
|
|
channel->mFlags & DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED,
|
|
channel->mPrPolicy, channel->mPrValue)) {
|
|
channel->mFlags &= ~DATA_CHANNEL_FLAGS_SEND_REQ;
|
|
+
|
|
+ channel->mState = OPEN;
|
|
+ channel->mReady = true;
|
|
+ LOG(("%s: sending ON_CHANNEL_OPEN for %p", __FUNCTION__, channel.get()));
|
|
+ NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
|
|
+ DataChannelOnMessageAvailable::ON_CHANNEL_OPEN, this,
|
|
+ channel));
|
|
sent = true;
|
|
} else {
|
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
|
@@ -1177,6 +1192,7 @@ DataChannelConnection::HandleOpenRequestMessage(const struct rtcweb_datachannel_
|
|
prPolicy = SCTP_PR_SCTP_TTL;
|
|
break;
|
|
default:
|
|
+ LOG(("Unknown channel type", req->channel_type));
|
|
/* XXX error handling */
|
|
return;
|
|
}
|
|
@@ -1203,6 +1219,10 @@ DataChannelConnection::HandleOpenRequestMessage(const struct rtcweb_datachannel_
|
|
}
|
|
return;
|
|
}
|
|
+ if (stream >= mStreams.Length()) {
|
|
+ LOG(("%s: stream %u out of bounds (%u)", __FUNCTION__, stream, mStreams.Length()));
|
|
+ return;
|
|
+ }
|
|
|
|
nsCString label(nsDependentCSubstring(&req->label[0], ntohs(req->label_length)));
|
|
nsCString protocol(nsDependentCSubstring(&req->label[ntohs(req->label_length)],
|
|
@@ -1220,8 +1240,8 @@ DataChannelConnection::HandleOpenRequestMessage(const struct rtcweb_datachannel_
|
|
|
|
channel->mState = DataChannel::WAITING_TO_OPEN;
|
|
|
|
- LOG(("%s: sending ON_CHANNEL_CREATED for %s/%s: %u", __FUNCTION__,
|
|
- channel->mLabel.get(), channel->mProtocol.get(), stream));
|
|
+ LOG(("%s: sending ON_CHANNEL_CREATED for %s/%s: %u (state %u)", __FUNCTION__,
|
|
+ channel->mLabel.get(), channel->mProtocol.get(), stream, channel->mState));
|
|
NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
|
|
DataChannelOnMessageAvailable::ON_CHANNEL_CREATED,
|
|
this, channel));
|
|
@@ -1739,13 +1759,14 @@ DataChannelConnection::HandleStreamResetEvent(const struct sctp_stream_reset_eve
|
|
// 2. We sent our own reset (CLOSING); either they crossed on the
|
|
// wire, or this is a response to our Reset.
|
|
// Go to CLOSED
|
|
- // 3. We've sent a open but haven't gotten a response yet (OPENING)
|
|
+ // 3. We've sent a open but haven't gotten a response yet (CONNECTING)
|
|
// I believe this is impossible, as we don't have an input stream yet.
|
|
|
|
LOG(("Incoming: Channel %u closed, state %d",
|
|
channel->mStream, channel->mState));
|
|
ASSERT_WEBRTC(channel->mState == DataChannel::OPEN ||
|
|
channel->mState == DataChannel::CLOSING ||
|
|
+ channel->mState == DataChannel::CONNECTING ||
|
|
channel->mState == DataChannel::WAITING_TO_OPEN);
|
|
if (channel->mState == DataChannel::OPEN ||
|
|
channel->mState == DataChannel::WAITING_TO_OPEN) {
|
|
@@ -1791,20 +1812,21 @@ DataChannelConnection::HandleStreamChangeEvent(const struct sctp_stream_change_e
|
|
return;
|
|
} else {
|
|
if (strchg->strchange_instrms > mStreams.Length()) {
|
|
- LOG(("Other side increased streamds from %u to %u",
|
|
+ LOG(("Other side increased streams from %u to %u",
|
|
mStreams.Length(), strchg->strchange_instrms));
|
|
}
|
|
- if (strchg->strchange_outstrms > mStreams.Length()) {
|
|
+ if (strchg->strchange_outstrms > mStreams.Length() ||
|
|
+ strchg->strchange_instrms > mStreams.Length()) {
|
|
uint16_t old_len = mStreams.Length();
|
|
+ uint16_t new_len = std::max(strchg->strchange_outstrms,
|
|
+ strchg->strchange_instrms);
|
|
LOG(("Increasing number of streams from %u to %u - adding %u (in: %u)",
|
|
- old_len,
|
|
- strchg->strchange_outstrms,
|
|
- strchg->strchange_outstrms - old_len,
|
|
+ old_len, new_len, new_len - old_len,
|
|
strchg->strchange_instrms));
|
|
// make sure both are the same length
|
|
- mStreams.AppendElements(strchg->strchange_outstrms - old_len);
|
|
+ mStreams.AppendElements(new_len - old_len);
|
|
LOG(("New length = %d (was %d)", mStreams.Length(), old_len));
|
|
- for (uint32_t i = old_len; i < mStreams.Length(); ++i) {
|
|
+ for (size_t i = old_len; i < mStreams.Length(); ++i) {
|
|
mStreams[i] = nullptr;
|
|
}
|
|
// Re-process any channels waiting for streams.
|
|
@@ -1815,13 +1837,17 @@ DataChannelConnection::HandleStreamChangeEvent(const struct sctp_stream_change_e
|
|
// Could make a more complex API for OpenXxxFinish() and avoid this loop
|
|
int32_t num_needed = mPending.GetSize();
|
|
LOG(("%d of %d new streams already needed", num_needed,
|
|
- strchg->strchange_outstrms - old_len));
|
|
- num_needed -= (strchg->strchange_outstrms - old_len); // number we added
|
|
+ new_len - old_len));
|
|
+ num_needed -= (new_len - old_len); // number we added
|
|
if (num_needed > 0) {
|
|
if (num_needed < 16)
|
|
num_needed = 16;
|
|
LOG(("Not enough new streams, asking for %d more", num_needed));
|
|
RequestMoreStreams(num_needed);
|
|
+ } else if (strchg->strchange_outstrms < strchg->strchange_instrms) {
|
|
+ LOG(("Requesting %d output streams to match partner",
|
|
+ strchg->strchange_instrms - strchg->strchange_outstrms));
|
|
+ RequestMoreStreams(strchg->strchange_instrms - strchg->strchange_outstrms);
|
|
}
|
|
|
|
ProcessQueuedOpens();
|
|
Modified netwerk/sctp/datachannel/DataChannelProtocol.h
|
|
diff --git a/netwerk/sctp/datachannel/DataChannelProtocol.h b/netwerk/sctp/datachannel/DataChannelProtocol.h
|
|
index 549f74b..74fbe58 100644
|
|
--- a/netwerk/sctp/datachannel/DataChannelProtocol.h
|
|
+++ b/netwerk/sctp/datachannel/DataChannelProtocol.h
|
|
@@ -17,7 +17,7 @@
|
|
#endif
|
|
|
|
// Duplicated in fsm.def
|
|
-#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 16
|
|
+#define WEBRTC_DATACHANNEL_STREAMS_DEFAULT 256
|
|
|
|
#define DATA_CHANNEL_PPID_CONTROL 50
|
|
#define DATA_CHANNEL_PPID_BINARY 52
|