15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/p2p/socket_host_tcp_server.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <list> 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/p2p/socket_host_tcp.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/p2p/socket_host_test_utils.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DeleteArg; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DoAll; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FakeServerSocket : public net::ServerSocket { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FakeServerSocket() 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : listening_(false), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_socket_(NULL) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~FakeServerSocket() {} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool listening() { return listening_; } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddIncoming(net::StreamSocket* socket) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!accept_callback_.is_null()) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(incoming_sockets_.empty()); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_socket_->reset(socket); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_socket_ = NULL; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This copy is necessary because this implementation of ServerSocket 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bases logic on the null-ness of |accept_callback_| in the bound 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback cb = accept_callback_; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_callback_.Reset(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cb.Run(net::OK); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming_sockets_.push_back(socket); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Listen(const net::IPEndPoint& address, int backlog) OVERRIDE { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_address_ = address; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listening_ = true; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *address = local_address_; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Accept(scoped_ptr<net::StreamSocket>* socket, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) OVERRIDE { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(socket); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!incoming_sockets_.empty()) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket->reset(incoming_sockets_.front()); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming_sockets_.pop_front(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::OK; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_socket_ = socket; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accept_callback_ = callback; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool listening_; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPEndPoint local_address_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::StreamSocket>* accept_socket_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback accept_callback_; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<net::StreamSocket*> incoming_sockets_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class P2PSocketHostTcpServerTest : public testing::Test { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = new FakeServerSocket(); 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) socket_host_.reset( 9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new P2PSocketHostTcpServer(&sender_, 0, P2P_SOCKET_TCP_CLIENT)); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_host_->socket_.reset(socket_); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(sender_, Send( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID)))) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) P2PHostAndIPEndPoint dest; 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dest.ip_address = ParseAddress(kTestIpAddress1, kTestPort1); 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_host_->Init(ParseAddress(kTestLocalIpAddress, 0), 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dest); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(socket_->listening()); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Needed by the chilt classes because only this class is a friend 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of P2PSocketHostTcp. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::StreamSocket* GetSocketFormTcpSocketHost(P2PSocketHostTcp* host) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return host->socket_.get(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockIPCSender sender_; 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FakeServerSocket* socket_; // Owned by |socket_host_|. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<P2PSocketHostTcpServer> socket_host_; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accept incoming connection. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpServerTest, Accept) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FakeSocket* incoming = new FakeSocket(NULL); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1)); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPEndPoint addr = ParseAddress(kTestIpAddress1, kTestPort1); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming->SetPeerAddress(addr); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr))) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_->AddIncoming(incoming); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kAcceptedSocketId = 1; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<P2PSocketHost> new_host( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_host_->AcceptIncomingTcpConnection(addr, kAcceptedSocketId)); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(new_host.get() != NULL); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(incoming, GetSocketFormTcpSocketHost( 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<P2PSocketHostTcp*>(new_host.get()))); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accept 2 simultaneous connections. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(P2PSocketHostTcpServerTest, Accept2) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FakeSocket* incoming1 = new FakeSocket(NULL); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming1->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPEndPoint addr1 = ParseAddress(kTestIpAddress1, kTestPort1); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming1->SetPeerAddress(addr1); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FakeSocket* incoming2 = new FakeSocket(NULL); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming2->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1)); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPEndPoint addr2 = ParseAddress(kTestIpAddress2, kTestPort2); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incoming2->SetPeerAddress(addr2); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr1))) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr2))) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_->AddIncoming(incoming1); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_->AddIncoming(incoming2); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kAcceptedSocketId1 = 1; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kAcceptedSocketId2 = 2; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<P2PSocketHost> new_host1( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_host_->AcceptIncomingTcpConnection(addr1, kAcceptedSocketId1)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(new_host1.get() != NULL); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(incoming1, GetSocketFormTcpSocketHost( 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<P2PSocketHostTcp*>(new_host1.get()))); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<P2PSocketHost> new_host2( 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_host_->AcceptIncomingTcpConnection(addr2, kAcceptedSocketId2)); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(new_host2.get() != NULL); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(incoming2, GetSocketFormTcpSocketHost( 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<P2PSocketHostTcp*>(new_host2.get()))); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 175