Browse Source

Use the correct stream identifiers for creating DataChannels

Paul-Louis Ageneau 6 years ago
parent
commit
b0c4121560
2 changed files with 14 additions and 9 deletions
  1. 10 7
      src/peerconnection.cpp
  2. 4 2
      src/sctptransport.cpp

+ 10 - 7
src/peerconnection.cpp

@@ -21,9 +21,6 @@
 #include "icetransport.hpp"
 #include "sctptransport.hpp"
 
-#include <chrono>
-#include <random>
-
 namespace rtc {
 
 using namespace std::placeholders;
@@ -71,10 +68,16 @@ void PeerConnection::setRemoteCandidate(const string &candidate) {
 shared_ptr<DataChannel> PeerConnection::createDataChannel(const string &label,
                                                           const string &protocol,
                                                           const Reliability &reliability) {
-	auto seed = std::chrono::system_clock::now().time_since_epoch().count();
-	std::default_random_engine generator(seed);
-	std::uniform_int_distribution<uint16_t> uniform;
-	uint16_t stream = 0; // uniform(generator);
+	// The active side must use streams with even identifiers, whereas the passive side must use
+	// streams with odd identifiers.
+	// See https://tools.ietf.org/html/draft-ietf-rtcweb-data-protocol-09#section-6
+	auto role = mIceTransport ? mIceTransport->role() : Description::Role::Active;
+	unsigned int stream = (role == Description::Role::Active) ? 0 : 1;
+	while (mDataChannels.find(stream) != mDataChannels.end()) {
+		stream += 2;
+		if (stream >= 65535)
+			throw std::runtime_error("Too many DataChannels");
+	}
 
 	auto channel = std::make_shared<DataChannel>(stream, label, protocol, reliability);
 	mDataChannels.insert(std::make_pair(stream, channel));

+ 4 - 2
src/sctptransport.cpp

@@ -95,9 +95,11 @@ SctpTransport::SctpTransport(std::shared_ptr<Transport> lower, uint16_t port, re
 		throw std::runtime_error("Could not set socket option SCTP_EVENT, errno=" +
 		                         std::to_string(errno));
 
+	// The IETF draft recommends the number of streams negotiated during SCTP association to be
+	// 65535. See https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.2
 	struct sctp_initmsg sinit = {};
-	sinit.sinit_num_ostreams = 0xFF;
-	sinit.sinit_max_instreams = 0xFF;
+	sinit.sinit_num_ostreams = 65535;
+	sinit.sinit_max_instreams = 65535;
 	if (usrsctp_setsockopt(mSock, IPPROTO_SCTP, SCTP_INITMSG, &sinit, sizeof(sinit)))
 		throw std::runtime_error("Could not set socket option SCTP_INITMSG, errno=" +
 		                         std::to_string(errno));