blob: 806b43b2db4299591bb8602fc0c6bbbac10e612a [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
kwiberg3ec46792016-04-27 07:22:53 -070011#include <memory>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "p2p/base/asyncstuntcpsocket.h"
14#include "rtc_base/asyncsocket.h"
15#include "rtc_base/gunit.h"
16#include "rtc_base/virtualsocketserver.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000017
18namespace cricket {
19
20static unsigned char kStunMessageWithZeroLength[] = {
21 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes)
22 0x21, 0x12, 0xA4, 0x42,
23 '0', '1', '2', '3',
24 '4', '5', '6', '7',
25 '8', '9', 'a', 'b',
26};
27
28
29static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
30 0x40, 0x00, 0x00, 0x00, // length of 0 (last 2 bytes)
31};
32
33static unsigned char kTurnChannelDataMessage[] = {
34 0x40, 0x00, 0x00, 0x10,
35 0x21, 0x12, 0xA4, 0x42,
36 '0', '1', '2', '3',
37 '4', '5', '6', '7',
38 '8', '9', 'a', 'b',
39};
40
41static unsigned char kStunMessageWithInvalidLength[] = {
42 0x00, 0x01, 0x00, 0x10,
43 0x21, 0x12, 0xA4, 0x42,
44 '0', '1', '2', '3',
45 '4', '5', '6', '7',
46 '8', '9', 'a', 'b',
47};
48
49static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
50 0x80, 0x00, 0x00, 0x20,
51 0x21, 0x12, 0xA4, 0x42,
52 '0', '1', '2', '3',
53 '4', '5', '6', '7',
54 '8', '9', 'a', 'b',
55};
56
57static unsigned char kTurnChannelDataMessageWithOddLength[] = {
58 0x40, 0x00, 0x00, 0x05,
59 0x21, 0x12, 0xA4, 0x42,
60 '0',
61};
62
63
64static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
65static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
66
67class AsyncStunTCPSocketTest : public testing::Test,
68 public sigslot::has_slots<> {
69 protected:
70 AsyncStunTCPSocketTest()
deadbeef98e186c2017-05-16 18:00:06 -070071 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072
73 virtual void SetUp() {
74 CreateSockets();
75 }
76
77 void CreateSockets() {
78 rtc::AsyncSocket* server = vss_->CreateAsyncSocket(
79 kServerAddr.family(), SOCK_STREAM);
80 server->Bind(kServerAddr);
81 recv_socket_.reset(new AsyncStunTCPSocket(server, true));
82 recv_socket_->SignalNewConnection.connect(
83 this, &AsyncStunTCPSocketTest::OnNewConnection);
84
85 rtc::AsyncSocket* client = vss_->CreateAsyncSocket(
86 kClientAddr.family(), SOCK_STREAM);
87 send_socket_.reset(AsyncStunTCPSocket::Create(
88 client, kClientAddr, recv_socket_->GetLocalAddress()));
deadbeefb56671e2017-05-26 18:40:05 -070089 send_socket_->SignalSentPacket.connect(
90 this, &AsyncStunTCPSocketTest::OnSentPacket);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000091 ASSERT_TRUE(send_socket_.get() != NULL);
92 vss_->ProcessMessagesUntilIdle();
93 }
94
95 void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
96 size_t len, const rtc::SocketAddress& remote_addr,
97 const rtc::PacketTime& packet_time) {
98 recv_packets_.push_back(std::string(data, len));
99 }
100
deadbeefb56671e2017-05-26 18:40:05 -0700101 void OnSentPacket(rtc::AsyncPacketSocket* socket,
102 const rtc::SentPacket& packet) {
103 ++sent_packets_;
104 }
105
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000106 void OnNewConnection(rtc::AsyncPacketSocket* server,
107 rtc::AsyncPacketSocket* new_socket) {
108 listen_socket_.reset(new_socket);
109 new_socket->SignalReadPacket.connect(
110 this, &AsyncStunTCPSocketTest::OnReadPacket);
111 }
112
113 bool Send(const void* data, size_t len) {
114 rtc::PacketOptions options;
115 size_t ret = send_socket_->Send(
116 reinterpret_cast<const char*>(data), len, options);
117 vss_->ProcessMessagesUntilIdle();
118 return (ret == len);
119 }
120
121 bool CheckData(const void* data, int len) {
122 bool ret = false;
123 if (recv_packets_.size()) {
124 std::string packet = recv_packets_.front();
125 recv_packets_.pop_front();
126 ret = (memcmp(data, packet.c_str(), len) == 0);
127 }
128 return ret;
129 }
130
kwiberg3ec46792016-04-27 07:22:53 -0700131 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700132 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700133 std::unique_ptr<AsyncStunTCPSocket> send_socket_;
134 std::unique_ptr<AsyncStunTCPSocket> recv_socket_;
135 std::unique_ptr<rtc::AsyncPacketSocket> listen_socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000136 std::list<std::string> recv_packets_;
deadbeefb56671e2017-05-26 18:40:05 -0700137 int sent_packets_ = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000138};
139
140// Testing a stun packet sent/recv properly.
141TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
142 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
143 sizeof(kStunMessageWithZeroLength)));
144 EXPECT_EQ(1u, recv_packets_.size());
145 EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
146 sizeof(kStunMessageWithZeroLength)));
147}
148
149// Verify sending multiple packets.
150TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
151 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
152 sizeof(kStunMessageWithZeroLength)));
153 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
154 sizeof(kStunMessageWithZeroLength)));
155 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
156 sizeof(kStunMessageWithZeroLength)));
157 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
158 sizeof(kStunMessageWithZeroLength)));
159 EXPECT_EQ(4u, recv_packets_.size());
160}
161
162// Verifying TURN channel data message with zero length.
163TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
164 EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
165 sizeof(kTurnChannelDataMessageWithZeroLength)));
166 EXPECT_EQ(1u, recv_packets_.size());
167 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
168 sizeof(kTurnChannelDataMessageWithZeroLength)));
169}
170
171// Verifying TURN channel data message.
172TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
173 EXPECT_TRUE(Send(kTurnChannelDataMessage,
174 sizeof(kTurnChannelDataMessage)));
175 EXPECT_EQ(1u, recv_packets_.size());
176 EXPECT_TRUE(CheckData(kTurnChannelDataMessage,
177 sizeof(kTurnChannelDataMessage)));
178}
179
180// Verifying TURN channel messages which needs padding handled properly.
181TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
182 EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
183 sizeof(kTurnChannelDataMessageWithOddLength)));
184 EXPECT_EQ(1u, recv_packets_.size());
185 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
186 sizeof(kTurnChannelDataMessageWithOddLength)));
187}
188
189// Verifying stun message with invalid length.
190TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
191 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
192 sizeof(kStunMessageWithInvalidLength)));
193 EXPECT_EQ(0u, recv_packets_.size());
194
195 // Modify the message length to larger value.
196 kStunMessageWithInvalidLength[2] = 0xFF;
197 kStunMessageWithInvalidLength[3] = 0xFF;
198 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
199 sizeof(kStunMessageWithInvalidLength)));
200
201 // Modify the message length to smaller value.
202 kStunMessageWithInvalidLength[2] = 0x00;
203 kStunMessageWithInvalidLength[3] = 0x01;
204 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
205 sizeof(kStunMessageWithInvalidLength)));
206}
207
208// Verifying TURN channel data message with invalid length.
209TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
210 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
211 sizeof(kTurnChannelDataMessageWithInvalidLength)));
212 // Modify the length to larger value.
213 kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
214 kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
215 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
216 sizeof(kTurnChannelDataMessageWithInvalidLength)));
217
218 // Modify the length to smaller value.
219 kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
220 kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
221 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
222 sizeof(kTurnChannelDataMessageWithInvalidLength)));
223}
224
225// Verifying a small buffer handled (dropped) properly. This will be
226// a common one for both stun and turn.
227TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
228 char data[1];
229 EXPECT_FALSE(Send(data, sizeof(data)));
230}
231
232// Verifying a legal large turn message.
233TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
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[65539];
239 packet[0] = 0x40;
240 packet[1] = 0x00;
241 packet[2] = 0xFF;
242 packet[3] = 0xFF;
243 EXPECT_TRUE(Send(packet, sizeof(packet)));
244}
245
246// Verifying a legal large stun message.
247TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
248 // We have problem in getting the SignalWriteEvent from the virtual socket
249 // server. So increasing the send buffer to 64k.
250 // TODO(mallinath) - Remove this setting after we fix vss issue.
251 vss_->set_send_buffer_capacity(64 * 1024);
252 unsigned char packet[65552];
253 packet[0] = 0x00;
254 packet[1] = 0x01;
255 packet[2] = 0xFF;
256 packet[3] = 0xFC;
257 EXPECT_TRUE(Send(packet, sizeof(packet)));
258}
259
260// Investigate why WriteEvent is not signaled from VSS.
261TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
262 vss_->set_send_buffer_capacity(1);
263 Send(kTurnChannelDataMessageWithOddLength,
264 sizeof(kTurnChannelDataMessageWithOddLength));
265 EXPECT_EQ(1u, recv_packets_.size());
266 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
267 sizeof(kTurnChannelDataMessageWithOddLength)));
268}
269
deadbeefb56671e2017-05-26 18:40:05 -0700270// Test that SignalSentPacket is fired when a packet is sent.
271TEST_F(AsyncStunTCPSocketTest, SignalSentPacketFiredWhenPacketSent) {
272 ASSERT_TRUE(
273 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
274 EXPECT_EQ(1, sent_packets_);
275 // Send another packet for good measure.
276 ASSERT_TRUE(
277 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
278 EXPECT_EQ(2, sent_packets_);
279}
280
281// Test that SignalSentPacket isn't fired when a packet isn't sent (for
282// example, because it's invalid).
283TEST_F(AsyncStunTCPSocketTest, SignalSentPacketNotFiredWhenPacketNotSent) {
284 // Attempt to send a packet that's too small; since it isn't sent,
285 // SignalSentPacket shouldn't fire.
286 char data[1];
287 ASSERT_FALSE(Send(data, sizeof(data)));
288 EXPECT_EQ(0, sent_packets_);
289}
290
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000291} // namespace cricket