1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/p2p/socket_host_tcp.h"
9 #include "base/sys_byteorder.h"
10 #include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
11 #include "net/socket/stream_socket.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
16 using ::testing::DeleteArg
;
17 using ::testing::DoAll
;
18 using ::testing::Return
;
22 class P2PSocketHostTcpTestBase
: public testing::Test
{
24 explicit P2PSocketHostTcpTestBase(P2PSocketType type
)
25 : socket_type_(type
) {
28 void SetUp() override
{
29 EXPECT_CALL(sender_
, Send(
30 MatchMessage(static_cast<uint32
>(P2PMsg_OnSocketCreated::ID
))))
31 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
33 if (socket_type_
== P2P_SOCKET_TCP_CLIENT
) {
35 new P2PSocketHostTcp(&sender_
, 0, P2P_SOCKET_TCP_CLIENT
, NULL
));
37 socket_host_
.reset(new P2PSocketHostStunTcp(
38 &sender_
, 0, P2P_SOCKET_STUN_TCP_CLIENT
, NULL
));
41 socket_
= new FakeSocket(&sent_data_
);
42 socket_
->SetLocalAddress(ParseAddress(kTestLocalIpAddress
, kTestPort1
));
43 socket_host_
->socket_
.reset(socket_
);
45 dest_
.ip_address
= ParseAddress(kTestIpAddress1
, kTestPort1
);
47 local_address_
= ParseAddress(kTestLocalIpAddress
, kTestPort1
);
49 socket_host_
->remote_address_
= dest_
;
50 socket_host_
->state_
= P2PSocketHost::STATE_CONNECTING
;
51 socket_host_
->OnConnected(net::OK
);
54 std::string
IntToSize(int size
) {
56 uint16 size16
= base::HostToNet16(size
);
57 result
.resize(sizeof(size16
));
58 memcpy(&result
[0], &size16
, sizeof(size16
));
62 std::string sent_data_
;
63 FakeSocket
* socket_
; // Owned by |socket_host_|.
64 scoped_ptr
<P2PSocketHostTcpBase
> socket_host_
;
65 MockIPCSender sender_
;
67 net::IPEndPoint local_address_
;
68 P2PHostAndIPEndPoint dest_
;
69 P2PSocketType socket_type_
;
72 class P2PSocketHostTcpTest
: public P2PSocketHostTcpTestBase
{
74 P2PSocketHostTcpTest() : P2PSocketHostTcpTestBase(P2P_SOCKET_TCP_CLIENT
) { }
77 class P2PSocketHostStunTcpTest
: public P2PSocketHostTcpTestBase
{
79 P2PSocketHostStunTcpTest()
80 : P2PSocketHostTcpTestBase(P2P_SOCKET_STUN_TCP_CLIENT
) {
84 // Verify that we can send STUN message and that they are formatted
86 TEST_F(P2PSocketHostTcpTest
, SendStunNoAuth
) {
87 EXPECT_CALL(sender_
, Send(
88 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
90 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
92 rtc::PacketOptions options
;
93 std::vector
<char> packet1
;
94 CreateStunRequest(&packet1
);
95 socket_host_
->Send(dest_
.ip_address
, packet1
, options
, 0);
97 std::vector
<char> packet2
;
98 CreateStunResponse(&packet2
);
99 socket_host_
->Send(dest_
.ip_address
, packet2
, options
, 0);
101 std::vector
<char> packet3
;
102 CreateStunError(&packet3
);
103 socket_host_
->Send(dest_
.ip_address
, packet3
, options
, 0);
105 std::string expected_data
;
106 expected_data
.append(IntToSize(packet1
.size()));
107 expected_data
.append(packet1
.begin(), packet1
.end());
108 expected_data
.append(IntToSize(packet2
.size()));
109 expected_data
.append(packet2
.begin(), packet2
.end());
110 expected_data
.append(IntToSize(packet3
.size()));
111 expected_data
.append(packet3
.begin(), packet3
.end());
113 EXPECT_EQ(expected_data
, sent_data_
);
116 // Verify that we can receive STUN messages from the socket, and that
117 // the messages are parsed properly.
118 TEST_F(P2PSocketHostTcpTest
, ReceiveStun
) {
119 EXPECT_CALL(sender_
, Send(
120 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
122 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
124 rtc::PacketOptions options
;
125 std::vector
<char> packet1
;
126 CreateStunRequest(&packet1
);
127 socket_host_
->Send(dest_
.ip_address
, packet1
, options
, 0);
129 std::vector
<char> packet2
;
130 CreateStunResponse(&packet2
);
131 socket_host_
->Send(dest_
.ip_address
, packet2
, options
, 0);
133 std::vector
<char> packet3
;
134 CreateStunError(&packet3
);
135 socket_host_
->Send(dest_
.ip_address
, packet3
, options
, 0);
137 std::string received_data
;
138 received_data
.append(IntToSize(packet1
.size()));
139 received_data
.append(packet1
.begin(), packet1
.end());
140 received_data
.append(IntToSize(packet2
.size()));
141 received_data
.append(packet2
.begin(), packet2
.end());
142 received_data
.append(IntToSize(packet3
.size()));
143 received_data
.append(packet3
.begin(), packet3
.end());
145 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet1
)))
146 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
147 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet2
)))
148 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
149 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet3
)))
150 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
153 size_t step_sizes
[] = {3, 2, 1};
155 while (pos
< received_data
.size()) {
156 size_t step_size
= std::min(step_sizes
[step
], received_data
.size() - pos
);
157 socket_
->AppendInputData(&received_data
[pos
], step_size
);
159 if (++step
>= arraysize(step_sizes
))
164 // Verify that we can't send data before we've received STUN response
165 // from the other side.
166 TEST_F(P2PSocketHostTcpTest
, SendDataNoAuth
) {
167 EXPECT_CALL(sender_
, Send(
168 MatchMessage(static_cast<uint32
>(P2PMsg_OnError::ID
))))
169 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
171 rtc::PacketOptions options
;
172 std::vector
<char> packet
;
173 CreateRandomPacket(&packet
);
174 socket_host_
->Send(dest_
.ip_address
, packet
, options
, 0);
176 EXPECT_EQ(0U, sent_data_
.size());
179 // Verify that we can send data after we've received STUN response
180 // from the other side.
181 TEST_F(P2PSocketHostTcpTest
, SendAfterStunRequest
) {
182 // Receive packet from |dest_|.
183 std::vector
<char> request_packet
;
184 CreateStunRequest(&request_packet
);
186 std::string received_data
;
187 received_data
.append(IntToSize(request_packet
.size()));
188 received_data
.append(request_packet
.begin(), request_packet
.end());
190 EXPECT_CALL(sender_
, Send(
191 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
192 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
193 EXPECT_CALL(sender_
, Send(MatchPacketMessage(request_packet
)))
194 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
195 socket_
->AppendInputData(&received_data
[0], received_data
.size());
197 rtc::PacketOptions options
;
198 // Now we should be able to send any data to |dest_|.
199 std::vector
<char> packet
;
200 CreateRandomPacket(&packet
);
201 socket_host_
->Send(dest_
.ip_address
, packet
, options
, 0);
203 std::string expected_data
;
204 expected_data
.append(IntToSize(packet
.size()));
205 expected_data
.append(packet
.begin(), packet
.end());
207 EXPECT_EQ(expected_data
, sent_data_
);
210 // Verify that asynchronous writes are handled correctly.
211 TEST_F(P2PSocketHostTcpTest
, AsyncWrites
) {
212 base::MessageLoop message_loop
;
214 socket_
->set_async_write(true);
216 EXPECT_CALL(sender_
, Send(
217 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
219 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
221 rtc::PacketOptions options
;
222 std::vector
<char> packet1
;
223 CreateStunRequest(&packet1
);
225 socket_host_
->Send(dest_
.ip_address
, packet1
, options
, 0);
227 std::vector
<char> packet2
;
228 CreateStunResponse(&packet2
);
229 socket_host_
->Send(dest_
.ip_address
, packet2
, options
, 0);
231 message_loop
.RunUntilIdle();
233 std::string expected_data
;
234 expected_data
.append(IntToSize(packet1
.size()));
235 expected_data
.append(packet1
.begin(), packet1
.end());
236 expected_data
.append(IntToSize(packet2
.size()));
237 expected_data
.append(packet2
.begin(), packet2
.end());
239 EXPECT_EQ(expected_data
, sent_data_
);
242 TEST_F(P2PSocketHostTcpTest
, SendDataWithPacketOptions
) {
243 std::vector
<char> request_packet
;
244 CreateStunRequest(&request_packet
);
246 std::string received_data
;
247 received_data
.append(IntToSize(request_packet
.size()));
248 received_data
.append(request_packet
.begin(), request_packet
.end());
250 EXPECT_CALL(sender_
, Send(
251 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
252 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
253 EXPECT_CALL(sender_
, Send(MatchPacketMessage(request_packet
)))
254 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
255 socket_
->AppendInputData(&received_data
[0], received_data
.size());
257 rtc::PacketOptions options
;
258 options
.packet_time_params
.rtp_sendtime_extension_id
= 3;
259 // Now we should be able to send any data to |dest_|.
260 std::vector
<char> packet
;
261 CreateRandomPacket(&packet
);
262 // Make it a RTP packet.
263 *reinterpret_cast<uint16
*>(&*packet
.begin()) = base::HostToNet16(0x8000);
264 socket_host_
->Send(dest_
.ip_address
, packet
, options
, 0);
266 std::string expected_data
;
267 expected_data
.append(IntToSize(packet
.size()));
268 expected_data
.append(packet
.begin(), packet
.end());
270 EXPECT_EQ(expected_data
, sent_data_
);
273 // Verify that we can send STUN message and that they are formatted
275 TEST_F(P2PSocketHostStunTcpTest
, SendStunNoAuth
) {
276 EXPECT_CALL(sender_
, Send(
277 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
279 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
281 rtc::PacketOptions options
;
282 std::vector
<char> packet1
;
283 CreateStunRequest(&packet1
);
284 socket_host_
->Send(dest_
.ip_address
, packet1
, options
, 0);
286 std::vector
<char> packet2
;
287 CreateStunResponse(&packet2
);
288 socket_host_
->Send(dest_
.ip_address
, packet2
, options
, 0);
290 std::vector
<char> packet3
;
291 CreateStunError(&packet3
);
292 socket_host_
->Send(dest_
.ip_address
, packet3
, options
, 0);
294 std::string expected_data
;
295 expected_data
.append(packet1
.begin(), packet1
.end());
296 expected_data
.append(packet2
.begin(), packet2
.end());
297 expected_data
.append(packet3
.begin(), packet3
.end());
299 EXPECT_EQ(expected_data
, sent_data_
);
302 // Verify that we can receive STUN messages from the socket, and that
303 // the messages are parsed properly.
304 TEST_F(P2PSocketHostStunTcpTest
, ReceiveStun
) {
305 EXPECT_CALL(sender_
, Send(
306 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
308 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
310 rtc::PacketOptions options
;
311 std::vector
<char> packet1
;
312 CreateStunRequest(&packet1
);
313 socket_host_
->Send(dest_
.ip_address
, packet1
, options
, 0);
315 std::vector
<char> packet2
;
316 CreateStunResponse(&packet2
);
317 socket_host_
->Send(dest_
.ip_address
, packet2
, options
, 0);
319 std::vector
<char> packet3
;
320 CreateStunError(&packet3
);
321 socket_host_
->Send(dest_
.ip_address
, packet3
, options
, 0);
323 std::string received_data
;
324 received_data
.append(packet1
.begin(), packet1
.end());
325 received_data
.append(packet2
.begin(), packet2
.end());
326 received_data
.append(packet3
.begin(), packet3
.end());
328 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet1
)))
329 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
330 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet2
)))
331 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
332 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet3
)))
333 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
336 size_t step_sizes
[] = {3, 2, 1};
338 while (pos
< received_data
.size()) {
339 size_t step_size
= std::min(step_sizes
[step
], received_data
.size() - pos
);
340 socket_
->AppendInputData(&received_data
[pos
], step_size
);
342 if (++step
>= arraysize(step_sizes
))
347 // Verify that we can't send data before we've received STUN response
348 // from the other side.
349 TEST_F(P2PSocketHostStunTcpTest
, SendDataNoAuth
) {
350 EXPECT_CALL(sender_
, Send(
351 MatchMessage(static_cast<uint32
>(P2PMsg_OnError::ID
))))
352 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
354 rtc::PacketOptions options
;
355 std::vector
<char> packet
;
356 CreateRandomPacket(&packet
);
357 socket_host_
->Send(dest_
.ip_address
, packet
, options
, 0);
359 EXPECT_EQ(0U, sent_data_
.size());
362 // Verify that asynchronous writes are handled correctly.
363 TEST_F(P2PSocketHostStunTcpTest
, AsyncWrites
) {
364 base::MessageLoop message_loop
;
366 socket_
->set_async_write(true);
368 EXPECT_CALL(sender_
, Send(
369 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
371 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
373 rtc::PacketOptions options
;
374 std::vector
<char> packet1
;
375 CreateStunRequest(&packet1
);
376 socket_host_
->Send(dest_
.ip_address
, packet1
, options
, 0);
378 std::vector
<char> packet2
;
379 CreateStunResponse(&packet2
);
380 socket_host_
->Send(dest_
.ip_address
, packet2
, options
, 0);
382 message_loop
.RunUntilIdle();
384 std::string expected_data
;
385 expected_data
.append(packet1
.begin(), packet1
.end());
386 expected_data
.append(packet2
.begin(), packet2
.end());
388 EXPECT_EQ(expected_data
, sent_data_
);
391 } // namespace content