Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: webrtc/p2p/base/p2ptransportchannel_unittest.cc

Issue 2143653005: Dampening connection switch. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: . Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.cc ('k') | webrtc/p2p/base/port.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2009 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2009 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 channel->SignalReadyToSend.connect( 343 channel->SignalReadyToSend.connect(
344 this, &P2PTransportChannelTestBase::OnReadyToSend); 344 this, &P2PTransportChannelTestBase::OnReadyToSend);
345 channel->SignalCandidateGathered.connect( 345 channel->SignalCandidateGathered.connect(
346 this, &P2PTransportChannelTestBase::OnCandidateGathered); 346 this, &P2PTransportChannelTestBase::OnCandidateGathered);
347 channel->SignalCandidatesRemoved.connect( 347 channel->SignalCandidatesRemoved.connect(
348 this, &P2PTransportChannelTestBase::OnCandidatesRemoved); 348 this, &P2PTransportChannelTestBase::OnCandidatesRemoved);
349 channel->SignalReadPacket.connect( 349 channel->SignalReadPacket.connect(
350 this, &P2PTransportChannelTestBase::OnReadPacket); 350 this, &P2PTransportChannelTestBase::OnReadPacket);
351 channel->SignalRoleConflict.connect( 351 channel->SignalRoleConflict.connect(
352 this, &P2PTransportChannelTestBase::OnRoleConflict); 352 this, &P2PTransportChannelTestBase::OnRoleConflict);
353 channel->SignalSelectedCandidatePairChanged.connect(
354 this, &P2PTransportChannelTestBase::OnSelectedCandidatePairChanged);
353 channel->SetIceCredentials(local_ice_ufrag, local_ice_pwd); 355 channel->SetIceCredentials(local_ice_ufrag, local_ice_pwd);
354 if (remote_ice_credential_source_ == FROM_SETICECREDENTIALS) { 356 if (remote_ice_credential_source_ == FROM_SETICECREDENTIALS) {
355 channel->SetRemoteIceCredentials(remote_ice_ufrag, remote_ice_pwd); 357 channel->SetRemoteIceCredentials(remote_ice_ufrag, remote_ice_pwd);
356 } 358 }
357 channel->SetIceRole(GetEndpoint(endpoint)->ice_role()); 359 channel->SetIceRole(GetEndpoint(endpoint)->ice_role());
358 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker()); 360 channel->SetIceTiebreaker(GetEndpoint(endpoint)->GetIceTiebreaker());
359 return channel; 361 return channel;
360 } 362 }
361 void DestroyChannels() { 363 void DestroyChannels() {
362 ep1_.cd1_.ch_.reset(); 364 ep1_.cd1_.ch_.reset();
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 return; 683 return;
682 684
683 if (GetEndpoint(ch)->save_candidates_) { 685 if (GetEndpoint(ch)->save_candidates_) {
684 GetEndpoint(ch)->saved_candidates_.push_back( 686 GetEndpoint(ch)->saved_candidates_.push_back(
685 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c))); 687 std::unique_ptr<CandidatesData>(new CandidatesData(ch, c)));
686 } else { 688 } else {
687 main_->Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES, 689 main_->Post(RTC_FROM_HERE, this, MSG_ADD_CANDIDATES,
688 new CandidatesData(ch, c)); 690 new CandidatesData(ch, c));
689 } 691 }
690 } 692 }
693 void OnSelectedCandidatePairChanged(
694 TransportChannel* transport_channel,
695 CandidatePairInterface* selected_candidate_pair,
696 int last_sent_packet_id,
697 bool ready_to_send) {
698 ++selected_candidate_pair_switches_;
699 }
700
701 int reset_selected_candidate_pair_switches() {
702 int switches = selected_candidate_pair_switches_;
703 selected_candidate_pair_switches_ = 0;
704 return switches;
705 }
691 706
692 void PauseCandidates(int endpoint) { 707 void PauseCandidates(int endpoint) {
693 GetEndpoint(endpoint)->save_candidates_ = true; 708 GetEndpoint(endpoint)->save_candidates_ = true;
694 } 709 }
695 710
696 void OnCandidatesRemoved(TransportChannelImpl* ch, 711 void OnCandidatesRemoved(TransportChannelImpl* ch,
697 const std::vector<Candidate>& candidates) { 712 const std::vector<Candidate>& candidates) {
698 // Candidate removals are not paused. 713 // Candidate removals are not paused.
699 CandidatesData* candidates_data = new CandidatesData(ch, candidates); 714 CandidatesData* candidates_data = new CandidatesData(ch, candidates);
700 main_->Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data); 715 main_->Post(RTC_FROM_HERE, this, MSG_REMOVE_CANDIDATES, candidates_data);
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 rtc::SocketServerScope ss_scope_; 858 rtc::SocketServerScope ss_scope_;
844 std::unique_ptr<TestStunServer> stun_server_; 859 std::unique_ptr<TestStunServer> stun_server_;
845 TestTurnServer turn_server_; 860 TestTurnServer turn_server_;
846 TestRelayServer relay_server_; 861 TestRelayServer relay_server_;
847 rtc::SocksProxyServer socks_server1_; 862 rtc::SocksProxyServer socks_server1_;
848 rtc::SocksProxyServer socks_server2_; 863 rtc::SocksProxyServer socks_server2_;
849 Endpoint ep1_; 864 Endpoint ep1_;
850 Endpoint ep2_; 865 Endpoint ep2_;
851 RemoteIceCredentialSource remote_ice_credential_source_ = FROM_CANDIDATE; 866 RemoteIceCredentialSource remote_ice_credential_source_ = FROM_CANDIDATE;
852 bool force_relay_; 867 bool force_relay_;
868 int selected_candidate_pair_switches_ = 0;
853 }; 869 };
854 870
855 // The tests have only a few outcomes, which we predefine. 871 // The tests have only a few outcomes, which we predefine.
856 const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase:: 872 const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
857 kLocalUdpToLocalUdp("local", "udp", "local", "udp", 873 kLocalUdpToLocalUdp("local", "udp", "local", "udp",
858 "local", "udp", "local", "udp", 1000); 874 "local", "udp", "local", "udp", 1000);
859 const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase:: 875 const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
860 kLocalUdpToStunUdp("local", "udp", "stun", "udp", 876 kLocalUdpToStunUdp("local", "udp", "stun", "udp",
861 "local", "udp", "stun", "udp", 1000); 877 "local", "udp", "stun", "udp", 1000);
862 const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase:: 878 const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 AddAddress(0, kPublicAddrs[0]); 1876 AddAddress(0, kPublicAddrs[0]);
1861 AddAddress(0, kAlternateAddrs[0]); 1877 AddAddress(0, kAlternateAddrs[0]);
1862 AddAddress(1, kPublicAddrs[1]); 1878 AddAddress(1, kPublicAddrs[1]);
1863 AddAddress(1, kAlternateAddrs[1]); 1879 AddAddress(1, kAlternateAddrs[1]);
1864 Test(kLocalUdpToLocalUdp); 1880 Test(kLocalUdpToLocalUdp);
1865 } 1881 }
1866 1882
1867 // Test that we can quickly switch links if an interface goes down. 1883 // Test that we can quickly switch links if an interface goes down.
1868 // The controlled side has two interfaces and one will die. 1884 // The controlled side has two interfaces and one will die.
1869 TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) { 1885 TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControlledSide) {
1886 rtc::ScopedFakeClock clock;
1870 AddAddress(0, kPublicAddrs[0]); 1887 AddAddress(0, kPublicAddrs[0]);
1871 // Adding alternate address will make sure |kPublicAddrs| has the higher 1888 // Adding alternate address will make sure |kPublicAddrs| has the higher
1872 // priority than others. This is due to FakeNetwork::AddInterface method. 1889 // priority than others. This is due to FakeNetwork::AddInterface method.
1873 AddAddress(1, kAlternateAddrs[1]); 1890 AddAddress(1, kAlternateAddrs[1]);
1874 AddAddress(1, kPublicAddrs[1]); 1891 AddAddress(1, kPublicAddrs[1]);
1875 1892
1876 // Use only local ports for simplicity. 1893 // Use only local ports for simplicity.
1877 SetAllocatorFlags(0, kOnlyLocalPorts); 1894 SetAllocatorFlags(0, kOnlyLocalPorts);
1878 SetAllocatorFlags(1, kOnlyLocalPorts); 1895 SetAllocatorFlags(1, kOnlyLocalPorts);
1879 1896
1880 // Create channels and let them go writable, as usual. 1897 // Create channels and let them go writable, as usual.
1881 CreateChannels(1); 1898 CreateChannels(1);
1882 1899
1883 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() && 1900 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1884 ep2_ch1()->receiving() && ep2_ch1()->writable(), 1901 ep2_ch1()->receiving() &&
1885 1000, 1000); 1902 ep2_ch1()->writable(),
1903 3000, clock);
1886 EXPECT_TRUE(ep1_ch1()->selected_connection() && 1904 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1887 ep2_ch1()->selected_connection() && 1905 ep2_ch1()->selected_connection() &&
1888 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) && 1906 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1889 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1])); 1907 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1890 1908
1891 // Make the receiving timeout shorter for testing. 1909 // Make the receiving timeout shorter for testing.
1892 IceConfig config = CreateIceConfig(1000, GATHER_ONCE); 1910 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
1893 ep1_ch1()->SetIceConfig(config); 1911 ep1_ch1()->SetIceConfig(config);
1894 ep2_ch1()->SetIceConfig(config); 1912 ep2_ch1()->SetIceConfig(config);
1895 1913
1896 // Blackhole any traffic to or from the public addrs. 1914 // Blackhole any traffic to or from the public addrs.
1897 LOG(LS_INFO) << "Failing over..."; 1915 LOG(LS_INFO) << "Failing over...";
1898 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]); 1916 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
1899 // The selected connections will switch, so keep references to them. 1917 // The selected connections may switch, so keep references to them.
1900 const Connection* selected_connection1 = ep1_ch1()->selected_connection(); 1918 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
1901 const Connection* selected_connection2 = ep2_ch1()->selected_connection(); 1919 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
1902 // We should detect loss of receiving within 1 second or so. 1920 // We should detect loss of receiving within 1 second or so.
1903 EXPECT_TRUE_WAIT( 1921 EXPECT_TRUE_SIMULATED_WAIT(
1904 !selected_connection1->receiving() && !selected_connection2->receiving(), 1922 !selected_connection1->receiving() && !selected_connection2->receiving(),
1905 3000); 1923 3000, clock);
1906 1924
1907 // We should switch over to use the alternate addr immediately on both sides 1925 // We should switch over to use the alternate addr on both sides
1908 // when we are not receiving. 1926 // when we are not receiving.
1909 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection()->receiving() && 1927 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
1910 ep2_ch1()->selected_connection()->receiving(), 1928 ep2_ch1()->selected_connection()->receiving(),
1911 1000); 1929 3000, clock);
1912 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0])); 1930 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
1913 EXPECT_TRUE( 1931 EXPECT_TRUE(
1914 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1])); 1932 RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]));
1915 EXPECT_TRUE( 1933 EXPECT_TRUE(
1916 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1])); 1934 LocalCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[1]));
1917 1935
1918 DestroyChannels(); 1936 DestroyChannels();
1919 } 1937 }
1920 1938
1921 // Test that we can quickly switch links if an interface goes down. 1939 // Test that we can quickly switch links if an interface goes down.
1922 // The controlling side has two interfaces and one will die. 1940 // The controlling side has two interfaces and one will die.
1923 TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) { 1941 TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) {
1942 rtc::ScopedFakeClock clock;
1924 // Adding alternate address will make sure |kPublicAddrs| has the higher 1943 // Adding alternate address will make sure |kPublicAddrs| has the higher
1925 // priority than others. This is due to FakeNetwork::AddInterface method. 1944 // priority than others. This is due to FakeNetwork::AddInterface method.
1926 AddAddress(0, kAlternateAddrs[0]); 1945 AddAddress(0, kAlternateAddrs[0]);
1927 AddAddress(0, kPublicAddrs[0]); 1946 AddAddress(0, kPublicAddrs[0]);
1928 AddAddress(1, kPublicAddrs[1]); 1947 AddAddress(1, kPublicAddrs[1]);
1929 1948
1930 // Use only local ports for simplicity. 1949 // Use only local ports for simplicity.
1931 SetAllocatorFlags(0, kOnlyLocalPorts); 1950 SetAllocatorFlags(0, kOnlyLocalPorts);
1932 SetAllocatorFlags(1, kOnlyLocalPorts); 1951 SetAllocatorFlags(1, kOnlyLocalPorts);
1933 1952
1934 // Create channels and let them go writable, as usual. 1953 // Create channels and let them go writable, as usual.
1935 CreateChannels(1); 1954 CreateChannels(1);
1936 EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() && 1955 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
1937 ep2_ch1()->receiving() && ep2_ch1()->writable(), 1956 ep2_ch1()->receiving() &&
1938 1000, 1000); 1957 ep2_ch1()->writable(),
1958 3000, clock);
1939 EXPECT_TRUE(ep1_ch1()->selected_connection() && 1959 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
1940 ep2_ch1()->selected_connection() && 1960 ep2_ch1()->selected_connection() &&
1941 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) && 1961 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
1942 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1])); 1962 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1943 1963
1944 // Make the receiving timeout shorter for testing. 1964 // Make the receiving timeout shorter for testing.
1945 IceConfig config = CreateIceConfig(1000, GATHER_ONCE); 1965 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
1946 ep1_ch1()->SetIceConfig(config); 1966 ep1_ch1()->SetIceConfig(config);
1947 ep2_ch1()->SetIceConfig(config); 1967 ep2_ch1()->SetIceConfig(config);
1948 1968
1949 // Blackhole any traffic to or from the public addrs. 1969 // Blackhole any traffic to or from the public addrs.
1950 LOG(LS_INFO) << "Failing over..."; 1970 LOG(LS_INFO) << "Failing over...";
1951 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]); 1971 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
1952 // The selected connections will switch, so keep references to them. 1972 // The selected connections will switch, so keep references to them.
1953 const Connection* selected_connection1 = ep1_ch1()->selected_connection(); 1973 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
1954 const Connection* selected_connection2 = ep2_ch1()->selected_connection(); 1974 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
1955 // We should detect loss of receiving within 1 second or so. 1975 // We should detect loss of receiving within 1 second or so.
1956 EXPECT_TRUE_WAIT( 1976 EXPECT_TRUE_SIMULATED_WAIT(
1957 !selected_connection1->receiving() && !selected_connection2->receiving(), 1977 !selected_connection1->receiving() && !selected_connection2->receiving(),
1958 3000); 1978 3000, clock);
1959 1979
1960 // We should switch over to use the alternate addr immediately on both sides 1980 // We should switch over to use the alternate addr on both sides
1961 // when we are not receiving. 1981 // when we are not receiving.
1962 EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection()->receiving() && 1982 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
1963 ep2_ch1()->selected_connection()->receiving(), 1983 ep2_ch1()->selected_connection()->receiving(),
1964 1000); 1984 3000, clock);
1965 EXPECT_TRUE( 1985 EXPECT_TRUE(
1966 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0])); 1986 LocalCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]));
1967 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1])); 1987 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
1968 EXPECT_TRUE( 1988 EXPECT_TRUE(
1969 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0])); 1989 RemoteCandidate(ep2_ch1())->address().EqualIPs(kAlternateAddrs[0]));
1970 1990
1971 DestroyChannels(); 1991 DestroyChannels();
1972 } 1992 }
1973 1993
1994 // Test that if an interface fails temporarily and then recovers quickly,
1995 // the selected connection will not switch.
1996 // The case that it will switch over to the backup connection if the selected
1997 // connection does not recover after enough time is covered in
1998 // TestFailoverControlledSide and TestFailoverControllingSide.
1999 TEST_F(P2PTransportChannelMultihomedTest,
2000 TestConnectionSwitchDampeningControlledSide) {
2001 rtc::ScopedFakeClock clock;
2002 AddAddress(0, kPublicAddrs[0]);
2003 // Adding alternate address will make sure |kPublicAddrs| has the higher
2004 // priority than others. This is due to FakeNetwork::AddInterface method.
2005 AddAddress(1, kAlternateAddrs[1]);
2006 AddAddress(1, kPublicAddrs[1]);
2007
2008 // Use only local ports for simplicity.
2009 SetAllocatorFlags(0, kOnlyLocalPorts);
2010 SetAllocatorFlags(1, kOnlyLocalPorts);
2011
2012 // Create channels and let them go writable, as usual.
2013 CreateChannels(1);
2014
2015 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2016 ep2_ch1()->receiving() &&
2017 ep2_ch1()->writable(),
2018 3000, clock);
2019 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2020 ep2_ch1()->selected_connection() &&
2021 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2022 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2023
2024 // Make the receiving timeout shorter for testing.
2025 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2026 ep1_ch1()->SetIceConfig(config);
2027 ep2_ch1()->SetIceConfig(config);
2028 reset_selected_candidate_pair_switches();
2029
2030 // Blackhole any traffic to or from the public addrs.
2031 LOG(LS_INFO) << "Failing over...";
2032 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[1]);
2033
2034 // The selected connections may switch, so keep references to them.
2035 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2036 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2037 // We should detect loss of receiving within 1 second or so.
2038 EXPECT_TRUE_SIMULATED_WAIT(
2039 !selected_connection1->receiving() && !selected_connection2->receiving(),
2040 3000, clock);
2041 // After a short while, the link recovers itself.
2042 SIMULATED_WAIT(false, 10, clock);
2043 fw()->ClearRules();
2044
2045 // We should remain on the public address on both sides and no connection
2046 // switches should have happened.
2047 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2048 ep2_ch1()->selected_connection()->receiving(),
2049 3000, clock);
2050 EXPECT_TRUE(RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2051 EXPECT_TRUE(LocalCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[1]));
2052 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2053
2054 DestroyChannels();
2055 }
2056
2057 // Test that if an interface fails temporarily and then recovers quickly,
2058 // the selected connection will not switch.
2059 TEST_F(P2PTransportChannelMultihomedTest,
2060 TestConnectionSwitchDampeningControllingSide) {
2061 rtc::ScopedFakeClock clock;
2062 // Adding alternate address will make sure |kPublicAddrs| has the higher
2063 // priority than others. This is due to FakeNetwork::AddInterface method.
2064 AddAddress(0, kAlternateAddrs[0]);
2065 AddAddress(0, kPublicAddrs[0]);
2066 AddAddress(1, kPublicAddrs[1]);
2067
2068 // Use only local ports for simplicity.
2069 SetAllocatorFlags(0, kOnlyLocalPorts);
2070 SetAllocatorFlags(1, kOnlyLocalPorts);
2071
2072 // Create channels and let them go writable, as usual.
2073 CreateChannels(1);
2074 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
2075 ep2_ch1()->receiving() &&
2076 ep2_ch1()->writable(),
2077 3000, clock);
2078 EXPECT_TRUE(ep1_ch1()->selected_connection() &&
2079 ep2_ch1()->selected_connection() &&
2080 LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
2081 RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
2082
2083 // Make the receiving timeout shorter for testing.
2084 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
2085 ep1_ch1()->SetIceConfig(config);
2086 ep2_ch1()->SetIceConfig(config);
2087 reset_selected_candidate_pair_switches();
2088
2089 // Blackhole any traffic to or from the public addrs.
2090 LOG(LS_INFO) << "Failing over...";
2091 fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, kPublicAddrs[0]);
2092 // The selected connections may switch, so keep references to them.
2093 const Connection* selected_connection1 = ep1_ch1()->selected_connection();
2094 const Connection* selected_connection2 = ep2_ch1()->selected_connection();
2095 // We should detect loss of receiving within 1 second or so.
2096 EXPECT_TRUE_SIMULATED_WAIT(
2097 !selected_connection1->receiving() && !selected_connection2->receiving(),
2098 3000, clock);
2099 // The link recovers after a short while.
2100 SIMULATED_WAIT(false, 10, clock);
2101 fw()->ClearRules();
2102
2103 // We should not switch to the alternate addr on both sides because of the
2104 // dampening.
2105 EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->selected_connection()->receiving() &&
2106 ep2_ch1()->selected_connection()->receiving(),
2107 3000, clock);
2108 EXPECT_TRUE(LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]));
2109 EXPECT_TRUE(RemoteCandidate(ep2_ch1())->address().EqualIPs(kPublicAddrs[0]));
2110 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
2111 DestroyChannels();
2112 }
2113
1974 // Tests that a Wifi-Wifi connection has the highest precedence. 2114 // Tests that a Wifi-Wifi connection has the highest precedence.
1975 TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) { 2115 TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
1976 // The interface names are chosen so that |cellular| would have higher 2116 // The interface names are chosen so that |cellular| would have higher
1977 // candidate priority if it is not for the network type. 2117 // candidate priority if it is not for the network type.
1978 auto& wifi = kAlternateAddrs; 2118 auto& wifi = kAlternateAddrs;
1979 auto& cellular = kPublicAddrs; 2119 auto& cellular = kPublicAddrs;
1980 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI); 2120 AddAddress(0, wifi[0], "test0", rtc::ADAPTER_TYPE_WIFI);
1981 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR); 2121 AddAddress(0, cellular[0], "test1", rtc::ADAPTER_TYPE_CELLULAR);
1982 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI); 2122 AddAddress(1, wifi[1], "test0", rtc::ADAPTER_TYPE_WIFI);
1983 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR); 2123 AddAddress(1, cellular[1], "test1", rtc::ADAPTER_TYPE_CELLULAR);
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 channel_state_ = channel->GetState(); 2581 channel_state_ = channel->GetState();
2442 } 2582 }
2443 2583
2444 CandidatePairInterface* last_selected_candidate_pair() { 2584 CandidatePairInterface* last_selected_candidate_pair() {
2445 return last_selected_candidate_pair_; 2585 return last_selected_candidate_pair_;
2446 } 2586 }
2447 int last_sent_packet_id() { return last_sent_packet_id_; } 2587 int last_sent_packet_id() { return last_sent_packet_id_; }
2448 bool channel_ready_to_send() { return channel_ready_to_send_; } 2588 bool channel_ready_to_send() { return channel_ready_to_send_; }
2449 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; } 2589 void reset_channel_ready_to_send() { channel_ready_to_send_ = false; }
2450 TransportChannelState channel_state() { return channel_state_; } 2590 TransportChannelState channel_state() { return channel_state_; }
2451 int get_and_reset_selected_candidate_pair_switches() { 2591 int reset_selected_candidate_pair_switches() {
2452 int switches = selected_candidate_pair_switches_; 2592 int switches = selected_candidate_pair_switches_;
2453 selected_candidate_pair_switches_ = 0; 2593 selected_candidate_pair_switches_ = 0;
2454 return switches; 2594 return switches;
2455 } 2595 }
2456 2596
2457 private: 2597 private:
2458 std::unique_ptr<rtc::PhysicalSocketServer> pss_; 2598 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
2459 std::unique_ptr<rtc::VirtualSocketServer> vss_; 2599 std::unique_ptr<rtc::VirtualSocketServer> vss_;
2460 rtc::SocketServerScope ss_scope_; 2600 rtc::SocketServerScope ss_scope_;
2461 CandidatePairInterface* last_selected_candidate_pair_ = nullptr; 2601 CandidatePairInterface* last_selected_candidate_pair_ = nullptr;
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
3048 ch.MaybeStartGathering(); 3188 ch.MaybeStartGathering();
3049 // The connections have decreasing priority. 3189 // The connections have decreasing priority.
3050 Connection* conn1 = 3190 Connection* conn1 =
3051 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true); 3191 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, true);
3052 ASSERT_TRUE(conn1 != nullptr); 3192 ASSERT_TRUE(conn1 != nullptr);
3053 Connection* conn2 = 3193 Connection* conn2 =
3054 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true); 3194 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, true);
3055 ASSERT_TRUE(conn2 != nullptr); 3195 ASSERT_TRUE(conn2 != nullptr);
3056 3196
3057 // Initially, connections are selected based on priority. 3197 // Initially, connections are selected based on priority.
3058 EXPECT_EQ(1, get_and_reset_selected_candidate_pair_switches()); 3198 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3059 EXPECT_EQ(conn1, last_selected_candidate_pair()); 3199 EXPECT_EQ(conn1, last_selected_candidate_pair());
3060 3200
3061 // conn2 receives data; it becomes selected. 3201 // conn2 receives data; it becomes selected.
3062 // Advance the clock by 1ms so that the last data receiving timestamp of 3202 // Advance the clock by 1ms so that the last data receiving timestamp of
3063 // conn2 is larger. 3203 // conn2 is larger.
3064 SIMULATED_WAIT(false, 1, clock); 3204 SIMULATED_WAIT(false, 1, clock);
3065 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0)); 3205 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3066 EXPECT_EQ(1, get_and_reset_selected_candidate_pair_switches()); 3206 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3067 EXPECT_EQ(conn2, last_selected_candidate_pair()); 3207 EXPECT_EQ(conn2, last_selected_candidate_pair());
3068 3208
3069 // conn1 also receives data; it becomes selected due to priority again. 3209 // conn1 also receives data; it becomes selected due to priority again.
3070 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0)); 3210 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3071 EXPECT_EQ(1, get_and_reset_selected_candidate_pair_switches()); 3211 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3072 EXPECT_EQ(conn1, last_selected_candidate_pair()); 3212 EXPECT_EQ(conn1, last_selected_candidate_pair());
3073 3213
3074 // Make sure sorting won't reselect candidate pair. 3214 // Make sure sorting won't reselect candidate pair.
3075 SIMULATED_WAIT(false, 10, clock); 3215 SIMULATED_WAIT(false, 10, clock);
3076 EXPECT_EQ(0, get_and_reset_selected_candidate_pair_switches()); 3216 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
3077 } 3217 }
3078 3218
3079 TEST_F(P2PTransportChannelPingTest, 3219 TEST_F(P2PTransportChannelPingTest,
3080 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) { 3220 TestControlledAgentNominationTakesHigherPrecedenceThanDataReceiving) {
3081 rtc::ScopedFakeClock clock; 3221 rtc::ScopedFakeClock clock;
3082 3222
3083 FakePortAllocator pa(rtc::Thread::Current(), nullptr); 3223 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3084 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa); 3224 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3085 PrepareChannel(&ch); 3225 PrepareChannel(&ch);
3086 ch.SetIceRole(ICEROLE_CONTROLLED); 3226 ch.SetIceRole(ICEROLE_CONTROLLED);
3087 ch.MaybeStartGathering(); 3227 ch.MaybeStartGathering();
3088 // The connections have decreasing priority. 3228 // The connections have decreasing priority.
3089 Connection* conn1 = 3229 Connection* conn1 =
3090 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false); 3230 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3091 ASSERT_TRUE(conn1 != nullptr); 3231 ASSERT_TRUE(conn1 != nullptr);
3092 Connection* conn2 = 3232 Connection* conn2 =
3093 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false); 3233 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false);
3094 ASSERT_TRUE(conn2 != nullptr); 3234 ASSERT_TRUE(conn2 != nullptr);
3095 3235
3096 // conn1 received data; it is the selected connection. 3236 // conn1 received data; it is the selected connection.
3097 // Advance the clock to have a non-zero last-data-receiving time. 3237 // Advance the clock to have a non-zero last-data-receiving time.
3098 SIMULATED_WAIT(false, 1, clock); 3238 SIMULATED_WAIT(false, 1, clock);
3099 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0)); 3239 conn1->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3100 EXPECT_EQ(1, get_and_reset_selected_candidate_pair_switches()); 3240 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3101 EXPECT_EQ(conn1, last_selected_candidate_pair()); 3241 EXPECT_EQ(conn1, last_selected_candidate_pair());
3102 3242
3103 // conn2 is nominated; it becomes the selected connection. 3243 // conn2 is nominated; it becomes the selected connection.
3104 NominateConnection(conn2); 3244 NominateConnection(conn2);
3105 EXPECT_EQ(1, get_and_reset_selected_candidate_pair_switches()); 3245 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3106 EXPECT_EQ(conn2, last_selected_candidate_pair()); 3246 EXPECT_EQ(conn2, last_selected_candidate_pair());
3107 3247
3108 NominateConnection(conn1); 3248 NominateConnection(conn1);
3109 EXPECT_EQ(1, get_and_reset_selected_candidate_pair_switches()); 3249 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3110 EXPECT_EQ(conn1, last_selected_candidate_pair()); 3250 EXPECT_EQ(conn1, last_selected_candidate_pair());
3111 3251
3112 // conn2 received data more recently; it is selected now because it 3252 // conn2 received data more recently; it is selected now because it
3113 // received data more recently. 3253 // received data more recently.
3114 SIMULATED_WAIT(false, 1, clock); 3254 SIMULATED_WAIT(false, 1, clock);
3115 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0)); 3255 conn2->OnReadPacket("XYZ", 3, rtc::CreatePacketTime(0));
3116 EXPECT_EQ(1, get_and_reset_selected_candidate_pair_switches()); 3256 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3117 EXPECT_EQ(conn2, last_selected_candidate_pair()); 3257 EXPECT_EQ(conn2, last_selected_candidate_pair());
3118 3258
3119 // Make sure sorting won't reselect candidate pair. 3259 // Make sure sorting won't reselect candidate pair.
3120 SIMULATED_WAIT(false, 10, clock); 3260 SIMULATED_WAIT(false, 10, clock);
3121 EXPECT_EQ(0, get_and_reset_selected_candidate_pair_switches()); 3261 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
3122 } 3262 }
3123 3263
3124 TEST_F(P2PTransportChannelPingTest, 3264 TEST_F(P2PTransportChannelPingTest,
3125 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) { 3265 TestControlledAgentWriteStateTakesHigherPrecedenceThanNomination) {
3126 rtc::ScopedFakeClock clock; 3266 rtc::ScopedFakeClock clock;
3127 3267
3128 FakePortAllocator pa(rtc::Thread::Current(), nullptr); 3268 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3129 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa); 3269 P2PTransportChannel ch("SwitchSelectedConnection", 1, &pa);
3130 PrepareChannel(&ch); 3270 PrepareChannel(&ch);
3131 ch.SetIceRole(ICEROLE_CONTROLLED); 3271 ch.SetIceRole(ICEROLE_CONTROLLED);
3132 ch.MaybeStartGathering(); 3272 ch.MaybeStartGathering();
3133 // The connections have decreasing priority. 3273 // The connections have decreasing priority.
3134 Connection* conn1 = 3274 Connection* conn1 =
3135 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false); 3275 CreateConnectionWithCandidate(ch, clock, "1.1.1.1", 1, 10, false);
3136 ASSERT_TRUE(conn1 != nullptr); 3276 ASSERT_TRUE(conn1 != nullptr);
3137 Connection* conn2 = 3277 Connection* conn2 =
3138 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false); 3278 CreateConnectionWithCandidate(ch, clock, "2.2.2.2", 2, 9, false);
3139 ASSERT_TRUE(conn2 != nullptr); 3279 ASSERT_TRUE(conn2 != nullptr);
3140 3280
3141 NominateConnection(conn1); 3281 NominateConnection(conn1);
3142 EXPECT_EQ(1, get_and_reset_selected_candidate_pair_switches()); 3282 EXPECT_EQ(1, reset_selected_candidate_pair_switches());
3143 3283
3144 // conn2 becomes writable; it is selected even though it is not nominated. 3284 // conn2 becomes writable; it is selected even though it is not nominated.
3145 conn2->ReceivedPingResponse(LOW_RTT); 3285 conn2->ReceivedPingResponse(LOW_RTT);
3146 3286
3147 EXPECT_EQ_SIMULATED_WAIT(1, get_and_reset_selected_candidate_pair_switches(), 3287 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
3148 kDefaultTimeout, clock); 3288 kDefaultTimeout, clock);
3149 EXPECT_EQ_SIMULATED_WAIT(conn2, last_selected_candidate_pair(), 3289 EXPECT_EQ_SIMULATED_WAIT(conn2, last_selected_candidate_pair(),
3150 kDefaultTimeout, clock); 3290 kDefaultTimeout, clock);
3151 3291
3152 // If conn1 is also writable, it will become selected. 3292 // If conn1 is also writable, it will become selected.
3153 conn1->ReceivedPingResponse(LOW_RTT); 3293 conn1->ReceivedPingResponse(LOW_RTT);
3154 EXPECT_EQ_SIMULATED_WAIT(1, get_and_reset_selected_candidate_pair_switches(), 3294 EXPECT_EQ_SIMULATED_WAIT(1, reset_selected_candidate_pair_switches(),
3155 kDefaultTimeout, clock); 3295 kDefaultTimeout, clock);
3156 EXPECT_EQ_SIMULATED_WAIT(conn1, last_selected_candidate_pair(), 3296 EXPECT_EQ_SIMULATED_WAIT(conn1, last_selected_candidate_pair(),
3157 kDefaultTimeout, clock); 3297 kDefaultTimeout, clock);
3158 3298
3159 // Make sure sorting won't reselect candidate pair. 3299 // Make sure sorting won't reselect candidate pair.
3160 SIMULATED_WAIT(false, 10, clock); 3300 SIMULATED_WAIT(false, 10, clock);
3161 EXPECT_EQ(0, get_and_reset_selected_candidate_pair_switches()); 3301 EXPECT_EQ(0, reset_selected_candidate_pair_switches());
3162 } 3302 }
3163 3303
3164 // Test that if a new remote candidate has the same address and port with 3304 // Test that if a new remote candidate has the same address and port with
3165 // an old one, it will be used to create a new connection. 3305 // an old one, it will be used to create a new connection.
3166 TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) { 3306 TEST_F(P2PTransportChannelPingTest, TestAddRemoteCandidateWithAddressReuse) {
3167 FakePortAllocator pa(rtc::Thread::Current(), nullptr); 3307 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3168 P2PTransportChannel ch("candidate reuse", 1, &pa); 3308 P2PTransportChannel ch("candidate reuse", 1, &pa);
3169 PrepareChannel(&ch); 3309 PrepareChannel(&ch);
3170 ch.MaybeStartGathering(); 3310 ch.MaybeStartGathering();
3171 const std::string host_address = "1.1.1.1"; 3311 const std::string host_address = "1.1.1.1";
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3282 // Need to wait until the channel state is updated. 3422 // Need to wait until the channel state is updated.
3283 EXPECT_EQ_WAIT(TransportChannelState::STATE_FAILED, ch.GetState(), 1000); 3423 EXPECT_EQ_WAIT(TransportChannelState::STATE_FAILED, ch.GetState(), 1000);
3284 } 3424 }
3285 3425
3286 // Test that when a low-priority connection is pruned, it is not deleted 3426 // Test that when a low-priority connection is pruned, it is not deleted
3287 // right away, and it can become active and be pruned again. 3427 // right away, and it can become active and be pruned again.
3288 TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) { 3428 TEST_F(P2PTransportChannelPingTest, TestConnectionPrunedAgain) {
3289 FakePortAllocator pa(rtc::Thread::Current(), nullptr); 3429 FakePortAllocator pa(rtc::Thread::Current(), nullptr);
3290 P2PTransportChannel ch("test channel", 1, &pa); 3430 P2PTransportChannel ch("test channel", 1, &pa);
3291 PrepareChannel(&ch); 3431 PrepareChannel(&ch);
3292 ch.SetIceConfig(CreateIceConfig(1000, GATHER_ONCE)); 3432 IceConfig config = CreateIceConfig(1000, GATHER_ONCE);
3433 config.receiving_switching_delay = rtc::Optional<int>(800);
3434 ch.SetIceConfig(config);
3293 ch.MaybeStartGathering(); 3435 ch.MaybeStartGathering();
3294 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100)); 3436 ch.AddRemoteCandidate(CreateUdpCandidate(LOCAL_PORT_TYPE, "1.1.1.1", 1, 100));
3295 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); 3437 Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1);
3296 ASSERT_TRUE(conn1 != nullptr); 3438 ASSERT_TRUE(conn1 != nullptr);
3297 EXPECT_EQ(conn1, ch.selected_connection()); 3439 EXPECT_EQ(conn1, ch.selected_connection());
3298 conn1->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving 3440 conn1->ReceivedPingResponse(LOW_RTT); // Becomes writable and receiving
3299 3441
3300 // Add a low-priority connection |conn2|, which will be pruned, but it will 3442 // Add a low-priority connection |conn2|, which will be pruned, but it will
3301 // not be deleted right away. Once the current selected connection becomes not 3443 // not be deleted right away. Once the current selected connection becomes not
3302 // receiving, |conn2| will start to ping and upon receiving the ping response, 3444 // receiving, |conn2| will start to ping and upon receiving the ping response,
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 3808
3667 // TCP Relay/Relay is the next. 3809 // TCP Relay/Relay is the next.
3668 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE, 3810 VerifyNextPingableConnection(RELAY_PORT_TYPE, RELAY_PORT_TYPE,
3669 TCP_PROTOCOL_NAME); 3811 TCP_PROTOCOL_NAME);
3670 3812
3671 // Finally, Local/Relay will be pinged. 3813 // Finally, Local/Relay will be pinged.
3672 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE); 3814 VerifyNextPingableConnection(LOCAL_PORT_TYPE, RELAY_PORT_TYPE);
3673 } 3815 }
3674 3816
3675 } // namespace cricket { 3817 } // namespace cricket {
OLDNEW
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.cc ('k') | webrtc/p2p/base/port.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698