Chromium Code Reviews| Index: talk/app/webrtc/webrtcsessiondescriptionfactory.cc |
| diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc |
| index 1909b0ed78dfe2c6cd5c6c82481d7560ca935ceb..d0b466a23b80ad6697ee07aef5079f524d4d5b26 100644 |
| --- a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc |
| +++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc |
| @@ -27,12 +27,13 @@ |
| #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h" |
| -#include "talk/app/webrtc/dtlsidentitystore.h" |
| +#include "talk/app/webrtc/dtlsidentityservice.h" |
| #include "talk/app/webrtc/jsep.h" |
| #include "talk/app/webrtc/jsepsessiondescription.h" |
| #include "talk/app/webrtc/mediaconstraintsinterface.h" |
| #include "talk/app/webrtc/mediastreamsignaling.h" |
| #include "talk/app/webrtc/webrtcsession.h" |
| +#include "webrtc/base/messagequeue.h" |
| using cricket::MediaSessionOptions; |
| @@ -68,7 +69,7 @@ static bool ValidStreams(const MediaSessionOptions::Streams& streams) { |
| enum { |
| MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, |
| MSG_CREATE_SESSIONDESCRIPTION_FAILED, |
| - MSG_GENERATE_IDENTITY, |
| + MSG_USE_CONSTRUCTOR_CERTIFICATE |
| }; |
| struct CreateSessionDescriptionMsg : public rtc::MessageData { |
| @@ -97,14 +98,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::OnSuccessWithIdentityObj( |
| rtc::scoped_ptr<rtc::SSLIdentity> identity) { |
| - SignalIdentityReady(identity.release()); |
| + SignalCertificateReady(DtlsCertificate::Create(identity.Pass())); |
| } |
| // static |
| @@ -126,16 +127,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, |
| - DTLSIdentityServiceInterface* dtls_identity_service, |
| 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,47 +146,97 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
| // to just use a random number as session id and start version from |
| // |kInitSessionVersion|. |
| session_version_(kInitSessionVersion), |
| - identity_service_(dtls_identity_service), |
| 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) { |
| - return; |
| +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) { |
| +} |
| + |
| +WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
| + rtc::Thread* signaling_thread, |
| + rtc::Thread* worker_thread, |
| + cricket::ChannelManager* channel_manager, |
| + MediaStreamSignaling* mediastream_signaling, |
| + DTLSIdentityServiceInterface* dtls_identity_service, |
| + WebRtcSession* session, |
| + const std::string& session_id, |
| + cricket::DataChannelType dct) |
| + : WebRtcSessionDescriptionFactory(signaling_thread, worker_thread, |
| + channel_manager, mediastream_signaling, |
| + session, session_id, dct, true) { |
| + identity_service_.reset(dtls_identity_service); |
| + |
| + // 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 |identity_service_| was not provided we default to using |
| + // DtlsIdentityStore and DtlsIdentityService. |
| + if (!identity_service_.get()) { |
| + identity_store_.reset( |
| + new DtlsIdentityStore(signaling_thread_, worker_thread_)); |
| + identity_service_.reset(new DtlsIdentityService(identity_store_.get())); |
| } |
| - if (identity_service_.get()) { |
| - identity_request_observer_ = |
| - new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); |
| - |
| - identity_request_observer_->SignalRequestFailed.connect( |
| - this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); |
| - identity_request_observer_->SignalIdentityReady.connect( |
| - this, &WebRtcSessionDescriptionFactory::SetIdentity); |
| - |
| - if (identity_service_->RequestIdentity( |
| - DtlsIdentityStore::kIdentityName, |
| - DtlsIdentityStore::kIdentityName, |
| - identity_request_observer_)) { |
| - LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request."; |
| - identity_request_state_ = IDENTITY_WAITING; |
| - } else { |
| - LOG(LS_ERROR) << "Failed to send DTLS identity request."; |
| - identity_request_state_ = IDENTITY_FAILED; |
| - } |
| + // Request identity. This happens asynchronously, so the caller will have a |
| + // chance to connect to SignalCertificateReady. |
| + if (identity_service_->RequestIdentity(DtlsIdentityStore::kIdentityName, |
| + DtlsIdentityStore::kIdentityName, |
| + identity_request_observer_)) { |
| + LOG(LS_VERBOSE) << "DTLS-SRTP enabled, sent DTLS identity request."; |
| } else { |
| - identity_request_state_ = IDENTITY_WAITING; |
| - // Do not generate the identity in the constructor since the caller has |
| - // not got a chance to connect to SignalIdentityReady. |
| - signaling_thread_->Post(this, MSG_GENERATE_IDENTITY, NULL); |
| + certificate_request_state_ = CERTIFICATE_FAILED; |
| + LOG(LS_VERBOSE) << "DTLS-SRTP enabled, DTLS identity request FAILED."; |
| } |
| } |
| +WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
| + rtc::Thread* signaling_thread, |
| + rtc::Thread* worker_thread, |
| + cricket::ChannelManager* channel_manager, |
| + MediaStreamSignaling* mediastream_signaling, |
| + 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() { |
| ASSERT(signaling_thread_->IsCurrent()); |
| @@ -197,7 +250,7 @@ WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { |
| for (auto& msg : list) |
| OnMessage(&msg); |
| - transport_desc_factory_.set_identity(NULL); |
| + transport_desc_factory_.set_certificate(nullptr); |
| } |
| void WebRtcSessionDescriptionFactory::CreateOffer( |
| @@ -206,7 +259,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); |
| @@ -235,11 +288,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); |
| } |
| } |
| @@ -248,7 +301,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); |
| @@ -290,11 +343,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); |
| } |
| } |
| @@ -324,9 +377,12 @@ void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { |
| delete param; |
| break; |
| } |
| - case MSG_GENERATE_IDENTITY: { |
| - LOG(LS_INFO) << "Generating identity."; |
| - SetIdentity(rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName)); |
| + 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: |
| @@ -447,19 +503,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( |
| + rtc::scoped_refptr<DtlsCertificate> certificate) { |
|
tommi (sloooow) - chröme
2015/08/10 16:10:16
this should be passed by const &
hbos
2015/08/12 08:55:15
Acknowledged.
|
| + 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()) { |