summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--remoting/client/jni/chromoting_jni_instance.cc4
-rw-r--r--remoting/client/plugin/chromoting_instance.cc4
-rw-r--r--remoting/host/it2me/it2me_host.cc2
-rw-r--r--remoting/host/remoting_me2me_host.cc2
-rw-r--r--remoting/host/session_manager_factory.cc15
-rw-r--r--remoting/host/session_manager_factory.h4
-rw-r--r--remoting/jingle_glue/jingle_info_request.cc30
-rw-r--r--remoting/jingle_glue/jingle_info_request.h18
-rw-r--r--remoting/protocol/connection_to_host.cc3
-rw-r--r--remoting/protocol/jingle_session_manager.cc51
-rw-r--r--remoting/protocol/jingle_session_manager.h13
-rw-r--r--remoting/protocol/jingle_session_unittest.cc12
-rw-r--r--remoting/protocol/libjingle_transport_factory.cc143
-rw-r--r--remoting/protocol/libjingle_transport_factory.h35
-rw-r--r--remoting/protocol/session_manager.h1
-rw-r--r--remoting/protocol/transport.h8
-rw-r--r--remoting/protocol/transport_config.cc17
-rw-r--r--remoting/protocol/transport_config.h25
-rw-r--r--remoting/remoting.gyp2
19 files changed, 210 insertions, 179 deletions
diff --git a/remoting/client/jni/chromoting_jni_instance.cc b/remoting/client/jni/chromoting_jni_instance.cc
index 339cea8..641fcd8 100644
--- a/remoting/client/jni/chromoting_jni_instance.cc
+++ b/remoting/client/jni/chromoting_jni_instance.cc
@@ -309,7 +309,9 @@ void ChromotingJniInstance::ConnectToHostOnNetworkThread() {
scoped_ptr<protocol::TransportFactory> transport_factory(
new protocol::LibjingleTransportFactory(
- port_allocator.PassAs<cricket::HttpPortAllocatorBase>(), false));
+ signaling_.get(),
+ port_allocator.PassAs<cricket::HttpPortAllocatorBase>(),
+ network_settings));
client_->Start(signaling_.get(), transport_factory.Pass());
}
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index ba69267..46e30f5 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -658,7 +658,9 @@ void ChromotingInstance::ConnectWithConfig(const ClientConfig& config,
scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator(
PepperPortAllocator::Create(this));
scoped_ptr<protocol::TransportFactory> transport_factory(
- new protocol::LibjingleTransportFactory(port_allocator.Pass(), false));
+ new protocol::LibjingleTransportFactory(
+ signal_strategy_.get(), port_allocator.Pass(),
+ NetworkSettings(NetworkSettings::NAT_TRAVERSAL_ENABLED)));
// Kick off the connection.
client_->Start(signal_strategy_.get(), transport_factory.Pass());
diff --git a/remoting/host/it2me/it2me_host.cc b/remoting/host/it2me/it2me_host.cc
index 9aa88fe..fec201f 100644
--- a/remoting/host/it2me/it2me_host.cc
+++ b/remoting/host/it2me/it2me_host.cc
@@ -195,7 +195,7 @@ void It2MeHost::FinishConnect() {
host_.reset(new ChromotingHost(
signal_strategy_.get(),
desktop_environment_factory_.get(),
- CreateHostSessionManager(network_settings,
+ CreateHostSessionManager(signal_strategy_.get(), network_settings,
host_context_->url_request_context_getter()),
host_context_->audio_task_runner(),
host_context_->input_task_runner(),
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index bc7e8a7..7a0faba 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -998,7 +998,7 @@ void HostProcess::StartHost() {
host_.reset(new ChromotingHost(
signal_strategy_.get(),
desktop_environment_factory_.get(),
- CreateHostSessionManager(network_settings,
+ CreateHostSessionManager(signal_strategy_.get(), network_settings,
context_->url_request_context_getter()),
context_->audio_task_runner(),
context_->input_task_runner(),
diff --git a/remoting/host/session_manager_factory.cc b/remoting/host/session_manager_factory.cc
index cd5befc..a055df2 100644
--- a/remoting/host/session_manager_factory.cc
+++ b/remoting/host/session_manager_factory.cc
@@ -14,6 +14,7 @@
namespace remoting {
scoped_ptr<protocol::SessionManager> CreateHostSessionManager(
+ SignalStrategy* signal_strategy,
const NetworkSettings& network_settings,
const scoped_refptr<net::URLRequestContextGetter>&
url_request_context_getter) {
@@ -22,22 +23,14 @@ scoped_ptr<protocol::SessionManager> CreateHostSessionManager(
ChromiumPortAllocator::Create(url_request_context_getter,
network_settings));
- bool incoming_only = network_settings.nat_traversal_mode ==
- NetworkSettings::NAT_TRAVERSAL_DISABLED;
-
scoped_ptr<protocol::TransportFactory> transport_factory(
new protocol::LibjingleTransportFactory(
+ signal_strategy,
port_allocator.PassAs<cricket::HttpPortAllocatorBase>(),
- incoming_only));
-
- // Use the Jingle protocol for channel-negotiation signalling between
- // peer TransportFactories.
- bool fetch_stun_relay_info = network_settings.nat_traversal_mode ==
- NetworkSettings::NAT_TRAVERSAL_ENABLED;
+ network_settings));
scoped_ptr<protocol::JingleSessionManager> session_manager(
- new protocol::JingleSessionManager(
- transport_factory.Pass(), fetch_stun_relay_info));
+ new protocol::JingleSessionManager(transport_factory.Pass()));
return session_manager.PassAs<protocol::SessionManager>();
}
diff --git a/remoting/host/session_manager_factory.h b/remoting/host/session_manager_factory.h
index 2c0a1b6..ce2a53d 100644
--- a/remoting/host/session_manager_factory.h
+++ b/remoting/host/session_manager_factory.h
@@ -15,12 +15,14 @@ class URLRequestContextGetter;
namespace remoting {
struct NetworkSettings;
+class SignalStrategy;
namespace protocol {
- class SessionManager;
+class SessionManager;
} // namespace protocol
scoped_ptr<protocol::SessionManager> CreateHostSessionManager(
+ SignalStrategy* signal_strategy,
const NetworkSettings& network_settings,
const scoped_refptr<net::URLRequestContextGetter>&
url_request_context_getter);
diff --git a/remoting/jingle_glue/jingle_info_request.cc b/remoting/jingle_glue/jingle_info_request.cc
index e75b89f..d41f18a 100644
--- a/remoting/jingle_glue/jingle_info_request.cc
+++ b/remoting/jingle_glue/jingle_info_request.cc
@@ -8,6 +8,7 @@
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
#include "net/base/net_util.h"
#include "remoting/jingle_glue/iq_sender.h"
#include "third_party/libjingle/source/talk/base/socketaddress.h"
@@ -16,12 +17,13 @@
namespace remoting {
+const int kRequestTimeoutSeconds = 5;
+
JingleInfoRequest::JingleInfoRequest(SignalStrategy* signal_strategy)
: iq_sender_(signal_strategy) {
}
-JingleInfoRequest::~JingleInfoRequest() {
-}
+JingleInfoRequest::~JingleInfoRequest() {}
void JingleInfoRequest::Send(const OnJingleInfoCallback& callback) {
on_jingle_info_cb_ = callback;
@@ -30,19 +32,39 @@ void JingleInfoRequest::Send(const OnJingleInfoCallback& callback) {
request_ = iq_sender_.SendIq(
buzz::STR_GET, buzz::STR_EMPTY, iq_body.Pass(),
base::Bind(&JingleInfoRequest::OnResponse, base::Unretained(this)));
+ if (!request_) {
+ // If we failed to send IqRequest it means that SignalStrategy is
+ // disconnected. Notify the caller.
+ std::vector<talk_base::SocketAddress> stun_hosts;
+ std::vector<std::string> relay_hosts;
+ std::string relay_token;
+ on_jingle_info_cb_.Run(relay_token, relay_hosts, stun_hosts);
+ return;
+ }
+ request_->SetTimeout(base::TimeDelta::FromSeconds(kRequestTimeoutSeconds));
}
void JingleInfoRequest::OnResponse(IqRequest* request,
const buzz::XmlElement* stanza) {
+ std::vector<talk_base::SocketAddress> stun_hosts;
+ std::vector<std::string> relay_hosts;
+ std::string relay_token;
+
+ if (!stanza) {
+ LOG(WARNING) << "Jingle info request has timed out.";
+ on_jingle_info_cb_.Run(relay_token, relay_hosts, stun_hosts);
+ return;
+ }
+
const buzz::XmlElement* query =
stanza->FirstNamed(buzz::QN_JINGLE_INFO_QUERY);
if (query == NULL) {
LOG(WARNING) << "No Jingle info found in Jingle Info query response."
<< stanza->Str();
+ on_jingle_info_cb_.Run(relay_token, relay_hosts, stun_hosts);
return;
}
- std::vector<talk_base::SocketAddress> stun_hosts;
const buzz::XmlElement* stun = query->FirstNamed(buzz::QN_JINGLE_INFO_STUN);
if (stun) {
for (const buzz::XmlElement* server =
@@ -63,8 +85,6 @@ void JingleInfoRequest::OnResponse(IqRequest* request,
}
}
- std::vector<std::string> relay_hosts;
- std::string relay_token;
const buzz::XmlElement* relay = query->FirstNamed(buzz::QN_JINGLE_INFO_RELAY);
if (relay) {
relay_token = relay->TextNamed(buzz::QN_JINGLE_INFO_TOKEN);
diff --git a/remoting/jingle_glue/jingle_info_request.h b/remoting/jingle_glue/jingle_info_request.h
index a1b10de..118aa4a 100644
--- a/remoting/jingle_glue/jingle_info_request.h
+++ b/remoting/jingle_glue/jingle_info_request.h
@@ -13,7 +13,6 @@
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "remoting/jingle_glue/iq_sender.h"
-#include "third_party/libjingle/source/talk/base/sigslot.h"
namespace buzz {
class XmlElement;
@@ -34,17 +33,14 @@ class SignalStrategy;
//
// This class is not threadsafe and should be used on the same thread it is
// created on.
-//
-// TODO(ajwong): Add support for a timeout.
-class JingleInfoRequest : public sigslot::has_slots<> {
+class JingleInfoRequest {
public:
- // Callback to receive the Jingle configuration settings. The arguments are
- // passed by pointer so the receive may call swap on them. The receiver does
- // NOT own the arguments, which are guaranteed only to be alive for the
- // duration of the callback.
- typedef base::Callback<void (
- const std::string&, const std::vector<std::string>&,
- const std::vector<talk_base::SocketAddress>&)> OnJingleInfoCallback;
+ // Callback to receive the Jingle configuration settings. All fields are empty
+ // if the request has timed out.
+ typedef base::Callback<void(const std::string& relay_token,
+ const std::vector<std::string>& relay_servers,
+ const std::vector<talk_base::SocketAddress>&
+ stun_servers)> OnJingleInfoCallback;
explicit JingleInfoRequest(SignalStrategy* signal_strategy);
virtual ~JingleInfoRequest();
diff --git a/remoting/protocol/connection_to_host.cc b/remoting/protocol/connection_to_host.cc
index bcd77e5..e35ba22 100644
--- a/remoting/protocol/connection_to_host.cc
+++ b/remoting/protocol/connection_to_host.cc
@@ -92,8 +92,7 @@ void ConnectionToHost::Connect(SignalStrategy* signal_strategy,
signal_strategy_->AddListener(this);
signal_strategy_->Connect();
- session_manager_.reset(new JingleSessionManager(
- transport_factory.Pass(), allow_nat_traversal_));
+ session_manager_.reset(new JingleSessionManager(transport_factory.Pass()));
session_manager_->Init(signal_strategy_, this);
SetState(CONNECTING, OK);
diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc
index 7cb1586..58bcd4d 100644
--- a/remoting/protocol/jingle_session_manager.cc
+++ b/remoting/protocol/jingle_session_manager.cc
@@ -6,14 +6,12 @@
#include "base/bind.h"
#include "remoting/jingle_glue/iq_sender.h"
-#include "remoting/jingle_glue/jingle_info_request.h"
#include "remoting/jingle_glue/signal_strategy.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/content_description.h"
#include "remoting/protocol/jingle_messages.h"
#include "remoting/protocol/jingle_session.h"
#include "remoting/protocol/transport.h"
-#include "remoting/protocol/transport_config.h"
#include "third_party/libjingle/source/talk/base/socketaddress.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
@@ -23,10 +21,8 @@ namespace remoting {
namespace protocol {
JingleSessionManager::JingleSessionManager(
- scoped_ptr<TransportFactory> transport_factory,
- bool fetch_stun_relay_config)
+ scoped_ptr<TransportFactory> transport_factory)
: transport_factory_(transport_factory.Pass()),
- fetch_stun_relay_config_(fetch_stun_relay_config),
signal_strategy_(NULL),
listener_(NULL),
ready_(false) {
@@ -48,35 +44,13 @@ void JingleSessionManager::Init(
OnSignalStrategyStateChange(signal_strategy_->GetState());
}
-void JingleSessionManager::OnJingleInfo(
- const std::string& relay_token,
- const std::vector<std::string>& relay_hosts,
- const std::vector<talk_base::SocketAddress>& stun_hosts) {
- DCHECK(CalledOnValidThread());
-
- // TODO(sergeyu): Add support for multiple STUN/relay servers when
- // it's implemented in libjingle and P2P Transport API.
- TransportConfig config;
- config.stun_server = stun_hosts[0].ToString();
- config.relay_server = relay_hosts[0];
- config.relay_token = relay_token;
- transport_factory_->SetTransportConfig(config);
-
- VLOG(1) << "STUN server: " << config.stun_server
- << " Relay server: " << config.relay_server
- << " Relay token: " << config.relay_token;
-
-
- if (!ready_) {
- ready_ = true;
- listener_->OnSessionManagerReady();
- }
-}
-
scoped_ptr<Session> JingleSessionManager::Connect(
const std::string& host_jid,
scoped_ptr<Authenticator> authenticator,
scoped_ptr<CandidateSessionConfig> config) {
+ // Notify |transport_factory_| that it may be used soon.
+ transport_factory_->PrepareTokens();
+
scoped_ptr<JingleSession> session(new JingleSession(this));
session->StartConnection(host_jid, authenticator.Pass(), config.Pass());
sessions_[session->session_id_] = session.get();
@@ -90,7 +64,6 @@ void JingleSessionManager::Close() {
DCHECK(sessions_.empty());
listener_ = NULL;
- jingle_info_request_.reset();
if (signal_strategy_) {
signal_strategy_->RemoveListener(this);
@@ -106,16 +79,9 @@ void JingleSessionManager::set_authenticator_factory(
void JingleSessionManager::OnSignalStrategyStateChange(
SignalStrategy::State state) {
- if (state == SignalStrategy::CONNECTED) {
- // Request STUN/Relay info if necessary.
- if (fetch_stun_relay_config_) {
- jingle_info_request_.reset(new JingleInfoRequest(signal_strategy_));
- jingle_info_request_->Send(base::Bind(&JingleSessionManager::OnJingleInfo,
- base::Unretained(this)));
- } else if (!ready_) {
- ready_ = true;
- listener_->OnSessionManagerReady();
- }
+ if (state == SignalStrategy::CONNECTED && !ready_) {
+ ready_ = true;
+ listener_->OnSessionManagerReady();
}
}
@@ -137,6 +103,9 @@ bool JingleSessionManager::OnSignalStrategyIncomingStanza(
SendReply(stanza, JingleMessageReply::NONE);
+ // Notify |transport_factory_| that it may be used soon.
+ transport_factory_->PrepareTokens();
+
scoped_ptr<Authenticator> authenticator =
authenticator_factory_->CreateAuthenticator(
signal_strategy_->GetLocalJid(), message.from,
diff --git a/remoting/protocol/jingle_session_manager.h b/remoting/protocol/jingle_session_manager.h
index 7130f3f..e808ad2 100644
--- a/remoting/protocol/jingle_session_manager.h
+++ b/remoting/protocol/jingle_session_manager.h
@@ -30,7 +30,6 @@ class SocketAddress;
namespace remoting {
class IqSender;
-class JingleInfoRequest;
namespace protocol {
@@ -44,15 +43,7 @@ class TransportFactory;
class JingleSessionManager : public SessionManager,
public SignalStrategy::Listener {
public:
- // When |fetch_stun_relay_config| is set to true then
- // JingleSessionManager will also try to query configuration of STUN
- // and Relay servers from the signaling server.
- //
- // TODO(sergeyu): Move NAT-traversal config fetching to a separate
- // class.
- explicit JingleSessionManager(
- scoped_ptr<TransportFactory> transport_factory,
- bool fetch_stun_relay_config);
+ explicit JingleSessionManager(scoped_ptr<TransportFactory> transport_factory);
virtual ~JingleSessionManager();
// SessionManager interface.
@@ -99,8 +90,6 @@ class JingleSessionManager : public SessionManager,
bool ready_;
- scoped_ptr<JingleInfoRequest> jingle_info_request_;
-
SessionsMap sessions_;
DISALLOW_COPY_AND_ASSIGN(JingleSessionManager);
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc
index 34e09d6..62e4d40 100644
--- a/remoting/protocol/jingle_session_unittest.cc
+++ b/remoting/protocol/jingle_session_unittest.cc
@@ -141,13 +141,14 @@ class JingleSessionTest : public testing::Test {
EXPECT_CALL(host_server_listener_, OnSessionManagerReady())
.Times(1);
- NetworkSettings network_settings;
+ NetworkSettings network_settings(NetworkSettings::NAT_TRAVERSAL_OUTGOING);
scoped_ptr<TransportFactory> host_transport(new LibjingleTransportFactory(
+ NULL,
ChromiumPortAllocator::Create(NULL, network_settings)
.PassAs<cricket::HttpPortAllocatorBase>(),
- false));
- host_server_.reset(new JingleSessionManager(host_transport.Pass(), false));
+ network_settings));
+ host_server_.reset(new JingleSessionManager(host_transport.Pass()));
host_server_->Init(host_signal_strategy_.get(), &host_server_listener_);
scoped_ptr<AuthenticatorFactory> factory(
@@ -157,11 +158,12 @@ class JingleSessionTest : public testing::Test {
EXPECT_CALL(client_server_listener_, OnSessionManagerReady())
.Times(1);
scoped_ptr<TransportFactory> client_transport(new LibjingleTransportFactory(
+ NULL,
ChromiumPortAllocator::Create(NULL, network_settings)
.PassAs<cricket::HttpPortAllocatorBase>(),
- false));
+ network_settings));
client_server_.reset(
- new JingleSessionManager(client_transport.Pass(), false));
+ new JingleSessionManager(client_transport.Pass()));
client_server_->Init(client_signal_strategy_.get(),
&client_server_listener_);
}
diff --git a/remoting/protocol/libjingle_transport_factory.cc b/remoting/protocol/libjingle_transport_factory.cc
index 76c3507..ef22f2a 100644
--- a/remoting/protocol/libjingle_transport_factory.cc
+++ b/remoting/protocol/libjingle_transport_factory.cc
@@ -4,6 +4,7 @@
#include "remoting/protocol/libjingle_transport_factory.h"
+#include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/timer/timer.h"
@@ -13,9 +14,9 @@
#include "jingle/glue/utils.h"
#include "net/base/net_errors.h"
#include "remoting/base/constants.h"
+#include "remoting/jingle_glue/jingle_info_request.h"
#include "remoting/jingle_glue/network_settings.h"
#include "remoting/protocol/channel_authenticator.h"
-#include "remoting/protocol/transport_config.h"
#include "third_party/libjingle/source/talk/base/network.h"
#include "third_party/libjingle/source/talk/p2p/base/constants.h"
#include "third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.h"
@@ -40,13 +41,21 @@ const int kTcpSendBufferSize = kTcpReceiveBufferSize + 30 * 1024;
const int kMaxReconnectAttempts = 2;
const int kReconnectDelaySeconds = 15;
-class LibjingleStreamTransport : public StreamTransport,
- public sigslot::has_slots<> {
+// Get fresh STUN/Relay configuration every hour.
+const int kJingleInfoUpdatePeriodSeconds = 3600;
+
+class LibjingleStreamTransport
+ : public StreamTransport,
+ public base::SupportsWeakPtr<LibjingleStreamTransport>,
+ public sigslot::has_slots<> {
public:
LibjingleStreamTransport(cricket::PortAllocator* port_allocator,
- bool incoming_only);
+ const NetworkSettings& network_settings);
virtual ~LibjingleStreamTransport();
+ // Called by JingleTransportFactory when it has fresh Jingle info.
+ void OnCanStart();
+
// StreamTransport interface.
virtual void Initialize(
const std::string& name,
@@ -59,6 +68,8 @@ class LibjingleStreamTransport : public StreamTransport,
virtual bool is_connected() const OVERRIDE;
private:
+ void DoStart();
+
// Signal handlers for cricket::TransportChannel.
void OnRequestSignaling(cricket::TransportChannelImpl* channel);
void OnCandidateReady(cricket::TransportChannelImpl* channel,
@@ -86,7 +97,7 @@ class LibjingleStreamTransport : public StreamTransport,
void NotifyConnectFailed();
cricket::PortAllocator* port_allocator_;
- bool incoming_only_;
+ NetworkSettings network_settings_;
std::string name_;
EventHandler* event_handler_;
@@ -95,6 +106,9 @@ class LibjingleStreamTransport : public StreamTransport,
std::string ice_username_fragment_;
std::string ice_password_;
+ bool can_start_;
+
+ std::list<cricket::Candidate> pending_candidates_;
scoped_ptr<cricket::P2PTransportChannel> channel_;
bool channel_was_writable_;
int connect_attempts_left_;
@@ -108,13 +122,14 @@ class LibjingleStreamTransport : public StreamTransport,
LibjingleStreamTransport::LibjingleStreamTransport(
cricket::PortAllocator* port_allocator,
- bool incoming_only)
+ const NetworkSettings& network_settings)
: port_allocator_(port_allocator),
- incoming_only_(incoming_only),
+ network_settings_(network_settings),
event_handler_(NULL),
ice_username_fragment_(
talk_base::CreateRandomString(cricket::ICE_UFRAG_LENGTH)),
ice_password_(talk_base::CreateRandomString(cricket::ICE_PWD_LENGTH)),
+ can_start_(false),
channel_was_writable_(false),
connect_attempts_left_(kMaxReconnectAttempts) {
}
@@ -131,6 +146,22 @@ LibjingleStreamTransport::~LibjingleStreamTransport() {
}
}
+void LibjingleStreamTransport::OnCanStart() {
+ DCHECK(CalledOnValidThread());
+
+ DCHECK(!can_start_);
+ can_start_ = true;
+
+ // If Connect() has been called then start connection.
+ if (!callback_.is_null())
+ DoStart();
+
+ while (!pending_candidates_.empty()) {
+ channel_->OnCandidate(pending_candidates_.front());
+ pending_candidates_.pop_front();
+ }
+}
+
void LibjingleStreamTransport::Initialize(
const std::string& name,
Transport::EventHandler* event_handler,
@@ -151,9 +182,13 @@ void LibjingleStreamTransport::Initialize(
void LibjingleStreamTransport::Connect(
const StreamTransport::ConnectedCallback& callback) {
DCHECK(CalledOnValidThread());
-
callback_ = callback;
+ if (can_start_)
+ DoStart();
+}
+
+void LibjingleStreamTransport::DoStart() {
DCHECK(!channel_.get());
// Create P2PTransportChannel, attach signal handlers and connect it.
@@ -169,7 +204,10 @@ void LibjingleStreamTransport::Connect(
this, &LibjingleStreamTransport::OnRouteChange);
channel_->SignalWritableState.connect(
this, &LibjingleStreamTransport::OnWritableState);
- channel_->set_incoming_only(incoming_only_);
+ if (network_settings_.nat_traversal_mode ==
+ NetworkSettings::NAT_TRAVERSAL_DISABLED) {
+ channel_->set_incoming_only(true);
+ }
channel_->Connect();
@@ -211,7 +249,11 @@ void LibjingleStreamTransport::Connect(
void LibjingleStreamTransport::AddRemoteCandidate(
const cricket::Candidate& candidate) {
DCHECK(CalledOnValidThread());
- channel_->OnCandidate(candidate);
+ if (channel_) {
+ channel_->OnCandidate(candidate);
+ } else {
+ pending_candidates_.push_back(candidate);
+ }
}
const std::string& LibjingleStreamTransport::name() const {
@@ -362,10 +404,12 @@ void LibjingleStreamTransport::NotifyConnectFailed() {
} // namespace
LibjingleTransportFactory::LibjingleTransportFactory(
+ SignalStrategy* signal_strategy,
scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator,
- bool incoming_only)
- : port_allocator_(port_allocator.Pass()),
- incoming_only_(incoming_only) {
+ const NetworkSettings& network_settings)
+ : signal_strategy_(signal_strategy),
+ port_allocator_(port_allocator.Pass()),
+ network_settings_(network_settings) {
jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
}
@@ -377,27 +421,27 @@ LibjingleTransportFactory::~LibjingleTransportFactory() {
task_runner->DeleteSoon(FROM_HERE, port_allocator_.release());
}
-void LibjingleTransportFactory::SetTransportConfig(
- const TransportConfig& config) {
- std::vector<talk_base::SocketAddress> stun_hosts;
- talk_base::SocketAddress stun_address;
- if (stun_address.FromString(config.stun_server)) {
- stun_hosts.push_back(stun_address);
- port_allocator_->SetStunHosts(stun_hosts);
- } else {
- LOG(ERROR) << "Failed to parse stun server address: "
- << config.stun_server;
- }
-
- std::vector<std::string> relay_hosts;
- relay_hosts.push_back(config.relay_server);
- port_allocator_->SetRelayHosts(relay_hosts);
- port_allocator_->SetRelayToken(config.relay_token);
+void LibjingleTransportFactory::PrepareTokens() {
+ EnsureFreshJingleInfo();
}
scoped_ptr<StreamTransport> LibjingleTransportFactory::CreateStreamTransport() {
- return scoped_ptr<StreamTransport>(
- new LibjingleStreamTransport(port_allocator_.get(), incoming_only_));
+ scoped_ptr<LibjingleStreamTransport> result(
+ new LibjingleStreamTransport(port_allocator_.get(), network_settings_));
+
+ 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(
+ base::Bind(&LibjingleStreamTransport::OnCanStart,
+ result->AsWeakPtr()));
+ } else {
+ result->OnCanStart();
+ }
+
+ return result.PassAs<StreamTransport>();
}
scoped_ptr<DatagramTransport>
@@ -406,5 +450,42 @@ LibjingleTransportFactory::CreateDatagramTransport() {
return scoped_ptr<DatagramTransport>();
}
+void LibjingleTransportFactory::EnsureFreshJingleInfo() {
+ if (network_settings_.nat_traversal_mode !=
+ NetworkSettings::NAT_TRAVERSAL_ENABLED ||
+ jingle_info_request_) {
+ return;
+ }
+
+ if (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(
+ &LibjingleTransportFactory::OnJingleInfo, base::Unretained(this)));
+ }
+}
+
+void LibjingleTransportFactory::OnJingleInfo(
+ const std::string& relay_token,
+ const std::vector<std::string>& relay_hosts,
+ const std::vector<talk_base::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/libjingle_transport_factory.h b/remoting/protocol/libjingle_transport_factory.h
index dfa0ab1..637410c 100644
--- a/remoting/protocol/libjingle_transport_factory.h
+++ b/remoting/protocol/libjingle_transport_factory.h
@@ -5,6 +5,10 @@
#ifndef REMOTING_PROTOCOL_LIBJINGLE_TRANSPORT_FACTORY_H_
#define REMOTING_PROTOCOL_LIBJINGLE_TRANSPORT_FACTORY_H_
+#include <list>
+
+#include "base/callback_forward.h"
+#include "remoting/jingle_glue/network_settings.h"
#include "remoting/protocol/transport.h"
namespace cricket {
@@ -19,34 +23,49 @@ class URLRequestContextGetter;
namespace talk_base {
class NetworkManager;
class PacketSocketFactory;
+class SocketAddress;
} // namespace talk_base
namespace remoting {
-struct NetworkSettings;
+class SignalStrategy;
+class JingleInfoRequest;
namespace protocol {
class LibjingleTransportFactory : public TransportFactory {
public:
- // Need to use cricket::HttpPortAllocatorBase pointer for the
- // |port_allocator|, so that it is possible to configure
- // |port_allocator| with STUN/Relay addresses.
- // TODO(sergeyu): Reconsider this design.
+ // |signal_strategy| must outlive LibjingleTransportFactory. Need to use
+ // cricket::HttpPortAllocatorBase pointer for the |port_allocator|, so that it
+ // is possible to configure |port_allocator| with STUN/Relay addresses.
LibjingleTransportFactory(
+ SignalStrategy* signal_strategy,
scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator,
- bool incoming_only);
+ const NetworkSettings& network_settings);
virtual ~LibjingleTransportFactory();
// TransportFactory interface.
- virtual void SetTransportConfig(const TransportConfig& config) OVERRIDE;
+ virtual void PrepareTokens() OVERRIDE;
virtual scoped_ptr<StreamTransport> CreateStreamTransport() OVERRIDE;
virtual scoped_ptr<DatagramTransport> CreateDatagramTransport() OVERRIDE;
private:
+ void EnsureFreshJingleInfo();
+ void OnJingleInfo(const std::string& relay_token,
+ const std::vector<std::string>& relay_hosts,
+ const std::vector<talk_base::SocketAddress>& stun_hosts);
+
+ SignalStrategy* signal_strategy_;
scoped_ptr<cricket::HttpPortAllocatorBase> port_allocator_;
- bool incoming_only_;
+ NetworkSettings network_settings_;
+
+ 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(LibjingleTransportFactory);
};
diff --git a/remoting/protocol/session_manager.h b/remoting/protocol/session_manager.h
index 37b9599..8ac484d 100644
--- a/remoting/protocol/session_manager.h
+++ b/remoting/protocol/session_manager.h
@@ -59,7 +59,6 @@
#include "base/memory/ref_counted.h"
#include "base/threading/non_thread_safe.h"
#include "remoting/protocol/session.h"
-#include "remoting/protocol/transport_config.h"
namespace remoting {
diff --git a/remoting/protocol/transport.h b/remoting/protocol/transport.h
index fe2f4e1..196b9d2 100644
--- a/remoting/protocol/transport.h
+++ b/remoting/protocol/transport.h
@@ -43,7 +43,6 @@ namespace remoting {
namespace protocol {
class ChannelAuthenticator;
-struct TransportConfig;
struct TransportRoute {
enum RouteType {
@@ -151,8 +150,11 @@ class TransportFactory {
TransportFactory() { }
virtual ~TransportFactory() { }
- // Sets configuration for the transports created by this factory.
- virtual void SetTransportConfig(const TransportConfig& config) = 0;
+ // Called to notify transport factory that a new transport might be created
+ // soon, e.g. when a new session is being created. Implementation may use it
+ // to start asynchronous preparation, e.g. fetch a new relay token if
+ // necessary while the session is being authenticated.
+ virtual void PrepareTokens() = 0;
virtual scoped_ptr<StreamTransport> CreateStreamTransport() = 0;
virtual scoped_ptr<DatagramTransport> CreateDatagramTransport() = 0;
diff --git a/remoting/protocol/transport_config.cc b/remoting/protocol/transport_config.cc
deleted file mode 100644
index 093e1b1..0000000
--- a/remoting/protocol/transport_config.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2012 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_config.h"
-
-namespace remoting {
-namespace protocol {
-
-TransportConfig::TransportConfig() {
-}
-
-TransportConfig::~TransportConfig() {
-}
-
-} // namespace protocol
-} // namespace remoting
diff --git a/remoting/protocol/transport_config.h b/remoting/protocol/transport_config.h
deleted file mode 100644
index d996bd5..0000000
--- a/remoting/protocol/transport_config.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2012 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_CONFIG_H_
-#define REMOTING_PROTOCOL_TRANSPORT_CONFIG_H_
-
-#include <string>
-
-namespace remoting {
-namespace protocol {
-
-struct TransportConfig {
- TransportConfig();
- ~TransportConfig();
-
- std::string stun_server;
- std::string relay_server;
- std::string relay_token;
-};
-
-} // namespace protocol
-} // namespace remoting
-
-#endif // REMOTING_PROTOCOL_TRANSPORT_CONFIG_H_
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index c4f6fde..ed93d2b 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -2767,8 +2767,6 @@
'protocol/ssl_hmac_channel_authenticator.h',
'protocol/transport.cc',
'protocol/transport.h',
- 'protocol/transport_config.cc',
- 'protocol/transport_config.h',
'protocol/util.cc',
'protocol/util.h',
'protocol/third_party_authenticator_base.cc',