summaryrefslogtreecommitdiffstats
path: root/content/renderer/p2p
diff options
context:
space:
mode:
Diffstat (limited to 'content/renderer/p2p')
-rw-r--r--content/renderer/p2p/port_allocator.cc152
-rw-r--r--content/renderer/p2p/port_allocator.h44
2 files changed, 128 insertions, 68 deletions
diff --git a/content/renderer/p2p/port_allocator.cc b/content/renderer/p2p/port_allocator.cc
index 1f921e4..3e71ee7 100644
--- a/content/renderer/p2p/port_allocator.cc
+++ b/content/renderer/p2p/port_allocator.cc
@@ -54,7 +54,6 @@ bool ParsePortNumber(
P2PPortAllocator::Config::Config()
: stun_server_port(0),
- relay_server_port(0),
legacy_relay(true),
disable_tcp_transport(false) {
}
@@ -62,6 +61,13 @@ P2PPortAllocator::Config::Config()
P2PPortAllocator::Config::~Config() {
}
+P2PPortAllocator::Config::RelayServerConfig::RelayServerConfig()
+ : port(0) {
+}
+
+P2PPortAllocator::Config::RelayServerConfig::~RelayServerConfig() {
+}
+
P2PPortAllocator::P2PPortAllocator(
WebKit::WebFrame* web_frame,
P2PSocketDispatcher* socket_dispatcher,
@@ -96,6 +102,12 @@ cricket::PortAllocatorSession* P2PPortAllocator::CreateSessionInternal(
this, content_name, component, ice_username_fragment, ice_password);
}
+P2PPortAllocatorSession::RelayServer::RelayServer() {
+}
+
+P2PPortAllocatorSession::RelayServer::~RelayServer() {
+}
+
P2PPortAllocatorSession::P2PPortAllocatorSession(
P2PPortAllocator* allocator,
const std::string& content_name,
@@ -109,12 +121,18 @@ P2PPortAllocatorSession::P2PPortAllocatorSession(
relay_session_attempts_(0),
relay_udp_port_(0),
relay_tcp_port_(0),
- relay_ssltcp_port_(0) {
+ relay_ssltcp_port_(0),
+ pending_relay_requests_(0) {
}
P2PPortAllocatorSession::~P2PPortAllocatorSession() {
if (stun_address_request_.get())
stun_address_request_->Cancel();
+
+ for (size_t i = 0; i < relay_info_.size(); ++i) {
+ if (relay_info_[i].relay_address_request.get())
+ relay_info_[i].relay_address_request->Cancel();
+ }
}
void P2PPortAllocatorSession::didReceiveData(
@@ -147,6 +165,7 @@ void P2PPortAllocatorSession::didFail(WebKit::WebURLLoader* loader,
}
void P2PPortAllocatorSession::GetPortConfigurations() {
+ // Resolve Stun and Relay server addresses.
if (!allocator_->config_.stun_server.empty() &&
stun_server_address_.IsNil()) {
ResolveStunServerAddress();
@@ -156,6 +175,8 @@ void P2PPortAllocatorSession::GetPortConfigurations() {
if (allocator_->config_.legacy_relay) {
AllocateLegacyRelaySession();
+ } else {
+ ResolveRelayServerAddresses();
}
}
@@ -185,13 +206,62 @@ void P2PPortAllocatorSession::OnStunServerAddress(
&stun_server_address_)) {
return;
}
-
AddConfig();
}
+void P2PPortAllocatorSession::ResolveRelayServerAddresses() {
+ for (size_t i = 0; i < allocator_->config_.relays.size(); ++i) {
+ scoped_refptr<P2PHostAddressRequest> relay_request =
+ new P2PHostAddressRequest(allocator_->socket_dispatcher_);
+ relay_request->Request(
+ allocator_->config_.relays[i].server_address,
+ base::Bind(&P2PPortAllocatorSession::OnRelayServerAddressResolved,
+ base::Unretained(this), i));
+ // Copy relay configuration from alloctor and keeping it in a map.
+ RelayServer relay;
+ relay.config = allocator_->config_.relays[i];
+ relay.relay_address_request = relay_request;
+ relay_info_.push_back(relay);
+ ++pending_relay_requests_;
+ }
+}
+
+void P2PPortAllocatorSession::OnRelayServerAddressResolved(
+ size_t index, const net::IPAddressNumber& address) {
+ // Let's first decrement the pending requests count.
+ --pending_relay_requests_;
+ if (index > relay_info_.size()) {
+ NOTREACHED();
+ return;
+ }
+
+ if (address.empty()) {
+ LOG(ERROR) << "Failed to resolve Relay server address "
+ << relay_info_.at(index).config.server_address;
+ } else {
+ // Getting relay server info for which this resolved address belongs.
+ RelayServer& relay_server = relay_info_.at(index);
+
+ talk_base::SocketAddress socket_address;
+ if (!jingle_glue::IPEndPointToSocketAddress(
+ net::IPEndPoint(address, relay_server.config.port),
+ &socket_address)) {
+ NOTREACHED();
+ }
+ relay_server.resolved_relay_address = socket_address;
+ }
+
+ if (!pending_relay_requests_)
+ AddConfig();
+}
+
void P2PPortAllocatorSession::AllocateLegacyRelaySession() {
- if (allocator_->config_.relay_server.empty())
+ if (allocator_->config_.relays.empty())
return;
+ // If we are using legacy relay, we will have only one entry in relay server
+ // list.
+ P2PPortAllocator::Config::RelayServerConfig relay_config =
+ allocator_->config_.relays[0];
if (relay_session_attempts_ > kRelaySessionRetries)
return;
@@ -212,7 +282,7 @@ void P2PPortAllocatorSession::AllocateLegacyRelaySession() {
return;
}
- std::string url = "https://" + allocator_->config_.relay_server +
+ std::string url = "https://" + relay_config.server_address +
kCreateRelaySessionURL +
"?username=" + net::EscapeUrlEncodedData(username(), true) +
"&password=" + net::EscapeUrlEncodedData(password(), true);
@@ -225,10 +295,10 @@ void P2PPortAllocatorSession::AllocateLegacyRelaySession() {
request.setHTTPMethod("GET");
request.addHTTPHeaderField(
WebString::fromUTF8("X-Talk-Google-Relay-Auth"),
- WebString::fromUTF8(allocator_->config_.relay_password));
+ WebString::fromUTF8(relay_config.password));
request.addHTTPHeaderField(
WebString::fromUTF8("X-Google-Relay-Auth"),
- WebString::fromUTF8(allocator_->config_.relay_password));
+ WebString::fromUTF8(relay_config.username));
request.addHTTPHeaderField(WebString::fromUTF8("X-Stream-Type"),
WebString::fromUTF8("chromoting"));
@@ -290,63 +360,37 @@ void P2PPortAllocatorSession::ParseRelayResponse() {
}
void P2PPortAllocatorSession::AddConfig() {
- cricket::PortConfiguration* config = new cricket::PortConfiguration(
+ cricket::PortConfiguration* port_config = new cricket::PortConfiguration(
stun_server_address_, std::string(), std::string());
- if (allocator_->config_.legacy_relay) {
- // Passing empty credentials for legacy google relay.
- cricket::RelayServerConfig gturn_config(cricket::RELAY_GTURN);
- if (relay_ip_.ip() != 0) {
- if (relay_udp_port_ > 0) {
- talk_base::SocketAddress address(relay_ip_.ip(), relay_udp_port_);
- gturn_config.ports.push_back(cricket::ProtocolAddress(
- address, cricket::PROTO_UDP));
- }
- if (relay_tcp_port_ > 0 && !allocator_->config_.disable_tcp_transport) {
- talk_base::SocketAddress address(relay_ip_.ip(), relay_tcp_port_);
- gturn_config.ports.push_back(cricket::ProtocolAddress(
- address, cricket::PROTO_TCP));
- }
- if (relay_ssltcp_port_ > 0 &&
- !allocator_->config_.disable_tcp_transport) {
- talk_base::SocketAddress address(relay_ip_.ip(), relay_ssltcp_port_);
- gturn_config.ports.push_back(cricket::ProtocolAddress(
- address, cricket::PROTO_SSLTCP));
- }
- if (!gturn_config.ports.empty()) {
- config->AddRelay(gturn_config);
- }
- }
- } else {
- if (!(allocator_->config_.relay_username.empty() ||
- allocator_->config_.relay_server.empty())) {
- // Adding TURN related information to config.
- // As per TURN RFC, same turn server should be used for stun as well.
- // Configuration should have same address for both stun and turn.
- DCHECK_EQ(allocator_->config_.stun_server,
- allocator_->config_.relay_server);
- cricket::RelayServerConfig turn_config(cricket::RELAY_TURN);
- cricket::RelayCredentials credentials(
- allocator_->config_.relay_username,
- allocator_->config_.relay_password);
- turn_config.credentials = credentials;
+ if (!pending_relay_requests_) {
+ // Push all resolved addresses and transport port type to allocator.
+ for (size_t i = 0; i < relay_info_.size(); ++i) {
+ if (relay_info_[i].resolved_relay_address.IsNil())
+ continue;
+ RelayServer relay_info = relay_info_[i];
+ cricket::RelayCredentials credentials(relay_info.config.username,
+ relay_info.config.password);
+ cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
cricket::ProtocolType protocol;
- if (cricket::StringToProto(
- allocator_->config_.relay_transport_type.c_str(), &protocol)) {
- turn_config.ports.push_back(cricket::ProtocolAddress(
- stun_server_address_, protocol));
- config->AddRelay(turn_config);
- } else {
+ if (!cricket::StringToProto(relay_info.config.transport_type.c_str(),
+ &protocol)) {
DLOG(WARNING) << "Ignoring TURN server "
- << allocator_->config_.relay_server << ". "
+ << relay_info.config.server_address << ". "
<< "Reason= Incorrect "
- << allocator_->config_.relay_transport_type
+ << relay_info.config.transport_type
<< " transport parameter.";
+ continue;
}
+
+ relay_server.ports.push_back(cricket::ProtocolAddress(
+ relay_info.resolved_relay_address, protocol));
+ relay_server.credentials = credentials;
+ port_config->AddRelay(relay_server);
}
}
- ConfigReady(config);
+ ConfigReady(port_config);
}
} // namespace content
diff --git a/content/renderer/p2p/port_allocator.h b/content/renderer/p2p/port_allocator.h
index 84537ac..9e4f764 100644
--- a/content/renderer/p2p/port_allocator.h
+++ b/content/renderer/p2p/port_allocator.h
@@ -31,26 +31,24 @@ class P2PPortAllocator : public cricket::BasicPortAllocator {
Config();
~Config();
+ struct RelayServerConfig {
+ RelayServerConfig();
+ ~RelayServerConfig();
+
+ std::string username;
+ std::string password;
+ std::string server_address;
+ int port;
+ std::string transport_type;
+ };
+
// STUN server address and port.
std::string stun_server;
int stun_server_port;
- // Relay server address and port.
- std::string relay_server;
- int relay_server_port;
-
- // Relay server username.
- std::string relay_username;
+ std::vector<RelayServerConfig> relays;
- // Relay server password.
- std::string relay_password;
-
- // Transport protocol used to communicate with the server.
- std::string relay_transport_type;
-
- // When set to true relay is a legacy Google relay (not TURN compliant).
bool legacy_relay;
-
// Disable TCP-based transport when set to true.
bool disable_tcp_transport;
};
@@ -104,9 +102,24 @@ class P2PPortAllocatorSession : public cricket::BasicPortAllocatorSession,
virtual void GetPortConfigurations() OVERRIDE;
private:
+
+ struct RelayServer {
+ RelayServer();
+ ~RelayServer();
+
+ P2PPortAllocator::Config::RelayServerConfig config;
+ talk_base::SocketAddress resolved_relay_address;
+ scoped_refptr<P2PHostAddressRequest> relay_address_request;
+ };
+
void ResolveStunServerAddress();
void OnStunServerAddress(const net::IPAddressNumber& address);
+ void ResolveRelayServerAddresses();
+ void OnRelayServerAddressResolved(size_t index,
+ const net::IPAddressNumber& address);
+ bool IsRelayAddressesResolved() const;
+
// This method allocates non-TURN relay sessions.
void AllocateLegacyRelaySession();
void ParseRelayResponse();
@@ -118,6 +131,8 @@ class P2PPortAllocatorSession : public cricket::BasicPortAllocatorSession,
scoped_refptr<P2PHostAddressRequest> stun_address_request_;
talk_base::SocketAddress stun_server_address_;
+ std::vector<RelayServer> relay_info_;
+
scoped_ptr<WebKit::WebURLLoader> relay_session_request_;
int relay_session_attempts_;
std::string relay_session_response_;
@@ -125,6 +140,7 @@ class P2PPortAllocatorSession : public cricket::BasicPortAllocatorSession,
int relay_udp_port_;
int relay_tcp_port_;
int relay_ssltcp_port_;
+ int pending_relay_requests_;
DISALLOW_COPY_AND_ASSIGN(P2PPortAllocatorSession);
};