blob: 8031dff93ddb61e7f9ec57ad74d817c06421d6b4 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <string.h>
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -080012#include <algorithm>
jbauch555604a2016-04-26 03:13:22 -070013#include <memory>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000014#include <string>
Yves Gerey3e707812018-11-28 16:47:49 +010015#include <vector>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000016
Karl Wiberg918f50c2018-07-05 11:40:33 +020017#include "absl/memory/memory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "rtc_base/asyncpacketsocket.h"
19#include "rtc_base/asyncsocket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/asynctcpsocket.h"
Yves Gerey3e707812018-11-28 16:47:49 +010021#include "rtc_base/asyncudpsocket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010023#include "rtc_base/ipaddress.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/logging.h"
25#include "rtc_base/natserver.h"
26#include "rtc_base/natsocketfactory.h"
Yves Gerey3e707812018-11-28 16:47:49 +010027#include "rtc_base/nattypes.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020028#include "rtc_base/nethelpers.h"
29#include "rtc_base/network.h"
30#include "rtc_base/physicalsocketserver.h"
Yves Gerey3e707812018-11-28 16:47:49 +010031#include "rtc_base/socketaddress.h"
32#include "rtc_base/socketfactory.h"
33#include "rtc_base/socketserver.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/testclient.h"
Yves Gerey3e707812018-11-28 16:47:49 +010035#include "rtc_base/third_party/sigslot/sigslot.h"
36#include "rtc_base/thread.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "rtc_base/virtualsocketserver.h"
Yves Gerey3e707812018-11-28 16:47:49 +010038#include "test/gtest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000039
40using namespace rtc;
41
Yves Gerey665174f2018-06-19 15:03:05 +020042bool CheckReceive(TestClient* client,
43 bool should_receive,
44 const char* buf,
45 size_t size) {
46 return (should_receive) ? client->CheckNextPacket(buf, size, 0)
47 : client->CheckNoPacket();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000048}
49
Yves Gerey665174f2018-06-19 15:03:05 +020050TestClient* CreateTestClient(SocketFactory* factory,
51 const SocketAddress& local_addr) {
nisse32f25052017-05-08 01:57:18 -070052 return new TestClient(
Karl Wiberg918f50c2018-07-05 11:40:33 +020053 absl::WrapUnique(AsyncUDPSocket::Create(factory, local_addr)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000054}
55
deadbeefc5d0d952015-07-16 10:22:21 -070056TestClient* CreateTCPTestClient(AsyncSocket* socket) {
Karl Wiberg918f50c2018-07-05 11:40:33 +020057 return new TestClient(absl::make_unique<AsyncTCPSocket>(socket, false));
deadbeefc5d0d952015-07-16 10:22:21 -070058}
59
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000060// Tests that when sending from internal_addr to external_addrs through the
61// NAT type specified by nat_type, all external addrs receive the sent packet
62// and, if exp_same is true, all use the same mapped-address on the NAT.
Yves Gerey665174f2018-06-19 15:03:05 +020063void TestSend(SocketServer* internal,
64 const SocketAddress& internal_addr,
65 SocketServer* external,
66 const SocketAddress external_addrs[4],
67 NATType nat_type,
68 bool exp_same) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000069 Thread th_int(internal);
70 Thread th_ext(external);
71
72 SocketAddress server_addr = internal_addr;
73 server_addr.SetPort(0); // Auto-select a port
deadbeefc5d0d952015-07-16 10:22:21 -070074 NATServer* nat = new NATServer(nat_type, internal, server_addr, server_addr,
75 external, external_addrs[0]);
Yves Gerey665174f2018-06-19 15:03:05 +020076 NATSocketFactory* natsf = new NATSocketFactory(
77 internal, nat->internal_udp_address(), nat->internal_tcp_address());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000078
79 TestClient* in = CreateTestClient(natsf, internal_addr);
80 TestClient* out[4];
81 for (int i = 0; i < 4; i++)
82 out[i] = CreateTestClient(external, external_addrs[i]);
83
84 th_int.Start();
85 th_ext.Start();
86
87 const char* buf = "filter_test";
88 size_t len = strlen(buf);
89
90 in->SendTo(buf, len, out[0]->address());
91 SocketAddress trans_addr;
92 EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
93
94 for (int i = 1; i < 4; i++) {
95 in->SendTo(buf, len, out[i]->address());
96 SocketAddress trans_addr2;
97 EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2));
98 bool are_same = (trans_addr == trans_addr2);
99 ASSERT_EQ(are_same, exp_same) << "same translated address";
100 ASSERT_NE(AF_UNSPEC, trans_addr.family());
101 ASSERT_NE(AF_UNSPEC, trans_addr2.family());
102 }
103
104 th_int.Stop();
105 th_ext.Stop();
106
107 delete nat;
108 delete natsf;
109 delete in;
110 for (int i = 0; i < 4; i++)
111 delete out[i];
112}
113
114// Tests that when sending from external_addrs to internal_addr, the packet
115// is delivered according to the specified filter_ip and filter_port rules.
Yves Gerey665174f2018-06-19 15:03:05 +0200116void TestRecv(SocketServer* internal,
117 const SocketAddress& internal_addr,
118 SocketServer* external,
119 const SocketAddress external_addrs[4],
120 NATType nat_type,
121 bool filter_ip,
122 bool filter_port) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000123 Thread th_int(internal);
124 Thread th_ext(external);
125
126 SocketAddress server_addr = internal_addr;
127 server_addr.SetPort(0); // Auto-select a port
deadbeefc5d0d952015-07-16 10:22:21 -0700128 NATServer* nat = new NATServer(nat_type, internal, server_addr, server_addr,
129 external, external_addrs[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200130 NATSocketFactory* natsf = new NATSocketFactory(
131 internal, nat->internal_udp_address(), nat->internal_tcp_address());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000132
133 TestClient* in = CreateTestClient(natsf, internal_addr);
134 TestClient* out[4];
135 for (int i = 0; i < 4; i++)
136 out[i] = CreateTestClient(external, external_addrs[i]);
137
138 th_int.Start();
139 th_ext.Start();
140
141 const char* buf = "filter_test";
142 size_t len = strlen(buf);
143
144 in->SendTo(buf, len, out[0]->address());
145 SocketAddress trans_addr;
146 EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
147
148 out[1]->SendTo(buf, len, trans_addr);
149 EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len));
150
151 out[2]->SendTo(buf, len, trans_addr);
152 EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len));
153
154 out[3]->SendTo(buf, len, trans_addr);
155 EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len));
156
157 th_int.Stop();
158 th_ext.Stop();
159
160 delete nat;
161 delete natsf;
162 delete in;
163 for (int i = 0; i < 4; i++)
164 delete out[i];
165}
166
167// Tests that NATServer allocates bindings properly.
Yves Gerey665174f2018-06-19 15:03:05 +0200168void TestBindings(SocketServer* internal,
169 const SocketAddress& internal_addr,
170 SocketServer* external,
171 const SocketAddress external_addrs[4]) {
172 TestSend(internal, internal_addr, external, external_addrs, NAT_OPEN_CONE,
173 true);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000174 TestSend(internal, internal_addr, external, external_addrs,
175 NAT_ADDR_RESTRICTED, true);
176 TestSend(internal, internal_addr, external, external_addrs,
177 NAT_PORT_RESTRICTED, true);
Yves Gerey665174f2018-06-19 15:03:05 +0200178 TestSend(internal, internal_addr, external, external_addrs, NAT_SYMMETRIC,
179 false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000180}
181
182// Tests that NATServer filters packets properly.
Yves Gerey665174f2018-06-19 15:03:05 +0200183void TestFilters(SocketServer* internal,
184 const SocketAddress& internal_addr,
185 SocketServer* external,
186 const SocketAddress external_addrs[4]) {
187 TestRecv(internal, internal_addr, external, external_addrs, NAT_OPEN_CONE,
188 false, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000189 TestRecv(internal, internal_addr, external, external_addrs,
190 NAT_ADDR_RESTRICTED, true, false);
191 TestRecv(internal, internal_addr, external, external_addrs,
192 NAT_PORT_RESTRICTED, true, true);
Yves Gerey665174f2018-06-19 15:03:05 +0200193 TestRecv(internal, internal_addr, external, external_addrs, NAT_SYMMETRIC,
194 true, true);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000195}
196
197bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) {
198 // The physical NAT tests require connectivity to the selected ip from the
199 // internal address used for the NAT. Things like firewalls can break that, so
200 // check to see if it's worth even trying with this ip.
jbauch555604a2016-04-26 03:13:22 -0700201 std::unique_ptr<PhysicalSocketServer> pss(new PhysicalSocketServer());
202 std::unique_ptr<AsyncSocket> client(
203 pss->CreateAsyncSocket(src.family(), SOCK_DGRAM));
204 std::unique_ptr<AsyncSocket> server(
205 pss->CreateAsyncSocket(src.family(), SOCK_DGRAM));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000206 if (client->Bind(SocketAddress(src.ipaddr(), 0)) != 0 ||
207 server->Bind(SocketAddress(dst, 0)) != 0) {
208 return false;
209 }
210 const char* buf = "hello other socket";
211 size_t len = strlen(buf);
212 int sent = client->SendTo(buf, len, server->GetLocalAddress());
213 SocketAddress addr;
214 const size_t kRecvBufSize = 64;
215 char recvbuf[kRecvBufSize];
216 Thread::Current()->SleepMs(100);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200217 int received = server->RecvFrom(recvbuf, kRecvBufSize, &addr, nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000218 return received == sent && ::memcmp(buf, recvbuf, len) == 0;
219}
220
221void TestPhysicalInternal(const SocketAddress& int_addr) {
222 BasicNetworkManager network_manager;
223 network_manager.set_ipv6_enabled(true);
224 network_manager.StartUpdating();
225 // Process pending messages so the network list is updated.
226 Thread::Current()->ProcessMessages(0);
227
228 std::vector<Network*> networks;
229 network_manager.GetNetworks(&networks);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800230 networks.erase(std::remove_if(networks.begin(), networks.end(),
231 [](rtc::Network* network) {
232 return rtc::kDefaultNetworkIgnoreMask &
233 network->type();
234 }),
235 networks.end());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000236 if (networks.empty()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100237 RTC_LOG(LS_WARNING) << "Not enough network adapters for test.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000238 return;
239 }
240
241 SocketAddress ext_addr1(int_addr);
242 SocketAddress ext_addr2;
243 // Find an available IP with matching family. The test breaks if int_addr
244 // can't talk to ip, so check for connectivity as well.
245 for (std::vector<Network*>::iterator it = networks.begin();
Yves Gerey665174f2018-06-19 15:03:05 +0200246 it != networks.end(); ++it) {
guoweis@webrtc.org369a6372014-09-17 22:37:29 +0000247 const IPAddress& ip = (*it)->GetBestIP();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000248 if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) {
249 ext_addr2.SetIP(ip);
250 break;
251 }
252 }
253 if (ext_addr2.IsNil()) {
Jonas Olssonabbe8412018-04-03 13:40:05 +0200254 RTC_LOG(LS_WARNING) << "No available IP of same family as "
255 << int_addr.ToString();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000256 return;
257 }
258
Jonas Olssonabbe8412018-04-03 13:40:05 +0200259 RTC_LOG(LS_INFO) << "selected ip " << ext_addr2.ipaddr().ToString();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000260
261 SocketAddress ext_addrs[4] = {
Yves Gerey665174f2018-06-19 15:03:05 +0200262 SocketAddress(ext_addr1), SocketAddress(ext_addr2),
263 SocketAddress(ext_addr1), SocketAddress(ext_addr2)};
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000264
jbauch555604a2016-04-26 03:13:22 -0700265 std::unique_ptr<PhysicalSocketServer> int_pss(new PhysicalSocketServer());
266 std::unique_ptr<PhysicalSocketServer> ext_pss(new PhysicalSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000267
268 TestBindings(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
269 TestFilters(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
270}
271
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000272TEST(NatTest, TestPhysicalIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000273 TestPhysicalInternal(SocketAddress("127.0.0.1", 0));
274}
275
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000276TEST(NatTest, TestPhysicalIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000277 if (HasIPv6Enabled()) {
278 TestPhysicalInternal(SocketAddress("::1", 0));
279 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100280 RTC_LOG(LS_WARNING) << "No IPv6, skipping";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000281 }
282}
283
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700284namespace {
285
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000286class TestVirtualSocketServer : public VirtualSocketServer {
287 public:
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000288 // Expose this publicly
289 IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000290};
291
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700292} // namespace
293
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000294void TestVirtualInternal(int family) {
jbauch555604a2016-04-26 03:13:22 -0700295 std::unique_ptr<TestVirtualSocketServer> int_vss(
deadbeef98e186c2017-05-16 18:00:06 -0700296 new TestVirtualSocketServer());
jbauch555604a2016-04-26 03:13:22 -0700297 std::unique_ptr<TestVirtualSocketServer> ext_vss(
deadbeef98e186c2017-05-16 18:00:06 -0700298 new TestVirtualSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000299
300 SocketAddress int_addr;
301 SocketAddress ext_addrs[4];
302 int_addr.SetIP(int_vss->GetNextIP(family));
303 ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.family()));
304 ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.family()));
305 ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
306 ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
307
308 TestBindings(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
309 TestFilters(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
310}
311
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000312TEST(NatTest, TestVirtualIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000313 TestVirtualInternal(AF_INET);
314}
315
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000316TEST(NatTest, TestVirtualIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000317 if (HasIPv6Enabled()) {
318 TestVirtualInternal(AF_INET6);
319 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100320 RTC_LOG(LS_WARNING) << "No IPv6, skipping";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000321 }
322}
323
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000324class NatTcpTest : public testing::Test, public sigslot::has_slots<> {
325 public:
deadbeefc5d0d952015-07-16 10:22:21 -0700326 NatTcpTest()
327 : int_addr_("192.168.0.1", 0),
328 ext_addr_("10.0.0.1", 0),
329 connected_(false),
deadbeef98e186c2017-05-16 18:00:06 -0700330 int_vss_(new TestVirtualSocketServer()),
331 ext_vss_(new TestVirtualSocketServer()),
deadbeefc5d0d952015-07-16 10:22:21 -0700332 int_thread_(new Thread(int_vss_.get())),
333 ext_thread_(new Thread(ext_vss_.get())),
deadbeef98e186c2017-05-16 18:00:06 -0700334 nat_(new NATServer(NAT_OPEN_CONE,
335 int_vss_.get(),
336 int_addr_,
337 int_addr_,
338 ext_vss_.get(),
339 ext_addr_)),
deadbeefc5d0d952015-07-16 10:22:21 -0700340 natsf_(new NATSocketFactory(int_vss_.get(),
341 nat_->internal_udp_address(),
342 nat_->internal_tcp_address())) {
343 int_thread_->Start();
344 ext_thread_->Start();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000345 }
deadbeefc5d0d952015-07-16 10:22:21 -0700346
Yves Gerey665174f2018-06-19 15:03:05 +0200347 void OnConnectEvent(AsyncSocket* socket) { connected_ = true; }
deadbeefc5d0d952015-07-16 10:22:21 -0700348
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000349 void OnAcceptEvent(AsyncSocket* socket) {
deadbeef37f5ecf2017-02-27 14:06:41 -0800350 accepted_.reset(server_->Accept(nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000351 }
deadbeefc5d0d952015-07-16 10:22:21 -0700352
Yves Gerey665174f2018-06-19 15:03:05 +0200353 void OnCloseEvent(AsyncSocket* socket, int error) {}
deadbeefc5d0d952015-07-16 10:22:21 -0700354
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000355 void ConnectEvents() {
356 server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
357 client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
358 }
deadbeefc5d0d952015-07-16 10:22:21 -0700359
360 SocketAddress int_addr_;
361 SocketAddress ext_addr_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000362 bool connected_;
jbauch555604a2016-04-26 03:13:22 -0700363 std::unique_ptr<TestVirtualSocketServer> int_vss_;
364 std::unique_ptr<TestVirtualSocketServer> ext_vss_;
365 std::unique_ptr<Thread> int_thread_;
366 std::unique_ptr<Thread> ext_thread_;
367 std::unique_ptr<NATServer> nat_;
368 std::unique_ptr<NATSocketFactory> natsf_;
369 std::unique_ptr<AsyncSocket> client_;
370 std::unique_ptr<AsyncSocket> server_;
371 std::unique_ptr<AsyncSocket> accepted_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000372};
373
magjed65eb1c32015-07-22 06:28:26 -0700374TEST_F(NatTcpTest, DISABLED_TestConnectOut) {
Steve Anton31e5bf52018-05-07 10:42:55 -0700375 server_.reset(ext_vss_->CreateAsyncSocket(AF_INET, SOCK_STREAM));
deadbeefc5d0d952015-07-16 10:22:21 -0700376 server_->Bind(ext_addr_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000377 server_->Listen(5);
378
Steve Anton31e5bf52018-05-07 10:42:55 -0700379 client_.reset(natsf_->CreateAsyncSocket(AF_INET, SOCK_STREAM));
deadbeefc5d0d952015-07-16 10:22:21 -0700380 EXPECT_GE(0, client_->Bind(int_addr_));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000381 EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
382
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000383 ConnectEvents();
384
385 EXPECT_TRUE_WAIT(connected_, 1000);
386 EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
deadbeefc5d0d952015-07-16 10:22:21 -0700387 EXPECT_EQ(accepted_->GetRemoteAddress().ipaddr(), ext_addr_.ipaddr());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000388
jbauch555604a2016-04-26 03:13:22 -0700389 std::unique_ptr<rtc::TestClient> in(CreateTCPTestClient(client_.release()));
390 std::unique_ptr<rtc::TestClient> out(
deadbeefc5d0d952015-07-16 10:22:21 -0700391 CreateTCPTestClient(accepted_.release()));
392
393 const char* buf = "test_packet";
394 size_t len = strlen(buf);
395
396 in->Send(buf, len);
397 SocketAddress trans_addr;
398 EXPECT_TRUE(out->CheckNextPacket(buf, len, &trans_addr));
399
400 out->Send(buf, len);
401 EXPECT_TRUE(in->CheckNextPacket(buf, len, &trans_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000402}
deadbeefc5d0d952015-07-16 10:22:21 -0700403// #endif