1 /*
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
11 #include "rtc_base/physical_socket_server.h"
12
13 #include <signal.h>
14
15 #include <algorithm>
16 #include <memory>
17
18 #include "rtc_base/gunit.h"
19 #include "rtc_base/ip_address.h"
20 #include "rtc_base/logging.h"
21 #include "rtc_base/network_monitor.h"
22 #include "rtc_base/socket_unittest.h"
23 #include "rtc_base/test_utils.h"
24 #include "rtc_base/thread.h"
25 #include "test/gtest.h"
26
27 namespace rtc {
28
29 #define MAYBE_SKIP_IPV4 \
30 if (!HasIPv4Enabled()) { \
31 RTC_LOG(LS_INFO) << "No IPv4... skipping"; \
32 return; \
33 }
34
35 #define MAYBE_SKIP_IPV6 \
36 if (!HasIPv6Enabled()) { \
37 RTC_LOG(LS_INFO) << "No IPv6... skipping"; \
38 return; \
39 }
40
41 class PhysicalSocketTest;
42
43 class FakeSocketDispatcher : public SocketDispatcher {
44 public:
FakeSocketDispatcher(PhysicalSocketServer * ss)45 explicit FakeSocketDispatcher(PhysicalSocketServer* ss)
46 : SocketDispatcher(ss) {}
47
FakeSocketDispatcher(SOCKET s,PhysicalSocketServer * ss)48 FakeSocketDispatcher(SOCKET s, PhysicalSocketServer* ss)
49 : SocketDispatcher(s, ss) {}
50
51 protected:
52 SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override;
53 int DoSend(SOCKET socket, const char* buf, int len, int flags) override;
54 int DoSendTo(SOCKET socket,
55 const char* buf,
56 int len,
57 int flags,
58 const struct sockaddr* dest_addr,
59 socklen_t addrlen) override;
60 };
61
62 class FakePhysicalSocketServer : public PhysicalSocketServer {
63 public:
FakePhysicalSocketServer(PhysicalSocketTest * test)64 explicit FakePhysicalSocketServer(PhysicalSocketTest* test) : test_(test) {}
65
CreateAsyncSocket(int family,int type)66 AsyncSocket* CreateAsyncSocket(int family, int type) override {
67 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
68 if (!dispatcher->Create(family, type)) {
69 delete dispatcher;
70 return nullptr;
71 }
72 return dispatcher;
73 }
74
WrapSocket(SOCKET s)75 AsyncSocket* WrapSocket(SOCKET s) override {
76 SocketDispatcher* dispatcher = new FakeSocketDispatcher(s, this);
77 if (!dispatcher->Initialize()) {
78 delete dispatcher;
79 return nullptr;
80 }
81 return dispatcher;
82 }
83
GetTest() const84 PhysicalSocketTest* GetTest() const { return test_; }
85
86 private:
87 PhysicalSocketTest* test_;
88 };
89
90 class FakeNetworkBinder : public NetworkBinderInterface {
91 public:
BindSocketToNetwork(int,const IPAddress &)92 NetworkBindingResult BindSocketToNetwork(int, const IPAddress&) override {
93 ++num_binds_;
94 return result_;
95 }
96
set_result(NetworkBindingResult result)97 void set_result(NetworkBindingResult result) { result_ = result; }
98
num_binds()99 int num_binds() { return num_binds_; }
100
101 private:
102 NetworkBindingResult result_ = NetworkBindingResult::SUCCESS;
103 int num_binds_ = 0;
104 };
105
106 class PhysicalSocketTest : public SocketTest {
107 public:
108 // Set flag to simluate failures when calling "::accept" on a AsyncSocket.
SetFailAccept(bool fail)109 void SetFailAccept(bool fail) { fail_accept_ = fail; }
FailAccept() const110 bool FailAccept() const { return fail_accept_; }
111
112 // Maximum size to ::send to a socket. Set to < 0 to disable limiting.
SetMaxSendSize(int max_size)113 void SetMaxSendSize(int max_size) { max_send_size_ = max_size; }
MaxSendSize() const114 int MaxSendSize() const { return max_send_size_; }
115
116 protected:
PhysicalSocketTest()117 PhysicalSocketTest()
118 : server_(new FakePhysicalSocketServer(this)),
119 thread_(server_.get()),
120 fail_accept_(false),
121 max_send_size_(-1) {}
122
123 void ConnectInternalAcceptError(const IPAddress& loopback);
124 void WritableAfterPartialWrite(const IPAddress& loopback);
125
126 std::unique_ptr<FakePhysicalSocketServer> server_;
127 rtc::AutoSocketServerThread thread_;
128 bool fail_accept_;
129 int max_send_size_;
130 };
131
DoAccept(SOCKET socket,sockaddr * addr,socklen_t * addrlen)132 SOCKET FakeSocketDispatcher::DoAccept(SOCKET socket,
133 sockaddr* addr,
134 socklen_t* addrlen) {
135 FakePhysicalSocketServer* ss =
136 static_cast<FakePhysicalSocketServer*>(socketserver());
137 if (ss->GetTest()->FailAccept()) {
138 return INVALID_SOCKET;
139 }
140
141 return SocketDispatcher::DoAccept(socket, addr, addrlen);
142 }
143
DoSend(SOCKET socket,const char * buf,int len,int flags)144 int FakeSocketDispatcher::DoSend(SOCKET socket,
145 const char* buf,
146 int len,
147 int flags) {
148 FakePhysicalSocketServer* ss =
149 static_cast<FakePhysicalSocketServer*>(socketserver());
150 if (ss->GetTest()->MaxSendSize() >= 0) {
151 len = std::min(len, ss->GetTest()->MaxSendSize());
152 }
153
154 return SocketDispatcher::DoSend(socket, buf, len, flags);
155 }
156
DoSendTo(SOCKET socket,const char * buf,int len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)157 int FakeSocketDispatcher::DoSendTo(SOCKET socket,
158 const char* buf,
159 int len,
160 int flags,
161 const struct sockaddr* dest_addr,
162 socklen_t addrlen) {
163 FakePhysicalSocketServer* ss =
164 static_cast<FakePhysicalSocketServer*>(socketserver());
165 if (ss->GetTest()->MaxSendSize() >= 0) {
166 len = std::min(len, ss->GetTest()->MaxSendSize());
167 }
168
169 return SocketDispatcher::DoSendTo(socket, buf, len, flags, dest_addr,
170 addrlen);
171 }
172
TEST_F(PhysicalSocketTest,TestConnectIPv4)173 TEST_F(PhysicalSocketTest, TestConnectIPv4) {
174 MAYBE_SKIP_IPV4;
175 SocketTest::TestConnectIPv4();
176 }
177
TEST_F(PhysicalSocketTest,TestConnectIPv6)178 TEST_F(PhysicalSocketTest, TestConnectIPv6) {
179 SocketTest::TestConnectIPv6();
180 }
181
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupIPv4)182 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
183 MAYBE_SKIP_IPV4;
184 SocketTest::TestConnectWithDnsLookupIPv4();
185 }
186
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupIPv6)187 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
188 SocketTest::TestConnectWithDnsLookupIPv6();
189 }
190
TEST_F(PhysicalSocketTest,TestConnectFailIPv4)191 TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
192 MAYBE_SKIP_IPV4;
193 SocketTest::TestConnectFailIPv4();
194 }
195
ConnectInternalAcceptError(const IPAddress & loopback)196 void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) {
197 webrtc::testing::StreamSink sink;
198 SocketAddress accept_addr;
199
200 // Create two clients.
201 std::unique_ptr<AsyncSocket> client1(
202 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
203 sink.Monitor(client1.get());
204 EXPECT_EQ(AsyncSocket::CS_CLOSED, client1->GetState());
205 EXPECT_TRUE(IsUnspecOrEmptyIP(client1->GetLocalAddress().ipaddr()));
206
207 std::unique_ptr<AsyncSocket> client2(
208 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
209 sink.Monitor(client2.get());
210 EXPECT_EQ(AsyncSocket::CS_CLOSED, client2->GetState());
211 EXPECT_TRUE(IsUnspecOrEmptyIP(client2->GetLocalAddress().ipaddr()));
212
213 // Create server and listen.
214 std::unique_ptr<AsyncSocket> server(
215 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
216 sink.Monitor(server.get());
217 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
218 EXPECT_EQ(0, server->Listen(5));
219 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
220
221 // Ensure no pending server connections, since we haven't done anything yet.
222 EXPECT_FALSE(sink.Check(server.get(), webrtc::testing::SSE_READ));
223 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
224 EXPECT_TRUE(accept_addr.IsNil());
225
226 // Attempt first connect to listening socket.
227 EXPECT_EQ(0, client1->Connect(server->GetLocalAddress()));
228 EXPECT_FALSE(client1->GetLocalAddress().IsNil());
229 EXPECT_NE(server->GetLocalAddress(), client1->GetLocalAddress());
230
231 // Client is connecting, outcome not yet determined.
232 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client1->GetState());
233 EXPECT_FALSE(sink.Check(client1.get(), webrtc::testing::SSE_OPEN));
234 EXPECT_FALSE(sink.Check(client1.get(), webrtc::testing::SSE_CLOSE));
235
236 // Server has pending connection, try to accept it (will fail).
237 EXPECT_TRUE_WAIT((sink.Check(server.get(), webrtc::testing::SSE_READ)),
238 kTimeout);
239 // Simulate "::accept" returning an error.
240 SetFailAccept(true);
241 std::unique_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
242 EXPECT_FALSE(accepted);
243 ASSERT_TRUE(accept_addr.IsNil());
244
245 // Ensure no more pending server connections.
246 EXPECT_FALSE(sink.Check(server.get(), webrtc::testing::SSE_READ));
247 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
248 EXPECT_TRUE(accept_addr.IsNil());
249
250 // Attempt second connect to listening socket.
251 EXPECT_EQ(0, client2->Connect(server->GetLocalAddress()));
252 EXPECT_FALSE(client2->GetLocalAddress().IsNil());
253 EXPECT_NE(server->GetLocalAddress(), client2->GetLocalAddress());
254
255 // Client is connecting, outcome not yet determined.
256 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client2->GetState());
257 EXPECT_FALSE(sink.Check(client2.get(), webrtc::testing::SSE_OPEN));
258 EXPECT_FALSE(sink.Check(client2.get(), webrtc::testing::SSE_CLOSE));
259
260 // Server has pending connection, try to accept it (will succeed).
261 EXPECT_TRUE_WAIT((sink.Check(server.get(), webrtc::testing::SSE_READ)),
262 kTimeout);
263 SetFailAccept(false);
264 std::unique_ptr<AsyncSocket> accepted2(server->Accept(&accept_addr));
265 ASSERT_TRUE(accepted2);
266 EXPECT_FALSE(accept_addr.IsNil());
267 EXPECT_EQ(accepted2->GetRemoteAddress(), accept_addr);
268 }
269
TEST_F(PhysicalSocketTest,TestConnectAcceptErrorIPv4)270 TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv4) {
271 MAYBE_SKIP_IPV4;
272 ConnectInternalAcceptError(kIPv4Loopback);
273 }
274
TEST_F(PhysicalSocketTest,TestConnectAcceptErrorIPv6)275 TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv6) {
276 MAYBE_SKIP_IPV6;
277 ConnectInternalAcceptError(kIPv6Loopback);
278 }
279
WritableAfterPartialWrite(const IPAddress & loopback)280 void PhysicalSocketTest::WritableAfterPartialWrite(const IPAddress& loopback) {
281 // Simulate a really small maximum send size.
282 const int kMaxSendSize = 128;
283 SetMaxSendSize(kMaxSendSize);
284
285 // Run the default send/receive socket tests with a smaller amount of data
286 // to avoid long running times due to the small maximum send size.
287 const size_t kDataSize = 128 * 1024;
288 TcpInternal(loopback, kDataSize, kMaxSendSize);
289 }
290
291 // https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
292 #if defined(WEBRTC_WIN)
293 #define MAYBE_TestWritableAfterPartialWriteIPv4 \
294 DISABLED_TestWritableAfterPartialWriteIPv4
295 #else
296 #define MAYBE_TestWritableAfterPartialWriteIPv4 \
297 TestWritableAfterPartialWriteIPv4
298 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestWritableAfterPartialWriteIPv4)299 TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv4) {
300 MAYBE_SKIP_IPV4;
301 WritableAfterPartialWrite(kIPv4Loopback);
302 }
303
304 // https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
305 #if defined(WEBRTC_WIN)
306 #define MAYBE_TestWritableAfterPartialWriteIPv6 \
307 DISABLED_TestWritableAfterPartialWriteIPv6
308 #else
309 #define MAYBE_TestWritableAfterPartialWriteIPv6 \
310 TestWritableAfterPartialWriteIPv6
311 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestWritableAfterPartialWriteIPv6)312 TEST_F(PhysicalSocketTest, MAYBE_TestWritableAfterPartialWriteIPv6) {
313 MAYBE_SKIP_IPV6;
314 WritableAfterPartialWrite(kIPv6Loopback);
315 }
316
TEST_F(PhysicalSocketTest,TestConnectFailIPv6)317 TEST_F(PhysicalSocketTest, TestConnectFailIPv6) {
318 SocketTest::TestConnectFailIPv6();
319 }
320
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupFailIPv4)321 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
322 MAYBE_SKIP_IPV4;
323 SocketTest::TestConnectWithDnsLookupFailIPv4();
324 }
325
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupFailIPv6)326 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv6) {
327 SocketTest::TestConnectWithDnsLookupFailIPv6();
328 }
329
TEST_F(PhysicalSocketTest,TestConnectWithClosedSocketIPv4)330 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
331 MAYBE_SKIP_IPV4;
332 SocketTest::TestConnectWithClosedSocketIPv4();
333 }
334
TEST_F(PhysicalSocketTest,TestConnectWithClosedSocketIPv6)335 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv6) {
336 SocketTest::TestConnectWithClosedSocketIPv6();
337 }
338
TEST_F(PhysicalSocketTest,TestConnectWhileNotClosedIPv4)339 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
340 MAYBE_SKIP_IPV4;
341 SocketTest::TestConnectWhileNotClosedIPv4();
342 }
343
TEST_F(PhysicalSocketTest,TestConnectWhileNotClosedIPv6)344 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv6) {
345 SocketTest::TestConnectWhileNotClosedIPv6();
346 }
347
TEST_F(PhysicalSocketTest,TestServerCloseDuringConnectIPv4)348 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
349 MAYBE_SKIP_IPV4;
350 SocketTest::TestServerCloseDuringConnectIPv4();
351 }
352
TEST_F(PhysicalSocketTest,TestServerCloseDuringConnectIPv6)353 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv6) {
354 SocketTest::TestServerCloseDuringConnectIPv6();
355 }
356
TEST_F(PhysicalSocketTest,TestClientCloseDuringConnectIPv4)357 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
358 MAYBE_SKIP_IPV4;
359 SocketTest::TestClientCloseDuringConnectIPv4();
360 }
361
TEST_F(PhysicalSocketTest,TestClientCloseDuringConnectIPv6)362 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv6) {
363 SocketTest::TestClientCloseDuringConnectIPv6();
364 }
365
TEST_F(PhysicalSocketTest,TestServerCloseIPv4)366 TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
367 MAYBE_SKIP_IPV4;
368 SocketTest::TestServerCloseIPv4();
369 }
370
TEST_F(PhysicalSocketTest,TestServerCloseIPv6)371 TEST_F(PhysicalSocketTest, TestServerCloseIPv6) {
372 SocketTest::TestServerCloseIPv6();
373 }
374
TEST_F(PhysicalSocketTest,TestCloseInClosedCallbackIPv4)375 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
376 MAYBE_SKIP_IPV4;
377 SocketTest::TestCloseInClosedCallbackIPv4();
378 }
379
TEST_F(PhysicalSocketTest,TestCloseInClosedCallbackIPv6)380 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv6) {
381 SocketTest::TestCloseInClosedCallbackIPv6();
382 }
383
TEST_F(PhysicalSocketTest,TestDeleteInReadCallbackIPv4)384 TEST_F(PhysicalSocketTest, TestDeleteInReadCallbackIPv4) {
385 MAYBE_SKIP_IPV4;
386 SocketTest::TestDeleteInReadCallbackIPv4();
387 }
388
TEST_F(PhysicalSocketTest,TestDeleteInReadCallbackIPv6)389 TEST_F(PhysicalSocketTest, TestDeleteInReadCallbackIPv6) {
390 SocketTest::TestDeleteInReadCallbackIPv6();
391 }
392
TEST_F(PhysicalSocketTest,TestSocketServerWaitIPv4)393 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
394 MAYBE_SKIP_IPV4;
395 SocketTest::TestSocketServerWaitIPv4();
396 }
397
TEST_F(PhysicalSocketTest,TestSocketServerWaitIPv6)398 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv6) {
399 SocketTest::TestSocketServerWaitIPv6();
400 }
401
TEST_F(PhysicalSocketTest,TestTcpIPv4)402 TEST_F(PhysicalSocketTest, TestTcpIPv4) {
403 MAYBE_SKIP_IPV4;
404 SocketTest::TestTcpIPv4();
405 }
406
TEST_F(PhysicalSocketTest,TestTcpIPv6)407 TEST_F(PhysicalSocketTest, TestTcpIPv6) {
408 SocketTest::TestTcpIPv6();
409 }
410
TEST_F(PhysicalSocketTest,TestUdpIPv4)411 TEST_F(PhysicalSocketTest, TestUdpIPv4) {
412 MAYBE_SKIP_IPV4;
413 SocketTest::TestUdpIPv4();
414 }
415
TEST_F(PhysicalSocketTest,TestUdpIPv6)416 TEST_F(PhysicalSocketTest, TestUdpIPv6) {
417 SocketTest::TestUdpIPv6();
418 }
419
420 // Disable for TSan v2, see
421 // https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
422 // Also disable for MSan, see:
423 // https://code.google.com/p/webrtc/issues/detail?id=4958
424 // TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
425 // Also disable for ASan.
426 // Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
427 // Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233
428 #if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
429 defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) || \
430 defined(WEBRTC_LINUX)
431 #define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
432 #else
433 #define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
434 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestUdpReadyToSendIPv4)435 TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
436 MAYBE_SKIP_IPV4;
437 SocketTest::TestUdpReadyToSendIPv4();
438 }
439
440 // https://bugs.chromium.org/p/webrtc/issues/detail?id=6167
441 #if defined(WEBRTC_WIN)
442 #define MAYBE_TestUdpReadyToSendIPv6 DISABLED_TestUdpReadyToSendIPv6
443 #else
444 #define MAYBE_TestUdpReadyToSendIPv6 TestUdpReadyToSendIPv6
445 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestUdpReadyToSendIPv6)446 TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv6) {
447 SocketTest::TestUdpReadyToSendIPv6();
448 }
449
TEST_F(PhysicalSocketTest,TestGetSetOptionsIPv4)450 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
451 MAYBE_SKIP_IPV4;
452 SocketTest::TestGetSetOptionsIPv4();
453 }
454
TEST_F(PhysicalSocketTest,TestGetSetOptionsIPv6)455 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
456 SocketTest::TestGetSetOptionsIPv6();
457 }
458
459 #if defined(WEBRTC_POSIX)
460
461 // We don't get recv timestamps on Mac.
462 #if !defined(WEBRTC_MAC)
TEST_F(PhysicalSocketTest,TestSocketRecvTimestampIPv4)463 TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv4) {
464 MAYBE_SKIP_IPV4;
465 SocketTest::TestSocketRecvTimestampIPv4();
466 }
467
TEST_F(PhysicalSocketTest,TestSocketRecvTimestampIPv6)468 TEST_F(PhysicalSocketTest, TestSocketRecvTimestampIPv6) {
469 SocketTest::TestSocketRecvTimestampIPv6();
470 }
471 #endif
472
473 // Verify that if the socket was unable to be bound to a real network interface
474 // (not loopback), Bind will return an error.
TEST_F(PhysicalSocketTest,BindFailsIfNetworkBinderFailsForNonLoopbackInterface)475 TEST_F(PhysicalSocketTest,
476 BindFailsIfNetworkBinderFailsForNonLoopbackInterface) {
477 MAYBE_SKIP_IPV4;
478 FakeNetworkBinder fake_network_binder;
479 server_->set_network_binder(&fake_network_binder);
480 std::unique_ptr<AsyncSocket> socket(
481 server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM));
482 fake_network_binder.set_result(NetworkBindingResult::FAILURE);
483 EXPECT_EQ(-1, socket->Bind(SocketAddress("192.168.0.1", 0)));
484 server_->set_network_binder(nullptr);
485 }
486
487 // Network binder shouldn't be used if the socket is bound to the "any" IP.
TEST_F(PhysicalSocketTest,NetworkBinderIsNotUsedForAnyIp)488 TEST_F(PhysicalSocketTest, NetworkBinderIsNotUsedForAnyIp) {
489 MAYBE_SKIP_IPV4;
490 FakeNetworkBinder fake_network_binder;
491 server_->set_network_binder(&fake_network_binder);
492 std::unique_ptr<AsyncSocket> socket(
493 server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM));
494 EXPECT_EQ(0, socket->Bind(SocketAddress("0.0.0.0", 0)));
495 EXPECT_EQ(0, fake_network_binder.num_binds());
496 server_->set_network_binder(nullptr);
497 }
498
499 // For a loopback interface, failures to bind to the interface should be
500 // tolerated.
TEST_F(PhysicalSocketTest,BindSucceedsIfNetworkBinderFailsForLoopbackInterface)501 TEST_F(PhysicalSocketTest,
502 BindSucceedsIfNetworkBinderFailsForLoopbackInterface) {
503 MAYBE_SKIP_IPV4;
504 FakeNetworkBinder fake_network_binder;
505 server_->set_network_binder(&fake_network_binder);
506 std::unique_ptr<AsyncSocket> socket(
507 server_->CreateAsyncSocket(AF_INET, SOCK_DGRAM));
508 fake_network_binder.set_result(NetworkBindingResult::FAILURE);
509 EXPECT_EQ(0, socket->Bind(SocketAddress(kIPv4Loopback, 0)));
510 server_->set_network_binder(nullptr);
511 }
512
513 #endif
514
515 } // namespace rtc
516