~ubuntu-branches/debian/experimental/kopete/experimental

« back to all changes in this revision

Viewing changes to protocols/jabber/googletalk/libjingle/talk/base/nat_unittest.cc

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2015-02-24 11:32:57 UTC
  • mfrom: (1.1.41 vivid)
  • Revision ID: package-import@ubuntu.com-20150224113257-gnupg4v7lzz18ij0
Tags: 4:14.12.2-1
* New upstream release (14.12.2).
* Bump Standards-Version to 3.9.6, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * libjingle
3
 
 * Copyright 2004, Google Inc.
4
 
 *
5
 
 * Redistribution and use in source and binary forms, with or without
6
 
 * modification, are permitted provided that the following conditions are met:
7
 
 *
8
 
 *  1. Redistributions of source code must retain the above copyright notice,
9
 
 *     this list of conditions and the following disclaimer.
10
 
 *  2. Redistributions in binary form must reproduce the above copyright notice,
11
 
 *     this list of conditions and the following disclaimer in the documentation
12
 
 *     and/or other materials provided with the distribution.
13
 
 *  3. The name of the author may not be used to endorse or promote products
14
 
 *     derived from this software without specific prior written permission.
15
 
 *
16
 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19
 
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 
 */
27
 
 
28
 
#include <string>
29
 
 
30
 
#include "talk/base/gunit.h"
31
 
#include "talk/base/host.h"
32
 
#include "talk/base/logging.h"
33
 
#include "talk/base/natserver.h"
34
 
#include "talk/base/natsocketfactory.h"
35
 
#include "talk/base/network.h"
36
 
#include "talk/base/physicalsocketserver.h"
37
 
#include "talk/base/testclient.h"
38
 
#include "talk/base/virtualsocketserver.h"
39
 
 
40
 
using namespace talk_base;
41
 
 
42
 
bool CheckReceive(
43
 
    TestClient* client, bool should_receive, const char* buf, size_t size) {
44
 
  return (should_receive) ?
45
 
      client->CheckNextPacket(buf, size, 0) :
46
 
      client->CheckNoPacket();
47
 
}
48
 
 
49
 
TestClient* CreateTestClient(
50
 
      SocketFactory* factory, const SocketAddress& local_addr) {
51
 
  AsyncUDPSocket* socket = AsyncUDPSocket::Create(factory, local_addr);
52
 
  return new TestClient(socket);
53
 
}
54
 
 
55
 
// Tests that when sending from internal_addr to external_addrs through the
56
 
// NAT type specified by nat_type, all external addrs receive the sent packet
57
 
// and, if exp_same is true, all use the same mapped-address on the NAT.
58
 
void TestSend(
59
 
      SocketServer* internal, const SocketAddress& internal_addr,
60
 
      SocketServer* external, const SocketAddress external_addrs[4],
61
 
      NATType nat_type, bool exp_same) {
62
 
  Thread th_int(internal);
63
 
  Thread th_ext(external);
64
 
 
65
 
  SocketAddress server_addr = internal_addr;
66
 
  server_addr.SetPort(0);  // Auto-select a port
67
 
  NATServer* nat = new NATServer(
68
 
      nat_type, internal, server_addr, external, external_addrs[0]);
69
 
  NATSocketFactory* natsf = new NATSocketFactory(internal,
70
 
                                                 nat->internal_address());
71
 
 
72
 
  TestClient* in = CreateTestClient(natsf, internal_addr);
73
 
  TestClient* out[4];
74
 
  for (int i = 0; i < 4; i++)
75
 
    out[i] = CreateTestClient(external, external_addrs[i]);
76
 
 
77
 
  th_int.Start();
78
 
  th_ext.Start();
79
 
 
80
 
  const char* buf = "filter_test";
81
 
  size_t len = strlen(buf);
82
 
 
83
 
  in->SendTo(buf, len, out[0]->address());
84
 
  SocketAddress trans_addr;
85
 
  EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
86
 
 
87
 
  for (int i = 1; i < 4; i++) {
88
 
    in->SendTo(buf, len, out[i]->address());
89
 
    SocketAddress trans_addr2;
90
 
    EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2));
91
 
    bool are_same = (trans_addr == trans_addr2);
92
 
    ASSERT_EQ(are_same, exp_same) << "same translated address";
93
 
  }
94
 
 
95
 
  th_int.Stop();
96
 
  th_ext.Stop();
97
 
 
98
 
  delete nat;
99
 
  delete natsf;
100
 
  delete in;
