From a742cb1f37aefad358dab5cec8d1b80109db12b2 Mon Sep 17 00:00:00 2001 From: "braveyao@webrtc.org" Date: Thu, 29 Jan 2015 04:23:01 +0000 Subject: [PATCH] Enable DTLS for peerconnection example. If it's a loopback test, then we recreate another peerconnection with DTLS off. BUG=3872 TEST=Manual Test R=jiayl@webrtc.org, tommi@webrtc.org Review URL: https://webrtc-codereview.appspot.com/36989004 Cr-Commit-Position: refs/heads/master@{#8193} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8193 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../peerconnection/client/conductor.cc | 93 ++++++++++++++++--- .../peerconnection/client/conductor.h | 3 + .../peerconnection/server/server_test.html | 28 ++---- 3 files changed, 88 insertions(+), 36 deletions(-) diff --git a/talk/examples/peerconnection/client/conductor.cc b/talk/examples/peerconnection/client/conductor.cc index a3ea99ff61..3fca758577 100644 --- a/talk/examples/peerconnection/client/conductor.cc +++ b/talk/examples/peerconnection/client/conductor.cc @@ -32,6 +32,7 @@ #include "talk/app/webrtc/videosourceinterface.h" #include "talk/examples/peerconnection/client/defaults.h" #include "talk/media/devices/devicemanager.h" +#include "talk/app/webrtc/test/fakeconstraints.h" #include "webrtc/base/common.h" #include "webrtc/base/json.h" #include "webrtc/base/logging.h" @@ -45,6 +46,9 @@ const char kCandidateSdpName[] = "candidate"; const char kSessionDescriptionTypeName[] = "type"; const char kSessionDescriptionSdpName[] = "sdp"; +#define DTLS_ON true +#define DTLS_OFF false + class DummySetSessionDescriptionObserver : public webrtc::SetSessionDescriptionObserver { public: @@ -66,6 +70,7 @@ class DummySetSessionDescriptionObserver Conductor::Conductor(PeerConnectionClient* client, MainWindow* main_wnd) : peer_id_(-1), + loopback_(false), client_(client), main_wnd_(main_wnd) { client_->RegisterObserver(this); @@ -98,16 +103,7 @@ bool Conductor::InitializePeerConnection() { return false; } - webrtc::PeerConnectionInterface::IceServers servers; - webrtc::PeerConnectionInterface::IceServer server; - server.uri = GetPeerConnectionString(); - servers.push_back(server); - peer_connection_ = peer_connection_factory_->CreatePeerConnection(servers, - NULL, - NULL, - NULL, - this); - if (!peer_connection_.get()) { + if (!CreatePeerConnection(DTLS_ON)) { main_wnd_->MessageBox("Error", "CreatePeerConnection failed", true); DeletePeerConnection(); @@ -116,6 +112,43 @@ bool Conductor::InitializePeerConnection() { return peer_connection_.get() != NULL; } +bool Conductor::ReinitializePeerConnectionForLoopback() { + loopback_ = true; + rtc::scoped_refptr streams( + peer_connection_->local_streams()); + peer_connection_ = NULL; + if (CreatePeerConnection(DTLS_OFF)) { + for (size_t i = 0; i < streams->count(); ++i) + peer_connection_->AddStream(streams->at(i)); + peer_connection_->CreateOffer(this, NULL); + } + return peer_connection_.get() != NULL; +} + +bool Conductor::CreatePeerConnection(bool dtls) { + ASSERT(peer_connection_factory_.get() != NULL); + ASSERT(peer_connection_.get() == NULL); + + webrtc::PeerConnectionInterface::IceServers servers; + webrtc::PeerConnectionInterface::IceServer server; + server.uri = GetPeerConnectionString(); + servers.push_back(server); + + webrtc::FakeConstraints constraints; + if (dtls) { + constraints.AddOptional(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, + "true"); + } + + peer_connection_ = + peer_connection_factory_->CreatePeerConnection(servers, + &constraints, + NULL, + NULL, + this); + return peer_connection_.get() != NULL; +} + void Conductor::DeletePeerConnection() { peer_connection_ = NULL; active_streams_.clear(); @@ -123,6 +156,7 @@ void Conductor::DeletePeerConnection() { main_wnd_->StopRemoteRenderer(); peer_connection_factory_ = NULL; peer_id_ = -1; + loopback_ = false; } void Conductor::EnsureStreamingUI() { @@ -155,6 +189,14 @@ void Conductor::OnRemoveStream(webrtc::MediaStreamInterface* stream) { void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* candidate) { LOG(INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index(); + // For loopback test. To save some connecting delay. + if (loopback_) { + if (!peer_connection_->AddIceCandidate(candidate)) { + LOG(WARNING) << "Failed to apply the received candidate"; + } + return; + } + Json::StyledWriter writer; Json::Value jmessage; @@ -237,6 +279,17 @@ void Conductor::OnMessageFromPeer(int peer_id, const std::string& message) { GetStringFromJsonObject(jmessage, kSessionDescriptionTypeName, &type); if (!type.empty()) { + if (type == "offer-loopback") { + // This is a loopback call. + // Recreate the peerconnection with DTLS disabled. + if (!ReinitializePeerConnectionForLoopback()) { + LOG(LS_ERROR) << "Failed to initialize our PeerConnection instance"; + DeletePeerConnection(); + client_->SignOut(); + } + return; + } + std::string sdp; if (!GetStringFromJsonObject(jmessage, kSessionDescriptionSdpName, &sdp)) { LOG(WARNING) << "Can't parse received session description message."; @@ -465,13 +518,25 @@ void Conductor::UIThreadCallback(int msg_id, void* data) { } void Conductor::OnSuccess(webrtc::SessionDescriptionInterface* desc) { - peer_connection_->SetLocalDescription( - DummySetSessionDescriptionObserver::Create(), desc); + peer_connection_->SetLocalDescription( + DummySetSessionDescriptionObserver::Create(), desc); + + std::string sdp; + desc->ToString(&sdp); + + // For loopback test. To save some connecting delay. + if (loopback_) { + // Replace message type from "offer" to "answer" + webrtc::SessionDescriptionInterface* session_description( + webrtc::CreateSessionDescription("answer", sdp)); + peer_connection_->SetRemoteDescription( + DummySetSessionDescriptionObserver::Create(), session_description); + return; + } + Json::StyledWriter writer; Json::Value jmessage; jmessage[kSessionDescriptionTypeName] = desc->type(); - std::string sdp; - desc->ToString(&sdp); jmessage[kSessionDescriptionSdpName] = sdp; SendMessage(writer.write(jmessage)); } diff --git a/talk/examples/peerconnection/client/conductor.h b/talk/examples/peerconnection/client/conductor.h index 1ce3e50ccf..d99c98a78b 100644 --- a/talk/examples/peerconnection/client/conductor.h +++ b/talk/examples/peerconnection/client/conductor.h @@ -71,6 +71,8 @@ class Conductor protected: ~Conductor(); bool InitializePeerConnection(); + bool ReinitializePeerConnectionForLoopback(); + bool CreatePeerConnection(bool dtls); void DeletePeerConnection(); void EnsureStreamingUI(); void AddStreams(); @@ -129,6 +131,7 @@ class Conductor void SendMessage(const std::string& json_object); int peer_id_; + bool loopback_; rtc::scoped_refptr peer_connection_; rtc::scoped_refptr peer_connection_factory_; diff --git a/talk/examples/peerconnection/server/server_test.html b/talk/examples/peerconnection/server/server_test.html index 01559176b0..0a165f19d5 100644 --- a/talk/examples/peerconnection/server/server_test.html +++ b/talk/examples/peerconnection/server/server_test.html @@ -33,28 +33,12 @@ function handlePeerMessage(peer_id, data) { trace(str); if (document.getElementById("loopback").checked) { if (data.search("offer") != -1) { - // In loopback mode, replace the offer with an answer. - data = data.replace("offer", "answer"); - // Keep only the first crypto line for each m line in the answer. - var mlines = data.split("m="); - // Start from 1 because the first item in the array is not a m line. - for (var i = 1; i < mlines.length; ++i) { - var mline = mlines[i]; - var cryptoBegin = mline.indexOf("a=crypto:", 0); - if (cryptoBegin == -1) { - // No crypto line found. - continue; - } - // Skip the first crypto line. - cryptoBegin = mline.indexOf("a=crypto:", cryptoBegin + 1); - while (cryptoBegin != -1) { - var cryptoEnd = mline.indexOf("\\n", cryptoBegin); - var crypto = mline.substring(cryptoBegin, cryptoEnd + 2); - data = data.replace(crypto, ""); - // Search for the the next crypto line. - cryptoBegin = mline.indexOf("a=crypto:", cryptoBegin + 1); - } - } + // In loopback mode, if DTLS is enabled, notify the client to disable it. + // Otherwise replace the offer with an answer. + if (data.search("fingerprint") != -1) + data = data.replace("offer", "offer-loopback"); + else + data = data.replace("offer", "answer"); } sendToPeer(peer_id, data); }