| 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);
|
| +}
|
|
|