147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string>
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/gunit.h"
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/logging.h"
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/natserver.h"
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/natsocketfactory.h"
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/nethelpers.h"
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/network.h"
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/physicalsocketserver.h"
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/testclient.h"
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/virtualsocketserver.h"
22a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.org#include "webrtc/test/testsupport/gtest_disable.h"
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgusing namespace rtc;
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool CheckReceive(
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    TestClient* client, bool should_receive, const char* buf, size_t size) {
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (should_receive) ?
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      client->CheckNextPacket(buf, size, 0) :
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      client->CheckNoPacket();
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTestClient* CreateTestClient(
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketFactory* factory, const SocketAddress& local_addr) {
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncUDPSocket* socket = AsyncUDPSocket::Create(factory, local_addr);
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return new TestClient(socket);
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests that when sending from internal_addr to external_addrs through the
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// NAT type specified by nat_type, all external addrs receive the sent packet
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// and, if exp_same is true, all use the same mapped-address on the NAT.
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestSend(
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketServer* internal, const SocketAddress& internal_addr,
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketServer* external, const SocketAddress external_addrs[4],
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      NATType nat_type, bool exp_same) {
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread th_int(internal);
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread th_ext(external);
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress server_addr = internal_addr;
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  server_addr.SetPort(0);  // Auto-select a port
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  NATServer* nat = new NATServer(
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      nat_type, internal, server_addr, external, external_addrs[0]);
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  NATSocketFactory* natsf = new NATSocketFactory(internal,
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                 nat->internal_address());
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestClient* in = CreateTestClient(natsf, internal_addr);
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestClient* out[4];
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < 4; i++)
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    out[i] = CreateTestClient(external, external_addrs[i]);
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  th_int.Start();
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  th_ext.Start();
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* buf = "filter_test";
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t len = strlen(buf);
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  in->SendTo(buf, len, out[0]->address());
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress trans_addr;
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 1; i < 4; i++) {
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    in->SendTo(buf, len, out[i]->address());
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketAddress trans_addr2;
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2));
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    bool are_same = (trans_addr == trans_addr2);
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT_EQ(are_same, exp_same) << "same translated address";
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT_NE(AF_UNSPEC, trans_addr.family());
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT_NE(AF_UNSPEC, trans_addr2.family());
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  th_int.Stop();
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  th_ext.Stop();
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete nat;
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete natsf;
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete in;
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < 4; i++)
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete out[i];
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests that when sending from external_addrs to internal_addr, the packet
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// is delivered according to the specified filter_ip and filter_port rules.
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestRecv(
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketServer* internal, const SocketAddress& internal_addr,
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketServer* external, const SocketAddress external_addrs[4],
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      NATType nat_type, bool filter_ip, bool filter_port) {
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread th_int(internal);
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread th_ext(external);
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress server_addr = internal_addr;
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  server_addr.SetPort(0);  // Auto-select a port
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  NATServer* nat = new NATServer(
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      nat_type, internal, server_addr, external, external_addrs[0]);
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  NATSocketFactory* natsf = new NATSocketFactory(internal,
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                 nat->internal_address());
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestClient* in = CreateTestClient(natsf, internal_addr);
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestClient* out[4];
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < 4; i++)
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    out[i] = CreateTestClient(external, external_addrs[i]);
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  th_int.Start();
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  th_ext.Start();
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* buf = "filter_test";
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t len = strlen(buf);
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  in->SendTo(buf, len, out[0]->address());
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress trans_addr;
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  out[1]->SendTo(buf, len, trans_addr);
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len));
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  out[2]->SendTo(buf, len, trans_addr);
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len));
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  out[3]->SendTo(buf, len, trans_addr);
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len));
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  th_int.Stop();
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  th_ext.Stop();
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete nat;
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete natsf;
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete in;
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < 4; i++)
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete out[i];
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests that NATServer allocates bindings properly.
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestBindings(
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketServer* internal, const SocketAddress& internal_addr,
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketServer* external, const SocketAddress external_addrs[4]) {
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestSend(internal, internal_addr, external, external_addrs,
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           NAT_OPEN_CONE, true);
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestSend(internal, internal_addr, external, external_addrs,
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           NAT_ADDR_RESTRICTED, true);
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestSend(internal, internal_addr, external, external_addrs,
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           NAT_PORT_RESTRICTED, true);
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestSend(internal, internal_addr, external, external_addrs,
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           NAT_SYMMETRIC, false);
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests that NATServer filters packets properly.
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestFilters(
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketServer* internal, const SocketAddress& internal_addr,
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketServer* external, const SocketAddress external_addrs[4]) {
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestRecv(internal, internal_addr, external, external_addrs,
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           NAT_OPEN_CONE, false, false);
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestRecv(internal, internal_addr, external, external_addrs,
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           NAT_ADDR_RESTRICTED, true, false);
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestRecv(internal, internal_addr, external, external_addrs,
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           NAT_PORT_RESTRICTED, true, true);
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestRecv(internal, internal_addr, external, external_addrs,
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           NAT_SYMMETRIC, true, true);
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool TestConnectivity(const SocketAddress& src, const IPAddress& dst) {
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // The physical NAT tests require connectivity to the selected ip from the
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // internal address used for the NAT. Things like firewalls can break that, so
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // check to see if it's worth even trying with this ip.
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<PhysicalSocketServer> pss(new PhysicalSocketServer());
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(pss->CreateAsyncSocket(src.family(),
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                        SOCK_DGRAM));
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(pss->CreateAsyncSocket(src.family(),
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                        SOCK_DGRAM));
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (client->Bind(SocketAddress(src.ipaddr(), 0)) != 0 ||
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      server->Bind(SocketAddress(dst, 0)) != 0) {
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* buf = "hello other socket";
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t len = strlen(buf);
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int sent = client->SendTo(buf, len, server->GetLocalAddress());
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress addr;
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t kRecvBufSize = 64;
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char recvbuf[kRecvBufSize];
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::Current()->SleepMs(100);
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int received = server->RecvFrom(recvbuf, kRecvBufSize, &addr);
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return received == sent && ::memcmp(buf, recvbuf, len) == 0;
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestPhysicalInternal(const SocketAddress& int_addr) {
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  BasicNetworkManager network_manager;
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  network_manager.set_ipv6_enabled(true);
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  network_manager.StartUpdating();
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Process pending messages so the network list is updated.
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::Current()->ProcessMessages(0);
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::vector<Network*> networks;
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  network_manager.GetNetworks(&networks);
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (networks.empty()) {
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_WARNING) << "Not enough network adapters for test.";
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return;
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress ext_addr1(int_addr);
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress ext_addr2;
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Find an available IP with matching family. The test breaks if int_addr
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // can't talk to ip, so check for connectivity as well.
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (std::vector<Network*>::iterator it = networks.begin();
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      it != networks.end(); ++it) {
2132738d4793348b524b02c8fcc5fabd113d4971cbdguoweis@webrtc.org    const IPAddress& ip = (*it)->GetBestIP();
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) {
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ext_addr2.SetIP(ip);
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (ext_addr2.IsNil()) {
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_WARNING) << "No available IP of same family as " << int_addr;
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return;
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LOG(LS_INFO) << "selected ip " << ext_addr2.ipaddr();
22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress ext_addrs[4] = {
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketAddress(ext_addr1),
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketAddress(ext_addr2),
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketAddress(ext_addr1),
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketAddress(ext_addr2)
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  };
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<PhysicalSocketServer> int_pss(new PhysicalSocketServer());
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<PhysicalSocketServer> ext_pss(new PhysicalSocketServer());
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestBindings(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestFilters(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
240a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(NatTest, DISABLED_ON_MAC(TestPhysicalIPv4)) {
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestPhysicalInternal(SocketAddress("127.0.0.1", 0));
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
244a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(NatTest, DISABLED_ON_MAC(TestPhysicalIPv6)) {
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (HasIPv6Enabled()) {
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    TestPhysicalInternal(SocketAddress("::1", 0));
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_WARNING) << "No IPv6, skipping";
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass TestVirtualSocketServer : public VirtualSocketServer {
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  explicit TestVirtualSocketServer(SocketServer* ss)
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      : VirtualSocketServer(ss),
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ss_(ss) {}
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Expose this publicly
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); }
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<SocketServer> ss_;
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestVirtualInternal(int family) {
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<TestVirtualSocketServer> int_vss(new TestVirtualSocketServer(
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      new PhysicalSocketServer()));
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<TestVirtualSocketServer> ext_vss(new TestVirtualSocketServer(
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      new PhysicalSocketServer()));
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress int_addr;
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress ext_addrs[4];
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int_addr.SetIP(int_vss->GetNextIP(family));
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.family()));
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.family()));
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestBindings(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestFilters(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
282a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(NatTest, DISABLED_ON_MAC(TestVirtualIPv4)) {
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestVirtualInternal(AF_INET);
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
286a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(NatTest, DISABLED_ON_MAC(TestVirtualIPv6)) {
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (HasIPv6Enabled()) {
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    TestVirtualInternal(AF_INET6);
28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_WARNING) << "No IPv6, skipping";
29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// TODO: Finish this test
29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass NatTcpTest : public testing::Test, public sigslot::has_slots<> {
29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  NatTcpTest() : connected_(false) {}
29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void SetUp() {
29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    int_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ext_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    nat_ = new NATServer(NAT_OPEN_CONE, int_vss_, SocketAddress(),
30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         ext_vss_, SocketAddress());
30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    natsf_ = new NATSocketFactory(int_vss_, nat_->internal_address());
30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnConnectEvent(AsyncSocket* socket) {
30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    connected_ = true;
30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnAcceptEvent(AsyncSocket* socket) {
30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    accepted_ = server_->Accept(NULL);
31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnCloseEvent(AsyncSocket* socket, int error) {
31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void ConnectEvents() {
31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestVirtualSocketServer* int_vss_;
31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestVirtualSocketServer* ext_vss_;
31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  NATServer* nat_;
32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  NATSocketFactory* natsf_;
32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket* client_;
32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket* server_;
32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket* accepted_;
32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool connected_;
32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST_F(NatTcpTest, DISABLED_TestConnectOut) {
32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  server_ = ext_vss_->CreateAsyncSocket(SOCK_STREAM);
32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  server_->Bind(SocketAddress());
33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  server_->Listen(5);
33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client_ = int_vss_->CreateAsyncSocket(SOCK_STREAM);
33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_GE(0, client_->Bind(SocketAddress()));
33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectEvents();
33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(connected_, 1000);
34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client_->GetRemoteAddress(), accepted_->GetLocalAddress());
34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client_->GetLocalAddress(), accepted_->GetRemoteAddress());
34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client_->Close();
34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//#endif
347