1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 // Original author: bcampen@mozilla.com
8 
9 extern "C" {
10 #include "stun_msg.h"  // for NR_STUN_MAX_MESSAGE_SIZE
11 #include "stun_util.h"
12 #include "nr_api.h"
13 #include "async_wait.h"
14 #include "nr_socket.h"
15 #include "nr_socket_local.h"
16 #include "stun_hint.h"
17 #include "local_addr.h"
18 #include "registry.h"
19 }
20 
21 #include "test_nr_socket.h"
22 
23 #include "nsCOMPtr.h"
24 #include "nsNetCID.h"
25 #include "nsServiceManagerUtils.h"
26 #include "runnable_utils.h"
27 
28 #include <vector>
29 
30 #define GTEST_HAS_RTTI 0
31 #include "gtest/gtest.h"
32 #include "gtest_utils.h"
33 
34 #define DATA_BUF_SIZE 1024
35 
36 namespace mozilla {
37 
38 class TestNrSocketTest : public MtransportTest {
39  public:
TestNrSocketTest()40   TestNrSocketTest()
41       : MtransportTest(),
42         wait_done_for_main_(false),
43         sts_(),
44         public_addrs_(),
45         private_addrs_(),
46         nats_() {}
47 
SetUp()48   void SetUp() override {
49     MtransportTest::SetUp();
50 
51     // Get the transport service as a dispatch target
52     nsresult rv;
53     sts_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
54     EXPECT_TRUE(NS_SUCCEEDED(rv)) << "Failed to get STS: " << (int)rv;
55   }
56 
TearDown()57   void TearDown() override {
58     sts_->Dispatch(WrapRunnable(this, &TestNrSocketTest::TearDown_s),
59                    NS_DISPATCH_SYNC);
60 
61     MtransportTest::TearDown();
62   }
63 
TearDown_s()64   void TearDown_s() {
65     public_addrs_.clear();
66     private_addrs_.clear();
67     nats_.clear();
68     sts_ = nullptr;
69   }
70 
CreateTestNrSocket_s(const char * ip_str,int proto,TestNat * nat)71   RefPtr<TestNrSocket> CreateTestNrSocket_s(const char* ip_str, int proto,
72                                             TestNat* nat) {
73     // If no nat is supplied, we create a default NAT which is disabled. This
74     // is how we simulate a non-natted socket.
75     RefPtr<TestNrSocket> sock(new TestNrSocket(nat ? nat : new TestNat));
76     nr_transport_addr address;
77     nr_str_port_to_transport_addr(ip_str, 0, proto, &address);
78     int r = sock->create(&address);
79     if (r) {
80       return nullptr;
81     }
82     return sock;
83   }
84 
CreatePublicAddrs(size_t count,const char * ip_str="127.0.0.1",int proto=IPPROTO_UDP)85   void CreatePublicAddrs(size_t count, const char* ip_str = "127.0.0.1",
86                          int proto = IPPROTO_UDP) {
87     sts_->Dispatch(WrapRunnable(this, &TestNrSocketTest::CreatePublicAddrs_s,
88                                 count, ip_str, proto),
89                    NS_DISPATCH_SYNC);
90   }
91 
CreatePublicAddrs_s(size_t count,const char * ip_str,int proto)92   void CreatePublicAddrs_s(size_t count, const char* ip_str, int proto) {
93     while (count--) {
94       auto sock = CreateTestNrSocket_s(ip_str, proto, nullptr);
95       ASSERT_TRUE(sock)
96       << "Failed to create socket";
97       public_addrs_.push_back(sock);
98     }
99   }
100 
CreatePrivateAddrs(size_t size,const char * ip_str="127.0.0.1",int proto=IPPROTO_UDP)101   RefPtr<TestNat> CreatePrivateAddrs(size_t size,
102                                      const char* ip_str = "127.0.0.1",
103                                      int proto = IPPROTO_UDP) {
104     RefPtr<TestNat> result;
105     sts_->Dispatch(
106         WrapRunnableRet(&result, this, &TestNrSocketTest::CreatePrivateAddrs_s,
107                         size, ip_str, proto),
108         NS_DISPATCH_SYNC);
109     return result;
110   }
111 
CreatePrivateAddrs_s(size_t count,const char * ip_str,int proto)112   RefPtr<TestNat> CreatePrivateAddrs_s(size_t count, const char* ip_str,
113                                        int proto) {
114     RefPtr<TestNat> nat(new TestNat);
115     while (count--) {
116       auto sock = CreateTestNrSocket_s(ip_str, proto, nat);
117       if (!sock) {
118         EXPECT_TRUE(false) << "Failed to create socket";
119         break;
120       }
121       private_addrs_.push_back(sock);
122     }
123     nat->enabled_ = true;
124     nats_.push_back(nat);
125     return nat;
126   }
127 
CheckConnectivityVia(TestNrSocket * from,TestNrSocket * to,const nr_transport_addr & via,nr_transport_addr * sender_external_address=nullptr)128   bool CheckConnectivityVia(
129       TestNrSocket* from, TestNrSocket* to, const nr_transport_addr& via,
130       nr_transport_addr* sender_external_address = nullptr) {
131     MOZ_ASSERT(from);
132 
133     if (!WaitForWriteable(from)) {
134       return false;
135     }
136 
137     int result = 0;
138     sts_->Dispatch(WrapRunnableRet(&result, this, &TestNrSocketTest::SendData_s,
139                                    from, via),
140                    NS_DISPATCH_SYNC);
141     if (result) {
142       return false;
143     }
144 
145     if (!WaitForReadable(to)) {
146       return false;
147     }
148 
149     nr_transport_addr dummy_outparam;
150     if (!sender_external_address) {
151       sender_external_address = &dummy_outparam;
152     }
153 
154     MOZ_ASSERT(to);
155     sts_->Dispatch(WrapRunnableRet(&result, this, &TestNrSocketTest::RecvData_s,
156                                    to, sender_external_address),
157                    NS_DISPATCH_SYNC);
158 
159     return !result;
160   }
161 
CheckConnectivity(TestNrSocket * from,TestNrSocket * to,nr_transport_addr * sender_external_address=nullptr)162   bool CheckConnectivity(TestNrSocket* from, TestNrSocket* to,
163                          nr_transport_addr* sender_external_address = nullptr) {
164     nr_transport_addr destination_address;
165     int r = GetAddress(to, &destination_address);
166     if (r) {
167       return false;
168     }
169 
170     return CheckConnectivityVia(from, to, destination_address,
171                                 sender_external_address);
172   }
173 
CheckTcpConnectivity(TestNrSocket * from,TestNrSocket * to)174   bool CheckTcpConnectivity(TestNrSocket* from, TestNrSocket* to) {
175     NrSocketBase* accepted_sock;
176     if (!Connect(from, to, &accepted_sock)) {
177       std::cerr << "Connect failed" << std::endl;
178       return false;
179     }
180 
181     // write on |from|, recv on |accepted_sock|
182     if (!WaitForWriteable(from)) {
183       std::cerr << __LINE__ << "WaitForWriteable (1) failed" << std::endl;
184       return false;
185     }
186 
187     int r;
188     sts_->Dispatch(
189         WrapRunnableRet(&r, this, &TestNrSocketTest::SendDataTcp_s, from),
190         NS_DISPATCH_SYNC);
191     if (r) {
192       std::cerr << "SendDataTcp_s (1) failed" << std::endl;
193       return false;
194     }
195 
196     if (!WaitForReadable(accepted_sock)) {
197       std::cerr << __LINE__ << "WaitForReadable (1) failed" << std::endl;
198       return false;
199     }
200 
201     sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::RecvDataTcp_s,
202                                    accepted_sock),
203                    NS_DISPATCH_SYNC);
204     if (r) {
205       std::cerr << "RecvDataTcp_s (1) failed" << std::endl;
206       return false;
207     }
208 
209     if (!WaitForWriteable(accepted_sock)) {
210       std::cerr << __LINE__ << "WaitForWriteable (2) failed" << std::endl;
211       return false;
212     }
213 
214     sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::SendDataTcp_s,
215                                    accepted_sock),
216                    NS_DISPATCH_SYNC);
217     if (r) {
218       std::cerr << "SendDataTcp_s (2) failed" << std::endl;
219       return false;
220     }
221 
222     if (!WaitForReadable(from)) {
223       std::cerr << __LINE__ << "WaitForReadable (2) failed" << std::endl;
224       return false;
225     }
226 
227     sts_->Dispatch(
228         WrapRunnableRet(&r, this, &TestNrSocketTest::RecvDataTcp_s, from),
229         NS_DISPATCH_SYNC);
230     if (r) {
231       std::cerr << "RecvDataTcp_s (2) failed" << std::endl;
232       return false;
233     }
234 
235     return true;
236   }
237 
GetAddress(TestNrSocket * sock,nr_transport_addr_ * address)238   int GetAddress(TestNrSocket* sock, nr_transport_addr_* address) {
239     MOZ_ASSERT(sock);
240     MOZ_ASSERT(address);
241     int r;
242     sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::GetAddress_s,
243                                    sock, address),
244                    NS_DISPATCH_SYNC);
245     return r;
246   }
247 
GetAddress_s(TestNrSocket * sock,nr_transport_addr * address)248   int GetAddress_s(TestNrSocket* sock, nr_transport_addr* address) {
249     return sock->getaddr(address);
250   }
251 
SendData_s(TestNrSocket * from,const nr_transport_addr & to)252   int SendData_s(TestNrSocket* from, const nr_transport_addr& to) {
253     // It is up to caller to ensure that |from| is writeable.
254     const char buf[] = "foobajooba";
255     return from->sendto(buf, sizeof(buf), 0, &to);
256   }
257 
SendDataTcp_s(NrSocketBase * from)258   int SendDataTcp_s(NrSocketBase* from) {
259     // It is up to caller to ensure that |from| is writeable.
260     const char buf[] = "foobajooba";
261     size_t written;
262     return from->write(buf, sizeof(buf), &written);
263   }
264 
RecvData_s(TestNrSocket * to,nr_transport_addr * from)265   int RecvData_s(TestNrSocket* to, nr_transport_addr* from) {
266     // It is up to caller to ensure that |to| is readable
267     char buf[DATA_BUF_SIZE];
268     size_t len;
269     // Maybe check that data matches?
270     int r = to->recvfrom(buf, sizeof(buf), &len, 0, from);
271     if (!r && (len == 0)) {
272       r = R_INTERNAL;
273     }
274     return r;
275   }
276 
RecvDataTcp_s(NrSocketBase * to)277   int RecvDataTcp_s(NrSocketBase* to) {
278     // It is up to caller to ensure that |to| is readable
279     char buf[DATA_BUF_SIZE];
280     size_t len;
281     // Maybe check that data matches?
282     int r = to->read(buf, sizeof(buf), &len);
283     if (!r && (len == 0)) {
284       r = R_INTERNAL;
285     }
286     return r;
287   }
288 
Listen_s(TestNrSocket * to)289   int Listen_s(TestNrSocket* to) {
290     // listen on |to|
291     int r = to->listen(1);
292     if (r) {
293       return r;
294     }
295     return 0;
296   }
297 
Connect_s(TestNrSocket * from,TestNrSocket * to)298   int Connect_s(TestNrSocket* from, TestNrSocket* to) {
299     // connect on |from|
300     nr_transport_addr destination_address;
301     int r = to->getaddr(&destination_address);
302     if (r) {
303       return r;
304     }
305 
306     r = from->connect(&destination_address);
307     if (r) {
308       return r;
309     }
310 
311     return 0;
312   }
313 
Accept_s(TestNrSocket * to,NrSocketBase ** accepted_sock)314   int Accept_s(TestNrSocket* to, NrSocketBase** accepted_sock) {
315     nr_socket* sock;
316     nr_transport_addr source_address;
317     int r = to->accept(&source_address, &sock);
318     if (r) {
319       return r;
320     }
321 
322     *accepted_sock = reinterpret_cast<NrSocketBase*>(sock->obj);
323     return 0;
324   }
325 
Connect(TestNrSocket * from,TestNrSocket * to,NrSocketBase ** accepted_sock)326   bool Connect(TestNrSocket* from, TestNrSocket* to,
327                NrSocketBase** accepted_sock) {
328     int r;
329     sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::Listen_s, to),
330                    NS_DISPATCH_SYNC);
331     if (r) {
332       std::cerr << "Listen_s failed: " << r << std::endl;
333       return false;
334     }
335 
336     sts_->Dispatch(
337         WrapRunnableRet(&r, this, &TestNrSocketTest::Connect_s, from, to),
338         NS_DISPATCH_SYNC);
339     if (r && r != R_WOULDBLOCK) {
340       std::cerr << "Connect_s failed: " << r << std::endl;
341       return false;
342     }
343 
344     if (!WaitForReadable(to)) {
345       std::cerr << "WaitForReadable failed" << std::endl;
346       return false;
347     }
348 
349     sts_->Dispatch(WrapRunnableRet(&r, this, &TestNrSocketTest::Accept_s, to,
350                                    accepted_sock),
351                    NS_DISPATCH_SYNC);
352 
353     if (r) {
354       std::cerr << "Accept_s failed: " << r << std::endl;
355       return false;
356     }
357     return true;
358   }
359 
WaitForSocketState(NrSocketBase * sock,int state)360   bool WaitForSocketState(NrSocketBase* sock, int state) {
361     MOZ_ASSERT(sock);
362     sts_->Dispatch(WrapRunnable(this, &TestNrSocketTest::WaitForSocketState_s,
363                                 sock, state),
364                    NS_DISPATCH_SYNC);
365 
366     bool res;
367     WAIT_(wait_done_for_main_, 500, res);
368     wait_done_for_main_ = false;
369 
370     if (!res) {
371       sts_->Dispatch(
372           WrapRunnable(this, &TestNrSocketTest::CancelWait_s, sock, state),
373           NS_DISPATCH_SYNC);
374     }
375 
376     return res;
377   }
378 
WaitForSocketState_s(NrSocketBase * sock,int state)379   void WaitForSocketState_s(NrSocketBase* sock, int state) {
380     NR_ASYNC_WAIT(sock, state, &WaitDone, this);
381   }
382 
CancelWait_s(NrSocketBase * sock,int state)383   void CancelWait_s(NrSocketBase* sock, int state) { sock->cancel(state); }
384 
WaitForReadable(NrSocketBase * sock)385   bool WaitForReadable(NrSocketBase* sock) {
386     return WaitForSocketState(sock, NR_ASYNC_WAIT_READ);
387   }
388 
WaitForWriteable(NrSocketBase * sock)389   bool WaitForWriteable(NrSocketBase* sock) {
390     return WaitForSocketState(sock, NR_ASYNC_WAIT_WRITE);
391   }
392 
WaitDone(void * sock,int how,void * test_fixture)393   static void WaitDone(void* sock, int how, void* test_fixture) {
394     TestNrSocketTest* test = static_cast<TestNrSocketTest*>(test_fixture);
395     test->wait_done_for_main_ = true;
396   }
397 
398   // Simple busywait boolean for the test cases to spin on.
399   Atomic<bool> wait_done_for_main_;
400 
401   nsCOMPtr<nsIEventTarget> sts_;
402   std::vector<RefPtr<TestNrSocket>> public_addrs_;
403   std::vector<RefPtr<TestNrSocket>> private_addrs_;
404   std::vector<RefPtr<TestNat>> nats_;
405 };
406 
407 }  // namespace mozilla
408 
409 using mozilla::NrSocketBase;
410 using mozilla::TestNat;
411 using mozilla::TestNrSocketTest;
412 
TEST_F(TestNrSocketTest,UnsafePortRejectedUDP)413 TEST_F(TestNrSocketTest, UnsafePortRejectedUDP) {
414   nr_transport_addr address;
415   ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
416                                              // ssh
417                                              22, IPPROTO_UDP, &address));
418   ASSERT_TRUE(NrSocketBase::IsForbiddenAddress(&address));
419 }
420 
TEST_F(TestNrSocketTest,UnsafePortRejectedTCP)421 TEST_F(TestNrSocketTest, UnsafePortRejectedTCP) {
422   nr_transport_addr address;
423   ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
424                                              // ssh
425                                              22, IPPROTO_TCP, &address));
426   ASSERT_TRUE(NrSocketBase::IsForbiddenAddress(&address));
427 }
428 
TEST_F(TestNrSocketTest,SafePortAcceptedUDP)429 TEST_F(TestNrSocketTest, SafePortAcceptedUDP) {
430   nr_transport_addr address;
431   ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
432                                              // stuns
433                                              5349, IPPROTO_UDP, &address));
434   ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
435 }
436 
TEST_F(TestNrSocketTest,SafePortAcceptedTCP)437 TEST_F(TestNrSocketTest, SafePortAcceptedTCP) {
438   nr_transport_addr address;
439   ASSERT_FALSE(nr_str_port_to_transport_addr("127.0.0.1",
440                                              // turns
441                                              5349, IPPROTO_TCP, &address));
442   ASSERT_FALSE(NrSocketBase::IsForbiddenAddress(&address));
443 }
444 
TEST_F(TestNrSocketTest,PublicConnectivity)445 TEST_F(TestNrSocketTest, PublicConnectivity) {
446   CreatePublicAddrs(2);
447 
448   ASSERT_TRUE(CheckConnectivity(public_addrs_[0], public_addrs_[1]));
449   ASSERT_TRUE(CheckConnectivity(public_addrs_[1], public_addrs_[0]));
450   ASSERT_TRUE(CheckConnectivity(public_addrs_[0], public_addrs_[0]));
451   ASSERT_TRUE(CheckConnectivity(public_addrs_[1], public_addrs_[1]));
452 }
453 
TEST_F(TestNrSocketTest,PrivateConnectivity)454 TEST_F(TestNrSocketTest, PrivateConnectivity) {
455   RefPtr<TestNat> nat(CreatePrivateAddrs(2));
456   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
457   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
458 
459   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
460   ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
461   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[0]));
462   ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[1]));
463 }
464 
TEST_F(TestNrSocketTest,NoConnectivityWithoutPinhole)465 TEST_F(TestNrSocketTest, NoConnectivityWithoutPinhole) {
466   RefPtr<TestNat> nat(CreatePrivateAddrs(1));
467   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
468   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
469   CreatePublicAddrs(1);
470 
471   ASSERT_FALSE(CheckConnectivity(public_addrs_[0], private_addrs_[0]));
472 }
473 
TEST_F(TestNrSocketTest,NoConnectivityBetweenSubnets)474 TEST_F(TestNrSocketTest, NoConnectivityBetweenSubnets) {
475   RefPtr<TestNat> nat1(CreatePrivateAddrs(1));
476   nat1->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
477   nat1->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
478   RefPtr<TestNat> nat2(CreatePrivateAddrs(1));
479   nat2->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
480   nat2->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
481 
482   ASSERT_FALSE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
483   ASSERT_FALSE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
484   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[0]));
485   ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[1]));
486 }
487 
TEST_F(TestNrSocketTest,FullConeAcceptIngress)488 TEST_F(TestNrSocketTest, FullConeAcceptIngress) {
489   RefPtr<TestNat> nat(CreatePrivateAddrs(1));
490   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
491   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
492   CreatePublicAddrs(2);
493 
494   nr_transport_addr sender_external_address;
495   // Open pinhole to public IP 0
496   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
497                                 &sender_external_address));
498 
499   // Verify that return traffic works
500   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
501                                    sender_external_address));
502 
503   // Verify that other public IP can use the pinhole
504   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
505                                    sender_external_address));
506 }
507 
TEST_F(TestNrSocketTest,FullConeOnePinhole)508 TEST_F(TestNrSocketTest, FullConeOnePinhole) {
509   RefPtr<TestNat> nat(CreatePrivateAddrs(1));
510   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
511   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
512   CreatePublicAddrs(2);
513 
514   nr_transport_addr sender_external_address;
515   // Open pinhole to public IP 0
516   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
517                                 &sender_external_address));
518 
519   // Verify that return traffic works
520   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
521                                    sender_external_address));
522 
523   // Send traffic to other public IP, verify that it uses the same pinhole
524   nr_transport_addr sender_external_address2;
525   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
526                                 &sender_external_address2));
527   ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
528                                      &sender_external_address2,
529                                      NR_TRANSPORT_ADDR_CMP_MODE_ALL))
530   << "addr1: " << sender_external_address.as_string
531   << " addr2: " << sender_external_address2.as_string;
532 }
533 
534 // OS 10.6 doesn't seem to allow us to open ports on 127.0.0.2, and while linux
535 // does allow this, it has other behavior (see below) that prevents this test
536 // from working.
TEST_F(TestNrSocketTest,DISABLED_AddressRestrictedCone)537 TEST_F(TestNrSocketTest, DISABLED_AddressRestrictedCone) {
538   RefPtr<TestNat> nat(CreatePrivateAddrs(1));
539   nat->filtering_type_ = TestNat::ADDRESS_DEPENDENT;
540   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
541   CreatePublicAddrs(2, "127.0.0.1");
542   CreatePublicAddrs(1, "127.0.0.2");
543 
544   nr_transport_addr sender_external_address;
545   // Open pinhole to public IP 0
546   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
547                                 &sender_external_address));
548 
549   // Verify that return traffic works
550   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
551                                    sender_external_address));
552 
553   // Verify that another address on the same host can use the pinhole
554   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
555                                    sender_external_address));
556 
557   // Linux has a tendency to monkey around with source addresses, doing
558   // stuff like substituting 127.0.0.1 for packets sent by 127.0.0.2, and even
559   // going as far as substituting localhost for a packet sent from a real IP
560   // address when the destination is localhost. The only way to make this test
561   // work on linux is to have two real IP addresses.
562 #ifndef __linux__
563   // Verify that an address on a different host can't use the pinhole
564   ASSERT_FALSE(CheckConnectivityVia(public_addrs_[2], private_addrs_[0],
565                                     sender_external_address));
566 #endif
567 
568   // Send traffic to other public IP, verify that it uses the same pinhole
569   nr_transport_addr sender_external_address2;
570   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
571                                 &sender_external_address2));
572   ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
573                                      &sender_external_address2,
574                                      NR_TRANSPORT_ADDR_CMP_MODE_ALL))
575   << "addr1: " << sender_external_address.as_string
576   << " addr2: " << sender_external_address2.as_string;
577 
578   // Verify that the other public IP can now use the pinhole
579   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
580                                    sender_external_address2));
581 
582   // Send traffic to other public IP, verify that it uses the same pinhole
583   nr_transport_addr sender_external_address3;
584   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[2],
585                                 &sender_external_address3));
586   ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
587                                      &sender_external_address3,
588                                      NR_TRANSPORT_ADDR_CMP_MODE_ALL))
589   << "addr1: " << sender_external_address.as_string
590   << " addr2: " << sender_external_address3.as_string;
591 
592   // Verify that the other public IP can now use the pinhole
593   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[2], private_addrs_[0],
594                                    sender_external_address3));
595 }
596 
TEST_F(TestNrSocketTest,RestrictedCone)597 TEST_F(TestNrSocketTest, RestrictedCone) {
598   RefPtr<TestNat> nat(CreatePrivateAddrs(1));
599   nat->filtering_type_ = TestNat::PORT_DEPENDENT;
600   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
601   CreatePublicAddrs(2);
602 
603   nr_transport_addr sender_external_address;
604   // Open pinhole to public IP 0
605   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
606                                 &sender_external_address));
607 
608   // Verify that return traffic works
609   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
610                                    sender_external_address));
611 
612   // Verify that other public IP cannot use the pinhole
613   ASSERT_FALSE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
614                                     sender_external_address));
615 
616   // Send traffic to other public IP, verify that it uses the same pinhole
617   nr_transport_addr sender_external_address2;
618   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
619                                 &sender_external_address2));
620   ASSERT_FALSE(nr_transport_addr_cmp(&sender_external_address,
621                                      &sender_external_address2,
622                                      NR_TRANSPORT_ADDR_CMP_MODE_ALL))
623   << "addr1: " << sender_external_address.as_string
624   << " addr2: " << sender_external_address2.as_string;
625 
626   // Verify that the other public IP can now use the pinhole
627   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
628                                    sender_external_address2));
629 }
630 
TEST_F(TestNrSocketTest,PortDependentMappingFullCone)631 TEST_F(TestNrSocketTest, PortDependentMappingFullCone) {
632   RefPtr<TestNat> nat(CreatePrivateAddrs(1));
633   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
634   nat->mapping_type_ = TestNat::PORT_DEPENDENT;
635   CreatePublicAddrs(2);
636 
637   nr_transport_addr sender_external_address0;
638   // Open pinhole to public IP 0
639   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
640                                 &sender_external_address0));
641 
642   // Verify that return traffic works
643   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
644                                    sender_external_address0));
645 
646   // Verify that other public IP can use the pinhole
647   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
648                                    sender_external_address0));
649 
650   // Send traffic to other public IP, verify that it uses a different pinhole
651   nr_transport_addr sender_external_address1;
652   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
653                                 &sender_external_address1));
654   ASSERT_TRUE(nr_transport_addr_cmp(&sender_external_address0,
655                                     &sender_external_address1,
656                                     NR_TRANSPORT_ADDR_CMP_MODE_ALL))
657   << "addr1: " << sender_external_address0.as_string
658   << " addr2: " << sender_external_address1.as_string;
659 
660   // Verify that return traffic works
661   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
662                                    sender_external_address1));
663 
664   // Verify that other public IP can use the original pinhole
665   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
666                                    sender_external_address1));
667 }
668 
TEST_F(TestNrSocketTest,Symmetric)669 TEST_F(TestNrSocketTest, Symmetric) {
670   RefPtr<TestNat> nat(CreatePrivateAddrs(1));
671   nat->filtering_type_ = TestNat::PORT_DEPENDENT;
672   nat->mapping_type_ = TestNat::PORT_DEPENDENT;
673   CreatePublicAddrs(2);
674 
675   nr_transport_addr sender_external_address;
676   // Open pinhole to public IP 0
677   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
678                                 &sender_external_address));
679 
680   // Verify that return traffic works
681   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
682                                    sender_external_address));
683 
684   // Verify that other public IP cannot use the pinhole
685   ASSERT_FALSE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
686                                     sender_external_address));
687 
688   // Send traffic to other public IP, verify that it uses a new pinhole
689   nr_transport_addr sender_external_address2;
690   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[1],
691                                 &sender_external_address2));
692   ASSERT_TRUE(nr_transport_addr_cmp(&sender_external_address,
693                                     &sender_external_address2,
694                                     NR_TRANSPORT_ADDR_CMP_MODE_ALL));
695 
696   // Verify that the other public IP can use the new pinhole
697   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[1], private_addrs_[0],
698                                    sender_external_address2));
699 }
700 
TEST_F(TestNrSocketTest,BlockUdp)701 TEST_F(TestNrSocketTest, BlockUdp) {
702   RefPtr<TestNat> nat(CreatePrivateAddrs(2));
703   nat->block_udp_ = true;
704   CreatePublicAddrs(1);
705 
706   nr_transport_addr sender_external_address;
707   ASSERT_FALSE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
708                                  &sender_external_address));
709 
710   // Make sure UDP behind the NAT still works
711   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], private_addrs_[1]));
712   ASSERT_TRUE(CheckConnectivity(private_addrs_[1], private_addrs_[0]));
713 }
714 
TEST_F(TestNrSocketTest,DenyHairpinning)715 TEST_F(TestNrSocketTest, DenyHairpinning) {
716   RefPtr<TestNat> nat(CreatePrivateAddrs(2));
717   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
718   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
719   CreatePublicAddrs(1);
720 
721   nr_transport_addr sender_external_address;
722   // Open pinhole to public IP 0
723   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
724                                 &sender_external_address));
725 
726   // Verify that hairpinning is disallowed
727   ASSERT_FALSE(CheckConnectivityVia(private_addrs_[1], private_addrs_[0],
728                                     sender_external_address));
729 }
730 
TEST_F(TestNrSocketTest,AllowHairpinning)731 TEST_F(TestNrSocketTest, AllowHairpinning) {
732   RefPtr<TestNat> nat(CreatePrivateAddrs(2));
733   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
734   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
735   nat->mapping_timeout_ = 30000;
736   nat->allow_hairpinning_ = true;
737   CreatePublicAddrs(1);
738 
739   nr_transport_addr sender_external_address;
740   // Open pinhole to public IP 0, obtain external address
741   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
742                                 &sender_external_address));
743 
744   // Verify that hairpinning is allowed
745   ASSERT_TRUE(CheckConnectivityVia(private_addrs_[1], private_addrs_[0],
746                                    sender_external_address));
747 }
748 
TEST_F(TestNrSocketTest,FullConeTimeout)749 TEST_F(TestNrSocketTest, FullConeTimeout) {
750   RefPtr<TestNat> nat(CreatePrivateAddrs(1));
751   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
752   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
753   nat->mapping_timeout_ = 200;
754   CreatePublicAddrs(2);
755 
756   nr_transport_addr sender_external_address;
757   // Open pinhole to public IP 0
758   ASSERT_TRUE(CheckConnectivity(private_addrs_[0], public_addrs_[0],
759                                 &sender_external_address));
760 
761   // Verify that return traffic works
762   ASSERT_TRUE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
763                                    sender_external_address));
764 
765   PR_Sleep(201);
766 
767   // Verify that return traffic does not work
768   ASSERT_FALSE(CheckConnectivityVia(public_addrs_[0], private_addrs_[0],
769                                     sender_external_address));
770 }
771 
TEST_F(TestNrSocketTest,PublicConnectivityTcp)772 TEST_F(TestNrSocketTest, PublicConnectivityTcp) {
773   CreatePublicAddrs(2, "127.0.0.1", IPPROTO_TCP);
774 
775   ASSERT_TRUE(CheckTcpConnectivity(public_addrs_[0], public_addrs_[1]));
776 }
777 
TEST_F(TestNrSocketTest,PrivateConnectivityTcp)778 TEST_F(TestNrSocketTest, PrivateConnectivityTcp) {
779   RefPtr<TestNat> nat(CreatePrivateAddrs(2, "127.0.0.1", IPPROTO_TCP));
780   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
781   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
782 
783   ASSERT_TRUE(CheckTcpConnectivity(private_addrs_[0], private_addrs_[1]));
784 }
785 
TEST_F(TestNrSocketTest,PrivateToPublicConnectivityTcp)786 TEST_F(TestNrSocketTest, PrivateToPublicConnectivityTcp) {
787   RefPtr<TestNat> nat(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
788   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
789   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
790   CreatePublicAddrs(1, "127.0.0.1", IPPROTO_TCP);
791 
792   ASSERT_TRUE(CheckTcpConnectivity(private_addrs_[0], public_addrs_[0]));
793 }
794 
TEST_F(TestNrSocketTest,NoConnectivityBetweenSubnetsTcp)795 TEST_F(TestNrSocketTest, NoConnectivityBetweenSubnetsTcp) {
796   RefPtr<TestNat> nat1(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
797   nat1->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
798   nat1->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
799   RefPtr<TestNat> nat2(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
800   nat2->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
801   nat2->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
802 
803   ASSERT_FALSE(CheckTcpConnectivity(private_addrs_[0], private_addrs_[1]));
804 }
805 
TEST_F(TestNrSocketTest,NoConnectivityPublicToPrivateTcp)806 TEST_F(TestNrSocketTest, NoConnectivityPublicToPrivateTcp) {
807   RefPtr<TestNat> nat(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
808   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
809   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
810   CreatePublicAddrs(1, "127.0.0.1", IPPROTO_TCP);
811 
812   ASSERT_FALSE(CheckTcpConnectivity(public_addrs_[0], private_addrs_[0]));
813 }
814