Bug 855769: Wire up TURN support in RTCPeerConnection config r=jesup

This commit is contained in:
Jan-Ivar Bruaroey 2013-03-29 19:02:08 -04:00
Родитель f7d3f3002b
Коммит 0466eb531d
7 изменённых файлов: 99 добавлений и 53 удалений

Просмотреть файл

@ -13,40 +13,56 @@
title: "RTCConfiguration valid/invalid permutations"
});
makePC = function (config, expect_success) {
var exception = null;
try {
var pc = new mozRTCPeerConnection(config);
} catch (e) {
exception = e;
}
if (expect_success) {
ok(!exception, "mozRTCPeerConnection(" +
JSON.stringify(config) + ") succeeds");
} else {
ok(exception, "mozRTCPeerConnection(" +
JSON.stringify(config) + ") throws");
}
}
runTest(function () {
var pc;
var pcs;
var exception = null;
var config;
try { pcs = new mozRTCPeerConnection(); } catch (e) { exception = e; }
ok(!exception, "mozRTCPeerConnection() succeeds");
exception = null;
try { pc = new mozRTCPeerConnection(1); } catch (e) { exception = e; }
ok(exception, "mozRTCPeerConnection(1) throws");
exception = null;
try { pc = new mozRTCPeerConnection({}); } catch (e) { exception = e; }
ok(exception, "mozRTCPeerConnection({}) throws");
exception = null;
try { pcs = new mozRTCPeerConnection([]); } catch (e) { exception = e; }
ok(exception, "mozRTCPeerConnection([]) throws");
exception = null;
try { pc = new mozRTCPeerConnection({ iceServers: {}}); } catch (e) { exception = e; }
ok(exception, "mozRTCPeerConnection({ iceServers: {}}) throws");
exception = null;
try { pcs = new mozRTCPeerConnection({ iceServers: [] }); } catch (e) { exception = e; }
ok(!exception, "mozRTCPeerConnection({ iceServers: [] }) succeeds");
exception = null;
try { pc = new mozRTCPeerConnection({ iceServers: [{ url:"" }] }); } catch (e) { exception = e; }
ok(exception, "mozRTCPeerConnection({ iceServers: [{ url:\"\" }] }) throws");
exception = null;
try { pc = new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }); } catch (e) { exception = e; }
ok(exception, "mozRTCPeerConnection({ iceServers: [{ url:\"http:0.0.0.0\" }] }) throws");
exception = null;
try { pcs = new mozRTCPeerConnection({ iceServers: [{ url:"stun:0.0.0.0" }, { url:"stuns:x.net", foo:"" }, { url: "turn:[::192.9.5.5]:42" }, { url:"turns:user@x.org:42", credential:"p" }] }); } catch (e) { exception = e; }
ok(!exception, "mozRTCPeerConnection({ iceServers: [{ url:\"stun:0.0.0.0\" }, { url:\"stuns:x.net\", foo:\"\" }, { url: \"turn:[::192.9.5.5]:42\" }, { url:\"turns:user@x.org:42\", credential:\"p\" }] }) succeeds");
exception = null;
try { pc = new mozRTCPeerConnection({ iceServers: [{ url:"stun:0.0.0.0", credential:{}}] }); } catch (e) { exception = e; }
ok(exception, "mozRTCPeerConnection({ iceServers: [{ url:\"stun:0.0.0.0\", credential:{}}] }) throws");
pc = null;
makePC(1, false);
makePC({}, false);
makePC([], false);
makePC({ iceServers: {}}, false);
makePC({ iceServers: [] }, true);
makePC({ iceServers: [{ url:"" }] }, false);
makePC({ iceServers: [{ url:"http:0.0.0.0" }] }, false);
makePC({ iceServers: [
{ url:"stun:0.0.0.0" },
{ url:"stuns:x.net", foo:"" },
{ url:"turn:[::192.9.5.5]:42", username:"p", credential:"p" },
{ url:"turns:x.org:42", username:"p", credential:"p" }
]}, true);
makePC({ iceServers: [{ url:"stun:0.0.0.0", credential:{}}] }, false);
pcs = null;
SimpleTest.finish();
}, true);

Просмотреть файл

