xref: /aosp_15_r20/external/webrtc/pc/peer_connection_ice_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #include <memory>
15 #include <string>
16 #include <tuple>
17 #include <type_traits>
18 #include <utility>
19 #include <vector>
20 
21 #include "absl/types/optional.h"
22 #include "api/audio/audio_mixer.h"
23 #include "api/candidate.h"
24 #include "api/ice_transport_interface.h"
25 #include "api/jsep.h"
26 #include "api/media_types.h"
27 #include "api/peer_connection_interface.h"
28 #include "api/rtc_error.h"
29 #include "api/scoped_refptr.h"
30 #include "modules/audio_device/include/audio_device.h"
31 #include "modules/audio_processing/include/audio_processing.h"
32 #include "p2p/base/fake_port_allocator.h"
33 #include "p2p/base/ice_transport_internal.h"
34 #include "p2p/base/p2p_constants.h"
35 #include "p2p/base/port.h"
36 #include "p2p/base/port_allocator.h"
37 #include "p2p/base/transport_description.h"
38 #include "p2p/base/transport_info.h"
39 #include "p2p/client/basic_port_allocator.h"
40 #include "pc/channel_interface.h"
41 #include "pc/dtls_transport.h"
42 #include "pc/media_session.h"
43 #include "pc/peer_connection.h"
44 #include "pc/peer_connection_wrapper.h"
45 #include "pc/rtp_transceiver.h"
46 #include "pc/sdp_utils.h"
47 #include "pc/session_description.h"
48 #include "rtc_base/checks.h"
49 #include "rtc_base/internal/default_socket_server.h"
50 #include "rtc_base/ip_address.h"
51 #include "rtc_base/logging.h"
52 #include "rtc_base/net_helper.h"
53 #include "rtc_base/rtc_certificate_generator.h"
54 #include "rtc_base/socket_address.h"
55 #include "rtc_base/thread.h"
56 #include "test/gtest.h"
57 #ifdef WEBRTC_ANDROID
58 #include "pc/test/android_test_initializer.h"
59 #endif
60 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
61 #include "api/audio_codecs/builtin_audio_encoder_factory.h"
62 #include "api/create_peerconnection_factory.h"
63 #include "api/uma_metrics.h"
64 #include "api/video_codecs/builtin_video_decoder_factory.h"
65 #include "api/video_codecs/builtin_video_encoder_factory.h"
66 #include "pc/peer_connection_proxy.h"
67 #include "pc/test/fake_audio_capture_module.h"
68 #include "pc/test/mock_peer_connection_observers.h"
69 #include "rtc_base/fake_network.h"
70 #include "rtc_base/gunit.h"
71 #include "rtc_base/strings/string_builder.h"
72 #include "rtc_base/virtual_socket_server.h"
73 #include "system_wrappers/include/metrics.h"
74 #include "test/gmock.h"
75 
76 namespace webrtc {
77 
78 using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
79 using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
80 using rtc::SocketAddress;
81 using ::testing::Combine;
82 using ::testing::ElementsAre;
83 using ::testing::Pair;
84 using ::testing::Values;
85 
86 constexpr int kIceCandidatesTimeout = 10000;
87 constexpr int64_t kWaitTimeout = 10000;
88 constexpr uint64_t kTiebreakerDefault = 44444;
89 
90 class PeerConnectionWrapperForIceTest : public PeerConnectionWrapper {
91  public:
92   using PeerConnectionWrapper::PeerConnectionWrapper;
93 
CreateJsepCandidateForFirstTransport(cricket::Candidate * candidate)94   std::unique_ptr<IceCandidateInterface> CreateJsepCandidateForFirstTransport(
95       cricket::Candidate* candidate) {
96     RTC_DCHECK(pc()->remote_description());
97     const auto* desc = pc()->remote_description()->description();
98     RTC_DCHECK(desc->contents().size() > 0);
99     const auto& first_content = desc->contents()[0];
100     candidate->set_transport_name(first_content.name);
101     return CreateIceCandidate(first_content.name, -1, *candidate);
102   }
103 
104   // Adds a new ICE candidate to the first transport.
AddIceCandidate(cricket::Candidate * candidate)105   bool AddIceCandidate(cricket::Candidate* candidate) {
106     return pc()->AddIceCandidate(
107         CreateJsepCandidateForFirstTransport(candidate).get());
108   }
109 
110   // Returns ICE candidates from the remote session description.
111   std::vector<const IceCandidateInterface*>
GetIceCandidatesFromRemoteDescription()112   GetIceCandidatesFromRemoteDescription() {
113     const SessionDescriptionInterface* sdesc = pc()->remote_description();
114     RTC_DCHECK(sdesc);
115     std::vector<const IceCandidateInterface*> candidates;
116     for (size_t mline_index = 0; mline_index < sdesc->number_of_mediasections();
117          mline_index++) {
118       const auto* candidate_collection = sdesc->candidates(mline_index);
119       for (size_t i = 0; i < candidate_collection->count(); i++) {
120         candidates.push_back(candidate_collection->at(i));
121       }
122     }
123     return candidates;
124   }
125 
network()126   rtc::FakeNetworkManager* network() { return network_; }
127 
set_network(rtc::FakeNetworkManager * network)128   void set_network(rtc::FakeNetworkManager* network) { network_ = network; }
129 
130   // The port allocator used by this PC.
131   cricket::PortAllocator* port_allocator_;
132 
133  private:
134   rtc::FakeNetworkManager* network_;
135 };
136 
137 class PeerConnectionIceBaseTest : public ::testing::Test {
138  protected:
139   typedef std::unique_ptr<PeerConnectionWrapperForIceTest> WrapperPtr;
140 
PeerConnectionIceBaseTest(SdpSemantics sdp_semantics)141   explicit PeerConnectionIceBaseTest(SdpSemantics sdp_semantics)
142       : vss_(new rtc::VirtualSocketServer()),
143         main_(vss_.get()),
144         sdp_semantics_(sdp_semantics) {
145 #ifdef WEBRTC_ANDROID
146     InitializeAndroidObjects();
147 #endif
148     pc_factory_ = CreatePeerConnectionFactory(
149         rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
150         rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
151         CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
152         CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(),
153         nullptr /* audio_mixer */, nullptr /* audio_processing */);
154   }
155 
CreatePeerConnection()156   WrapperPtr CreatePeerConnection() {
157     return CreatePeerConnection(RTCConfiguration());
158   }
159 
CreatePeerConnection(const RTCConfiguration & config)160   WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
161     auto* fake_network = NewFakeNetwork();
162     auto port_allocator = std::make_unique<cricket::BasicPortAllocator>(
163         fake_network,
164         std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get()));
165     port_allocator->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
166                               cricket::PORTALLOCATOR_DISABLE_RELAY);
167     port_allocator->set_step_delay(cricket::kMinimumStepDelay);
168     RTCConfiguration modified_config = config;
169     modified_config.sdp_semantics = sdp_semantics_;
170     auto observer = std::make_unique<MockPeerConnectionObserver>();
171     auto port_allocator_copy = port_allocator.get();
172     PeerConnectionDependencies pc_dependencies(observer.get());
173     pc_dependencies.allocator = std::move(port_allocator);
174     auto result = pc_factory_->CreatePeerConnectionOrError(
175         modified_config, std::move(pc_dependencies));
176     if (!result.ok()) {
177       return nullptr;
178     }
179 
180     observer->SetPeerConnectionInterface(result.value().get());
181     auto wrapper = std::make_unique<PeerConnectionWrapperForIceTest>(
182         pc_factory_, result.MoveValue(), std::move(observer));
183     wrapper->set_network(fake_network);
184     wrapper->port_allocator_ = port_allocator_copy;
185     return wrapper;
186   }
187 
188   // Accepts the same arguments as CreatePeerConnection and adds default audio
189   // and video tracks.
190   template <typename... Args>
CreatePeerConnectionWithAudioVideo(Args &&...args)191   WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
192     auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
193     if (!wrapper) {
194       return nullptr;
195     }
196     wrapper->AddAudioTrack("a");
197     wrapper->AddVideoTrack("v");
198     return wrapper;
199   }
200 
CreateLocalUdpCandidate(const rtc::SocketAddress & address)201   cricket::Candidate CreateLocalUdpCandidate(
202       const rtc::SocketAddress& address) {
203     cricket::Candidate candidate;
204     candidate.set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
205     candidate.set_protocol(cricket::UDP_PROTOCOL_NAME);
206     candidate.set_address(address);
207     candidate.set_type(cricket::LOCAL_PORT_TYPE);
208     return candidate;
209   }
210 
211   // Remove all ICE ufrag/pwd lines from the given session description.
RemoveIceUfragPwd(SessionDescriptionInterface * sdesc)212   void RemoveIceUfragPwd(SessionDescriptionInterface* sdesc) {
213     SetIceUfragPwd(sdesc, "", "");
214   }
215 
216   // Sets all ICE ufrag/pwds on the given session description.
SetIceUfragPwd(SessionDescriptionInterface * sdesc,const std::string & ufrag,const std::string & pwd)217   void SetIceUfragPwd(SessionDescriptionInterface* sdesc,
218                       const std::string& ufrag,
219                       const std::string& pwd) {
220     auto* desc = sdesc->description();
221     for (const auto& content : desc->contents()) {
222       auto* transport_info = desc->GetTransportInfoByName(content.name);
223       transport_info->description.ice_ufrag = ufrag;
224       transport_info->description.ice_pwd = pwd;
225     }
226   }
227 
228   // Set ICE mode on the given session description.
SetIceMode(SessionDescriptionInterface * sdesc,const cricket::IceMode ice_mode)229   void SetIceMode(SessionDescriptionInterface* sdesc,
230                   const cricket::IceMode ice_mode) {
231     auto* desc = sdesc->description();
232     for (const auto& content : desc->contents()) {
233       auto* transport_info = desc->GetTransportInfoByName(content.name);
234       transport_info->description.ice_mode = ice_mode;
235     }
236   }
237 
GetFirstTransportDescription(SessionDescriptionInterface * sdesc)238   cricket::TransportDescription* GetFirstTransportDescription(
239       SessionDescriptionInterface* sdesc) {
240     auto* desc = sdesc->description();
241     RTC_DCHECK(desc->contents().size() > 0);
242     auto* transport_info =
243         desc->GetTransportInfoByName(desc->contents()[0].name);
244     RTC_DCHECK(transport_info);
245     return &transport_info->description;
246   }
247 
GetFirstTransportDescription(const SessionDescriptionInterface * sdesc)248   const cricket::TransportDescription* GetFirstTransportDescription(
249       const SessionDescriptionInterface* sdesc) {
250     auto* desc = sdesc->description();
251     RTC_DCHECK(desc->contents().size() > 0);
252     auto* transport_info =
253         desc->GetTransportInfoByName(desc->contents()[0].name);
254     RTC_DCHECK(transport_info);
255     return &transport_info->description;
256   }
257 
258   // TODO(qingsi): Rewrite this method in terms of the standard IceTransport
259   // after it is implemented.
GetIceRole(const WrapperPtr & pc_wrapper_ptr)260   cricket::IceRole GetIceRole(const WrapperPtr& pc_wrapper_ptr) {
261     auto* pc_proxy =
262         static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
263             pc_wrapper_ptr->pc());
264     PeerConnection* pc = static_cast<PeerConnection*>(pc_proxy->internal());
265     for (const auto& transceiver : pc->GetTransceiversInternal()) {
266       if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
267         auto dtls_transport = pc->LookupDtlsTransportByMidInternal(
268             transceiver->internal()->channel()->mid());
269         return dtls_transport->ice_transport()->internal()->GetIceRole();
270       }
271     }
272     RTC_DCHECK_NOTREACHED();
273     return cricket::ICEROLE_UNKNOWN;
274   }
275 
276   // Returns a list of (ufrag, pwd) pairs in the order that they appear in
277   // `description`, or the empty list if `description` is null.
GetIceCredentials(const SessionDescriptionInterface * description)278   std::vector<std::pair<std::string, std::string>> GetIceCredentials(
279       const SessionDescriptionInterface* description) {
280     std::vector<std::pair<std::string, std::string>> ice_credentials;
281     if (!description)
282       return ice_credentials;
283     const auto* desc = description->description();
284     for (const auto& content_info : desc->contents()) {
285       const auto* transport_info =
286           desc->GetTransportInfoByName(content_info.name);
287       if (transport_info) {
288         ice_credentials.push_back(
289             std::make_pair(transport_info->description.ice_ufrag,
290                            transport_info->description.ice_pwd));
291       }
292     }
293     return ice_credentials;
294   }
295 
AddCandidateToFirstTransport(cricket::Candidate * candidate,SessionDescriptionInterface * sdesc)296   bool AddCandidateToFirstTransport(cricket::Candidate* candidate,
297                                     SessionDescriptionInterface* sdesc) {
298     auto* desc = sdesc->description();
299     RTC_DCHECK(desc->contents().size() > 0);
300     const auto& first_content = desc->contents()[0];
301     candidate->set_transport_name(first_content.name);
302     std::unique_ptr<IceCandidateInterface> jsep_candidate =
303         CreateIceCandidate(first_content.name, 0, *candidate);
304     return sdesc->AddCandidate(jsep_candidate.get());
305   }
306 
NewFakeNetwork()307   rtc::FakeNetworkManager* NewFakeNetwork() {
308     // The PeerConnection's port allocator is tied to the PeerConnection's
309     // lifetime and expects the underlying NetworkManager to outlive it. That
310     // prevents us from having the PeerConnectionWrapper own the fake network.
311     // Therefore, the test fixture will own all the fake networks even though
312     // tests should access the fake network through the PeerConnectionWrapper.
313     auto* fake_network = new rtc::FakeNetworkManager();
314     fake_networks_.emplace_back(fake_network);
315     return fake_network;
316   }
317 
318   std::unique_ptr<rtc::VirtualSocketServer> vss_;
319   rtc::AutoSocketServerThread main_;
320   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
321   std::vector<std::unique_ptr<rtc::FakeNetworkManager>> fake_networks_;
322   const SdpSemantics sdp_semantics_;
323 };
324 
325 class PeerConnectionIceTest
326     : public PeerConnectionIceBaseTest,
327       public ::testing::WithParamInterface<SdpSemantics> {
328  protected:
PeerConnectionIceTest()329   PeerConnectionIceTest() : PeerConnectionIceBaseTest(GetParam()) {
330     webrtc::metrics::Reset();
331   }
332 };
333 
AssertCandidatesEqual(const char * a_expr,const char * b_expr,const cricket::Candidate & a,const cricket::Candidate & b)334 ::testing::AssertionResult AssertCandidatesEqual(const char* a_expr,
335                                                  const char* b_expr,
336                                                  const cricket::Candidate& a,
337                                                  const cricket::Candidate& b) {
338   rtc::StringBuilder failure_info;
339   if (a.component() != b.component()) {
340     failure_info << "\ncomponent: " << a.component() << " != " << b.component();
341   }
342   if (a.protocol() != b.protocol()) {
343     failure_info << "\nprotocol: " << a.protocol() << " != " << b.protocol();
344   }
345   if (a.address() != b.address()) {
346     failure_info << "\naddress: " << a.address().ToString()
347                  << " != " << b.address().ToString();
348   }
349   if (a.type() != b.type()) {
350     failure_info << "\ntype: " << a.type() << " != " << b.type();
351   }
352   std::string failure_info_str = failure_info.str();
353   if (failure_info_str.empty()) {
354     return ::testing::AssertionSuccess();
355   } else {
356     return ::testing::AssertionFailure()
357            << a_expr << " and " << b_expr << " are not equal"
358            << failure_info_str;
359   }
360 }
361 
TEST_P(PeerConnectionIceTest,OfferContainsGatheredCandidates)362 TEST_P(PeerConnectionIceTest, OfferContainsGatheredCandidates) {
363   const SocketAddress kLocalAddress("1.1.1.1", 0);
364 
365   auto caller = CreatePeerConnectionWithAudioVideo();
366   caller->network()->AddInterface(kLocalAddress);
367 
368   // Start ICE candidate gathering by setting the local offer.
369   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
370 
371   EXPECT_TRUE_WAIT(caller->IsIceGatheringDone(), kIceCandidatesTimeout);
372 
373   auto offer = caller->CreateOffer();
374   EXPECT_LT(0u, caller->observer()->GetCandidatesByMline(0).size());
375   EXPECT_EQ(caller->observer()->GetCandidatesByMline(0).size(),
376             offer->candidates(0)->count());
377   EXPECT_LT(0u, caller->observer()->GetCandidatesByMline(1).size());
378   EXPECT_EQ(caller->observer()->GetCandidatesByMline(1).size(),
379             offer->candidates(1)->count());
380 }
381 
TEST_P(PeerConnectionIceTest,AnswerContainsGatheredCandidates)382 TEST_P(PeerConnectionIceTest, AnswerContainsGatheredCandidates) {
383   const SocketAddress kCallerAddress("1.1.1.1", 0);
384 
385   auto caller = CreatePeerConnectionWithAudioVideo();
386   auto callee = CreatePeerConnectionWithAudioVideo();
387   caller->network()->AddInterface(kCallerAddress);
388 
389   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
390   ASSERT_TRUE(callee->SetLocalDescription(callee->CreateAnswer()));
391 
392   EXPECT_TRUE_WAIT(callee->IsIceGatheringDone(), kIceCandidatesTimeout);
393 
394   auto* answer = callee->pc()->local_description();
395   EXPECT_LT(0u, caller->observer()->GetCandidatesByMline(0).size());
396   EXPECT_EQ(callee->observer()->GetCandidatesByMline(0).size(),
397             answer->candidates(0)->count());
398   EXPECT_LT(0u, caller->observer()->GetCandidatesByMline(1).size());
399   EXPECT_EQ(callee->observer()->GetCandidatesByMline(1).size(),
400             answer->candidates(1)->count());
401 }
402 
TEST_P(PeerConnectionIceTest,CanSetRemoteSessionDescriptionWithRemoteCandidates)403 TEST_P(PeerConnectionIceTest,
404        CanSetRemoteSessionDescriptionWithRemoteCandidates) {
405   const SocketAddress kCallerAddress("1.1.1.1", 1111);
406 
407   auto caller = CreatePeerConnectionWithAudioVideo();
408   auto callee = CreatePeerConnectionWithAudioVideo();
409 
410   auto offer = caller->CreateOfferAndSetAsLocal();
411   cricket::Candidate candidate = CreateLocalUdpCandidate(kCallerAddress);
412   AddCandidateToFirstTransport(&candidate, offer.get());
413 
414   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
415   auto remote_candidates = callee->GetIceCandidatesFromRemoteDescription();
416   ASSERT_EQ(1u, remote_candidates.size());
417   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate,
418                       remote_candidates[0]->candidate());
419 }
420 
TEST_P(PeerConnectionIceTest,SetLocalDescriptionFailsIfNoIceCredentials)421 TEST_P(PeerConnectionIceTest, SetLocalDescriptionFailsIfNoIceCredentials) {
422   auto caller = CreatePeerConnectionWithAudioVideo();
423 
424   auto offer = caller->CreateOffer();
425   RemoveIceUfragPwd(offer.get());
426 
427   EXPECT_FALSE(caller->SetLocalDescription(std::move(offer)));
428 }
429 
TEST_P(PeerConnectionIceTest,SetRemoteDescriptionFailsIfNoIceCredentials)430 TEST_P(PeerConnectionIceTest, SetRemoteDescriptionFailsIfNoIceCredentials) {
431   auto caller = CreatePeerConnectionWithAudioVideo();
432   auto callee = CreatePeerConnectionWithAudioVideo();
433 
434   auto offer = caller->CreateOfferAndSetAsLocal();
435   RemoveIceUfragPwd(offer.get());
436 
437   EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer)));
438 }
439 
440 // Test that doing an offer/answer exchange with no transport (i.e., no data
441 // channel or media) results in the ICE connection state staying at New.
TEST_P(PeerConnectionIceTest,OfferAnswerWithNoTransportsDoesNotChangeIceConnectionState)442 TEST_P(PeerConnectionIceTest,
443        OfferAnswerWithNoTransportsDoesNotChangeIceConnectionState) {
444   auto caller = CreatePeerConnection();
445   auto callee = CreatePeerConnection();
446 
447   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
448 
449   EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
450             caller->pc()->ice_connection_state());
451   EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
452             callee->pc()->ice_connection_state());
453 }
454 
455 // The following group tests that ICE candidates are not generated before
456 // SetLocalDescription is called on a PeerConnection.
457 
TEST_P(PeerConnectionIceTest,NoIceCandidatesBeforeSetLocalDescription)458 TEST_P(PeerConnectionIceTest, NoIceCandidatesBeforeSetLocalDescription) {
459   const SocketAddress kLocalAddress("1.1.1.1", 0);
460 
461   auto caller = CreatePeerConnectionWithAudioVideo();
462   caller->network()->AddInterface(kLocalAddress);
463 
464   // Pump for 1 second and verify that no candidates are generated.
465   rtc::Thread::Current()->ProcessMessages(1000);
466 
467   EXPECT_EQ(0u, caller->observer()->candidates_.size());
468 }
TEST_P(PeerConnectionIceTest,NoIceCandidatesBeforeAnswerSetAsLocalDescription)469 TEST_P(PeerConnectionIceTest,
470        NoIceCandidatesBeforeAnswerSetAsLocalDescription) {
471   const SocketAddress kCallerAddress("1.1.1.1", 1111);
472 
473   auto caller = CreatePeerConnectionWithAudioVideo();
474   auto callee = CreatePeerConnectionWithAudioVideo();
475   caller->network()->AddInterface(kCallerAddress);
476 
477   auto offer = caller->CreateOfferAndSetAsLocal();
478   cricket::Candidate candidate = CreateLocalUdpCandidate(kCallerAddress);
479   AddCandidateToFirstTransport(&candidate, offer.get());
480   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
481 
482   // Pump for 1 second and verify that no candidates are generated.
483   rtc::Thread::Current()->ProcessMessages(1000);
484 
485   EXPECT_EQ(0u, callee->observer()->candidates_.size());
486 }
487 
TEST_P(PeerConnectionIceTest,CannotAddCandidateWhenRemoteDescriptionNotSet)488 TEST_P(PeerConnectionIceTest, CannotAddCandidateWhenRemoteDescriptionNotSet) {
489   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
490 
491   auto caller = CreatePeerConnectionWithAudioVideo();
492   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
493   std::unique_ptr<IceCandidateInterface> jsep_candidate =
494       CreateIceCandidate(cricket::CN_AUDIO, 0, candidate);
495 
496   EXPECT_FALSE(caller->pc()->AddIceCandidate(jsep_candidate.get()));
497 
498   caller->CreateOfferAndSetAsLocal();
499 
500   EXPECT_FALSE(caller->pc()->AddIceCandidate(jsep_candidate.get()));
501   EXPECT_METRIC_THAT(
502       webrtc::metrics::Samples("WebRTC.PeerConnection.AddIceCandidate"),
503       ElementsAre(Pair(kAddIceCandidateFailNoRemoteDescription, 2)));
504 }
505 
TEST_P(PeerConnectionIceTest,CannotAddCandidateWhenPeerConnectionClosed)506 TEST_P(PeerConnectionIceTest, CannotAddCandidateWhenPeerConnectionClosed) {
507   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
508 
509   auto caller = CreatePeerConnectionWithAudioVideo();
510   auto callee = CreatePeerConnectionWithAudioVideo();
511 
512   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
513 
514   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
515   auto* audio_content = cricket::GetFirstAudioContent(
516       caller->pc()->local_description()->description());
517   std::unique_ptr<IceCandidateInterface> jsep_candidate =
518       CreateIceCandidate(audio_content->name, 0, candidate);
519 
520   caller->pc()->Close();
521 
522   EXPECT_FALSE(caller->pc()->AddIceCandidate(jsep_candidate.get()));
523 }
524 
TEST_P(PeerConnectionIceTest,DuplicateIceCandidateIgnoredWhenAdded)525 TEST_P(PeerConnectionIceTest, DuplicateIceCandidateIgnoredWhenAdded) {
526   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
527 
528   auto caller = CreatePeerConnectionWithAudioVideo();
529   auto callee = CreatePeerConnectionWithAudioVideo();
530 
531   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
532   ASSERT_TRUE(
533       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
534 
535   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
536   caller->AddIceCandidate(&candidate);
537   EXPECT_TRUE(caller->AddIceCandidate(&candidate));
538   EXPECT_EQ(1u, caller->GetIceCandidatesFromRemoteDescription().size());
539 }
540 
541 // TODO(tommi): Re-enable after updating RTCPeerConnection-blockedPorts.html in
542 // Chromium (the test needs setRemoteDescription to succeed for an invalid
543 // candidate).
TEST_P(PeerConnectionIceTest,DISABLED_ErrorOnInvalidRemoteIceCandidateAdded)544 TEST_P(PeerConnectionIceTest, DISABLED_ErrorOnInvalidRemoteIceCandidateAdded) {
545   auto caller = CreatePeerConnectionWithAudioVideo();
546   auto callee = CreatePeerConnectionWithAudioVideo();
547   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
548   // Add a candidate to the remote description with a candidate that has an
549   // invalid address (port number == 2).
550   auto answer = callee->CreateAnswerAndSetAsLocal();
551   cricket::Candidate bad_candidate =
552       CreateLocalUdpCandidate(SocketAddress("2.2.2.2", 2));
553   RTC_LOG(LS_INFO) << "Bad candidate: " << bad_candidate.ToString();
554   AddCandidateToFirstTransport(&bad_candidate, answer.get());
555   // Now the call to SetRemoteDescription should fail.
556   EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer)));
557 }
558 
TEST_P(PeerConnectionIceTest,CannotRemoveIceCandidatesWhenPeerConnectionClosed)559 TEST_P(PeerConnectionIceTest,
560        CannotRemoveIceCandidatesWhenPeerConnectionClosed) {
561   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
562 
563   auto caller = CreatePeerConnectionWithAudioVideo();
564   auto callee = CreatePeerConnectionWithAudioVideo();
565 
566   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
567 
568   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
569   auto* audio_content = cricket::GetFirstAudioContent(
570       caller->pc()->local_description()->description());
571   std::unique_ptr<IceCandidateInterface> ice_candidate =
572       CreateIceCandidate(audio_content->name, 0, candidate);
573 
574   ASSERT_TRUE(caller->pc()->AddIceCandidate(ice_candidate.get()));
575 
576   caller->pc()->Close();
577 
578   EXPECT_FALSE(caller->pc()->RemoveIceCandidates({candidate}));
579 }
580 
TEST_P(PeerConnectionIceTest,AddRemoveCandidateWithEmptyTransportDoesNotCrash)581 TEST_P(PeerConnectionIceTest,
582        AddRemoveCandidateWithEmptyTransportDoesNotCrash) {
583   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
584 
585   auto caller = CreatePeerConnectionWithAudioVideo();
586   auto callee = CreatePeerConnectionWithAudioVideo();
587 
588   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
589   ASSERT_TRUE(
590       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
591 
592   // `candidate.transport_name()` is empty.
593   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
594   auto* audio_content = cricket::GetFirstAudioContent(
595       caller->pc()->local_description()->description());
596   std::unique_ptr<IceCandidateInterface> ice_candidate =
597       CreateIceCandidate(audio_content->name, 0, candidate);
598   EXPECT_TRUE(caller->pc()->AddIceCandidate(ice_candidate.get()));
599   EXPECT_TRUE(caller->pc()->RemoveIceCandidates({candidate}));
600 }
601 
TEST_P(PeerConnectionIceTest,RemoveCandidateRemovesFromRemoteDescription)602 TEST_P(PeerConnectionIceTest, RemoveCandidateRemovesFromRemoteDescription) {
603   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
604 
605   auto caller = CreatePeerConnectionWithAudioVideo();
606   auto callee = CreatePeerConnectionWithAudioVideo();
607 
608   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
609   ASSERT_TRUE(
610       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
611 
612   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
613   ASSERT_TRUE(caller->AddIceCandidate(&candidate));
614   EXPECT_TRUE(caller->pc()->RemoveIceCandidates({candidate}));
615   EXPECT_EQ(0u, caller->GetIceCandidatesFromRemoteDescription().size());
616 }
617 
618 // Test that if a candidate is added via AddIceCandidate and via an updated
619 // remote description, then both candidates appear in the stored remote
620 // description.
TEST_P(PeerConnectionIceTest,CandidateInSubsequentOfferIsAddedToRemoteDescription)621 TEST_P(PeerConnectionIceTest,
622        CandidateInSubsequentOfferIsAddedToRemoteDescription) {
623   const SocketAddress kCallerAddress1("1.1.1.1", 1111);
624   const SocketAddress kCallerAddress2("2.2.2.2", 2222);
625 
626   auto caller = CreatePeerConnectionWithAudioVideo();
627   auto callee = CreatePeerConnectionWithAudioVideo();
628 
629   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
630   ASSERT_TRUE(
631       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
632 
633   // Add one candidate via `AddIceCandidate`.
634   cricket::Candidate candidate1 = CreateLocalUdpCandidate(kCallerAddress1);
635   ASSERT_TRUE(callee->AddIceCandidate(&candidate1));
636 
637   // Add the second candidate via a reoffer.
638   auto offer = caller->CreateOffer();
639   cricket::Candidate candidate2 = CreateLocalUdpCandidate(kCallerAddress2);
640   AddCandidateToFirstTransport(&candidate2, offer.get());
641 
642   // Expect both candidates to appear in the callee's remote description.
643   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
644   EXPECT_EQ(2u, callee->GetIceCandidatesFromRemoteDescription().size());
645 }
646 
647 // The follow test verifies that SetLocal/RemoteDescription fails when an offer
648 // has either ICE ufrag/pwd too short or too long and succeeds otherwise.
649 // The standard (https://tools.ietf.org/html/rfc5245#section-15.4) says that
650 // pwd must be 22-256 characters and ufrag must be 4-256 characters.
TEST_P(PeerConnectionIceTest,VerifyUfragPwdLength)651 TEST_P(PeerConnectionIceTest, VerifyUfragPwdLength) {
652   auto set_local_description_with_ufrag_pwd_length = [this](int ufrag_len,
653                                                             int pwd_len) {
654     auto pc = CreatePeerConnectionWithAudioVideo();
655     auto offer = pc->CreateOffer();
656     SetIceUfragPwd(offer.get(), std::string(ufrag_len, 'x'),
657                    std::string(pwd_len, 'x'));
658     return pc->SetLocalDescription(std::move(offer));
659   };
660 
661   auto set_remote_description_with_ufrag_pwd_length = [this](int ufrag_len,
662                                                              int pwd_len) {
663     auto pc = CreatePeerConnectionWithAudioVideo();
664     auto offer = pc->CreateOffer();
665     SetIceUfragPwd(offer.get(), std::string(ufrag_len, 'x'),
666                    std::string(pwd_len, 'x'));
667     return pc->SetRemoteDescription(std::move(offer));
668   };
669 
670   EXPECT_FALSE(set_local_description_with_ufrag_pwd_length(3, 22));
671   EXPECT_FALSE(set_remote_description_with_ufrag_pwd_length(3, 22));
672   EXPECT_FALSE(set_local_description_with_ufrag_pwd_length(257, 22));
673   EXPECT_FALSE(set_remote_description_with_ufrag_pwd_length(257, 22));
674   EXPECT_FALSE(set_local_description_with_ufrag_pwd_length(4, 21));
675   EXPECT_FALSE(set_remote_description_with_ufrag_pwd_length(4, 21));
676   EXPECT_FALSE(set_local_description_with_ufrag_pwd_length(4, 257));
677   EXPECT_FALSE(set_remote_description_with_ufrag_pwd_length(4, 257));
678   EXPECT_TRUE(set_local_description_with_ufrag_pwd_length(4, 22));
679   EXPECT_TRUE(set_remote_description_with_ufrag_pwd_length(4, 22));
680   EXPECT_TRUE(set_local_description_with_ufrag_pwd_length(256, 256));
681   EXPECT_TRUE(set_remote_description_with_ufrag_pwd_length(256, 256));
682 }
683 
AssertIpInCandidates(const char * address_expr,const char * candidates_expr,const SocketAddress & address,const std::vector<IceCandidateInterface * > candidates)684 ::testing::AssertionResult AssertIpInCandidates(
685     const char* address_expr,
686     const char* candidates_expr,
687     const SocketAddress& address,
688     const std::vector<IceCandidateInterface*> candidates) {
689   rtc::StringBuilder candidate_hosts;
690   for (const auto* candidate : candidates) {
691     const auto& candidate_ip = candidate->candidate().address().ipaddr();
692     if (candidate_ip == address.ipaddr()) {
693       return ::testing::AssertionSuccess();
694     }
695     candidate_hosts << "\n" << candidate_ip.ToString();
696   }
697   return ::testing::AssertionFailure()
698          << address_expr << " (host " << address.HostAsURIString()
699          << ") not in " << candidates_expr
700          << " which have the following address hosts:" << candidate_hosts.str();
701 }
702 
TEST_P(PeerConnectionIceTest,CandidatesGeneratedForEachLocalInterface)703 TEST_P(PeerConnectionIceTest, CandidatesGeneratedForEachLocalInterface) {
704   const SocketAddress kLocalAddress1("1.1.1.1", 0);
705   const SocketAddress kLocalAddress2("2.2.2.2", 0);
706 
707   auto caller = CreatePeerConnectionWithAudioVideo();
708   caller->network()->AddInterface(kLocalAddress1);
709   caller->network()->AddInterface(kLocalAddress2);
710 
711   caller->CreateOfferAndSetAsLocal();
712   EXPECT_TRUE_WAIT(caller->IsIceGatheringDone(), kIceCandidatesTimeout);
713 
714   auto candidates = caller->observer()->GetCandidatesByMline(0);
715   EXPECT_PRED_FORMAT2(AssertIpInCandidates, kLocalAddress1, candidates);
716   EXPECT_PRED_FORMAT2(AssertIpInCandidates, kLocalAddress2, candidates);
717 }
718 
TEST_P(PeerConnectionIceTest,TrickledSingleCandidateAddedToRemoteDescription)719 TEST_P(PeerConnectionIceTest, TrickledSingleCandidateAddedToRemoteDescription) {
720   const SocketAddress kCallerAddress("1.1.1.1", 1111);
721 
722   auto caller = CreatePeerConnectionWithAudioVideo();
723   auto callee = CreatePeerConnectionWithAudioVideo();
724 
725   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
726 
727   cricket::Candidate candidate = CreateLocalUdpCandidate(kCallerAddress);
728   callee->AddIceCandidate(&candidate);
729   auto candidates = callee->GetIceCandidatesFromRemoteDescription();
730   ASSERT_EQ(1u, candidates.size());
731   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate,
732                       candidates[0]->candidate());
733 }
734 
TEST_P(PeerConnectionIceTest,TwoTrickledCandidatesAddedToRemoteDescription)735 TEST_P(PeerConnectionIceTest, TwoTrickledCandidatesAddedToRemoteDescription) {
736   const SocketAddress kCalleeAddress1("1.1.1.1", 1111);
737   const SocketAddress kCalleeAddress2("2.2.2.2", 2222);
738 
739   auto caller = CreatePeerConnectionWithAudioVideo();
740   auto callee = CreatePeerConnectionWithAudioVideo();
741 
742   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
743   ASSERT_TRUE(
744       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
745 
746   cricket::Candidate candidate1 = CreateLocalUdpCandidate(kCalleeAddress1);
747   caller->AddIceCandidate(&candidate1);
748 
749   cricket::Candidate candidate2 = CreateLocalUdpCandidate(kCalleeAddress2);
750   caller->AddIceCandidate(&candidate2);
751 
752   auto candidates = caller->GetIceCandidatesFromRemoteDescription();
753   ASSERT_EQ(2u, candidates.size());
754   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate1,
755                       candidates[0]->candidate());
756   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate2,
757                       candidates[1]->candidate());
758 }
759 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateIsAddedToRemoteDescription)760 TEST_P(PeerConnectionIceTest, AsyncAddIceCandidateIsAddedToRemoteDescription) {
761   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
762 
763   auto caller = CreatePeerConnectionWithAudioVideo();
764   auto callee = CreatePeerConnectionWithAudioVideo();
765 
766   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
767 
768   auto jsep_candidate =
769       callee->CreateJsepCandidateForFirstTransport(&candidate);
770   bool operation_completed = false;
771   callee->pc()->AddIceCandidate(std::move(jsep_candidate),
772                                 [&operation_completed](RTCError result) {
773                                   EXPECT_TRUE(result.ok());
774                                   operation_completed = true;
775                                 });
776   EXPECT_TRUE_WAIT(operation_completed, kWaitTimeout);
777 
778   auto candidates = callee->GetIceCandidatesFromRemoteDescription();
779   ASSERT_EQ(1u, candidates.size());
780   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, candidate,
781                       candidates[0]->candidate());
782 }
783 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateCompletesImmediatelyIfNoPendingOperation)784 TEST_P(PeerConnectionIceTest,
785        AsyncAddIceCandidateCompletesImmediatelyIfNoPendingOperation) {
786   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
787 
788   auto caller = CreatePeerConnectionWithAudioVideo();
789   auto callee = CreatePeerConnectionWithAudioVideo();
790 
791   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
792 
793   auto jsep_candidate =
794       callee->CreateJsepCandidateForFirstTransport(&candidate);
795   bool operation_completed = false;
796   callee->pc()->AddIceCandidate(
797       std::move(jsep_candidate),
798       [&operation_completed](RTCError result) { operation_completed = true; });
799   EXPECT_TRUE(operation_completed);
800 }
801 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateCompletesWhenPendingOperationCompletes)802 TEST_P(PeerConnectionIceTest,
803        AsyncAddIceCandidateCompletesWhenPendingOperationCompletes) {
804   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
805 
806   auto caller = CreatePeerConnectionWithAudioVideo();
807   auto callee = CreatePeerConnectionWithAudioVideo();
808 
809   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
810 
811   // Chain an operation that will block AddIceCandidate() from executing.
812   auto answer_observer =
813       rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
814   callee->pc()->CreateAnswer(answer_observer.get(), RTCOfferAnswerOptions());
815 
816   auto jsep_candidate =
817       callee->CreateJsepCandidateForFirstTransport(&candidate);
818   bool operation_completed = false;
819   callee->pc()->AddIceCandidate(
820       std::move(jsep_candidate),
821       [&operation_completed](RTCError result) { operation_completed = true; });
822   // The operation will not be able to complete until we EXPECT_TRUE_WAIT()
823   // allowing CreateAnswer() to complete.
824   EXPECT_FALSE(operation_completed);
825   EXPECT_TRUE_WAIT(answer_observer->called(), kWaitTimeout);
826   // As soon as it does, AddIceCandidate() will execute without delay, so it
827   // must also have completed.
828   EXPECT_TRUE(operation_completed);
829 }
830 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateFailsBeforeSetRemoteDescription)831 TEST_P(PeerConnectionIceTest,
832        AsyncAddIceCandidateFailsBeforeSetRemoteDescription) {
833   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
834 
835   auto caller = CreatePeerConnectionWithAudioVideo();
836   std::unique_ptr<IceCandidateInterface> jsep_candidate =
837       CreateIceCandidate(cricket::CN_AUDIO, 0, candidate);
838 
839   bool operation_completed = false;
840   caller->pc()->AddIceCandidate(
841       std::move(jsep_candidate), [&operation_completed](RTCError result) {
842         EXPECT_FALSE(result.ok());
843         EXPECT_EQ(result.message(),
844                   std::string("The remote description was null"));
845         operation_completed = true;
846       });
847   EXPECT_TRUE_WAIT(operation_completed, kWaitTimeout);
848 }
849 
TEST_P(PeerConnectionIceTest,AsyncAddIceCandidateFailsIfPeerConnectionDestroyed)850 TEST_P(PeerConnectionIceTest,
851        AsyncAddIceCandidateFailsIfPeerConnectionDestroyed) {
852   auto candidate = CreateLocalUdpCandidate(SocketAddress("1.1.1.1", 1111));
853 
854   auto caller = CreatePeerConnectionWithAudioVideo();
855   auto callee = CreatePeerConnectionWithAudioVideo();
856 
857   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
858 
859   // Chain an operation that will block AddIceCandidate() from executing.
860   auto answer_observer =
861       rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
862   callee->pc()->CreateAnswer(answer_observer.get(), RTCOfferAnswerOptions());
863 
864   auto jsep_candidate =
865       callee->CreateJsepCandidateForFirstTransport(&candidate);
866   bool operation_completed = false;
867   callee->pc()->AddIceCandidate(
868       std::move(jsep_candidate), [&operation_completed](RTCError result) {
869         EXPECT_FALSE(result.ok());
870         EXPECT_EQ(
871             result.message(),
872             std::string(
873                 "AddIceCandidate failed because the session was shut down"));
874         operation_completed = true;
875       });
876   // The operation will not be able to run until EXPECT_TRUE_WAIT(), giving us
877   // time to remove all references to the PeerConnection.
878   EXPECT_FALSE(operation_completed);
879   // This should delete the callee PC.
880   callee = nullptr;
881   EXPECT_TRUE_WAIT(operation_completed, kWaitTimeout);
882 }
883 
TEST_P(PeerConnectionIceTest,LocalDescriptionUpdatedWhenContinualGathering)884 TEST_P(PeerConnectionIceTest, LocalDescriptionUpdatedWhenContinualGathering) {
885   const SocketAddress kLocalAddress("1.1.1.1", 0);
886 
887   RTCConfiguration config;
888   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
889   config.continual_gathering_policy =
890       PeerConnectionInterface::GATHER_CONTINUALLY;
891   auto caller = CreatePeerConnectionWithAudioVideo(config);
892   caller->network()->AddInterface(kLocalAddress);
893 
894   // Start ICE candidate gathering by setting the local offer.
895   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
896 
897   // Since we're using continual gathering, we won't get "gathering done".
898   EXPECT_TRUE_WAIT(
899       caller->pc()->local_description()->candidates(0)->count() > 0,
900       kIceCandidatesTimeout);
901 }
902 
903 // Test that when continual gathering is enabled, and a network interface goes
904 // down, the candidate is signaled as removed and removed from the local
905 // description.
TEST_P(PeerConnectionIceTest,LocalCandidatesRemovedWhenNetworkDownIfGatheringContinually)906 TEST_P(PeerConnectionIceTest,
907        LocalCandidatesRemovedWhenNetworkDownIfGatheringContinually) {
908   const SocketAddress kLocalAddress("1.1.1.1", 0);
909 
910   RTCConfiguration config;
911   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
912   config.continual_gathering_policy =
913       PeerConnectionInterface::GATHER_CONTINUALLY;
914   auto caller = CreatePeerConnectionWithAudioVideo(config);
915   caller->network()->AddInterface(kLocalAddress);
916 
917   // Start ICE candidate gathering by setting the local offer.
918   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
919 
920   EXPECT_TRUE_WAIT(
921       caller->pc()->local_description()->candidates(0)->count() > 0,
922       kIceCandidatesTimeout);
923 
924   // Remove the only network interface, causing the PeerConnection to signal
925   // the removal of all candidates derived from this interface.
926   caller->network()->RemoveInterface(kLocalAddress);
927 
928   EXPECT_EQ_WAIT(0u, caller->pc()->local_description()->candidates(0)->count(),
929                  kIceCandidatesTimeout);
930   EXPECT_LT(0, caller->observer()->num_candidates_removed_);
931 }
932 
TEST_P(PeerConnectionIceTest,LocalCandidatesNotRemovedWhenNetworkDownIfGatheringOnce)933 TEST_P(PeerConnectionIceTest,
934        LocalCandidatesNotRemovedWhenNetworkDownIfGatheringOnce) {
935   const SocketAddress kLocalAddress("1.1.1.1", 0);
936 
937   RTCConfiguration config;
938   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
939   config.continual_gathering_policy = PeerConnectionInterface::GATHER_ONCE;
940   auto caller = CreatePeerConnectionWithAudioVideo(config);
941   caller->network()->AddInterface(kLocalAddress);
942 
943   // Start ICE candidate gathering by setting the local offer.
944   ASSERT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
945 
946   EXPECT_TRUE_WAIT(caller->IsIceGatheringDone(), kIceCandidatesTimeout);
947 
948   caller->network()->RemoveInterface(kLocalAddress);
949 
950   // Verify that the local candidates are not removed;
951   rtc::Thread::Current()->ProcessMessages(1000);
952   EXPECT_EQ(0, caller->observer()->num_candidates_removed_);
953 }
954 
955 // The following group tests that when an offer includes a new ufrag or pwd
956 // (indicating an ICE restart) the old candidates are removed and new candidates
957 // added to the remote description.
958 
TEST_P(PeerConnectionIceTest,IceRestartOfferClearsExistingCandidate)959 TEST_P(PeerConnectionIceTest, IceRestartOfferClearsExistingCandidate) {
960   const SocketAddress kCallerAddress("1.1.1.1", 1111);
961 
962   auto caller = CreatePeerConnectionWithAudioVideo();
963   auto callee = CreatePeerConnectionWithAudioVideo();
964 
965   auto offer = caller->CreateOfferAndSetAsLocal();
966   cricket::Candidate candidate = CreateLocalUdpCandidate(kCallerAddress);
967   AddCandidateToFirstTransport(&candidate, offer.get());
968 
969   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
970 
971   RTCOfferAnswerOptions options;
972   options.ice_restart = true;
973   ASSERT_TRUE(
974       callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal(options)));
975 
976   EXPECT_EQ(0u, callee->GetIceCandidatesFromRemoteDescription().size());
977 }
TEST_P(PeerConnectionIceTest,IceRestartOfferCandidateReplacesExistingCandidate)978 TEST_P(PeerConnectionIceTest,
979        IceRestartOfferCandidateReplacesExistingCandidate) {
980   const SocketAddress kFirstCallerAddress("1.1.1.1", 1111);
981   const SocketAddress kRestartedCallerAddress("2.2.2.2", 2222);
982 
983   auto caller = CreatePeerConnectionWithAudioVideo();
984   auto callee = CreatePeerConnectionWithAudioVideo();
985 
986   auto offer = caller->CreateOfferAndSetAsLocal();
987   cricket::Candidate old_candidate =
988       CreateLocalUdpCandidate(kFirstCallerAddress);
989   AddCandidateToFirstTransport(&old_candidate, offer.get());
990 
991   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
992 
993   RTCOfferAnswerOptions options;
994   options.ice_restart = true;
995   auto restart_offer = caller->CreateOfferAndSetAsLocal(options);
996   cricket::Candidate new_candidate =
997       CreateLocalUdpCandidate(kRestartedCallerAddress);
998   AddCandidateToFirstTransport(&new_candidate, restart_offer.get());
999 
1000   ASSERT_TRUE(callee->SetRemoteDescription(std::move(restart_offer)));
1001 
1002   auto remote_candidates = callee->GetIceCandidatesFromRemoteDescription();
1003   ASSERT_EQ(1u, remote_candidates.size());
1004   EXPECT_PRED_FORMAT2(AssertCandidatesEqual, new_candidate,
1005                       remote_candidates[0]->candidate());
1006 }
1007 
1008 // Test that if there is not an ICE restart (i.e., nothing changes), then the
1009 // answer to a later offer should have the same ufrag/pwd as the first answer.
TEST_P(PeerConnectionIceTest,LaterAnswerHasSameIceCredentialsIfNoIceRestart)1010 TEST_P(PeerConnectionIceTest, LaterAnswerHasSameIceCredentialsIfNoIceRestart) {
1011   auto caller = CreatePeerConnectionWithAudioVideo();
1012   auto callee = CreatePeerConnectionWithAudioVideo();
1013 
1014   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1015   ASSERT_TRUE(
1016       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1017 
1018   // Re-offer.
1019   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1020 
1021   auto answer = callee->CreateAnswer();
1022   auto* answer_transport_desc = GetFirstTransportDescription(answer.get());
1023   auto* local_transport_desc =
1024       GetFirstTransportDescription(callee->pc()->local_description());
1025 
1026   EXPECT_EQ(answer_transport_desc->ice_ufrag, local_transport_desc->ice_ufrag);
1027   EXPECT_EQ(answer_transport_desc->ice_pwd, local_transport_desc->ice_pwd);
1028 }
1029 
TEST_P(PeerConnectionIceTest,RestartIceGeneratesNewCredentials)1030 TEST_P(PeerConnectionIceTest, RestartIceGeneratesNewCredentials) {
1031   auto caller = CreatePeerConnectionWithAudioVideo();
1032   auto callee = CreatePeerConnectionWithAudioVideo();
1033 
1034   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1035   auto initial_ice_credentials =
1036       GetIceCredentials(caller->pc()->local_description());
1037   caller->pc()->RestartIce();
1038   ASSERT_TRUE(caller->CreateOfferAndSetAsLocal());
1039   auto restarted_ice_credentials =
1040       GetIceCredentials(caller->pc()->local_description());
1041   EXPECT_NE(initial_ice_credentials, restarted_ice_credentials);
1042 }
1043 
TEST_P(PeerConnectionIceTest,RestartIceWhileLocalOfferIsPendingGeneratesNewCredentialsInNextOffer)1044 TEST_P(PeerConnectionIceTest,
1045        RestartIceWhileLocalOfferIsPendingGeneratesNewCredentialsInNextOffer) {
1046   auto caller = CreatePeerConnectionWithAudioVideo();
1047   auto callee = CreatePeerConnectionWithAudioVideo();
1048 
1049   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1050   auto initial_ice_credentials =
1051       GetIceCredentials(caller->pc()->local_description());
1052   // ICE restart becomes needed while an O/A is pending and `caller` is the
1053   // offerer.
1054   caller->pc()->RestartIce();
1055   ASSERT_TRUE(
1056       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1057   ASSERT_TRUE(caller->CreateOfferAndSetAsLocal());
1058   auto restarted_ice_credentials =
1059       GetIceCredentials(caller->pc()->local_description());
1060   EXPECT_NE(initial_ice_credentials, restarted_ice_credentials);
1061 }
1062 
TEST_P(PeerConnectionIceTest,RestartIceWhileRemoteOfferIsPendingGeneratesNewCredentialsInNextOffer)1063 TEST_P(PeerConnectionIceTest,
1064        RestartIceWhileRemoteOfferIsPendingGeneratesNewCredentialsInNextOffer) {
1065   auto caller = CreatePeerConnectionWithAudioVideo();
1066   auto callee = CreatePeerConnectionWithAudioVideo();
1067 
1068   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1069   auto initial_ice_credentials =
1070       GetIceCredentials(caller->pc()->local_description());
1071   ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateOfferAndSetAsLocal()));
1072   // ICE restart becomes needed while an O/A is pending and `caller` is the
1073   // answerer.
1074   caller->pc()->RestartIce();
1075   ASSERT_TRUE(
1076       callee->SetRemoteDescription(caller->CreateAnswerAndSetAsLocal()));
1077   ASSERT_TRUE(caller->CreateOfferAndSetAsLocal());
1078   auto restarted_ice_credentials =
1079       GetIceCredentials(caller->pc()->local_description());
1080   EXPECT_NE(initial_ice_credentials, restarted_ice_credentials);
1081 }
1082 
TEST_P(PeerConnectionIceTest,RestartIceTriggeredByRemoteSide)1083 TEST_P(PeerConnectionIceTest, RestartIceTriggeredByRemoteSide) {
1084   auto caller = CreatePeerConnectionWithAudioVideo();
1085   auto callee = CreatePeerConnectionWithAudioVideo();
1086 
1087   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1088   auto initial_ice_credentials =
1089       GetIceCredentials(caller->pc()->local_description());
1090 
1091   // Remote restart and O/A exchange with `caller` as the answerer should
1092   // restart ICE locally as well.
1093   callee->pc()->RestartIce();
1094   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
1095 
1096   auto restarted_ice_credentials =
1097       GetIceCredentials(caller->pc()->local_description());
1098   EXPECT_NE(initial_ice_credentials, restarted_ice_credentials);
1099 }
1100 
TEST_P(PeerConnectionIceTest,RestartIceCausesNegotiationNeeded)1101 TEST_P(PeerConnectionIceTest, RestartIceCausesNegotiationNeeded) {
1102   auto caller = CreatePeerConnectionWithAudioVideo();
1103   auto callee = CreatePeerConnectionWithAudioVideo();
1104 
1105   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1106   caller->observer()->clear_legacy_renegotiation_needed();
1107   caller->observer()->clear_latest_negotiation_needed_event();
1108   caller->pc()->RestartIce();
1109   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1110   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1111 }
1112 
1113 // In Unified Plan, "onnegotiationneeded" is spec-compliant, including not
1114 // firing multipe times in a row, or firing when returning to the stable
1115 // signaling state if negotiation is still needed. In Plan B it fires any time
1116 // something changes. As such, some tests are SdpSemantics-specific.
1117 class PeerConnectionIceTestUnifiedPlan : public PeerConnectionIceBaseTest {
1118  protected:
PeerConnectionIceTestUnifiedPlan()1119   PeerConnectionIceTestUnifiedPlan()
1120       : PeerConnectionIceBaseTest(SdpSemantics::kUnifiedPlan) {}
1121 };
1122 
TEST_F(PeerConnectionIceTestUnifiedPlan,RestartIceWhileLocalOfferIsPendingCausesNegotiationNeededWhenStable)1123 TEST_F(PeerConnectionIceTestUnifiedPlan,
1124        RestartIceWhileLocalOfferIsPendingCausesNegotiationNeededWhenStable) {
1125   auto caller = CreatePeerConnectionWithAudioVideo();
1126   auto callee = CreatePeerConnectionWithAudioVideo();
1127 
1128   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1129   // ICE restart becomes needed while an O/A is pending and `caller` is the
1130   // offerer.
1131   caller->observer()->clear_legacy_renegotiation_needed();
1132   caller->observer()->clear_latest_negotiation_needed_event();
1133   caller->pc()->RestartIce();
1134   // In Unified Plan, the event should not fire until we are back in the stable
1135   // signaling state.
1136   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1137   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1138   ASSERT_TRUE(
1139       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1140   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1141   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1142 }
1143 
TEST_F(PeerConnectionIceTestUnifiedPlan,RestartIceWhileRemoteOfferIsPendingCausesNegotiationNeededWhenStable)1144 TEST_F(PeerConnectionIceTestUnifiedPlan,
1145        RestartIceWhileRemoteOfferIsPendingCausesNegotiationNeededWhenStable) {
1146   auto caller = CreatePeerConnectionWithAudioVideo();
1147   auto callee = CreatePeerConnectionWithAudioVideo();
1148 
1149   // Establish initial credentials as the caller.
1150   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1151   ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateOfferAndSetAsLocal()));
1152   // ICE restart becomes needed while an O/A is pending and `caller` is the
1153   // answerer.
1154   caller->observer()->clear_legacy_renegotiation_needed();
1155   caller->observer()->clear_latest_negotiation_needed_event();
1156   caller->pc()->RestartIce();
1157   // In Unified Plan, the event should not fire until we are back in the stable
1158   // signaling state.
1159   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1160   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1161   ASSERT_TRUE(
1162       callee->SetRemoteDescription(caller->CreateAnswerAndSetAsLocal()));
1163   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1164   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1165 }
1166 
TEST_F(PeerConnectionIceTestUnifiedPlan,RestartIceTriggeredByRemoteSideCauseNegotiationNotNeeded)1167 TEST_F(PeerConnectionIceTestUnifiedPlan,
1168        RestartIceTriggeredByRemoteSideCauseNegotiationNotNeeded) {
1169   auto caller = CreatePeerConnectionWithAudioVideo();
1170   auto callee = CreatePeerConnectionWithAudioVideo();
1171 
1172   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1173   // Local restart.
1174   caller->pc()->RestartIce();
1175   caller->observer()->clear_legacy_renegotiation_needed();
1176   caller->observer()->clear_latest_negotiation_needed_event();
1177   // Remote restart and O/A exchange with `caller` as the answerer should
1178   // restart ICE locally as well.
1179   callee->pc()->RestartIce();
1180   ASSERT_TRUE(callee->ExchangeOfferAnswerWith(caller.get()));
1181   // Having restarted ICE by the remote offer, we do not need to renegotiate ICE
1182   // credentials when back in the stable signaling state.
1183   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1184   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1185 }
1186 
TEST_F(PeerConnectionIceTestUnifiedPlan,RestartIceTwiceDoesNotFireNegotiationNeededTwice)1187 TEST_F(PeerConnectionIceTestUnifiedPlan,
1188        RestartIceTwiceDoesNotFireNegotiationNeededTwice) {
1189   auto caller = CreatePeerConnectionWithAudioVideo();
1190   auto callee = CreatePeerConnectionWithAudioVideo();
1191 
1192   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1193   caller->pc()->RestartIce();
1194   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1195   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1196   caller->observer()->clear_legacy_renegotiation_needed();
1197   caller->observer()->clear_latest_negotiation_needed_event();
1198   caller->pc()->RestartIce();
1199   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1200   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1201 }
1202 
1203 // In Plan B, "onnegotiationneeded" is not spec-compliant, firing based on if
1204 // something changed rather than if negotiation is needed. In Unified Plan it
1205 // fires according to spec. As such, some tests are SdpSemantics-specific.
1206 class PeerConnectionIceTestPlanB : public PeerConnectionIceBaseTest {
1207  protected:
PeerConnectionIceTestPlanB()1208   PeerConnectionIceTestPlanB()
1209       : PeerConnectionIceBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
1210 };
1211 
TEST_F(PeerConnectionIceTestPlanB,RestartIceWhileOfferIsPendingCausesNegotiationNeededImmediately)1212 TEST_F(PeerConnectionIceTestPlanB,
1213        RestartIceWhileOfferIsPendingCausesNegotiationNeededImmediately) {
1214   auto caller = CreatePeerConnectionWithAudioVideo();
1215   auto callee = CreatePeerConnectionWithAudioVideo();
1216 
1217   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1218   caller->observer()->clear_legacy_renegotiation_needed();
1219   caller->observer()->clear_latest_negotiation_needed_event();
1220   caller->pc()->RestartIce();
1221   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1222   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1223   caller->observer()->clear_legacy_renegotiation_needed();
1224   caller->observer()->clear_latest_negotiation_needed_event();
1225   ASSERT_TRUE(
1226       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1227   // In Plan B, the event fired early so we don't expect it to fire now. This is
1228   // not spec-compliant but follows the pattern of existing Plan B behavior.
1229   EXPECT_FALSE(caller->observer()->legacy_renegotiation_needed());
1230   EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
1231 }
1232 
TEST_F(PeerConnectionIceTestPlanB,RestartIceTwiceDoesFireNegotiationNeededTwice)1233 TEST_F(PeerConnectionIceTestPlanB,
1234        RestartIceTwiceDoesFireNegotiationNeededTwice) {
1235   auto caller = CreatePeerConnectionWithAudioVideo();
1236   auto callee = CreatePeerConnectionWithAudioVideo();
1237 
1238   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1239   caller->observer()->clear_legacy_renegotiation_needed();
1240   caller->observer()->clear_latest_negotiation_needed_event();
1241   caller->pc()->RestartIce();
1242   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1243   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1244   caller->observer()->clear_legacy_renegotiation_needed();
1245   caller->observer()->clear_latest_negotiation_needed_event();
1246   caller->pc()->RestartIce();
1247   // In Plan B, the event fires every time something changed, even if we have
1248   // already fired the event. This is not spec-compliant but follows the same
1249   // pattern of existing Plan B behavior.
1250   EXPECT_TRUE(caller->observer()->legacy_renegotiation_needed());
1251   EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
1252 }
1253 
1254 // The following parameterized test verifies that if an offer is sent with a
1255 // modified ICE ufrag and/or ICE pwd, then the answer should identify that the
1256 // other side has initiated an ICE restart and generate a new ufrag and pwd.
1257 // RFC 5245 says: "If the offer contained a change in the a=ice-ufrag or
1258 // a=ice-pwd attributes compared to the previous SDP from the peer, it
1259 // indicates that ICE is restarting for this media stream."
1260 
1261 class PeerConnectionIceUfragPwdAnswerTest
1262     : public PeerConnectionIceBaseTest,
1263       public ::testing::WithParamInterface<
1264           std::tuple<SdpSemantics, std::tuple<bool, bool>>> {
1265  protected:
PeerConnectionIceUfragPwdAnswerTest()1266   PeerConnectionIceUfragPwdAnswerTest()
1267       : PeerConnectionIceBaseTest(std::get<0>(GetParam())) {
1268     auto param = std::get<1>(GetParam());
1269     offer_new_ufrag_ = std::get<0>(param);
1270     offer_new_pwd_ = std::get<1>(param);
1271   }
1272 
1273   bool offer_new_ufrag_;
1274   bool offer_new_pwd_;
1275 };
1276 
TEST_P(PeerConnectionIceUfragPwdAnswerTest,TestIncludedInAnswer)1277 TEST_P(PeerConnectionIceUfragPwdAnswerTest, TestIncludedInAnswer) {
1278   auto caller = CreatePeerConnectionWithAudioVideo();
1279   auto callee = CreatePeerConnectionWithAudioVideo();
1280 
1281   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1282   ASSERT_TRUE(
1283       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1284 
1285   auto offer = caller->CreateOffer();
1286   auto* offer_transport_desc = GetFirstTransportDescription(offer.get());
1287   if (offer_new_ufrag_) {
1288     offer_transport_desc->ice_ufrag += "+new";
1289   }
1290   if (offer_new_pwd_) {
1291     offer_transport_desc->ice_pwd += "+new";
1292   }
1293 
1294   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1295 
1296   auto answer = callee->CreateAnswer();
1297   auto* answer_transport_desc = GetFirstTransportDescription(answer.get());
1298   auto* local_transport_desc =
1299       GetFirstTransportDescription(callee->pc()->local_description());
1300 
1301   EXPECT_NE(answer_transport_desc->ice_ufrag, local_transport_desc->ice_ufrag);
1302   EXPECT_NE(answer_transport_desc->ice_pwd, local_transport_desc->ice_pwd);
1303 }
1304 
1305 INSTANTIATE_TEST_SUITE_P(
1306     PeerConnectionIceTest,
1307     PeerConnectionIceUfragPwdAnswerTest,
1308     Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
1309             Values(std::make_pair(true, true),      // Both changed.
1310                    std::make_pair(true, false),     // Only ufrag changed.
1311                    std::make_pair(false, true))));  // Only pwd changed.
1312 
1313 // Test that if an ICE restart is offered on one media section, then the answer
1314 // will only change ICE ufrag/pwd for that section and keep the other sections
1315 // the same.
1316 // Note that this only works if we have disabled BUNDLE, otherwise all media
1317 // sections will share the same transport.
TEST_P(PeerConnectionIceTest,CreateAnswerHasNewUfragPwdForOnlyMediaSectionWhichRestarted)1318 TEST_P(PeerConnectionIceTest,
1319        CreateAnswerHasNewUfragPwdForOnlyMediaSectionWhichRestarted) {
1320   auto caller = CreatePeerConnectionWithAudioVideo();
1321   auto callee = CreatePeerConnectionWithAudioVideo();
1322 
1323   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1324   ASSERT_TRUE(
1325       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1326 
1327   RTCOfferAnswerOptions disable_bundle_options;
1328   disable_bundle_options.use_rtp_mux = false;
1329 
1330   auto offer = caller->CreateOffer(disable_bundle_options);
1331 
1332   // Signal ICE restart on the first media section.
1333   auto* offer_transport_desc = GetFirstTransportDescription(offer.get());
1334   offer_transport_desc->ice_ufrag += "+new";
1335   offer_transport_desc->ice_pwd += "+new";
1336 
1337   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1338 
1339   auto answer = callee->CreateAnswer(disable_bundle_options);
1340   const auto& answer_transports = answer->description()->transport_infos();
1341   const auto& local_transports =
1342       callee->pc()->local_description()->description()->transport_infos();
1343 
1344   EXPECT_NE(answer_transports[0].description.ice_ufrag,
1345             local_transports[0].description.ice_ufrag);
1346   EXPECT_NE(answer_transports[0].description.ice_pwd,
1347             local_transports[0].description.ice_pwd);
1348   EXPECT_EQ(answer_transports[1].description.ice_ufrag,
1349             local_transports[1].description.ice_ufrag);
1350   EXPECT_EQ(answer_transports[1].description.ice_pwd,
1351             local_transports[1].description.ice_pwd);
1352 }
1353 
1354 // Test that when the initial offerer (caller) uses the lite implementation of
1355 // ICE and the callee uses the full implementation, the caller takes the
1356 // CONTROLLED role and the callee takes the CONTROLLING role. This is specified
1357 // in RFC5245 Section 5.1.1.
TEST_P(PeerConnectionIceTest,OfferFromLiteIceControlledAndAnswerFromFullIceControlling)1358 TEST_P(PeerConnectionIceTest,
1359        OfferFromLiteIceControlledAndAnswerFromFullIceControlling) {
1360   auto caller = CreatePeerConnectionWithAudioVideo();
1361   auto callee = CreatePeerConnectionWithAudioVideo();
1362 
1363   auto offer = caller->CreateOffer();
1364   SetIceMode(offer.get(), cricket::IceMode::ICEMODE_LITE);
1365   ASSERT_TRUE(
1366       caller->SetLocalDescription(CloneSessionDescription(offer.get())));
1367   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1368 
1369   auto answer = callee->CreateAnswer();
1370   SetIceMode(answer.get(), cricket::IceMode::ICEMODE_FULL);
1371   ASSERT_TRUE(
1372       callee->SetLocalDescription(CloneSessionDescription(answer.get())));
1373   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
1374 
1375   EXPECT_EQ(cricket::ICEROLE_CONTROLLED, GetIceRole(caller));
1376   EXPECT_EQ(cricket::ICEROLE_CONTROLLING, GetIceRole(callee));
1377 }
1378 
1379 // Test that when the caller and the callee both use the lite implementation of
1380 // ICE, the initial offerer (caller) takes the CONTROLLING role and the callee
1381 // takes the CONTROLLED role. This is specified in RFC5245 Section 5.1.1.
TEST_P(PeerConnectionIceTest,OfferFromLiteIceControllingAndAnswerFromLiteIceControlled)1382 TEST_P(PeerConnectionIceTest,
1383        OfferFromLiteIceControllingAndAnswerFromLiteIceControlled) {
1384   auto caller = CreatePeerConnectionWithAudioVideo();
1385   auto callee = CreatePeerConnectionWithAudioVideo();
1386 
1387   auto offer = caller->CreateOffer();
1388   SetIceMode(offer.get(), cricket::IceMode::ICEMODE_LITE);
1389   ASSERT_TRUE(
1390       caller->SetLocalDescription(CloneSessionDescription(offer.get())));
1391   ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
1392 
1393   auto answer = callee->CreateAnswer();
1394   SetIceMode(answer.get(), cricket::IceMode::ICEMODE_LITE);
1395   ASSERT_TRUE(
1396       callee->SetLocalDescription(CloneSessionDescription(answer.get())));
1397   ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer)));
1398 
1399   EXPECT_EQ(cricket::ICEROLE_CONTROLLING, GetIceRole(caller));
1400   EXPECT_EQ(cricket::ICEROLE_CONTROLLED, GetIceRole(callee));
1401 }
1402 
1403 INSTANTIATE_TEST_SUITE_P(PeerConnectionIceTest,
1404                          PeerConnectionIceTest,
1405                          Values(SdpSemantics::kPlanB_DEPRECATED,
1406                                 SdpSemantics::kUnifiedPlan));
1407 
1408 class PeerConnectionIceConfigTest : public ::testing::Test {
1409  public:
PeerConnectionIceConfigTest()1410   PeerConnectionIceConfigTest()
1411       : socket_server_(rtc::CreateDefaultSocketServer()),
1412         main_thread_(socket_server_.get()) {}
1413 
1414  protected:
SetUp()1415   void SetUp() override {
1416     pc_factory_ = CreatePeerConnectionFactory(
1417         rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
1418         FakeAudioCaptureModule::Create(), CreateBuiltinAudioEncoderFactory(),
1419         CreateBuiltinAudioDecoderFactory(), CreateBuiltinVideoEncoderFactory(),
1420         CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
1421         nullptr /* audio_processing */);
1422   }
CreatePeerConnection(const RTCConfiguration & config)1423   void CreatePeerConnection(const RTCConfiguration& config) {
1424     packet_socket_factory_.reset(
1425         new rtc::BasicPacketSocketFactory(socket_server_.get()));
1426     std::unique_ptr<cricket::FakePortAllocator> port_allocator(
1427         new cricket::FakePortAllocator(rtc::Thread::Current(),
1428                                        packet_socket_factory_.get()));
1429     port_allocator_ = port_allocator.get();
1430     port_allocator_->SetIceTiebreaker(kTiebreakerDefault);
1431     PeerConnectionDependencies pc_dependencies(&observer_);
1432     pc_dependencies.allocator = std::move(port_allocator);
1433     auto result = pc_factory_->CreatePeerConnectionOrError(
1434         config, std::move(pc_dependencies));
1435     EXPECT_TRUE(result.ok());
1436     pc_ = result.MoveValue();
1437   }
1438 
1439   std::unique_ptr<rtc::SocketServer> socket_server_;
1440   rtc::AutoSocketServerThread main_thread_;
1441   rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_ = nullptr;
1442   rtc::scoped_refptr<PeerConnectionInterface> pc_ = nullptr;
1443   std::unique_ptr<rtc::PacketSocketFactory> packet_socket_factory_;
1444   cricket::FakePortAllocator* port_allocator_ = nullptr;
1445 
1446   MockPeerConnectionObserver observer_;
1447 };
1448 
TEST_F(PeerConnectionIceConfigTest,SetStunCandidateKeepaliveInterval)1449 TEST_F(PeerConnectionIceConfigTest, SetStunCandidateKeepaliveInterval) {
1450   RTCConfiguration config;
1451   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
1452   config.stun_candidate_keepalive_interval = 123;
1453   config.ice_candidate_pool_size = 1;
1454   CreatePeerConnection(config);
1455   ASSERT_NE(port_allocator_, nullptr);
1456   absl::optional<int> actual_stun_keepalive_interval =
1457       port_allocator_->stun_candidate_keepalive_interval();
1458   EXPECT_EQ(actual_stun_keepalive_interval.value_or(-1), 123);
1459   config.stun_candidate_keepalive_interval = 321;
1460   ASSERT_TRUE(pc_->SetConfiguration(config).ok());
1461   actual_stun_keepalive_interval =
1462       port_allocator_->stun_candidate_keepalive_interval();
1463   EXPECT_EQ(actual_stun_keepalive_interval.value_or(-1), 321);
1464 }
1465 
TEST_F(PeerConnectionIceConfigTest,SetStableWritableConnectionInterval)1466 TEST_F(PeerConnectionIceConfigTest, SetStableWritableConnectionInterval) {
1467   RTCConfiguration config;
1468   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
1469   config.stable_writable_connection_ping_interval_ms = 3500;
1470   CreatePeerConnection(config);
1471   EXPECT_TRUE(pc_->SetConfiguration(config).ok());
1472   EXPECT_EQ(pc_->GetConfiguration().stable_writable_connection_ping_interval_ms,
1473             config.stable_writable_connection_ping_interval_ms);
1474 }
1475 
TEST_F(PeerConnectionIceConfigTest,SetStableWritableConnectionInterval_FailsValidation)1476 TEST_F(PeerConnectionIceConfigTest,
1477        SetStableWritableConnectionInterval_FailsValidation) {
1478   RTCConfiguration config;
1479   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
1480   CreatePeerConnection(config);
1481   ASSERT_TRUE(pc_->SetConfiguration(config).ok());
1482   config.stable_writable_connection_ping_interval_ms = 5000;
1483   config.ice_check_interval_strong_connectivity = 7500;
1484   EXPECT_FALSE(pc_->SetConfiguration(config).ok());
1485 }
1486 
TEST_F(PeerConnectionIceConfigTest,SetStableWritableConnectionInterval_DefaultValue_FailsValidation)1487 TEST_F(PeerConnectionIceConfigTest,
1488        SetStableWritableConnectionInterval_DefaultValue_FailsValidation) {
1489   RTCConfiguration config;
1490   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
1491   CreatePeerConnection(config);
1492   ASSERT_TRUE(pc_->SetConfiguration(config).ok());
1493   config.ice_check_interval_strong_connectivity = 2500;
1494   EXPECT_TRUE(pc_->SetConfiguration(config).ok());
1495   config.ice_check_interval_strong_connectivity = 2501;
1496   EXPECT_FALSE(pc_->SetConfiguration(config).ok());
1497 }
1498 
TEST_P(PeerConnectionIceTest,IceCredentialsCreateOffer)1499 TEST_P(PeerConnectionIceTest, IceCredentialsCreateOffer) {
1500   RTCConfiguration config;
1501   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
1502   config.ice_candidate_pool_size = 1;
1503   auto pc = CreatePeerConnectionWithAudioVideo(config);
1504   ASSERT_NE(pc->port_allocator_, nullptr);
1505   auto offer = pc->CreateOffer();
1506   auto credentials = pc->port_allocator_->GetPooledIceCredentials();
1507   ASSERT_EQ(1u, credentials.size());
1508 
1509   auto* desc = offer->description();
1510   for (const auto& content : desc->contents()) {
1511     auto* transport_info = desc->GetTransportInfoByName(content.name);
1512     EXPECT_EQ(transport_info->description.ice_ufrag, credentials[0].ufrag);
1513     EXPECT_EQ(transport_info->description.ice_pwd, credentials[0].pwd);
1514   }
1515 }
1516 
TEST_P(PeerConnectionIceTest,IceCredentialsCreateAnswer)1517 TEST_P(PeerConnectionIceTest, IceCredentialsCreateAnswer) {
1518   RTCConfiguration config;
1519   config.sdp_semantics = SdpSemantics::kUnifiedPlan;
1520   config.ice_candidate_pool_size = 1;
1521   auto pc = CreatePeerConnectionWithAudioVideo(config);
1522   ASSERT_NE(pc->port_allocator_, nullptr);
1523   auto offer = pc->CreateOffer();
1524   ASSERT_TRUE(pc->SetRemoteDescription(std::move(offer)));
1525   auto answer = pc->CreateAnswer();
1526 
1527   auto credentials = pc->port_allocator_->GetPooledIceCredentials();
1528   ASSERT_EQ(1u, credentials.size());
1529 
1530   auto* desc = answer->description();
1531   for (const auto& content : desc->contents()) {
1532     auto* transport_info = desc->GetTransportInfoByName(content.name);
1533     EXPECT_EQ(transport_info->description.ice_ufrag, credentials[0].ufrag);
1534     EXPECT_EQ(transport_info->description.ice_pwd, credentials[0].pwd);
1535   }
1536 }
1537 
1538 // Regression test for https://bugs.chromium.org/p/webrtc/issues/detail?id=4728
TEST_P(PeerConnectionIceTest,CloseDoesNotTransitionGatheringStateToComplete)1539 TEST_P(PeerConnectionIceTest, CloseDoesNotTransitionGatheringStateToComplete) {
1540   auto pc = CreatePeerConnectionWithAudioVideo();
1541   pc->pc()->Close();
1542   EXPECT_FALSE(pc->IsIceGatheringDone());
1543   EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
1544             pc->pc()->ice_gathering_state());
1545 }
1546 
TEST_P(PeerConnectionIceTest,PrefersMidOverMLineIndex)1547 TEST_P(PeerConnectionIceTest, PrefersMidOverMLineIndex) {
1548   const SocketAddress kCalleeAddress("1.1.1.1", 1111);
1549 
1550   auto caller = CreatePeerConnectionWithAudioVideo();
1551   auto callee = CreatePeerConnectionWithAudioVideo();
1552 
1553   ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
1554   ASSERT_TRUE(
1555       caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));
1556 
1557   // `candidate.transport_name()` is empty.
1558   cricket::Candidate candidate = CreateLocalUdpCandidate(kCalleeAddress);
1559   auto* audio_content = cricket::GetFirstAudioContent(
1560       caller->pc()->local_description()->description());
1561   std::unique_ptr<IceCandidateInterface> ice_candidate =
1562       CreateIceCandidate(audio_content->name, 65535, candidate);
1563   EXPECT_TRUE(caller->pc()->AddIceCandidate(ice_candidate.get()));
1564   EXPECT_TRUE(caller->pc()->RemoveIceCandidates({candidate}));
1565 }
1566 
1567 }  // namespace webrtc
1568