blob: de9541941f418da14581e14788b9cb28e87a8a11 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2013 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton6c38cc72017-11-29 10:25:58 -080011#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070012#include <memory>
Steve Anton6c38cc72017-11-29 10:25:58 -080013#include <string>
kwiberg3ec46792016-04-27 07:22:53 -070014
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "p2p/base/asyncstuntcpsocket.h"
16#include "rtc_base/asyncsocket.h"
17#include "rtc_base/gunit.h"
18#include "rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000019
20namespace cricket {
21
22static unsigned char kStunMessageWithZeroLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020023 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes)
24 0x21, 0x12, 0xA4, 0x42, '0', '1', '2', '3',
25 '4', '5', '6', '7', '8', '9', 'a', 'b',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000026};
27
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000028static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020029 0x40, 0x00, 0x00, 0x00, // length of 0 (last 2 bytes)
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000030};
31
32static unsigned char kTurnChannelDataMessage[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020033 0x40, 0x00, 0x00, 0x10, 0x21, 0x12, 0xA4, 0x42, '0', '1',
34 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000035};
36
37static unsigned char kStunMessageWithInvalidLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020038 0x00, 0x01, 0x00, 0x10, 0x21, 0x12, 0xA4, 0x42, '0', '1',
39 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000040};
41
42static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020043 0x80, 0x00, 0x00, 0x20, 0x21, 0x12, 0xA4, 0x42, '0', '1',
44 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000045};
46
47static unsigned char kTurnChannelDataMessageWithOddLength[] = {
Yves Gerey665174f2018-06-19 15:03:05 +020048 0x40, 0x00, 0x00, 0x05, 0x21, 0x12, 0xA4, 0x42, '0',
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000049};
50
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
52static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
53
54class AsyncStunTCPSocketTest : public testing::Test,
55 public sigslot::has_slots<> {
56 protected:
57 AsyncStunTCPSocketTest()
deadbeef98e186c2017-05-16 18:00:06 -070058 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000059
Yves Gerey665174f2018-06-19 15:03:05 +020060 virtual void SetUp() { CreateSockets(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000061
62 void CreateSockets() {
Yves Gerey665174f2018-06-19 15:03:05 +020063 rtc::AsyncSocket* server =
64 vss_->CreateAsyncSocket(kServerAddr.family(), SOCK_STREAM);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000065 server->Bind(kServerAddr);
66 recv_socket_.reset(new AsyncStunTCPSocket(server, true));
67 recv_socket_->SignalNewConnection.connect(
68 this, &AsyncStunTCPSocketTest::OnNewConnection);
69
Yves Gerey665174f2018-06-19 15:03:05 +020070 rtc::AsyncSocket* client =
71 vss_->CreateAsyncSocket(kClientAddr.family(), SOCK_STREAM);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072 send_socket_.reset(AsyncStunTCPSocket::Create(
73 client, kClientAddr, recv_socket_->GetLocalAddress()));
deadbeefb56671e2017-05-26 18:40:05 -070074 send_socket_->SignalSentPacket.connect(
75 this, &AsyncStunTCPSocketTest::OnSentPacket);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000076 ASSERT_TRUE(send_socket_.get() != NULL);
77 vss_->ProcessMessagesUntilIdle();
78 }
79
Yves Gerey665174f2018-06-19 15:03:05 +020080 void OnReadPacket(rtc::AsyncPacketSocket* socket,
81 const char* data,
82 size_t len,
83 const rtc::SocketAddress& remote_addr,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000084 const rtc::PacketTime& packet_time) {
85 recv_packets_.push_back(std::string(data, len));
86 }
87
deadbeefb56671e2017-05-26 18:40:05 -070088 void OnSentPacket(rtc::AsyncPacketSocket* socket,
89 const rtc::SentPacket& packet) {
90 ++sent_packets_;
91 }
92
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000093 void OnNewConnection(rtc::AsyncPacketSocket* server,
94 rtc::AsyncPacketSocket* new_socket) {
95 listen_socket_.reset(new_socket);
Yves Gerey665174f2018-06-19 15:03:05 +020096 new_socket->SignalReadPacket.connect(this,
97 &AsyncStunTCPSocketTest::OnReadPacket);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000098 }
99
100 bool Send(const void* data, size_t len) {
101 rtc::PacketOptions options;
Yves Gerey665174f2018-06-19 15:03:05 +0200102 size_t ret =
103 send_socket_->Send(reinterpret_cast<const char*>(data), len, options);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000104 vss_->ProcessMessagesUntilIdle();
105 return (ret == len);
106 }
107
108 bool CheckData(const void* data, int len) {
109 bool ret = false;
110 if (recv_packets_.size()) {
Yves Gerey665174f2018-06-19 15:03:05 +0200111 std::string packet = recv_packets_.front();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000112 recv_packets_.pop_front();
113 ret = (memcmp(data, packet.c_str(), len) == 0);
114 }
115 return ret;
116 }
117
kwiberg3ec46792016-04-27 07:22:53 -0700118 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700119 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700120 std::unique_ptr<AsyncStunTCPSocket> send_socket_;
121 std::unique_ptr<AsyncStunTCPSocket> recv_socket_;
122 std::unique_ptr<rtc::AsyncPacketSocket> listen_socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000123 std::list<std::string> recv_packets_;
deadbeefb56671e2017-05-26 18:40:05 -0700124 int sent_packets_ = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000125};
126
127// Testing a stun packet sent/recv properly.
128TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
Yves Gerey665174f2018-06-19 15:03:05 +0200129 EXPECT_TRUE(
130 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000131 EXPECT_EQ(1u, recv_packets_.size());
132 EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
133 sizeof(kStunMessageWithZeroLength)));
134}
135
136// Verify sending multiple packets.
137TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
Yves Gerey665174f2018-06-19 15:03:05 +0200138 EXPECT_TRUE(
139 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
140 EXPECT_TRUE(
141 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
142 EXPECT_TRUE(
143 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
144 EXPECT_TRUE(
145 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000146 EXPECT_EQ(4u, recv_packets_.size());
147}
148
149// Verifying TURN channel data message with zero length.
150TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
151 EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
152 sizeof(kTurnChannelDataMessageWithZeroLength)));
153 EXPECT_EQ(1u, recv_packets_.size());
154 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
155 sizeof(kTurnChannelDataMessageWithZeroLength)));
156}
157
158// Verifying TURN channel data message.
159TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
Yves Gerey665174f2018-06-19 15:03:05 +0200160 EXPECT_TRUE(Send(kTurnChannelDataMessage, sizeof(kTurnChannelDataMessage)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000161 EXPECT_EQ(1u, recv_packets_.size());
Yves Gerey665174f2018-06-19 15:03:05 +0200162 EXPECT_TRUE(
163 CheckData(kTurnChannelDataMessage, sizeof(kTurnChannelDataMessage)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000164}
165
166// Verifying TURN channel messages which needs padding handled properly.
167TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
168 EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
169 sizeof(kTurnChannelDataMessageWithOddLength)));
170 EXPECT_EQ(1u, recv_packets_.size());
171 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
172 sizeof(kTurnChannelDataMessageWithOddLength)));
173}
174
175// Verifying stun message with invalid length.
176TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
177 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
178 sizeof(kStunMessageWithInvalidLength)));
179 EXPECT_EQ(0u, recv_packets_.size());
180
181 // Modify the message length to larger value.
182 kStunMessageWithInvalidLength[2] = 0xFF;
183 kStunMessageWithInvalidLength[3] = 0xFF;
184 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
185 sizeof(kStunMessageWithInvalidLength)));
186
187 // Modify the message length to smaller value.
188 kStunMessageWithInvalidLength[2] = 0x00;
189 kStunMessageWithInvalidLength[3] = 0x01;
190 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
191 sizeof(kStunMessageWithInvalidLength)));
192}
193
194// Verifying TURN channel data message with invalid length.
195TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
196 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
Yves Gerey665174f2018-06-19 15:03:05 +0200197 sizeof(kTurnChannelDataMessageWithInvalidLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000198 // Modify the length to larger value.
199 kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
200 kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
201 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
Yves Gerey665174f2018-06-19 15:03:05 +0200202 sizeof(kTurnChannelDataMessageWithInvalidLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000203
204 // Modify the length to smaller value.
205 kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
206 kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
207 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
Yves Gerey665174f2018-06-19 15:03:05 +0200208 sizeof(kTurnChannelDataMessageWithInvalidLength)));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000209}
210
211// Verifying a small buffer handled (dropped) properly. This will be
212// a common one for both stun and turn.
213TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
214 char data[1];
215 EXPECT_FALSE(Send(data, sizeof(data)));
216}
217
218// Verifying a legal large turn message.
219TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
220 // We have problem in getting the SignalWriteEvent from the virtual socket
221 // server. So increasing the send buffer to 64k.
222 // TODO(mallinath) - Remove this setting after we fix vss issue.
223 vss_->set_send_buffer_capacity(64 * 1024);
224 unsigned char packet[65539];
225 packet[0] = 0x40;
226 packet[1] = 0x00;
227 packet[2] = 0xFF;
228 packet[3] = 0xFF;
229 EXPECT_TRUE(Send(packet, sizeof(packet)));
230}
231
232// Verifying a legal large stun message.
233TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
234 // We have problem in getting the SignalWriteEvent from the virtual socket
235 // server. So increasing the send buffer to 64k.
236 // TODO(mallinath) - Remove this setting after we fix vss issue.
237 vss_->set_send_buffer_capacity(64 * 1024);
238 unsigned char packet[65552];
239 packet[0] = 0x00;
240 packet[1] = 0x01;
241 packet[2] = 0xFF;
242 packet[3] = 0xFC;
243 EXPECT_TRUE(Send(packet, sizeof(packet)));
244}
245
246// Investigate why WriteEvent is not signaled from VSS.
247TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
248 vss_->set_send_buffer_capacity(1);
249 Send(kTurnChannelDataMessageWithOddLength,
250 sizeof(kTurnChannelDataMessageWithOddLength));
251 EXPECT_EQ(1u, recv_packets_.size());
252 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
253 sizeof(kTurnChannelDataMessageWithOddLength)));
254}
255
deadbeefb56671e2017-05-26 18:40:05 -0700256// Test that SignalSentPacket is fired when a packet is sent.
257TEST_F(AsyncStunTCPSocketTest, SignalSentPacketFiredWhenPacketSent) {
258 ASSERT_TRUE(
259 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
260 EXPECT_EQ(1, sent_packets_);
261 // Send another packet for good measure.
262 ASSERT_TRUE(
263 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
264 EXPECT_EQ(2, sent_packets_);
265}
266
267// Test that SignalSentPacket isn't fired when a packet isn't sent (for
268// example, because it's invalid).
269TEST_F(AsyncStunTCPSocketTest, SignalSentPacketNotFiredWhenPacketNotSent) {
270 // Attempt to send a packet that's too small; since it isn't sent,
271 // SignalSentPacket shouldn't fire.
272 char data[1];
273 ASSERT_FALSE(Send(data, sizeof(data)));
274 EXPECT_EQ(0, sent_packets_);
275}
276
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000277} // namespace cricket