101
 
  for (int i = 0; i < 4; i++)
102
 
    delete out[i];
103
 
}
104
 
 
105
 
// Tests that when sending from external_addrs to internal_addr, the packet
106
 
// is delivered according to the specified filter_ip and filter_port rules.
107
 
void TestRecv(
108
 
      SocketServer* internal, const SocketAddress& internal_addr,
109
 
      SocketServer* external, const SocketAddress external_addrs[4],
110
 
      NATType nat_type, bool filter_ip, bool filter_port) {
111
 
  Thread th_int(internal);
112
 
  Thread th_ext(external);
113
 
 
114
 
  SocketAddress server_addr = internal_addr;
115
 
  server_addr.SetPort(0);  // Auto-select a port
116
 
  NATServer* nat = new NATServer(
117
 
      nat_type, internal, server_addr, external, external_addrs[0]);
118
 
  NATSocketFactory* natsf = new NATSocketFactory(internal,
119
 
                                                 nat->internal_address());
120
 
 
121
 
  TestClient* in = CreateTestClient(natsf, internal_addr);
122
 
  TestClient* out[4];
123
 
  for (int i = 0; i < 4; i++)
124
 
    out[i] = CreateTestClient(external, external_addrs[i]);
125
 
 
126
 
  th_int.Start();
127
 
  th_ext.Start();
128
 
 
129
 
  const char* buf = "filter_test";
130
 
  size_t len = strlen(buf);
131
 
 
132
 
  in->SendTo(buf, len, out[0]->address());
133
 
  SocketAddress trans_addr;
134
 
  EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
135
 
 
136
 
  out[1]->SendTo(buf, len, trans_addr);
137
 
  EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len));
138
 
 
139
 
  out[2]->SendTo(buf, len, trans_addr);
140
 
  EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len));
141
 
 
142
 
  out[3]->SendTo(buf, len, trans_addr);
143
 
  EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len));
144
 
 
145
 
  th_int.Stop();
146
 
  th_ext.Stop();
147
 
 
148
 
  delete nat;
149
 
  delete natsf;
150
 
  delete in;
151
 
  for (int i = 0; i < 4; i++)
152
 
    delete out[i];
153
 
}
154
 
 
155
 
// Tests that NATServer allocates bindings properly.
156
 
void TestBindings(
157
 
    SocketServer* internal, const SocketAddress& internal_addr,
158
 
    SocketServer* external, const SocketAddress external_addrs[4]) {
159
 
  TestSend(internal, internal_addr, external, external_addrs,
160
 
           NAT_OPEN_CONE, true);
161
 
  TestSend(internal, internal_addr, external, external_addrs,
162
 
           NAT_ADDR_RESTRICTED, true);
163
 
  TestSend(internal, internal_addr, external, external_addrs,
164
 
           NAT_PORT_RESTRICTED, true);
165
 
  TestSend(internal, internal_addr, external, external_addrs,
166
 
           NAT_SYMMETRIC, false);
167
 
}
168
 
 
169
 
// Tests that NATServer filters packets properly.
170
 
void TestFilters(
171
 
    SocketServer* internal, const SocketAddress& internal_addr,
172
 
    SocketServer* external, const SocketAddress external_addrs[4]) {
173
 
  TestRecv(internal, internal_addr, external, external_addrs,
174
 
           NAT_OPEN_CONE, false, false);
175
 
  TestRecv(internal, internal_addr, external, external_addrs,
176
 
           NAT_ADDR_RESTRICTED, true, false);
177
 
  TestRecv(internal, internal_addr, external, external_addrs,
178
 
           NAT_PORT_RESTRICTED, true, true);
179
 
  TestRecv(internal, internal_addr, external, external_addrs,
180
 
           NAT_SYMMETRIC, true, true);
181
 
}
182
 
 
183
 
