Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(592)

Unified Diff: remoting/protocol/libjingle_transport_factory.cc

Issue 98173006: Fix LibjingleTransportFactory to refresh STUN/Relay. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « remoting/protocol/libjingle_transport_factory.h ('k') | remoting/protocol/session_manager.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/protocol/libjingle_transport_factory.cc
diff --git a/remoting/protocol/libjingle_transport_factory.cc b/remoting/protocol/libjingle_transport_factory.cc
index 76c3507aaa6d55b6e107ce364e0618a9ec33ebd2..ef22f2a95f380a950171448b590edd010894b21e 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
« no previous file with comments | « remoting/protocol/libjingle_transport_factory.h ('k') | remoting/protocol/session_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698