xref: /aosp_15_r20/external/webrtc/p2p/base/async_stun_tcp_socket_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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