Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / base / nat_unittest.cc
1 /*
2  *  Copyright 2004 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
11 #include <string>
12
13 #include "webrtc/base/gunit.h"
14 #include "webrtc/base/logging.h"
15 #include "webrtc/base/natserver.h"
16 #include "webrtc/base/natsocketfactory.h"
17 #include "webrtc/base/nethelpers.h"
18 #include "webrtc/base/network.h"
19 #include "webrtc/base/physicalsocketserver.h"
20 #include "webrtc/base/testclient.h"
21 #include "webrtc/base/virtualsocketserver.h"
22 #include "webrtc/test/testsupport/gtest_disable.h"
23
24 using namespace rtc;
25
26 bool CheckReceive(
27     TestClient* client, bool should_receive, const char* buf, size_t size) {
28   return (should_receive) ?
29       client->CheckNextPacket(buf, size, 0) :
30       client->CheckNoPacket();
31 }
32
33 TestClient* CreateTestClient(
34       SocketFactory* factory, const SocketAddress& local_addr) {
35   AsyncUDPSocket* socket = AsyncUDPSocket::Create(factory, local_addr);
36   return new TestClient(socket);
37 }
38
39 // Tests that when sending from internal_addr to external_addrs through the
40 // NAT type specified by nat_type, all external addrs receive the sent packet
41 // and, if exp_same is true, all use the same mapped-address on the NAT.
42 void TestSend(
43       SocketServer* internal, const SocketAddress& internal_addr,
44       SocketServer* external, const SocketAddress external_addrs[4],
45       NATType nat_type, bool exp_same) {
46   Thread th_int(internal);
47   Thread th_ext(external);
48
49   SocketAddress server_addr = internal_addr;
50   server_addr.SetPort(0);  // Auto-select a port
51   NATServer* nat = new NATServer(
52       nat_type, internal, server_addr, external, external_addrs[0]);
53   NATSocketFactory* natsf = new NATSocketFactory(internal,
54                                                  nat->internal_address());
55
56   TestClient* in = CreateTestClient(natsf, internal_addr);
57   TestClient* out[4];
58   for (int i = 0; i < 4; i++)
59     out[i] = CreateTestClient(external, external_addrs[i]);
60
61   th_int.Start();
62   th_ext.Start();
63
64   const char* buf = "filter_test";
65   size_t len = strlen(buf);
66
67   in->SendTo(buf, len, out[0]->address());
68   SocketAddress trans_addr;
69   EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
70
71   for (int i = 1; i < 4; i++) {
72     in->SendTo(buf, len, out[i]->address());
73     SocketAddress trans_addr2;
74     EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2));
75     bool are_same = (trans_addr == trans_addr2);
76     ASSERT_EQ(are_same, exp_same) << "same translated address";
77     ASSERT_NE(AF_UNSPEC, trans_addr.family());
78     ASSERT_NE(AF_UNSPEC, trans_addr2.family());
79   }
80
81   th_int.Stop();
82   th_ext.Stop();
83
84   delete nat;
85   delete natsf;
86   delete in;
87   for (int i = 0; i < 4; i++)
88     delete out[i];
89 }
90
91 // Tests that when sending from external_addrs to internal_addr, the packet
92 // is delivered according to the specified filter_ip and filter_port rules.
93 void TestRecv(
94       SocketServer* internal, const SocketAddress& internal_addr,
95       SocketServer* external, const SocketAddress external_addrs[4],
96       NATType nat_type, bool filter_ip, bool filter_port) {
97   Thread th_int(internal);
98   Thread th_ext(external);
99
100   SocketAddress server_addr = internal_addr;
101   server_addr.SetPort(0);  // Auto-select a port
102   NATServer* nat = new NATServer(
103       nat_type, internal, server_addr, external, external_addrs[0]);
104   NATSocketFactory* natsf = new NATSocketFactory(internal,
105                                                  nat->internal_address());
106
107   TestClient* in = CreateTestClient(natsf, internal_addr);
108   TestClient* out[4];
109   for (int i = 0; i < 4; i++)
110     out[i] = CreateTestClient(external, external_addrs[i]);
111
112   th_int.Start();
113   th_ext.Start();
114
115   const char* buf = "filter_test";
116   size_t len = strlen(buf);
117
118   in->SendTo(buf, len, out[0]->address());
119   SocketAddress trans_addr;
120   EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
121
122   out[1]->SendTo(buf, len, trans_addr);
123   EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len));
124
125   out[2]->SendTo(buf, len, trans_addr);
126   EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len));
127
128   out[3]->SendTo(buf, len, trans_addr);
129   EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len));
130
131   th_int.Stop();
132   th_ext.Stop();
133
134   delete nat;
135   delete natsf;
136   delete in;
137   for (int i = 0; i < 4; i++)
138     delete out[i];
139 }
140
141 // Tests that NATServer allocates bindings properly.
142 void TestBindings(
143     SocketServer* internal, const SocketAddress& internal_addr,
144     SocketServer* external, const SocketAddress external_addrs[4]) {
145   TestSend(internal, internal_addr, external, external_addrs,
146            NAT_OPEN_CONE, true);
147   TestSend(internal, internal_addr, external, external_addrs,
148            NAT_ADDR_RESTRICTED, true);
149   TestSend(internal, internal_addr, external, external_addrs,
150            NAT_PORT_RESTRICTED, true);
151   TestSend(internal, internal_addr, external, external_addrs,
152            NAT_SYMMETRIC, false);
153 }
154
155 // Tests that NATServer filters packets properly.
156 void TestFilters(
157     SocketServer* internal, const SocketAddress& internal_addr,
158     SocketServer* external, const SocketAddress external_addrs[4]) {
159   TestRecv(internal, internal_addr, external, external_addrs,
160            NAT_OPEN_CONE, false, false);
161   TestRecv(internal, internal_addr, external, external_addrs,
162            NAT_ADDR_RESTRICTED, true, false);
163   TestRecv(internal, internal_addr, external, external_addrs,
164            NAT_PORT_RESTRICTED, true, true);
165   TestRecv(internal, internal_addr, external, external_addrs,
166            NAT_SYMMETRIC, true, true);
167 }
168
169 bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) {
170   // The physical NAT tests require connectivity to the selected ip from the
171   // internal address used for the NAT. Things like firewalls can break that, so
172   // check to see if it's worth even trying with this ip.
173   scoped_ptr<PhysicalSocketServer> pss(new PhysicalSocketServer());
174   scoped_ptr<AsyncSocket> client(pss->CreateAsyncSocket(src.family(),
175                                                         SOCK_DGRAM));
176   scoped_ptr<AsyncSocket> server(pss->CreateAsyncSocket(src.family(),
177                                                         SOCK_DGRAM));
178   if (client->Bind(SocketAddress(src.ipaddr(), 0)) != 0 ||
179       server->Bind(SocketAddress(dst, 0)) != 0) {
180     return false;
181   }
182   const char* buf = "hello other socket";
183   size_t len = strlen(buf);
184   int sent = client->SendTo(buf, len, server->GetLocalAddress());
185   SocketAddress addr;
186   const size_t kRecvBufSize = 64;
187   char recvbuf[kRecvBufSize];
188   Thread::Current()->SleepMs(100);
189   int received = server->RecvFrom(recvbuf, kRecvBufSize, &addr);
190   return received == sent && ::memcmp(buf, recvbuf, len) == 0;
191 }
192
193 void TestPhysicalInternal(const SocketAddress& int_addr) {
194   BasicNetworkManager network_manager;
195   network_manager.set_ipv6_enabled(true);
196   network_manager.StartUpdating();
197   // Process pending messages so the network list is updated.
198   Thread::Current()->ProcessMessages(0);
199
200   std::vector<Network*> networks;
201   network_manager.GetNetworks(&networks);
202   if (networks.empty()) {
203     LOG(LS_WARNING) << "Not enough network adapters for test.";
204     return;
205   }
206
207   SocketAddress ext_addr1(int_addr);
208   SocketAddress ext_addr2;
209   // Find an available IP with matching family. The test breaks if int_addr
210   // can't talk to ip, so check for connectivity as well.
211   for (std::vector<Network*>::iterator it = networks.begin();
212       it != networks.end(); ++it) {
213     const IPAddress& ip = (*it)->GetBestIP();
214     if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) {
215       ext_addr2.SetIP(ip);
216       break;
217     }
218   }
219   if (ext_addr2.IsNil()) {
220     LOG(LS_WARNING) << "No available IP of same family as " << int_addr;
221     return;
222   }
223
224   LOG(LS_INFO) << "selected ip " << ext_addr2.ipaddr();
225
226   SocketAddress ext_addrs[4] = {
227       SocketAddress(ext_addr1),
228       SocketAddress(ext_addr2),
229       SocketAddress(ext_addr1),
230       SocketAddress(ext_addr2)
231   };
232
233   scoped_ptr<PhysicalSocketServer> int_pss(new PhysicalSocketServer());
234   scoped_ptr<PhysicalSocketServer> ext_pss(new PhysicalSocketServer());
235
236   TestBindings(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
237   TestFilters(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
238 }
239
240 TEST(NatTest, DISABLED_ON_MAC(TestPhysicalIPv4)) {
241   TestPhysicalInternal(SocketAddress("127.0.0.1", 0));
242 }
243
244 TEST(NatTest, DISABLED_ON_MAC(TestPhysicalIPv6)) {
245   if (HasIPv6Enabled()) {
246     TestPhysicalInternal(SocketAddress("::1", 0));
247   } else {
248     LOG(LS_WARNING) << "No IPv6, skipping";
249   }
250 }
251
252 class TestVirtualSocketServer : public VirtualSocketServer {
253  public:
254   explicit TestVirtualSocketServer(SocketServer* ss)
255       : VirtualSocketServer(ss),
256         ss_(ss) {}
257   // Expose this publicly
258   IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); }
259
260  private:
261   scoped_ptr<SocketServer> ss_;
262 };
263
264 void TestVirtualInternal(int family) {
265   scoped_ptr<TestVirtualSocketServer> int_vss(new TestVirtualSocketServer(
266       new PhysicalSocketServer()));
267   scoped_ptr<TestVirtualSocketServer> ext_vss(new TestVirtualSocketServer(
268       new PhysicalSocketServer()));
269
270   SocketAddress int_addr;
271   SocketAddress ext_addrs[4];
272   int_addr.SetIP(int_vss->GetNextIP(family));
273   ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.family()));
274   ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.family()));
275   ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
276   ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
277
278   TestBindings(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
279   TestFilters(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
280 }
281
282 TEST(NatTest, DISABLED_ON_MAC(TestVirtualIPv4)) {
283   TestVirtualInternal(AF_INET);
284 }
285
286 TEST(NatTest, DISABLED_ON_MAC(TestVirtualIPv6)) {
287   if (HasIPv6Enabled()) {
288     TestVirtualInternal(AF_INET6);
289   } else {
290     LOG(LS_WARNING) << "No IPv6, skipping";
291   }
292 }
293
294 // TODO: Finish this test
295 class NatTcpTest : public testing::Test, public sigslot::has_slots<> {
296  public:
297   NatTcpTest() : connected_(false) {}
298   virtual void SetUp() {
299     int_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
300     ext_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
301     nat_ = new NATServer(NAT_OPEN_CONE, int_vss_, SocketAddress(),
302                          ext_vss_, SocketAddress());
303     natsf_ = new NATSocketFactory(int_vss_, nat_->internal_address());
304   }
305   void OnConnectEvent(AsyncSocket* socket) {
306     connected_ = true;
307   }
308   void OnAcceptEvent(AsyncSocket* socket) {
309     accepted_ = server_->Accept(NULL);
310   }
311   void OnCloseEvent(AsyncSocket* socket, int error) {
312   }
313   void ConnectEvents() {
314     server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
315     client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
316   }
317   TestVirtualSocketServer* int_vss_;
318   TestVirtualSocketServer* ext_vss_;
319   NATServer* nat_;
320   NATSocketFactory* natsf_;
321   AsyncSocket* client_;
322   AsyncSocket* server_;
323   AsyncSocket* accepted_;
324   bool connected_;
325 };
326
327 TEST_F(NatTcpTest, DISABLED_TestConnectOut) {
328   server_ = ext_vss_->CreateAsyncSocket(SOCK_STREAM);
329   server_->Bind(SocketAddress());
330   server_->Listen(5);
331
332   client_ = int_vss_->CreateAsyncSocket(SOCK_STREAM);
333   EXPECT_GE(0, client_->Bind(SocketAddress()));
334   EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
335
336
337   ConnectEvents();
338
339   EXPECT_TRUE_WAIT(connected_, 1000);
340   EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
341   EXPECT_EQ(client_->GetRemoteAddress(), accepted_->GetLocalAddress());
342   EXPECT_EQ(client_->GetLocalAddress(), accepted_->GetRemoteAddress());
343
344   client_->Close();
345 }
346 //#endif