Index: talk/app/webrtc/peerconnectionfactory.cc |
diff --git a/talk/app/webrtc/peerconnectionfactory.cc b/talk/app/webrtc/peerconnectionfactory.cc |
index 3524af7932a4f92f60da84e552f742d1a2aaa7ac..7a4a54c5a3e9a7604e9ad734da3b383e74e01d1e 100644 |
--- a/talk/app/webrtc/peerconnectionfactory.cc |
+++ b/talk/app/webrtc/peerconnectionfactory.cc |
@@ -49,6 +49,64 @@ |
namespace webrtc { |
+namespace { |
+ |
+class BlockingIdentityRequestObserver : public DTLSIdentityRequestObserver { |
+ public: |
+ BlockingIdentityRequestObserver( |
+ rtc::scoped_refptr<DtlsCertificate>* out_certificate) |
+ : has_been_called_(false), |
+ out_certificate_(out_certificate) { |
+ DCHECK(out_certificate_); |
+ } |
+ |
+ void OnFailure(int error) override { |
+ ReturnIdentity(nullptr); |
+ } |
+ void OnSuccess(const std::string& der_cert, |
+ const std::string& der_private_key) override { |
+ std::string pem_cert = rtc::SSLIdentity::DerToPem( |
+ rtc::kPemTypeCertificate, |
+ reinterpret_cast<const unsigned char*>(der_cert.data()), |
+ der_cert.length()); |
+ std::string pem_key = rtc::SSLIdentity::DerToPem( |
+ rtc::kPemTypeRsaPrivateKey, |
+ reinterpret_cast<const unsigned char*>(der_private_key.data()), |
+ der_private_key.length()); |
+ rtc::scoped_ptr<rtc::SSLIdentity> identity( |
+ rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert)); |
+ OnSuccessWithIdentityObj(identity.Pass()); |
+ } |
+ void OnSuccessWithIdentityObj( |
+ rtc::scoped_ptr<rtc::SSLIdentity> identity) override { |
+ ReturnIdentity(identity.Pass()); |
+ } |
+ |
+ void WaitForIdentity() { |
+ // Process messages while waiting for |has_been_called_| to become true. |
+ // If the service generating the identity is Posting to the current thread |
+ // then processing messages is necessary for identity generation to finish |
+ // (waiting without processing would block forever). |
+ while (!has_been_called_) { |
+ rtc::Thread::Current()->ProcessMessages(1); |
+ } |
+ } |
+ |
+ private: |
+ void ReturnIdentity(rtc::scoped_ptr<rtc::SSLIdentity> identity) { |
+ if (identity.get()) |
+ *out_certificate_ = DtlsCertificate::Create(identity.Pass()); |
+ else |
+ *out_certificate_ = nullptr; |
+ has_been_called_ = true; |
+ } |
+ |
+ volatile bool has_been_called_; |
+ rtc::scoped_refptr<DtlsCertificate>* out_certificate_; |
+}; |
+ |
+} // anonymous namespace |
+ |
rtc::scoped_refptr<PeerConnectionFactoryInterface> |
CreatePeerConnectionFactory() { |
rtc::scoped_refptr<PeerConnectionFactory> pc_factory( |
@@ -205,15 +263,11 @@ PeerConnectionFactory::CreatePeerConnection( |
const PeerConnectionInterface::RTCConfiguration& configuration, |
const MediaConstraintsInterface* constraints, |
PortAllocatorFactoryInterface* allocator_factory, |
- DTLSIdentityServiceInterface* dtls_identity_service, |
+ rtc::scoped_refptr<webrtc::DtlsCertificate> certificate, |
PeerConnectionObserver* observer) { |
DCHECK(signaling_thread_->IsCurrent()); |
DCHECK(allocator_factory || default_allocator_factory_); |
- if (!dtls_identity_service) { |
- dtls_identity_service = new DtlsIdentityService(dtls_identity_store_.get()); |
- } |
- |
PortAllocatorFactoryInterface* chosen_allocator_factory = |
allocator_factory ? allocator_factory : default_allocator_factory_.get(); |
chosen_allocator_factory->SetNetworkIgnoreMask(options_.network_ignore_mask); |
@@ -224,13 +278,44 @@ PeerConnectionFactory::CreatePeerConnection( |
configuration, |
constraints, |
chosen_allocator_factory, |
- dtls_identity_service, |
+ certificate, |
observer)) { |
return NULL; |
} |
return PeerConnectionProxy::Create(signaling_thread(), pc); |
} |
+rtc::scoped_refptr<PeerConnectionInterface> |
+PeerConnectionFactory::CreatePeerConnection( |
+ const PeerConnectionInterface::RTCConfiguration& configuration, |
+ const MediaConstraintsInterface* constraints, |
+ PortAllocatorFactoryInterface* allocator_factory, |
+ DTLSIdentityServiceInterface* dtls_identity_service, |
+ PeerConnectionObserver* observer) { |
hbos
2015/08/04 12:50:21
This version of CreatePeerConnection uses the old
|
+ DCHECK(signaling_thread_->IsCurrent()); |
+ |
+ if (!dtls_identity_service) { |
+ dtls_identity_service = new DtlsIdentityService(dtls_identity_store_.get()); |
+ } |
+ // TODO(hbos): This certificate generation is a blocking operation and does |
+ // not inform if the generation failed (but then a null certificate will be |
+ // passed and some failure will likely occur later). This function signature |
+ // only exists temporarily as to not break Chromium. It shall be removed ASAP. |
+ rtc::scoped_refptr<DtlsCertificate> certificate; |
+ rtc::scoped_refptr<BlockingIdentityRequestObserver> cert_blocking_observer( |
+ new rtc::RefCountedObject<BlockingIdentityRequestObserver>(&certificate)); |
+ dtls_identity_service->RequestIdentity( |
+ DtlsIdentityStore::kIdentityName, DtlsIdentityStore::kIdentityName, |
+ cert_blocking_observer.get()); |
+ cert_blocking_observer->WaitForIdentity(); |
+ // Having taken ownership of |dtls_identity_service| it is up to us to delete. |
+ delete dtls_identity_service; |
+ dtls_identity_service = nullptr; |
+ |
+ return CreatePeerConnection(configuration, constraints, allocator_factory, |
+ certificate, observer); |
+} |
+ |
rtc::scoped_refptr<MediaStreamInterface> |
PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) { |
DCHECK(signaling_thread_->IsCurrent()); |