/*
 *  Copyright 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <atomic>
#include <cstdint>
#include <cstdlib>
#include <iterator>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "api/data_channel_interface.h"
#include "api/dtls_transport_interface.h"
#include "api/jsep.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/scoped_refptr.h"
#include "api/sctp_transport_interface.h"
#include "api/stats/rtc_stats_report.h"
#include "api/stats/rtcstats_objects.h"
#include "api/test/rtc_error_matchers.h"
#include "api/units/time_delta.h"
#include "p2p/base/transport_description.h"
#include "p2p/base/transport_info.h"
#include "p2p/test/test_turn_server.h"
#include "pc/media_session.h"
#include "pc/session_description.h"
#include "pc/test/fake_rtc_certificate_generator.h"
#include "pc/test/integration_test_helpers.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/crypto_random.h"
#include "rtc_base/fake_clock.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/virtual_socket_server.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/run_loop.h"
#include "test/wait_until.h"

namespace webrtc {

namespace {

using ::testing::Eq;
using ::testing::IsTrue;
using ::testing::Ne;
using ::testing::NotNull;
using ::testing::ValuesIn;

// All tests in this file require SCTP support.
#ifdef WEBRTC_HAVE_SCTP

#if defined(WEBRTC_ANDROID)
// Disable heavy tests running on low-end Android devices.
#define DISABLED_ON_ANDROID(t) DISABLED_##t
#else
#define DISABLED_ON_ANDROID(t) t
#endif

void VerifySctpState(PeerConnectionIntegrationWrapper* pc,
                     SctpTransportState expected_state) {
  auto sctp_transport = pc->pc()->GetSctpTransport();
  ASSERT_TRUE(sctp_transport);
  EXPECT_EQ(sctp_transport->Information().state(), expected_state);
}

class DataChannelIntegrationTest
    : public PeerConnectionIntegrationBaseTest,
      public ::testing::WithParamInterface<std::tuple<SdpSemantics, bool>> {
 protected:
  DataChannelIntegrationTest()
      : PeerConnectionIntegrationBaseTest(std::get<0>(GetParam())),
        allow_media_(std::get<1>(GetParam())) {}
  bool allow_media() { return allow_media_; }

  bool CreatePeerConnectionWrappers() {
    if (allow_media_) {
      return PeerConnectionIntegrationBaseTest::CreatePeerConnectionWrappers();
    }
    return PeerConnectionIntegrationBaseTest::
        CreatePeerConnectionWrappersWithoutMediaEngine();
  }

 private:
  // True if media is allowed to be added
  const bool allow_media_;
};

// Fake clock must be set before threads are started to prevent race on
// Set/GetClockForTesting().
// To achieve that, multiple inheritance is used as a mixin pattern
// where order of construction is finely controlled.
// This also ensures peerconnection is closed before switching back to non-fake
// clock, avoiding other races and DCHECK failures such as in rtp_sender.cc.
class FakeClockForTest : public ScopedFakeClock {
 protected:
  FakeClockForTest() {
    // Some things use a time of "0" as a special value, so we need to start out
    // the fake clock at a nonzero time.
    // TODO(deadbeef): Fix this.
    AdvanceTime(TimeDelta::Seconds(1));
  }

  // Explicit handle.
  ScopedFakeClock& FakeClock() { return *this; }
};

class DataChannelIntegrationTestPlanB
    : public PeerConnectionIntegrationBaseTest {
 protected:
  DataChannelIntegrationTestPlanB()
      : PeerConnectionIntegrationBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
};

class DataChannelIntegrationTestUnifiedPlan
    : public PeerConnectionIntegrationBaseTest {
 protected:
  DataChannelIntegrationTestUnifiedPlan()
      : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
};

void MakeOfferHaveActiveDtlsRole(
    std::unique_ptr<SessionDescriptionInterface>& desc) {
  auto& transport_infos = desc->description()->transport_infos();
  for (auto& transport_info : transport_infos) {
    transport_info.description.connection_role = CONNECTIONROLE_ACTIVE;
  }
}

void MakeOfferHavePassiveDtlsRole(
    std::unique_ptr<SessionDescriptionInterface>& desc) {
  auto& transport_infos = desc->description()->transport_infos();
  for (auto& transport_info : transport_infos) {
    transport_info.description.connection_role = CONNECTIONROLE_PASSIVE;
  }
}

// This test causes a PeerConnection to enter Disconnected state, and
// sends data on a DataChannel while disconnected.
// The data should be surfaced when the connection reestablishes.
TEST_P(DataChannelIntegrationTest, DataChannelWhileDisconnected) {
  CreatePeerConnectionWrappers();
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_observer(); }, IsTrue()),
              IsRtcOk());
  std::string data1 = "hello first";
  caller()->data_channel()->Send(DataBuffer(data1));
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq(data1)),
      IsRtcOk());
  // Cause a network outage
  virtual_socket_server()->set_drop_probability(1.0);
  EXPECT_THAT(
      WaitUntil([&] { return caller()->standardized_ice_connection_state(); },
                Eq(PeerConnectionInterface::kIceConnectionDisconnected),
                {.timeout = TimeDelta::Seconds(10)}),
      IsRtcOk());
  std::string data2 = "hello second";
  caller()->data_channel()->Send(DataBuffer(data2));
  // Remove the network outage. The connection should reestablish.
  virtual_socket_server()->set_drop_probability(0.0);
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq(data2)),
      IsRtcOk());
}

// This test causes a PeerConnection to enter Disconnected state,
// sends data on a DataChannel while disconnected, and then triggers
// an ICE restart.
// The data should be surfaced when the connection reestablishes.
TEST_P(DataChannelIntegrationTest, DataChannelWhileDisconnectedIceRestart) {
  CreatePeerConnectionWrappers();
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_observer(); }, IsTrue()),
              IsRtcOk());
  std::string data1 = "hello first";
  caller()->data_channel()->Send(DataBuffer(data1));
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq(data1)),
      IsRtcOk());
  // Cause a network outage
  virtual_socket_server()->set_drop_probability(1.0);
  ASSERT_THAT(
      WaitUntil([&] { return caller()->standardized_ice_connection_state(); },
                Eq(PeerConnectionInterface::kIceConnectionDisconnected),
                {.timeout = TimeDelta::Seconds(10)}),
      IsRtcOk());
  std::string data2 = "hello second";
  caller()->data_channel()->Send(DataBuffer(data2));

  // Trigger an ICE restart. The signaling channel is not affected by
  // the network outage.
  caller()->SetOfferAnswerOptions(IceRestartOfferAnswerOptions());
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Remove the network outage. The connection should reestablish.
  virtual_socket_server()->set_drop_probability(0.0);
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq(data2)),
      IsRtcOk());
}

// This test sets up a call between two parties with audio, video and an SCTP
// data channel.
TEST_P(DataChannelIntegrationTest, EndToEndCallWithSctpDataChannel) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  // Expect that data channel created on caller side will show up for callee as
  // well.
  caller()->CreateDataChannel();
  if (allow_media()) {
    caller()->AddAudioVideoTracks();
    callee()->AddAudioVideoTracks();
  }
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  if (allow_media()) {
    // Ensure the existence of the SCTP data channel didn't impede audio/video.
    MediaExpectations media_expectations;
    media_expectations.ExpectBidirectionalAudioAndVideo();
    ASSERT_TRUE(ExpectNewFrames(media_expectations));
  }
  // Caller data channel should already exist (it created one). Callee data
  // channel may not exist yet, since negotiation happens in-band, not in SDP.
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  // Ensure data can be sent in both directions.
  std::string data = "hello world";
  caller()->data_channel()->Send(DataBuffer(data));
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq(data)),
      IsRtcOk());
  callee()->data_channel()->Send(DataBuffer(data));
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->last_message(); },
                Eq(data)),
      IsRtcOk());
}

// This test sets up a call between two parties with an SCTP
// data channel only, and sends messages of various sizes.
TEST_P(DataChannelIntegrationTest,
       EndToEndCallWithSctpDataChannelVariousSizes) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  // Expect that data channel created on caller side will show up for callee as
  // well.
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Caller data channel should already exist (it created one). Callee data
  // channel may not exist yet, since negotiation happens in-band, not in SDP.
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  // Expect that all sizes under kSctpSendBufferSize(256 * 1024) to be sent
  // without any issue.
  for (int message_size = 1; message_size <= kSctpSendBufferSize;
       message_size *= 2) {
    std::string data(message_size, 'a');
    caller()->data_channel()->Send(DataBuffer(data));
    EXPECT_THAT(
        WaitUntil([&] { return callee()->data_observer()->last_message(); },
                  Eq(data)),
        IsRtcOk());
    callee()->data_channel()->Send(DataBuffer(data));
    EXPECT_THAT(
        WaitUntil([&] { return caller()->data_observer()->last_message(); },
                  Eq(data)),
        IsRtcOk());
  }
  // Specifically probe the area around the MTU size.
  for (int message_size = 1100; message_size < 1300; message_size += 1) {
    std::string data(message_size, 'a');
    caller()->data_channel()->Send(DataBuffer(data));
    EXPECT_THAT(
        WaitUntil([&] { return callee()->data_observer()->last_message(); },
                  Eq(data)),
        IsRtcOk());
    callee()->data_channel()->Send(DataBuffer(data));
    EXPECT_THAT(
        WaitUntil([&] { return caller()->data_observer()->last_message(); },
                  Eq(data)),
        IsRtcOk());
  }
  caller()->data_channel()->Close();

  EXPECT_THAT(WaitUntil([&] { return caller()->data_observer()->state(); },
                        Eq(DataChannelInterface::kClosed)),
              IsRtcOk());
  EXPECT_THAT(WaitUntil([&] { return callee()->data_observer()->state(); },
                        Eq(DataChannelInterface::kClosed)),
              IsRtcOk());
}

// This test sets up a call between two parties with an SCTP
// data channel only, and sends a message exceeding the default size limit
// kSctpSendBufferSize(256 * 1024). We expect the Send method returns
// false and the channel closes.
TEST_P(DataChannelIntegrationTest,
       EndToEndCallWithSctpDataChannelOversizedMessage) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  // Expect that data channel created on caller side will show up for callee as
  // well.
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Caller data channel should already exist (it created one). Callee data
  // channel may not exist yet, since negotiation happens in-band, not in SDP.
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  // By default, SDP would set kSctpSendBufferSize as the size limit for the
  // transport. Expect that a longer message will not be sent and cause the
  // channel to be closed by error.
  std::string data(kSctpSendBufferSize + 1, 'a');
  EXPECT_FALSE(caller()->data_channel()->Send(DataBuffer(data)));
  EXPECT_EQ(caller()->data_channel()->state(), DataChannelInterface::kClosed);
  RTCError last_error = caller()->data_channel()->error();
  EXPECT_FALSE(last_error.ok());
  EXPECT_FALSE(std::string(last_error.message()).empty());
  EXPECT_EQ(RTCErrorType::NETWORK_ERROR, last_error.type());
}

// This test sets up a call between two parties with an SCTP
// data channel only, and sends enough messages to fill the queue and then
// closes on the caller. We expect the state to transition to closed on both
// caller and callee.
TEST_P(DataChannelIntegrationTest, EndToEndCallWithSctpDataChannelFullBuffer) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  // Expect that data channel created on caller side will show up for callee as
  // well.
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Caller data channel should already exist (it created one). Callee data
  // channel may not exist yet, since negotiation happens in-band, not in SDP.
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  std::string data(256 * 1024, 'a');
  for (size_t queued_size = 0;
       queued_size < DataChannelInterface::MaxSendQueueSize();
       queued_size += data.size()) {
    caller()->data_channel()->SendAsync(DataBuffer(data), nullptr);
  }

  caller()->data_channel()->Close();

  DataChannelInterface::DataState expected_states[] = {
      DataChannelInterface::DataState::kConnecting,
      DataChannelInterface::DataState::kOpen,
      DataChannelInterface::DataState::kClosing,
      DataChannelInterface::DataState::kClosed};

  // Debug data channels are very slow, use a long timeout for those slow,
  // heavily parallelized runs.
  EXPECT_THAT(WaitUntil([&] { return caller()->data_observer()->state(); },
                        Eq(DataChannelInterface::DataState::kClosed),
                        {.timeout = kLongTimeout}),
              IsRtcOk());
  EXPECT_THAT(caller()->data_observer()->states(),
              ::testing::ElementsAreArray(expected_states));

  EXPECT_THAT(WaitUntil([&] { return callee()->data_observer()->state(); },
                        Eq(DataChannelInterface::DataState::kClosed)),
              IsRtcOk());
  EXPECT_THAT(callee()->data_observer()->states(),
              ::testing::ElementsAreArray(expected_states));
}

// This test sets up a call between two parties with an SCTP
// data channel only, and sends empty messages
TEST_P(DataChannelIntegrationTest,
       EndToEndCallWithSctpDataChannelEmptyMessages) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  // Expect that data channel created on caller side will show up for callee as
  // well.
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Caller data channel should already exist (it created one). Callee data
  // channel may not exist yet, since negotiation happens in-band, not in SDP.
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  // Ensure data can be sent in both directions.
  // Sending empty string data
  std::string data = "";
  caller()->data_channel()->Send(DataBuffer(data));
  EXPECT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(1u)),
      IsRtcOk());
  EXPECT_TRUE(callee()->data_observer()->last_message().empty());
  EXPECT_FALSE(callee()->data_observer()->messages().back().binary);
  callee()->data_channel()->Send(DataBuffer(data));
  EXPECT_THAT(
      WaitUntil(
          [&] { return caller()->data_observer()->received_message_count(); },
          Eq(1u)),
      IsRtcOk());
  EXPECT_TRUE(caller()->data_observer()->last_message().empty());
  EXPECT_FALSE(caller()->data_observer()->messages().back().binary);

  // Sending empty binary data
  CopyOnWriteBuffer empty_buffer;
  caller()->data_channel()->Send(DataBuffer(empty_buffer, true));
  EXPECT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(2u)),
      IsRtcOk());
  EXPECT_TRUE(callee()->data_observer()->last_message().empty());
  EXPECT_TRUE(callee()->data_observer()->messages().back().binary);
  callee()->data_channel()->Send(DataBuffer(empty_buffer, true));
  EXPECT_THAT(
      WaitUntil(
          [&] { return caller()->data_observer()->received_message_count(); },
          Eq(2u)),
      IsRtcOk());
  EXPECT_TRUE(caller()->data_observer()->last_message().empty());
  EXPECT_TRUE(caller()->data_observer()->messages().back().binary);
}

TEST_P(DataChannelIntegrationTest,
       EndToEndCallWithSctpDataChannelLowestSafeMtu) {
  // The lowest payload size limit that's tested and found safe for this
  // application. Note that this is not the safe limit under all conditions;
  // in particular, the default is not the largest DTLS signature, and
  // this test does not use TURN.
  const size_t kLowestSafePayloadSizeLimit = 1225;

  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  // Expect that data channel created on caller side will show up for callee as
  // well.
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Caller data channel should already exist (it created one). Callee data
  // channel may not exist yet, since negotiation happens in-band, not in SDP.
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  virtual_socket_server()->set_max_udp_payload(kLowestSafePayloadSizeLimit);
  for (int message_size = 1140; message_size < 1240; message_size += 1) {
    std::string data(message_size, 'a');
    caller()->data_channel()->Send(DataBuffer(data));
    ASSERT_THAT(
        WaitUntil([&] { return callee()->data_observer()->last_message(); },
                  Eq(data)),
        IsRtcOk());
    callee()->data_channel()->Send(DataBuffer(data));
    ASSERT_THAT(
        WaitUntil([&] { return caller()->data_observer()->last_message(); },
                  Eq(data)),
        IsRtcOk());
  }
}

// This test verifies that lowering the MTU of the connection will cause
// the datachannel to not transmit reliably.
// The purpose of this test is to ensure that we know how a too-small MTU
// error manifests itself.
TEST_P(DataChannelIntegrationTest, EndToEndCallWithSctpDataChannelHarmfulMtu) {
  // The lowest payload size limit that's tested and found safe for this
  // application in this configuration (see test above).
  const size_t kLowestSafePayloadSizeLimit = 1225;
  // The size of the smallest message that fails to be delivered.
  const size_t kMessageSizeThatIsNotDelivered = 1157;

  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  if (caller()->tls_version() == kDtls13VersionBytes) {
    ASSERT_EQ(caller()->tls_version(), kDtls13VersionBytes);
    GTEST_SKIP() << "DTLS1.3 fragments packets larger than MTU";
  }

  virtual_socket_server()->set_max_udp_payload(kLowestSafePayloadSizeLimit - 1);
  // Probe for an undelivered or slowly delivered message. The exact
  // size limit seems to be dependent on the message history, so make the
  // code easily able to find the current value.
  bool failure_seen = false;
  for (size_t message_size = 1110; message_size < 1400; message_size++) {
    const size_t message_count =
        callee()->data_observer()->received_message_count();
    const std::string data(message_size, 'a');
    caller()->data_channel()->Send(DataBuffer(data));
    // Wait a very short time for the message to be delivered.
    // Note: Waiting only 10 ms is too short for Windows bots; they will
    // flakily fail at a random frame.
    callee()->data_observer()->set_on_message_callback(
        [&](const DataBuffer&) { run_loop().Quit(); });
    run_loop().RunFor(TimeDelta::Millis(100));
    callee()->data_observer()->set_on_message_callback(nullptr);
    if (callee()->data_observer()->received_message_count() == message_count) {
      ASSERT_EQ(kMessageSizeThatIsNotDelivered, message_size);
      failure_seen = true;
      break;
    }
  }
  ASSERT_TRUE(failure_seen);
}

// Ensure that when the callee closes an SCTP data channel, the closing
// procedure results in the data channel being closed for the caller as well.
TEST_P(DataChannelIntegrationTest, CalleeClosesSctpDataChannel) {
  // Same procedure as above test.
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  if (allow_media()) {
    caller()->AddAudioVideoTracks();
    callee()->AddAudioVideoTracks();
  }
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  // Close the data channel on the callee side, and wait for it to reach the
  // "closed" state on both sides.
  callee()->data_channel()->Close();

  DataChannelInterface::DataState expected_states[] = {
      DataChannelInterface::DataState::kConnecting,
      DataChannelInterface::DataState::kOpen,
      DataChannelInterface::DataState::kClosing,
      DataChannelInterface::DataState::kClosed};

  EXPECT_THAT(WaitUntil([&] { return caller()->data_observer()->state(); },
                        Eq(DataChannelInterface::DataState::kClosed)),
              IsRtcOk());
  EXPECT_THAT(caller()->data_observer()->states(),
              ::testing::ElementsAreArray(expected_states));

  EXPECT_THAT(WaitUntil([&] { return callee()->data_observer()->state(); },
                        Eq(DataChannelInterface::DataState::kClosed)),
              IsRtcOk());
  EXPECT_THAT(callee()->data_observer()->states(),
              ::testing::ElementsAreArray(expected_states));
}

TEST_P(DataChannelIntegrationTest, SctpDataChannelConfigSentToOtherSide) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  DataChannelInit init;
  init.id = 53;
  init.maxRetransmits = 52;
  caller()->CreateDataChannel("data-channel", &init);
  if (allow_media()) {
    caller()->AddAudioVideoTracks();
    callee()->AddAudioVideoTracks();
  }
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  // Since "negotiated" is false, the "id" parameter should be ignored.
  EXPECT_NE(init.id, callee()->data_channel()->id());
  EXPECT_EQ("data-channel", callee()->data_channel()->label());
  EXPECT_EQ(init.maxRetransmits,
            *callee()->data_channel()->maxRetransmitsOpt());
  EXPECT_FALSE(callee()->data_channel()->negotiated());
}

// Test sctp's ability to process unordered data stream, where data actually
// arrives out of order using simulated delays. Previously there have been some
// bugs in this area.
TEST_P(DataChannelIntegrationTest, StressTestUnorderedSctpDataChannel) {
  // Introduce random network delays.
  // Otherwise it's not a true "unordered" test.
  virtual_socket_server()->set_delay_mean(20);
  virtual_socket_server()->set_delay_stddev(5);
  virtual_socket_server()->UpdateDelayDistribution();
  // Normal procedure, but with unordered data channel config.
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  DataChannelInit init;
  init.ordered = false;
  caller()->CreateDataChannel(&init);
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  static constexpr int kNumMessages = 100;
  // Deliberately chosen to be larger than the MTU so messages get fragmented.
  static constexpr size_t kMaxMessageSize = 4096;
  // Create and send random messages.
  std::vector<std::string> sent_messages;
  for (int i = 0; i < kNumMessages; ++i) {
    size_t length =
        (rand() % kMaxMessageSize) + 1;  // NOLINT (rand_r instead of rand)
    std::string message;
    ASSERT_TRUE(CreateRandomString(length, &message));
    caller()->data_channel()->Send(DataBuffer(message));
    callee()->data_channel()->Send(DataBuffer(message));
    sent_messages.push_back(message);
  }

  // Wait for all messages to be received.
  EXPECT_THAT(
      WaitUntil(
          [&] { return caller()->data_observer()->received_message_count(); },
          Eq(checked_cast<size_t>(kNumMessages))),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(checked_cast<size_t>(kNumMessages))),
      IsRtcOk());

  // Sort and compare to make sure none of the messages were corrupted.
  std::vector<std::string> caller_received_messages;
  absl::c_transform(caller()->data_observer()->messages(),
                    std::back_inserter(caller_received_messages),
                    [](const auto& a) { return a.data; });

  std::vector<std::string> callee_received_messages;
  absl::c_transform(callee()->data_observer()->messages(),
                    std::back_inserter(callee_received_messages),
                    [](const auto& a) { return a.data; });

  absl::c_sort(sent_messages);
  absl::c_sort(caller_received_messages);
  absl::c_sort(callee_received_messages);
  EXPECT_EQ(sent_messages, caller_received_messages);
  EXPECT_EQ(sent_messages, callee_received_messages);
}

// Repeatedly open and close data channels on a peer connection to check that
// the channels are properly negotiated and SCTP stream IDs properly recycled.
TEST_P(DataChannelIntegrationTest, StressTestOpenCloseChannelNoDelay) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();

  int channel_id = 0;
  const size_t kChannelCount = 8;
  const size_t kIterations = 10;
  bool has_negotiated = false;

  DataChannelInit init;
  for (size_t repeats = 0; repeats < kIterations; ++repeats) {
    RTC_LOG(LS_INFO) << "Iteration " << (repeats + 1) << "/" << kIterations;

    for (size_t i = 0; i < kChannelCount; ++i) {
      StringBuilder sb;
      sb << "channel-" << channel_id++;
      caller()->CreateDataChannel(sb.Release(), &init);
    }
    ASSERT_EQ(caller()->data_channels().size(), kChannelCount);

    if (!has_negotiated) {
      caller()->CreateAndSetAndSignalOffer();
      ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
                  IsRtcOk());
      has_negotiated = true;
    }

    for (size_t i = 0; i < kChannelCount; ++i) {
      ASSERT_THAT(
          WaitUntil([&] { return caller()->data_channels()[i]->state(); },
                    Eq(DataChannelInterface::DataState::kOpen)),
          IsRtcOk());
      RTC_LOG(LS_INFO) << "Caller Channel "
                       << caller()->data_channels()[i]->label() << " with id "
                       << caller()->data_channels()[i]->id() << " is open.";
    }
    ASSERT_THAT(WaitUntil([&] { return callee()->data_channels().size(); },
                          Eq(kChannelCount)),
                IsRtcOk());
    for (size_t i = 0; i < kChannelCount; ++i) {
      ASSERT_THAT(
          WaitUntil([&] { return callee()->data_channels()[i]->state(); },
                    Eq(DataChannelInterface::DataState::kOpen)),
          IsRtcOk());
      RTC_LOG(LS_INFO) << "Callee Channel "
                       << callee()->data_channels()[i]->label() << " with id "
                       << callee()->data_channels()[i]->id() << " is open.";
    }

    // Closing from both sides to attempt creating races.
    // A real application would likely only close from one side.
    for (size_t i = 0; i < kChannelCount; ++i) {
      if (i % 3 == 0) {
        callee()->data_channels()[i]->Close();
        caller()->data_channels()[i]->Close();
      } else {
        caller()->data_channels()[i]->Close();
        callee()->data_channels()[i]->Close();
      }
    }

    for (size_t i = 0; i < kChannelCount; ++i) {
      ASSERT_THAT(
          WaitUntil([&] { return caller()->data_channels()[i]->state(); },
                    Eq(DataChannelInterface::DataState::kClosed)),
          IsRtcOk());
      ASSERT_THAT(
          WaitUntil([&] { return callee()->data_channels()[i]->state(); },
                    Eq(DataChannelInterface::DataState::kClosed)),
          IsRtcOk());
    }

    caller()->data_channels().clear();
    caller()->data_observers().clear();
    callee()->data_channels().clear();
    callee()->data_observers().clear();
  }
}

// Repeatedly open and close data channels on a peer connection to check that
// the channels are properly negotiated and SCTP stream IDs properly recycled.
// Some delay is added for better coverage.
TEST_P(DataChannelIntegrationTest, StressTestOpenCloseChannelWithDelay) {
  // Simulate some network delay
  virtual_socket_server()->set_delay_mean(20);
  virtual_socket_server()->set_delay_stddev(5);
  virtual_socket_server()->UpdateDelayDistribution();

  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();

  int channel_id = 0;
  const size_t kChannelCount = 8;
  const size_t kIterations = 10;
  bool has_negotiated = false;

  DataChannelInit init;
  for (size_t repeats = 0; repeats < kIterations; ++repeats) {
    RTC_LOG(LS_INFO) << "Iteration " << (repeats + 1) << "/" << kIterations;

    for (size_t i = 0; i < kChannelCount; ++i) {
      StringBuilder sb;
      sb << "channel-" << channel_id++;
      caller()->CreateDataChannel(sb.Release(), &init);
    }
    ASSERT_EQ(caller()->data_channels().size(), kChannelCount);

    if (!has_negotiated) {
      caller()->CreateAndSetAndSignalOffer();
      ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
                  IsRtcOk());
      has_negotiated = true;
    }

    for (size_t i = 0; i < kChannelCount; ++i) {
      ASSERT_THAT(
          WaitUntil([&] { return caller()->data_channels()[i]->state(); },
                    Eq(DataChannelInterface::DataState::kOpen)),
          IsRtcOk());
      RTC_LOG(LS_INFO) << "Caller Channel "
                       << caller()->data_channels()[i]->label() << " with id "
                       << caller()->data_channels()[i]->id() << " is open.";
    }
    ASSERT_THAT(WaitUntil([&] { return callee()->data_channels().size(); },
                          Eq(kChannelCount)),
                IsRtcOk());
    for (size_t i = 0; i < kChannelCount; ++i) {
      ASSERT_THAT(
          WaitUntil([&] { return callee()->data_channels()[i]->state(); },
                    Eq(DataChannelInterface::DataState::kOpen)),
          IsRtcOk());
      RTC_LOG(LS_INFO) << "Callee Channel "
                       << callee()->data_channels()[i]->label() << " with id "
                       << callee()->data_channels()[i]->id() << " is open.";
    }

    // Closing from both sides to attempt creating races.
    // A real application would likely only close from one side.
    for (size_t i = 0; i < kChannelCount; ++i) {
      if (i % 3 == 0) {
        callee()->data_channels()[i]->Close();
        caller()->data_channels()[i]->Close();
      } else {
        caller()->data_channels()[i]->Close();
        callee()->data_channels()[i]->Close();
      }
    }

    for (size_t i = 0; i < kChannelCount; ++i) {
      ASSERT_THAT(
          WaitUntil([&] { return caller()->data_channels()[i]->state(); },
                    Eq(DataChannelInterface::DataState::kClosed)),
          IsRtcOk());
      ASSERT_THAT(
          WaitUntil([&] { return callee()->data_channels()[i]->state(); },
                    Eq(DataChannelInterface::DataState::kClosed)),
          IsRtcOk());
    }

    caller()->data_channels().clear();
    caller()->data_observers().clear();
    callee()->data_channels().clear();
    callee()->data_observers().clear();
  }
}

// This test sets up a call between two parties with audio, and video. When
// audio and video are setup and flowing, an SCTP data channel is negotiated.
TEST_P(DataChannelIntegrationTest, AddSctpDataChannelInSubsequentOffer) {
  // This test can't be performed without media.
  if (!allow_media()) {
    return;
  }
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  // Do initial offer/answer with audio/video.
  caller()->AddAudioVideoTracks();
  callee()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Create data channel and do new offer and answer.
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Caller data channel should already exist (it created one). Callee data
  // channel may not exist yet, since negotiation happens in-band, not in SDP.
  ASSERT_NE(nullptr, caller()->data_channel());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  // Ensure data can be sent in both directions.
  std::string data = "hello world";
  caller()->data_channel()->Send(DataBuffer(data));
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq(data)),
      IsRtcOk());
  callee()->data_channel()->Send(DataBuffer(data));
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->last_message(); },
                Eq(data)),
      IsRtcOk());
}

// Set up a connection initially just using SCTP data channels, later
// upgrading to audio/video, ensuring frames are received end-to-end.
// Effectively the inverse of the test above. This was broken in M57; see
// https://crbug.com/711243
TEST_P(DataChannelIntegrationTest, SctpDataChannelToAudioVideoUpgrade) {
  // This test can't be performed without media.
  if (!allow_media()) {
    return;
  }
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  // Do initial offer/answer with just data channel.
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  // Wait until data can be sent over the data channel.
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  // Do subsequent offer/answer with two-way audio and video. Audio and video
  // should end up bundled on the DTLS/ICE transport already used for data.
  caller()->AddAudioVideoTracks();
  callee()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  MediaExpectations media_expectations;
  media_expectations.ExpectBidirectionalAudioAndVideo();
  ASSERT_TRUE(ExpectNewFrames(media_expectations));
}

void MakeSpecCompliantSctpOffer(
    std::unique_ptr<SessionDescriptionInterface>& desc) {
  SctpDataContentDescription* dcd_offer =
      GetFirstSctpDataContentDescription(desc->description());
  // See https://crbug.com/webrtc/11211 - this function is a no-op
  ASSERT_TRUE(dcd_offer);
  dcd_offer->set_use_sctpmap(false);
  dcd_offer->set_protocol("UDP/DTLS/SCTP");
}

// Test that the data channel works when a spec-compliant SCTP m= section is
// offered (using "a=sctp-port" instead of "a=sctpmap", and using
// "UDP/DTLS/SCTP" as the protocol).
TEST_P(DataChannelIntegrationTest,
       DataChannelWorksWhenSpecCompliantSctpOfferReceived) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->SetGeneratedSdpMunger(MakeSpecCompliantSctpOffer);
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  // Ensure data can be sent in both directions.
  std::string data = "hello world";
  caller()->data_channel()->Send(DataBuffer(data));
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq(data)),
      IsRtcOk());
  callee()->data_channel()->Send(DataBuffer(data));
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->last_message(); },
                Eq(data)),
      IsRtcOk());
}

// Test that after closing PeerConnections, they stop sending any packets
// (ICE, DTLS, RTP...).
TEST_P(DataChannelIntegrationTest, ClosingConnectionStopsPacketFlow) {
  // This test can't be performed without media.
  if (!allow_media()) {
    return;
  }
  // Set up audio/video/data, wait for some frames to be received.
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->AddAudioVideoTracks();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  MediaExpectations media_expectations;
  media_expectations.CalleeExpectsSomeAudioAndVideo();
  ASSERT_TRUE(ExpectNewFrames(media_expectations));
  // Close PeerConnections.
  ClosePeerConnections();
  // Pump messages for a second, and ensure no new packets end up sent.
  uint32_t sent_packets_a = virtual_socket_server()->sent_packets();
  run_loop().RunFor(TimeDelta::Seconds(1));
  uint32_t sent_packets_b = virtual_socket_server()->sent_packets();
  EXPECT_EQ(sent_packets_a, sent_packets_b);
}

TEST_P(DataChannelIntegrationTest, DtlsRoleIsSetNormally) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  ASSERT_FALSE(caller()->pc()->GetSctpTransport());
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  ASSERT_TRUE(caller()->pc()->GetSctpTransport());
  ASSERT_TRUE(
      caller()->pc()->GetSctpTransport()->Information().dtls_transport());
  EXPECT_TRUE(caller()
                  ->pc()
                  ->GetSctpTransport()
                  ->Information()
                  .dtls_transport()
                  ->Information()
                  .role());
  EXPECT_EQ(caller()
                ->pc()
                ->GetSctpTransport()
                ->Information()
                .dtls_transport()
                ->Information()
                .role(),
            DtlsTransportTlsRole::kServer);
  EXPECT_EQ(callee()
                ->pc()
                ->GetSctpTransport()
                ->Information()
                .dtls_transport()
                ->Information()
                .role(),
            DtlsTransportTlsRole::kClient);
  // ID should be assigned according to the odd/even rule based on role;
  // client gets even numbers, server gets odd ones. RFC 8832 section 6.
  // TODO(hta): Test multiple channels.
  EXPECT_EQ(caller()->data_channel()->id(), 1);
}

TEST_P(DataChannelIntegrationTest, DtlsRoleIsSetWhenReversed) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  callee()->SetReceivedSdpMunger(MakeOfferHaveActiveDtlsRole);
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_TRUE(caller()
                  ->pc()
                  ->GetSctpTransport()
                  ->Information()
                  .dtls_transport()
                  ->Information()
                  .role());
  EXPECT_EQ(caller()
                ->pc()
                ->GetSctpTransport()
                ->Information()
                .dtls_transport()
                ->Information()
                .role(),
            DtlsTransportTlsRole::kClient);
  EXPECT_EQ(callee()
                ->pc()
                ->GetSctpTransport()
                ->Information()
                .dtls_transport()
                ->Information()
                .role(),
            DtlsTransportTlsRole::kServer);
  // ID should be assigned according to the odd/even rule based on role;
  // client gets even numbers, server gets odd ones. RFC 8832 section 6.
  // TODO(hta): Test multiple channels.
  EXPECT_EQ(caller()->data_channel()->id(), 0);
}

TEST_P(DataChannelIntegrationTest,
       DtlsRoleIsSetWhenReversedWithChannelCollision) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();

  callee()->SetReceivedSdpMunger(
      [this](std::unique_ptr<SessionDescriptionInterface>& desc) {
        MakeOfferHaveActiveDtlsRole(desc);
        callee()->CreateDataChannel();
      });
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_channels().size(); }, Eq(2U)),
      IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return caller()->data_channels().size(); }, Eq(2U)),
      IsRtcOk());
  EXPECT_TRUE(caller()
                  ->pc()
                  ->GetSctpTransport()
                  ->Information()
                  .dtls_transport()
                  ->Information()
                  .role());
  EXPECT_EQ(caller()
                ->pc()
                ->GetSctpTransport()
                ->Information()
                .dtls_transport()
                ->Information()
                .role(),
            DtlsTransportTlsRole::kClient);
  EXPECT_EQ(callee()
                ->pc()
                ->GetSctpTransport()
                ->Information()
                .dtls_transport()
                ->Information()
                .role(),
            DtlsTransportTlsRole::kServer);
  // ID should be assigned according to the odd/even rule based on role;
  // client gets even numbers, server gets odd ones. RFC 8832 section 6.
  ASSERT_EQ(caller()->data_channels().size(), 2U);
  ASSERT_EQ(callee()->data_channels().size(), 2U);
  EXPECT_EQ(caller()->data_channels()[0]->id(), 0);
  EXPECT_EQ(caller()->data_channels()[1]->id(), 1);
  EXPECT_EQ(callee()->data_channels()[0]->id(), 1);
  EXPECT_EQ(callee()->data_channels()[1]->id(), 0);
}

// Test that transport stats are generated by the RTCStatsCollector for a
// connection that only involves data channels. This is a regression test for
// crbug.com/826972.
TEST_P(DataChannelIntegrationTest,
       TransportStatsReportedForDataChannelOnlyConnection) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();

  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, IsTrue()),
              IsRtcOk());

  auto caller_report = caller()->NewGetStats(run_loop());
  ASSERT_THAT(caller_report, NotNull());
  EXPECT_EQ(1u, caller_report->GetStatsOfType<RTCTransportStats>().size());
  auto callee_report = callee()->NewGetStats(run_loop());
  ASSERT_THAT(callee_report, NotNull());
  EXPECT_EQ(1u, callee_report->GetStatsOfType<RTCTransportStats>().size());
}

TEST_P(DataChannelIntegrationTest, CreateDataChannelInvalidatesStatsCache) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  auto first_report = caller()->NewGetStats(run_loop());
  ASSERT_THAT(first_report, NotNull());
  caller()->CreateDataChannel();
  auto second_report = caller()->NewGetStats(run_loop());
  ASSERT_THAT(second_report, NotNull());

  EXPECT_EQ(0u, first_report->GetStatsOfType<RTCDataChannelStats>().size());
  EXPECT_EQ(1u, second_report->GetStatsOfType<RTCDataChannelStats>().size());
}

TEST_P(DataChannelIntegrationTest, QueuedPacketsGetDeliveredInReliableMode) {
  CreatePeerConnectionWrappers();
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, IsTrue()),
              IsRtcOk());

  caller()->data_channel()->Send(DataBuffer("hello first"));
  ASSERT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(1u)),
      IsRtcOk());
  // Cause a temporary network outage
  virtual_socket_server()->set_drop_probability(1.0);
  for (int i = 1; i <= 10; i++) {
    caller()->data_channel()->Send(DataBuffer("Sent while blocked"));
  }
  // Nothing should be delivered during outage. Short wait.
  EXPECT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(1u)),
      IsRtcOk());
  // Reverse outage
  virtual_socket_server()->set_drop_probability(0.0);
  // All packets should be delivered.
  EXPECT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(11u)),
      IsRtcOk());
}

TEST_P(DataChannelIntegrationTest, QueuedPacketsGetDroppedInUnreliableMode) {
  CreatePeerConnectionWrappers();
  ConnectFakeSignaling();
  DataChannelInit init;
  init.maxRetransmits = 0;
  init.ordered = false;
  caller()->CreateDataChannel(&init);
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, IsTrue()),
              IsRtcOk());
  caller()->data_channel()->Send(DataBuffer("hello first"));
  ASSERT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(1u)),
      IsRtcOk());
  // Cause a temporary network outage
  virtual_socket_server()->set_drop_probability(1.0);
  // Send a few packets. Note that all get dropped only when all packets
  // fit into the receiver receive window/congestion window, so that they
  // actually get sent.
  for (int i = 1; i <= 10; i++) {
    caller()->data_channel()->Send(DataBuffer("Sent while blocked"));
  }
  // Nothing should be delivered during outage.
  // We do a short wait to verify that delivery count is still 1.
  run_loop().RunFor(TimeDelta::Millis(10));
  EXPECT_EQ(1u, callee()->data_observer()->received_message_count());
  // Reverse the network outage.
  virtual_socket_server()->set_drop_probability(0.0);
  // Send a new packet, and wait for it to be delivered.
  caller()->data_channel()->Send(DataBuffer("After block"));
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq("After block")),
      IsRtcOk());
  // Some messages should be lost, but first and last message should have
  // been delivered.
  // First, check that the protocol guarantee is preserved.
  EXPECT_GT(11u, callee()->data_observer()->received_message_count());
  EXPECT_LE(2u, callee()->data_observer()->received_message_count());
  // Then, check that observed behavior (lose all messages) has not changed
  EXPECT_EQ(2u, callee()->data_observer()->received_message_count());
}

TEST_P(DataChannelIntegrationTest,
       QueuedPacketsGetDroppedInLifetimeLimitedMode) {
  CreatePeerConnectionWrappers();
  ConnectFakeSignaling();
  DataChannelInit init;
  init.maxRetransmitTime = 1;
  init.ordered = false;
  caller()->CreateDataChannel(&init);
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, IsTrue()),
              IsRtcOk());
  caller()->data_channel()->Send(DataBuffer("hello first"));
  ASSERT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(1u)),
      IsRtcOk());
  // Cause a temporary network outage
  virtual_socket_server()->set_drop_probability(1.0);
  for (int i = 1; i <= 200; i++) {
    caller()->data_channel()->Send(DataBuffer("Sent while blocked"));
  }
  // Nothing should be delivered during outage.
  // We do a short wait to verify that delivery count is still 1,
  // and to make sure max packet lifetime (which is in ms) is exceeded.
  run_loop().RunFor(TimeDelta::Millis(10));
  EXPECT_EQ(1u, callee()->data_observer()->received_message_count());
  // Reverse the network outage.
  virtual_socket_server()->set_drop_probability(0.0);
  // Send a new packet, and wait for it to be delivered.
  caller()->data_channel()->Send(DataBuffer("After block"));
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq("After block")),
      IsRtcOk());
  // Some messages should be lost, but first and last message should have
  // been delivered.
  // First, check that the protocol guarantee is preserved.
  EXPECT_GT(202u, callee()->data_observer()->received_message_count());
  EXPECT_LE(2u, callee()->data_observer()->received_message_count());
  // Then, check that observed behavior (lose some messages) has not changed
  // DcSctp loses all messages. This is correct.
  EXPECT_EQ(2u, callee()->data_observer()->received_message_count());
}

TEST_P(DataChannelIntegrationTest,
       DISABLED_ON_ANDROID(SomeQueuedPacketsGetDroppedInMaxRetransmitsMode)) {
  CreatePeerConnectionWrappers();
  ConnectFakeSignaling();
  DataChannelInit init;
  init.maxRetransmits = 0;
  init.ordered = false;
  caller()->CreateDataChannel(&init);
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, IsTrue()),
              IsRtcOk());
  caller()->data_channel()->Send(DataBuffer("hello first"));
  ASSERT_THAT(
      WaitUntil(
          [&] { return callee()->data_observer()->received_message_count(); },
          Eq(1u)),
      IsRtcOk());
  // Cause a temporary network outage
  virtual_socket_server()->set_drop_probability(1.0);
  // Fill the SCTP socket buffer until queued data starts to build.
  constexpr size_t kBufferedDataInSctpSocket = 2'000'000;
  size_t packet_counter = 0;
  while (caller()->data_channel()->buffered_amount() <
             kBufferedDataInSctpSocket &&
         packet_counter < 10000) {
    packet_counter++;
    caller()->data_channel()->Send(DataBuffer("Sent while blocked"));
  }
  if (caller()->data_channel()->buffered_amount() > kBufferedDataInSctpSocket) {
    RTC_LOG(LS_INFO) << "Buffered data after " << packet_counter << " packets";
  } else {
    RTC_LOG(LS_INFO) << "No buffered data after " << packet_counter
                     << " packets";
  }
  // Nothing should be delivered during outage.
  // We do a short wait to verify that delivery count is still 1.
  run_loop().RunFor(TimeDelta::Millis(10));
  EXPECT_EQ(1u, callee()->data_observer()->received_message_count());
  // Reverse the network outage.
  virtual_socket_server()->set_drop_probability(0.0);
  // Send a new packet, and wait for it to be delivered.
  caller()->data_channel()->Send(DataBuffer("After block"));
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->last_message(); },
                Eq("After block")),
      IsRtcOk());
  // Some messages should be lost, but first and last message should have
  // been delivered.
  // Due to the fact that retransmissions are only counted when the packet
  // goes on the wire, NOT when they are stalled in queue due to
  // congestion, we expect some of the packets to be delivered, because
  // congestion prevented them from being sent.
  // Citation: https://tools.ietf.org/html/rfc7496#section-3.1

  // First, check that the protocol guarantee is preserved.
  EXPECT_GT(packet_counter,
            callee()->data_observer()->received_message_count());
  EXPECT_LE(2u, callee()->data_observer()->received_message_count());
  // Then, check that observed behavior (lose between 100 and 200 messages)
  // has not changed.
  // Usrsctp behavior is different on Android (177) and other platforms (122).
  // Dcsctp loses 432 packets.
  EXPECT_GT(2 + packet_counter - 100,
            callee()->data_observer()->received_message_count());
  EXPECT_LT(2 + packet_counter - 500,
            callee()->data_observer()->received_message_count());
}

TEST_P(DataChannelIntegrationTest, ChangingSctpPortIsNotAllowed) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  std::unique_ptr<SessionDescriptionInterface> answer;
  caller()->SetReceivedSdpMunger(
      [&answer](std::unique_ptr<SessionDescriptionInterface>& desc) {
        // Change the SCTP port.
        ContentInfo* sctp_content = GetFirstDataContent(desc->description());
        ASSERT_TRUE(sctp_content);
        auto sctp_description = sctp_content->media_description()->as_sctp();
        ASSERT_TRUE(sctp_description);
        sctp_description->set_port(sctp_description->port() + 1);

        // Capture and suppress the answer.
        answer.reset(desc.release());
      });
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(answer, NotNull());

  // Currently SRD succeeds.
  EXPECT_TRUE(caller()->SetRemoteDescription(std::move(answer)));
  // Check the state of the SCTP transport.
  VerifySctpState(caller(), SctpTransportState::kClosed);
}

TEST_P(DataChannelIntegrationTest, ChangingSctpPortIsAllowedWithDtlsRestart) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, Ne(nullptr)),
              IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  EXPECT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());

  // Recreate the second peerconnection.
  PeerConnectionDependencies dependencies(nullptr);
  std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
      new FakeRTCCertificateGenerator());
  cert_generator->use_alternate_key();
  dependencies.cert_generator = std::move(cert_generator);
  SetCalleePcWrapperAndReturnCurrent(CreatePeerConnectionWrapper(
      "Callee2", nullptr, {}, std::move(dependencies), nullptr,
      /*reset_encoder_factory=*/false,
      /*reset_decoder_factory=*/false,
      /*create_media_engine=*/false));
  ConnectFakeSignaling();

  std::unique_ptr<SessionDescriptionInterface> answer;
  caller()->SetReceivedSdpMunger(
      [&answer](std::unique_ptr<SessionDescriptionInterface>& desc) {
        // Change the SCTP port.
        ContentInfo* sctp_content = GetFirstDataContent(desc->description());
        ASSERT_TRUE(sctp_content);
        auto sctp_description = sctp_content->media_description()->as_sctp();
        ASSERT_TRUE(sctp_description);
        sctp_description->set_port(sctp_description->port() + 1);

        // Capture and suppress the answer.
        answer.reset(desc.release());
      });
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(answer, NotNull());

  EXPECT_TRUE(caller()->SetRemoteDescription(std::move(answer)));
  // Check the state of the SCTP transport.
  VerifySctpState(caller(), SctpTransportState::kConnected);
}

