blob: cc3f9adbd85b7602624ea1e648dd0399fe6c89a3 [file] [log] [blame]
tommi5ce1a2a2016-05-14 03:19:31 -07001/*
2 * Copyright 2016 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
kwibergfd8be342016-05-14 19:44:11 -070011#include <memory>
12
Henrik Kjellandera80c16a2017-07-01 16:48:15 +020013#include "webrtc/base/gunit.h"
14#include "webrtc/base/thread.h"
15#include "webrtc/base/virtualsocketserver.h"
tommi5ce1a2a2016-05-14 03:19:31 -070016#include "webrtc/p2p/base/basicpacketsocketfactory.h"
17#include "webrtc/p2p/base/tcpport.h"
18
19using rtc::SocketAddress;
20using cricket::Connection;
21using cricket::Port;
22using cricket::TCPPort;
23using cricket::ICE_UFRAG_LENGTH;
24using cricket::ICE_PWD_LENGTH;
25
26static int kTimeout = 1000;
27static const SocketAddress kLocalAddr("11.11.11.11", 1);
28static const SocketAddress kRemoteAddr("22.22.22.22", 2);
29
30class TCPPortTest : public testing::Test, public sigslot::has_slots<> {
31 public:
32 TCPPortTest()
deadbeef98e186c2017-05-16 18:00:06 -070033 : ss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -070034 main_(ss_.get()),
tommi5ce1a2a2016-05-14 03:19:31 -070035 network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
36 socket_factory_(rtc::Thread::Current()),
37 username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
38 password_(rtc::CreateRandomString(ICE_PWD_LENGTH)) {
39 network_.AddIP(rtc::IPAddress(INADDR_ANY));
40 }
41
42 void ConnectSignalSocketCreated() {
43 ss_->SignalSocketCreated.connect(this, &TCPPortTest::OnSocketCreated);
44 }
45
46 void OnSocketCreated(rtc::VirtualSocket* socket) {
47 LOG(LS_INFO) << "socket created ";
48 socket->SignalAddressReady.connect(
49 this, &TCPPortTest::SetLocalhostAsAlternativeLocalAddress);
50 }
51
52 void SetLocalhostAsAlternativeLocalAddress(rtc::VirtualSocket* socket,
53 const SocketAddress& address) {
54 SocketAddress local_address("127.0.0.1", 2000);
55 socket->SetAlternativeLocalAddress(local_address);
56 }
57
58 TCPPort* CreateTCPPort(const SocketAddress& addr) {
nisse7eaa4ea2017-05-08 05:25:41 -070059 return TCPPort::Create(&main_, &socket_factory_, &network_, addr.ipaddr(),
60 0, 0, username_, password_, true);
tommi5ce1a2a2016-05-14 03:19:31 -070061 }
62
63 protected:
kwibergfd8be342016-05-14 19:44:11 -070064 std::unique_ptr<rtc::VirtualSocketServer> ss_;
nisse7eaa4ea2017-05-08 05:25:41 -070065 rtc::AutoSocketServerThread main_;
tommi5ce1a2a2016-05-14 03:19:31 -070066 rtc::Network network_;
67 rtc::BasicPacketSocketFactory socket_factory_;
68 std::string username_;
69 std::string password_;
70};
71
72TEST_F(TCPPortTest, TestTCPPortWithLocalhostAddress) {
kwibergfd8be342016-05-14 19:44:11 -070073 std::unique_ptr<TCPPort> lport(CreateTCPPort(kLocalAddr));
74 std::unique_ptr<TCPPort> rport(CreateTCPPort(kRemoteAddr));
tommi5ce1a2a2016-05-14 03:19:31 -070075 lport->PrepareAddress();
76 rport->PrepareAddress();
77 // Start to listen to new socket creation event.
78 ConnectSignalSocketCreated();
79 Connection* conn =
80 lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE);
81 EXPECT_TRUE_WAIT(conn->connected(), kTimeout);
82}
deadbeef06878292017-04-21 14:22:23 -070083
84class SentPacketCounter : public sigslot::has_slots<> {
85 public:
86 SentPacketCounter(TCPPort* p) {
87 p->SignalSentPacket.connect(this, &SentPacketCounter::OnSentPacket);
88 }
89
90 int sent_packets() const { return sent_packets_; }
91
92 private:
93 void OnSentPacket(const rtc::SentPacket&) { ++sent_packets_; }
94
95 int sent_packets_ = 0;
96};
97
98// Test that SignalSentPacket is fired when a packet is successfully sent, for
99// both TCP client and server sockets.
100TEST_F(TCPPortTest, SignalSentPacket) {
101 std::unique_ptr<TCPPort> client(CreateTCPPort(kLocalAddr));
102 std::unique_ptr<TCPPort> server(CreateTCPPort(kRemoteAddr));
103 client->SetIceRole(cricket::ICEROLE_CONTROLLING);
104 server->SetIceRole(cricket::ICEROLE_CONTROLLED);
105 client->PrepareAddress();
106 server->PrepareAddress();
107
108 Connection* client_conn =
109 client->CreateConnection(server->Candidates()[0], Port::ORIGIN_MESSAGE);
110 ASSERT_NE(nullptr, client_conn);
111 ASSERT_TRUE_WAIT(client_conn->connected(), kTimeout);
112
113 // Need to get the port of the actual outgoing socket, not the server socket..
114 cricket::Candidate client_candidate = client->Candidates()[0];
115 client_candidate.set_address(static_cast<cricket::TCPConnection*>(client_conn)
116 ->socket()
117 ->GetLocalAddress());
118 Connection* server_conn =
119 server->CreateConnection(client_candidate, Port::ORIGIN_THIS_PORT);
120 ASSERT_NE(nullptr, server_conn);
121 ASSERT_TRUE_WAIT(server_conn->connected(), kTimeout);
122
123 client_conn->Ping(rtc::TimeMillis());
124 server_conn->Ping(rtc::TimeMillis());
125 ASSERT_TRUE_WAIT(client_conn->writable(), kTimeout);
126 ASSERT_TRUE_WAIT(server_conn->writable(), kTimeout);
127
128 SentPacketCounter client_counter(client.get());
129 SentPacketCounter server_counter(server.get());
130 static const char kData[] = "hello";
131 for (int i = 0; i < 10; ++i) {
132 client_conn->Send(&kData, sizeof(kData), rtc::PacketOptions());
133 server_conn->Send(&kData, sizeof(kData), rtc::PacketOptions());
134 }
135 EXPECT_EQ_WAIT(10, client_counter.sent_packets(), kTimeout);
136 EXPECT_EQ_WAIT(10, server_counter.sent_packets(), kTimeout);
137}