DtlsIdentityStoreInterface added and the implementation is called DtlsIdentityStoreImpl (previously named without the -Impl bit and without an interface).
DtlsIdentityStoreImpl is updated to take KeyType into account, something which will be relevant after this CL lands: https://codereview.webrtc.org/1189583002 The DtlsIdentityService[Interface] classes are about to be removed (to be removed when Chromium no longer implements and uses the interface). This was an unnecessary layer of complexity. The FakeIdentityService is now instead a FakeDtlsIdentityStore. Where a service was previously passed around, a store is now passed around. Identity generation is now commonly performed using DtlsIdentityStoreInterface. Previously, if a service was not specified, WebRtcSessionDescriptionFactory could fall back on its own generation code. Now, a store has to be provided for generation to occur. For more information about the steps being taken to land this without breaking Chromium, see referenced bug. BUG=webrtc:4899 R=magjed@webrtc.org, tommi@webrtc.org Review URL: https://codereview.webrtc.org/1176383004 . Cr-Commit-Position: refs/heads/master@{#9696}
This commit is contained in:
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* libjingle
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "talk/app/webrtc/dtlsidentityservice.h"
|
||||
|
||||
#include "talk/app/webrtc/dtlsidentitystore.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
bool DtlsIdentityService::RequestIdentity(
|
||||
const std::string& identity_name,
|
||||
const std::string& common_name,
|
||||
webrtc::DTLSIdentityRequestObserver* observer) {
|
||||
if (identity_name != DtlsIdentityStore::kIdentityName ||
|
||||
common_name != DtlsIdentityStore::kIdentityName) {
|
||||
LOG(LS_WARNING) << "DtlsIdentityService::RequestIdentity called with "
|
||||
<< "unsupported params, identity_name=" << identity_name
|
||||
<< ", common_name=" << common_name;
|
||||
return false;
|
||||
}
|
||||
store_->RequestIdentity(observer);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* libjingle
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TALK_APP_WEBRTC_DTLSIDENTITYSERVICE_H_
|
||||
#define TALK_APP_WEBRTC_DTLSIDENTITYSERVICE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class DtlsIdentityStore;
|
||||
|
||||
// This class forwards the request to DtlsIdentityStore to generate the
|
||||
// identity.
|
||||
class DtlsIdentityService : public webrtc::DTLSIdentityServiceInterface {
|
||||
public:
|
||||
explicit DtlsIdentityService(DtlsIdentityStore* store) : store_(store) {}
|
||||
|
||||
// DTLSIdentityServiceInterface impl.
|
||||
// |identity_name| and |common_name| must equal to
|
||||
// DtlsIdentityStore::kIdentityName, otherwise the request will fail and false
|
||||
// will be returned.
|
||||
bool RequestIdentity(const std::string& identity_name,
|
||||
const std::string& common_name,
|
||||
webrtc::DTLSIdentityRequestObserver* observer) override;
|
||||
|
||||
private:
|
||||
DtlsIdentityStore* store_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // TALK_APP_WEBRTC_DTLSIDENTITYSERVICE_H_
|
||||
@ -30,47 +30,52 @@
|
||||
#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
|
||||
using webrtc::DTLSIdentityRequestObserver;
|
||||
using webrtc::DtlsIdentityRequestObserver;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Passed to SSLIdentity::Generate, "WebRTC". Used for the certificates'
|
||||
// subject and issuer name.
|
||||
static const char kIdentityName[] = "WebRTC";
|
||||
|
||||
namespace {
|
||||
|
||||
enum {
|
||||
MSG_DESTROY,
|
||||
MSG_GENERATE_IDENTITY,
|
||||
MSG_GENERATE_IDENTITY_RESULT,
|
||||
MSG_RETURN_FREE_IDENTITY
|
||||
MSG_GENERATE_IDENTITY_RESULT
|
||||
};
|
||||
|
||||
typedef rtc::ScopedMessageData<rtc::SSLIdentity> IdentityResultMessageData;
|
||||
|
||||
} // namespace
|
||||
|
||||
// This class runs on the worker thread to generate the identity. It's necessary
|
||||
// to separate this class from DtlsIdentityStore so that it can live on the
|
||||
// worker thread after DtlsIdentityStore is destroyed.
|
||||
class DtlsIdentityStore::WorkerTask : public sigslot::has_slots<>,
|
||||
public rtc::MessageHandler {
|
||||
class DtlsIdentityStoreImpl::WorkerTask : public sigslot::has_slots<>,
|
||||
public rtc::MessageHandler {
|
||||
public:
|
||||
explicit WorkerTask(DtlsIdentityStore* store)
|
||||
: signaling_thread_(rtc::Thread::Current()), store_(store) {
|
||||
WorkerTask(DtlsIdentityStoreImpl* store, rtc::KeyType key_type)
|
||||
: signaling_thread_(rtc::Thread::Current()),
|
||||
store_(store),
|
||||
key_type_(key_type) {
|
||||
store_->SignalDestroyed.connect(this, &WorkerTask::OnStoreDestroyed);
|
||||
}
|
||||
|
||||
virtual ~WorkerTask() { DCHECK(rtc::Thread::Current() == signaling_thread_); }
|
||||
virtual ~WorkerTask() { DCHECK(signaling_thread_->IsCurrent()); }
|
||||
|
||||
private:
|
||||
void GenerateIdentity_w() {
|
||||
// TODO(hbos): Use key_type_ when torbjorng's CL has landed.
|
||||
LOG(LS_INFO) << "Generating identity. Key type (TODO(hbos): should use): "
|
||||
<< key_type_;
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity(
|
||||
rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName));
|
||||
rtc::SSLIdentity::Generate(kIdentityName));
|
||||
|
||||
{
|
||||
rtc::CritScope cs(&cs_);
|
||||
if (store_) {
|
||||
store_->PostGenerateIdentityResult_w(identity.Pass());
|
||||
}
|
||||
}
|
||||
// Posting to |this| avoids touching |store_| on threads other than
|
||||
// |signaling_thread_| and thus avoids having to use locks.
|
||||
IdentityResultMessageData* msg = new IdentityResultMessageData(
|
||||
new IdentityResult(key_type_, identity.Pass()));
|
||||
signaling_thread_->Post(this, MSG_GENERATE_IDENTITY_RESULT, msg);
|
||||
}
|
||||
|
||||
void OnMessage(rtc::Message* msg) override {
|
||||
@ -83,8 +88,19 @@ class DtlsIdentityStore::WorkerTask : public sigslot::has_slots<>,
|
||||
// avoid races on disconnecting the signal.
|
||||
signaling_thread_->Post(this, MSG_DESTROY, msg->pdata);
|
||||
break;
|
||||
case MSG_GENERATE_IDENTITY_RESULT:
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
{
|
||||
rtc::scoped_ptr<IdentityResultMessageData> pdata(
|
||||
static_cast<IdentityResultMessageData*>(msg->pdata));
|
||||
if (store_) {
|
||||
store_->OnIdentityGenerated(pdata->data()->key_type_,
|
||||
pdata->data()->identity_.Pass());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSG_DESTROY:
|
||||
DCHECK(rtc::Thread::Current() == signaling_thread_);
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
delete msg->pdata;
|
||||
// |this| has now been deleted. Don't touch member variables.
|
||||
break;
|
||||
@ -94,141 +110,141 @@ class DtlsIdentityStore::WorkerTask : public sigslot::has_slots<>,
|
||||
}
|
||||
|
||||
void OnStoreDestroyed() {
|
||||
rtc::CritScope cs(&cs_);
|
||||
store_ = NULL;
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
store_ = nullptr;
|
||||
}
|
||||
|
||||
rtc::Thread* const signaling_thread_;
|
||||
rtc::CriticalSection cs_;
|
||||
DtlsIdentityStore* store_;
|
||||
DtlsIdentityStoreImpl* store_; // Only touched on |signaling_thread_|.
|
||||
const rtc::KeyType key_type_;
|
||||
};
|
||||
|
||||
// Arbitrary constant used as common name for the identity.
|
||||
// Chosen to make the certificates more readable.
|
||||
const char DtlsIdentityStore::kIdentityName[] = "WebRTC";
|
||||
|
||||
DtlsIdentityStore::DtlsIdentityStore(rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread)
|
||||
DtlsIdentityStoreImpl::DtlsIdentityStoreImpl(rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread)
|
||||
: signaling_thread_(signaling_thread),
|
||||
worker_thread_(worker_thread),
|
||||
pending_jobs_(0) {}
|
||||
request_info_() {
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
// Preemptively generate identities unless the worker thread and signaling
|
||||
// thread are the same (only do preemptive work in the background).
|
||||
if (worker_thread_ != signaling_thread_) {
|
||||
// Only necessary for RSA.
|
||||
GenerateIdentity(rtc::KT_RSA, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
DtlsIdentityStore::~DtlsIdentityStore() {
|
||||
DtlsIdentityStoreImpl::~DtlsIdentityStoreImpl() {
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
SignalDestroyed();
|
||||
}
|
||||
|
||||
void DtlsIdentityStore::Initialize() {
|
||||
DCHECK(rtc::Thread::Current() == signaling_thread_);
|
||||
// Do not aggressively generate the free identity if the worker thread and the
|
||||
// signaling thread are the same.
|
||||
if (worker_thread_ != signaling_thread_) {
|
||||
GenerateIdentity();
|
||||
}
|
||||
}
|
||||
|
||||
void DtlsIdentityStore::RequestIdentity(DTLSIdentityRequestObserver* observer) {
|
||||
DCHECK(rtc::Thread::Current() == signaling_thread_);
|
||||
void DtlsIdentityStoreImpl::RequestIdentity(
|
||||
rtc::KeyType key_type,
|
||||
const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>& observer) {
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
DCHECK(observer);
|
||||
|
||||
// Must return the free identity async.
|
||||
if (free_identity_.get()) {
|
||||
IdentityResultMessageData* msg =
|
||||
new IdentityResultMessageData(free_identity_.release());
|
||||
signaling_thread_->Post(this, MSG_RETURN_FREE_IDENTITY, msg);
|
||||
}
|
||||
|
||||
pending_observers_.push(observer);
|
||||
GenerateIdentity();
|
||||
GenerateIdentity(key_type, observer);
|
||||
}
|
||||
|
||||
void DtlsIdentityStore::OnMessage(rtc::Message* msg) {
|
||||
DCHECK(rtc::Thread::Current() == signaling_thread_);
|
||||
void DtlsIdentityStoreImpl::OnMessage(rtc::Message* msg) {
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
switch (msg->message_id) {
|
||||
case MSG_GENERATE_IDENTITY_RESULT: {
|
||||
rtc::scoped_ptr<IdentityResultMessageData> pdata(
|
||||
static_cast<IdentityResultMessageData*>(msg->pdata));
|
||||
OnIdentityGenerated(pdata->data().Pass());
|
||||
break;
|
||||
}
|
||||
case MSG_RETURN_FREE_IDENTITY: {
|
||||
rtc::scoped_ptr<IdentityResultMessageData> pdata(
|
||||
static_cast<IdentityResultMessageData*>(msg->pdata));
|
||||
ReturnIdentity(pdata->data().Pass());
|
||||
OnIdentityGenerated(pdata->data()->key_type_,
|
||||
pdata->data()->identity_.Pass());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DtlsIdentityStore::HasFreeIdentityForTesting() const {
|
||||
DCHECK(rtc::Thread::Current() == signaling_thread_);
|
||||
return free_identity_.get() != nullptr;
|
||||
bool DtlsIdentityStoreImpl::HasFreeIdentityForTesting(
|
||||
rtc::KeyType key_type) const {
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
return request_info_[key_type].free_identity_.get() != nullptr;
|
||||
}
|
||||
|
||||
void DtlsIdentityStore::GenerateIdentity() {
|
||||
DCHECK(rtc::Thread::Current() == signaling_thread_);
|
||||
pending_jobs_++;
|
||||
LOG(LS_VERBOSE) << "New DTLS identity generation is posted, "
|
||||
<< "pending_identities=" << pending_jobs_;
|
||||
void DtlsIdentityStoreImpl::GenerateIdentity(
|
||||
rtc::KeyType key_type,
|
||||
const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>& observer) {
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
|
||||
WorkerTask* task = new WorkerTask(this);
|
||||
// Enqueue observer to be informed when generation of |key_type| is completed.
|
||||
if (observer.get()) {
|
||||
request_info_[key_type].request_observers_.push(observer);
|
||||
|
||||
// Already have a free identity generated?
|
||||
if (request_info_[key_type].free_identity_.get()) {
|
||||
// Return identity async - post even though we are on |signaling_thread_|.
|
||||
LOG(LS_VERBOSE) << "Using a free DTLS identity.";
|
||||
++request_info_[key_type].gen_in_progress_counts_;
|
||||
IdentityResultMessageData* msg = new IdentityResultMessageData(
|
||||
new IdentityResult(key_type,
|
||||
request_info_[key_type].free_identity_.Pass()));
|
||||
signaling_thread_->Post(this, MSG_GENERATE_IDENTITY_RESULT, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// Free identity in the process of being generated?
|
||||
if (request_info_[key_type].gen_in_progress_counts_ ==
|
||||
request_info_[key_type].request_observers_.size()) {
|
||||
// No need to do anything, the free identity will be returned to the
|
||||
// observer in a MSG_GENERATE_IDENTITY_RESULT.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Enqueue/Post a worker task to do the generation.
|
||||
++request_info_[key_type].gen_in_progress_counts_;
|
||||
WorkerTask* task = new WorkerTask(this, key_type); // Post 1 task/request.
|
||||
// The WorkerTask is owned by the message data to make sure it will not be
|
||||
// leaked even if the task does not get run.
|
||||
IdentityTaskMessageData* msg = new IdentityTaskMessageData(task);
|
||||
WorkerTaskMessageData* msg = new WorkerTaskMessageData(task);
|
||||
worker_thread_->Post(task, MSG_GENERATE_IDENTITY, msg);
|
||||
}
|
||||
|
||||
void DtlsIdentityStore::OnIdentityGenerated(
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity) {
|
||||
DCHECK(rtc::Thread::Current() == signaling_thread_);
|
||||
void DtlsIdentityStoreImpl::OnIdentityGenerated(
|
||||
rtc::KeyType key_type, rtc::scoped_ptr<rtc::SSLIdentity> identity) {
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
|
||||
pending_jobs_--;
|
||||
LOG(LS_VERBOSE) << "A DTLS identity generation job returned, "
|
||||
<< "pending_identities=" << pending_jobs_;
|
||||
DCHECK(request_info_[key_type].gen_in_progress_counts_);
|
||||
--request_info_[key_type].gen_in_progress_counts_;
|
||||
|
||||
if (pending_observers_.empty()) {
|
||||
if (!free_identity_.get()) {
|
||||
free_identity_.reset(identity.release());
|
||||
LOG(LS_VERBOSE) << "A free DTLS identity is saved";
|
||||
}
|
||||
return;
|
||||
rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver> observer;
|
||||
if (!request_info_[key_type].request_observers_.empty()) {
|
||||
observer = request_info_[key_type].request_observers_.front();
|
||||
request_info_[key_type].request_observers_.pop();
|
||||
}
|
||||
ReturnIdentity(identity.Pass());
|
||||
}
|
||||
|
||||
void DtlsIdentityStore::ReturnIdentity(
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity) {
|
||||
DCHECK(rtc::Thread::Current() == signaling_thread_);
|
||||
DCHECK(!free_identity_.get());
|
||||
DCHECK(!pending_observers_.empty());
|
||||
|
||||
rtc::scoped_refptr<DTLSIdentityRequestObserver> observer =
|
||||
pending_observers_.front();
|
||||
pending_observers_.pop();
|
||||
|
||||
if (identity.get()) {
|
||||
observer->OnSuccessWithIdentityObj(identity.Pass());
|
||||
if (observer.get() == nullptr) {
|
||||
// No observer - store result in |free_identities_|.
|
||||
DCHECK(!request_info_[key_type].free_identity_.get());
|
||||
request_info_[key_type].free_identity_.swap(identity);
|
||||
if (request_info_[key_type].free_identity_.get())
|
||||
LOG(LS_VERBOSE) << "A free DTLS identity was saved.";
|
||||
else
|
||||
LOG(LS_WARNING) << "Failed to generate DTLS identity (preemptively).";
|
||||
} else {
|
||||
// Pass an arbitrary error code.
|
||||
observer->OnFailure(0);
|
||||
LOG(LS_WARNING) << "Failed to generate SSL identity";
|
||||
}
|
||||
// Return the result to the observer.
|
||||
if (identity.get()) {
|
||||
LOG(LS_VERBOSE) << "A DTLS identity is returned to an observer.";
|
||||
observer->OnSuccess(identity.Pass());
|
||||
} else {
|
||||
LOG(LS_WARNING) << "Failed to generate DTLS identity.";
|
||||
observer->OnFailure(0);
|
||||
}
|
||||
|
||||
// Do not aggressively generate the free identity if the worker thread and the
|
||||
// signaling thread are the same.
|
||||
if (worker_thread_ != signaling_thread_ &&
|
||||
pending_observers_.empty() &&
|
||||
pending_jobs_ == 0) {
|
||||
// Generate a free identity in the background.
|
||||
GenerateIdentity();
|
||||
// Preemptively generate another identity of the same type?
|
||||
if (worker_thread_ != signaling_thread_ && // Only do in background thread.
|
||||
key_type == rtc::KT_RSA && // Only necessary for RSA.
|
||||
!request_info_[key_type].free_identity_.get() &&
|
||||
request_info_[key_type].request_observers_.size() <=
|
||||
request_info_[key_type].gen_in_progress_counts_) {
|
||||
GenerateIdentity(key_type, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DtlsIdentityStore::PostGenerateIdentityResult_w(
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity) {
|
||||
DCHECK(rtc::Thread::Current() == worker_thread_);
|
||||
|
||||
IdentityResultMessageData* msg =
|
||||
new IdentityResultMessageData(identity.release());
|
||||
signaling_thread_->Post(this, MSG_GENERATE_IDENTITY_RESULT, msg);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -84,57 +84,78 @@ class DtlsIdentityStoreInterface {
|
||||
public:
|
||||
virtual ~DtlsIdentityStoreInterface() { }
|
||||
|
||||
// The |observer| will be called when the requested identity is ready, or when
|
||||
// identity generation fails.
|
||||
virtual void RequestIdentity(
|
||||
rtc::KeyType key_type,
|
||||
const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer) = 0;
|
||||
};
|
||||
|
||||
// This class implements an in-memory DTLS identity store, which generates the
|
||||
// DTLS identity on the worker thread.
|
||||
// APIs calls must be made on the signaling thread and the callbacks are also
|
||||
// called on the signaling thread.
|
||||
class DtlsIdentityStore : public rtc::MessageHandler {
|
||||
// The WebRTC default implementation of DtlsIdentityStoreInterface.
|
||||
// Identity generation is performed on the worker thread.
|
||||
class DtlsIdentityStoreImpl : public DtlsIdentityStoreInterface,
|
||||
public rtc::MessageHandler {
|
||||
public:
|
||||
static const char kIdentityName[];
|
||||
// This will start to preemptively generating an RSA identity in the
|
||||
// background if the worker thread is not the same as the signaling thread.
|
||||
DtlsIdentityStoreImpl(rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread);
|
||||
~DtlsIdentityStoreImpl() override;
|
||||
|
||||
DtlsIdentityStore(rtc::Thread* signaling_thread,
|
||||
rtc::Thread* worker_thread);
|
||||
virtual ~DtlsIdentityStore();
|
||||
|
||||
// Initialize will start generating the free identity in the background.
|
||||
void Initialize();
|
||||
|
||||
// The |observer| will be called when the requested identity is ready, or when
|
||||
// identity generation fails.
|
||||
void RequestIdentity(webrtc::DTLSIdentityRequestObserver* observer);
|
||||
// DtlsIdentityStoreInterface override;
|
||||
void RequestIdentity(
|
||||
rtc::KeyType key_type,
|
||||
const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer) override;
|
||||
|
||||
// rtc::MessageHandler override;
|
||||
void OnMessage(rtc::Message* msg) override;
|
||||
|
||||
// Returns true if there is a free identity, used for unit tests.
|
||||
bool HasFreeIdentityForTesting() const;
|
||||
// Returns true if there is a free RSA identity, used for unit tests.
|
||||
bool HasFreeIdentityForTesting(rtc::KeyType key_type) const;
|
||||
|
||||
private:
|
||||
sigslot::signal0<> SignalDestroyed;
|
||||
void GenerateIdentity(
|
||||
rtc::KeyType key_type,
|
||||
const rtc::scoped_refptr<DtlsIdentityRequestObserver>& observer);
|
||||
void OnIdentityGenerated(rtc::KeyType key_type,
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity);
|
||||
|
||||
class WorkerTask;
|
||||
typedef rtc::ScopedMessageData<DtlsIdentityStore::WorkerTask>
|
||||
IdentityTaskMessageData;
|
||||
typedef rtc::ScopedMessageData<DtlsIdentityStoreImpl::WorkerTask>
|
||||
WorkerTaskMessageData;
|
||||
|
||||
void GenerateIdentity();
|
||||
void OnIdentityGenerated(rtc::scoped_ptr<rtc::SSLIdentity> identity);
|
||||
void ReturnIdentity(rtc::scoped_ptr<rtc::SSLIdentity> identity);
|
||||
// A key type-identity pair.
|
||||
struct IdentityResult {
|
||||
IdentityResult(rtc::KeyType key_type,
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity)
|
||||
: key_type_(key_type), identity_(identity.Pass()) {}
|
||||
|
||||
void PostGenerateIdentityResult_w(rtc::scoped_ptr<rtc::SSLIdentity> identity);
|
||||
rtc::KeyType key_type_;
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity_;
|
||||
};
|
||||
|
||||
typedef rtc::ScopedMessageData<IdentityResult> IdentityResultMessageData;
|
||||
|
||||
sigslot::signal0<> SignalDestroyed;
|
||||
|
||||
rtc::Thread* const signaling_thread_;
|
||||
// TODO(hbos): RSA generation is slow and would be VERY slow if we switch over
|
||||
// to 2048, DtlsIdentityStore should use a new thread and not the "general
|
||||
// purpose" worker thread.
|
||||
rtc::Thread* const worker_thread_;
|
||||
|
||||
// These members should be accessed on the signaling thread only.
|
||||
int pending_jobs_;
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> free_identity_;
|
||||
typedef std::queue<rtc::scoped_refptr<webrtc::DTLSIdentityRequestObserver>>
|
||||
ObserverList;
|
||||
ObserverList pending_observers_;
|
||||
struct RequestInfo {
|
||||
RequestInfo()
|
||||
: request_observers_(), gen_in_progress_counts_(0), free_identity_() {}
|
||||
|
||||
std::queue<rtc::scoped_refptr<DtlsIdentityRequestObserver>>
|
||||
request_observers_;
|
||||
size_t gen_in_progress_counts_;
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> free_identity_;
|
||||
};
|
||||
|
||||
// One RequestInfo per KeyType. Only touch on the |signaling_thread_|.
|
||||
RequestInfo request_info_[rtc::KT_LAST];
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -32,12 +32,12 @@
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/base/ssladapter.h"
|
||||
|
||||
using webrtc::DtlsIdentityStore;
|
||||
using webrtc::DtlsIdentityStoreImpl;
|
||||
|
||||
static const int kTimeoutMs = 10000;
|
||||
|
||||
class MockDtlsIdentityRequestObserver :
|
||||
public webrtc::DTLSIdentityRequestObserver {
|
||||
public webrtc::DtlsIdentityRequestObserver {
|
||||
public:
|
||||
MockDtlsIdentityRequestObserver()
|
||||
: call_back_called_(false), last_request_success_(false) {}
|
||||
@ -47,12 +47,11 @@ class MockDtlsIdentityRequestObserver :
|
||||
last_request_success_ = false;
|
||||
}
|
||||
void OnSuccess(const std::string& der_cert,
|
||||
const std::string& der_private_key) {
|
||||
const std::string& der_private_key) override {
|
||||
LOG(LS_WARNING) << "The string version of OnSuccess is called unexpectedly";
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
void OnSuccessWithIdentityObj(
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity) override {
|
||||
void OnSuccess(rtc::scoped_ptr<rtc::SSLIdentity> identity) override {
|
||||
EXPECT_FALSE(call_back_called_);
|
||||
call_back_called_ = true;
|
||||
last_request_success_ = true;
|
||||
@ -80,12 +79,11 @@ class DtlsIdentityStoreTest : public testing::Test {
|
||||
protected:
|
||||
DtlsIdentityStoreTest()
|
||||
: worker_thread_(new rtc::Thread()),
|
||||
store_(new DtlsIdentityStore(rtc::Thread::Current(),
|
||||
worker_thread_.get())),
|
||||
store_(new DtlsIdentityStoreImpl(rtc::Thread::Current(),
|
||||
worker_thread_.get())),
|
||||
observer_(
|
||||
new rtc::RefCountedObject<MockDtlsIdentityRequestObserver>()) {
|
||||
CHECK(worker_thread_->Start());
|
||||
store_->Initialize();
|
||||
}
|
||||
~DtlsIdentityStoreTest() {}
|
||||
|
||||
@ -97,30 +95,55 @@ class DtlsIdentityStoreTest : public testing::Test {
|
||||
}
|
||||
|
||||
rtc::scoped_ptr<rtc::Thread> worker_thread_;
|
||||
rtc::scoped_ptr<DtlsIdentityStore> store_;
|
||||
rtc::scoped_ptr<DtlsIdentityStoreImpl> store_;
|
||||
rtc::scoped_refptr<MockDtlsIdentityRequestObserver> observer_;
|
||||
};
|
||||
|
||||
TEST_F(DtlsIdentityStoreTest, RequestIdentitySuccess) {
|
||||
EXPECT_TRUE_WAIT(store_->HasFreeIdentityForTesting(), kTimeoutMs);
|
||||
TEST_F(DtlsIdentityStoreTest, RequestIdentitySuccessRSA) {
|
||||
EXPECT_TRUE_WAIT(store_->HasFreeIdentityForTesting(rtc::KT_RSA), kTimeoutMs);
|
||||
|
||||
store_->RequestIdentity(observer_.get());
|
||||
store_->RequestIdentity(rtc::KT_RSA, observer_.get());
|
||||
EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
|
||||
|
||||
EXPECT_TRUE_WAIT(store_->HasFreeIdentityForTesting(), kTimeoutMs);
|
||||
EXPECT_TRUE_WAIT(store_->HasFreeIdentityForTesting(rtc::KT_RSA), kTimeoutMs);
|
||||
|
||||
observer_->Reset();
|
||||
|
||||
// Verifies that the callback is async when a free identity is ready.
|
||||
store_->RequestIdentity(observer_.get());
|
||||
store_->RequestIdentity(rtc::KT_RSA, observer_.get());
|
||||
EXPECT_FALSE(observer_->call_back_called());
|
||||
EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
|
||||
}
|
||||
|
||||
TEST_F(DtlsIdentityStoreTest, DeleteStoreEarlyNoCrash) {
|
||||
EXPECT_FALSE(store_->HasFreeIdentityForTesting());
|
||||
TEST_F(DtlsIdentityStoreTest, RequestIdentitySuccessECDSA) {
|
||||
// Since store currently does not preemptively generate free ECDSA identities
|
||||
// we do not invoke HasFreeIdentityForTesting between requests.
|
||||
|
||||
store_->RequestIdentity(observer_.get());
|
||||
store_->RequestIdentity(rtc::KT_ECDSA, observer_.get());
|
||||
EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
|
||||
|
||||
observer_->Reset();
|
||||
|
||||
// Verifies that the callback is async when a free identity is ready.
|
||||
store_->RequestIdentity(rtc::KT_ECDSA, observer_.get());
|
||||
EXPECT_FALSE(observer_->call_back_called());
|
||||
EXPECT_TRUE_WAIT(observer_->LastRequestSucceeded(), kTimeoutMs);
|
||||
}
|
||||
|
||||
TEST_F(DtlsIdentityStoreTest, DeleteStoreEarlyNoCrashRSA) {
|
||||
EXPECT_FALSE(store_->HasFreeIdentityForTesting(rtc::KT_RSA));
|
||||
|
||||
store_->RequestIdentity(rtc::KT_RSA, observer_.get());
|
||||
store_.reset();
|
||||
|
||||
worker_thread_->Stop();
|
||||
EXPECT_FALSE(observer_->call_back_called());
|
||||
}
|
||||
|
||||
TEST_F(DtlsIdentityStoreTest, DeleteStoreEarlyNoCrashECDSA) {
|
||||
EXPECT_FALSE(store_->HasFreeIdentityForTesting(rtc::KT_ECDSA));
|
||||
|
||||
store_->RequestIdentity(rtc::KT_ECDSA, observer_.get());
|
||||
store_.reset();
|
||||
|
||||
worker_thread_->Stop();
|
||||
|
||||
@ -349,7 +349,7 @@ bool PeerConnection::Initialize(
|
||||
const PeerConnectionInterface::RTCConfiguration& configuration,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
PortAllocatorFactoryInterface* allocator_factory,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
PeerConnectionObserver* observer) {
|
||||
ASSERT(observer != NULL);
|
||||
if (!observer)
|
||||
@ -404,7 +404,7 @@ bool PeerConnection::Initialize(
|
||||
|
||||
// Initialize the WebRtcSession. It creates transport channels etc.
|
||||
if (!session_->Initialize(factory_->options(), constraints,
|
||||
dtls_identity_service, configuration))
|
||||
dtls_identity_store.Pass(), configuration))
|
||||
return false;
|
||||
|
||||
// Register PeerConnection as receiver of local ice candidates.
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "talk/app/webrtc/dtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/mediastreamsignaling.h"
|
||||
#include "talk/app/webrtc/peerconnectionfactory.h"
|
||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||
@ -61,7 +62,7 @@ class PeerConnection : public PeerConnectionInterface,
|
||||
const PeerConnectionInterface::RTCConfiguration& configuration,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
PortAllocatorFactoryInterface* allocator_factory,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
PeerConnectionObserver* observer);
|
||||
virtual rtc::scoped_refptr<StreamCollectionInterface> local_streams();
|
||||
virtual rtc::scoped_refptr<StreamCollectionInterface> remote_streams();
|
||||
@ -157,14 +158,6 @@ class PeerConnection : public PeerConnectionInterface,
|
||||
cricket::BaseSession::State state);
|
||||
void ChangeSignalingState(SignalingState signaling_state);
|
||||
|
||||
bool DoInitialize(IceTransportsType type,
|
||||
const StunConfigurations& stun_config,
|
||||
const TurnConfigurations& turn_config,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
PortAllocatorFactoryInterface* allocator_factory,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
PeerConnectionObserver* observer);
|
||||
|
||||
rtc::Thread* signaling_thread() const {
|
||||
return factory_->signaling_thread();
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||
#include "talk/app/webrtc/test/fakeaudiocapturemodule.h"
|
||||
#include "talk/app/webrtc/test/fakeconstraints.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentityservice.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/test/fakeperiodicvideocapturer.h"
|
||||
#include "talk/app/webrtc/test/fakevideotrackrenderer.h"
|
||||
#include "talk/app/webrtc/test/mockpeerconnectionobservers.h"
|
||||
@ -780,20 +780,21 @@ class JsepTestClient
|
||||
remove_sdes_(false) {
|
||||
}
|
||||
|
||||
virtual rtc::scoped_refptr<webrtc::PeerConnectionInterface>
|
||||
CreatePeerConnection(webrtc::PortAllocatorFactoryInterface* factory,
|
||||
const MediaConstraintsInterface* constraints) {
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionInterface>
|
||||
CreatePeerConnection(
|
||||
webrtc::PortAllocatorFactoryInterface* factory,
|
||||
const MediaConstraintsInterface* constraints) override {
|
||||
// CreatePeerConnection with IceServers.
|
||||
webrtc::PeerConnectionInterface::IceServers ice_servers;
|
||||
webrtc::PeerConnectionInterface::IceServer ice_server;
|
||||
ice_server.uri = "stun:stun.l.google.com:19302";
|
||||
ice_servers.push_back(ice_server);
|
||||
|
||||
FakeIdentityService* dtls_service =
|
||||
rtc::SSLStreamAdapter::HaveDtlsSrtp() ?
|
||||
new FakeIdentityService() : NULL;
|
||||
rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
rtc::SSLStreamAdapter::HaveDtlsSrtp() ? new FakeDtlsIdentityStore()
|
||||
: nullptr);
|
||||
return peer_connection_factory()->CreatePeerConnection(
|
||||
ice_servers, constraints, factory, dtls_service, this);
|
||||
ice_servers, constraints, factory, dtls_identity_store.Pass(), this);
|
||||
}
|
||||
|
||||
void HandleIncomingOffer(const std::string& msg) {
|
||||
|
||||
@ -28,8 +28,6 @@
|
||||
#include "talk/app/webrtc/peerconnectionfactory.h"
|
||||
|
||||
#include "talk/app/webrtc/audiotrack.h"
|
||||
#include "talk/app/webrtc/dtlsidentityservice.h"
|
||||
#include "talk/app/webrtc/dtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/localaudiosource.h"
|
||||
#include "talk/app/webrtc/mediastreamproxy.h"
|
||||
#include "talk/app/webrtc/mediastreamtrackproxy.h"
|
||||
@ -49,6 +47,30 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Passes down the calls to |store_|. See usage in CreatePeerConnection.
|
||||
class DtlsIdentityStoreWrapper : public DtlsIdentityStoreInterface {
|
||||
public:
|
||||
DtlsIdentityStoreWrapper(
|
||||
const rtc::scoped_refptr<RefCountedDtlsIdentityStore>& store)
|
||||
: store_(store) {
|
||||
DCHECK(store_);
|
||||
}
|
||||
|
||||
void RequestIdentity(
|
||||
rtc::KeyType key_type,
|
||||
const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>&
|
||||
observer) override {
|
||||
store_->RequestIdentity(key_type, observer);
|
||||
}
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<RefCountedDtlsIdentityStore> store_;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
rtc::scoped_refptr<PeerConnectionFactoryInterface>
|
||||
CreatePeerConnectionFactory() {
|
||||
rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
|
||||
@ -130,12 +152,12 @@ PeerConnectionFactory::PeerConnectionFactory(
|
||||
|
||||
PeerConnectionFactory::~PeerConnectionFactory() {
|
||||
DCHECK(signaling_thread_->IsCurrent());
|
||||
channel_manager_.reset(NULL);
|
||||
default_allocator_factory_ = NULL;
|
||||
channel_manager_.reset(nullptr);
|
||||
default_allocator_factory_ = nullptr;
|
||||
|
||||
// Make sure |worker_thread_| and |signaling_thread_| outlive
|
||||
// |dtls_identity_store_|.
|
||||
dtls_identity_store_.reset(NULL);
|
||||
dtls_identity_store_ = nullptr;
|
||||
|
||||
if (owns_ptrs_) {
|
||||
if (wraps_current_thread_)
|
||||
@ -169,9 +191,8 @@ bool PeerConnectionFactory::Initialize() {
|
||||
return false;
|
||||
}
|
||||
|
||||
dtls_identity_store_.reset(
|
||||
new DtlsIdentityStore(signaling_thread_, worker_thread_));
|
||||
dtls_identity_store_->Initialize();
|
||||
dtls_identity_store_ = new RefCountedDtlsIdentityStore(
|
||||
signaling_thread_, worker_thread_);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -205,13 +226,17 @@ PeerConnectionFactory::CreatePeerConnection(
|
||||
const PeerConnectionInterface::RTCConfiguration& configuration,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
PortAllocatorFactoryInterface* allocator_factory,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
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());
|
||||
if (!dtls_identity_store.get()) {
|
||||
// Because |pc|->Initialize takes ownership of the store we need a new
|
||||
// wrapper object that can be deleted without deleting the underlying
|
||||
// |dtls_identity_store_|, protecting it from being deleted multiple times.
|
||||
dtls_identity_store.reset(
|
||||
new DtlsIdentityStoreWrapper(dtls_identity_store_));
|
||||
}
|
||||
|
||||
PortAllocatorFactoryInterface* chosen_allocator_factory =
|
||||
@ -224,7 +249,7 @@ PeerConnectionFactory::CreatePeerConnection(
|
||||
configuration,
|
||||
constraints,
|
||||
chosen_allocator_factory,
|
||||
dtls_identity_service,
|
||||
dtls_identity_store.Pass(),
|
||||
observer)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -30,15 +30,18 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "talk/app/webrtc/dtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||
#include "talk/session/media/channelmanager.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class DtlsIdentityStore;
|
||||
typedef rtc::RefCountedObject<DtlsIdentityStoreImpl>
|
||||
RefCountedDtlsIdentityStore;
|
||||
|
||||
class PeerConnectionFactory : public PeerConnectionFactoryInterface {
|
||||
public:
|
||||
@ -46,13 +49,14 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface {
|
||||
options_ = options;
|
||||
}
|
||||
|
||||
virtual rtc::scoped_refptr<PeerConnectionInterface>
|
||||
// webrtc::PeerConnectionFactoryInterface override;
|
||||
rtc::scoped_refptr<PeerConnectionInterface>
|
||||
CreatePeerConnection(
|
||||
const PeerConnectionInterface::RTCConfiguration& configuration,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
PortAllocatorFactoryInterface* allocator_factory,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
PeerConnectionObserver* observer);
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
PeerConnectionObserver* observer) override;
|
||||
|
||||
bool Initialize();
|
||||
|
||||
@ -112,7 +116,7 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface {
|
||||
rtc::scoped_ptr<cricket::WebRtcVideoDecoderFactory>
|
||||
video_decoder_factory_;
|
||||
|
||||
rtc::scoped_ptr<webrtc::DtlsIdentityStore> dtls_identity_store_;
|
||||
rtc::scoped_refptr<RefCountedDtlsIdentityStore> dtls_identity_store_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
#include "talk/app/webrtc/fakeportallocatorfactory.h"
|
||||
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||
#include "talk/app/webrtc/peerconnectionfactory.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentityservice.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/test/fakevideotrackrenderer.h"
|
||||
#include "talk/app/webrtc/videosourceinterface.h"
|
||||
#include "talk/media/base/fakevideocapturer.h"
|
||||
@ -40,8 +40,9 @@
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
|
||||
using webrtc::FakeVideoTrackRenderer;
|
||||
using webrtc::DataChannelInterface;
|
||||
using webrtc::DtlsIdentityStoreInterface;
|
||||
using webrtc::FakeVideoTrackRenderer;
|
||||
using webrtc::MediaStreamInterface;
|
||||
using webrtc::PeerConnectionFactoryInterface;
|
||||
using webrtc::PeerConnectionInterface;
|
||||
@ -157,11 +158,13 @@ TEST(PeerConnectionFactoryTestInternal, CreatePCUsingInternalModules) {
|
||||
NullPeerConnectionObserver observer;
|
||||
webrtc::PeerConnectionInterface::IceServers servers;
|
||||
|
||||
rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
factory->CreatePeerConnection(
|
||||
servers, NULL, NULL, new FakeIdentityService(), &observer));
|
||||
servers, nullptr, nullptr, dtls_identity_store.Pass(), &observer));
|
||||
|
||||
EXPECT_TRUE(pc.get() != NULL);
|
||||
EXPECT_TRUE(pc.get() != nullptr);
|
||||
}
|
||||
|
||||
// This test verifies creation of PeerConnection with valid STUN and TURN
|
||||
@ -177,10 +180,12 @@ TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServers) {
|
||||
ice_server.uri = kTurnIceServerWithTransport;
|
||||
ice_server.password = kTurnPassword;
|
||||
config.servers.push_back(ice_server);
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
factory_->CreatePeerConnection(config, NULL,
|
||||
factory_->CreatePeerConnection(config, nullptr,
|
||||
allocator_factory_.get(),
|
||||
new FakeIdentityService(),
|
||||
dtls_identity_store.Pass(),
|
||||
&observer_));
|
||||
EXPECT_TRUE(pc.get() != NULL);
|
||||
StunConfigurations stun_configs;
|
||||
@ -209,10 +214,12 @@ TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServersUrls) {
|
||||
ice_server.urls.push_back(kTurnIceServerWithTransport);
|
||||
ice_server.password = kTurnPassword;
|
||||
config.servers.push_back(ice_server);
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
factory_->CreatePeerConnection(config, NULL,
|
||||
factory_->CreatePeerConnection(config, nullptr,
|
||||
allocator_factory_.get(),
|
||||
new FakeIdentityService(),
|
||||
dtls_identity_store.Pass(),
|
||||
&observer_));
|
||||
EXPECT_TRUE(pc.get() != NULL);
|
||||
StunConfigurations stun_configs;
|
||||
@ -245,10 +252,12 @@ TEST_F(PeerConnectionFactoryTest, CreatePCUsingIceServersOldSignature) {
|
||||
ice_server.uri = kTurnIceServerWithTransport;
|
||||
ice_server.password = kTurnPassword;
|
||||
ice_servers.push_back(ice_server);
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
factory_->CreatePeerConnection(ice_servers, NULL,
|
||||
factory_->CreatePeerConnection(ice_servers, nullptr,
|
||||
allocator_factory_.get(),
|
||||
new FakeIdentityService(),
|
||||
dtls_identity_store.Pass(),
|
||||
&observer_));
|
||||
EXPECT_TRUE(pc.get() != NULL);
|
||||
StunConfigurations stun_configs;
|
||||
@ -275,10 +284,12 @@ TEST_F(PeerConnectionFactoryTest, CreatePCUsingNoUsernameInUri) {
|
||||
ice_server.username = kTurnUsername;
|
||||
ice_server.password = kTurnPassword;
|
||||
config.servers.push_back(ice_server);
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
factory_->CreatePeerConnection(config, NULL,
|
||||
factory_->CreatePeerConnection(config, nullptr,
|
||||
allocator_factory_.get(),
|
||||
new FakeIdentityService(),
|
||||
dtls_identity_store.Pass(),
|
||||
&observer_));
|
||||
EXPECT_TRUE(pc.get() != NULL);
|
||||
TurnConfigurations turn_configs;
|
||||
@ -296,10 +307,12 @@ TEST_F(PeerConnectionFactoryTest, CreatePCUsingTurnUrlWithTransportParam) {
|
||||
ice_server.uri = kTurnIceServerWithTransport;
|
||||
ice_server.password = kTurnPassword;
|
||||
config.servers.push_back(ice_server);
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
factory_->CreatePeerConnection(config, NULL,
|
||||
factory_->CreatePeerConnection(config, nullptr,
|
||||
allocator_factory_.get(),
|
||||
new FakeIdentityService(),
|
||||
dtls_identity_store.Pass(),
|
||||
&observer_));
|
||||
EXPECT_TRUE(pc.get() != NULL);
|
||||
TurnConfigurations turn_configs;
|
||||
@ -321,10 +334,12 @@ TEST_F(PeerConnectionFactoryTest, CreatePCUsingSecureTurnUrl) {
|
||||
ice_server.uri = kSecureTurnIceServerWithoutTransportAndPortParam;
|
||||
ice_server.password = kTurnPassword;
|
||||
config.servers.push_back(ice_server);
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
factory_->CreatePeerConnection(config, NULL,
|
||||
factory_->CreatePeerConnection(config, nullptr,
|
||||
allocator_factory_.get(),
|
||||
new FakeIdentityService(),
|
||||
dtls_identity_store.Pass(),
|
||||
&observer_));
|
||||
EXPECT_TRUE(pc.get() != NULL);
|
||||
TurnConfigurations turn_configs;
|
||||
@ -358,10 +373,12 @@ TEST_F(PeerConnectionFactoryTest, CreatePCUsingIPLiteralAddress) {
|
||||
ice_server.uri = kTurnIceServerWithIPv6Address;
|
||||
ice_server.password = kTurnPassword;
|
||||
config.servers.push_back(ice_server);
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
rtc::scoped_refptr<PeerConnectionInterface> pc(
|
||||
factory_->CreatePeerConnection(config, NULL,
|
||||
factory_->CreatePeerConnection(config, nullptr,
|
||||
allocator_factory_.get(),
|
||||
new FakeIdentityService(),
|
||||
dtls_identity_store.Pass(),
|
||||
&observer_));
|
||||
EXPECT_TRUE(pc.get() != NULL);
|
||||
StunConfigurations stun_configs;
|
||||
|
||||
@ -32,18 +32,24 @@
|
||||
|
||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||
#include "talk/app/webrtc/proxy.h"
|
||||
#include "webrtc/base/bind.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
BEGIN_PROXY_MAP(PeerConnectionFactory)
|
||||
PROXY_METHOD1(void, SetOptions, const Options&)
|
||||
PROXY_METHOD5(rtc::scoped_refptr<PeerConnectionInterface>,
|
||||
CreatePeerConnection,
|
||||
const PeerConnectionInterface::RTCConfiguration&,
|
||||
const MediaConstraintsInterface*,
|
||||
PortAllocatorFactoryInterface*,
|
||||
DTLSIdentityServiceInterface*,
|
||||
PeerConnectionObserver*)
|
||||
// Can't use PROXY_METHOD5 because scoped_ptr must be Pass()ed.
|
||||
// TODO(tommi,hbos): Use of templates to support scoped_ptr?
|
||||
rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
|
||||
const PeerConnectionInterface::RTCConfiguration& a1,
|
||||
const MediaConstraintsInterface* a2,
|
||||
PortAllocatorFactoryInterface* a3,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> a4,
|
||||
PeerConnectionObserver* a5) override {
|
||||
return owner_thread_->Invoke<rtc::scoped_refptr<PeerConnectionInterface>>(
|
||||
rtc::Bind(&PeerConnectionFactoryProxy::CreatePeerConnection_ot, this,
|
||||
a1, a2, a3, a4.release(), a5));
|
||||
}
|
||||
PROXY_METHOD1(rtc::scoped_refptr<MediaStreamInterface>,
|
||||
CreateLocalMediaStream, const std::string&)
|
||||
PROXY_METHOD1(rtc::scoped_refptr<AudioSourceInterface>,
|
||||
@ -56,6 +62,17 @@ BEGIN_PROXY_MAP(PeerConnectionFactory)
|
||||
PROXY_METHOD2(rtc::scoped_refptr<AudioTrackInterface>,
|
||||
CreateAudioTrack, const std::string&, AudioSourceInterface*)
|
||||
PROXY_METHOD1(bool, StartAecDump, rtc::PlatformFile)
|
||||
|
||||
private:
|
||||
rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection_ot(
|
||||
const PeerConnectionInterface::RTCConfiguration& a1,
|
||||
const MediaConstraintsInterface* a2,
|
||||
PortAllocatorFactoryInterface* a3,
|
||||
DtlsIdentityStoreInterface* a4,
|
||||
PeerConnectionObserver* a5) {
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> ptr_a4(a4);
|
||||
return c_->CreatePeerConnection(a1, a2, a3, ptr_a4.Pass(), a5);
|
||||
}
|
||||
END_PROXY()
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -74,6 +74,7 @@
|
||||
#include "talk/app/webrtc/datachannelinterface.h"
|
||||
#include "talk/app/webrtc/dtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/dtmfsenderinterface.h"
|
||||
#include "talk/app/webrtc/dtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/jsep.h"
|
||||
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||
#include "talk/app/webrtc/statstypes.h"
|
||||
@ -467,6 +468,7 @@ class PortAllocatorFactoryInterface : public rtc::RefCountInterface {
|
||||
~PortAllocatorFactoryInterface() {}
|
||||
};
|
||||
|
||||
// TODO(hbos): Remove once cr/1176383004 lands.
|
||||
class DTLSIdentityServiceInterface {
|
||||
public:
|
||||
// Asynchronously request a DTLS identity, including a self-signed certificate
|
||||
@ -535,6 +537,7 @@ class PeerConnectionFactoryInterface : public rtc::RefCountInterface {
|
||||
|
||||
// TODO(hbos): Temporary CreatePeerConnection function while we transition
|
||||
// from DTLSIdentityServiceInterface to DtlsIdentityStoreInterface.
|
||||
// This method takes the ownership of |dtls_identity_service|.
|
||||
rtc::scoped_refptr<PeerConnectionInterface>
|
||||
CreatePeerConnection(
|
||||
const PeerConnectionInterface::RTCConfiguration& configuration,
|
||||
@ -543,21 +546,23 @@ class PeerConnectionFactoryInterface : public rtc::RefCountInterface {
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
PeerConnectionObserver* observer) {
|
||||
if (dtls_identity_service) {
|
||||
// Store used instead of service, our ownership responsibility to delete.
|
||||
delete dtls_identity_service;
|
||||
}
|
||||
return CreatePeerConnection(configuration, constraints, allocator_factory,
|
||||
dtls_identity_service, observer);
|
||||
dtls_identity_store.Pass(), observer);
|
||||
}
|
||||
|
||||
// This method takes the ownership of |dtls_identity_service|.
|
||||
virtual rtc::scoped_refptr<PeerConnectionInterface>
|
||||
CreatePeerConnection(
|
||||
const PeerConnectionInterface::RTCConfiguration& configuration,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
PortAllocatorFactoryInterface* allocator_factory,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
PeerConnectionObserver* observer) = 0;
|
||||
|
||||
// TODO(mallinath) : Remove below versions after clients are updated
|
||||
// to above method.
|
||||
// TODO(hbos): Remove below version after clients are updated to above method.
|
||||
// In latest W3C WebRTC draft, PC constructor will take RTCConfiguration,
|
||||
// and not IceServers. RTCConfiguration is made up of ice servers and
|
||||
// ice transport type.
|
||||
@ -567,12 +572,12 @@ class PeerConnectionFactoryInterface : public rtc::RefCountInterface {
|
||||
const PeerConnectionInterface::IceServers& servers,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
PortAllocatorFactoryInterface* allocator_factory,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
PeerConnectionObserver* observer) {
|
||||
PeerConnectionInterface::RTCConfiguration rtc_config;
|
||||
rtc_config.servers = servers;
|
||||
return CreatePeerConnection(rtc_config, constraints, allocator_factory,
|
||||
dtls_identity_service, observer);
|
||||
dtls_identity_store.Pass(), observer);
|
||||
}
|
||||
|
||||
virtual rtc::scoped_refptr<MediaStreamInterface>
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
#include "talk/app/webrtc/mediastreaminterface.h"
|
||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||
#include "talk/app/webrtc/test/fakeconstraints.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentityservice.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/test/mockpeerconnectionobservers.h"
|
||||
#include "talk/app/webrtc/test/testsdpstrings.h"
|
||||
#include "talk/app/webrtc/videosource.h"
|
||||
@ -264,17 +264,17 @@ class PeerConnectionInterfaceTest : public testing::Test {
|
||||
webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
|
||||
}
|
||||
|
||||
FakeIdentityService* dtls_service = NULL;
|
||||
scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store;
|
||||
bool dtls;
|
||||
if (FindConstraint(constraints,
|
||||
webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
|
||||
&dtls,
|
||||
NULL) && dtls) {
|
||||
dtls_service = new FakeIdentityService();
|
||||
nullptr) && dtls) {
|
||||
dtls_identity_store.reset(new FakeDtlsIdentityStore());
|
||||
}
|
||||
pc_ = pc_factory_->CreatePeerConnection(servers, constraints,
|
||||
port_allocator_factory_.get(),
|
||||
dtls_service,
|
||||
dtls_identity_store.Pass(),
|
||||
&observer_);
|
||||
ASSERT_TRUE(pc_.get() != NULL);
|
||||
observer_.SetPeerConnectionInterface(pc_.get());
|
||||
|
||||
@ -28,6 +28,9 @@
|
||||
#ifndef TALK_APP_WEBRTC_TEST_FAKEDTLSIDENTITYSERVICE_H_
|
||||
#define TALK_APP_WEBRTC_TEST_FAKEDTLSIDENTITYSERVICE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "talk/app/webrtc/dtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||
|
||||
static const char kRSA_PRIVATE_KEY_PEM[] =
|
||||
@ -61,38 +64,28 @@ static const char kCERT_PEM[] =
|
||||
"UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
using webrtc::DTLSIdentityRequestObserver;
|
||||
|
||||
class FakeIdentityService : public webrtc::DTLSIdentityServiceInterface,
|
||||
public rtc::MessageHandler {
|
||||
class FakeDtlsIdentityStore : public webrtc::DtlsIdentityStoreInterface,
|
||||
public rtc::MessageHandler {
|
||||
public:
|
||||
struct Request {
|
||||
Request(const std::string& common_name,
|
||||
DTLSIdentityRequestObserver* observer)
|
||||
: common_name(common_name), observer(observer) {}
|
||||
typedef rtc::TypedMessageData<rtc::scoped_refptr<
|
||||
webrtc::DtlsIdentityRequestObserver> > MessageData;
|
||||
|
||||
std::string common_name;
|
||||
rtc::scoped_refptr<DTLSIdentityRequestObserver> observer;
|
||||
};
|
||||
typedef rtc::TypedMessageData<Request> MessageData;
|
||||
|
||||
FakeIdentityService() : should_fail_(false) {}
|
||||
FakeDtlsIdentityStore() : should_fail_(false) {}
|
||||
|
||||
void set_should_fail(bool should_fail) {
|
||||
should_fail_ = should_fail;
|
||||
}
|
||||
|
||||
// DTLSIdentityServiceInterface implemenation.
|
||||
virtual bool RequestIdentity(const std::string& identity_name,
|
||||
const std::string& common_name,
|
||||
DTLSIdentityRequestObserver* observer) {
|
||||
MessageData* msg = new MessageData(Request(common_name, observer));
|
||||
if (should_fail_) {
|
||||
rtc::Thread::Current()->Post(this, MSG_FAILURE, msg);
|
||||
} else {
|
||||
rtc::Thread::Current()->Post(this, MSG_SUCCESS, msg);
|
||||
}
|
||||
return true;
|
||||
void RequestIdentity(
|
||||
rtc::KeyType key_type,
|
||||
const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>&
|
||||
observer) override {
|
||||
// TODO(hbos): Should be able to generate KT_ECDSA too.
|
||||
DCHECK(key_type == rtc::KT_RSA || should_fail_);
|
||||
MessageData* msg = new MessageData(
|
||||
rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>(observer));
|
||||
rtc::Thread::Current()->Post(
|
||||
this, should_fail_ ? MSG_FAILURE : MSG_SUCCESS, msg);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -103,13 +96,16 @@ class FakeIdentityService : public webrtc::DTLSIdentityServiceInterface,
|
||||
|
||||
// rtc::MessageHandler implementation.
|
||||
void OnMessage(rtc::Message* msg) {
|
||||
FakeIdentityService::MessageData* message_data =
|
||||
static_cast<FakeIdentityService::MessageData*>(msg->pdata);
|
||||
DTLSIdentityRequestObserver* observer = message_data->data().observer.get();
|
||||
MessageData* message_data = static_cast<MessageData*>(msg->pdata);
|
||||
rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver> observer =
|
||||
message_data->data();
|
||||
switch (msg->message_id) {
|
||||
case MSG_SUCCESS: {
|
||||
std::string cert, key;
|
||||
GenerateIdentity(message_data->data().common_name, &cert, &key);
|
||||
std::string cert;
|
||||
std::string key;
|
||||
rtc::SSLIdentity::PemToDer("CERTIFICATE", kCERT_PEM, &cert);
|
||||
rtc::SSLIdentity::PemToDer("RSA PRIVATE KEY", kRSA_PRIVATE_KEY_PEM,
|
||||
&key);
|
||||
observer->OnSuccess(cert, key);
|
||||
break;
|
||||
}
|
||||
@ -120,16 +116,6 @@ class FakeIdentityService : public webrtc::DTLSIdentityServiceInterface,
|
||||
delete message_data;
|
||||
}
|
||||
|
||||
void GenerateIdentity(
|
||||
const std::string& common_name,
|
||||
std::string* der_cert,
|
||||
std::string* der_key) {
|
||||
rtc::SSLIdentity::PemToDer("CERTIFICATE", kCERT_PEM, der_cert);
|
||||
rtc::SSLIdentity::PemToDer("RSA PRIVATE KEY",
|
||||
kRSA_PRIVATE_KEY_PEM,
|
||||
der_key);
|
||||
}
|
||||
|
||||
bool should_fail_;
|
||||
};
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
#include "talk/app/webrtc/fakeportallocatorfactory.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentityservice.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/test/fakeperiodicvideocapturer.h"
|
||||
#include "talk/app/webrtc/test/mockpeerconnectionobservers.h"
|
||||
#include "talk/app/webrtc/test/peerconnectiontestwrapper.h"
|
||||
@ -93,11 +93,12 @@ bool PeerConnectionTestWrapper::CreatePc(
|
||||
webrtc::PeerConnectionInterface::IceServer ice_server;
|
||||
ice_server.uri = "stun:stun.l.google.com:19302";
|
||||
ice_servers.push_back(ice_server);
|
||||
FakeIdentityService* dtls_service =
|
||||
rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store(
|
||||
rtc::SSLStreamAdapter::HaveDtlsSrtp() ?
|
||||
new FakeIdentityService() : NULL;
|
||||
new FakeDtlsIdentityStore() : nullptr);
|
||||
peer_connection_ = peer_connection_factory_->CreatePeerConnection(
|
||||
ice_servers, constraints, allocator_factory_.get(), dtls_service, this);
|
||||
ice_servers, constraints, allocator_factory_.get(),
|
||||
dtls_identity_store.Pass(), this);
|
||||
|
||||
return peer_connection_.get() != NULL;
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "webrtc/base/thread.h"
|
||||
|
||||
namespace webrtc {
|
||||
class DtlsIdentityStoreInterface;
|
||||
class PortAllocatorFactoryInterface;
|
||||
}
|
||||
|
||||
|
||||
@ -523,7 +523,7 @@ WebRtcSession::~WebRtcSession() {
|
||||
bool WebRtcSession::Initialize(
|
||||
const PeerConnectionFactoryInterface::Options& options,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
|
||||
bundle_policy_ = rtc_configuration.bundle_policy;
|
||||
rtcp_mux_policy_ = rtc_configuration.rtcp_mux_policy;
|
||||
@ -537,8 +537,8 @@ bool WebRtcSession::Initialize(
|
||||
if (options.disable_encryption) {
|
||||
dtls_enabled_ = false;
|
||||
} else {
|
||||
// Enable DTLS by default if |dtls_identity_service| is valid.
|
||||
dtls_enabled_ = (dtls_identity_service != NULL);
|
||||
// Enable DTLS by default if we have a |dtls_identity_store|.
|
||||
dtls_enabled_ = (dtls_identity_store != nullptr);
|
||||
// |constraints| can override the default |dtls_enabled_| value.
|
||||
if (FindConstraint(
|
||||
constraints,
|
||||
@ -664,7 +664,7 @@ bool WebRtcSession::Initialize(
|
||||
signaling_thread(),
|
||||
channel_manager_,
|
||||
mediastream_signaling_,
|
||||
dtls_identity_service,
|
||||
dtls_identity_store.Pass(),
|
||||
this,
|
||||
id(),
|
||||
data_channel_type_,
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "webrtc/p2p/base/session.h"
|
||||
#include "talk/session/media/mediasession.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/sslidentity.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
|
||||
namespace cricket {
|
||||
@ -125,7 +126,7 @@ class WebRtcSession : public cricket::BaseSession,
|
||||
bool Initialize(
|
||||
const PeerConnectionFactoryInterface::Options& options,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
const PeerConnectionInterface::RTCConfiguration& rtc_configuration);
|
||||
// Deletes the voice, video and data channel and changes the session state
|
||||
// to STATE_RECEIVEDTERMINATE.
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
#include "talk/app/webrtc/mediastreamsignaling.h"
|
||||
#include "talk/app/webrtc/streamcollection.h"
|
||||
#include "talk/app/webrtc/test/fakeconstraints.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentityservice.h"
|
||||
#include "talk/app/webrtc/test/fakedtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/test/fakemediastreamsignaling.h"
|
||||
#include "talk/app/webrtc/videotrack.h"
|
||||
#include "talk/app/webrtc/webrtcsession.h"
|
||||
@ -55,6 +55,7 @@
|
||||
#include "webrtc/base/network.h"
|
||||
#include "webrtc/base/physicalsocketserver.h"
|
||||
#include "webrtc/base/ssladapter.h"
|
||||
#include "webrtc/base/sslidentity.h"
|
||||
#include "webrtc/base/sslstreamadapter.h"
|
||||
#include "webrtc/base/stringutils.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
@ -77,8 +78,7 @@ using rtc::Thread;
|
||||
using webrtc::CreateSessionDescription;
|
||||
using webrtc::CreateSessionDescriptionObserver;
|
||||
using webrtc::CreateSessionDescriptionRequest;
|
||||
using webrtc::DTLSIdentityRequestObserver;
|
||||
using webrtc::DTLSIdentityServiceInterface;
|
||||
using webrtc::DtlsIdentityStoreInterface;
|
||||
using webrtc::FakeConstraints;
|
||||
using webrtc::FakeMetricsObserver;
|
||||
using webrtc::IceCandidateCollection;
|
||||
@ -353,7 +353,7 @@ class WebRtcSessionTest : public testing::Test {
|
||||
}
|
||||
|
||||
void Init(
|
||||
DTLSIdentityServiceInterface* identity_service,
|
||||
rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
|
||||
ASSERT_TRUE(session_.get() == NULL);
|
||||
session_.reset(new WebRtcSessionForTest(
|
||||
@ -367,42 +367,44 @@ class WebRtcSessionTest : public testing::Test {
|
||||
EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
|
||||
observer_.ice_gathering_state_);
|
||||
|
||||
EXPECT_TRUE(session_->Initialize(options_, constraints_.get(),
|
||||
identity_service, rtc_configuration));
|
||||
EXPECT_TRUE(session_->Initialize(
|
||||
options_, constraints_.get(), dtls_identity_store.Pass(),
|
||||
rtc_configuration));
|
||||
session_->set_metrics_observer(metrics_observer_);
|
||||
}
|
||||
|
||||
void Init() {
|
||||
PeerConnectionInterface::RTCConfiguration configuration;
|
||||
Init(NULL, configuration);
|
||||
Init(nullptr, configuration);
|
||||
}
|
||||
|
||||
void InitWithIceTransport(
|
||||
PeerConnectionInterface::IceTransportsType ice_transport_type) {
|
||||
PeerConnectionInterface::RTCConfiguration configuration;
|
||||
configuration.type = ice_transport_type;
|
||||
Init(NULL, configuration);
|
||||
Init(nullptr, configuration);
|
||||
}
|
||||
|
||||
void InitWithBundlePolicy(
|
||||
PeerConnectionInterface::BundlePolicy bundle_policy) {
|
||||
PeerConnectionInterface::RTCConfiguration configuration;
|
||||
configuration.bundle_policy = bundle_policy;
|
||||
Init(NULL, configuration);
|
||||
Init(nullptr, configuration);
|
||||
}
|
||||
|
||||
void InitWithRtcpMuxPolicy(
|
||||
PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy) {
|
||||
PeerConnectionInterface::RTCConfiguration configuration;
|
||||
configuration.rtcp_mux_policy = rtcp_mux_policy;
|
||||
Init(NULL, configuration);
|
||||
Init(nullptr, configuration);
|
||||
}
|
||||
|
||||
void InitWithDtls(bool identity_request_should_fail = false) {
|
||||
FakeIdentityService* identity_service = new FakeIdentityService();
|
||||
identity_service->set_should_fail(identity_request_should_fail);
|
||||
rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store(
|
||||
new FakeDtlsIdentityStore());
|
||||
dtls_identity_store->set_should_fail(identity_request_should_fail);
|
||||
PeerConnectionInterface::RTCConfiguration configuration;
|
||||
Init(identity_service, configuration);
|
||||
Init(dtls_identity_store.Pass(), configuration);
|
||||
}
|
||||
|
||||
void InitWithDtmfCodec() {
|
||||
|
||||
@ -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/sslidentity.h"
|
||||
|
||||
using cricket::MediaSessionOptions;
|
||||
|
||||
@ -67,8 +68,7 @@ static bool ValidStreams(const MediaSessionOptions::Streams& streams) {
|
||||
|
||||
enum {
|
||||
MSG_CREATE_SESSIONDESCRIPTION_SUCCESS,
|
||||
MSG_CREATE_SESSIONDESCRIPTION_FAILED,
|
||||
MSG_GENERATE_IDENTITY,
|
||||
MSG_CREATE_SESSIONDESCRIPTION_FAILED
|
||||
};
|
||||
|
||||
struct CreateSessionDescriptionMsg : public rtc::MessageData {
|
||||
@ -102,7 +102,7 @@ void WebRtcIdentityRequestObserver::OnSuccess(
|
||||
SignalIdentityReady(identity);
|
||||
}
|
||||
|
||||
void WebRtcIdentityRequestObserver::OnSuccessWithIdentityObj(
|
||||
void WebRtcIdentityRequestObserver::OnSuccess(
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity) {
|
||||
SignalIdentityReady(identity.release());
|
||||
}
|
||||
@ -130,7 +130,7 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
|
||||
rtc::Thread* signaling_thread,
|
||||
cricket::ChannelManager* channel_manager,
|
||||
MediaStreamSignaling* mediastream_signaling,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
WebRtcSession* session,
|
||||
const std::string& session_id,
|
||||
cricket::DataChannelType dct,
|
||||
@ -143,7 +143,7 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
|
||||
// to just use a random number as session id and start version from
|
||||
// |kInitSessionVersion|.
|
||||
session_version_(kInitSessionVersion),
|
||||
identity_service_(dtls_identity_service),
|
||||
dtls_identity_store_(dtls_identity_store.Pass()),
|
||||
session_(session),
|
||||
session_id_(session_id),
|
||||
data_channel_type_(dct),
|
||||
@ -152,11 +152,10 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
|
||||
// SRTP-SDES is disabled if DTLS is on.
|
||||
SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED);
|
||||
|
||||
if (!dtls_enabled) {
|
||||
return;
|
||||
}
|
||||
// If |dtls_enabled| we must have a |dtls_identity_store_|.
|
||||
DCHECK(!dtls_enabled || dtls_identity_store_);
|
||||
|
||||
if (identity_service_.get()) {
|
||||
if (dtls_enabled && dtls_identity_store_) {
|
||||
identity_request_observer_ =
|
||||
new rtc::RefCountedObject<WebRtcIdentityRequestObserver>();
|
||||
|
||||
@ -165,21 +164,10 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sending DTLS identity request.";
|
||||
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);
|
||||
dtls_identity_store_->RequestIdentity(rtc::KT_DEFAULT,
|
||||
identity_request_observer_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,11 +311,6 @@ void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) {
|
||||
delete param;
|
||||
break;
|
||||
}
|
||||
case MSG_GENERATE_IDENTITY: {
|
||||
LOG(LS_INFO) << "Generating identity.";
|
||||
SetIdentity(rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
|
||||
@ -28,9 +28,10 @@
|
||||
#ifndef TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_
|
||||
#define TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_
|
||||
|
||||
#include "talk/app/webrtc/dtlsidentitystore.h"
|
||||
#include "talk/app/webrtc/peerconnectioninterface.h"
|
||||
#include "webrtc/p2p/base/transportdescriptionfactory.h"
|
||||
#include "talk/session/media/mediasession.h"
|
||||
#include "webrtc/p2p/base/transportdescriptionfactory.h"
|
||||
#include "webrtc/base/messagehandler.h"
|
||||
|
||||
namespace cricket {
|
||||
@ -46,15 +47,14 @@ class SessionDescriptionInterface;
|
||||
class WebRtcSession;
|
||||
|
||||
// DTLS identity request callback class.
|
||||
class WebRtcIdentityRequestObserver : public DTLSIdentityRequestObserver,
|
||||
class WebRtcIdentityRequestObserver : public DtlsIdentityRequestObserver,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
// DTLSIdentityRequestObserver overrides.
|
||||
// DtlsIdentityRequestObserver overrides.
|
||||
void OnFailure(int error) override;
|
||||
void OnSuccess(const std::string& der_cert,
|
||||
const std::string& der_private_key) override;
|
||||
void OnSuccessWithIdentityObj(
|
||||
rtc::scoped_ptr<rtc::SSLIdentity> identity) override;
|
||||
void OnSuccess(rtc::scoped_ptr<rtc::SSLIdentity> identity) override;
|
||||
|
||||
sigslot::signal1<int> SignalRequestFailed;
|
||||
sigslot::signal1<rtc::SSLIdentity*> SignalIdentityReady;
|
||||
@ -85,14 +85,14 @@ struct CreateSessionDescriptionRequest {
|
||||
// request has completed, i.e. when OnIdentityRequestFailed or OnIdentityReady
|
||||
// is called.
|
||||
class WebRtcSessionDescriptionFactory : public rtc::MessageHandler,
|
||||
public sigslot::has_slots<> {
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
WebRtcSessionDescriptionFactory(
|
||||
rtc::Thread* signaling_thread,
|
||||
cricket::ChannelManager* channel_manager,
|
||||
MediaStreamSignaling* mediastream_signaling,
|
||||
DTLSIdentityServiceInterface* dtls_identity_service,
|
||||
// TODO(jiayl): remove the dependency on session once b/10226852 is fixed.
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
|
||||
// TODO(jiayl): remove the dependency on session once bug 2264 is fixed.
|
||||
WebRtcSession* session,
|
||||
const std::string& session_id,
|
||||
cricket::DataChannelType dct,
|
||||
@ -152,7 +152,7 @@ class WebRtcSessionDescriptionFactory : public rtc::MessageHandler,
|
||||
cricket::TransportDescriptionFactory transport_desc_factory_;
|
||||
cricket::MediaSessionDescriptionFactory session_desc_factory_;
|
||||
uint64 session_version_;
|
||||
rtc::scoped_ptr<DTLSIdentityServiceInterface> identity_service_;
|
||||
rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store_;
|
||||
rtc::scoped_refptr<WebRtcIdentityRequestObserver> identity_request_observer_;
|
||||
WebRtcSession* const session_;
|
||||
const std::string session_id_;
|
||||
|
||||
@ -708,8 +708,6 @@
|
||||
'app/webrtc/datachannel.cc',
|
||||
'app/webrtc/datachannel.h',
|
||||
'app/webrtc/datachannelinterface.h',
|
||||
'app/webrtc/dtlsidentityservice.cc',
|
||||
'app/webrtc/dtlsidentityservice.h',
|
||||
'app/webrtc/dtlsidentitystore.cc',
|
||||
'app/webrtc/dtlsidentitystore.h',
|
||||
'app/webrtc/dtmfsender.cc',
|
||||
|
||||
@ -218,7 +218,7 @@
|
||||
'app/webrtc/test/fakeaudiocapturemodule_unittest.cc',
|
||||
'app/webrtc/test/fakeconstraints.h',
|
||||
'app/webrtc/test/fakedatachannelprovider.h',
|
||||
'app/webrtc/test/fakedtlsidentityservice.h',
|
||||
'app/webrtc/test/fakedtlsidentitystore.h',
|
||||
'app/webrtc/test/fakemediastreamsignaling.h',
|
||||
'app/webrtc/test/fakeperiodicvideocapturer.h',
|
||||
'app/webrtc/test/fakevideotrackrenderer.h',
|
||||
|
||||
@ -22,8 +22,6 @@
|
||||
|
||||
namespace rtc {
|
||||
|
||||
enum KeyType { KT_RSA, KT_ECDSA, KT_LAST, KT_DEFAULT = KT_RSA };
|
||||
|
||||
// Forward declaration due to circular dependency with SSLCertificate.
|
||||
class SSLCertChain;
|
||||
|
||||
@ -109,6 +107,8 @@ class SSLCertChain {
|
||||
DISALLOW_COPY_AND_ASSIGN(SSLCertChain);
|
||||
};
|
||||
|
||||
enum KeyType { KT_RSA, KT_ECDSA, KT_LAST, KT_DEFAULT = KT_RSA };
|
||||
|
||||
// Parameters for generating an identity for testing. If common_name is
|
||||
// non-empty, it will be used for the certificate's subject and issuer name,
|
||||
// otherwise a random string will be used. |not_before| and |not_after| are
|
||||
|
||||
Reference in New Issue
Block a user