summaryrefslogtreecommitdiffstats
path: root/remoting/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/protocol')
-rw-r--r--remoting/protocol/chromium_port_allocator.cc43
-rw-r--r--remoting/protocol/chromium_port_allocator.h29
-rw-r--r--remoting/protocol/chromium_port_allocator_factory.cc39
-rw-r--r--remoting/protocol/chromium_port_allocator_factory.h47
-rw-r--r--remoting/protocol/connection_to_host.h4
-rw-r--r--remoting/protocol/connection_to_host_impl.cc7
-rw-r--r--remoting/protocol/connection_to_host_impl.h2
-rw-r--r--remoting/protocol/fake_connection_to_host.cc3
-rw-r--r--remoting/protocol/fake_connection_to_host.h2
-rw-r--r--remoting/protocol/ice_transport.cc41
-rw-r--r--remoting/protocol/ice_transport.h32
-rw-r--r--remoting/protocol/ice_transport_channel.cc76
-rw-r--r--remoting/protocol/ice_transport_channel.h22
-rw-r--r--remoting/protocol/ice_transport_factory.cc93
-rw-r--r--remoting/protocol/ice_transport_factory.h61
-rw-r--r--remoting/protocol/ice_transport_unittest.cc22
-rw-r--r--remoting/protocol/jingle_session_unittest.cc22
-rw-r--r--remoting/protocol/port_allocator_factory.h8
-rw-r--r--remoting/protocol/transport_context.cc122
-rw-r--r--remoting/protocol/transport_context.h92
-rw-r--r--remoting/protocol/webrtc_transport.cc51
-rw-r--r--remoting/protocol/webrtc_transport.h22
-rw-r--r--remoting/protocol/webrtc_transport_unittest.cc19
23 files changed, 412 insertions, 447 deletions
diff --git a/remoting/protocol/chromium_port_allocator.cc b/remoting/protocol/chromium_port_allocator.cc
index ffe6756..5a5c103 100644
--- a/remoting/protocol/chromium_port_allocator.cc
+++ b/remoting/protocol/chromium_port_allocator.cc
@@ -12,7 +12,6 @@
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "remoting/protocol/chromium_socket_factory.h"
-#include "remoting/protocol/network_settings.h"
#include "url/gurl.h"
namespace remoting {
@@ -131,35 +130,13 @@ void ChromiumPortAllocatorSession::OnURLFetchComplete(
// static
scoped_ptr<ChromiumPortAllocator> ChromiumPortAllocator::Create(
- const scoped_refptr<net::URLRequestContextGetter>& url_context,
- const NetworkSettings& network_settings) {
+ const scoped_refptr<net::URLRequestContextGetter>& url_context) {
scoped_ptr<rtc::NetworkManager> network_manager(
new rtc::BasicNetworkManager());
scoped_ptr<rtc::PacketSocketFactory> socket_factory(
new ChromiumPacketSocketFactory());
- scoped_ptr<ChromiumPortAllocator> result(
- new ChromiumPortAllocator(url_context, network_manager.Pass(),
- socket_factory.Pass()));
-
- // We always use PseudoTcp to provide a reliable channel. It provides poor
- // performance when combined with TCP-based transport, so we have to disable
- // TCP ports. ENABLE_SHARED_UFRAG flag is specified so that the same username
- // fragment is shared between all candidates for this channel.
- int flags = cricket::PORTALLOCATOR_DISABLE_TCP |
- cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
- cricket::PORTALLOCATOR_ENABLE_IPV6;
-
- if (!(network_settings.flags & NetworkSettings::NAT_TRAVERSAL_STUN))
- flags |= cricket::PORTALLOCATOR_DISABLE_STUN;
-
- if (!(network_settings.flags & NetworkSettings::NAT_TRAVERSAL_RELAY))
- flags |= cricket::PORTALLOCATOR_DISABLE_RELAY;
-
- result->set_flags(flags);
- result->SetPortRange(network_settings.port_range.min_port,
- network_settings.port_range.max_port);
-
- return result.Pass();
+ return make_scoped_ptr(new ChromiumPortAllocator(
+ url_context, network_manager.Pass(), socket_factory.Pass()));
}
ChromiumPortAllocator::ChromiumPortAllocator(
@@ -173,8 +150,7 @@ ChromiumPortAllocator::ChromiumPortAllocator(
network_manager_(network_manager.Pass()),
socket_factory_(socket_factory.Pass()) {}
-ChromiumPortAllocator::~ChromiumPortAllocator() {
-}
+ChromiumPortAllocator::~ChromiumPortAllocator() {}
cricket::PortAllocatorSession* ChromiumPortAllocator::CreateSessionInternal(
const std::string& content_name,
@@ -186,5 +162,16 @@ cricket::PortAllocatorSession* ChromiumPortAllocator::CreateSessionInternal(
stun_hosts(), relay_hosts(), relay_token(), url_context_);
}
+ChromiumPortAllocatorFactory::ChromiumPortAllocatorFactory(
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
+ : url_request_context_getter_(url_request_context_getter) {}
+
+ChromiumPortAllocatorFactory::~ChromiumPortAllocatorFactory() {}
+
+scoped_ptr<cricket::HttpPortAllocatorBase>
+ChromiumPortAllocatorFactory::CreatePortAllocator() {
+ return ChromiumPortAllocator::Create(url_request_context_getter_);
+}
+
} // namespace protocol
} // namespace remoting
diff --git a/remoting/protocol/chromium_port_allocator.h b/remoting/protocol/chromium_port_allocator.h
index 021000e..65d5799 100644
--- a/remoting/protocol/chromium_port_allocator.h
+++ b/remoting/protocol/chromium_port_allocator.h
@@ -9,22 +9,24 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "net/url_request/url_request_context_getter.h"
+#include "remoting/protocol/port_allocator_factory.h"
#include "third_party/webrtc/p2p/client/httpportallocator.h"
+namespace net {
+class URLRequestContextGetter;
+} // namespace net
+
namespace remoting {
namespace protocol {
struct NetworkSettings;
-// An implementation of cricket::PortAllocator for libjingle that
-// uses Chromium's network stack and configures itself according
-// to the specified NetworkSettings.
+// An implementation of cricket::PortAllocator that uses Chromium's network
+// stack.
class ChromiumPortAllocator : public cricket::HttpPortAllocatorBase {
public:
static scoped_ptr<ChromiumPortAllocator> Create(
- const scoped_refptr<net::URLRequestContextGetter>& url_context,
- const NetworkSettings& network_settings);
+ const scoped_refptr<net::URLRequestContextGetter>& url_context);
~ChromiumPortAllocator() override;
@@ -48,6 +50,21 @@ class ChromiumPortAllocator : public cricket::HttpPortAllocatorBase {
DISALLOW_COPY_AND_ASSIGN(ChromiumPortAllocator);
};
+class ChromiumPortAllocatorFactory : public PortAllocatorFactory {
+ public:
+ ChromiumPortAllocatorFactory(
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
+ ~ChromiumPortAllocatorFactory() override;
+
+ // PortAllocatorFactory interface.
+ scoped_ptr<cricket::HttpPortAllocatorBase> CreatePortAllocator() override;
+
+ private:
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromiumPortAllocatorFactory);
+};
+
} // namespace protocol
} // namespace remoting
diff --git a/remoting/protocol/chromium_port_allocator_factory.cc b/remoting/protocol/chromium_port_allocator_factory.cc
deleted file mode 100644
index 32c980b..0000000
--- a/remoting/protocol/chromium_port_allocator_factory.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "remoting/protocol/chromium_port_allocator_factory.h"
-
-#include "base/logging.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "remoting/protocol/chromium_port_allocator.h"
-#include "remoting/protocol/network_settings.h"
-
-namespace remoting {
-namespace protocol {
-
-ChromiumPortAllocatorFactory::ChromiumPortAllocatorFactory(
- const NetworkSettings& network_settings,
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
- : network_settings_(network_settings),
- url_request_context_getter_(url_request_context_getter) {}
-
-ChromiumPortAllocatorFactory::~ChromiumPortAllocatorFactory() {}
-
-scoped_ptr<PortAllocatorFactory> ChromiumPortAllocatorFactory::Create(
- const NetworkSettings& network_settings,
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
- return scoped_ptr<PortAllocatorFactory>(new ChromiumPortAllocatorFactory(
- network_settings, url_request_context_getter));
-}
-
-cricket::PortAllocator* ChromiumPortAllocatorFactory::CreatePortAllocator() {
- scoped_ptr<ChromiumPortAllocator> port_allocator(
- ChromiumPortAllocator::Create(url_request_context_getter_,
- network_settings_));
- return port_allocator.release();
-}
-
-} // namespace protocol
-} // namespace remoting
-
diff --git a/remoting/protocol/chromium_port_allocator_factory.h b/remoting/protocol/chromium_port_allocator_factory.h
deleted file mode 100644
index 4c7db57..0000000
--- a/remoting/protocol/chromium_port_allocator_factory.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef REMOTING_PROTOCOL_CHROMIUM_PORT_ALLOCATOR_FACTORY_H_
-#define REMOTING_PROTOCOL_CHROMIUM_PORT_ALLOCATOR_FACTORY_H_
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "remoting/protocol/network_settings.h"
-#include "remoting/protocol/port_allocator_factory.h"
-
-namespace net {
-class URLRequestContextGetter;
-} // namespace net
-
-namespace remoting {
-namespace protocol {
-
-class ChromiumPortAllocatorFactory : public PortAllocatorFactory {
- public:
- static scoped_ptr<PortAllocatorFactory> Create(
- const NetworkSettings& network_settings,
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
-
- // PortAllocatorFactory implementation.
- cricket::PortAllocator* CreatePortAllocator() override;
-
- protected:
- ChromiumPortAllocatorFactory(
- const NetworkSettings& network_settings,
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
- ~ChromiumPortAllocatorFactory() override;
-
- private:
- NetworkSettings network_settings_;
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
-
- DISALLOW_COPY_AND_ASSIGN(ChromiumPortAllocatorFactory);
-};
-
-} // namespace protocol
-} // namespace remoting
-
-#endif // REMOTING_PROTOCOL_CHROMIUM_PORT_ALLOCATOR_FACTORY_H_
-
diff --git a/remoting/protocol/connection_to_host.h b/remoting/protocol/connection_to_host.h
index ad9c8ba..f5c8c82 100644
--- a/remoting/protocol/connection_to_host.h
+++ b/remoting/protocol/connection_to_host.h
@@ -27,7 +27,7 @@ class ExtensionMessage;
class HostStub;
class InputStub;
class SessionConfig;
-class TransportFactory;
+class TransportContext;
struct TransportRoute;
class VideoStub;
@@ -92,7 +92,7 @@ class ConnectionToHost {
// and must outlive the ConnectionToHost.
// Caller must set stubs (see below) before calling Connect.
virtual void Connect(SignalStrategy* signal_strategy,
- scoped_ptr<TransportFactory> transport_factory,
+ scoped_refptr<TransportContext> transport_context,
scoped_ptr<Authenticator> authenticator,
const std::string& host_jid,
HostEventCallback* event_callback) = 0;
diff --git a/remoting/protocol/connection_to_host_impl.cc b/remoting/protocol/connection_to_host_impl.cc
index fbfdb30..bcca1b0 100644
--- a/remoting/protocol/connection_to_host_impl.cc
+++ b/remoting/protocol/connection_to_host_impl.cc
@@ -18,8 +18,10 @@
#include "remoting/protocol/client_video_dispatcher.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/errors.h"
+#include "remoting/protocol/ice_transport.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/transport.h"
+#include "remoting/protocol/transport_context.h"
#include "remoting/protocol/video_stub.h"
namespace remoting {
@@ -66,7 +68,7 @@ const char* ConnectionToHost::StateToString(State state) {
void ConnectionToHostImpl::Connect(
SignalStrategy* signal_strategy,
- scoped_ptr<TransportFactory> transport_factory,
+ scoped_refptr<TransportContext> transport_context,
scoped_ptr<Authenticator> authenticator,
const std::string& host_jid,
HostEventCallback* event_callback) {
@@ -91,7 +93,8 @@ void ConnectionToHostImpl::Connect(
signal_strategy_->AddListener(this);
- session_manager_.reset(new JingleSessionManager(transport_factory.Pass()));
+ session_manager_.reset(new JingleSessionManager(
+ make_scoped_ptr(new IceTransportFactory(transport_context))));
session_manager_->set_protocol_config(candidate_config_->Clone());
session_manager_->Init(signal_strategy_, this);
diff --git a/remoting/protocol/connection_to_host_impl.h b/remoting/protocol/connection_to_host_impl.h
index 936d583..9ee9687 100644
--- a/remoting/protocol/connection_to_host_impl.h
+++ b/remoting/protocol/connection_to_host_impl.h
@@ -54,7 +54,7 @@ class ConnectionToHostImpl : public ConnectionToHost,
void set_video_stub(VideoStub* video_stub) override;
void set_audio_stub(AudioStub* audio_stub) override;
void Connect(SignalStrategy* signal_strategy,
- scoped_ptr<TransportFactory> transport_factory,
+ scoped_refptr<TransportContext> transport_context,
scoped_ptr<Authenticator> authenticator,
const std::string& host_jid,
HostEventCallback* event_callback) override;
diff --git a/remoting/protocol/fake_connection_to_host.cc b/remoting/protocol/fake_connection_to_host.cc
index 2983596..865b61c 100644
--- a/remoting/protocol/fake_connection_to_host.cc
+++ b/remoting/protocol/fake_connection_to_host.cc
@@ -5,6 +5,7 @@
#include "remoting/protocol/fake_connection_to_host.h"
#include "remoting/protocol/authenticator.h"
+#include "remoting/protocol/transport_context.h"
namespace remoting {
namespace test {
@@ -36,7 +37,7 @@ void FakeConnectionToHost::set_audio_stub(protocol::AudioStub* audio_stub) {
void FakeConnectionToHost::Connect(
SignalStrategy* signal_strategy,
- scoped_ptr<protocol::TransportFactory> transport_factory,
+ scoped_refptr<protocol::TransportContext> transport_context,
scoped_ptr<protocol::Authenticator> authenticator,
const std::string& host_jid,
HostEventCallback* event_callback) {
diff --git a/remoting/protocol/fake_connection_to_host.h b/remoting/protocol/fake_connection_to_host.h
index 1c3fe40..85ea24a 100644
--- a/remoting/protocol/fake_connection_to_host.h
+++ b/remoting/protocol/fake_connection_to_host.h
@@ -26,7 +26,7 @@ class FakeConnectionToHost : public protocol::ConnectionToHost {
void set_video_stub(protocol::VideoStub* video_stub) override;
void set_audio_stub(protocol::AudioStub* audio_stub) override;
void Connect(SignalStrategy* signal_strategy,
- scoped_ptr<protocol::TransportFactory> transport_factory,
+ scoped_refptr<protocol::TransportContext> transport_context,
scoped_ptr<protocol::Authenticator> authenticator,
const std::string& host_jid,
HostEventCallback* event_callback) override;
diff --git a/remoting/protocol/ice_transport.cc b/remoting/protocol/ice_transport.cc
index 8984dd2..08e95d3 100644
--- a/remoting/protocol/ice_transport.cc
+++ b/remoting/protocol/ice_transport.cc
@@ -10,6 +10,7 @@
#include "remoting/protocol/pseudotcp_channel_factory.h"
#include "remoting/protocol/secure_channel_factory.h"
#include "remoting/protocol/stream_channel_factory.h"
+#include "remoting/protocol/transport_context.h"
namespace remoting {
namespace protocol {
@@ -22,24 +23,16 @@ const int kTransportInfoSendDelayMs = 20;
// Name of the multiplexed channel.
static const char kMuxChannelName[] = "mux";
-IceTransport::IceTransport(cricket::PortAllocator* port_allocator,
- const NetworkSettings& network_settings,
- TransportRole role)
- : port_allocator_(port_allocator),
- network_settings_(network_settings),
- role_(role),
- weak_factory_(this) {}
+IceTransport::IceTransport(scoped_refptr<TransportContext> transport_context)
+ : transport_context_(transport_context), weak_factory_(this) {
+ transport_context->Prepare();
+}
IceTransport::~IceTransport() {
channel_multiplexer_.reset();
DCHECK(channels_.empty());
}
-base::Closure IceTransport::GetCanStartClosure() {
- return base::Bind(&IceTransport::OnCanStart,
- weak_factory_.GetWeakPtr());
-}
-
void IceTransport::Start(Transport::EventHandler* event_handler,
Authenticator* authenticator) {
DCHECK(event_handler);
@@ -95,24 +88,12 @@ StreamChannelFactory* IceTransport::GetMultiplexedChannelFactory() {
return channel_multiplexer_.get();
}
-void IceTransport::OnCanStart() {
- DCHECK(!can_start_);
-
- can_start_ = true;
- for (ChannelsMap::iterator it = channels_.begin(); it != channels_.end();
- ++it) {
- it->second->OnCanStart();
- }
-}
-
void IceTransport::CreateChannel(const std::string& name,
const ChannelCreatedCallback& callback) {
DCHECK(!channels_[name]);
scoped_ptr<IceTransportChannel> channel(
- new IceTransportChannel(port_allocator_, network_settings_, role_));
- if (can_start_)
- channel->OnCanStart();
+ new IceTransportChannel(transport_context_));
channel->Connect(name, this, callback);
AddPendingRemoteTransportInfo(channel.get());
channels_[name] = channel.release();
@@ -205,5 +186,15 @@ void IceTransport::SendTransportInfo() {
pending_transport_info_message_.reset();
}
+IceTransportFactory::IceTransportFactory(
+ scoped_refptr<TransportContext> transport_context)
+ : transport_context_(transport_context) {}
+
+IceTransportFactory::~IceTransportFactory() {}
+
+scoped_ptr<Transport> IceTransportFactory::CreateTransport() {
+ return make_scoped_ptr(new IceTransport(transport_context_.get()));
+}
+
} // namespace protocol
} // namespace remoting
diff --git a/remoting/protocol/ice_transport.h b/remoting/protocol/ice_transport.h
index 09f7da6..fc72b29 100644
--- a/remoting/protocol/ice_transport.h
+++ b/remoting/protocol/ice_transport.h
@@ -27,16 +27,10 @@ class IceTransport : public Transport,
public IceTransportChannel::Delegate,
public DatagramChannelFactory {
public:
- // |port_allocator| must outlive the session.
- IceTransport(cricket::PortAllocator* port_allocator,
- const NetworkSettings& network_settings,
- TransportRole role);
+ // |transport_context| must outlive the session.
+ explicit IceTransport(scoped_refptr<TransportContext> transport_context);
~IceTransport() override;
- // Returns a closure that must be called before transport channels start
- // connecting .
- base::Closure GetCanStartClosure();
-
// Transport interface.
void Start(EventHandler* event_handler,
Authenticator* authenticator) override;
@@ -47,8 +41,6 @@ class IceTransport : public Transport,
private:
typedef std::map<std::string, IceTransportChannel*> ChannelsMap;
- void OnCanStart();
-
// DatagramChannelFactory interface.
void CreateChannel(const std::string& name,
const ChannelCreatedCallback& callback) override;
@@ -76,11 +68,7 @@ class IceTransport : public Transport,
// Sends transport-info message with candidates from |pending_candidates_|.
void SendTransportInfo();
- cricket::PortAllocator* port_allocator_;
- NetworkSettings network_settings_;
- TransportRole role_;
-
- bool can_start_ = false;
+ scoped_refptr<TransportContext> transport_context_;
Transport::EventHandler* event_handler_ = nullptr;
@@ -102,6 +90,20 @@ class IceTransport : public Transport,
DISALLOW_COPY_AND_ASSIGN(IceTransport);
};
+class IceTransportFactory : public TransportFactory {
+ public:
+ IceTransportFactory(scoped_refptr<TransportContext> transport_context);
+ ~IceTransportFactory() override;
+
+ // TransportFactory interface.
+ scoped_ptr<Transport> CreateTransport() override;
+
+ private:
+ scoped_refptr<TransportContext> transport_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(IceTransportFactory);
+};
+
} // namespace protocol
} // namespace remoting
diff --git a/remoting/protocol/ice_transport_channel.cc b/remoting/protocol/ice_transport_channel.cc
index 7e47bce..1ef4d7d 100644
--- a/remoting/protocol/ice_transport_channel.cc
+++ b/remoting/protocol/ice_transport_channel.cc
@@ -13,6 +13,7 @@
#include "jingle/glue/utils.h"
#include "net/base/net_errors.h"
#include "remoting/protocol/channel_socket_adapter.h"
+#include "remoting/protocol/transport_context.h"
#include "third_party/webrtc/base/network.h"
#include "third_party/webrtc/p2p/base/constants.h"
#include "third_party/webrtc/p2p/base/p2ptransportchannel.h"
@@ -46,16 +47,11 @@ TransportRoute::RouteType CandidateTypeToTransportRouteType(
} // namespace
-IceTransportChannel::IceTransportChannel(cricket::PortAllocator* port_allocator,
- const NetworkSettings& network_settings,
- TransportRole role)
- : port_allocator_(port_allocator),
- network_settings_(network_settings),
- role_(role),
- delegate_(nullptr),
+IceTransportChannel::IceTransportChannel(
+ scoped_refptr<TransportContext> transport_context)
+ : transport_context_(transport_context),
ice_username_fragment_(
rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH)),
- can_start_(false),
connect_attempts_left_(kMaxReconnectAttempts),
weak_factory_(this) {
DCHECK(!ice_username_fragment_.empty());
@@ -66,32 +62,11 @@ IceTransportChannel::~IceTransportChannel() {
delegate_->OnTransportDeleted(this);
- if (channel_.get()) {
- base::ThreadTaskRunnerHandle::Get()->DeleteSoon(
- FROM_HERE, channel_.release());
- }
-}
-
-void IceTransportChannel::OnCanStart() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- DCHECK(!can_start_);
- can_start_ = true;
-
- // If Connect() has been called then start connection.
- if (!callback_.is_null())
- DoStart();
-
- // Pass pending ICE credentials and candidates to the channel.
- if (!remote_ice_username_fragment_.empty()) {
- channel_->SetRemoteIceCredentials(remote_ice_username_fragment_,
- remote_ice_password_);
- }
-
- while (!pending_candidates_.empty()) {
- channel_->AddRemoteCandidate(pending_candidates_.front());
- pending_candidates_.pop_front();
- }
+ auto task_runner = base::ThreadTaskRunnerHandle::Get();
+ if (channel_)
+ task_runner->DeleteSoon(FROM_HERE, channel_.release());
+ if (port_allocator_)
+ task_runner->DeleteSoon(FROM_HERE, port_allocator_.release());
}
void IceTransportChannel::Connect(const std::string& name,
@@ -107,20 +82,24 @@ void IceTransportChannel::Connect(const std::string& name,
delegate_ = delegate;
callback_ = callback;
- if (can_start_)
- DoStart();
+ transport_context_->CreatePortAllocator(
+ base::Bind(&IceTransportChannel::OnPortAllocatorCreated,
+ weak_factory_.GetWeakPtr()));
}
-void IceTransportChannel::DoStart() {
+void IceTransportChannel::OnPortAllocatorCreated(
+ scoped_ptr<cricket::PortAllocator> port_allocator){
DCHECK(!channel_.get());
+ port_allocator_ = port_allocator.Pass();
+
// Create P2PTransportChannel, attach signal handlers and connect it.
// TODO(sergeyu): Specify correct component ID for the channel.
channel_.reset(new cricket::P2PTransportChannel(
- std::string(), 0, nullptr, port_allocator_));
+ std::string(), 0, nullptr, port_allocator_.get()));
std::string ice_password = rtc::CreateRandomString(cricket::ICE_PWD_LENGTH);
channel_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
- channel_->SetIceRole((role_ == TransportRole::CLIENT)
+ channel_->SetIceRole((transport_context_->role() == TransportRole::CLIENT)
? cricket::ICEROLE_CONTROLLING
: cricket::ICEROLE_CONTROLLED);
delegate_->OnTransportIceCredentials(this, ice_username_fragment_,
@@ -134,12 +113,23 @@ void IceTransportChannel::DoStart() {
this, &IceTransportChannel::OnReceivingState);
channel_->SignalWritableState.connect(
this, &IceTransportChannel::OnWritableState);
- channel_->set_incoming_only(
- !(network_settings_.flags & NetworkSettings::NAT_TRAVERSAL_OUTGOING));
+ channel_->set_incoming_only(!(transport_context_->network_settings().flags &
+ NetworkSettings::NAT_TRAVERSAL_OUTGOING));
channel_->Connect();
channel_->MaybeStartGathering();
+ // Pass pending ICE credentials and candidates to the channel.
+ if (!remote_ice_username_fragment_.empty()) {
+ channel_->SetRemoteIceCredentials(remote_ice_username_fragment_,
+ remote_ice_password_);
+ }
+
+ while (!pending_candidates_.empty()) {
+ channel_->AddRemoteCandidate(pending_candidates_.front());
+ pending_candidates_.pop_front();
+ }
+
--connect_attempts_left_;
// Start reconnection timer.
@@ -158,7 +148,7 @@ void IceTransportChannel::NotifyConnected() {
}
void IceTransportChannel::SetRemoteCredentials(const std::string& ufrag,
- const std::string& password) {
+ const std::string& password) {
DCHECK(thread_checker_.CalledOnValidThread());
remote_ice_username_fragment_ = ufrag;
@@ -174,7 +164,7 @@ void IceTransportChannel::AddRemoteCandidate(
// To enforce the no-relay setting, it's not enough to not produce relay
// candidates. It's also necessary to discard remote relay candidates.
- bool relay_allowed = (network_settings_.flags &
+ bool relay_allowed = (transport_context_->network_settings().flags &
NetworkSettings::NAT_TRAVERSAL_RELAY) != 0;
if (!relay_allowed && candidate.type() == cricket::RELAY_PORT_TYPE)
return;
diff --git a/remoting/protocol/ice_transport_channel.h b/remoting/protocol/ice_transport_channel.h
index a0dd6e7..7bde3e5 100644
--- a/remoting/protocol/ice_transport_channel.h
+++ b/remoting/protocol/ice_transport_channel.h
@@ -26,6 +26,8 @@ class TransportChannelImpl;
namespace remoting {
namespace protocol {
+class TransportContext;
+
class IceTransportChannel : public sigslot::has_slots<> {
public:
class Delegate {
@@ -59,14 +61,10 @@ class IceTransportChannel : public sigslot::has_slots<> {
typedef base::Callback<void(scoped_ptr<P2PDatagramSocket>)> ConnectedCallback;
- IceTransportChannel(cricket::PortAllocator* port_allocator,
- const NetworkSettings& network_settings,
- TransportRole role);
+ explicit IceTransportChannel(
+ scoped_refptr<TransportContext> transport_context);
~IceTransportChannel() override;
- // Called by IceTransport when it has fresh Jingle info.
- void OnCanStart();
-
// Connects the channel and calls the |callback| after that.
void Connect(const std::string& name,
Delegate* delegate,
@@ -87,7 +85,9 @@ class IceTransportChannel : public sigslot::has_slots<> {
bool is_connected() const;
private:
- void DoStart();
+ void OnPortAllocatorCreated(
+ scoped_ptr<cricket::PortAllocator> port_allocator);
+
void NotifyConnected();
// Signal handlers for cricket::TransportChannel.
@@ -107,16 +107,14 @@ class IceTransportChannel : public sigslot::has_slots<> {
// Tries to connect by restarting ICE. Called by |reconnect_timer_|.
void TryReconnect();
- cricket::PortAllocator* port_allocator_;
- NetworkSettings network_settings_;
- TransportRole role_;
+ scoped_refptr<TransportContext> transport_context_;
std::string name_;
- Delegate* delegate_;
+ Delegate* delegate_ = nullptr;
ConnectedCallback callback_;
std::string ice_username_fragment_;
- bool can_start_;
+ scoped_ptr<cricket::PortAllocator> port_allocator_;
std::string remote_ice_username_fragment_;
std::string remote_ice_password_;
diff --git a/remoting/protocol/ice_transport_factory.cc b/remoting/protocol/ice_transport_factory.cc
deleted file mode 100644
index 19b14cb..0000000
--- a/remoting/protocol/ice_transport_factory.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "remoting/protocol/ice_transport_factory.h"
-
-#include "base/single_thread_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "remoting/protocol/ice_transport.h"
-#include "third_party/webrtc/p2p/client/httpportallocator.h"
-
-namespace remoting {
-namespace protocol {
-
-// Get fresh STUN/Relay configuration every hour.
-static const int kJingleInfoUpdatePeriodSeconds = 3600;
-
-IceTransportFactory::IceTransportFactory(
- SignalStrategy* signal_strategy,
- scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator,
- const NetworkSettings& network_settings,
- TransportRole role)
- : signal_strategy_(signal_strategy),
- port_allocator_(port_allocator.Pass()),
- network_settings_(network_settings),
- role_(role) {}
-
-IceTransportFactory::~IceTransportFactory() {
- // This method may be called in response to a libjingle signal, so
- // libjingle objects must be deleted asynchronously.
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- base::ThreadTaskRunnerHandle::Get();
- task_runner->DeleteSoon(FROM_HERE, port_allocator_.release());
-}
-
-scoped_ptr<Transport> IceTransportFactory::CreateTransport() {
- scoped_ptr<IceTransport> result(
- new IceTransport(port_allocator_.get(), network_settings_, role_));
-
- EnsureFreshJingleInfo();
-
- // If there is a pending |jingle_info_request_| delay starting the new
- // transport until the request is finished.
- if (jingle_info_request_) {
- on_jingle_info_callbacks_.push_back(result->GetCanStartClosure());
- } else {
- result->GetCanStartClosure().Run();
- }
-
- return result.Pass();
-}
-
-void IceTransportFactory::EnsureFreshJingleInfo() {
- uint32 stun_or_relay_flags = NetworkSettings::NAT_TRAVERSAL_STUN |
- NetworkSettings::NAT_TRAVERSAL_RELAY;
- if (!(network_settings_.flags & stun_or_relay_flags) ||
- jingle_info_request_) {
- return;
- }
-
- if (last_jingle_info_update_time_.is_null() ||
- base::TimeTicks::Now() - last_jingle_info_update_time_ >
- base::TimeDelta::FromSeconds(kJingleInfoUpdatePeriodSeconds)) {
- jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_));
- jingle_info_request_->Send(base::Bind(
- &IceTransportFactory::OnJingleInfo, base::Unretained(this)));
- }
-}
-
-void IceTransportFactory::OnJingleInfo(
- const std::string& relay_token,
- const std::vector<std::string>& relay_hosts,
- const std::vector<rtc::SocketAddress>& stun_hosts) {
- if (!relay_token.empty() && !relay_hosts.empty()) {
- port_allocator_->SetRelayHosts(relay_hosts);
- port_allocator_->SetRelayToken(relay_token);
- }
- if (!stun_hosts.empty()) {
- port_allocator_->SetStunHosts(stun_hosts);
- }
-
- jingle_info_request_.reset();
- if ((!relay_token.empty() && !relay_hosts.empty()) || !stun_hosts.empty())
- last_jingle_info_update_time_ = base::TimeTicks::Now();
-
- while (!on_jingle_info_callbacks_.empty()) {
- on_jingle_info_callbacks_.begin()->Run();
- on_jingle_info_callbacks_.pop_front();
- }
-}
-
-} // namespace protocol
-} // namespace remoting
diff --git a/remoting/protocol/ice_transport_factory.h b/remoting/protocol/ice_transport_factory.h
deleted file mode 100644
index deaf72e..0000000
--- a/remoting/protocol/ice_transport_factory.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef REMOTING_PROTOCOL_ICE_TRANSPORT_FACTORY_H_
-#define REMOTING_PROTOCOL_ICE_TRANSPORT_FACTORY_H_
-
-#include <list>
-
-#include "base/macros.h"
-#include "remoting/protocol/network_settings.h"
-#include "remoting/protocol/transport.h"
-#include "remoting/signaling/jingle_info_request.h"
-
-namespace cricket {
-class HttpPortAllocatorBase;
-} // namespace cricket
-
-namespace remoting {
-
-class SignalStrategy;
-
-namespace protocol {
-
-class IceTransportFactory : public TransportFactory {
- public:
- IceTransportFactory(
- SignalStrategy* signal_strategy,
- scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator,
- const NetworkSettings& network_settings,
- TransportRole role);
- ~IceTransportFactory() override;
-
- // TransportFactory interface.
- scoped_ptr<Transport> CreateTransport() override;
-
- private:
- void EnsureFreshJingleInfo();
- void OnJingleInfo(const std::string& relay_token,
- const std::vector<std::string>& relay_hosts,
- const std::vector<rtc::SocketAddress>& stun_hosts);
-
- SignalStrategy* signal_strategy_;
- scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator_;
- NetworkSettings network_settings_;
- TransportRole role_;
-
- base::TimeTicks last_jingle_info_update_time_;
- scoped_ptr<JingleInfoRequest> jingle_info_request_;
-
- // When there is an active |jingle_info_request_| stores list of callbacks to
- // be called once the |jingle_info_request_| is finished.
- std::list<base::Closure> on_jingle_info_callbacks_;
-
- DISALLOW_COPY_AND_ASSIGN(IceTransportFactory);
-};
-
-} // namespace protocol
-} // namespace remoting
-
-#endif // REMOTING_PROTOCOL_ICE_TRANSPORT_FACTORY_H_
diff --git a/remoting/protocol/ice_transport_unittest.cc b/remoting/protocol/ice_transport_unittest.cc
index 110a6d7..1f881a6 100644
--- a/remoting/protocol/ice_transport_unittest.cc
+++ b/remoting/protocol/ice_transport_unittest.cc
@@ -17,6 +17,7 @@
#include "remoting/protocol/fake_authenticator.h"
#include "remoting/protocol/p2p_stream_socket.h"
#include "remoting/protocol/stream_channel_factory.h"
+#include "remoting/protocol/transport_context.h"
#include "remoting/signaling/fake_signal_strategy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -128,20 +129,19 @@ class IceTransportTest : public testing::Test {
}
void InitializeConnection() {
- port_allocator_ = ChromiumPortAllocator::Create(nullptr, network_settings_);
-
- host_transport_.reset(new IceTransport(
- port_allocator_.get(), network_settings_, TransportRole::SERVER));
- host_transport_->GetCanStartClosure().Run();
-
+ host_transport_.reset(new IceTransport(new TransportContext(
+ signal_strategy_.get(),
+ make_scoped_ptr(new ChromiumPortAllocatorFactory(nullptr)),
+ network_settings_, TransportRole::SERVER)));
if (!host_authenticator_) {
host_authenticator_.reset(new FakeAuthenticator(
FakeAuthenticator::HOST, 0, FakeAuthenticator::ACCEPT, true));
}
- client_transport_.reset(new IceTransport(
- port_allocator_.get(), network_settings_, TransportRole::CLIENT));
- client_transport_->GetCanStartClosure().Run();
+ client_transport_.reset(new IceTransport(new TransportContext(
+ signal_strategy_.get(),
+ make_scoped_ptr(new ChromiumPortAllocatorFactory(nullptr)),
+ network_settings_, TransportRole::CLIENT)));
if (!client_authenticator_) {
client_authenticator_.reset(new FakeAuthenticator(
FakeAuthenticator::CLIENT, 0, FakeAuthenticator::ACCEPT, true));
@@ -208,14 +208,10 @@ class IceTransportTest : public testing::Test {
base::TimeDelta transport_info_delay_;
- scoped_ptr<cricket::PortAllocator> port_allocator_;
-
- // scoped_ptr<IceTransportFactory> host_transport_factory_;
scoped_ptr<IceTransport> host_transport_;
TestTransportEventHandler host_event_handler_;
scoped_ptr<FakeAuthenticator> host_authenticator_;
- // scoped_ptr<IceTransportFactory> client_transport_factory_;
scoped_ptr<IceTransport> client_transport_;
TestTransportEventHandler client_event_handler_;
scoped_ptr<FakeAuthenticator> client_authenticator_;
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc
index c1338951..03cb533 100644
--- a/remoting/protocol/jingle_session_unittest.cc
+++ b/remoting/protocol/jingle_session_unittest.cc
@@ -19,9 +19,10 @@
#include "remoting/protocol/chromium_port_allocator.h"
#include "remoting/protocol/connection_tester.h"
#include "remoting/protocol/fake_authenticator.h"
-#include "remoting/protocol/ice_transport_factory.h"
+#include "remoting/protocol/ice_transport.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/network_settings.h"
+#include "remoting/protocol/transport_context.h"
#include "remoting/signaling/fake_signal_strategy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -102,11 +103,10 @@ class JingleSessionTest : public testing::Test {
FakeSignalStrategy::Connect(host_signal_strategy_.get(),
client_signal_strategy_.get());
- scoped_ptr<TransportFactory> host_transport(new IceTransportFactory(
- nullptr,
- ChromiumPortAllocator::Create(nullptr, network_settings_).Pass(),
- network_settings_, TransportRole::SERVER));
- host_server_.reset(new JingleSessionManager(host_transport.Pass()));
+ host_server_.reset(new JingleSessionManager(
+ make_scoped_ptr(new IceTransportFactory(new TransportContext(
+ nullptr, make_scoped_ptr(new ChromiumPortAllocatorFactory(nullptr)),
+ network_settings_, TransportRole::SERVER)))));
host_server_->Init(host_signal_strategy_.get(), &host_server_listener_);
scoped_ptr<AuthenticatorFactory> factory(
@@ -114,12 +114,10 @@ class JingleSessionTest : public testing::Test {
messages_till_start, auth_action, true));
host_server_->set_authenticator_factory(factory.Pass());
- scoped_ptr<TransportFactory> client_transport(new IceTransportFactory(
- nullptr,
- ChromiumPortAllocator::Create(nullptr, network_settings_).Pass(),
- network_settings_, TransportRole::CLIENT));
- client_server_.reset(
- new JingleSessionManager(client_transport.Pass()));
+ client_server_.reset(new JingleSessionManager(
+ make_scoped_ptr(new IceTransportFactory(new TransportContext(
+ nullptr, make_scoped_ptr(new ChromiumPortAllocatorFactory(nullptr)),
+ network_settings_, TransportRole::CLIENT)))));
client_server_->Init(client_signal_strategy_.get(),
&client_server_listener_);
}
diff --git a/remoting/protocol/port_allocator_factory.h b/remoting/protocol/port_allocator_factory.h
index 741ccca..b08df71 100644
--- a/remoting/protocol/port_allocator_factory.h
+++ b/remoting/protocol/port_allocator_factory.h
@@ -5,7 +5,11 @@
#ifndef REMOTING_PROTOCOL_PORT_ALLOCATOR_FACTORY_H_
#define REMOTING_PROTOCOL_PORT_ALLOCATOR_FACTORY_H_
-#include "third_party/webrtc/p2p/base/portallocator.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace cricket {
+class HttpPortAllocatorBase;
+} // namespace cricket
namespace remoting {
namespace protocol {
@@ -14,7 +18,7 @@ namespace protocol {
// for ICE negotiation.
class PortAllocatorFactory {
public:
- virtual cricket::PortAllocator* CreatePortAllocator() = 0;
+ virtual scoped_ptr<cricket::HttpPortAllocatorBase> CreatePortAllocator() = 0;
virtual ~PortAllocatorFactory() {}
};
diff --git a/remoting/protocol/transport_context.cc b/remoting/protocol/transport_context.cc
new file mode 100644
index 0000000..251a028
--- /dev/null
+++ b/remoting/protocol/transport_context.cc
@@ -0,0 +1,122 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/protocol/transport_context.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "remoting/protocol/port_allocator_factory.h"
+#include "third_party/webrtc/p2p/client/httpportallocator.h"
+
+namespace remoting {
+namespace protocol {
+
+// Get fresh STUN/Relay configuration every hour.
+static const int kJingleInfoUpdatePeriodSeconds = 3600;
+
+TransportContext::TransportContext(
+ SignalStrategy* signal_strategy,
+ scoped_ptr<PortAllocatorFactory> port_allocator_factory,
+ const NetworkSettings& network_settings,
+ TransportRole role)
+ : signal_strategy_(signal_strategy),
+ port_allocator_factory_(port_allocator_factory.Pass()),
+ network_settings_(network_settings),
+ role_(role) {}
+
+TransportContext::~TransportContext() {}
+
+void TransportContext::Prepare() {
+ EnsureFreshJingleInfo();
+}
+
+void TransportContext::CreatePortAllocator(
+ const CreatePortAllocatorCallback& callback) {
+ EnsureFreshJingleInfo();
+
+ // If there is a pending |jingle_info_request_| delay starting the new
+ // transport until the request is finished.
+ if (jingle_info_request_) {
+ pending_port_allocator_requests_.push_back(callback);
+ } else {
+ callback.Run(CreatePortAllocatorInternal());
+ }
+}
+
+void TransportContext::EnsureFreshJingleInfo() {
+ // Check if request is already pending.
+ if (jingle_info_request_)
+ return;
+
+ // Don't need to make jingleinfo request if both STUN and Relay are disabled.
+ if ((network_settings_.flags & (NetworkSettings::NAT_TRAVERSAL_STUN |
+ NetworkSettings::NAT_TRAVERSAL_RELAY)) == 0) {
+ return;
+ }
+
+ if (last_jingle_info_update_time_.is_null() ||
+ base::TimeTicks::Now() - last_jingle_info_update_time_ >
+ base::TimeDelta::FromSeconds(kJingleInfoUpdatePeriodSeconds)) {
+ jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_));
+ jingle_info_request_->Send(base::Bind(
+ &TransportContext::OnJingleInfo, base::Unretained(this)));
+ }
+}
+
+void TransportContext::OnJingleInfo(
+ const std::string& relay_token,
+ const std::vector<std::string>& relay_hosts,
+ const std::vector<rtc::SocketAddress>& stun_hosts) {
+ relay_token_ = relay_token;
+ relay_hosts_ = relay_hosts;
+ stun_hosts_ = stun_hosts;
+
+ jingle_info_request_.reset();
+ if ((!relay_token.empty() && !relay_hosts.empty()) || !stun_hosts.empty())
+ last_jingle_info_update_time_ = base::TimeTicks::Now();
+
+ while (!pending_port_allocator_requests_.empty()) {
+ pending_port_allocator_requests_.begin()->Run(
+ CreatePortAllocatorInternal());
+ pending_port_allocator_requests_.pop_front();
+ }
+}
+
+scoped_ptr<cricket::PortAllocator>
+TransportContext::CreatePortAllocatorInternal() {
+ scoped_ptr<cricket::HttpPortAllocatorBase> result =
+ port_allocator_factory_->CreatePortAllocator();
+
+ if (!relay_token_.empty() && !relay_hosts_.empty()) {
+ result->SetRelayHosts(relay_hosts_);
+ result->SetRelayToken(relay_token_);
+ }
+ if (!stun_hosts_.empty())
+ result->SetStunHosts(stun_hosts_);
+
+ // We always use PseudoTcp to provide a reliable channel. It provides poor
+ // performance when combined with TCP-based transport, so we have to disable
+ // TCP ports. ENABLE_SHARED_UFRAG flag is specified so that the same username
+ // fragment is shared between all candidates.
+ int flags = cricket::PORTALLOCATOR_DISABLE_TCP |
+ cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
+ cricket::PORTALLOCATOR_ENABLE_IPV6;
+
+ if (!(network_settings_.flags & NetworkSettings::NAT_TRAVERSAL_STUN))
+ flags |= cricket::PORTALLOCATOR_DISABLE_STUN;
+
+ if (!(network_settings_.flags & NetworkSettings::NAT_TRAVERSAL_RELAY))
+ flags |= cricket::PORTALLOCATOR_DISABLE_RELAY;
+
+ result->set_flags(flags);
+ result->SetPortRange(network_settings_.port_range.min_port,
+ network_settings_.port_range.max_port);
+
+ return result.Pass();
+}
+
+} // namespace protocol
+} // namespace remoting
diff --git a/remoting/protocol/transport_context.h b/remoting/protocol/transport_context.h
new file mode 100644
index 0000000..faac2d2
--- /dev/null
+++ b/remoting/protocol/transport_context.h
@@ -0,0 +1,92 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_PROTOCOL_TRANSPORT_CONTEXT_H_
+#define REMOTING_PROTOCOL_TRANSPORT_CONTEXT_H_
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "remoting/protocol/network_settings.h"
+#include "remoting/protocol/transport.h"
+#include "remoting/signaling/jingle_info_request.h"
+
+namespace cricket {
+class PortAllocator;
+} // namespace cricket
+
+namespace remoting {
+
+class SignalStrategy;
+
+namespace protocol {
+
+class PortAllocatorFactory;
+
+// TransportContext is responsible for storing all parameters required for
+// P2P transport initialization. It's also responsible for making JingleInfo
+// request and creation of PortAllocators configured according to the JingleInfo
+// result.
+class TransportContext : public base::RefCountedThreadSafe<TransportContext> {
+ public:
+ typedef base::Callback<void(scoped_ptr<cricket::PortAllocator>
+ port_allocator)> CreatePortAllocatorCallback;
+
+ TransportContext(
+ SignalStrategy* signal_strategy,
+ scoped_ptr<PortAllocatorFactory> port_allocator_factory,
+ const NetworkSettings& network_settings,
+ TransportRole role);
+
+ // Prepares to create new PortAllocator instances. It may be called while
+ // connection is being negotiated to minimize the chance that the following
+ // CreatePortAllocator() will be blocking.
+ void Prepare();
+
+ // Creates new PortAllocator making sure that it has correct STUN and TURN
+ // information.
+ void CreatePortAllocator(const CreatePortAllocatorCallback& callback);
+
+ const NetworkSettings& network_settings() { return network_settings_; }
+ TransportRole role() { return role_; }
+
+ private:
+ friend class base::RefCountedThreadSafe<TransportContext>;
+
+ ~TransportContext();
+
+ void EnsureFreshJingleInfo();
+ void OnJingleInfo(const std::string& relay_token,
+ const std::vector<std::string>& relay_hosts,
+ const std::vector<rtc::SocketAddress>& stun_hosts);
+
+ scoped_ptr<cricket::PortAllocator> CreatePortAllocatorInternal();
+
+ SignalStrategy* signal_strategy_;
+ scoped_ptr<PortAllocatorFactory> port_allocator_factory_;
+ NetworkSettings network_settings_;
+ TransportRole role_;
+
+ base::TimeTicks last_jingle_info_update_time_;
+ scoped_ptr<JingleInfoRequest> jingle_info_request_;
+
+ std::string relay_token_;
+ std::vector<std::string> relay_hosts_;
+ std::vector<rtc::SocketAddress> stun_hosts_;
+
+ // When there is an active |jingle_info_request_| stores list of callbacks to
+ // be called once the |jingle_info_request_| is finished.
+ std::list<CreatePortAllocatorCallback> pending_port_allocator_requests_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransportContext);
+};
+
+} // namespace protocol
+} // namespace remoting
+
+#endif // REMOTING_PROTOCOL_TRANSPORT_CONTEXT_H_
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc
index 2c82aab..e4fd5c8f 100644
--- a/remoting/protocol/webrtc_transport.cc
+++ b/remoting/protocol/webrtc_transport.cc
@@ -10,6 +10,7 @@
#include "base/task_runner_util.h"
#include "base/thread_task_runner_handle.h"
#include "jingle/glue/thread_wrapper.h"
+#include "remoting/protocol/transport_context.h"
#include "third_party/libjingle/source/talk/app/webrtc/test/fakeconstraints.h"
#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
#include "third_party/webrtc/modules/audio_device/include/fake_audio_device.h"
@@ -99,11 +100,10 @@ class SetSessionDescriptionObserver
} // namespace
-WebrtcTransport::WebrtcTransport(rtc::Thread* worker_thread,
- PortAllocatorFactory* port_allocator_factory,
- TransportRole role)
- : port_allocator_factory_(port_allocator_factory),
- role_(role),
+WebrtcTransport::WebrtcTransport(
+ rtc::Thread* worker_thread,
+ scoped_refptr<TransportContext> transport_context)
+ : transport_context_(transport_context),
worker_thread_(worker_thread),
weak_factory_(this) {}
@@ -114,8 +114,14 @@ void WebrtcTransport::Start(EventHandler* event_handler,
DCHECK(thread_checker_.CalledOnValidThread());
event_handler_ = event_handler;
-
// TODO(sergeyu): Use the |authenticator| to authenticate PeerConnection.
+
+ transport_context_->CreatePortAllocator(base::Bind(
+ &WebrtcTransport::OnPortAllocatorCreated, weak_factory_.GetWeakPtr()));
+}
+
+void WebrtcTransport::OnPortAllocatorCreated(
+ scoped_ptr<cricket::PortAllocator> port_allocator) {
jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
// TODO(sergeyu): Investigate if it's possible to avoid Send().
@@ -136,16 +142,15 @@ void WebrtcTransport::Start(EventHandler* event_handler,
constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp,
webrtc::MediaConstraintsInterface::kValueTrue);
- rtc::scoped_ptr<cricket::PortAllocator> port_allocator(
- port_allocator_factory_->CreatePortAllocator());
-
peer_connection_ = peer_connection_factory_->CreatePeerConnection(
- rtc_config, &constraints, std::move(port_allocator), nullptr, this);
+ rtc_config, &constraints,
+ rtc::scoped_ptr<cricket::PortAllocator>(port_allocator.release()),
+ nullptr, this);
- data_stream_adapter_.Initialize(peer_connection_,
- role_ == TransportRole::SERVER);
+ data_stream_adapter_.Initialize(
+ peer_connection_, transport_context_->role() == TransportRole::SERVER);
- if (role_ == TransportRole::SERVER)
+ if (transport_context_->role() == TransportRole::SERVER)
RequestNegotiation();
}
@@ -162,7 +167,7 @@ bool WebrtcTransport::ProcessTransportInfo(XmlElement* transport_info) {
QName(kTransportNamespace, "session-description"));
if (session_description) {
webrtc::PeerConnectionInterface::SignalingState expected_state =
- role_ == TransportRole::CLIENT
+ transport_context_->role() == TransportRole::CLIENT
? webrtc::PeerConnectionInterface::kStable
: webrtc::PeerConnectionInterface::kHaveLocalOffer;
if (peer_connection_->signaling_state() != expected_state) {
@@ -365,7 +370,7 @@ void WebrtcTransport::OnDataChannel(
void WebrtcTransport::OnRenegotiationNeeded() {
DCHECK(thread_checker_.CalledOnValidThread());
- if (role_ == TransportRole::SERVER) {
+ if (transport_context_->role() == TransportRole::SERVER) {
RequestNegotiation();
} else {
// TODO(sergeyu): Is it necessary to support renegotiation initiated by the
@@ -375,7 +380,7 @@ void WebrtcTransport::OnRenegotiationNeeded() {
}
void WebrtcTransport::RequestNegotiation() {
- DCHECK(role_ == TransportRole::SERVER);
+ DCHECK(transport_context_->role() == TransportRole::SERVER);
if (!negotiation_pending_) {
negotiation_pending_ = true;
@@ -440,7 +445,7 @@ void WebrtcTransport::EnsurePendingTransportInfoMessage() {
}
void WebrtcTransport::SendOffer() {
- DCHECK(role_ == TransportRole::SERVER);
+ DCHECK(transport_context_->role() == TransportRole::SERVER);
DCHECK(negotiation_pending_);
negotiation_pending_ = false;
@@ -488,19 +493,15 @@ void WebrtcTransport::AddPendingCandidatesIfPossible() {
WebrtcTransportFactory::WebrtcTransportFactory(
rtc::Thread* worker_thread,
- SignalStrategy* signal_strategy,
- scoped_ptr<PortAllocatorFactory> port_allocator_factory,
- TransportRole role)
+ scoped_refptr<TransportContext> transport_context)
: worker_thread_(worker_thread),
- signal_strategy_(signal_strategy),
- port_allocator_factory_(std::move(port_allocator_factory)),
- role_(role) {}
+ transport_context_(transport_context) {}
WebrtcTransportFactory::~WebrtcTransportFactory() {}
scoped_ptr<Transport> WebrtcTransportFactory::CreateTransport() {
- return make_scoped_ptr(new WebrtcTransport(
- worker_thread_, port_allocator_factory_.get(), role_));
+ return make_scoped_ptr(
+ new WebrtcTransport(worker_thread_, transport_context_.get()));
}
} // namespace protocol
diff --git a/remoting/protocol/webrtc_transport.h b/remoting/protocol/webrtc_transport.h
index 6fc79d7..827d2ef 100644
--- a/remoting/protocol/webrtc_transport.h
+++ b/remoting/protocol/webrtc_transport.h
@@ -25,12 +25,13 @@ class FakeAudioDeviceModule;
namespace remoting {
namespace protocol {
+class TransportContext;
+
class WebrtcTransport : public Transport,
public webrtc::PeerConnectionObserver {
public:
WebrtcTransport(rtc::Thread* worker_thread,
- PortAllocatorFactory* port_allocator_factory,
- TransportRole role);
+ scoped_refptr<TransportContext> transport_context);
~WebrtcTransport() override;
webrtc::PeerConnectionInterface* peer_connection() {
@@ -49,6 +50,9 @@ class WebrtcTransport : public Transport,
WebrtcTransport* AsWebrtcTransport() override;
private:
+ void OnPortAllocatorCreated(
+ scoped_ptr<cricket::PortAllocator> port_allocator);
+
void OnLocalSessionDescriptionCreated(
scoped_ptr<webrtc::SessionDescriptionInterface> description,
const std::string& error);
@@ -80,8 +84,7 @@ class WebrtcTransport : public Transport,
base::ThreadChecker thread_checker_;
- PortAllocatorFactory* port_allocator_factory_;
- TransportRole role_;
+ scoped_refptr<TransportContext> transport_context_;
EventHandler* event_handler_ = nullptr;
rtc::Thread* worker_thread_;
@@ -110,11 +113,8 @@ class WebrtcTransport : public Transport,
class WebrtcTransportFactory : public TransportFactory {
public:
- WebrtcTransportFactory(
- rtc::Thread* worker_thread,
- SignalStrategy* signal_strategy,
- scoped_ptr<PortAllocatorFactory> port_allocator_factory,
- TransportRole role);
+ WebrtcTransportFactory(rtc::Thread* worker_thread,
+ scoped_refptr<TransportContext> transport_context);
~WebrtcTransportFactory() override;
// TransportFactory interface.
@@ -122,9 +122,7 @@ class WebrtcTransportFactory : public TransportFactory {
private:
rtc::Thread* worker_thread_;
- SignalStrategy* signal_strategy_;
- scoped_ptr<PortAllocatorFactory> port_allocator_factory_;
- TransportRole role_;
+ scoped_refptr<TransportContext> transport_context_;
DISALLOW_COPY_AND_ASSIGN(WebrtcTransportFactory);
};
diff --git a/remoting/protocol/webrtc_transport_unittest.cc b/remoting/protocol/webrtc_transport_unittest.cc
index 1797a7e..82fb6d3 100644
--- a/remoting/protocol/webrtc_transport_unittest.cc
+++ b/remoting/protocol/webrtc_transport_unittest.cc
@@ -9,11 +9,12 @@
#include "jingle/glue/thread_wrapper.h"
#include "net/base/io_buffer.h"
#include "net/url_request/url_request_context_getter.h"
-#include "remoting/protocol/chromium_port_allocator_factory.h"
+#include "remoting/protocol/chromium_port_allocator.h"
#include "remoting/protocol/connection_tester.h"
#include "remoting/protocol/fake_authenticator.h"
#include "remoting/protocol/network_settings.h"
#include "remoting/protocol/p2p_stream_socket.h"
+#include "remoting/protocol/transport_context.h"
#include "remoting/signaling/fake_signal_strategy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
@@ -90,17 +91,21 @@ class WebrtcTransportTest : public testing::Test {
signal_strategy_.reset(new FakeSignalStrategy(kTestJid));
host_transport_factory_.reset(new WebrtcTransportFactory(
- jingle_glue::JingleThreadWrapper::current(), signal_strategy_.get(),
- ChromiumPortAllocatorFactory::Create(network_settings_, nullptr),
- TransportRole::SERVER));
+ jingle_glue::JingleThreadWrapper::current(),
+ new TransportContext(
+ signal_strategy_.get(),
+ make_scoped_ptr(new ChromiumPortAllocatorFactory(nullptr)),
+ network_settings_, TransportRole::SERVER)));
host_transport_ = host_transport_factory_->CreateTransport();
host_authenticator_.reset(new FakeAuthenticator(
FakeAuthenticator::HOST, 0, FakeAuthenticator::ACCEPT, false));
client_transport_factory_.reset(new WebrtcTransportFactory(
- jingle_glue::JingleThreadWrapper::current(), signal_strategy_.get(),
- ChromiumPortAllocatorFactory::Create(network_settings_, nullptr),
- TransportRole::CLIENT));
+ jingle_glue::JingleThreadWrapper::current(),
+ new TransportContext(
+ signal_strategy_.get(),
+ make_scoped_ptr(new ChromiumPortAllocatorFactory(nullptr)),
+ network_settings_, TransportRole::CLIENT)));
client_transport_ = client_transport_factory_->CreateTransport();
host_authenticator_.reset(new FakeAuthenticator(
FakeAuthenticator::CLIENT, 0, FakeAuthenticator::ACCEPT, false));