Index: talk/app/webrtc/webrtcsessiondescriptionfactory.cc |
diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc |
index 3dcc0a1a3b7a78a24da249a0f7b9271c07b7e405..2b2f7597bc1f2e4585f496253e3b7cedf90804de 100644 |
--- a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc |
+++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc |
@@ -33,6 +33,7 @@ |
#include "talk/app/webrtc/mediaconstraintsinterface.h" |
#include "talk/app/webrtc/mediastreamsignaling.h" |
#include "talk/app/webrtc/webrtcsession.h" |
+#include "webrtc/base/messagequeue.h" |
#include "webrtc/base/sslidentity.h" |
using cricket::MediaSessionOptions; |
@@ -68,7 +69,8 @@ static bool ValidStreams(const MediaSessionOptions::Streams& streams) { |
enum { |
MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, |
- MSG_CREATE_SESSIONDESCRIPTION_FAILED |
+ MSG_CREATE_SESSIONDESCRIPTION_FAILED, |
+ MSG_USE_CONSTRUCTOR_CERTIFICATE |
}; |
struct CreateSessionDescriptionMsg : public rtc::MessageData { |
@@ -97,14 +99,14 @@ void WebRtcIdentityRequestObserver::OnSuccess( |
rtc::kPemTypeRsaPrivateKey, |
reinterpret_cast<const unsigned char*>(der_private_key.data()), |
der_private_key.length()); |
- rtc::SSLIdentity* identity = |
- rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert); |
- SignalIdentityReady(identity); |
+ rtc::scoped_ptr<rtc::SSLIdentity> identity( |
+ rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert)); |
+ SignalCertificateReady(DtlsCertificate::Create(identity.Pass())); |
} |
void WebRtcIdentityRequestObserver::OnSuccess( |
rtc::scoped_ptr<rtc::SSLIdentity> identity) { |
- SignalIdentityReady(identity.release()); |
+ SignalCertificateReady(DtlsCertificate::Create(identity.Pass())); |
} |
// static |
@@ -126,16 +128,18 @@ void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
} |
} |
+// Private constructor called by other constructors. |
WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
rtc::Thread* signaling_thread, |
+ rtc::Thread* worker_thread, |
cricket::ChannelManager* channel_manager, |
MediaStreamSignaling* mediastream_signaling, |
- rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, |
WebRtcSession* session, |
const std::string& session_id, |
cricket::DataChannelType dct, |
bool dtls_enabled) |
: signaling_thread_(signaling_thread), |
+ worker_thread_(worker_thread), |
mediastream_signaling_(mediastream_signaling), |
session_desc_factory_(channel_manager, &transport_desc_factory_), |
// RFC 4566 suggested a Network Time Protocol (NTP) format timestamp |
@@ -143,33 +147,89 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
// to just use a random number as session id and start version from |
// |kInitSessionVersion|. |
session_version_(kInitSessionVersion), |
- dtls_identity_store_(dtls_identity_store.Pass()), |
session_(session), |
session_id_(session_id), |
data_channel_type_(dct), |
- identity_request_state_(IDENTITY_NOT_NEEDED) { |
+ certificate_request_state_(CERTIFICATE_NOT_NEEDED) { |
transport_desc_factory_.set_protocol(cricket::ICEPROTO_RFC5245); |
session_desc_factory_.set_add_legacy_streams(false); |
// SRTP-SDES is disabled if DTLS is on. |
SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); |
+} |
- // If |dtls_enabled| we must have a |dtls_identity_store_|. |
- DCHECK(!dtls_enabled || dtls_identity_store_); |
+WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
+ rtc::Thread* signaling_thread, |
+ rtc::Thread* worker_thread, |
+ cricket::ChannelManager* channel_manager, |
+ MediaStreamSignaling* mediastream_signaling, |
+ WebRtcSession* session, |
+ const std::string& session_id, |
+ cricket::DataChannelType dct) |
+ : WebRtcSessionDescriptionFactory(signaling_thread, worker_thread, |
+ channel_manager, mediastream_signaling, |
+ session, session_id, dct, false) { |
+} |
- if (dtls_enabled && dtls_identity_store_) { |
- identity_request_observer_ = |
- new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); |
+WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
+ rtc::Thread* signaling_thread, |
+ rtc::Thread* worker_thread, |
+ cricket::ChannelManager* channel_manager, |
+ MediaStreamSignaling* mediastream_signaling, |
+ rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, |
+ WebRtcSession* session, |
+ const std::string& session_id, |
+ cricket::DataChannelType dct) |
+ : WebRtcSessionDescriptionFactory(signaling_thread, worker_thread, |
+ channel_manager, mediastream_signaling, |
+ session, session_id, dct, true) { |
+ dtls_identity_store_.reset(dtls_identity_store.release()); |
tommi (sloooow) - chröme
2015/08/18 14:49:35
dtls_identity_store_(dtls_identity_store.Pass()) i
|
+ |
+ // Generate certificate. |
+ certificate_request_state_ = CERTIFICATE_WAITING; |
+ |
+ identity_request_observer_ = |
+ new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); |
+ identity_request_observer_->SignalRequestFailed.connect( |
+ this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); |
+ identity_request_observer_->SignalCertificateReady.connect( |
+ this, &WebRtcSessionDescriptionFactory::SetCertificate); |
+ |
+ // If an |dtls_identity_store_| was not provided we default to using |
+ // DtlsIdentityStore. |
+ if (!dtls_identity_store_) { |
+ dtls_identity_store_.reset( |
+ new DtlsIdentityStoreImpl(signaling_thread_, worker_thread_)); |
+ } |
- identity_request_observer_->SignalRequestFailed.connect( |
- this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); |
- identity_request_observer_->SignalIdentityReady.connect( |
- this, &WebRtcSessionDescriptionFactory::SetIdentity); |
+ // Request identity. This happens asynchronously, so the caller will have a |
+ // chance to connect to SignalCertificateReady. |
+ dtls_identity_store_->RequestIdentity(rtc::KT_DEFAULT, |
+ identity_request_observer_); |
+ LOG(LS_VERBOSE) << "DTLS-SRTP enabled, sent DTLS identity request."; |
+} |
- LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sending DTLS identity request."; |
- identity_request_state_ = IDENTITY_WAITING; |
- dtls_identity_store_->RequestIdentity(rtc::KT_DEFAULT, |
- identity_request_observer_); |
- } |
+WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
+ rtc::Thread* signaling_thread, |
+ rtc::Thread* worker_thread, |
+ cricket::ChannelManager* channel_manager, |
+ MediaStreamSignaling* mediastream_signaling, |
+ const rtc::scoped_refptr<DtlsCertificate>& certificate, |
+ WebRtcSession* session, |
+ const std::string& session_id, |
+ cricket::DataChannelType dct) |
+ : WebRtcSessionDescriptionFactory(signaling_thread, worker_thread, |
+ channel_manager, mediastream_signaling, |
+ session, session_id, dct, true) { |
+ DCHECK(certificate.get()); |
+ |
+ LOG(LS_VERBOSE) << "DTLS-SRTP enabled; using DTLS certificate."; |
+ // We already have a certificate but we wait to do SetCertificate; if we do |
+ // it in the constructor then the caller has not had a chance to connect to |
+ // SignalCertificateReady. |
+ certificate_request_state_ = CERTIFICATE_WAITING; |
+ signaling_thread_->Post(this, MSG_USE_CONSTRUCTOR_CERTIFICATE, |
+ new rtc::ScopedRefMessageData<DtlsCertificate>( |
+ certificate)); |
} |
WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { |
@@ -185,7 +245,7 @@ WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { |
for (auto& msg : list) |
OnMessage(&msg); |
- transport_desc_factory_.set_identity(NULL); |
+ transport_desc_factory_.set_certificate(nullptr); |
} |
void WebRtcSessionDescriptionFactory::CreateOffer( |
@@ -194,7 +254,7 @@ void WebRtcSessionDescriptionFactory::CreateOffer( |
cricket::MediaSessionOptions session_options; |
std::string error = "CreateOffer"; |
- if (identity_request_state_ == IDENTITY_FAILED) { |
+ if (certificate_request_state_ == CERTIFICATE_FAILED) { |
error += kFailedDueToIdentityFailed; |
LOG(LS_ERROR) << error; |
PostCreateSessionDescriptionFailed(observer, error); |
@@ -223,11 +283,11 @@ void WebRtcSessionDescriptionFactory::CreateOffer( |
CreateSessionDescriptionRequest request( |
CreateSessionDescriptionRequest::kOffer, observer, session_options); |
- if (identity_request_state_ == IDENTITY_WAITING) { |
+ if (certificate_request_state_ == CERTIFICATE_WAITING) { |
create_session_description_requests_.push(request); |
} else { |
- ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED || |
- identity_request_state_ == IDENTITY_NOT_NEEDED); |
+ ASSERT(certificate_request_state_ == CERTIFICATE_SUCCEEDED || |
+ certificate_request_state_ == CERTIFICATE_NOT_NEEDED); |
InternalCreateOffer(request); |
} |
} |
@@ -236,7 +296,7 @@ void WebRtcSessionDescriptionFactory::CreateAnswer( |
CreateSessionDescriptionObserver* observer, |
const MediaConstraintsInterface* constraints) { |
std::string error = "CreateAnswer"; |
- if (identity_request_state_ == IDENTITY_FAILED) { |
+ if (certificate_request_state_ == CERTIFICATE_FAILED) { |
error += kFailedDueToIdentityFailed; |
LOG(LS_ERROR) << error; |
PostCreateSessionDescriptionFailed(observer, error); |
@@ -278,11 +338,11 @@ void WebRtcSessionDescriptionFactory::CreateAnswer( |
CreateSessionDescriptionRequest request( |
CreateSessionDescriptionRequest::kAnswer, observer, options); |
- if (identity_request_state_ == IDENTITY_WAITING) { |
+ if (certificate_request_state_ == CERTIFICATE_WAITING) { |
create_session_description_requests_.push(request); |
} else { |
- ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED || |
- identity_request_state_ == IDENTITY_NOT_NEEDED); |
+ ASSERT(certificate_request_state_ == CERTIFICATE_SUCCEEDED || |
+ certificate_request_state_ == CERTIFICATE_NOT_NEEDED); |
InternalCreateAnswer(request); |
} |
} |
@@ -312,6 +372,14 @@ void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { |
delete param; |
break; |
} |
+ case MSG_USE_CONSTRUCTOR_CERTIFICATE: { |
+ rtc::ScopedRefMessageData<DtlsCertificate>* param = |
+ static_cast<rtc::ScopedRefMessageData<DtlsCertificate>*>(msg->pdata); |
+ LOG(LS_INFO) << "Using certificate supplied to constructor."; |
+ SetCertificate(param->data()); |
+ delete param; |
+ break; |
+ } |
default: |
ASSERT(false); |
break; |
@@ -430,19 +498,21 @@ void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { |
ASSERT(signaling_thread_->IsCurrent()); |
LOG(LS_ERROR) << "Async identity request failed: error = " << error; |
- identity_request_state_ = IDENTITY_FAILED; |
+ certificate_request_state_ = CERTIFICATE_FAILED; |
FailPendingRequests(kFailedDueToIdentityFailed); |
} |
-void WebRtcSessionDescriptionFactory::SetIdentity( |
- rtc::SSLIdentity* identity) { |
- LOG(LS_VERBOSE) << "Setting new identity"; |
+void WebRtcSessionDescriptionFactory::SetCertificate( |
+ const rtc::scoped_refptr<DtlsCertificate>& certificate) { |
+ LOG(LS_VERBOSE) << "Setting new certificate"; |
+ |
+ DCHECK(certificate); |
- identity_request_state_ = IDENTITY_SUCCEEDED; |
- SignalIdentityReady(identity); |
+ certificate_request_state_ = CERTIFICATE_SUCCEEDED; |
+ SignalCertificateReady(certificate); |
- transport_desc_factory_.set_identity(identity); |
+ transport_desc_factory_.set_certificate(certificate); |
transport_desc_factory_.set_secure(cricket::SEC_ENABLED); |
while (!create_session_description_requests_.empty()) { |