diff options
Diffstat (limited to 'content/renderer/p2p')
-rw-r--r-- | content/renderer/p2p/port_allocator.cc | 152 | ||||
-rw-r--r-- | content/renderer/p2p/port_allocator.h | 44 |
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); }; |