3
* Copyright 2004, Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
8
* 1. Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
13
* 3. The name of the author may not be used to endorse or promote products
14
* derived from this software without specific prior written permission.
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
#include "talk/base/gunit.h"
31
#include "talk/base/host.h"
32
#include "talk/base/logging.h"
33
#include "talk/base/natserver.h"
34
#include "talk/base/natsocketfactory.h"
35
#include "talk/base/network.h"
36
#include "talk/base/physicalsocketserver.h"
37
#include "talk/base/testclient.h"
38
#include "talk/base/virtualsocketserver.h"
40
using namespace talk_base;
43
TestClient* client, bool should_receive, const char* buf, size_t size) {
44
return (should_receive) ?
45
client->CheckNextPacket(buf, size, 0) :
46
client->CheckNoPacket();
49
TestClient* CreateTestClient(
50
SocketFactory* factory, const SocketAddress& local_addr) {
51
AsyncUDPSocket* socket = AsyncUDPSocket::Create(factory, local_addr);
52
return new TestClient(socket);
55
// Tests that when sending from internal_addr to external_addrs through the
56
// NAT type specified by nat_type, all external addrs receive the sent packet
57
// and, if exp_same is true, all use the same mapped-address on the NAT.
59
SocketServer* internal, const SocketAddress& internal_addr,
60
SocketServer* external, const SocketAddress external_addrs[4],
61
NATType nat_type, bool exp_same) {
62
Thread th_int(internal);
63
Thread th_ext(external);
65
SocketAddress server_addr = internal_addr;
66
server_addr.SetPort(0); // Auto-select a port
67
NATServer* nat = new NATServer(
68
nat_type, internal, server_addr, external, external_addrs[0]);
69
NATSocketFactory* natsf = new NATSocketFactory(internal,
70
nat->internal_address());
72
TestClient* in = CreateTestClient(natsf, internal_addr);
74
for (int i = 0; i < 4; i++)
75
out[i] = CreateTestClient(external, external_addrs[i]);
80
const char* buf = "filter_test";
81
size_t len = strlen(buf);
83
in->SendTo(buf, len, out[0]->address());
84
SocketAddress trans_addr;
85
EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
87
for (int i = 1; i < 4; i++) {
88
in->SendTo(buf, len, out[i]->address());
89
SocketAddress trans_addr2;
90
EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2));
91
bool are_same = (trans_addr == trans_addr2);
92
ASSERT_EQ(are_same, exp_same) << "same translated address";
101
for (int i = 0; i < 4; i++)
105
// Tests that when sending from external_addrs to internal_addr, the packet
106
// is delivered according to the specified filter_ip and filter_port rules.
108
SocketServer* internal, const SocketAddress& internal_addr,
109
SocketServer* external, const SocketAddress external_addrs[4],
110
NATType nat_type, bool filter_ip, bool filter_port) {
111
Thread th_int(internal);
112
Thread th_ext(external);
114
SocketAddress server_addr = internal_addr;
115
server_addr.SetPort(0); // Auto-select a port
116
NATServer* nat = new NATServer(
117
nat_type, internal, server_addr, external, external_addrs[0]);
118
NATSocketFactory* natsf = new NATSocketFactory(internal,
119
nat->internal_address());
121
TestClient* in = CreateTestClient(natsf, internal_addr);
123
for (int i = 0; i < 4; i++)
124
out[i] = CreateTestClient(external, external_addrs[i]);
129
const char* buf = "filter_test";
130
size_t len = strlen(buf);
132
in->SendTo(buf, len, out[0]->address());
133
SocketAddress trans_addr;
134
EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
136
out[1]->SendTo(buf, len, trans_addr);
137
EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len));
139
out[2]->SendTo(buf, len, trans_addr);
140
EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len));
142
out[3]->SendTo(buf, len, trans_addr);
143
EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len));
151
for (int i = 0; i < 4; i++)
155
// Tests that NATServer allocates bindings properly.
157
SocketServer* internal, const SocketAddress& internal_addr,
158
SocketServer* external, const SocketAddress external_addrs[4]) {
159
TestSend(internal, internal_addr, external, external_addrs,
160
NAT_OPEN_CONE, true);
161
TestSend(internal, internal_addr, external, external_addrs,
162
NAT_ADDR_RESTRICTED, true);
163
TestSend(internal, internal_addr, external, external_addrs,
164
NAT_PORT_RESTRICTED, true);
165
TestSend(internal, internal_addr, external, external_addrs,
166
NAT_SYMMETRIC, false);
169
// Tests that NATServer filters packets properly.
171
SocketServer* internal, const SocketAddress& internal_addr,
172
SocketServer* external, const SocketAddress external_addrs[4]) {
173
TestRecv(internal, internal_addr, external, external_addrs,
174
NAT_OPEN_CONE, false, false);
175
TestRecv(internal, internal_addr, external, external_addrs,
176
NAT_ADDR_RESTRICTED, true, false);
177
TestRecv(internal, internal_addr, external, external_addrs,
178
NAT_PORT_RESTRICTED, true, true);
179
TestRecv(internal, internal_addr, external, external_addrs,
180
NAT_SYMMETRIC, true, true);
183
TEST(NatTest, TestPhysical) {
184
BasicNetworkManager network_manager;
185
network_manager.StartUpdating();
186
// Process pending messages so the network list is updated.
187
Thread::Current()->ProcessMessages(0);
189
std::vector<Network*> networks;
190
network_manager.GetNetworks(&networks);
191
if (networks.empty()) {
192
LOG(LS_WARNING) << "Not enough network adapters for test.";
196
SocketAddress int_addr("127.0.0.1", 0);
197
std::string ext_ip1 = "127.0.0.1";
198
std::string ext_ip2 = networks[0]->ip().ToString();
200
LOG(LS_INFO) << "selected ip " << ext_ip2;
202
SocketAddress ext_addrs[4] = {
203
SocketAddress(ext_ip1, 0),
204
SocketAddress(ext_ip2, 0),
205
SocketAddress(ext_ip1, 0),
206
SocketAddress(ext_ip2, 0)
209
PhysicalSocketServer* int_pss = new PhysicalSocketServer();
210
PhysicalSocketServer* ext_pss = new PhysicalSocketServer();
212
TestBindings(int_pss, int_addr, ext_pss, ext_addrs);
213
TestFilters(int_pss, int_addr, ext_pss, ext_addrs);
216
class TestVirtualSocketServer : public VirtualSocketServer {
218
explicit TestVirtualSocketServer(SocketServer* ss)
219
: VirtualSocketServer(ss) {}
220
// Expose this publicly
221
IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); }
224
TEST(NatTest, TestVirtual) {
225
TestVirtualSocketServer* int_vss = new TestVirtualSocketServer(
226
new PhysicalSocketServer());
227
TestVirtualSocketServer* ext_vss = new TestVirtualSocketServer(
228
new PhysicalSocketServer());
230
// TODO: IPv6ize this test when the NAT stuff is v6ed.
231
SocketAddress int_addr, ext_addrs[4];
232
int_addr.SetIP(int_vss->GetNextIP(int_addr.ipaddr().family()));
233
ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.ipaddr().family()));
234
ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.ipaddr().family()));
235
ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
236
ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
238
TestBindings(int_vss, int_addr, ext_vss, ext_addrs);
239
TestFilters(int_vss, int_addr, ext_vss, ext_addrs);
243
// TODO: Finish this test
244
class NatTcpTest : public testing::Test, public sigslot::has_slots<> {
246
NatTcpTest() : connected_(false) {}
247
virtual void SetUp() {
248
int_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
249
ext_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
250
nat_ = new NATServer(NAT_OPEN_CONE, int_vss_, SocketAddress(),
251
ext_vss_, SocketAddress());
252
natsf_ = new NATSocketFactory(int_vss_, nat_->internal_address());
254
void OnConnectEvent(AsyncSocket* socket) {
257
void OnAcceptEvent(AsyncSocket* socket) {
258
accepted_ = server_->Accept(NULL);
260
void OnCloseEvent(AsyncSocket* socket, int error) {
262
void ConnectEvents() {
263
server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
264
client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
266
TestVirtualSocketServer* int_vss_;
267
TestVirtualSocketServer* ext_vss_;
269
NATSocketFactory* natsf_;
270
AsyncSocket* client_;
271
AsyncSocket* server_;
272
AsyncSocket* accepted_;
276
TEST_F(NatTcpTest, DISABLED_TestConnectOut) {
277
server_ = ext_vss_->CreateAsyncSocket(SOCK_STREAM);
278
server_->Bind(SocketAddress());
281
client_ = int_vss_->CreateAsyncSocket(SOCK_STREAM);
282
EXPECT_GE(0, client_->Bind(SocketAddress()));
283
EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
288
EXPECT_TRUE_WAIT(connected_, 1000);
289
EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
290
EXPECT_EQ(client_->GetRemoteAddress(), accepted_->GetLocalAddress());
291
EXPECT_EQ(client_->GetLocalAddress(), accepted_->GetRemoteAddress());