blob: 6c026f67668cc79d3f798af5490b26a0696b0400 [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
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013#include "webrtc/p2p/base/asyncstuntcpsocket.h"
14#include "webrtc/base/asyncsocket.h"
15#include "webrtc/base/gunit.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000016#include "webrtc/base/virtualsocketserver.h"
17
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()));
89 ASSERT_TRUE(send_socket_.get() != NULL);
90 vss_->ProcessMessagesUntilIdle();
91 }
92
93 void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
94 size_t len, const rtc::SocketAddress& remote_addr,
95 const rtc::PacketTime& packet_time) {
96 recv_packets_.push_back(std::string(data, len));
97 }
98
99 void OnNewConnection(rtc::AsyncPacketSocket* server,
100 rtc::AsyncPacketSocket* new_socket) {
101 listen_socket_.reset(new_socket);
102 new_socket->SignalReadPacket.connect(
103 this, &AsyncStunTCPSocketTest::OnReadPacket);
104 }
105
106 bool Send(const void* data, size_t len) {
107 rtc::PacketOptions options;
108 size_t ret = send_socket_->Send(
109 reinterpret_cast<const char*>(data), len, options);
110 vss_->ProcessMessagesUntilIdle();
111 return (ret == len);
112 }
113
114 bool CheckData(const void* data, int len) {
115 bool ret = false;
116 if (recv_packets_.size()) {
117 std::string packet = recv_packets_.front();
118 recv_packets_.pop_front();
119 ret = (memcmp(data, packet.c_str(), len) == 0);
120 }
121 return ret;
122 }
123
kwiberg3ec46792016-04-27 07:22:53 -0700124 std::unique_ptr<rtc::VirtualSocketServer> vss_;
nisse7eaa4ea2017-05-08 05:25:41 -0700125 rtc::AutoSocketServerThread thread_;
kwiberg3ec46792016-04-27 07:22:53 -0700126 std::unique_ptr<AsyncStunTCPSocket> send_socket_;
127 std::unique_ptr<AsyncStunTCPSocket> recv_socket_;
128 std::unique_ptr<rtc::AsyncPacketSocket> listen_socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000129 std::list<std::string> recv_packets_;
130};
131
132// Testing a stun packet sent/recv properly.
133TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
134 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
135 sizeof(kStunMessageWithZeroLength)));
136 EXPECT_EQ(1u, recv_packets_.size());
137 EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
138 sizeof(kStunMessageWithZeroLength)));
139}
140
141// Verify sending multiple packets.
142TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
143 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
144 sizeof(kStunMessageWithZeroLength)));
145 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
146 sizeof(kStunMessageWithZeroLength)));
147 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
148 sizeof(kStunMessageWithZeroLength)));
149 EXPECT_TRUE(Send(kStunMessageWithZeroLength,
150 sizeof(kStunMessageWithZeroLength)));
151 EXPECT_EQ(4u, recv_packets_.size());
152}
153
154// Verifying TURN channel data message with zero length.
155TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
156 EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
157 sizeof(kTurnChannelDataMessageWithZeroLength)));
158 EXPECT_EQ(1u, recv_packets_.size());
159 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
160 sizeof(kTurnChannelDataMessageWithZeroLength)));
161}
162
163// Verifying TURN channel data message.
164TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
165 EXPECT_TRUE(Send(kTurnChannelDataMessage,
166 sizeof(kTurnChannelDataMessage)));
167 EXPECT_EQ(1u, recv_packets_.size());
168 EXPECT_TRUE(CheckData(kTurnChannelDataMessage,
169 sizeof(kTurnChannelDataMessage)));
170}
171
172// Verifying TURN channel messages which needs padding handled properly.
173TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
174 EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
175 sizeof(kTurnChannelDataMessageWithOddLength)));
176 EXPECT_EQ(1u, recv_packets_.size());
177 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
178 sizeof(kTurnChannelDataMessageWithOddLength)));
179}
180
181// Verifying stun message with invalid length.
182TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
183 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
184 sizeof(kStunMessageWithInvalidLength)));
185 EXPECT_EQ(0u, recv_packets_.size());
186
187 // Modify the message length to larger value.
188 kStunMessageWithInvalidLength[2] = 0xFF;
189 kStunMessageWithInvalidLength[3] = 0xFF;
190 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
191 sizeof(kStunMessageWithInvalidLength)));
192
193 // Modify the message length to smaller value.
194 kStunMessageWithInvalidLength[2] = 0x00;
195 kStunMessageWithInvalidLength[3] = 0x01;
196 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
197 sizeof(kStunMessageWithInvalidLength)));
198}
199
200// Verifying TURN channel data message with invalid length.
201TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
202 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
203 sizeof(kTurnChannelDataMessageWithInvalidLength)));
204 // Modify the length to larger value.
205 kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
206 kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
207 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
208 sizeof(kTurnChannelDataMessageWithInvalidLength)));
209
210 // Modify the length to smaller value.
211 kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
212 kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
213 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
214 sizeof(kTurnChannelDataMessageWithInvalidLength)));
215}
216
217// Verifying a small buffer handled (dropped) properly. This will be
218// a common one for both stun and turn.
219TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
220 char data[1];
221 EXPECT_FALSE(Send(data, sizeof(data)));
222}
223
224// Verifying a legal large turn message.
225TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
226 // We have problem in getting the SignalWriteEvent from the virtual socket
227 // server. So increasing the send buffer to 64k.
228 // TODO(mallinath) - Remove this setting after we fix vss issue.
229 vss_->set_send_buffer_capacity(64 * 1024);
230 unsigned char packet[65539];
231 packet[0] = 0x40;
232 packet[1] = 0x00;
233 packet[2] = 0xFF;
234 packet[3] = 0xFF;
235 EXPECT_TRUE(Send(packet, sizeof(packet)));
236}
237
238// Verifying a legal large stun message.
239TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
240 // We have problem in getting the SignalWriteEvent from the virtual socket
241 // server. So increasing the send buffer to 64k.
242 // TODO(mallinath) - Remove this setting after we fix vss issue.
243 vss_->set_send_buffer_capacity(64 * 1024);
244 unsigned char packet[65552];
245 packet[0] = 0x00;
246 packet[1] = 0x01;
247 packet[2] = 0xFF;
248 packet[3] = 0xFC;
249 EXPECT_TRUE(Send(packet, sizeof(packet)));
250}
251
252// Investigate why WriteEvent is not signaled from VSS.
253TEST_F(AsyncStunTCPSocketTest, DISABLED_TestWithSmallSendBuffer) {
254 vss_->set_send_buffer_capacity(1);
255 Send(kTurnChannelDataMessageWithOddLength,
256 sizeof(kTurnChannelDataMessageWithOddLength));
257 EXPECT_EQ(1u, recv_packets_.size());
258 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
259 sizeof(kTurnChannelDataMessageWithOddLength)));
260}
261
262} // namespace cricket