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