Index: webrtc/p2p/base/p2ptransportchannel_unittest.cc |
diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
index 74b96a353287aad743f9a8c72aa6dab4da02b750..49446ddad73d51fb12ab876c304635f12d641192 100644 |
--- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
+++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
@@ -81,6 +81,8 @@ static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005); |
// The addresses for the public turn server. |
static const SocketAddress kTurnUdpIntAddr("99.99.99.4", |
cricket::STUN_SERVER_PORT); |
+static const SocketAddress kTurnTcpIntAddr("99.99.99.4", |
+ cricket::STUN_SERVER_PORT + 1); |
static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0); |
static const cricket::RelayCredentials kRelayCredentials("test", "test"); |
@@ -1865,16 +1867,17 @@ class P2PTransportChannelPingTest : public testing::Test, |
ch->SetRemoteIceCredentials(kIceUfrag[1], kIcePwd[1]); |
} |
- cricket::Candidate CreateCandidate(const std::string& ip, |
- int port, |
- int priority, |
- const std::string& ufrag = "") { |
+ cricket::Candidate CreateHostCandidate(const std::string& ip, |
+ int port, |
+ int priority, |
+ const std::string& ufrag = "") { |
cricket::Candidate c; |
c.set_address(rtc::SocketAddress(ip, port)); |
c.set_component(1); |
c.set_protocol(cricket::UDP_PROTOCOL_NAME); |
c.set_priority(priority); |
c.set_username(ufrag); |
+ c.set_type(cricket::LOCAL_PORT_TYPE); |
return c; |
} |
@@ -1902,6 +1905,15 @@ class P2PTransportChannelPingTest : public testing::Test, |
return port->GetConnection(rtc::SocketAddress(ip, port_num)); |
} |
+ cricket::Connection* FindNextPingableConnectionAndPingIt( |
+ cricket::P2PTransportChannel* ch) { |
+ cricket::Connection* conn = ch->FindNextPingableConnection(); |
+ if (conn) { |
+ ch->MarkConnectionPinged(conn); |
+ } |
+ return conn; |
+ } |
+ |
private: |
rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_; |
rtc::scoped_ptr<rtc::VirtualSocketServer> vss_; |
@@ -1914,8 +1926,8 @@ TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) { |
PrepareChannel(&ch); |
ch.Connect(); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 1)); |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 2)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
@@ -1924,13 +1936,13 @@ TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) { |
// Before a triggered check, the first connection to ping is the |
// highest priority one. |
- EXPECT_EQ(conn2, ch.FindNextPingableConnection()); |
+ EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch)); |
// Receiving a ping causes a triggered check which should make conn1 |
// be pinged first instead of conn2, even though conn2 has a higher |
// priority. |
conn1->ReceivedPing(); |
- EXPECT_EQ(conn1, ch.FindNextPingableConnection()); |
+ EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch)); |
} |
TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) { |
@@ -1939,15 +1951,16 @@ TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) { |
PrepareChannel(&ch); |
ch.Connect(); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 1)); |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 2)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn1 != nullptr); |
ASSERT_TRUE(conn2 != nullptr); |
- EXPECT_EQ(conn2, ch.FindNextPingableConnection()); |
+ EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch)); |
+ EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch)); |
conn1->ReceivedPingResponse(); |
ASSERT_TRUE(conn1->writable()); |
conn1->ReceivedPing(); |
@@ -1955,7 +1968,7 @@ TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) { |
// Ping received, but the connection is already writable, so no |
// "triggered check" and conn2 is pinged before conn1 because it has |
// a higher priority. |
- EXPECT_EQ(conn2, ch.FindNextPingableConnection()); |
+ EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch)); |
} |
// Test adding remote candidates with different ufrags. If a remote candidate |
@@ -1971,13 +1984,13 @@ TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) { |
ch.Connect(); |
ch.MaybeStartGathering(); |
// Add a candidate with a future ufrag. |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 1, kIceUfrag[2])); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1, kIceUfrag[2])); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
const cricket::Candidate& candidate = conn1->remote_candidate(); |
EXPECT_EQ(kIceUfrag[2], candidate.username()); |
EXPECT_TRUE(candidate.password().empty()); |
- EXPECT_TRUE(ch.FindNextPingableConnection() == nullptr); |
+ EXPECT_TRUE(FindNextPingableConnectionAndPingIt(&ch) == nullptr); |
// Set the remote credentials with the "future" ufrag. |
// This should set the ICE pwd in the remote candidate of |conn1|, making |
@@ -1985,16 +1998,16 @@ TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithVariousUfrags) { |
ch.SetRemoteIceCredentials(kIceUfrag[2], kIcePwd[2]); |
EXPECT_EQ(kIceUfrag[2], candidate.username()); |
EXPECT_EQ(kIcePwd[2], candidate.password()); |
- EXPECT_EQ(conn1, ch.FindNextPingableConnection()); |
+ EXPECT_EQ(conn1, FindNextPingableConnectionAndPingIt(&ch)); |
// Add a candidate with an old ufrag. No connection will be created. |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 2, kIceUfrag[1])); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2, kIceUfrag[1])); |
rtc::Thread::Current()->ProcessMessages(500); |
EXPECT_TRUE(GetConnectionTo(&ch, "2.2.2.2", 2) == nullptr); |
// Add a candidate with the current ufrag, its pwd and generation will be |
// assigned, even if the generation is not set. |
- ch.AddRemoteCandidate(CreateCandidate("3.3.3.3", 3, 0, kIceUfrag[2])); |
+ ch.AddRemoteCandidate(CreateHostCandidate("3.3.3.3", 3, 0, kIceUfrag[2])); |
cricket::Connection* conn3 = nullptr; |
ASSERT_TRUE_WAIT((conn3 = GetConnectionTo(&ch, "3.3.3.3", 3)) != nullptr, |
3000); |
@@ -2022,14 +2035,14 @@ TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) { |
ch.MaybeStartGathering(); |
// Create conn1 and keep track of original candidate priority. |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
uint32_t remote_priority = conn1->remote_candidate().priority(); |
// Create a higher priority candidate and make the connection |
// receiving/writable. This will prune conn1. |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 2)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2)); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn2 != nullptr); |
conn2->ReceivedPing(); |
@@ -2080,7 +2093,7 @@ TEST_F(P2PTransportChannelPingTest, TestReceivingStateChange) { |
EXPECT_EQ(50, ch.check_receiving_delay()); |
ch.Connect(); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
@@ -2102,14 +2115,14 @@ TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) { |
ch.SetIceRole(cricket::ICEROLE_CONTROLLED); |
ch.Connect(); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
EXPECT_EQ(conn1, ch.best_connection()); |
// When a higher priority candidate comes in, the new connection is chosen |
// as the best connection. |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 10)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 10)); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn2 != nullptr); |
EXPECT_EQ(conn2, ch.best_connection()); |
@@ -2117,7 +2130,7 @@ TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) { |
// If a stun request with use-candidate attribute arrives, the receiving |
// connection will be set as the best connection, even though |
// its priority is lower. |
- ch.AddRemoteCandidate(CreateCandidate("3.3.3.3", 3, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("3.3.3.3", 3, 1)); |
cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3); |
ASSERT_TRUE(conn3 != nullptr); |
// Because it has a lower priority, the best connection is still conn2. |
@@ -2132,7 +2145,7 @@ TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBeforeNomination) { |
// Even if another higher priority candidate arrives, |
// it will not be set as the best connection because the best connection |
// is nominated by the controlling side. |
- ch.AddRemoteCandidate(CreateCandidate("4.4.4.4", 4, 100)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("4.4.4.4", 4, 100)); |
cricket::Connection* conn4 = WaitForConnectionTo(&ch, "4.4.4.4", 4); |
ASSERT_TRUE(conn4 != nullptr); |
EXPECT_EQ(conn3, ch.best_connection()); |
@@ -2179,7 +2192,7 @@ TEST_F(P2PTransportChannelPingTest, TestSelectConnectionFromUnknownAddress) { |
port->set_sent_binding_response(false); |
// Another connection is nominated via use_candidate. |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1)); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn2 != nullptr); |
// Because it has a lower priority, the best connection is still conn1. |
@@ -2241,7 +2254,7 @@ TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) { |
ch.SetIceRole(cricket::ICEROLE_CONTROLLED); |
ch.Connect(); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 10)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 10)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
EXPECT_EQ(conn1, ch.best_connection()); |
@@ -2249,7 +2262,7 @@ TEST_F(P2PTransportChannelPingTest, TestSelectConnectionBasedOnMediaReceived) { |
// If a data packet is received on conn2, the best connection should |
// switch to conn2 because the controlled side must mirror the media path |
// chosen by the controlling side. |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1)); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn2 != nullptr); |
conn2->ReceivedPing(); // Start receiving. |
@@ -2299,7 +2312,7 @@ TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) { |
ch.SetIceRole(cricket::ICEROLE_CONTROLLED); |
ch.Connect(); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
EXPECT_EQ(conn1, ch.best_connection()); |
@@ -2307,7 +2320,7 @@ TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) { |
// When a higher-priority, nominated candidate comes in, the connections with |
// lower-priority are pruned. |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 10)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 10)); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn2 != nullptr); |
conn2->ReceivedPingResponse(); // Becomes writable and receiving |
@@ -2319,7 +2332,7 @@ TEST_F(P2PTransportChannelPingTest, TestDontPruneWhenWeak) { |
// Wait until conn2 becomes not receiving. |
EXPECT_TRUE_WAIT(!conn2->receiving(), 3000); |
- ch.AddRemoteCandidate(CreateCandidate("3.3.3.3", 3, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("3.3.3.3", 3, 1)); |
cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3); |
ASSERT_TRUE(conn3 != nullptr); |
// The best connection should still be conn2. Even through conn3 has lower |
@@ -2337,8 +2350,8 @@ TEST_F(P2PTransportChannelPingTest, TestGetState) { |
ch.Connect(); |
ch.MaybeStartGathering(); |
EXPECT_EQ(cricket::TransportChannelState::STATE_INIT, ch.GetState()); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 100)); |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 100)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn1 != nullptr); |
@@ -2364,7 +2377,7 @@ TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) { |
ch.SetIceConfig(CreateIceConfig(1000, false)); |
ch.Connect(); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 100)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 100)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
EXPECT_EQ(conn1, ch.best_connection()); |
@@ -2374,7 +2387,7 @@ TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) { |
// not be deleted right away. Once the current best connection becomes not |
// receiving, |conn2| will start to ping and upon receiving the ping response, |
// it will become the best connection. |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1)); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn2 != nullptr); |
EXPECT_TRUE_WAIT(!conn2->active(), 1000); |
@@ -2407,7 +2420,7 @@ TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) { |
ch.Connect(); |
ch.MaybeStartGathering(); |
// Have one connection only but later becomes write-time-out. |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 100)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 100)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
conn1->ReceivedPing(); // Becomes receiving |
@@ -2415,11 +2428,11 @@ TEST_F(P2PTransportChannelPingTest, TestDeleteConnectionsIfAllWriteTimedout) { |
EXPECT_TRUE_WAIT(ch.connections().empty(), 1000); |
// Have two connections but both become write-time-out later. |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 1)); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn2 != nullptr); |
conn2->ReceivedPing(); // Becomes receiving |
- ch.AddRemoteCandidate(CreateCandidate("3.3.3.3", 3, 2)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("3.3.3.3", 3, 2)); |
cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 3); |
ASSERT_TRUE(conn3 != nullptr); |
conn3->ReceivedPing(); // Becomes receiving |
@@ -2439,7 +2452,7 @@ TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) { |
ch.SetIceConfig(CreateIceConfig(2000, false)); |
ch.Connect(); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("1.1.1.1", 1, 100)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 100)); |
cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
ASSERT_TRUE(conn1 != nullptr); |
conn1->ReceivedPingResponse(); // Becomes writable and receiving |
@@ -2450,9 +2463,237 @@ TEST_F(P2PTransportChannelPingTest, TestStopPortAllocatorSessions) { |
// connected. |
ch.SetIceCredentials(kIceUfrag[1], kIcePwd[1]); |
ch.MaybeStartGathering(); |
- ch.AddRemoteCandidate(CreateCandidate("2.2.2.2", 2, 100)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 100)); |
cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
ASSERT_TRUE(conn2 != nullptr); |
conn2->ReceivedPingResponse(); // Becomes writable and receiving |
EXPECT_TRUE(!ch.allocator_session()->IsGettingPorts()); |
} |
+ |
+class P2PTransportChannelMostLikelyToWorkFirstTest |
+ : public P2PTransportChannelPingTest { |
+ public: |
+ P2PTransportChannelMostLikelyToWorkFirstTest() |
+ : turn_server_(rtc::Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr) { |
+ network_manager_.AddInterface(kPublicAddrs[0]); |
+ allocator_.reset(new cricket::BasicPortAllocator( |
+ &network_manager_, ServerAddresses(), rtc::SocketAddress(), |
+ rtc::SocketAddress(), rtc::SocketAddress())); |
+ allocator_->set_flags(allocator_->flags() | |
+ cricket::PORTALLOCATOR_DISABLE_STUN | |
+ cricket::PORTALLOCATOR_DISABLE_TCP); |
+ cricket::RelayServerConfig config(cricket::RELAY_TURN); |
+ config.credentials = kRelayCredentials; |
+ config.ports.push_back( |
+ cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false)); |
+ allocator_->AddTurnServer(config); |
+ allocator_->set_step_delay(kMinimumStepDelay); |
+ } |
+ |
+ cricket::P2PTransportChannel& StartTransportChannel( |
+ bool prioritize_most_likely_to_work, |
+ uint32_t max_strong_delay) { |
+ channel_.reset( |
+ new cricket::P2PTransportChannel("checks", 1, nullptr, allocator())); |
+ cricket::IceConfig config = channel_->config(); |
+ config.prioritize_most_likely_candidate_pairs = |
+ prioritize_most_likely_to_work; |
+ config.max_strong_delay = max_strong_delay; |
+ channel_->SetIceConfig(config); |
+ PrepareChannel(channel_.get()); |
+ channel_->Connect(); |
+ channel_->MaybeStartGathering(); |
+ return *channel_.get(); |
+ } |
+ |
+ cricket::BasicPortAllocator* allocator() { return allocator_.get(); } |
+ cricket::TestTurnServer* turn_server() { return &turn_server_; } |
+ |
+ // This verifies the next pingable connection has the expected candidates' |
+ // types and, for relay local candidate, the expected relay protocol and ping |
+ // it. |
+ void VerifyNextPingableConnection( |
+ const std::string& local_candidate_type, |
+ const std::string& remote_candidate_type, |
+ const std::string& relay_protocol_type = cricket::UDP_PROTOCOL_NAME) { |
+ cricket::Connection* conn = |
+ FindNextPingableConnectionAndPingIt(channel_.get()); |
+ EXPECT_EQ(conn->local_candidate().type(), local_candidate_type); |
+ if (conn->local_candidate().type() == cricket::RELAY_PORT_TYPE) { |
+ EXPECT_EQ(conn->local_candidate().relay_protocol(), relay_protocol_type); |
+ } |
+ EXPECT_EQ(conn->remote_candidate().type(), remote_candidate_type); |
+ } |
+ |
+ cricket::Candidate CreateRelayCandidate(const std::string& ip, |
+ int port, |
+ int priority, |
+ const std::string& ufrag = "") { |
+ cricket::Candidate c = CreateHostCandidate(ip, port, priority, ufrag); |
+ c.set_type(cricket::RELAY_PORT_TYPE); |
+ return c; |
+ } |
+ |
+ private: |
+ rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_; |
+ rtc::FakeNetworkManager network_manager_; |
+ cricket::TestTurnServer turn_server_; |
+ rtc::scoped_ptr<cricket::P2PTransportChannel> channel_; |
+}; |
+ |
+// Test that Relay/Relay connections will be pinged first when no other |
+// connections have been pinged yet, unless we need to ping a trigger check or |
+// we have a best connection. |
+TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, |
+ TestRelayRelayFirstWhenNothingPingedYet) { |
+ const uint32_t max_strong_delay = 100; |
+ cricket::P2PTransportChannel& ch = |
+ StartTransportChannel(true, max_strong_delay); |
+ EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000); |
+ EXPECT_EQ(ch.ports()[0]->Type(), cricket::LOCAL_PORT_TYPE); |
+ EXPECT_EQ(ch.ports()[1]->Type(), cricket::RELAY_PORT_TYPE); |
+ |
+ ch.AddRemoteCandidate(CreateRelayCandidate("1.1.1.1", 1, 1)); |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2)); |
+ |
+ EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000); |
+ |
+ // Relay/Relay should be the first pingable connection. |
+ cricket::Connection* conn = FindNextPingableConnectionAndPingIt(&ch); |
+ EXPECT_EQ(conn->local_candidate().type(), cricket::RELAY_PORT_TYPE); |
+ EXPECT_EQ(conn->remote_candidate().type(), cricket::RELAY_PORT_TYPE); |
+ |
+ // Unless that we have a trigger check waiting to be pinged. |
+ cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
+ EXPECT_EQ(conn2->local_candidate().type(), cricket::LOCAL_PORT_TYPE); |
+ EXPECT_EQ(conn2->remote_candidate().type(), cricket::LOCAL_PORT_TYPE); |
+ conn2->ReceivedPing(); |
+ EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch)); |
+ |
+ // Make conn3 the best connection. |
+ cricket::Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
+ EXPECT_EQ(conn3->local_candidate().type(), cricket::LOCAL_PORT_TYPE); |
+ EXPECT_EQ(conn3->remote_candidate().type(), cricket::RELAY_PORT_TYPE); |
+ conn3->ReceivedPingResponse(); |
+ ASSERT_TRUE(conn3->writable()); |
+ conn3->ReceivedPing(); |
+ |
+ // Verify that conn3 will be the "best connection" since it is readable and |
+ // writable. After |MAX_CURRENT_STRONG_DELAY|, it should be the next pingable |
+ // connection. |
+ EXPECT_TRUE_WAIT(conn3 == ch.best_connection(), 5000); |
+ WAIT(false, max_strong_delay + 100); |
+ conn3->ReceivedPingResponse(); |
+ ASSERT_TRUE(conn3->writable()); |
+ EXPECT_EQ(conn3, FindNextPingableConnectionAndPingIt(&ch)); |
+} |
+ |
+// Test that Relay/Relay connections will be pinged first when everything has |
+// been pinged even if the Relay/Relay connection wasn't the first to be pinged |
+// in the first round. |
+TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, |
+ TestRelayRelayFirstWhenEverythingPinged) { |
+ cricket::P2PTransportChannel& ch = StartTransportChannel(true, 100); |
+ EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000); |
+ EXPECT_EQ(ch.ports()[0]->Type(), cricket::LOCAL_PORT_TYPE); |
+ EXPECT_EQ(ch.ports()[1]->Type(), cricket::RELAY_PORT_TYPE); |
+ |
+ ch.AddRemoteCandidate(CreateHostCandidate("1.1.1.1", 1, 1)); |
+ EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000); |
+ |
+ // Initially, only have Local/Local and Local/Relay. |
+ VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE, |
+ cricket::LOCAL_PORT_TYPE); |
+ VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE, |
+ cricket::LOCAL_PORT_TYPE); |
+ |
+ // Remote Relay candidate arrives. |
+ ch.AddRemoteCandidate(CreateRelayCandidate("2.2.2.2", 2, 2)); |
+ EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000); |
+ |
+ // Relay/Relay should be the first since it hasn't been pinged before. |
+ VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE); |
+ |
+ // Local/Relay is the final one. |
+ VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE); |
+ |
+ // Now, every connection has been pinged once. The next one should be |
+ // Relay/Relay. |
+ VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE); |
+} |
+ |
+// Test that when we receive a new remote candidate, they will be tried first |
+// before we re-ping Relay/Relay connections again. |
+TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, |
+ TestNoStarvationOnNonRelayConnection) { |
+ cricket::P2PTransportChannel& ch = StartTransportChannel(true, 100); |
+ EXPECT_TRUE_WAIT(ch.ports().size() == 2, 5000); |
+ EXPECT_EQ(ch.ports()[0]->Type(), cricket::LOCAL_PORT_TYPE); |
+ EXPECT_EQ(ch.ports()[1]->Type(), cricket::RELAY_PORT_TYPE); |
+ |
+ ch.AddRemoteCandidate(CreateRelayCandidate("1.1.1.1", 1, 1)); |
+ EXPECT_TRUE_WAIT(ch.connections().size() == 2, 5000); |
+ |
+ // Initially, only have Relay/Relay and Local/Relay. Ping Relay/Relay first. |
+ VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE); |
+ |
+ // Next, ping Local/Relay. |
+ VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE); |
+ |
+ // Remote Local candidate arrives. |
+ ch.AddRemoteCandidate(CreateHostCandidate("2.2.2.2", 2, 2)); |
+ EXPECT_TRUE_WAIT(ch.connections().size() == 4, 5000); |
+ |
+ // Local/Local should be the first since it hasn't been pinged before. |
+ VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE, |
+ cricket::LOCAL_PORT_TYPE); |
+ |
+ // Relay/Local is the final one. |
+ VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE, |
+ cricket::LOCAL_PORT_TYPE); |
+ |
+ // Now, every connection has been pinged once. The next one should be |
+ // Relay/Relay. |
+ VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE); |
+} |
+ |
+// Test the ping sequence is UDP Relay/Relay followed by TCP Relay/Relay, |
+// followed by the rest. |
+TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, TestTcpTurn) { |
+ // Add a Tcp Turn server. |
+ turn_server()->AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP); |
+ cricket::RelayServerConfig config(cricket::RELAY_TURN); |
+ config.credentials = kRelayCredentials; |
+ config.ports.push_back( |
+ cricket::ProtocolAddress(kTurnTcpIntAddr, cricket::PROTO_TCP, false)); |
+ allocator()->AddTurnServer(config); |
+ |
+ cricket::P2PTransportChannel& ch = StartTransportChannel(true, 100); |
+ EXPECT_TRUE_WAIT(ch.ports().size() == 3, 5000); |
+ EXPECT_EQ(ch.ports()[0]->Type(), cricket::LOCAL_PORT_TYPE); |
+ EXPECT_EQ(ch.ports()[1]->Type(), cricket::RELAY_PORT_TYPE); |
+ EXPECT_EQ(ch.ports()[2]->Type(), cricket::RELAY_PORT_TYPE); |
+ |
+ // Remote Relay candidate arrives. |
+ ch.AddRemoteCandidate(CreateRelayCandidate("1.1.1.1", 1, 1)); |
+ EXPECT_TRUE_WAIT(ch.connections().size() == 3, 5000); |
+ |
+ // UDP Relay/Relay should be pinged first. |
+ VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE); |
+ |
+ // TCP Relay/Relay is the next. |
+ VerifyNextPingableConnection(cricket::RELAY_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE, |
+ cricket::TCP_PROTOCOL_NAME); |
+ |
+ // Finally, Local/Relay will be pinged. |
+ VerifyNextPingableConnection(cricket::LOCAL_PORT_TYPE, |
+ cricket::RELAY_PORT_TYPE); |
+} |