TEST(NatTest, TestPhysical) {
184
 
  BasicNetworkManager network_manager;
185
 
  network_manager.StartUpdating();
186
 
  // Process pending messages so the network list is updated.
187
 
  Thread::Current()->ProcessMessages(0);
188
 
 
189
 
  std::vector<Network*> networks;
190
 
  network_manager.GetNetworks(&networks);
191
 
  if (networks.empty()) {
192
 
    LOG(LS_WARNING) << "Not enough network adapters for test.";
193
 
    return;
194
 
  }
195
 
 
196
 
  SocketAddress int_addr("127.0.0.1", 0);
197
 
  std::string ext_ip1 = "127.0.0.1";
198
 
  std::string ext_ip2 = networks[0]->ip().ToString();
199
 
 
200
 
  LOG(LS_INFO) << "selected ip " << ext_ip2;
201
 
 
202
 
  SocketAddress ext_addrs[4] = {
203
 
      SocketAddress(ext_ip1, 0),
204
 
      SocketAddress(ext_ip2, 0),
205
 
      SocketAddress(ext_ip1, 0),
206
 
      SocketAddress(ext_ip2, 0)
207
 
  };
208
 
 
209
 
  PhysicalSocketServer* int_pss = new PhysicalSocketServer();
210
 
  PhysicalSocketServer* ext_pss = new PhysicalSocketServer();
211
 
 
212
 
  TestBindings(int_pss, int_addr, ext_pss, ext_addrs);
213
 
  TestFilters(int_pss, int_addr, ext_pss, ext_addrs);
214
 
}
215
 
 
216
 
class TestVirtualSocketServer : public VirtualSocketServer {
217
 
 public:
218
 
  explicit TestVirtualSocketServer(SocketServer* ss)
219
 
      : VirtualSocketServer(ss) {}
220
 
  // Expose this publicly
221
 
  IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); }
222
 
};
223
 
 
224
 
TEST(NatTest, TestVirtual) {
225
 
  TestVirtualSocketServer* int_vss = new TestVirtualSocketServer(
226
 
      new PhysicalSocketServer());
227
 
  TestVirtualSocketServer* ext_vss = new TestVirtualSocketServer(
228
 
      new PhysicalSocketServer());
229
 
 
230
 
  // TODO: IPv6ize this test when the NAT stuff is v6ed.
231
 
  SocketAddress int_addr, ext_addrs[4];
232
 
  int_addr.SetIP(int_vss->GetNextIP(int_addr.ipaddr().family()));
233
 
  ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.ipaddr().family()));
234
 
  ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.ipaddr().family()));
235
 
  ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
236
 
  ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
237
 
 
238
 
  TestBindings(int_vss, int_addr, ext_vss, ext_addrs);
239
 
  TestFilters(int_vss, int_addr, ext_vss, ext_addrs);
240
 
}
241
 
 
242
 
 
243
 
// TODO: Finish this test
244
 
class NatTcpTest : public testing::Test, public sigslot::has_slots<> {
245
 
 public:
246
 
  NatTcpTest() : connected_(false) {}
247
 
  virtual void SetUp() {
248
 
    int_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
249
 
    ext_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
250
 
    nat_ = new NATServer(NAT_OPEN_CONE, int_vss_, SocketAddress(),
251
 
                         ext_vss_, SocketAddress());
252
 
    natsf_ = new NATSocketFactory(int_vss_, nat_->internal_address());
253
 
  }
254
 
  void OnConnectEvent(AsyncSocket* socket) {
255
 
    connected_ = true;
256
 
  }
257
 
  void OnAcceptEvent(AsyncSocket* socket) {
258
 
    accepted_ = server_->Accept(NULL);
259
 
  }
260
 
  void OnCloseEvent(AsyncSocket* socket, int error) {
261
 
  }
262
 
  void ConnectEvents() {
263
 
    server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
264
 
    client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
265
 
  }
266
 
  TestVirtualSocketServer* int_vss_;
267
 
  TestVirtualSocketServer* ext_vss_;
268
 
  NATServer* nat_;
269
 
  NATSocketFactory* natsf_;
270
 
  AsyncSocket* client_;
271
 
  AsyncSocket* server_;
272
 
  AsyncSocket* accepted_;
273
 
  bool connected_;
274
 
};
275
 
 
276
 
TEST_F(NatTcpTest, DISABLED_TestConnectOut) {
277
 
  server_ = ext_vss_->CreateAsyncSocket(SOCK_STREAM);
278
 
  server_->Bind(SocketAddress());
279
 
  server_->Listen(5);
280
 
 
281
 
  client_ = int_vss_->CreateAsyncSocket(SOCK_STREAM);
282
 
  EXPECT_GE(0, client_->Bind(SocketAddress()));
283
 
  EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
284
 
 
285
 
 
286
 
  ConnectEvents();
287
 
 
288
 
  EXPECT_TRUE_WAIT(connected_, 1000);
289
 
  EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
290
 
  EXPECT_EQ(client_->GetRemoteAddress(), accepted_->GetLocalAddress());
291
 
  EXPECT_EQ(client_->GetLocalAddress(), accepted_->GetRemoteAddress());
292
 
 
293
 
  client_->Close();
294
 
}
295
 
//#endif