Include relay protocol type when computing the turn candidate foundation.

BUG=576353
R=deadbeef@webrtc.org, pthatcher@google.com, pthatcher@webrtc.org

Review URL: https://codereview.webrtc.org/1619213003 .

Cr-Commit-Position: refs/heads/master@{#11400}
This commit is contained in:
Honghai Zhang 2016-01-27 11:54:45 -08:00
parent 3afc8c40be
commit 80f1db971d
3 changed files with 34 additions and 20 deletions

View File

@ -120,12 +120,12 @@ const char TCPTYPE_SIMOPEN_STR[] = "so";
// then the foundation will be different. Two candidate pairs with
// the same foundation pairs are likely to have similar network
// characteristics. Foundations are used in the frozen algorithm.
static std::string ComputeFoundation(
const std::string& type,
const std::string& protocol,
const rtc::SocketAddress& base_address) {
static std::string ComputeFoundation(const std::string& type,
const std::string& protocol,
const std::string& relay_protocol,
const rtc::SocketAddress& base_address) {
std::ostringstream ost;
ost << type << base_address.ipaddr().ToString() << protocol;
ost << type << base_address.ipaddr().ToString() << protocol << relay_protocol;
return rtc::ToString<uint32_t>(rtc::ComputeCrc32(ost.str()));
}
@ -252,7 +252,8 @@ void Port::AddAddress(const rtc::SocketAddress& address,
c.set_network_type(network_->type());
c.set_generation(generation_);
c.set_related_address(related_address);
c.set_foundation(ComputeFoundation(type, protocol, base_address));
c.set_foundation(
ComputeFoundation(type, protocol, relay_protocol, base_address));
candidates_.push_back(c);
SignalCandidateReady(this, c);
@ -1389,9 +1390,9 @@ void Connection::MaybeAddPrflxCandidate(ConnectionRequest* request,
new_local_candidate.set_network_name(local_candidate().network_name());
new_local_candidate.set_network_type(local_candidate().network_type());
new_local_candidate.set_related_address(local_candidate().address());
new_local_candidate.set_foundation(
ComputeFoundation(PRFLX_PORT_TYPE, local_candidate().protocol(),
local_candidate().address()));
new_local_candidate.set_foundation(ComputeFoundation(
PRFLX_PORT_TYPE, local_candidate().protocol(),
local_candidate().relay_protocol(), local_candidate().address()));
// Change the local candidate of this Connection to the new prflx candidate.
local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate);

View File

@ -58,6 +58,7 @@ static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
static const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
static const SocketAddress kTurnTcpIntAddr("99.99.99.4", 5010);
static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
static const RelayCredentials kRelayCredentials("test", "test");
@ -497,19 +498,19 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
TurnPort* CreateTurnPort(const SocketAddress& addr,
PacketSocketFactory* socket_factory,
ProtocolType int_proto, ProtocolType ext_proto) {
return CreateTurnPort(addr, socket_factory,
int_proto, ext_proto, kTurnUdpIntAddr);
SocketAddress server_addr =
int_proto == PROTO_TCP ? kTurnTcpIntAddr : kTurnUdpIntAddr;
return CreateTurnPort(addr, socket_factory, int_proto, ext_proto,
server_addr);
}
TurnPort* CreateTurnPort(const SocketAddress& addr,
PacketSocketFactory* socket_factory,
ProtocolType int_proto, ProtocolType ext_proto,
const rtc::SocketAddress& server_addr) {
return TurnPort::Create(main_, socket_factory, &network_,
addr.ipaddr(), 0, 0,
username_, password_, ProtocolAddress(
server_addr, PROTO_UDP),
kRelayCredentials, 0,
std::string());
return TurnPort::Create(main_, socket_factory, &network_, addr.ipaddr(), 0,
0, username_, password_,
ProtocolAddress(server_addr, int_proto),
kRelayCredentials, 0, std::string());
}
RelayPort* CreateGturnPort(const SocketAddress& addr,
ProtocolType int_proto, ProtocolType ext_proto) {
@ -2162,6 +2163,17 @@ TEST_F(PortTest, TestCandidateFoundation) {
ASSERT_EQ_WAIT(1U, turnport3->Candidates().size(), kTimeout);
EXPECT_NE(turnport3->Candidates()[0].foundation(),
turnport2->Candidates()[0].foundation());
// Start a TCP turn server, and check that two turn candidates have
// different foundations if their relay protocols are different.
TestTurnServer turn_server3(rtc::Thread::Current(), kTurnTcpIntAddr,
kTurnUdpExtAddr, PROTO_TCP);
rtc::scoped_ptr<Port> turnport4(
CreateTurnPort(kLocalAddr1, nat_socket_factory1(), PROTO_TCP, PROTO_UDP));
turnport4->PrepareAddress();
ASSERT_EQ_WAIT(1U, turnport4->Candidates().size(), kTimeout);
EXPECT_NE(turnport2->Candidates()[0].foundation(),
turnport4->Candidates()[0].foundation());
}
// This test verifies the related addresses of different types of

View File

@ -49,10 +49,11 @@ class TestTurnRedirector : public TurnRedirectInterface {
class TestTurnServer : public TurnAuthInterface {
public:
TestTurnServer(rtc::Thread* thread,
const rtc::SocketAddress& udp_int_addr,
const rtc::SocketAddress& udp_ext_addr)
const rtc::SocketAddress& int_addr,
const rtc::SocketAddress& udp_ext_addr,
ProtocolType int_protocol = PROTO_UDP)
: server_(thread) {
AddInternalSocket(udp_int_addr, cricket::PROTO_UDP);
AddInternalSocket(int_addr, int_protocol);
server_.SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(),
udp_ext_addr);
server_.set_realm(kTestRealm);