blob: 52c54e73f25f6f21e2dbe89958cef97498e10f34 [file] [log] [blame]
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2013 The WebRTC project authors. All Rights Reserved.
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
wu@webrtc.orgd64719d2013-08-01 00:00:07 +00009 */
10
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <string.h>
kwibergd1fe2812016-04-27 06:47:29 -070012#include <memory>
Steve Anton36b29d12017-10-30 09:57:42 -070013#include <vector>
kwibergd1fe2812016-04-27 06:47:29 -070014
Steve Anton10542f22019-01-11 09:11:00 -080015#include "pc/data_channel.h"
16#include "pc/sctp_utils.h"
17#include "pc/test/fake_data_channel_provider.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "rtc_base/gunit.h"
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +020019#include "rtc_base/numerics/safe_conversions.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "test/gtest.h"
wu@webrtc.orgd64719d2013-08-01 00:00:07 +000021
wu@webrtc.org78187522013-10-07 23:32:02 +000022using webrtc::DataChannel;
deadbeefab9b2d12015-10-14 11:33:11 -070023using webrtc::SctpSidAllocator;
wu@webrtc.orgd64719d2013-08-01 00:00:07 +000024
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -070025static constexpr int kDefaultTimeout = 10000;
26
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +000027class FakeDataChannelObserver : public webrtc::DataChannelObserver {
28 public:
jiayl@webrtc.org9f8164c2014-05-30 21:53:17 +000029 FakeDataChannelObserver()
bemasc0edd50c2015-07-01 13:34:33 -070030 : messages_received_(0),
31 on_state_change_count_(0),
32 on_buffered_amount_change_count_(0) {}
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +000033
Yves Gerey665174f2018-06-19 15:03:05 +020034 void OnStateChange() { ++on_state_change_count_; }
jiayl@webrtc.org9f8164c2014-05-30 21:53:17 +000035
Peter Boström0c4e06b2015-10-07 12:23:21 +020036 void OnBufferedAmountChange(uint64_t previous_amount) {
bemasc0edd50c2015-07-01 13:34:33 -070037 ++on_buffered_amount_change_count_;
38 }
39
Yves Gerey665174f2018-06-19 15:03:05 +020040 void OnMessage(const webrtc::DataBuffer& buffer) { ++messages_received_; }
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +000041
Yves Gerey665174f2018-06-19 15:03:05 +020042 size_t messages_received() const { return messages_received_; }
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +000043
Yves Gerey665174f2018-06-19 15:03:05 +020044 void ResetOnStateChangeCount() { on_state_change_count_ = 0; }
jiayl@webrtc.org9f8164c2014-05-30 21:53:17 +000045
bemasc0edd50c2015-07-01 13:34:33 -070046 void ResetOnBufferedAmountChangeCount() {
47 on_buffered_amount_change_count_ = 0;
48 }
49
Yves Gerey665174f2018-06-19 15:03:05 +020050 size_t on_state_change_count() const { return on_state_change_count_; }
jiayl@webrtc.org9f8164c2014-05-30 21:53:17 +000051
bemasc0edd50c2015-07-01 13:34:33 -070052 size_t on_buffered_amount_change_count() const {
53 return on_buffered_amount_change_count_;
54 }
55
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +000056 private:
57 size_t messages_received_;
jiayl@webrtc.org9f8164c2014-05-30 21:53:17 +000058 size_t on_state_change_count_;
bemasc0edd50c2015-07-01 13:34:33 -070059 size_t on_buffered_amount_change_count_;
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +000060};
61
Taylor Brandstettercdd05f02018-05-31 13:23:32 -070062// TODO(deadbeef): The fact that these tests use a fake provider makes them not
63// too valuable. Should rewrite using the
64// peerconnection_datachannel_unittest.cc infrastructure.
Mirko Bonadei6a489f22019-04-09 15:11:12 +020065class SctpDataChannelTest : public ::testing::Test {
wu@webrtc.orgd64719d2013-08-01 00:00:07 +000066 protected:
67 SctpDataChannelTest()
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -070068 : provider_(new FakeDataChannelProvider()),
69 webrtc_data_channel_(DataChannel::Create(provider_.get(),
70 cricket::DCT_SCTP,
71 "test",
72 init_)) {}
wu@webrtc.orgd64719d2013-08-01 00:00:07 +000073
wu@webrtc.org78187522013-10-07 23:32:02 +000074 void SetChannelReady() {
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -070075 provider_->set_transport_available(true);
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000076 webrtc_data_channel_->OnTransportChannelCreated();
77 if (webrtc_data_channel_->id() < 0) {
78 webrtc_data_channel_->SetSctpSid(0);
79 }
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -070080 provider_->set_ready_to_send(true);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +000081 }
wu@webrtc.org78187522013-10-07 23:32:02 +000082
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +000083 void AddObserver() {
84 observer_.reset(new FakeDataChannelObserver());
85 webrtc_data_channel_->RegisterObserver(observer_.get());
86 }
87
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +000088 webrtc::InternalDataChannelInit init_;
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -070089 std::unique_ptr<FakeDataChannelProvider> provider_;
kwibergd1fe2812016-04-27 06:47:29 -070090 std::unique_ptr<FakeDataChannelObserver> observer_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000091 rtc::scoped_refptr<DataChannel> webrtc_data_channel_;
wu@webrtc.orgd64719d2013-08-01 00:00:07 +000092};
93
hbos82ebe022016-11-14 01:41:09 -080094class StateSignalsListener : public sigslot::has_slots<> {
95 public:
96 int opened_count() const { return opened_count_; }
97 int closed_count() const { return closed_count_; }
98
Yves Gerey665174f2018-06-19 15:03:05 +020099 void OnSignalOpened(DataChannel* data_channel) { ++opened_count_; }
hbos82ebe022016-11-14 01:41:09 -0800100
Yves Gerey665174f2018-06-19 15:03:05 +0200101 void OnSignalClosed(DataChannel* data_channel) { ++closed_count_; }
hbos82ebe022016-11-14 01:41:09 -0800102
103 private:
104 int opened_count_ = 0;
105 int closed_count_ = 0;
106};
107
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000108// Verifies that the data channel is connected to the transport after creation.
109TEST_F(SctpDataChannelTest, ConnectedToTransportOnCreated) {
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700110 provider_->set_transport_available(true);
111 rtc::scoped_refptr<DataChannel> dc =
112 DataChannel::Create(provider_.get(), cricket::DCT_SCTP, "test1", init_);
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000113
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700114 EXPECT_TRUE(provider_->IsConnected(dc.get()));
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000115 // The sid is not set yet, so it should not have added the streams.
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700116 EXPECT_FALSE(provider_->IsSendStreamAdded(dc->id()));
117 EXPECT_FALSE(provider_->IsRecvStreamAdded(dc->id()));
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000118
119 dc->SetSctpSid(0);
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700120 EXPECT_TRUE(provider_->IsSendStreamAdded(dc->id()));
121 EXPECT_TRUE(provider_->IsRecvStreamAdded(dc->id()));
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000122}
123
124// Verifies that the data channel is connected to the transport if the transport
125// is not available initially and becomes available later.
126TEST_F(SctpDataChannelTest, ConnectedAfterTransportBecomesAvailable) {
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700127 EXPECT_FALSE(provider_->IsConnected(webrtc_data_channel_.get()));
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000128
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700129 provider_->set_transport_available(true);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000130 webrtc_data_channel_->OnTransportChannelCreated();
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700131 EXPECT_TRUE(provider_->IsConnected(webrtc_data_channel_.get()));
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000132}
133
wu@webrtc.org78187522013-10-07 23:32:02 +0000134// Tests the state of the data channel.
135TEST_F(SctpDataChannelTest, StateTransition) {
hbos82ebe022016-11-14 01:41:09 -0800136 StateSignalsListener state_signals_listener;
137 webrtc_data_channel_->SignalOpened.connect(
138 &state_signals_listener, &StateSignalsListener::OnSignalOpened);
139 webrtc_data_channel_->SignalClosed.connect(
140 &state_signals_listener, &StateSignalsListener::OnSignalClosed);
wu@webrtc.org78187522013-10-07 23:32:02 +0000141 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting,
142 webrtc_data_channel_->state());
hbos82ebe022016-11-14 01:41:09 -0800143 EXPECT_EQ(state_signals_listener.opened_count(), 0);
144 EXPECT_EQ(state_signals_listener.closed_count(), 0);
wu@webrtc.org78187522013-10-07 23:32:02 +0000145 SetChannelReady();
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000146
wu@webrtc.org78187522013-10-07 23:32:02 +0000147 EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state());
hbos82ebe022016-11-14 01:41:09 -0800148 EXPECT_EQ(state_signals_listener.opened_count(), 1);
149 EXPECT_EQ(state_signals_listener.closed_count(), 0);
wu@webrtc.org78187522013-10-07 23:32:02 +0000150 webrtc_data_channel_->Close();
151 EXPECT_EQ(webrtc::DataChannelInterface::kClosed,
152 webrtc_data_channel_->state());
hbos82ebe022016-11-14 01:41:09 -0800153 EXPECT_EQ(state_signals_listener.opened_count(), 1);
154 EXPECT_EQ(state_signals_listener.closed_count(), 1);
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000155 // Verifies that it's disconnected from the transport.
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700156 EXPECT_FALSE(provider_->IsConnected(webrtc_data_channel_.get()));
wu@webrtc.org78187522013-10-07 23:32:02 +0000157}
158
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000159// Tests that DataChannel::buffered_amount() is correct after the channel is
160// blocked.
161TEST_F(SctpDataChannelTest, BufferedAmountWhenBlocked) {
bemasc0edd50c2015-07-01 13:34:33 -0700162 AddObserver();
wu@webrtc.org78187522013-10-07 23:32:02 +0000163 SetChannelReady();
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000164 webrtc::DataBuffer buffer("abcd");
165 EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
Marina Cioceae448a3f2019-03-04 15:52:21 +0100166 size_t successful_send_count = 1;
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000167
168 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
Marina Cioceae448a3f2019-03-04 15:52:21 +0100169 EXPECT_EQ(successful_send_count,
170 observer_->on_buffered_amount_change_count());
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000171
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700172 provider_->set_send_blocked(true);
wu@webrtc.org78187522013-10-07 23:32:02 +0000173
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000174 const int number_of_packets = 3;
175 for (int i = 0; i < number_of_packets; ++i) {
176 EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
177 }
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06 +0000178 EXPECT_EQ(buffer.data.size() * number_of_packets,
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000179 webrtc_data_channel_->buffered_amount());
Marina Cioceae448a3f2019-03-04 15:52:21 +0100180 EXPECT_EQ(successful_send_count,
181 observer_->on_buffered_amount_change_count());
182
183 provider_->set_send_blocked(false);
184 successful_send_count += number_of_packets;
185 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
186 EXPECT_EQ(successful_send_count,
Mirko Bonadeie12c1fe2018-07-03 12:53:23 +0200187 observer_->on_buffered_amount_change_count());
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000188}
189
190// Tests that the queued data are sent when the channel transitions from blocked
191// to unblocked.
192TEST_F(SctpDataChannelTest, QueuedDataSentWhenUnblocked) {
bemasc0edd50c2015-07-01 13:34:33 -0700193 AddObserver();
wu@webrtc.org78187522013-10-07 23:32:02 +0000194 SetChannelReady();
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000195 webrtc::DataBuffer buffer("abcd");
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700196 provider_->set_send_blocked(true);
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000197 EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
198
Marina Cioceae448a3f2019-03-04 15:52:21 +0100199 EXPECT_EQ(0U, observer_->on_buffered_amount_change_count());
bemasc0edd50c2015-07-01 13:34:33 -0700200
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700201 provider_->set_send_blocked(false);
wu@webrtc.org78187522013-10-07 23:32:02 +0000202 SetChannelReady();
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000203 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
Marina Cioceae448a3f2019-03-04 15:52:21 +0100204 EXPECT_EQ(1U, observer_->on_buffered_amount_change_count());
wu@webrtc.orgd64719d2013-08-01 00:00:07 +0000205}
wu@webrtc.org78187522013-10-07 23:32:02 +0000206
jiayl@webrtc.orgcceb1662015-01-22 00:55:10 +0000207// Tests that no crash when the channel is blocked right away while trying to
208// send queued data.
209TEST_F(SctpDataChannelTest, BlockedWhenSendQueuedDataNoCrash) {
bemasc0edd50c2015-07-01 13:34:33 -0700210 AddObserver();
jiayl@webrtc.orgcceb1662015-01-22 00:55:10 +0000211 SetChannelReady();
212 webrtc::DataBuffer buffer("abcd");
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700213 provider_->set_send_blocked(true);
jiayl@webrtc.orgcceb1662015-01-22 00:55:10 +0000214 EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
Marina Cioceae448a3f2019-03-04 15:52:21 +0100215 EXPECT_EQ(0U, observer_->on_buffered_amount_change_count());
jiayl@webrtc.orgcceb1662015-01-22 00:55:10 +0000216
217 // Set channel ready while it is still blocked.
218 SetChannelReady();
219 EXPECT_EQ(buffer.size(), webrtc_data_channel_->buffered_amount());
Marina Cioceae448a3f2019-03-04 15:52:21 +0100220 EXPECT_EQ(0U, observer_->on_buffered_amount_change_count());
jiayl@webrtc.orgcceb1662015-01-22 00:55:10 +0000221
222 // Unblock the channel to send queued data again, there should be no crash.
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700223 provider_->set_send_blocked(false);
jiayl@webrtc.orgcceb1662015-01-22 00:55:10 +0000224 SetChannelReady();
225 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
Marina Cioceae448a3f2019-03-04 15:52:21 +0100226 EXPECT_EQ(1U, observer_->on_buffered_amount_change_count());
jiayl@webrtc.orgcceb1662015-01-22 00:55:10 +0000227}
228
hbos84ffdee2016-10-12 14:14:39 -0700229// Tests that DataChannel::messages_sent() and DataChannel::bytes_sent() are
230// correct, sending data both while unblocked and while blocked.
231TEST_F(SctpDataChannelTest, VerifyMessagesAndBytesSent) {
232 AddObserver();
233 SetChannelReady();
234 std::vector<webrtc::DataBuffer> buffers({
Yves Gerey665174f2018-06-19 15:03:05 +0200235 webrtc::DataBuffer("message 1"), webrtc::DataBuffer("msg 2"),
236 webrtc::DataBuffer("message three"), webrtc::DataBuffer("quadra message"),
237 webrtc::DataBuffer("fifthmsg"),
238 webrtc::DataBuffer("message of the beast"),
hbos84ffdee2016-10-12 14:14:39 -0700239 });
240
241 // Default values.
242 EXPECT_EQ(0U, webrtc_data_channel_->messages_sent());
243 EXPECT_EQ(0U, webrtc_data_channel_->bytes_sent());
244
245 // Send three buffers while not blocked.
246 provider_->set_send_blocked(false);
247 EXPECT_TRUE(webrtc_data_channel_->Send(buffers[0]));
248 EXPECT_TRUE(webrtc_data_channel_->Send(buffers[1]));
249 EXPECT_TRUE(webrtc_data_channel_->Send(buffers[2]));
250 size_t bytes_sent = buffers[0].size() + buffers[1].size() + buffers[2].size();
251 EXPECT_EQ_WAIT(0U, webrtc_data_channel_->buffered_amount(), kDefaultTimeout);
252 EXPECT_EQ(3U, webrtc_data_channel_->messages_sent());
253 EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent());
254
255 // Send three buffers while blocked, queuing the buffers.
256 provider_->set_send_blocked(true);
257 EXPECT_TRUE(webrtc_data_channel_->Send(buffers[3]));
258 EXPECT_TRUE(webrtc_data_channel_->Send(buffers[4]));
259 EXPECT_TRUE(webrtc_data_channel_->Send(buffers[5]));
260 size_t bytes_queued =
261 buffers[3].size() + buffers[4].size() + buffers[5].size();
262 EXPECT_EQ(bytes_queued, webrtc_data_channel_->buffered_amount());
263 EXPECT_EQ(3U, webrtc_data_channel_->messages_sent());
264 EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent());
265
266 // Unblock and make sure everything was sent.
267 provider_->set_send_blocked(false);
268 EXPECT_EQ_WAIT(0U, webrtc_data_channel_->buffered_amount(), kDefaultTimeout);
269 bytes_sent += bytes_queued;
270 EXPECT_EQ(6U, webrtc_data_channel_->messages_sent());
271 EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent());
272}
273
wu@webrtc.org78187522013-10-07 23:32:02 +0000274// Tests that the queued control message is sent when channel is ready.
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000275TEST_F(SctpDataChannelTest, OpenMessageSent) {
276 // Initially the id is unassigned.
277 EXPECT_EQ(-1, webrtc_data_channel_->id());
278
wu@webrtc.org78187522013-10-07 23:32:02 +0000279 SetChannelReady();
wu@webrtc.orgcecfd182013-10-30 05:18:12 +0000280 EXPECT_GE(webrtc_data_channel_->id(), 0);
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700281 EXPECT_EQ(cricket::DMT_CONTROL, provider_->last_send_data_params().type);
282 EXPECT_EQ(provider_->last_send_data_params().ssrc,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200283 static_cast<uint32_t>(webrtc_data_channel_->id()));
wu@webrtc.org78187522013-10-07 23:32:02 +0000284}
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000285
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000286TEST_F(SctpDataChannelTest, QueuedOpenMessageSent) {
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700287 provider_->set_send_blocked(true);
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000288 SetChannelReady();
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700289 provider_->set_send_blocked(false);
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000290
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700291 EXPECT_EQ(cricket::DMT_CONTROL, provider_->last_send_data_params().type);
292 EXPECT_EQ(provider_->last_send_data_params().ssrc,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200293 static_cast<uint32_t>(webrtc_data_channel_->id()));
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000294}
295
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000296// Tests that the DataChannel created after transport gets ready can enter OPEN
297// state.
298TEST_F(SctpDataChannelTest, LateCreatedChannelTransitionToOpen) {
299 SetChannelReady();
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000300 webrtc::InternalDataChannelInit init;
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000301 init.id = 1;
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700302 rtc::scoped_refptr<DataChannel> dc =
303 DataChannel::Create(provider_.get(), cricket::DCT_SCTP, "test1", init);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000304 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, dc->state());
Yves Gerey665174f2018-06-19 15:03:05 +0200305 EXPECT_TRUE_WAIT(webrtc::DataChannelInterface::kOpen == dc->state(), 1000);
wu@webrtc.org07a6fbe2013-11-04 18:41:34 +0000306}
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000307
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000308// Tests that an unordered DataChannel sends data as ordered until the OPEN_ACK
309// message is received.
310TEST_F(SctpDataChannelTest, SendUnorderedAfterReceivesOpenAck) {
311 SetChannelReady();
312 webrtc::InternalDataChannelInit init;
313 init.id = 1;
314 init.ordered = false;
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700315 rtc::scoped_refptr<DataChannel> dc =
316 DataChannel::Create(provider_.get(), cricket::DCT_SCTP, "test1", init);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000317
318 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000);
319
320 // Sends a message and verifies it's ordered.
321 webrtc::DataBuffer buffer("some data");
322 ASSERT_TRUE(dc->Send(buffer));
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700323 EXPECT_TRUE(provider_->last_send_data_params().ordered);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000324
325 // Emulates receiving an OPEN_ACK message.
326 cricket::ReceiveDataParams params;
327 params.ssrc = init.id;
328 params.type = cricket::DMT_CONTROL;
jbaucheec21bd2016-03-20 06:15:43 -0700329 rtc::CopyOnWriteBuffer payload;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000330 webrtc::WriteDataChannelOpenAckMessage(&payload);
deadbeef953c2ce2017-01-09 14:53:41 -0800331 dc->OnDataReceived(params, payload);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000332
333 // Sends another message and verifies it's unordered.
334 ASSERT_TRUE(dc->Send(buffer));
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700335 EXPECT_FALSE(provider_->last_send_data_params().ordered);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000336}
337
338// Tests that an unordered DataChannel sends unordered data after any DATA
339// message is received.
340TEST_F(SctpDataChannelTest, SendUnorderedAfterReceiveData) {
341 SetChannelReady();
342 webrtc::InternalDataChannelInit init;
343 init.id = 1;
344 init.ordered = false;
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700345 rtc::scoped_refptr<DataChannel> dc =
346 DataChannel::Create(provider_.get(), cricket::DCT_SCTP, "test1", init);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000347
348 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000);
349
350 // Emulates receiving a DATA message.
351 cricket::ReceiveDataParams params;
352 params.ssrc = init.id;
353 params.type = cricket::DMT_TEXT;
354 webrtc::DataBuffer buffer("data");
deadbeef953c2ce2017-01-09 14:53:41 -0800355 dc->OnDataReceived(params, buffer.data);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000356
357 // Sends a message and verifies it's unordered.
358 ASSERT_TRUE(dc->Send(buffer));
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700359 EXPECT_FALSE(provider_->last_send_data_params().ordered);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000360}
361
Lally Singh5c6c6e02015-05-29 11:52:39 -0400362// Tests that the channel can't open until it's successfully sent the OPEN
363// message.
364TEST_F(SctpDataChannelTest, OpenWaitsForOpenMesssage) {
365 webrtc::DataBuffer buffer("foo");
366
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700367 provider_->set_send_blocked(true);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400368 SetChannelReady();
369 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting,
370 webrtc_data_channel_->state());
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700371 provider_->set_send_blocked(false);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400372 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen,
373 webrtc_data_channel_->state(), 1000);
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700374 EXPECT_EQ(cricket::DMT_CONTROL, provider_->last_send_data_params().type);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400375}
376
377// Tests that close first makes sure all queued data gets sent.
378TEST_F(SctpDataChannelTest, QueuedCloseFlushes) {
379 webrtc::DataBuffer buffer("foo");
380
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700381 provider_->set_send_blocked(true);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400382 SetChannelReady();
383 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting,
384 webrtc_data_channel_->state());
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700385 provider_->set_send_blocked(false);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400386 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen,
387 webrtc_data_channel_->state(), 1000);
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700388 provider_->set_send_blocked(true);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400389 webrtc_data_channel_->Send(buffer);
390 webrtc_data_channel_->Close();
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700391 provider_->set_send_blocked(false);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400392 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed,
393 webrtc_data_channel_->state(), 1000);
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700394 EXPECT_EQ(cricket::DMT_TEXT, provider_->last_send_data_params().type);
Lally Singh5c6c6e02015-05-29 11:52:39 -0400395}
396
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000397// Tests that messages are sent with the right ssrc.
398TEST_F(SctpDataChannelTest, SendDataSsrc) {
399 webrtc_data_channel_->SetSctpSid(1);
400 SetChannelReady();
401 webrtc::DataBuffer buffer("data");
402 EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700403 EXPECT_EQ(1U, provider_->last_send_data_params().ssrc);
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000404}
405
406// Tests that the incoming messages with wrong ssrcs are rejected.
407TEST_F(SctpDataChannelTest, ReceiveDataWithInvalidSsrc) {
408 webrtc_data_channel_->SetSctpSid(1);
409 SetChannelReady();
410
411 AddObserver();
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000412
413 cricket::ReceiveDataParams params;
414 params.ssrc = 0;
415 webrtc::DataBuffer buffer("abcd");
deadbeef953c2ce2017-01-09 14:53:41 -0800416 webrtc_data_channel_->OnDataReceived(params, buffer.data);
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +0000417
418 EXPECT_EQ(0U, observer_->messages_received());
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000419}
420
421// Tests that the incoming messages with right ssrcs are acceted.
422TEST_F(SctpDataChannelTest, ReceiveDataWithValidSsrc) {
423 webrtc_data_channel_->SetSctpSid(1);
424 SetChannelReady();
425
426 AddObserver();
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000427
428 cricket::ReceiveDataParams params;
429 params.ssrc = 1;
430 webrtc::DataBuffer buffer("abcd");
431
deadbeef953c2ce2017-01-09 14:53:41 -0800432 webrtc_data_channel_->OnDataReceived(params, buffer.data);
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +0000433 EXPECT_EQ(1U, observer_->messages_received());
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000434}
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000435
436// Tests that no CONTROL message is sent if the datachannel is negotiated and
437// not created from an OPEN message.
438TEST_F(SctpDataChannelTest, NoMsgSentIfNegotiatedAndNotFromOpenMsg) {
439 webrtc::InternalDataChannelInit config;
440 config.id = 1;
441 config.negotiated = true;
442 config.open_handshake_role = webrtc::InternalDataChannelInit::kNone;
443
444 SetChannelReady();
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700445 rtc::scoped_refptr<DataChannel> dc =
446 DataChannel::Create(provider_.get(), cricket::DCT_SCTP, "test1", config);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000447
448 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000);
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700449 EXPECT_EQ(0U, provider_->last_send_data_params().ssrc);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000450}
451
hbos84ffdee2016-10-12 14:14:39 -0700452// Tests that DataChannel::messages_received() and DataChannel::bytes_received()
453// are correct, receiving data both while not open and while open.
454TEST_F(SctpDataChannelTest, VerifyMessagesAndBytesReceived) {
455 AddObserver();
456 std::vector<webrtc::DataBuffer> buffers({
Yves Gerey665174f2018-06-19 15:03:05 +0200457 webrtc::DataBuffer("message 1"), webrtc::DataBuffer("msg 2"),
458 webrtc::DataBuffer("message three"), webrtc::DataBuffer("quadra message"),
459 webrtc::DataBuffer("fifthmsg"),
460 webrtc::DataBuffer("message of the beast"),
hbos84ffdee2016-10-12 14:14:39 -0700461 });
462
463 webrtc_data_channel_->SetSctpSid(1);
464 cricket::ReceiveDataParams params;
465 params.ssrc = 1;
466
467 // Default values.
468 EXPECT_EQ(0U, webrtc_data_channel_->messages_received());
469 EXPECT_EQ(0U, webrtc_data_channel_->bytes_received());
470
471 // Receive three buffers while data channel isn't open.
deadbeef953c2ce2017-01-09 14:53:41 -0800472 webrtc_data_channel_->OnDataReceived(params, buffers[0].data);
473 webrtc_data_channel_->OnDataReceived(params, buffers[1].data);
474 webrtc_data_channel_->OnDataReceived(params, buffers[2].data);
hbos84ffdee2016-10-12 14:14:39 -0700475 EXPECT_EQ(0U, observer_->messages_received());
476 EXPECT_EQ(0U, webrtc_data_channel_->messages_received());
477 EXPECT_EQ(0U, webrtc_data_channel_->bytes_received());
478
479 // Open channel and make sure everything was received.
480 SetChannelReady();
481 size_t bytes_received =
482 buffers[0].size() + buffers[1].size() + buffers[2].size();
483 EXPECT_EQ(3U, observer_->messages_received());
484 EXPECT_EQ(3U, webrtc_data_channel_->messages_received());
485 EXPECT_EQ(bytes_received, webrtc_data_channel_->bytes_received());
486
487 // Receive three buffers while open.
deadbeef953c2ce2017-01-09 14:53:41 -0800488 webrtc_data_channel_->OnDataReceived(params, buffers[3].data);
489 webrtc_data_channel_->OnDataReceived(params, buffers[4].data);
490 webrtc_data_channel_->OnDataReceived(params, buffers[5].data);
hbos84ffdee2016-10-12 14:14:39 -0700491 bytes_received += buffers[3].size() + buffers[4].size() + buffers[5].size();
492 EXPECT_EQ(6U, observer_->messages_received());
493 EXPECT_EQ(6U, webrtc_data_channel_->messages_received());
494 EXPECT_EQ(bytes_received, webrtc_data_channel_->bytes_received());
495}
496
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000497// Tests that OPEN_ACK message is sent if the datachannel is created from an
498// OPEN message.
499TEST_F(SctpDataChannelTest, OpenAckSentIfCreatedFromOpenMessage) {
500 webrtc::InternalDataChannelInit config;
501 config.id = 1;
502 config.negotiated = true;
503 config.open_handshake_role = webrtc::InternalDataChannelInit::kAcker;
504
505 SetChannelReady();
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700506 rtc::scoped_refptr<DataChannel> dc =
507 DataChannel::Create(provider_.get(), cricket::DCT_SCTP, "test1", config);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000508
509 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000);
510
511 EXPECT_EQ(static_cast<unsigned int>(config.id),
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700512 provider_->last_send_data_params().ssrc);
513 EXPECT_EQ(cricket::DMT_CONTROL, provider_->last_send_data_params().type);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000514}
515
516// Tests the OPEN_ACK role assigned by InternalDataChannelInit.
517TEST_F(SctpDataChannelTest, OpenAckRoleInitialization) {
518 webrtc::InternalDataChannelInit init;
519 EXPECT_EQ(webrtc::InternalDataChannelInit::kOpener, init.open_handshake_role);
520 EXPECT_FALSE(init.negotiated);
521
522 webrtc::DataChannelInit base;
523 base.negotiated = true;
524 webrtc::InternalDataChannelInit init2(base);
525 EXPECT_EQ(webrtc::InternalDataChannelInit::kNone, init2.open_handshake_role);
526}
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +0000527
528// Tests that the DataChannel is closed if the sending buffer is full.
529TEST_F(SctpDataChannelTest, ClosedWhenSendBufferFull) {
530 SetChannelReady();
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000531
jbaucheec21bd2016-03-20 06:15:43 -0700532 rtc::CopyOnWriteBuffer buffer(1024);
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06 +0000533 memset(buffer.data(), 0, buffer.size());
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000534
535 webrtc::DataBuffer packet(buffer, true);
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700536 provider_->set_send_blocked(true);
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +0000537
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000538 for (size_t i = 0; i < 16 * 1024 + 1; ++i) {
539 EXPECT_TRUE(webrtc_data_channel_->Send(packet));
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +0000540 }
541
Lally Singh5c6c6e02015-05-29 11:52:39 -0400542 EXPECT_TRUE(
543 webrtc::DataChannelInterface::kClosed == webrtc_data_channel_->state() ||
544 webrtc::DataChannelInterface::kClosing == webrtc_data_channel_->state());
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +0000545}
546
547// Tests that the DataChannel is closed on transport errors.
548TEST_F(SctpDataChannelTest, ClosedOnTransportError) {
549 SetChannelReady();
550 webrtc::DataBuffer buffer("abcd");
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700551 provider_->set_transport_error();
jiayl@webrtc.org5dc51fb2014-05-29 15:33:54 +0000552
553 EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
554
555 EXPECT_EQ(webrtc::DataChannelInterface::kClosed,
556 webrtc_data_channel_->state());
557}
jiayl@webrtc.org9f8164c2014-05-30 21:53:17 +0000558
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000559// Tests that the DataChannel is closed if the received buffer is full.
560TEST_F(SctpDataChannelTest, ClosedWhenReceivedBufferFull) {
561 SetChannelReady();
jbaucheec21bd2016-03-20 06:15:43 -0700562 rtc::CopyOnWriteBuffer buffer(1024);
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06 +0000563 memset(buffer.data(), 0, buffer.size());
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000564
565 cricket::ReceiveDataParams params;
566 params.ssrc = 0;
567
568 // Receiving data without having an observer will overflow the buffer.
569 for (size_t i = 0; i < 16 * 1024 + 1; ++i) {
deadbeef953c2ce2017-01-09 14:53:41 -0800570 webrtc_data_channel_->OnDataReceived(params, buffer);
jiayl@webrtc.orgb43c99d2014-06-20 17:11:14 +0000571 }
572 EXPECT_EQ(webrtc::DataChannelInterface::kClosed,
573 webrtc_data_channel_->state());
574}
jiayl@webrtc.org3edbaaf2014-07-18 23:57:50 +0000575
576// Tests that sending empty data returns no error and keeps the channel open.
577TEST_F(SctpDataChannelTest, SendEmptyData) {
578 webrtc_data_channel_->SetSctpSid(1);
579 SetChannelReady();
Yves Gerey665174f2018-06-19 15:03:05 +0200580 EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state());
jiayl@webrtc.org3edbaaf2014-07-18 23:57:50 +0000581
582 webrtc::DataBuffer buffer("");
583 EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
Yves Gerey665174f2018-06-19 15:03:05 +0200584 EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state());
jiayl@webrtc.org3edbaaf2014-07-18 23:57:50 +0000585}
bemasc@webrtc.org9b5467e2014-12-04 23:16:52 +0000586
587// Tests that a channel can be closed without being opened or assigned an sid.
588TEST_F(SctpDataChannelTest, NeverOpened) {
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700589 provider_->set_transport_available(true);
bemasc@webrtc.org9b5467e2014-12-04 23:16:52 +0000590 webrtc_data_channel_->OnTransportChannelCreated();
591 webrtc_data_channel_->Close();
592}
deadbeefab9b2d12015-10-14 11:33:11 -0700593
Taylor Brandstetter4cb5b642016-08-12 10:10:31 -0700594// Test that the data channel goes to the "closed" state (and doesn't crash)
595// when its transport goes away, even while data is buffered.
596TEST_F(SctpDataChannelTest, TransportDestroyedWhileDataBuffered) {
597 SetChannelReady();
598
599 rtc::CopyOnWriteBuffer buffer(1024);
600 memset(buffer.data(), 0, buffer.size());
601 webrtc::DataBuffer packet(buffer, true);
602
603 // Send a packet while sending is blocked so it ends up buffered.
604 provider_->set_send_blocked(true);
605 EXPECT_TRUE(webrtc_data_channel_->Send(packet));
606
607 // Tell the data channel that its tranpsort is being destroyed.
608 // It should then stop using the transport (allowing us to delete it) and
609 // transition to the "closed" state.
610 webrtc_data_channel_->OnTransportChannelDestroyed();
611 provider_.reset(nullptr);
612 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed,
613 webrtc_data_channel_->state(), kDefaultTimeout);
614}
615
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200616class SctpSidAllocatorTest : public ::testing::Test {
deadbeefab9b2d12015-10-14 11:33:11 -0700617 protected:
618 SctpSidAllocator allocator_;
619};
620
621// Verifies that an even SCTP id is allocated for SSL_CLIENT and an odd id for
622// SSL_SERVER.
623TEST_F(SctpSidAllocatorTest, SctpIdAllocationBasedOnRole) {
624 int id;
625 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &id));
626 EXPECT_EQ(1, id);
627 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &id));
628 EXPECT_EQ(0, id);
629 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &id));
630 EXPECT_EQ(3, id);
631 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &id));
632 EXPECT_EQ(2, id);
633}
634
635// Verifies that SCTP ids of existing DataChannels are not reused.
636TEST_F(SctpSidAllocatorTest, SctpIdAllocationNoReuse) {
637 int old_id = 1;
638 EXPECT_TRUE(allocator_.ReserveSid(old_id));
639
640 int new_id;
641 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &new_id));
642 EXPECT_NE(old_id, new_id);
643
644 old_id = 0;
645 EXPECT_TRUE(allocator_.ReserveSid(old_id));
646 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &new_id));
647 EXPECT_NE(old_id, new_id);
648}
649
650// Verifies that SCTP ids of removed DataChannels can be reused.
651TEST_F(SctpSidAllocatorTest, SctpIdReusedForRemovedDataChannel) {
652 int odd_id = 1;
653 int even_id = 0;
654 EXPECT_TRUE(allocator_.ReserveSid(odd_id));
655 EXPECT_TRUE(allocator_.ReserveSid(even_id));
656
657 int allocated_id = -1;
658 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id));
659 EXPECT_EQ(odd_id + 2, allocated_id);
660
661 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id));
662 EXPECT_EQ(even_id + 2, allocated_id);
663
664 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id));
665 EXPECT_EQ(odd_id + 4, allocated_id);
666
667 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id));
668 EXPECT_EQ(even_id + 4, allocated_id);
669
670 allocator_.ReleaseSid(odd_id);
671 allocator_.ReleaseSid(even_id);
672
673 // Verifies that removed ids are reused.
674 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id));
675 EXPECT_EQ(odd_id, allocated_id);
676
677 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id));
678 EXPECT_EQ(even_id, allocated_id);
679
680 // Verifies that used higher ids are not reused.
681 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id));
682 EXPECT_EQ(odd_id + 6, allocated_id);
683
684 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id));
685 EXPECT_EQ(even_id + 6, allocated_id);
686}