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