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