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