diff --git a/talk/app/webrtc/portallocatorfactory.cc b/talk/app/webrtc/portallocatorfactory.cc index decd33c7b6..a436c44b24 100644 --- a/talk/app/webrtc/portallocatorfactory.cc +++ b/talk/app/webrtc/portallocatorfactory.cc @@ -77,6 +77,8 @@ cricket::PortAllocator* PortAllocatorFactory::CreatePortAllocator( relay_server.ports.push_back(cricket::ProtocolAddress( turn[i].server, protocol, turn[i].secure)); relay_server.credentials = credentials; + // First in the list gets highest priority. + relay_server.priority = static_cast(turn.size() - i - 1); allocator->AddRelay(relay_server); } else { LOG(LS_WARNING) << "Ignoring TURN server " << turn[i].server << ". " diff --git a/talk/p2p/base/candidate.h b/talk/p2p/base/candidate.h index 547725df83..d6abdb0428 100644 --- a/talk/p2p/base/candidate.h +++ b/talk/p2p/base/candidate.h @@ -166,7 +166,8 @@ class Candidate { } uint32 GetPriority(uint32 type_preference, - int network_adapter_preference) const { + int network_adapter_preference, + int relay_preference) const { // RFC 5245 - 4.1.2.1. // priority = (2^24)*(type preference) + // (2^8)*(local preference) + @@ -181,10 +182,11 @@ class Candidate { // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // NIC Type - Type of the network adapter e.g. 3G/Wifi/Wired. // Addr Pref - Address preference value as per RFC 3484. - // local preference is calculated as - NIC Type << 8 | Addr_Pref. + // local preference = (NIC Type << 8 | Addr_Pref) - relay preference. int addr_pref = IPAddressPrecedence(address_.ipaddr()); - int local_preference = (network_adapter_preference << 8) | addr_pref; + int local_preference = ((network_adapter_preference << 8) | addr_pref) + + relay_preference; return (type_preference << 24) | (local_preference << 8) | diff --git a/talk/p2p/base/p2ptransportchannel.cc b/talk/p2p/base/p2ptransportchannel.cc index 8a3ec7ff70..2e1160f0f9 100644 --- a/talk/p2p/base/p2ptransportchannel.cc +++ b/talk/p2p/base/p2ptransportchannel.cc @@ -494,7 +494,7 @@ void P2PTransportChannel::OnUnknownAddress( talk_base::ToString(talk_base::ComputeCrc32(id))); new_remote_candidate.set_priority( new_remote_candidate.GetPriority(ICE_TYPE_PREFERENCE_SRFLX, - port->Network()->preference())); + port->Network()->preference(), 0)); } if (port->IceProtocol() == ICEPROTO_RFC5245) { diff --git a/talk/p2p/base/port.cc b/talk/p2p/base/port.cc index ad692cec1b..cf0f203e2c 100644 --- a/talk/p2p/base/port.cc +++ b/talk/p2p/base/port.cc @@ -253,13 +253,26 @@ void Port::AddAddress(const talk_base::SocketAddress& address, const std::string& type, uint32 type_preference, bool final) { + AddAddress(address, base_address, related_address, protocol, + type, type_preference, 0, final); +} + +void Port::AddAddress(const talk_base::SocketAddress& address, + const talk_base::SocketAddress& base_address, + const talk_base::SocketAddress& related_address, + const std::string& protocol, + const std::string& type, + uint32 type_preference, + uint32 relay_preference, + bool final) { Candidate c; c.set_id(talk_base::CreateRandomString(8)); c.set_component(component_); c.set_type(type); c.set_protocol(protocol); c.set_address(address); - c.set_priority(c.GetPriority(type_preference, network_->preference())); + c.set_priority(c.GetPriority(type_preference, network_->preference(), + relay_preference)); c.set_username(username_fragment()); c.set_password(password_); c.set_network_name(network_->name()); diff --git a/talk/p2p/base/port.h b/talk/p2p/base/port.h index 6e5c383b79..39d4e25b91 100644 --- a/talk/p2p/base/port.h +++ b/talk/p2p/base/port.h @@ -312,6 +312,12 @@ class Port : public PortInterface, public talk_base::MessageHandler, const std::string& protocol, const std::string& type, uint32 type_preference, bool final); + void AddAddress(const talk_base::SocketAddress& address, + const talk_base::SocketAddress& base_address, + const talk_base::SocketAddress& related_address, + const std::string& protocol, const std::string& type, + uint32 type_preference, uint32 relay_preference, bool final); + // Adds the given connection to the list. (Deleting removes them.) void AddConnection(Connection* conn); diff --git a/talk/p2p/base/port_unittest.cc b/talk/p2p/base/port_unittest.cc index fc6d48c9a5..dcddc46f90 100644 --- a/talk/p2p/base/port_unittest.cc +++ b/talk/p2p/base/port_unittest.cc @@ -481,7 +481,7 @@ class PortTest : public testing::Test, public sigslot::has_slots<> { addr.ipaddr(), 0, 0, username_, password_, ProtocolAddress( server_addr, PROTO_UDP), - kRelayCredentials); + kRelayCredentials, 0); port->SetIceProtocolType(ice_protocol_); return port; } diff --git a/talk/p2p/base/turnport.cc b/talk/p2p/base/turnport.cc index 195e9707bd..afd8efce7f 100644 --- a/talk/p2p/base/turnport.cc +++ b/talk/p2p/base/turnport.cc @@ -175,7 +175,8 @@ TurnPort::TurnPort(talk_base::Thread* thread, const std::string& username, const std::string& password, const ProtocolAddress& server_address, - const RelayCredentials& credentials) + const RelayCredentials& credentials, + int server_priority) : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(), username, password), server_address_(server_address), @@ -185,7 +186,8 @@ TurnPort::TurnPort(talk_base::Thread* thread, error_(0), request_manager_(thread), next_channel_number_(TURN_CHANNEL_NUMBER_START), - connected_(false) { + connected_(false), + server_priority_(server_priority) { request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket); } @@ -197,7 +199,8 @@ TurnPort::TurnPort(talk_base::Thread* thread, const std::string& username, const std::string& password, const ProtocolAddress& server_address, - const RelayCredentials& credentials) + const RelayCredentials& credentials, + int server_priority) : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port, username, password), server_address_(server_address), @@ -207,7 +210,8 @@ TurnPort::TurnPort(talk_base::Thread* thread, error_(0), request_manager_(thread), next_channel_number_(TURN_CHANNEL_NUMBER_START), - connected_(false) { + connected_(false), + server_priority_(server_priority) { request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket); } @@ -501,6 +505,7 @@ void TurnPort::OnAllocateSuccess(const talk_base::SocketAddress& address, UDP_PROTOCOL_NAME, RELAY_PORT_TYPE, GetRelayPreference(server_address_.proto, server_address_.secure), + server_priority_, true); } diff --git a/talk/p2p/base/turnport.h b/talk/p2p/base/turnport.h index 2f5e8c4ab1..3eea34e4ad 100644 --- a/talk/p2p/base/turnport.h +++ b/talk/p2p/base/turnport.h @@ -56,9 +56,11 @@ class TurnPort : public Port { const std::string& username, // ice username. const std::string& password, // ice password. const ProtocolAddress& server_address, - const RelayCredentials& credentials) { + const RelayCredentials& credentials, + int server_priority) { return new TurnPort(thread, factory, network, socket, - username, password, server_address, credentials); + username, password, server_address, + credentials, server_priority); } static TurnPort* Create(talk_base::Thread* thread, @@ -69,9 +71,11 @@ class TurnPort : public Port { const std::string& username, // ice username. const std::string& password, // ice password. const ProtocolAddress& server_address, - const RelayCredentials& credentials) { + const RelayCredentials& credentials, + int server_priority) { return new TurnPort(thread, factory, network, ip, min_port, max_port, - username, password, server_address, credentials); + username, password, server_address, credentials, + server_priority); } virtual ~TurnPort(); @@ -132,7 +136,8 @@ class TurnPort : public Port { const std::string& username, const std::string& password, const ProtocolAddress& server_address, - const RelayCredentials& credentials); + const RelayCredentials& credentials, + int server_priority); TurnPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory, @@ -142,7 +147,8 @@ class TurnPort : public Port { const std::string& username, const std::string& password, const ProtocolAddress& server_address, - const RelayCredentials& credentials); + const RelayCredentials& credentials, + int server_priority); private: enum { MSG_ERROR = MSG_FIRST_AVAILABLE }; @@ -212,6 +218,9 @@ class TurnPort : public Port { EntryList entries_; bool connected_; + // By default the value will be set to 0. This value will be used in + // calculating the candidate priority. + int server_priority_; friend class TurnEntry; friend class TurnAllocateRequest; diff --git a/talk/p2p/base/turnport_unittest.cc b/talk/p2p/base/turnport_unittest.cc index 12a19aa4db..bef85e6232 100644 --- a/talk/p2p/base/turnport_unittest.cc +++ b/talk/p2p/base/turnport_unittest.cc @@ -184,7 +184,7 @@ class TurnPortTest : public testing::Test, turn_port_.reset(TurnPort::Create(main_, &socket_factory_, &network_, local_address.ipaddr(), 0, 0, kIceUfrag1, kIcePwd1, - server_address, credentials)); + server_address, credentials, 0)); // Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be // in Hybrid mode. Protocol type is necessary to send correct type STUN ping // messages. @@ -207,7 +207,7 @@ class TurnPortTest : public testing::Test, cricket::RelayCredentials credentials(username, password); turn_port_.reset(cricket::TurnPort::Create( main_, &socket_factory_, &network_, socket_.get(), - kIceUfrag1, kIcePwd1, server_address, credentials)); + kIceUfrag1, kIcePwd1, server_address, credentials, 0)); // Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be // in Hybrid mode. Protocol type is necessary to send correct type STUN ping // messages. diff --git a/talk/p2p/client/basicportallocator.cc b/talk/p2p/client/basicportallocator.cc index 696588a513..aa1651749a 100644 --- a/talk/p2p/client/basicportallocator.cc +++ b/talk/p2p/client/basicportallocator.cc @@ -1026,7 +1026,7 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) { session_->socket_factory(), network_, udp_socket_.get(), session_->username(), session_->password(), - *relay_port, config.credentials); + *relay_port, config.credentials, config.priority); // If we are using shared socket for TURN and udp ports, we need to // find a way to demux the packets to the correct port when received. // Mapping against server_address is one way of doing this. When packet @@ -1051,7 +1051,7 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) { session_->allocator()->max_port(), session_->username(), session_->password(), - *relay_port, config.credentials); + *relay_port, config.credentials, config.priority); } ASSERT(port != NULL); session_->AddAllocatedPort(port, this, true); diff --git a/talk/p2p/client/basicportallocator.h b/talk/p2p/client/basicportallocator.h index 8a60c425ca..5c43b42c24 100644 --- a/talk/p2p/client/basicportallocator.h +++ b/talk/p2p/client/basicportallocator.h @@ -54,11 +54,12 @@ struct RelayCredentials { typedef std::vector PortList; struct RelayServerConfig { - RelayServerConfig(RelayType type) : type(type) {} + RelayServerConfig(RelayType type) : type(type), priority(0) {} RelayType type; PortList ports; RelayCredentials credentials; + int priority; }; class BasicPortAllocator : public PortAllocator {