| Index: talk/app/webrtc/webrtcsessiondescriptionfactory.cc
|
| diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
|
| index 1909b0ed78dfe2c6cd5c6c82481d7560ca935ceb..2b9cb98f9a3bc31c02c20044a9b7706d59379c78 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) {
|
| +void WebRtcSessionDescriptionFactory::SetCertificate(
|
| + rtc::scoped_refptr<DtlsCertificate> certificate) {
|
| LOG(LS_VERBOSE) << "Setting new identity";
|
|
|
| - identity_request_state_ = IDENTITY_SUCCEEDED;
|
| - SignalIdentityReady(identity);
|
| + DCHECK(certificate.get());
|
| +
|
| + 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()) {
|
|
|