From e5995aadd5fb6c649cbe191e8c987df85b38b79c Mon Sep 17 00:00:00 2001 From: "mallinath@webrtc.org" Date: Thu, 17 Jul 2014 18:23:52 +0000 Subject: [PATCH] Assigning a priority to TURN server list passed to PeerConnection. First entry in the TURN server list will get the highest priotity and so forth. This priority will be used in calculating the candidate priority generated from the server. This will allow candidate generated from server to have unique priority. BUG=3223 R=jiayl@webrtc.org, juberti@webrtc.org, pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/16549004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6721 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/app/webrtc/portallocatorfactory.cc | 2 ++ talk/p2p/base/candidate.h | 8 +++++--- talk/p2p/base/p2ptransportchannel.cc | 2 +- talk/p2p/base/port.cc | 15 ++++++++++++++- talk/p2p/base/port.h | 6 ++++++ talk/p2p/base/port_unittest.cc | 2 +- talk/p2p/base/turnport.cc | 13 +++++++++---- talk/p2p/base/turnport.h | 21 +++++++++++++++------ talk/p2p/base/turnport_unittest.cc | 4 ++-- talk/p2p/client/basicportallocator.cc | 4 ++-- talk/p2p/client/basicportallocator.h | 3 ++- 11 files changed, 59 insertions(+), 21 deletions(-) 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 {