diff --git a/media/mtransport/nricectx.h b/media/mtransport/nricectx.h index 40a5912968e..c576e7d0ea5 100644 --- a/media/mtransport/nricectx.h +++ b/media/mtransport/nricectx.h @@ -81,6 +81,9 @@ namespace mozilla { class NrIceMediaStream; +const std::string kNrIceTransportUdp("udp"); +const std::string kNrIceTransportTcp("tcp"); + class NrIceStunServer { public: NrIceStunServer(const PRNetAddr& addr) : has_addr_(true) { @@ -134,7 +137,9 @@ class NrIceTurnServer : public NrIceStunServer { public: static NrIceTurnServer *Create(const std::string& addr, uint16_t port, const std::string& username, - const std::vector& password) { + const std::vector& password, + const std::string& transport = kNrIceTransportUdp) { + // TODO: Bug 906968 - Support TCP ScopedDeletePtr server( new NrIceTurnServer(username, password)); diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index 4b4a185c84c..ea6d098ebdd 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -573,6 +573,12 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc, for (uint32_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) { const RTCIceServer& server = aSrc.mIceServers.Value()[i]; NS_ENSURE_TRUE(server.mUrl.WasPassed(), NS_ERROR_UNEXPECTED); + + // Without STUN/TURN handlers, NS_NewURI returns nsSimpleURI rather than + // nsStandardURL. To parse STUN/TURN URI's to spec + // http://tools.ietf.org/html/draft-nandakumar-rtcweb-stun-uri-02#section-3 + // http://tools.ietf.org/html/draft-petithuguenin-behave-turn-uri-03#section-3 + // we parse out the query-string, and use ParseAuthority() on the rest nsRefPtr url; nsresult rv = NS_NewURI(getter_AddRefs(url), server.mUrl.Value()); NS_ENSURE_SUCCESS(rv, rv); @@ -588,9 +594,10 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc, rv = url->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); - // TODO(jib@mozilla.com): Revisit once nsURI has STUN host+port (Bug 833509) + // TODO(jib@mozilla.com): Revisit once nsURI supports STUN/TURN (Bug 833509) int32_t port; nsAutoCString host; + nsAutoCString transport; { uint32_t hostPos; int32_t hostLen; @@ -598,9 +605,20 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc, rv = url->GetPath(path); NS_ENSURE_SUCCESS(rv, rv); - // Tolerate '?transport=udp' by stripping it. + // Tolerate query-string + parse 'transport=[udp|tcp]' by hand. int32_t questionmark = path.FindChar('?'); if (questionmark >= 0) { + const nsCString match = NS_LITERAL_CSTRING("transport="); + + for (int32_t i = questionmark, endPos; i >= 0; i = endPos) { + endPos = path.FindCharInSet("&", i + 1); + const nsDependentCSubstring fieldvaluepair = Substring(path, i + 1, + endPos); + if (StringBeginsWith(fieldvaluepair, match)) { + transport = Substring(fieldvaluepair, match.Length()); + ToLowerCase(transport); + } + } path.SetLength(questionmark); } @@ -625,7 +643,9 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc, if (!aDst->addTurnServer(host.get(), port, username.get(), - credential.get())) { + credential.get(), + (transport.IsEmpty() ? + kNrIceTransportUdp : transport.get()))) { return NS_ERROR_FAILURE; } } else { diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h index de8fef6eb12..a175c7cc306 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h @@ -126,13 +126,15 @@ public: } bool addTurnServer(const std::string& addr, uint16_t port, const std::string& username, - const std::string& pwd) + const std::string& pwd, + const std::string& transport) { // TODO(ekr@rtfm.com): Need support for SASLprep for // username and password. Bug # ??? std::vector password(pwd.begin(), pwd.end()); - NrIceTurnServer* server(NrIceTurnServer::Create(addr, port, username, password)); + NrIceTurnServer* server(NrIceTurnServer::Create(addr, port, username, password, + transport)); if (!server) { return false; }