INSTANTIATE_TEST_SUITE_P(DataChannelIntegrationTest,
                         DataChannelIntegrationTest,
                         Combine(Values(SdpSemantics::kPlanB_DEPRECATED,
                                        SdpSemantics::kUnifiedPlan),
                                 testing::Bool()));

TEST_F(DataChannelIntegrationTestUnifiedPlan,
       EndToEndCallWithBundledSctpDataChannel) {
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->AddAudioVideoTracks();
  callee()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return caller()->pc()->GetSctpTransport(); }, IsTrue()),
      IsRtcOk());
  ASSERT_THAT(
      WaitUntil(
          [&] {
            return caller()->pc()->GetSctpTransport()->Information().state();
          },
          Eq(SctpTransportState::kConnected)),
      IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
}

TEST_F(DataChannelIntegrationTestUnifiedPlan,
       EndToEndCallWithDataChannelOnlyConnects) {
  ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_channel(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  ASSERT_TRUE(caller()->data_observer()->IsOpen());
}

TEST_F(DataChannelIntegrationTestUnifiedPlan, DataChannelClosesWhenClosed) {
  ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_observer(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  caller()->data_channel()->Close();
  ASSERT_THAT(
      WaitUntil([&] { return !callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
}

TEST_F(DataChannelIntegrationTestUnifiedPlan,
       DataChannelClosesWhenClosedReverse) {
  ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_observer(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  callee()->data_channel()->Close();
  ASSERT_THAT(
      WaitUntil([&] { return !caller()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
}

TEST_F(DataChannelIntegrationTestUnifiedPlan,
       DataChannelClosesWhenPeerConnectionClosed) {
  ASSERT_TRUE(CreatePeerConnectionWrappersWithoutMediaEngine());
  ConnectFakeSignaling();
  caller()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(WaitUntil([&] { return callee()->data_observer(); }, IsTrue()),
              IsRtcOk());
  ASSERT_THAT(
      WaitUntil([&] { return callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
  caller()->pc()->Close();
  ASSERT_THAT(
      WaitUntil([&] { return !callee()->data_observer()->IsOpen(); }, IsTrue()),
      IsRtcOk());
}

TEST_F(DataChannelIntegrationTestUnifiedPlan, ReducingMaxChannelsAtCaller) {
  const int stream_count = 2;
  RTCConfiguration caller_config;
  caller_config.always_negotiate_data_channels = true;
  caller_config.max_sctp_streams = stream_count;
  ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(
      caller_config, PeerConnectionInterface::RTCConfiguration()));
  ConnectFakeSignaling();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  scoped_refptr<SctpTransportInterface> caller_transport =
      caller()->pc()->GetSctpTransport();
  ASSERT_THAT(caller_transport, NotNull());
  ASSERT_THAT(WaitUntil(
                  [&] {
                    return caller_transport->Information().state() ==
                           SctpTransportState::kConnected;
                  },
                  IsTrue()),
              IsRtcOk());
  scoped_refptr<SctpTransportInterface> callee_transport =
      callee()->pc()->GetSctpTransport();
  ASSERT_THAT(callee_transport, NotNull());
  std::optional<int> caller_channels =
      caller_transport->Information().MaxChannels();
  std::optional<int> callee_channels =
      callee_transport->Information().MaxChannels();
  ASSERT_TRUE(caller_channels.has_value());
  ASSERT_TRUE(callee_channels.has_value());
  EXPECT_THAT(caller_channels.value(), Eq(stream_count));
  EXPECT_THAT(callee_channels.value(), Eq(stream_count));
}
TEST_F(DataChannelIntegrationTestUnifiedPlan, ReducingMaxChannelsAtCallee) {
  const int stream_count = 2;
  RTCConfiguration caller_config;
  caller_config.always_negotiate_data_channels = true;
  RTCConfiguration callee_config;
  callee_config.max_sctp_streams = stream_count;
  ASSERT_TRUE(
      CreatePeerConnectionWrappersWithConfig(caller_config, callee_config));
  ConnectFakeSignaling();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()),
              IsRtcOk());
  scoped_refptr<SctpTransportInterface> caller_transport =
      caller()->pc()->GetSctpTransport();
  ASSERT_THAT(caller_transport, NotNull());
  ASSERT_THAT(WaitUntil(
                  [&] {
                    return caller_transport->Information().state() ==
                           SctpTransportState::kConnected;
                  },
                  IsTrue()),
              IsRtcOk());
  scoped_refptr<SctpTransportInterface> callee_transport =
      callee()->pc()->GetSctpTransport();
  ASSERT_THAT(callee_transport, NotNull());
  std::optional<int> caller_channels =
      caller_transport->Information().MaxChannels();
  std::optional<int> callee_channels =
      callee_transport->Information().MaxChannels();
  ASSERT_TRUE(caller_channels.has_value());
  ASSERT_TRUE(callee_channels.has_value());
  EXPECT_THAT(caller_channels.value(), Eq(stream_count));
  EXPECT_THAT(callee_channels.value(), Eq(stream_count));
}

class DataChannelIntegrationTestUnifiedPlanFieldTrials
    : public DataChannelIntegrationTestUnifiedPlan,
      public ::testing::WithParamInterface<std::tuple<
          /* callee-DTLS-active=*/bool,
          /* caller-field-trials=*/const char*,
          /* callee-field-trials=*/const char*,
          /* callee2-field-trials=*/const char*>> {
 protected:
  DataChannelIntegrationTestUnifiedPlanFieldTrials() {
    const bool callee_active = std::get<0>(GetParam());
    RTC_LOG(LS_INFO) << "dtls_active: " << (callee_active ? "callee" : "caller")
                     << " field-trials: caller: " << std::get<1>(GetParam())
                     << " callee: " << std::get<2>(GetParam())
                     << " callee2: " << std::get<3>(GetParam());

    SetFieldTrials(kCallerName, std::get<1>(GetParam()));
    SetFieldTrials(kCalleeName, std::get<2>(GetParam()));
    SetFieldTrials("Callee2", std::get<3>(GetParam()));
  }

  std::unique_ptr<PeerConnectionIntegrationWrapper> SetupCallee2AndDc(
      bool addTurn) {
    RTCConfiguration config;
    if (addTurn) {
      static const SocketAddress turn_server_1_internal_address{"192.0.2.1",
                                                                3478};
      static const SocketAddress turn_server_1_external_address{"192.0.3.1", 0};
      TestTurnServer* turn_server_1 = CreateTurnServer(
          turn_server_1_internal_address, turn_server_1_external_address);

      // Bypass permission check on received packets so media can be sent before
      // the candidate is signaled.
      SendTask(network_thread(), [turn_server_1] {
        turn_server_1->set_enable_permission_checks(false);
      });

      PeerConnectionInterface::IceServer ice_server_1;
      ice_server_1.urls.push_back("turn:192.0.2.1:3478");
      ice_server_1.username = "test";
      ice_server_1.password = "test";
      config.servers.push_back(ice_server_1);
      config.type = PeerConnectionInterface::kRelay;
      config.presume_writable_when_fully_relayed = true;
    }
    CreatePeerConnectionWrappersWithConfig(config, config,
                                           /* create_media_engine= */ false);
    PeerConnectionDependencies dependencies(nullptr);
    std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
        new FakeRTCCertificateGenerator());
    cert_generator->use_alternate_key();
    dependencies.cert_generator = std::move(cert_generator);
    auto callee2 = CreatePeerConnectionWrapper("Callee2", nullptr, &config,
                                               std::move(dependencies), nullptr,
                                               /*reset_encoder_factory=*/false,
                                               /*reset_decoder_factory=*/false,
                                               /*create_media_engine=*/false);
    ConnectFakeSignaling();
    DataChannelInit dc_init;
    dc_init.negotiated = true;
    dc_init.id = 77;
    caller()->CreateDataChannel("label", &dc_init);
    callee()->CreateDataChannel("label", &dc_init);
    callee2->CreateDataChannel("label", &dc_init);

    callee2->set_signaling_message_receiver(caller());
    return callee2;
  }

  void WaitConnectedAndDcOpen(bool prAnswer,
                              PeerConnectionIntegrationWrapper* caller,
                              PeerConnectionIntegrationWrapper* callee) {
    if (prAnswer) {
      EXPECT_EQ(caller->pc()->signaling_state(),
                PeerConnectionInterface::kHaveRemotePrAnswer);
      EXPECT_EQ(callee->pc()->signaling_state(),
                PeerConnectionInterface::kHaveLocalPrAnswer);
    } else {
      EXPECT_EQ(caller->pc()->signaling_state(),
                PeerConnectionInterface::kStable);
      EXPECT_EQ(callee->pc()->signaling_state(),
                PeerConnectionInterface::kStable);
    }
    ASSERT_THAT(WaitUntil([&] { return caller->data_channel()->state(); },
                          Eq(DataChannelInterface::kOpen)),
                IsRtcOk());
    ASSERT_THAT(WaitUntil([&] { return callee->data_channel()->state(); },
                          Eq(DataChannelInterface::kOpen)),
                IsRtcOk());
    ASSERT_THAT(
        WaitUntil([&] { return caller->pc()->peer_connection_state(); },
                  Eq(PeerConnectionInterface::PeerConnectionState::kConnected)),
        IsRtcOk());
    ASSERT_THAT(
        WaitUntil([&] { return callee->pc()->peer_connection_state(); },
                  Eq(PeerConnectionInterface::PeerConnectionState::kConnected)),
        IsRtcOk());
  }

  static void SendOnDatachannelWhenConnectedCallback(
      PeerConnectionIntegrationWrapper* peer,
      const std::string& data,
      std::atomic<int>& signal) {
    if (peer->pc()->peer_connection_state() ==
            PeerConnectionInterface::PeerConnectionState::kConnected &&
        peer->data_channel()->state() == DataChannelInterface::kOpen) {
      peer->data_channel()->SendAsync(DataBuffer(data), [&](RTCError err) {
        signal.store(err.ok() ? 1 : -1);
      });
    }
  }

  void VerifyDtlsRoles(PeerConnectionIntegrationWrapper* caller,
                       PeerConnectionIntegrationWrapper* callee) {
    const bool callee_active = std::get<0>(GetParam());
    if (callee_active) {
      ASSERT_THAT(caller->dtls_transport_role(),
                  Eq(DtlsTransportTlsRole::kServer));
      ASSERT_THAT(callee->dtls_transport_role(),
                  Eq(DtlsTransportTlsRole::kClient));
    } else {
      ASSERT_THAT(caller->dtls_transport_role(),
                  Eq(DtlsTransportTlsRole::kClient));
      ASSERT_THAT(callee->dtls_transport_role(),
                  Eq(DtlsTransportTlsRole::kServer));
    }
  }

  void VerifyReceivedDcMessages(PeerConnectionIntegrationWrapper* peer,
                                const std::string& data,
                                std::atomic<int>& signal) {
    ASSERT_THAT(WaitUntil([&] { return signal.load(); }, Ne(0)), IsRtcOk());
    EXPECT_THAT(WaitUntil([&] { return peer->data_observer()->last_message(); },
                          Eq(data)),
                IsRtcOk());
  }

  const char* CheckSupported() {
    const bool callee_active = std::get<0>(GetParam());
    const bool caller_has_dtls_in_stun = absl::StrContains(
        std::get<1>(GetParam()), "WebRTC-IceHandshakeDtls/Enabled/");
    const bool callee_has_dtls_in_stun = absl::StrContains(
        std::get<2>(GetParam()), "WebRTC-IceHandshakeDtls/Enabled/");
    const bool callee2_has_dtls_in_stun = absl::StrContains(
        std::get<3>(GetParam()), "WebRTC-IceHandshakeDtls/Enabled/");
    if (callee_active && (caller_has_dtls_in_stun || callee_has_dtls_in_stun ||
                          callee2_has_dtls_in_stun)) {
      return "dtls-in-stun when callee(s) are dtls clients";
    }

    return nullptr;
  }
};

const char* kTrialsVariants[] = {
    "",
    "WebRTC-ForceDtls13/Enabled/",
    "WebRTC-IceHandshakeDtls/Enabled/",
    "WebRTC-ForceDtls13/Enabled/WebRTC-EnableDtlsPqc/Enabled/",
    "WebRTC-ForceDtls13/Enabled/WebRTC-IceHandshakeDtls/Enabled/",
    ("WebRTC-ForceDtls13/Enabled/WebRTC-IceHandshakeDtls/Enabled/"
     "WebRTC-EnableDtlsPqc/Enabled/"),
};

INSTANTIATE_TEST_SUITE_P(DataChannelIntegrationTestUnifiedPlanFieldTrials,
                         DataChannelIntegrationTestUnifiedPlanFieldTrials,
                         Combine(testing::Bool(),
                                 ValuesIn(kTrialsVariants),
                                 ValuesIn(kTrialsVariants),
                                 ValuesIn(kTrialsVariants)));

TEST_P(DataChannelIntegrationTestUnifiedPlanFieldTrials,
       DtlsRestartOneCalleAtATime) {
  if (auto msg = CheckSupported()) {
    GTEST_SKIP() << "Testcase not supported for this scenario: " << msg;
  }

  auto callee2 = SetupCallee2AndDc(/* addTurn= */ false);
  const bool callee_active = std::get<0>(GetParam());
  std::unique_ptr<SessionDescriptionInterface> offer;
  callee()->SetReceivedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        if (callee_active) {
          MakeOfferHavePassiveDtlsRole(sdp);
        } else {
          MakeOfferHaveActiveDtlsRole(sdp);
        }
        // Capture offer so that it can be sent to Callee2 too.
        offer = sdp->Clone();
      });
  callee2->SetReceivedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        if (callee_active) {
          MakeOfferHavePassiveDtlsRole(sdp);
        } else {
          MakeOfferHaveActiveDtlsRole(sdp);
        }
      });
  callee()->SetGeneratedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        // Modify offer to kPrAnswer
        SetSdpType(sdp, SdpType::kPrAnswer);
        if (callee_active) {
          MakeOfferHaveActiveDtlsRole(sdp);
        } else {
          MakeOfferHavePassiveDtlsRole(sdp);
        }
      });
  callee2->SetGeneratedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        if (callee_active) {
          MakeOfferHaveActiveDtlsRole(sdp);
        } else {
          MakeOfferHavePassiveDtlsRole(sdp);
        }
      });
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_FALSE(HasFailure());
  WaitConnectedAndDcOpen(/* prAnswer= */ true, caller(), callee());
  VerifyDtlsRoles(caller(), callee());
  ASSERT_FALSE(HasFailure());

  std::atomic<int> caller_sent_on_dc(0);
  std::atomic<int> callee2_sent_on_dc(0);
  caller()->set_connection_change_callback([&](auto new_state) {
    SendOnDatachannelWhenConnectedCallback(caller(), "KESO", caller_sent_on_dc);
  });
  // Install same cb on both connection_change_callback and
  // data_observer->set_state_change_callback since they can fire in any order.
  callee2->set_connection_change_callback([&](auto new_state) {
    SendOnDatachannelWhenConnectedCallback(callee2.get(), "KENT",
                                           callee2_sent_on_dc);
  });
  callee2->data_observer()->set_state_change_callback([&](auto new_state) {
    SendOnDatachannelWhenConnectedCallback(callee2.get(), "KENT",
                                           callee2_sent_on_dc);
  });

  // Now let callee2 get the offer, apply it and send the answer to caller.
  std::string offer_sdp;
  EXPECT_TRUE(offer->ToString(&offer_sdp));
  callee2->ReceiveSdpMessage(SdpType::kOffer, offer_sdp);
  WaitConnectedAndDcOpen(/* prAnswer= */ false, caller(), callee2.get());
  ASSERT_FALSE(HasFailure());

  VerifyReceivedDcMessages(caller(), "KENT", callee2_sent_on_dc);
  VerifyReceivedDcMessages(callee2.get(), "KESO", caller_sent_on_dc);
  VerifyDtlsRoles(caller(), callee2.get());
  VerifySctpState(caller(), SctpTransportState::kConnected);
  VerifySctpState(callee(), SctpTransportState::kClosed);
  VerifySctpState(callee2.get(), SctpTransportState::kConnected);
  ASSERT_FALSE(HasFailure());
}

