1 /*
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
11 #include "p2p/base/async_stun_tcp_socket.h"
12
13 #include <stdint.h>
14 #include <string.h>
15
16 #include <list>
17 #include <memory>
18 #include <string>
19 #include <utility>
20
21 #include "absl/memory/memory.h"
22 #include "rtc_base/network/sent_packet.h"
23 #include "rtc_base/socket.h"
24 #include "rtc_base/third_party/sigslot/sigslot.h"
25 #include "rtc_base/thread.h"
26 #include "rtc_base/virtual_socket_server.h"
27 #include "test/gtest.h"
28
29 namespace cricket {
30
31 static unsigned char kStunMessageWithZeroLength[] = {
32 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes)
33 0x21, 0x12, 0xA4, 0x42, '0', '1', '2', '3',
34 '4', '5', '6', '7', '8', '9', 'a', 'b',
35 };
36
37 static unsigned char kTurnChannelDataMessageWithZeroLength[] = {
38 0x40, 0x00, 0x00, 0x00, // length of 0 (last 2 bytes)
39 };
40
41 static unsigned char kTurnChannelDataMessage[] = {
42 0x40, 0x00, 0x00, 0x10, 0x21, 0x12, 0xA4, 0x42, '0', '1',
43 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
44 };
45
46 static unsigned char kStunMessageWithInvalidLength[] = {
47 0x00, 0x01, 0x00, 0x10, 0x21, 0x12, 0xA4, 0x42, '0', '1',
48 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
49 };
50
51 static unsigned char kTurnChannelDataMessageWithInvalidLength[] = {
52 0x80, 0x00, 0x00, 0x20, 0x21, 0x12, 0xA4, 0x42, '0', '1',
53 '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
54 };
55
56 static unsigned char kTurnChannelDataMessageWithOddLength[] = {
57 0x40, 0x00, 0x00, 0x05, 0x21, 0x12, 0xA4, 0x42, '0',
58 };
59
60 static const rtc::SocketAddress kClientAddr("11.11.11.11", 0);
61 static const rtc::SocketAddress kServerAddr("22.22.22.22", 0);
62
63 class AsyncStunServerTCPSocket : public rtc::AsyncTcpListenSocket {
64 public:
AsyncStunServerTCPSocket(std::unique_ptr<rtc::Socket> socket)65 explicit AsyncStunServerTCPSocket(std::unique_ptr<rtc::Socket> socket)
66 : AsyncTcpListenSocket(std::move(socket)) {}
HandleIncomingConnection(rtc::Socket * socket)67 void HandleIncomingConnection(rtc::Socket* socket) override {
68 SignalNewConnection(this, new AsyncStunTCPSocket(socket));
69 }
70 };
71
72 class AsyncStunTCPSocketTest : public ::testing::Test,
73 public sigslot::has_slots<> {
74 protected:
AsyncStunTCPSocketTest()75 AsyncStunTCPSocketTest()
76 : vss_(new rtc::VirtualSocketServer()), thread_(vss_.get()) {}
77
SetUp()78 virtual void SetUp() { CreateSockets(); }
79
CreateSockets()80 void CreateSockets() {
81 std::unique_ptr<rtc::Socket> server =
82 absl::WrapUnique(vss_->CreateSocket(kServerAddr.family(), SOCK_STREAM));
83 server->Bind(kServerAddr);
84 listen_socket_ =
85 std::make_unique<AsyncStunServerTCPSocket>(std::move(server));
86 listen_socket_->SignalNewConnection.connect(
87 this, &AsyncStunTCPSocketTest::OnNewConnection);
88
89 rtc::Socket* client = vss_->CreateSocket(kClientAddr.family(), SOCK_STREAM);
90 send_socket_.reset(AsyncStunTCPSocket::Create(
91 client, kClientAddr, listen_socket_->GetLocalAddress()));
92 send_socket_->SignalSentPacket.connect(
93 this, &AsyncStunTCPSocketTest::OnSentPacket);
94 ASSERT_TRUE(send_socket_.get() != NULL);
95 vss_->ProcessMessagesUntilIdle();
96 }
97
OnReadPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t len,const rtc::SocketAddress & remote_addr,const int64_t &)98 void OnReadPacket(rtc::AsyncPacketSocket* socket,
99 const char* data,
100 size_t len,
101 const rtc::SocketAddress& remote_addr,
102 const int64_t& /* packet_time_us */) {
103 recv_packets_.push_back(std::string(data, len));
104 }
105
OnSentPacket(rtc::AsyncPacketSocket * socket,const rtc::SentPacket & packet)106 void OnSentPacket(rtc::AsyncPacketSocket* socket,
107 const rtc::SentPacket& packet) {
108 ++sent_packets_;
109 }
110
OnNewConnection(rtc::AsyncListenSocket *,rtc::AsyncPacketSocket * new_socket)111 void OnNewConnection(rtc::AsyncListenSocket* /*server*/,
112 rtc::AsyncPacketSocket* new_socket) {
113 recv_socket_ = absl::WrapUnique(new_socket);
114 new_socket->SignalReadPacket.connect(this,
115 &AsyncStunTCPSocketTest::OnReadPacket);
116 }
117
Send(const void * data,size_t len)118 bool Send(const void* data, size_t len) {
119 rtc::PacketOptions options;
120 int ret =
121 send_socket_->Send(reinterpret_cast<const char*>(data), len, options);
122 vss_->ProcessMessagesUntilIdle();
123 return (ret == static_cast<int>(len));
124 }
125
CheckData(const void * data,int len)126 bool CheckData(const void* data, int len) {
127 bool ret = false;
128 if (recv_packets_.size()) {
129 std::string packet = recv_packets_.front();
130 recv_packets_.pop_front();
131 ret = (memcmp(data, packet.c_str(), len) == 0);
132 }
133 return ret;
134 }
135
136 std::unique_ptr<rtc::VirtualSocketServer> vss_;
137 rtc::AutoSocketServerThread thread_;
138 std::unique_ptr<AsyncStunTCPSocket> send_socket_;
139 std::unique_ptr<rtc::AsyncListenSocket> listen_socket_;
140 std::unique_ptr<rtc::AsyncPacketSocket> recv_socket_;
141 std::list<std::string> recv_packets_;
142 int sent_packets_ = 0;
143 };
144
145 // Testing a stun packet sent/recv properly.
TEST_F(AsyncStunTCPSocketTest,TestSingleStunPacket)146 TEST_F(AsyncStunTCPSocketTest, TestSingleStunPacket) {
147 EXPECT_TRUE(
148 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
149 EXPECT_EQ(1u, recv_packets_.size());
150 EXPECT_TRUE(CheckData(kStunMessageWithZeroLength,
151 sizeof(kStunMessageWithZeroLength)));
152 }
153
154 // Verify sending multiple packets.
TEST_F(AsyncStunTCPSocketTest,TestMultipleStunPackets)155 TEST_F(AsyncStunTCPSocketTest, TestMultipleStunPackets) {
156 EXPECT_TRUE(
157 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
158 EXPECT_TRUE(
159 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
160 EXPECT_TRUE(
161 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
162 EXPECT_TRUE(
163 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
164 EXPECT_EQ(4u, recv_packets_.size());
165 }
166
167 // Verifying TURN channel data message with zero length.
TEST_F(AsyncStunTCPSocketTest,TestTurnChannelDataWithZeroLength)168 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithZeroLength) {
169 EXPECT_TRUE(Send(kTurnChannelDataMessageWithZeroLength,
170 sizeof(kTurnChannelDataMessageWithZeroLength)));
171 EXPECT_EQ(1u, recv_packets_.size());
172 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithZeroLength,
173 sizeof(kTurnChannelDataMessageWithZeroLength)));
174 }
175
176 // Verifying TURN channel data message.
TEST_F(AsyncStunTCPSocketTest,TestTurnChannelData)177 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelData) {
178 EXPECT_TRUE(Send(kTurnChannelDataMessage, sizeof(kTurnChannelDataMessage)));
179 EXPECT_EQ(1u, recv_packets_.size());
180 EXPECT_TRUE(
181 CheckData(kTurnChannelDataMessage, sizeof(kTurnChannelDataMessage)));
182 }
183
184 // Verifying TURN channel messages which needs padding handled properly.
TEST_F(AsyncStunTCPSocketTest,TestTurnChannelDataPadding)185 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataPadding) {
186 EXPECT_TRUE(Send(kTurnChannelDataMessageWithOddLength,
187 sizeof(kTurnChannelDataMessageWithOddLength)));
188 EXPECT_EQ(1u, recv_packets_.size());
189 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
190 sizeof(kTurnChannelDataMessageWithOddLength)));
191 }
192
193 // Verifying stun message with invalid length.
TEST_F(AsyncStunTCPSocketTest,TestStunInvalidLength)194 TEST_F(AsyncStunTCPSocketTest, TestStunInvalidLength) {
195 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
196 sizeof(kStunMessageWithInvalidLength)));
197 EXPECT_EQ(0u, recv_packets_.size());
198
199 // Modify the message length to larger value.
200 kStunMessageWithInvalidLength[2] = 0xFF;
201 kStunMessageWithInvalidLength[3] = 0xFF;
202 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
203 sizeof(kStunMessageWithInvalidLength)));
204
205 // Modify the message length to smaller value.
206 kStunMessageWithInvalidLength[2] = 0x00;
207 kStunMessageWithInvalidLength[3] = 0x01;
208 EXPECT_FALSE(Send(kStunMessageWithInvalidLength,
209 sizeof(kStunMessageWithInvalidLength)));
210 }
211
212 // Verifying TURN channel data message with invalid length.
TEST_F(AsyncStunTCPSocketTest,TestTurnChannelDataWithInvalidLength)213 TEST_F(AsyncStunTCPSocketTest, TestTurnChannelDataWithInvalidLength) {
214 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
215 sizeof(kTurnChannelDataMessageWithInvalidLength)));
216 // Modify the length to larger value.
217 kTurnChannelDataMessageWithInvalidLength[2] = 0xFF;
218 kTurnChannelDataMessageWithInvalidLength[3] = 0xF0;
219 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
220 sizeof(kTurnChannelDataMessageWithInvalidLength)));
221
222 // Modify the length to smaller value.
223 kTurnChannelDataMessageWithInvalidLength[2] = 0x00;
224 kTurnChannelDataMessageWithInvalidLength[3] = 0x00;
225 EXPECT_FALSE(Send(kTurnChannelDataMessageWithInvalidLength,
226 sizeof(kTurnChannelDataMessageWithInvalidLength)));
227 }
228
229 // Verifying a small buffer handled (dropped) properly. This will be
230 // a common one for both stun and turn.
TEST_F(AsyncStunTCPSocketTest,TestTooSmallMessageBuffer)231 TEST_F(AsyncStunTCPSocketTest, TestTooSmallMessageBuffer) {
232 char data[1];
233 EXPECT_FALSE(Send(data, sizeof(data)));
234 }
235
236 // Verifying a legal large turn message.
TEST_F(AsyncStunTCPSocketTest,TestMaximumSizeTurnPacket)237 TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeTurnPacket) {
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.
TEST_F(AsyncStunTCPSocketTest,TestMaximumSizeStunPacket)247 TEST_F(AsyncStunTCPSocketTest, TestMaximumSizeStunPacket) {
248 unsigned char packet[65552];
249 packet[0] = 0x00;
250 packet[1] = 0x01;
251 packet[2] = 0xFF;
252 packet[3] = 0xFC;
253 EXPECT_TRUE(Send(packet, sizeof(packet)));
254 }
255
256 // Test that a turn message is sent completely even if it exceeds the socket
257 // send buffer capacity.
TEST_F(AsyncStunTCPSocketTest,TestWithSmallSendBuffer)258 TEST_F(AsyncStunTCPSocketTest, TestWithSmallSendBuffer) {
259 vss_->set_send_buffer_capacity(1);
260 Send(kTurnChannelDataMessageWithOddLength,
261 sizeof(kTurnChannelDataMessageWithOddLength));
262 EXPECT_EQ(1u, recv_packets_.size());
263 EXPECT_TRUE(CheckData(kTurnChannelDataMessageWithOddLength,
264 sizeof(kTurnChannelDataMessageWithOddLength)));
265 }
266
267 // Test that SignalSentPacket is fired when a packet is sent.
TEST_F(AsyncStunTCPSocketTest,SignalSentPacketFiredWhenPacketSent)268 TEST_F(AsyncStunTCPSocketTest, SignalSentPacketFiredWhenPacketSent) {
269 ASSERT_TRUE(
270 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
271 EXPECT_EQ(1, sent_packets_);
272 // Send another packet for good measure.
273 ASSERT_TRUE(
274 Send(kStunMessageWithZeroLength, sizeof(kStunMessageWithZeroLength)));
275 EXPECT_EQ(2, sent_packets_);
276 }
277
278 // Test that SignalSentPacket isn't fired when a packet isn't sent (for
279 // example, because it's invalid).
TEST_F(AsyncStunTCPSocketTest,SignalSentPacketNotFiredWhenPacketNotSent)280 TEST_F(AsyncStunTCPSocketTest, SignalSentPacketNotFiredWhenPacketNotSent) {
281 // Attempt to send a packet that's too small; since it isn't sent,
282 // SignalSentPacket shouldn't fire.
283 char data[1];
284 ASSERT_FALSE(Send(data, sizeof(data)));
285 EXPECT_EQ(0, sent_packets_);
286 }
287
288 } // namespace cricket
289