blob: e757bfda972377b91c13eeb69caaf97167873511 [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>
Jonas Olssona4d87372019-07-05 19:08:33 +020012
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -080013#include <algorithm>
jbauch555604a2016-04-26 03:13:22 -070014#include <memory>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000015#include <string>
Yves Gerey3e707812018-11-28 16:47:49 +010016#include <vector>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017
Karl Wiberg918f50c2018-07-05 11:40:33 +020018#include "absl/memory/memory.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "rtc_base/async_packet_socket.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "rtc_base/async_tcp_socket.h"
21#include "rtc_base/async_udp_socket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/ip_address.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/nat_server.h"
26#include "rtc_base/nat_socket_factory.h"
27#include "rtc_base/nat_types.h"
28#include "rtc_base/net_helpers.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/network.h"
Steve Anton10542f22019-01-11 09:11:00 -080030#include "rtc_base/physical_socket_server.h"
Niels Möllerd0b88792021-08-12 10:32:30 +020031#include "rtc_base/socket.h"
Steve Anton10542f22019-01-11 09:11:00 -080032#include "rtc_base/socket_address.h"
33#include "rtc_base/socket_factory.h"
34#include "rtc_base/socket_server.h"
35#include "rtc_base/test_client.h"
Yves Gerey3e707812018-11-28 16:47:49 +010036#include "rtc_base/third_party/sigslot/sigslot.h"
37#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080038#include "rtc_base/virtual_socket_server.h"
Yves Gerey3e707812018-11-28 16:47:49 +010039#include "test/gtest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000040
Mirko Bonadeie10b1632018-12-11 18:43:40 +010041namespace rtc {
42namespace {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000043
Yves Gerey665174f2018-06-19 15:03:05 +020044bool CheckReceive(TestClient* client,
45 bool should_receive,
46 const char* buf,
47 size_t size) {
48 return (should_receive) ? client->CheckNextPacket(buf, size, 0)
49 : client->CheckNoPacket();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000050}
51
Yves Gerey665174f2018-06-19 15:03:05 +020052TestClient* CreateTestClient(SocketFactory* factory,
53 const SocketAddress& local_addr) {
nisse32f25052017-05-08 01:57:18 -070054 return new TestClient(
Karl Wiberg918f50c2018-07-05 11:40:33 +020055 absl::WrapUnique(AsyncUDPSocket::Create(factory, local_addr)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000056}
57
Niels Möllerd0b88792021-08-12 10:32:30 +020058TestClient* CreateTCPTestClient(Socket* socket) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020059 return new TestClient(std::make_unique<AsyncTCPSocket>(socket, false));
deadbeefc5d0d952015-07-16 10:22:21 -070060}
61
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000062// Tests that when sending from internal_addr to external_addrs through the
63// NAT type specified by nat_type, all external addrs receive the sent packet
64// and, if exp_same is true, all use the same mapped-address on the NAT.
Yves Gerey665174f2018-06-19 15:03:05 +020065void TestSend(SocketServer* internal,
66 const SocketAddress& internal_addr,
67 SocketServer* external,
68 const SocketAddress external_addrs[4],
69 NATType nat_type,
70 bool exp_same) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000071 Thread th_int(internal);
72 Thread th_ext(external);
73
74 SocketAddress server_addr = internal_addr;
75 server_addr.SetPort(0); // Auto-select a port
deadbeefc5d0d952015-07-16 10:22:21 -070076 NATServer* nat = new NATServer(nat_type, internal, server_addr, server_addr,
77 external, external_addrs[0]);
Yves Gerey665174f2018-06-19 15:03:05 +020078 NATSocketFactory* natsf = new NATSocketFactory(
79 internal, nat->internal_udp_address(), nat->internal_tcp_address());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000080
81 TestClient* in = CreateTestClient(natsf, internal_addr);
82 TestClient* out[4];
83 for (int i = 0; i < 4; i++)
84 out[i] = CreateTestClient(external, external_addrs[i]);
85
86 th_int.Start();
87 th_ext.Start();
88
89 const char* buf = "filter_test";
90 size_t len = strlen(buf);
91
92 in->SendTo(buf, len, out[0]->address());
93 SocketAddress trans_addr;
94 EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
95
96 for (int i = 1; i < 4; i++) {
97 in->SendTo(buf, len, out[i]->address());
98 SocketAddress trans_addr2;
99 EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2));
100 bool are_same = (trans_addr == trans_addr2);
101 ASSERT_EQ(are_same, exp_same) << "same translated address";
102 ASSERT_NE(AF_UNSPEC, trans_addr.family());
103 ASSERT_NE(AF_UNSPEC, trans_addr2.family());
104 }
105
106 th_int.Stop();
107 th_ext.Stop();
108
109 delete nat;
110 delete natsf;
111 delete in;
112 for (int i = 0; i < 4; i++)
113 delete out[i];
114}
115
116// Tests that when sending from external_addrs to internal_addr, the packet
117// is delivered according to the specified filter_ip and filter_port rules.
Yves Gerey665174f2018-06-19 15:03:05 +0200118void TestRecv(SocketServer* internal,
119 const SocketAddress& internal_addr,
120 SocketServer* external,
121 const SocketAddress external_addrs[4],
122 NATType nat_type,
123 bool filter_ip,
124 bool filter_port) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000125 Thread th_int(internal);
126 Thread th_ext(external);
127
128 SocketAddress server_addr = internal_addr;
129 server_addr.SetPort(0); // Auto-select a port
deadbeefc5d0d952015-07-16 10:22:21 -0700130 NATServer* nat = new NATServer(nat_type, internal, server_addr, server_addr,
131 external, external_addrs[0]);
Yves Gerey665174f2018-06-19 15:03:05 +0200132 NATSocketFactory* natsf = new NATSocketFactory(
133 internal, nat->internal_udp_address(), nat->internal_tcp_address());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000134
135 TestClient* in = CreateTestClient(natsf, internal_addr);
136 TestClient* out[4];
137 for (int i = 0; i < 4; i++)
138 out[i] = CreateTestClient(external, external_addrs[i]);
139
140 th_int.Start();
141 th_ext.Start();
142
143 const char* buf = "filter_test";
144 size_t len = strlen(buf);
145
146 in->SendTo(buf, len, out[0]->address());
147 SocketAddress trans_addr;
148 EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
149
150 out[1]->SendTo(buf, len, trans_addr);
151 EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len));
152
153 out[2]->SendTo(buf, len, trans_addr);
154 EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len));
155
156 out[3]->SendTo(buf, len, trans_addr);
157 EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len));
158
159 th_int.Stop();
160 th_ext.Stop();
161
162 delete nat;
163 delete natsf;
164 delete in;
165 for (int i = 0; i < 4; i++)
166 delete out[i];
167}
168
169// Tests that NATServer allocates bindings properly.
Yves Gerey665174f2018-06-19 15:03:05 +0200170void TestBindings(SocketServer* internal,
171 const SocketAddress& internal_addr,
172 SocketServer* external,
173 const SocketAddress external_addrs[4]) {
174 TestSend(internal, internal_addr, external, external_addrs, NAT_OPEN_CONE,
175 true);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000176 TestSend(internal, internal_addr, external, external_addrs,
177 NAT_ADDR_RESTRICTED, true);
178 TestSend(internal, internal_addr, external, external_addrs,
179 NAT_PORT_RESTRICTED, true);
Yves Gerey665174f2018-06-19 15:03:05 +0200180 TestSend(internal, internal_addr, external, external_addrs, NAT_SYMMETRIC,
181 false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000182}
183
184// Tests that NATServer filters packets properly.
Yves Gerey665174f2018-06-19 15:03:05 +0200185void TestFilters(SocketServer* internal,
186 const SocketAddress& internal_addr,
187 SocketServer* external,
188 const SocketAddress external_addrs[4]) {
189 TestRecv(internal, internal_addr, external, external_addrs, NAT_OPEN_CONE,
190 false, false);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000191 TestRecv(internal, internal_addr, external, external_addrs,
192 NAT_ADDR_RESTRICTED, true, false);
193 TestRecv(internal, internal_addr, external, external_addrs,
194 NAT_PORT_RESTRICTED, true, true);
Yves Gerey665174f2018-06-19 15:03:05 +0200195 TestRecv(internal, internal_addr, external, external_addrs, NAT_SYMMETRIC,
196 true, true);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000197}
198
199bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) {
200 // The physical NAT tests require connectivity to the selected ip from the
201 // internal address used for the NAT. Things like firewalls can break that, so
202 // check to see if it's worth even trying with this ip.
jbauch555604a2016-04-26 03:13:22 -0700203 std::unique_ptr<PhysicalSocketServer> pss(new PhysicalSocketServer());
Niels Möllerd0b88792021-08-12 10:32:30 +0200204 std::unique_ptr<Socket> client(pss->CreateSocket(src.family(), SOCK_DGRAM));
205 std::unique_ptr<Socket> server(pss->CreateSocket(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;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000223 network_manager.StartUpdating();
224 // Process pending messages so the network list is updated.
225 Thread::Current()->ProcessMessages(0);
226
227 std::vector<Network*> networks;
228 network_manager.GetNetworks(&networks);
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800229 networks.erase(std::remove_if(networks.begin(), networks.end(),
230 [](rtc::Network* network) {
231 return rtc::kDefaultNetworkIgnoreMask &
232 network->type();
233 }),
234 networks.end());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000235 if (networks.empty()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100236 RTC_LOG(LS_WARNING) << "Not enough network adapters for test.";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000237 return;
238 }
239
240 SocketAddress ext_addr1(int_addr);
241 SocketAddress ext_addr2;
242 // Find an available IP with matching family. The test breaks if int_addr
243 // can't talk to ip, so check for connectivity as well.
244 for (std::vector<Network*>::iterator it = networks.begin();
Yves Gerey665174f2018-06-19 15:03:05 +0200245 it != networks.end(); ++it) {
guoweis@webrtc.org369a6372014-09-17 22:37:29 +0000246 const IPAddress& ip = (*it)->GetBestIP();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000247 if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) {
248 ext_addr2.SetIP(ip);
249 break;
250 }
251 }
252 if (ext_addr2.IsNil()) {
Jonas Olssonabbe8412018-04-03 13:40:05 +0200253 RTC_LOG(LS_WARNING) << "No available IP of same family as "
254 << int_addr.ToString();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000255 return;
256 }
257
Jonas Olssonabbe8412018-04-03 13:40:05 +0200258 RTC_LOG(LS_INFO) << "selected ip " << ext_addr2.ipaddr().ToString();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000259
260 SocketAddress ext_addrs[4] = {
Yves Gerey665174f2018-06-19 15:03:05 +0200261 SocketAddress(ext_addr1), SocketAddress(ext_addr2),
262 SocketAddress(ext_addr1), SocketAddress(ext_addr2)};
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000263
jbauch555604a2016-04-26 03:13:22 -0700264 std::unique_ptr<PhysicalSocketServer> int_pss(new PhysicalSocketServer());
265 std::unique_ptr<PhysicalSocketServer> ext_pss(new PhysicalSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000266
267 TestBindings(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
268 TestFilters(int_pss.get(), int_addr, ext_pss.get(), ext_addrs);
269}
270
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000271TEST(NatTest, TestPhysicalIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000272 TestPhysicalInternal(SocketAddress("127.0.0.1", 0));
273}
274
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000275TEST(NatTest, TestPhysicalIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000276 if (HasIPv6Enabled()) {
277 TestPhysicalInternal(SocketAddress("::1", 0));
278 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100279 RTC_LOG(LS_WARNING) << "No IPv6, skipping";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000280 }
281}
282
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700283namespace {
284
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000285class TestVirtualSocketServer : public VirtualSocketServer {
286 public:
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000287 // Expose this publicly
288 IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000289};
290
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700291} // namespace
292
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000293void TestVirtualInternal(int family) {
jbauch555604a2016-04-26 03:13:22 -0700294 std::unique_ptr<TestVirtualSocketServer> int_vss(
deadbeef98e186c2017-05-16 18:00:06 -0700295 new TestVirtualSocketServer());
jbauch555604a2016-04-26 03:13:22 -0700296 std::unique_ptr<TestVirtualSocketServer> ext_vss(
deadbeef98e186c2017-05-16 18:00:06 -0700297 new TestVirtualSocketServer());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000298
299 SocketAddress int_addr;
300 SocketAddress ext_addrs[4];
301 int_addr.SetIP(int_vss->GetNextIP(family));
302 ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.family()));
303 ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.family()));
304 ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
305 ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
306
307 TestBindings(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
308 TestFilters(int_vss.get(), int_addr, ext_vss.get(), ext_addrs);
309}
310
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000311TEST(NatTest, TestVirtualIPv4) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000312 TestVirtualInternal(AF_INET);
313}
314
henrike@webrtc.orgc732a3e2014-10-09 22:08:15 +0000315TEST(NatTest, TestVirtualIPv6) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000316 if (HasIPv6Enabled()) {
317 TestVirtualInternal(AF_INET6);
318 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100319 RTC_LOG(LS_WARNING) << "No IPv6, skipping";
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000320 }
321}
322
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200323class NatTcpTest : public ::testing::Test, public sigslot::has_slots<> {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000324 public:
deadbeefc5d0d952015-07-16 10:22:21 -0700325 NatTcpTest()
326 : int_addr_("192.168.0.1", 0),
327 ext_addr_("10.0.0.1", 0),
328 connected_(false),
deadbeef98e186c2017-05-16 18:00:06 -0700329 int_vss_(new TestVirtualSocketServer()),
330 ext_vss_(new TestVirtualSocketServer()),
deadbeefc5d0d952015-07-16 10:22:21 -0700331 int_thread_(new Thread(int_vss_.get())),
332 ext_thread_(new Thread(ext_vss_.get())),
deadbeef98e186c2017-05-16 18:00:06 -0700333 nat_(new NATServer(NAT_OPEN_CONE,
334 int_vss_.get(),
335 int_addr_,
336 int_addr_,
337 ext_vss_.get(),
338 ext_addr_)),
deadbeefc5d0d952015-07-16 10:22:21 -0700339 natsf_(new NATSocketFactory(int_vss_.get(),
340 nat_->internal_udp_address(),
341 nat_->internal_tcp_address())) {
342 int_thread_->Start();
343 ext_thread_->Start();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000344 }
deadbeefc5d0d952015-07-16 10:22:21 -0700345
Niels Möllerd0b88792021-08-12 10:32:30 +0200346 void OnConnectEvent(Socket* socket) { connected_ = true; }
deadbeefc5d0d952015-07-16 10:22:21 -0700347
Niels Möllerd0b88792021-08-12 10:32:30 +0200348 void OnAcceptEvent(Socket* socket) {
deadbeef37f5ecf2017-02-27 14:06:41 -0800349 accepted_.reset(server_->Accept(nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000350 }
deadbeefc5d0d952015-07-16 10:22:21 -0700351
Niels Möllerd0b88792021-08-12 10:32:30 +0200352 void OnCloseEvent(Socket* socket, int error) {}
deadbeefc5d0d952015-07-16 10:22:21 -0700353
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000354 void ConnectEvents() {
355 server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
356 client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
357 }
deadbeefc5d0d952015-07-16 10:22:21 -0700358
359 SocketAddress int_addr_;
360 SocketAddress ext_addr_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000361 bool connected_;
jbauch555604a2016-04-26 03:13:22 -0700362 std::unique_ptr<TestVirtualSocketServer> int_vss_;
363 std::unique_ptr<TestVirtualSocketServer> ext_vss_;
364 std::unique_ptr<Thread> int_thread_;
365 std::unique_ptr<Thread> ext_thread_;
366 std::unique_ptr<NATServer> nat_;
367 std::unique_ptr<NATSocketFactory> natsf_;
Niels Möllerd0b88792021-08-12 10:32:30 +0200368 std::unique_ptr<Socket> client_;
369 std::unique_ptr<Socket> server_;
370 std::unique_ptr<Socket> accepted_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000371};
372
magjed65eb1c32015-07-22 06:28:26 -0700373TEST_F(NatTcpTest, DISABLED_TestConnectOut) {
Niels Möllerd0b88792021-08-12 10:32:30 +0200374 server_.reset(ext_vss_->CreateSocket(AF_INET, SOCK_STREAM));
deadbeefc5d0d952015-07-16 10:22:21 -0700375 server_->Bind(ext_addr_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000376 server_->Listen(5);
377
Niels Möllerd0b88792021-08-12 10:32:30 +0200378 client_.reset(natsf_->CreateSocket(AF_INET, SOCK_STREAM));
deadbeefc5d0d952015-07-16 10:22:21 -0700379 EXPECT_GE(0, client_->Bind(int_addr_));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000380 EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
381
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000382 ConnectEvents();
383
384 EXPECT_TRUE_WAIT(connected_, 1000);
385 EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
deadbeefc5d0d952015-07-16 10:22:21 -0700386 EXPECT_EQ(accepted_->GetRemoteAddress().ipaddr(), ext_addr_.ipaddr());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000387
jbauch555604a2016-04-26 03:13:22 -0700388 std::unique_ptr<rtc::TestClient> in(CreateTCPTestClient(client_.release()));
389 std::unique_ptr<rtc::TestClient> out(
deadbeefc5d0d952015-07-16 10:22:21 -0700390 CreateTCPTestClient(accepted_.release()));
391
392 const char* buf = "test_packet";
393 size_t len = strlen(buf);
394
395 in->Send(buf, len);
396 SocketAddress trans_addr;
397 EXPECT_TRUE(out->CheckNextPacket(buf, len, &trans_addr));
398
399 out->Send(buf, len);
400 EXPECT_TRUE(in->CheckNextPacket(buf, len, &trans_addr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000401}
Mirko Bonadeie10b1632018-12-11 18:43:40 +0100402
403} // namespace
404} // namespace rtc