• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2022 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 // This file is intended for PeerConnection integration tests that are
12 // slow to execute (currently defined as more than 5 seconds per test).
13 
14 #include <stdint.h>
15 
16 #include <memory>
17 #include <string>
18 #include <tuple>
19 #include <utility>
20 #include <vector>
21 
22 #include "absl/algorithm/container.h"
23 #include "absl/strings/string_view.h"
24 #include "absl/types/optional.h"
25 #include "api/dtmf_sender_interface.h"
26 #include "api/peer_connection_interface.h"
27 #include "api/rtp_receiver_interface.h"
28 #include "api/scoped_refptr.h"
29 #include "api/units/time_delta.h"
30 #include "p2p/base/port_allocator.h"
31 #include "p2p/base/port_interface.h"
32 #include "p2p/base/stun_server.h"
33 #include "p2p/base/test_stun_server.h"
34 #include "pc/test/integration_test_helpers.h"
35 #include "pc/test/mock_peer_connection_observers.h"
36 #include "rtc_base/fake_clock.h"
37 #include "rtc_base/fake_network.h"
38 #include "rtc_base/firewall_socket_server.h"
39 #include "rtc_base/gunit.h"
40 #include "rtc_base/logging.h"
41 #include "rtc_base/socket_address.h"
42 #include "rtc_base/ssl_certificate.h"
43 #include "rtc_base/test_certificate_verifier.h"
44 #include "test/gmock.h"
45 #include "test/gtest.h"
46 
47 namespace webrtc {
48 
49 namespace {
50 
51 class PeerConnectionIntegrationTest
52     : public PeerConnectionIntegrationBaseTest,
53       public ::testing::WithParamInterface<
54           std::tuple<SdpSemantics, std::string>> {
55  protected:
PeerConnectionIntegrationTest()56   PeerConnectionIntegrationTest()
57       : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam()),
58                                           std::get<1>(GetParam())) {}
59 };
60 
61 // Fake clock must be set before threads are started to prevent race on
62 // Set/GetClockForTesting().
63 // To achieve that, multiple inheritance is used as a mixin pattern
64 // where order of construction is finely controlled.
65 // This also ensures peerconnection is closed before switching back to non-fake
66 // clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
67 class FakeClockForTest : public rtc::ScopedFakeClock {
68  protected:
FakeClockForTest()69   FakeClockForTest() {
70     // Some things use a time of "0" as a special value, so we need to start out
71     // the fake clock at a nonzero time.
72     // TODO(deadbeef): Fix this.
73     AdvanceTime(webrtc::TimeDelta::Seconds(1));
74   }
75 
76   // Explicit handle.
FakeClock()77   ScopedFakeClock& FakeClock() { return *this; }
78 };
79 
80 // Ensure FakeClockForTest is constructed first (see class for rationale).
81 class PeerConnectionIntegrationTestWithFakeClock
82     : public FakeClockForTest,
83       public PeerConnectionIntegrationTest {};
84 
85 class PeerConnectionIntegrationTestPlanB
86     : public PeerConnectionIntegrationBaseTest {
87  protected:
PeerConnectionIntegrationTestPlanB()88   PeerConnectionIntegrationTestPlanB()
89       : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
90 };
91 
92 class PeerConnectionIntegrationTestUnifiedPlan
93     : public PeerConnectionIntegrationBaseTest {
94  protected:
PeerConnectionIntegrationTestUnifiedPlan()95   PeerConnectionIntegrationTestUnifiedPlan()
96       : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
97 };
98 
99 // Test the OnFirstPacketReceived callback from audio/video RtpReceivers.  This
100 // includes testing that the callback is invoked if an observer is connected
101 // after the first packet has already been received.
TEST_P(PeerConnectionIntegrationTest,RtpReceiverObserverOnFirstPacketReceived)102 TEST_P(PeerConnectionIntegrationTest,
103        RtpReceiverObserverOnFirstPacketReceived) {
104   ASSERT_TRUE(CreatePeerConnectionWrappers());
105   ConnectFakeSignaling();
106   caller()->AddAudioVideoTracks();
107   callee()->AddAudioVideoTracks();
108   // Start offer/answer exchange and wait for it to complete.
109   caller()->CreateAndSetAndSignalOffer();
110   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
111   // Should be one receiver each for audio/video.
112   EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
113   EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
114   // Wait for all "first packet received" callbacks to be fired.
115   EXPECT_TRUE_WAIT(
116       absl::c_all_of(caller()->rtp_receiver_observers(),
117                      [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
118                        return o->first_packet_received();
119                      }),
120       kMaxWaitForFramesMs);
121   EXPECT_TRUE_WAIT(
122       absl::c_all_of(callee()->rtp_receiver_observers(),
123                      [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
124                        return o->first_packet_received();
125                      }),
126       kMaxWaitForFramesMs);
127   // If new observers are set after the first packet was already received, the
128   // callback should still be invoked.
129   caller()->ResetRtpReceiverObservers();
130   callee()->ResetRtpReceiverObservers();
131   EXPECT_EQ(2U, caller()->rtp_receiver_observers().size());
132   EXPECT_EQ(2U, callee()->rtp_receiver_observers().size());
133   EXPECT_TRUE(
134       absl::c_all_of(caller()->rtp_receiver_observers(),
135                      [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
136                        return o->first_packet_received();
137                      }));
138   EXPECT_TRUE(
139       absl::c_all_of(callee()->rtp_receiver_observers(),
140                      [](const std::unique_ptr<MockRtpReceiverObserver>& o) {
141                        return o->first_packet_received();
142                      }));
143 }
144 
145 class DummyDtmfObserver : public DtmfSenderObserverInterface {
146  public:
DummyDtmfObserver()147   DummyDtmfObserver() : completed_(false) {}
148 
149   // Implements DtmfSenderObserverInterface.
OnToneChange(const std::string & tone)150   void OnToneChange(const std::string& tone) override {
151     tones_.push_back(tone);
152     if (tone.empty()) {
153       completed_ = true;
154     }
155   }
156 
tones() const157   const std::vector<std::string>& tones() const { return tones_; }
completed() const158   bool completed() const { return completed_; }
159 
160  private:
161   bool completed_;
162   std::vector<std::string> tones_;
163 };
164 
TEST_P(PeerConnectionIntegrationTest,SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection)165 TEST_P(PeerConnectionIntegrationTest,
166        SSLCertificateVerifierFailureUsedForTurnConnectionsFailsConnection) {
167   static const rtc::SocketAddress turn_server_internal_address{"88.88.88.0",
168                                                                3478};
169   static const rtc::SocketAddress turn_server_external_address{"88.88.88.1", 0};
170 
171   // Enable TCP-TLS for the fake turn server. We need to pass in 88.88.88.0 so
172   // that host name verification passes on the fake certificate.
173   CreateTurnServer(turn_server_internal_address, turn_server_external_address,
174                    cricket::PROTO_TLS, "88.88.88.0");
175 
176   webrtc::PeerConnectionInterface::IceServer ice_server;
177   ice_server.urls.push_back("turns:88.88.88.0:3478?transport=tcp");
178   ice_server.username = "test";
179   ice_server.password = "test";
180 
181   PeerConnectionInterface::RTCConfiguration client_1_config;
182   client_1_config.servers.push_back(ice_server);
183   client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
184 
185   PeerConnectionInterface::RTCConfiguration client_2_config;
186   client_2_config.servers.push_back(ice_server);
187   // Setting the type to kRelay forces the connection to go through a TURN
188   // server.
189   client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
190 
191   // Get a copy to the pointer so we can verify calls later.
192   rtc::TestCertificateVerifier* client_1_cert_verifier =
193       new rtc::TestCertificateVerifier();
194   client_1_cert_verifier->verify_certificate_ = false;
195   rtc::TestCertificateVerifier* client_2_cert_verifier =
196       new rtc::TestCertificateVerifier();
197   client_2_cert_verifier->verify_certificate_ = false;
198 
199   // Create the dependencies with the test certificate verifier.
200   webrtc::PeerConnectionDependencies client_1_deps(nullptr);
201   client_1_deps.tls_cert_verifier =
202       std::unique_ptr<rtc::TestCertificateVerifier>(client_1_cert_verifier);
203   webrtc::PeerConnectionDependencies client_2_deps(nullptr);
204   client_2_deps.tls_cert_verifier =
205       std::unique_ptr<rtc::TestCertificateVerifier>(client_2_cert_verifier);
206 
207   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps(
208       client_1_config, std::move(client_1_deps), client_2_config,
209       std::move(client_2_deps)));
210   ConnectFakeSignaling();
211 
212   // Set "offer to receive audio/video" without adding any tracks, so we just
213   // set up ICE/DTLS with no media.
214   PeerConnectionInterface::RTCOfferAnswerOptions options;
215   options.offer_to_receive_audio = 1;
216   options.offer_to_receive_video = 1;
217   caller()->SetOfferAnswerOptions(options);
218   caller()->CreateAndSetAndSignalOffer();
219   bool wait_res = true;
220   // TODO(bugs.webrtc.org/9219): When IceConnectionState is implemented
221   // properly, should be able to just wait for a state of "failed" instead of
222   // waiting a fixed 10 seconds.
223   WAIT_(DtlsConnected(), kDefaultTimeout, wait_res);
224   ASSERT_FALSE(wait_res);
225 
226   EXPECT_GT(client_1_cert_verifier->call_count_, 0u);
227   EXPECT_GT(client_2_cert_verifier->call_count_, 0u);
228 }
229 
230 // Test that we can get capture start ntp time.
TEST_P(PeerConnectionIntegrationTest,GetCaptureStartNtpTimeWithOldStatsApi)231 TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) {
232   ASSERT_TRUE(CreatePeerConnectionWrappers());
233   ConnectFakeSignaling();
234   caller()->AddAudioTrack();
235 
236   callee()->AddAudioTrack();
237 
238   // Do offer/answer, wait for the callee to receive some frames.
239   caller()->CreateAndSetAndSignalOffer();
240   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
241 
242   // Get the remote audio track created on the receiver, so they can be used as
243   // GetStats filters.
244   auto receivers = callee()->pc()->GetReceivers();
245   ASSERT_EQ(1u, receivers.size());
246   auto remote_audio_track = receivers[0]->track();
247 
248   // Get the audio output level stats. Note that the level is not available
249   // until an RTCP packet has been received.
250   EXPECT_TRUE_WAIT(callee()->OldGetStatsForTrack(remote_audio_track.get())
251                            ->CaptureStartNtpTime() > 0,
252                    2 * kMaxWaitForFramesMs);
253 }
254 
255 // Test that firewalling the ICE connection causes the clients to identify the
256 // disconnected state and then removing the firewall causes them to reconnect.
257 class PeerConnectionIntegrationIceStatesTest
258     : public PeerConnectionIntegrationBaseTest,
259       public ::testing::WithParamInterface<
260           std::tuple<SdpSemantics, std::tuple<std::string, uint32_t>>> {
261  protected:
PeerConnectionIntegrationIceStatesTest()262   PeerConnectionIntegrationIceStatesTest()
263       : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())) {
264     port_allocator_flags_ = std::get<1>(std::get<1>(GetParam()));
265   }
266 
StartStunServer(const SocketAddress & server_address)267   void StartStunServer(const SocketAddress& server_address) {
268     stun_server_.reset(
269         cricket::TestStunServer::Create(firewall(), server_address));
270   }
271 
TestIPv6()272   bool TestIPv6() {
273     return (port_allocator_flags_ & cricket::PORTALLOCATOR_ENABLE_IPV6);
274   }
275 
SetPortAllocatorFlags()276   void SetPortAllocatorFlags() {
277     PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags(
278         port_allocator_flags_, port_allocator_flags_);
279   }
280 
CallerAddresses()281   std::vector<SocketAddress> CallerAddresses() {
282     std::vector<SocketAddress> addresses;
283     addresses.push_back(SocketAddress("1.1.1.1", 0));
284     if (TestIPv6()) {
285       addresses.push_back(SocketAddress("1111:0:a:b:c:d:e:f", 0));
286     }
287     return addresses;
288   }
289 
CalleeAddresses()290   std::vector<SocketAddress> CalleeAddresses() {
291     std::vector<SocketAddress> addresses;
292     addresses.push_back(SocketAddress("2.2.2.2", 0));
293     if (TestIPv6()) {
294       addresses.push_back(SocketAddress("2222:0:a:b:c:d:e:f", 0));
295     }
296     return addresses;
297   }
298 
SetUpNetworkInterfaces()299   void SetUpNetworkInterfaces() {
300     // Remove the default interfaces added by the test infrastructure.
301     caller()->network_manager()->RemoveInterface(kDefaultLocalAddress);
302     callee()->network_manager()->RemoveInterface(kDefaultLocalAddress);
303 
304     // Add network addresses for test.
305     for (const auto& caller_address : CallerAddresses()) {
306       caller()->network_manager()->AddInterface(caller_address);
307     }
308     for (const auto& callee_address : CalleeAddresses()) {
309       callee()->network_manager()->AddInterface(callee_address);
310     }
311   }
312 
313  private:
314   uint32_t port_allocator_flags_;
315   std::unique_ptr<cricket::TestStunServer> stun_server_;
316 };
317 
318 // Ensure FakeClockForTest is constructed first (see class for rationale).
319 class PeerConnectionIntegrationIceStatesTestWithFakeClock
320     : public FakeClockForTest,
321       public PeerConnectionIntegrationIceStatesTest {};
322 
323 #if !defined(THREAD_SANITIZER)
324 // This test provokes TSAN errors. bugs.webrtc.org/11282
325 
326 // Tests that the PeerConnection goes through all the ICE gathering/connection
327 // states over the duration of the call. This includes Disconnected and Failed
328 // states, induced by putting a firewall between the peers and waiting for them
329 // to time out.
TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock,VerifyIceStates)330 TEST_P(PeerConnectionIntegrationIceStatesTestWithFakeClock, VerifyIceStates) {
331   const SocketAddress kStunServerAddress =
332       SocketAddress("99.99.99.1", cricket::STUN_SERVER_PORT);
333   StartStunServer(kStunServerAddress);
334 
335   PeerConnectionInterface::RTCConfiguration config;
336   PeerConnectionInterface::IceServer ice_stun_server;
337   ice_stun_server.urls.push_back(
338       "stun:" + kStunServerAddress.HostAsURIString() + ":" +
339       kStunServerAddress.PortAsString());
340   config.servers.push_back(ice_stun_server);
341 
342   ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(config, config));
343   ConnectFakeSignaling();
344   SetPortAllocatorFlags();
345   SetUpNetworkInterfaces();
346   caller()->AddAudioVideoTracks();
347   callee()->AddAudioVideoTracks();
348 
349   // Initial state before anything happens.
350   ASSERT_EQ(PeerConnectionInterface::kIceGatheringNew,
351             caller()->ice_gathering_state());
352   ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
353             caller()->ice_connection_state());
354   ASSERT_EQ(PeerConnectionInterface::kIceConnectionNew,
355             caller()->standardized_ice_connection_state());
356 
357   // Start the call by creating the offer, setting it as the local description,
358   // then sending it to the peer who will respond with an answer. This happens
359   // asynchronously so that we can watch the states as it runs in the
360   // background.
361   caller()->CreateAndSetAndSignalOffer();
362 
363   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
364                            caller()->ice_connection_state(), kDefaultTimeout,
365                            FakeClock());
366   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
367                            caller()->standardized_ice_connection_state(),
368                            kDefaultTimeout, FakeClock());
369 
370   // Verify that the observer was notified of the intermediate transitions.
371   EXPECT_THAT(caller()->ice_connection_state_history(),
372               ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
373                           PeerConnectionInterface::kIceConnectionConnected,
374                           PeerConnectionInterface::kIceConnectionCompleted));
375   EXPECT_THAT(caller()->standardized_ice_connection_state_history(),
376               ElementsAre(PeerConnectionInterface::kIceConnectionChecking,
377                           PeerConnectionInterface::kIceConnectionConnected,
378                           PeerConnectionInterface::kIceConnectionCompleted));
379   EXPECT_THAT(
380       caller()->peer_connection_state_history(),
381       ElementsAre(PeerConnectionInterface::PeerConnectionState::kConnecting,
382                   PeerConnectionInterface::PeerConnectionState::kConnected));
383   EXPECT_THAT(caller()->ice_gathering_state_history(),
384               ElementsAre(PeerConnectionInterface::kIceGatheringGathering,
385                           PeerConnectionInterface::kIceGatheringComplete));
386 
387   // Block connections to/from the caller and wait for ICE to become
388   // disconnected.
389   for (const auto& caller_address : CallerAddresses()) {
390     firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
391   }
392   RTC_LOG(LS_INFO) << "Firewall rules applied";
393   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
394                            caller()->ice_connection_state(), kDefaultTimeout,
395                            FakeClock());
396   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
397                            caller()->standardized_ice_connection_state(),
398                            kDefaultTimeout, FakeClock());
399 
400   // Let ICE re-establish by removing the firewall rules.
401   firewall()->ClearRules();
402   RTC_LOG(LS_INFO) << "Firewall rules cleared";
403   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
404                            caller()->ice_connection_state(), kDefaultTimeout,
405                            FakeClock());
406   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
407                            caller()->standardized_ice_connection_state(),
408                            kDefaultTimeout, FakeClock());
409 
410   // According to RFC7675, if there is no response within 30 seconds then the
411   // peer should consider the other side to have rejected the connection. This
412   // is signaled by the state transitioning to "failed".
413   constexpr int kConsentTimeout = 30000;
414   for (const auto& caller_address : CallerAddresses()) {
415     firewall()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, caller_address);
416   }
417   RTC_LOG(LS_INFO) << "Firewall rules applied again";
418   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
419                            caller()->ice_connection_state(), kConsentTimeout,
420                            FakeClock());
421   ASSERT_EQ_SIMULATED_WAIT(PeerConnectionInterface::kIceConnectionFailed,
422                            caller()->standardized_ice_connection_state(),
423                            kConsentTimeout, FakeClock());
424 }
425 #endif
426 
427 // This test sets up a call that's transferred to a new caller with a different
428 // DTLS fingerprint.
TEST_P(PeerConnectionIntegrationTest,CallTransferredForCallee)429 TEST_P(PeerConnectionIntegrationTest, CallTransferredForCallee) {
430   ASSERT_TRUE(CreatePeerConnectionWrappers());
431   ConnectFakeSignaling();
432   caller()->AddAudioVideoTracks();
433   callee()->AddAudioVideoTracks();
434   caller()->CreateAndSetAndSignalOffer();
435   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
436 
437   // Keep the original peer around which will still send packets to the
438   // receiving client. These SRTP packets will be dropped.
439   std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
440       SetCallerPcWrapperAndReturnCurrent(
441           CreatePeerConnectionWrapperWithAlternateKey().release()));
442   // TODO(deadbeef): Why do we call Close here? That goes against the comment
443   // directly above.
444   original_peer->pc()->Close();
445 
446   ConnectFakeSignaling();
447   caller()->AddAudioVideoTracks();
448   caller()->CreateAndSetAndSignalOffer();
449   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
450   // Wait for some additional frames to be transmitted end-to-end.
451   MediaExpectations media_expectations;
452   media_expectations.ExpectBidirectionalAudioAndVideo();
453   ASSERT_TRUE(ExpectNewFrames(media_expectations));
454 }
455 
456 // This test sets up a call that's transferred to a new callee with a different
457 // DTLS fingerprint.
TEST_P(PeerConnectionIntegrationTest,CallTransferredForCaller)458 TEST_P(PeerConnectionIntegrationTest, CallTransferredForCaller) {
459   ASSERT_TRUE(CreatePeerConnectionWrappers());
460   ConnectFakeSignaling();
461   caller()->AddAudioVideoTracks();
462   callee()->AddAudioVideoTracks();
463   caller()->CreateAndSetAndSignalOffer();
464   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
465 
466   // Keep the original peer around which will still send packets to the
467   // receiving client. These SRTP packets will be dropped.
468   std::unique_ptr<PeerConnectionIntegrationWrapper> original_peer(
469       SetCalleePcWrapperAndReturnCurrent(
470           CreatePeerConnectionWrapperWithAlternateKey().release()));
471   // TODO(deadbeef): Why do we call Close here? That goes against the comment
472   // directly above.
473   original_peer->pc()->Close();
474 
475   ConnectFakeSignaling();
476   callee()->AddAudioVideoTracks();
477   caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
478   caller()->CreateAndSetAndSignalOffer();
479   ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
480   // Wait for some additional frames to be transmitted end-to-end.
481   MediaExpectations media_expectations;
482   media_expectations.ExpectBidirectionalAudioAndVideo();
483   ASSERT_TRUE(ExpectNewFrames(media_expectations));
484 }
485 
486 INSTANTIATE_TEST_SUITE_P(
487     PeerConnectionIntegrationTest,
488     PeerConnectionIntegrationTest,
489     Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
490             Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
491                    "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
492                    "WebRTC-FrameBuffer3/arm:SyncDecoding/")));
493 
494 constexpr uint32_t kFlagsIPv4NoStun = cricket::PORTALLOCATOR_DISABLE_TCP |
495                                       cricket::PORTALLOCATOR_DISABLE_STUN |
496                                       cricket::PORTALLOCATOR_DISABLE_RELAY;
497 constexpr uint32_t kFlagsIPv6NoStun =
498     cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_STUN |
499     cricket::PORTALLOCATOR_ENABLE_IPV6 | cricket::PORTALLOCATOR_DISABLE_RELAY;
500 constexpr uint32_t kFlagsIPv4Stun =
501     cricket::PORTALLOCATOR_DISABLE_TCP | cricket::PORTALLOCATOR_DISABLE_RELAY;
502 
503 INSTANTIATE_TEST_SUITE_P(
504     PeerConnectionIntegrationTest,
505     PeerConnectionIntegrationIceStatesTestWithFakeClock,
506     Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
507             Values(std::make_pair("IPv4 no STUN", kFlagsIPv4NoStun),
508                    std::make_pair("IPv6 no STUN", kFlagsIPv6NoStun),
509                    std::make_pair("IPv4 with STUN", kFlagsIPv4Stun))));
510 
511 }  // namespace
512 }  // namespace webrtc
513