diff --git a/pc/peerconnection_integrationtest.cc b/pc/peerconnection_integrationtest.cc index c1624083f9..21701cedde 100644 --- a/pc/peerconnection_integrationtest.cc +++ b/pc/peerconnection_integrationtest.cc @@ -31,6 +31,7 @@ #include "p2p/base/p2pconstants.h" #include "p2p/base/portinterface.h" #include "p2p/base/sessiondescription.h" +#include "p2p/base/teststunserver.h" #include "p2p/base/testturncustomizer.h" #include "p2p/base/testturnserver.h" #include "p2p/client/basicportallocator.h" @@ -45,6 +46,7 @@ #include "pc/test/fakevideotrackrenderer.h" #include "pc/test/mockpeerconnectionobservers.h" #include "rtc_base/fakenetwork.h" +#include "rtc_base/firewallsocketserver.h" #include "rtc_base/gunit.h" #include "rtc_base/virtualsocketserver.h" #include "test/gmock.h" @@ -55,6 +57,9 @@ using cricket::FakeWebRtcVideoDecoderFactory; using cricket::FakeWebRtcVideoEncoder; using cricket::FakeWebRtcVideoEncoderFactory; using cricket::MediaContentDescription; +using rtc::SocketAddress; +using ::testing::ElementsAre; +using ::testing::Values; using webrtc::DataBuffer; using webrtc::DataChannelInterface; using webrtc::DtmfSender; @@ -94,6 +99,8 @@ static const char kDataChannelLabel[] = "data_channel"; static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_32; static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM; +static const SocketAddress kDefaultLocalAddress("192.168.1.1", 0); + // Helper function for constructing offer/answer options to initiate an ICE // restart. PeerConnectionInterface::RTCOfferAnswerOptions IceRestartOfferAnswerOptions() { @@ -277,10 +284,16 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, generated_sdp_munger_ = munger; } - // Number of times the gathering state has transitioned to "gathering". - // Useful for telling if an ICE restart occurred as expected. - int transitions_to_gathering_state() const { - return transitions_to_gathering_state_; + // Every ICE connection state in order that has been seen by the observer. + std::vector + ice_connection_state_history() const { + return ice_connection_state_history_; + } + + // Every ICE gathering state in order that has been seen by the observer. + std::vector + ice_gathering_state_history() const { + return ice_gathering_state_history_; } // TODO(deadbeef): Switch the majority of these tests to use AddTrack instead @@ -538,6 +551,11 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, } } + rtc::FakeNetworkManager* network() const { + return fake_network_manager_.get(); + } + cricket::PortAllocator* port_allocator() const { return port_allocator_; } + private: explicit PeerConnectionWrapper(const std::string& debug_name) : debug_name_(debug_name) {} @@ -554,10 +572,11 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, RTC_DCHECK(!peer_connection_factory_); fake_network_manager_.reset(new rtc::FakeNetworkManager()); - fake_network_manager_->AddInterface(rtc::SocketAddress("192.168.1.1", 0)); + fake_network_manager_->AddInterface(kDefaultLocalAddress); std::unique_ptr port_allocator( new cricket::BasicPortAllocator(fake_network_manager_.get())); + port_allocator_ = port_allocator.get(); fake_audio_capture_module_ = FakeAudioCaptureModule::Create(); if (!fake_audio_capture_module_) { return false; @@ -612,6 +631,10 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; } + void set_signal_ice_candidates(bool signal) { + signal_ice_candidates_ = signal; + } + void EnableVideoDecoderFactory() { video_decoder_factory_enabled_ = true; fake_video_decoder_factory_->AddSupportedVideoCodecType( @@ -818,20 +841,19 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, void OnIceConnectionChange( webrtc::PeerConnectionInterface::IceConnectionState new_state) override { EXPECT_EQ(pc()->ice_connection_state(), new_state); + ice_connection_state_history_.push_back(new_state); } void OnIceGatheringChange( webrtc::PeerConnectionInterface::IceGatheringState new_state) override { - if (new_state == PeerConnectionInterface::kIceGatheringGathering) { - ++transitions_to_gathering_state_; - } EXPECT_EQ(pc()->ice_gathering_state(), new_state); + ice_gathering_state_history_.push_back(new_state); } void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override { LOG(LS_INFO) << debug_name_ << ": OnIceCandidate"; std::string ice_sdp; EXPECT_TRUE(candidate->ToString(&ice_sdp)); - if (signaling_message_receiver_ == nullptr) { + if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) { // Remote party may be deleted. return; } @@ -886,6 +908,7 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, rtc::scoped_refptr peer_connection_factory_; + cricket::PortAllocator* port_allocator_; // Needed to keep track of number of frames sent. rtc::scoped_refptr fake_audio_capture_module_; // Needed to keep track of number of frames received. @@ -903,6 +926,7 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, // For remote peer communication. SignalingMessageReceiver* signaling_message_receiver_ = nullptr; int signaling_delay_ms_ = 0; + bool signal_ice_candidates_ = true; // Store references to the video capturers we've created, so that we can stop // them, if required. @@ -919,7 +943,10 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, std::vector> rtp_receiver_observers_; - int transitions_to_gathering_state_ = 0; + std::vector + ice_connection_state_history_; + std::vector + ice_gathering_state_history_; rtc::AsyncInvoker invoker_; @@ -941,7 +968,8 @@ class PeerConnectionIntegrationTest : public testing::Test { public: PeerConnectionIntegrationTest() : ss_(new rtc::VirtualSocketServer()), - network_thread_(new rtc::Thread(ss_.get())), + fss_(new rtc::FirewallSocketServer(ss_.get())), + network_thread_(new rtc::Thread(fss_.get())), worker_thread_(rtc::Thread::Create()) { RTC_CHECK(network_thread_->Start()); RTC_CHECK(worker_thread_->Start()); @@ -1030,11 +1058,24 @@ class PeerConnectionIntegrationTest : public testing::Test { callee_->set_signaling_message_receiver(caller_.get()); } + // Once called, SDP blobs will be automatically signaled between + // PeerConnections. Note that ICE candidates will not be signaled unless they + // are in the exchanged SDP blobs. + void ConnectFakeSignalingForSdpOnly() { + ConnectFakeSignaling(); + SetSignalIceCandidates(false); + } + void SetSignalingDelayMs(int delay_ms) { caller_->set_signaling_delay_ms(delay_ms); callee_->set_signaling_delay_ms(delay_ms); } + void SetSignalIceCandidates(bool signal) { + caller_->set_signal_ice_candidates(signal); + callee_->set_signal_ice_candidates(signal); + } + void EnableVideoDecoderFactory() { caller_->EnableVideoDecoderFactory(); callee_->EnableVideoDecoderFactory(); @@ -1076,6 +1117,8 @@ class PeerConnectionIntegrationTest : public testing::Test { return old; } + rtc::FirewallSocketServer* firewall() const { return fss_.get(); } + // Expects the provided number of new frames to be received within |wait_ms|. // "New frames" meaning that it waits for the current frame counts to // *increase* by the provided values. For video, uses @@ -1146,6 +1189,7 @@ class PeerConnectionIntegrationTest : public testing::Test { private: // |ss_| is used by |network_thread_| so it must be destroyed later. std::unique_ptr ss_; + std::unique_ptr fss_; // |network_thread_| and |worker_thread_| are used by both // |caller_| and |callee_| so they must be destroyed // later. @@ -2720,6 +2764,207 @@ TEST_F(PeerConnectionIntegrationTest, IceStatesReachCompletion) { callee()->ice_connection_state(), kDefaultTimeout); } +// Test that firewalling the ICE connection causes the clients to identify the +// disconnected state and then removing the firewall causes them to reconnect. +class PeerConnectionIntegrationIceStatesTest + : public PeerConnectionIntegrationTest, + public ::testing::WithParamInterface> { + protected: + PeerConnectionIntegrationIceStatesTest() { + port_allocator_flags_ = std::get<1>(GetParam()); + } + + void StartStunServer(const SocketAddress& server_address) { + stun_server_.reset( + cricket::TestStunServer::Create(network_thread(), server_address)); + } + + bool TestIPv6() { + return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6); + } + + void SetPortAllocatorFlags() { + caller()->port_allocator()->set_flags(port_allocator_flags_); + callee()->port_allocator()->set_flags(port_allocator_flags_); + } + + std::vector CallerAddresses() { + std::vector addresses; + addresses.push_back(SocketAddress("1.1.1.1", 0)); + if (TestIPv6()) { + addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0)); + } + return addresses; + } + + std::vector CalleeAddresses() { + std::vector addresses; + addresses.push_back(SocketAddress("2.2.2.2", 0)); + if (TestIPv6()) { + addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0)); + } + return addresses; + } + + void SetUpNetworkInterfaces() { + // Remove the default interfaces added by the test infrastructure. + caller()->network()->RemoveInterface(kDefaultLocalAddress); + callee()->network()->RemoveInterface(kDefaultLocalAddress); + + // Add network addresses for test. + for (const auto& caller_address : CallerAddresses()) { + caller()->network()->AddInterface(caller_address); + } + for (const auto& callee_address : CalleeAddresses()) { + callee()->network()->AddInterface(callee_address); + } + } + + private: + uint32_t port_allocator_flags_; + std::unique_ptr stun_server_; +}; + +// Tests that the PeerConnection goes through all the ICE gathering/connection +// states over the duration of the call. This includes Disconnected and Failed +// states, induced by putting a firewall between the peers and waiting for them +// to time out. +TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyIceStates) { + rtc::ScopedFakeClock fake_clock; + // Some things use a time of "0" as a special value, so we need to start out + // the fake clock at a nonzero time. + // TODO(deadbeef): Fix this. + fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1)); + + const SocketAddress kStunServerAddress = + SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT); + StartStunServer(kStunServerAddress); + + PeerConnectionInterface::RTCConfiguration config; + PeerConnectionInterface::IceServer ice_stun_server; + ice_stun_server.urls.push_back( + "stun:" + kStunServerAddress.HostAsURIString() + ":" + + kStunServerAddress.PortAsString()); + config.servers.push_back(ice_stun_server); + + ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config)); + ConnectFakeSignaling(); + SetPortAllocatorFlags(); + SetUpNetworkInterfaces(); + caller()->AddAudioVideoMediaStream(); + callee()->AddAudioVideoMediaStream(); + + // Initial state before anything happens. + ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew, + caller()->ice_gathering_state()); + ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew, + caller()->ice_connection_state()); + + // Start the call by creating the offer, setting it as the local description, + // then sending it to the peer who will respond with an answer. This happens + // asynchronously so that we can watch the states as it runs in the + // background. + caller()->CreateAndSetAndSignalOffer(); + + ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted, + caller()->ice_connection_state(), kDefaultTimeout, + fake_clock); + + // Verify that the observer was notified of the intermediate transitions. + EXPECT_THAT(caller()->ice_connection_state_history(), + ElementsAre(PeerConnectionInterface::kIceConnectionChecking, + PeerConnectionInterface::kIceConnectionConnected, + PeerConnectionInterface::kIceConnectionCompleted)); + EXPECT_THAT(caller()->ice_gathering_state_history(), + ElementsAre(PeerConnectionInterface::kIceGatheringGathering, + PeerConnectionInterface::kIceGatheringComplete)); + + // Block connections to/from the caller and wait for ICE to become + // disconnected. + for (const auto& caller_address : CallerAddresses()) { + firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address); + } + LOG(LS_INFO) << "Firewall rules applied"; + ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected, + caller()->ice_connection_state(), kDefaultTimeout, + fake_clock); + + // Let ICE re-establish by removing the firewall rules. + firewall()->ClearRules(); + LOG(LS_INFO) << "Firewall rules cleared"; + ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted, + caller()->ice_connection_state(), kDefaultTimeout, + fake_clock); + + // According to RFC7675, if there is no response within 30 seconds then the + // peer should consider the other side to have rejected the connection. This + // is signalled by the state transitioning to "failed". + constexpr int kConsentTimeout = 30000; + for (const auto& caller_address : CallerAddresses()) { + firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address); + } + LOG(LS_INFO) << "Firewall rules applied again"; + ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed, + caller()->ice_connection_state(), kConsentTimeout, + fake_clock); +} + +// Tests that the best connection is set to the appropriate IPv4/IPv6 connection +// and that the statistics in the metric observers are updated correctly. +TEST_P(PeerConnectionIntegrationIceStatesTest, VerifyBestConnection) { + ASSERT_TRUE(CreatePeerConnectionWrappers()); + ConnectFakeSignaling(); + SetPortAllocatorFlags(); + SetUpNetworkInterfaces(); + caller()->AddAudioVideoMediaStream(); + callee()->AddAudioVideoMediaStream(); + + rtc::scoped_refptr metrics_observer( + new rtc::RefCountedObject()); + caller()->pc()->RegisterUMAObserver(metrics_observer.get()); + + caller()->CreateAndSetAndSignalOffer(); + + ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); + + const int num_best_ipv4 = metrics_observer->GetEnumCounter( + webrtc::kEnumCounterAddressFamily, webrtc::kBestConnections_IPv4); + const int num_best_ipv6 = metrics_observer->GetEnumCounter( + webrtc::kEnumCounterAddressFamily, webrtc::kBestConnections_IPv6); + if (TestIPv6()) { + // When IPv6 is enabled, we should prefer an IPv6 connection over an IPv4 + // connection. + EXPECT_EQ(0u, num_best_ipv4); + EXPECT_EQ(1u, num_best_ipv6); + } else { + EXPECT_EQ(1u, num_best_ipv4); + EXPECT_EQ(0u, num_best_ipv6); + } + + EXPECT_EQ(0u, metrics_observer->GetEnumCounter( + webrtc::kEnumCounterIceCandidatePairTypeUdp, + webrtc::kIceCandidatePairHostHost)); + EXPECT_EQ(1u, metrics_observer->GetEnumCounter( + webrtc::kEnumCounterIceCandidatePairTypeUdp, + webrtc::kIceCandidatePairHostPublicHostPublic)); +} + +constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP | + cricket::PORTALLOCATOR_DISABLE_STUN | + cricket::PORTALLOCATOR_DISABLE_RELAY; +constexpr uint32_t kFlagsIPv6NoStun = + cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN | + cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY; +constexpr uint32_t kFlagsIPv4Stun = + cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY; + +INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest, + PeerConnectionIntegrationIceStatesTest, + Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun), + std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun), + std::make_pair("IPv4 with STUN", + kFlagsIPv4Stun))); + // This test sets up a call between two parties with audio and video. // During the call, the caller restarts ICE and the test verifies that // new ICE candidates are generated and audio and video still can flow, and the @@ -3232,6 +3477,38 @@ TEST_F(PeerConnectionIntegrationTest, RtcEventLogOutputWriteCalled) { ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); } +// Test that if candidates are only signaled by applying full session +// descriptions (instead of using AddIceCandidate), the peers can connect to +// each other and exchange media. +TEST_F(PeerConnectionIntegrationTest, MediaFlowsWhenCandidatesSetOnlyInSdp) { + ASSERT_TRUE(CreatePeerConnectionWrappers()); + // Each side will signal the session descriptions but not candidates. + ConnectFakeSignalingForSdpOnly(); + + // Add audio video track and exchange the initial offer/answer with media + // information only. This will start ICE gathering on each side. + caller()->AddAudioVideoMediaStream(); + callee()->AddAudioVideoMediaStream(); + caller()->CreateAndSetAndSignalOffer(); + + // Wait for all candidates to be gathered on both the caller and callee. + ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete, + caller()->ice_gathering_state(), kDefaultTimeout); + ASSERT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete, + callee()->ice_gathering_state(), kDefaultTimeout); + + // The candidates will now be included in the session description, so + // signaling them will start the ICE connection. + caller()->CreateAndSetAndSignalOffer(); + ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); + + // Ensure that media flows in both directions. + ExpectNewFramesReceivedWithWait( + kDefaultExpectedAudioFrameCount, kDefaultExpectedVideoFrameCount, + kDefaultExpectedAudioFrameCount, kDefaultExpectedVideoFrameCount, + kMaxWaitForFramesMs); +} + } // namespace #endif // if !defined(THREAD_SANITIZER) diff --git a/pc/webrtcsession_unittest.cc b/pc/webrtcsession_unittest.cc index a1c709cdb5..25cb35a6a9 100644 --- a/pc/webrtcsession_unittest.cc +++ b/pc/webrtcsession_unittest.cc @@ -77,9 +77,6 @@ typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions; static const int kClientAddrPort = 0; static const char kClientAddrHost1[] = "11.11.11.11"; -static const char kClientIPv6AddrHost1[] = - "2620:0:aaaa:bbbb:cccc:dddd:eeee:ffff"; -static const char kClientAddrHost2[] = "22.22.22.22"; static const char kStunAddrHost[] = "99.99.99.1"; static const char kSessionVersion[] = "1"; @@ -370,9 +367,6 @@ class WebRtcSessionTest void AddInterface(const SocketAddress& addr) { network_manager_.AddInterface(addr); } - void RemoveInterface(const SocketAddress& addr) { - network_manager_.RemoveInterface(addr); - } // If |cert_generator| != null or |rtc_configuration| contains |certificates| // then DTLS will be enabled unless explicitly disabled by |rtc_configuration| @@ -1057,99 +1051,6 @@ class WebRtcSessionTest } return false; } - // Helper class to configure loopback network and verify Best - // Connection using right IP protocol for TestLoopbackCall - // method. LoopbackNetworkManager applies firewall rules to block - // all ping traffic once ICE completed, and remove them to observe - // ICE reconnected again. This LoopbackNetworkConfiguration struct - // verifies the best connection is using the right IP protocol after - // initial ICE convergences. - - class LoopbackNetworkConfiguration { - public: - LoopbackNetworkConfiguration() - : test_ipv6_network_(false), - test_extra_ipv4_network_(false), - best_connection_after_initial_ice_converged_(1, 0) {} - - // Used to track the expected best connection count in each IP protocol. - struct ExpectedBestConnection { - ExpectedBestConnection(int ipv4_count, int ipv6_count) - : ipv4_count_(ipv4_count), - ipv6_count_(ipv6_count) {} - - int ipv4_count_; - int ipv6_count_; - }; - - bool test_ipv6_network_; - bool test_extra_ipv4_network_; - ExpectedBestConnection best_connection_after_initial_ice_converged_; - - void VerifyBestConnectionAfterIceConverge( - const rtc::scoped_refptr metrics_observer) const { - Verify(metrics_observer, best_connection_after_initial_ice_converged_); - } - - private: - void Verify(const rtc::scoped_refptr metrics_observer, - const ExpectedBestConnection& expected) const { - EXPECT_EQ( - metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily, - webrtc::kBestConnections_IPv4), - expected.ipv4_count_); - EXPECT_EQ( - metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily, - webrtc::kBestConnections_IPv6), - expected.ipv6_count_); - // This is used in the loopback call so there is only single host to host - // candidate pair. - EXPECT_EQ(metrics_observer->GetEnumCounter( - webrtc::kEnumCounterIceCandidatePairTypeUdp, - webrtc::kIceCandidatePairHostHost), - 0); - EXPECT_EQ(metrics_observer->GetEnumCounter( - webrtc::kEnumCounterIceCandidatePairTypeUdp, - webrtc::kIceCandidatePairHostPublicHostPublic), - 1); - } - }; - - class LoopbackNetworkManager { - public: - LoopbackNetworkManager(WebRtcSessionTest* session, - const LoopbackNetworkConfiguration& config) - : config_(config) { - session->AddInterface( - rtc::SocketAddress(kClientAddrHost1, kClientAddrPort)); - if (config_.test_extra_ipv4_network_) { - session->AddInterface( - rtc::SocketAddress(kClientAddrHost2, kClientAddrPort)); - } - if (config_.test_ipv6_network_) { - session->AddInterface( - rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort)); - } - } - - void ApplyFirewallRules(rtc::FirewallSocketServer* fss) { - fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, - rtc::SocketAddress(kClientAddrHost1, kClientAddrPort)); - if (config_.test_extra_ipv4_network_) { - fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, - rtc::SocketAddress(kClientAddrHost2, kClientAddrPort)); - } - if (config_.test_ipv6_network_) { - fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, - rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort)); - } - } - - void ClearRules(rtc::FirewallSocketServer* fss) { fss->ClearRules(); } - - private: - LoopbackNetworkConfiguration config_; - }; // The method sets up a call from the session to itself, in a loopback // arrangement. It also uses a firewall rule to create a temporary @@ -1195,50 +1096,8 @@ class WebRtcSessionTest observer_.ice_connection_state_, kIceCandidatesTimeout); } - void TestLoopbackCall(const LoopbackNetworkConfiguration& config) { - LoopbackNetworkManager loopback_network_manager(this, config); - SetupLoopbackCall(); - config.VerifyBestConnectionAfterIceConverge(metrics_observer_); - // Adding firewall rule to block ping requests, which should cause - // transport channel failure. - - loopback_network_manager.ApplyFirewallRules(fss_.get()); - - LOG(LS_INFO) << "Firewall Rules applied"; - EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected, - observer_.ice_connection_state_, - kIceCandidatesTimeout); - - metrics_observer_->Reset(); - - // Clearing the rules, session should move back to completed state. - loopback_network_manager.ClearRules(fss_.get()); - - LOG(LS_INFO) << "Firewall Rules cleared"; - EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted, - observer_.ice_connection_state_, - kIceCandidatesTimeout); - - // Now we block ping requests and wait until the ICE connection transitions - // to the Failed state. This will take at least 30 seconds because it must - // wait for the Port to timeout. - int port_timeout = 30000; - - loopback_network_manager.ApplyFirewallRules(fss_.get()); - LOG(LS_INFO) << "Firewall Rules applied again"; - EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected, - observer_.ice_connection_state_, - kIceCandidatesTimeout + port_timeout); - } - - void TestLoopbackCall() { - LoopbackNetworkConfiguration config; - TestLoopbackCall(config); - } - void TestPacketOptions() { - LoopbackNetworkConfiguration config; - LoopbackNetworkManager loopback_network_manager(this, config); + AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort)); SetupLoopbackCall(); @@ -2481,8 +2340,7 @@ TEST_F(WebRtcSessionTest, TestMaxBundleWithSetRemoteDescriptionFirst) { // disconnected non-bundle transport and then replacing it. The application // should not receive any changes in the ICE state. TEST_F(WebRtcSessionTest, TestAddChannelToConnectedBundle) { - LoopbackNetworkConfiguration config; - LoopbackNetworkManager loopback_network_manager(this, config); + AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort)); // Both BUNDLE and RTCP-mux need to be enabled for the ICE state to remain // connected. Disabling either of these two means that we need to wait for the // answer to find out if more transports are needed. @@ -2721,37 +2579,6 @@ TEST_F(WebRtcSessionTest, TestSessionContentError) { SetLocalDescriptionExpectError("", "ERROR_CONTENT", offer); } -// Runs the loopback call test with BUNDLE and STUN disabled. -TEST_F(WebRtcSessionTest, TestIceStatesBasic) { - // Lets try with only UDP ports. - allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP | - cricket::PORTALLOCATOR_DISABLE_STUN | - cricket::PORTALLOCATOR_DISABLE_RELAY); - TestLoopbackCall(); -} - -TEST_F(WebRtcSessionTest, TestIceStatesBasicIPv6) { - allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP | - cricket::PORTALLOCATOR_DISABLE_STUN | - cricket::PORTALLOCATOR_ENABLE_IPV6 | - cricket::PORTALLOCATOR_DISABLE_RELAY); - - // best connection is IPv6 since it has higher network preference. - LoopbackNetworkConfiguration config; - config.test_ipv6_network_ = true; - config.best_connection_after_initial_ice_converged_ = - LoopbackNetworkConfiguration::ExpectedBestConnection(0, 1); - - TestLoopbackCall(config); -} - -// Runs the loopback call test with BUNDLE and STUN enabled. -TEST_F(WebRtcSessionTest, TestIceStatesBundle) { - allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP | - cricket::PORTALLOCATOR_DISABLE_RELAY); - TestLoopbackCall(); -} - TEST_F(WebRtcSessionTest, TestRtpDataChannel) { configuration_.enable_rtp_data_channel = true; Init(); @@ -2945,64 +2772,6 @@ TEST_F(WebRtcSessionTest, TestCombinedAudioVideoBweConstraint) { EXPECT_EQ(rtc::Optional(true), audio_options.combined_audio_video_bwe); } -// Tests that we can renegotiate new media content with ICE candidates in the -// new remote SDP. -TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) { - InitWithDtls(GetParam()); - SetFactoryDtlsSrtp(); - - SendAudioOnlyStream2(); - SessionDescriptionInterface* offer = CreateOffer(); - SetLocalDescriptionWithoutError(offer); - - SessionDescriptionInterface* answer = CreateRemoteAnswer(offer); - SetRemoteDescriptionWithoutError(answer); - - cricket::MediaSessionOptions options; - GetOptionsForRemoteOffer(&options); - offer = CreateRemoteOffer(options, cricket::SEC_DISABLED); - - cricket::Candidate candidate1; - candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000)); - candidate1.set_component(1); - JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1, - candidate1); - EXPECT_TRUE(offer->AddCandidate(&ice_candidate)); - SetRemoteDescriptionWithoutError(offer); - - answer = CreateAnswer(); - SetLocalDescriptionWithoutError(answer); -} - -// Tests that we can renegotiate new media content with ICE candidates separated -// from the remote SDP. -TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) { - InitWithDtls(GetParam()); - SetFactoryDtlsSrtp(); - - SendAudioOnlyStream2(); - SessionDescriptionInterface* offer = CreateOffer(); - SetLocalDescriptionWithoutError(offer); - - SessionDescriptionInterface* answer = CreateRemoteAnswer(offer); - SetRemoteDescriptionWithoutError(answer); - - cricket::MediaSessionOptions options; - GetOptionsForRemoteOffer(&options); - offer = CreateRemoteOffer(options, cricket::SEC_DISABLED); - SetRemoteDescriptionWithoutError(offer); - - cricket::Candidate candidate1; - candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000)); - candidate1.set_component(1); - JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1, - candidate1); - EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate)); - - answer = CreateAnswer(); - SetLocalDescriptionWithoutError(answer); -} - #ifdef HAVE_QUIC TEST_P(WebRtcSessionTest, TestNegotiateQuic) { configuration_.enable_quic = true;