@ -7,6 +7,7 @@
dictionary RTCIceServer {
DOMString url;
DOMString? credential = null;
DOMString? username = null;
};
dictionary RTCConfiguration {

Просмотреть файл

@ -376,7 +376,7 @@ Warn(JSContext* aCx, const nsCString& aMsg) {
* In JS, an RTCConfiguration looks like this:
*
* { "iceServers": [ { url:"stun:23.21.150.121" },
* { url:"turn:user@turn.example.org", credential:"mypass"} ] }
* { url:"turn:turn.example.org", credential:"mypass", "username"} ] }
*
* This function converts an already-validated jsval that looks like the above
* into an IceConfiguration object.
@ -416,17 +416,8 @@ PeerConnectionImpl::ConvertRTCConfiguration(const JS::Value& aSrc,
nsAutoCString spec;
rv = url->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
if (!server.mCredential.IsEmpty()) {
// TODO(jib@mozilla.com): Support username, credentials & TURN servers
Warn(aCx, nsPrintfCString(ICE_PARSING
": Credentials not yet implemented. Omitting \"%s\"", spec.get()));
continue;
}
if (isTurn || isTurns) {
Warn(aCx, nsPrintfCString(ICE_PARSING
": TURN servers not yet supported. Treating as STUN: \"%s\"", spec.get()));
}
// TODO(jib@mozilla.com): Revisit once nsURI supports host and port on STUN
// TODO(jib@mozilla.com): Revisit once nsURI has STUN host+port (Bug 833509)
int32_t port;
nsAutoCString host;
{
@ -443,13 +434,26 @@ PeerConnectionImpl::ConvertRTCConfiguration(const JS::Value& aSrc,
if (!hostLen) {
return NS_ERROR_FAILURE;
}
if (hostPos > 1) /* The username was removed */
return NS_ERROR_FAILURE;
path.Mid(host, hostPos, hostLen);
}
if (port == -1)
port = (isStuns || isTurns)? 5349 : 3478;
if (!aDst->addServer(host.get(), port)) {
Warn(aCx, nsPrintfCString(ICE_PARSING
": FQDN not yet implemented (only IP-#s). Omitting \"%s\"", spec.get()));
if (isTurn || isTurns) {
NS_ConvertUTF16toUTF8 credential(server.mCredential);
NS_ConvertUTF16toUTF8 username(server.mUsername);
if (!aDst->addTurnServer(host.get(), port,
username.get(),
credential.get())) {
return NS_ERROR_FAILURE;
}
} else {
if (!aDst->addStunServer(host.get(), port)) {
return NS_ERROR_FAILURE;
}
}
}
#endif
@ -523,9 +527,10 @@ PeerConnectionImpl::Initialize(IPeerConnectionObserver* aObserver,
IceConfiguration ic;
res = ConvertRTCConfiguration(*aRTCConfiguration, &ic, aCx);
NS_ENSURE_SUCCESS(res, res);
res = mMedia->Init(ic.getServers());
res = mMedia->Init(ic.getStunServers(), ic.getTurnServers());
} else {
res = mMedia->Init(aConfiguration->getServers());
res = mMedia->Init(aConfiguration->getStunServers(),
aConfiguration->getTurnServers());
}
if (NS_FAILED(res)) {
CSFLogError(logTag, "%s: Couldn't initialize media object", __FUNCTION__);

Просмотреть файл

@ -68,19 +68,37 @@ private:
class IceConfiguration
{
public:
bool addServer(const std::string& addr, uint16_t port)
bool addStunServer(const std::string& addr, uint16_t port)
{
NrIceStunServer* server(NrIceStunServer::Create(addr, port));
if (!server) {
return false;
}
addServer(*server);
addStunServer(*server);
return true;
}
void addServer(const NrIceStunServer& server) { mServers.push_back (server); }
const std::vector<NrIceStunServer>& getServers() const { return mServers; }
bool addTurnServer(const std::string& addr, uint16_t port,
const std::string& username,
const std::string& pwd)
{
// TODO(ekr@rtfm.com): Need support for SASLprep for
// username and password. Bug # ???
std::vector<unsigned char> password(pwd.begin(), pwd.end());
NrIceTurnServer* server(NrIceTurnServer::Create(addr, port, username, password));
if (!server) {
return false;
}
addTurnServer(*server);
return true;
}
void addStunServer(const NrIceStunServer& server) { mStunServers.push_back (server); }
void addTurnServer(const NrIceTurnServer& server) { mTurnServers.push_back (server); }
const std::vector<NrIceStunServer>& getStunServers() const { return mStunServers; }
const std::vector<NrIceTurnServer>& getTurnServers() const { return mTurnServers; }
private:
std::vector<NrIceStunServer> mServers;
std::vector<NrIceStunServer> mStunServers;
std::vector<NrIceTurnServer> mTurnServers;
};
class PeerConnectionWrapper;

Просмотреть файл

@ -119,7 +119,8 @@ PeerConnectionImpl* PeerConnectionImpl::CreatePeerConnection()
}
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers)
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers,
const std::vector<NrIceTurnServer>& turn_servers)
{
mMainThread = mParent->GetMainThread();
mSTSThread = mParent->GetSTSThread();
@ -136,6 +137,10 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
CSFLogError(logTag, "%s: Failed to set stun servers", __FUNCTION__);
return rv;
}
if (NS_FAILED(rv = mIceCtx->SetTurnServers(turn_servers))) {
CSFLogError(logTag, "%s: Failed to set turn servers", __FUNCTION__);
return rv;
}
if (NS_FAILED(rv = mDNSResolver->Init())) {
CSFLogError(logTag, "%s: Failed to initialize dns resolver", __FUNCTION__);
return rv;

Просмотреть файл

@ -238,7 +238,8 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
~PeerConnectionMedia() {}
nsresult Init(const std::vector<mozilla::NrIceStunServer>& stun_servers);
nsresult Init(const std::vector<mozilla::NrIceStunServer>& stun_servers,
const std::vector<mozilla::NrIceTurnServer>& turn_servers);
// WARNING: This destroys the object!
void SelfDestruct();

Просмотреть файл

@ -544,7 +544,7 @@ class SignalingAgent {
ASSERT_TRUE(pObserver);
sipcc::IceConfiguration cfg;
cfg.addServer("23.21.150.121", 3478);
cfg.addStunServer("23.21.150.121", 3478);
ASSERT_EQ(pc->Initialize(pObserver, nullptr, cfg, thread), NS_OK);
}