TEST_P(DataChannelIntegrationTestUnifiedPlanFieldTrials,
       DtlsRestartTwoActiveCallees) {
  if (auto msg = CheckSupported()) {
    GTEST_SKIP() << "Testcase not supported for this scenario: " << msg;
  }

  auto callee2 = SetupCallee2AndDc(/* addTurn= */ true);
  const bool callee_active = std::get<0>(GetParam());
  std::unique_ptr<SessionDescriptionInterface> offer;
  callee()->SetReceivedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        if (callee_active) {
          MakeOfferHavePassiveDtlsRole(sdp);
        } else {
          MakeOfferHaveActiveDtlsRole(sdp);
        }
        // Capture offer so that it can be sent to Callee2 too.
        offer = sdp->Clone();
      });
  callee2->SetReceivedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        if (callee_active) {
          MakeOfferHavePassiveDtlsRole(sdp);
        } else {
          MakeOfferHaveActiveDtlsRole(sdp);
        }
      });
  callee()->SetGeneratedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        // Modify offer to kPrAnswer
        SetSdpType(sdp, SdpType::kPrAnswer);
        if (callee_active) {
          MakeOfferHaveActiveDtlsRole(sdp);
        } else {
          MakeOfferHavePassiveDtlsRole(sdp);
        }
      });
  callee2->SetGeneratedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        if (callee_active) {
          MakeOfferHaveActiveDtlsRole(sdp);
        } else {
          MakeOfferHavePassiveDtlsRole(sdp);
        }
      });
  bool first_answer = true;
  std::unique_ptr<SessionDescriptionInterface> answer;
  caller()->SetReceivedSdpMunger(
      [&](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        if (first_answer) {
          first_answer = false;
        } else {
          answer = std::move(sdp);
        }
      });
  caller()->CreateAndSetAndSignalOffer();
  std::string offer_sdp;
  EXPECT_TRUE(offer->ToString(&offer_sdp));
  // Apply offer on callee2 "in parallell" to callee.
  callee2->ReceiveSdpMessage(SdpType::kOffer, offer_sdp);

  ASSERT_FALSE(HasFailure());
  EXPECT_EQ(callee2->pc()->signaling_state(), PeerConnectionInterface::kStable);
  WaitConnectedAndDcOpen(/* prAnswer= */ true, caller(), callee());
  ASSERT_FALSE(HasFailure());

  // Forward turn ice candidate also to callee2.
  auto candidate = caller()->last_gathered_ice_candidate();
  std::string ice_sdp = candidate->ToString();
  callee2->ReceiveIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(),
                             ice_sdp);

  // Wait until callee2 is ICE connected.
  ASSERT_THAT(
      WaitUntil(
          [&] { return callee2->pc()->standardized_ice_connection_state(); },
          Eq(PeerConnectionInterface::kIceConnectionConnected)),
      IsRtcOk());

  VerifyDtlsRoles(caller(), callee());
  ASSERT_THAT(callee2->dtls_transport_role(), Eq(std::nullopt));

  std::atomic<int> caller_sent_on_dc(0);
  std::atomic<int> callee2_sent_on_dc(0);
  caller()->set_connection_change_callback([&](auto new_state) {
    SendOnDatachannelWhenConnectedCallback(caller(), "KESO", caller_sent_on_dc);
  });
  // Install same cb on both connection_change_callback and
  // data_observer->set_state_change_callback since they can fire in any order.
  callee2->set_connection_change_callback([&](auto new_state) {
    SendOnDatachannelWhenConnectedCallback(callee2.get(), "KENT",
                                           callee2_sent_on_dc);
  });
  callee2->data_observer()->set_state_change_callback([&](auto new_state) {
    SendOnDatachannelWhenConnectedCallback(callee2.get(), "KENT",
                                           callee2_sent_on_dc);
  });

  // Now switch to callee2!
  first_answer = true;
  ASSERT_THAT(answer, testing::Not(testing::IsNull()));
  std::string answer_sdp;
  EXPECT_TRUE(answer->ToString(&answer_sdp));

  caller()->ReceiveSdpMessage(SdpType::kAnswer, answer_sdp);

  EXPECT_EQ(caller()->pc()->signaling_state(),
            PeerConnectionInterface::kStable);

  VerifyReceivedDcMessages(caller(), "KENT", callee2_sent_on_dc);
  VerifyReceivedDcMessages(callee2.get(), "KESO", caller_sent_on_dc);
  VerifyDtlsRoles(caller(), callee2.get());
  ASSERT_FALSE(HasFailure());
}

#endif  // WEBRTC_HAVE_SCTP

}  // namespace

}  // namespace webrtc
