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 virtual 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
) {
34 socket_host_
.reset(new P2PSocketHostTcp(
35 &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_
= 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_
;
69 net::IPEndPoint dest_
;
70 net::IPEndPoint dest2_
;
72 P2PSocketType socket_type_
;
75 class P2PSocketHostTcpTest
: public P2PSocketHostTcpTestBase
{
77 P2PSocketHostTcpTest() : P2PSocketHostTcpTestBase(P2P_SOCKET_TCP_CLIENT
) { }
80 class P2PSocketHostStunTcpTest
: public P2PSocketHostTcpTestBase
{
82 P2PSocketHostStunTcpTest()
83 : P2PSocketHostTcpTestBase(P2P_SOCKET_STUN_TCP_CLIENT
) {
87 // Verify that we can send STUN message and that they are formatted
89 TEST_F(P2PSocketHostTcpTest
, SendStunNoAuth
) {
90 EXPECT_CALL(sender_
, Send(
91 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
93 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
95 std::vector
<char> packet1
;
96 CreateStunRequest(&packet1
);
97 socket_host_
->Send(dest_
, packet1
, net::DSCP_NO_CHANGE
, 0);
99 std::vector
<char> packet2
;
100 CreateStunResponse(&packet2
);
101 socket_host_
->Send(dest_
, packet2
, net::DSCP_NO_CHANGE
, 0);
103 std::vector
<char> packet3
;
104 CreateStunError(&packet3
);
105 socket_host_
->Send(dest_
, packet3
, net::DSCP_NO_CHANGE
, 0);
107 std::string expected_data
;
108 expected_data
.append(IntToSize(packet1
.size()));
109 expected_data
.append(packet1
.begin(), packet1
.end());
110 expected_data
.append(IntToSize(packet2
.size()));
111 expected_data
.append(packet2
.begin(), packet2
.end());
112 expected_data
.append(IntToSize(packet3
.size()));
113 expected_data
.append(packet3
.begin(), packet3
.end());
115 EXPECT_EQ(expected_data
, sent_data_
);
118 // Verify that we can receive STUN messages from the socket, and that
119 // the messages are parsed properly.
120 TEST_F(P2PSocketHostTcpTest
, ReceiveStun
) {
121 EXPECT_CALL(sender_
, Send(
122 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
124 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
126 std::vector
<char> packet1
;
127 CreateStunRequest(&packet1
);
128 socket_host_
->Send(dest_
, packet1
, net::DSCP_NO_CHANGE
, 0);
130 std::vector
<char> packet2
;
131 CreateStunResponse(&packet2
);
132 socket_host_
->Send(dest_
, packet2
, net::DSCP_NO_CHANGE
, 0);
134 std::vector
<char> packet3
;
135 CreateStunError(&packet3
);
136 socket_host_
->Send(dest_
, packet3
, net::DSCP_NO_CHANGE
, 0);
138 std::string received_data
;
139 received_data
.append(IntToSize(packet1
.size()));
140 received_data
.append(packet1
.begin(), packet1
.end());
141 received_data
.append(IntToSize(packet2
.size()));
142 received_data
.append(packet2
.begin(), packet2
.end());
143 received_data
.append(IntToSize(packet3
.size()));
144 received_data
.append(packet3
.begin(), packet3
.end());
146 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet1
)))
147 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
148 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet2
)))
149 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
150 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet3
)))
151 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
154 size_t step_sizes
[] = {3, 2, 1};
156 while (pos
< received_data
.size()) {
157 size_t step_size
= std::min(step_sizes
[step
], received_data
.size() - pos
);
158 socket_
->AppendInputData(&received_data
[pos
], step_size
);
160 if (++step
>= arraysize(step_sizes
))
165 // Verify that we can't send data before we've received STUN response
166 // from the other side.
167 TEST_F(P2PSocketHostTcpTest
, SendDataNoAuth
) {
168 EXPECT_CALL(sender_
, Send(
169 MatchMessage(static_cast<uint32
>(P2PMsg_OnError::ID
))))
170 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
172 std::vector
<char> packet
;
173 CreateRandomPacket(&packet
);
174 socket_host_
->Send(dest_
, packet
, net::DSCP_NO_CHANGE
, 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 // Now we should be able to send any data to |dest_|.
198 std::vector
<char> packet
;
199 CreateRandomPacket(&packet
);
200 socket_host_
->Send(dest_
, packet
, net::DSCP_NO_CHANGE
, 0);
202 std::string expected_data
;
203 expected_data
.append(IntToSize(packet
.size()));
204 expected_data
.append(packet
.begin(), packet
.end());
206 EXPECT_EQ(expected_data
, sent_data_
);
209 // Verify that asynchronous writes are handled correctly.
210 TEST_F(P2PSocketHostTcpTest
, AsyncWrites
) {
211 base::MessageLoop message_loop
;
213 socket_
->set_async_write(true);
215 EXPECT_CALL(sender_
, Send(
216 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
218 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
220 std::vector
<char> packet1
;
221 CreateStunRequest(&packet1
);
223 socket_host_
->Send(dest_
, packet1
, net::DSCP_NO_CHANGE
, 0);
225 std::vector
<char> packet2
;
226 CreateStunResponse(&packet2
);
227 socket_host_
->Send(dest_
, packet2
, net::DSCP_NO_CHANGE
, 0);
229 message_loop
.RunUntilIdle();
231 std::string expected_data
;
232 expected_data
.append(IntToSize(packet1
.size()));
233 expected_data
.append(packet1
.begin(), packet1
.end());
234 expected_data
.append(IntToSize(packet2
.size()));
235 expected_data
.append(packet2
.begin(), packet2
.end());
237 EXPECT_EQ(expected_data
, sent_data_
);
240 // Verify that we can send STUN message and that they are formatted
242 TEST_F(P2PSocketHostStunTcpTest
, SendStunNoAuth
) {
243 EXPECT_CALL(sender_
, Send(
244 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
246 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
248 std::vector
<char> packet1
;
249 CreateStunRequest(&packet1
);
250 socket_host_
->Send(dest_
, packet1
, net::DSCP_NO_CHANGE
, 0);
252 std::vector
<char> packet2
;
253 CreateStunResponse(&packet2
);
254 socket_host_
->Send(dest_
, packet2
, net::DSCP_NO_CHANGE
, 0);
256 std::vector
<char> packet3
;
257 CreateStunError(&packet3
);
258 socket_host_
->Send(dest_
, packet3
, net::DSCP_NO_CHANGE
, 0);
260 std::string expected_data
;
261 expected_data
.append(packet1
.begin(), packet1
.end());
262 expected_data
.append(packet2
.begin(), packet2
.end());
263 expected_data
.append(packet3
.begin(), packet3
.end());
265 EXPECT_EQ(expected_data
, sent_data_
);
268 // Verify that we can receive STUN messages from the socket, and that
269 // the messages are parsed properly.
270 TEST_F(P2PSocketHostStunTcpTest
, ReceiveStun
) {
271 EXPECT_CALL(sender_
, Send(
272 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
274 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
276 std::vector
<char> packet1
;
277 CreateStunRequest(&packet1
);
278 socket_host_
->Send(dest_
, packet1
, net::DSCP_NO_CHANGE
, 0);
280 std::vector
<char> packet2
;
281 CreateStunResponse(&packet2
);
282 socket_host_
->Send(dest_
, packet2
, net::DSCP_NO_CHANGE
, 0);
284 std::vector
<char> packet3
;
285 CreateStunError(&packet3
);
286 socket_host_
->Send(dest_
, packet3
, net::DSCP_NO_CHANGE
, 0);
288 std::string received_data
;
289 received_data
.append(packet1
.begin(), packet1
.end());
290 received_data
.append(packet2
.begin(), packet2
.end());
291 received_data
.append(packet3
.begin(), packet3
.end());
293 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet1
)))
294 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
295 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet2
)))
296 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
297 EXPECT_CALL(sender_
, Send(MatchPacketMessage(packet3
)))
298 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
301 size_t step_sizes
[] = {3, 2, 1};
303 while (pos
< received_data
.size()) {
304 size_t step_size
= std::min(step_sizes
[step
], received_data
.size() - pos
);
305 socket_
->AppendInputData(&received_data
[pos
], step_size
);
307 if (++step
>= arraysize(step_sizes
))
312 // Verify that we can't send data before we've received STUN response
313 // from the other side.
314 TEST_F(P2PSocketHostStunTcpTest
, SendDataNoAuth
) {
315 EXPECT_CALL(sender_
, Send(
316 MatchMessage(static_cast<uint32
>(P2PMsg_OnError::ID
))))
317 .WillOnce(DoAll(DeleteArg
<0>(), Return(true)));
319 std::vector
<char> packet
;
320 CreateRandomPacket(&packet
);
321 socket_host_
->Send(dest_
, packet
, net::DSCP_NO_CHANGE
, 0);
323 EXPECT_EQ(0U, sent_data_
.size());
326 // Verify that asynchronous writes are handled correctly.
327 TEST_F(P2PSocketHostStunTcpTest
, AsyncWrites
) {
328 base::MessageLoop message_loop
;
330 socket_
->set_async_write(true);
332 EXPECT_CALL(sender_
, Send(
333 MatchMessage(static_cast<uint32
>(P2PMsg_OnSendComplete::ID
))))
335 .WillRepeatedly(DoAll(DeleteArg
<0>(), Return(true)));
337 std::vector
<char> packet1
;
338 CreateStunRequest(&packet1
);
339 socket_host_
->Send(dest_
, packet1
, net::DSCP_NO_CHANGE
,0);
341 std::vector
<char> packet2
;
342 CreateStunResponse(&packet2
);
343 socket_host_
->Send(dest_
, packet2
, net::DSCP_NO_CHANGE
, 0);
345 message_loop
.RunUntilIdle();
347 std::string expected_data
;
348 expected_data
.append(packet1
.begin(), packet1
.end());
349 expected_data
.append(packet2
.begin(), packet2
.end());
351 EXPECT_EQ(expected_data
, sent_data_
);
354 } // namespace content