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 <signal.h>
12#include <stdarg.h>
13
14#include "webrtc/base/gunit.h"
15#include "webrtc/base/logging.h"
16#include "webrtc/base/physicalsocketserver.h"
17#include "webrtc/base/scoped_ptr.h"
18#include "webrtc/base/socket_unittest.h"
19#include "webrtc/base/testutils.h"
20#include "webrtc/base/thread.h"
21
22namespace rtc {
23
24class PhysicalSocketTest;
25
26class FakeSocketDispatcher : public SocketDispatcher {
27 public:
28  explicit FakeSocketDispatcher(PhysicalSocketServer* ss)
29    : SocketDispatcher(ss) {
30  }
31
32 protected:
33  SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override;
34};
35
36class FakePhysicalSocketServer : public PhysicalSocketServer {
37 public:
38  explicit FakePhysicalSocketServer(PhysicalSocketTest* test)
39    : test_(test) {
40  }
41
42  AsyncSocket* CreateAsyncSocket(int type) override {
43    SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
44    if (dispatcher->Create(type)) {
45      return dispatcher;
46    } else {
47      delete dispatcher;
48      return nullptr;
49    }
50  }
51
52  AsyncSocket* CreateAsyncSocket(int family, int type) override {
53    SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
54    if (dispatcher->Create(family, type)) {
55      return dispatcher;
56    } else {
57      delete dispatcher;
58      return nullptr;
59    }
60  }
61
62  PhysicalSocketTest* GetTest() const { return test_; }
63
64 private:
65  PhysicalSocketTest* test_;
66};
67
68class PhysicalSocketTest : public SocketTest {
69 public:
70  // Set flag to simluate failures when calling "::accept" on a AsyncSocket.
71  void SetFailAccept(bool fail) { fail_accept_ = fail; }
72  bool FailAccept() const { return fail_accept_; }
73
74 protected:
75  PhysicalSocketTest()
76    : server_(new FakePhysicalSocketServer(this)),
77      scope_(server_.get()),
78      fail_accept_(false) {
79  }
80
81  void ConnectInternalAcceptError(const IPAddress& loopback);
82
83  rtc::scoped_ptr<FakePhysicalSocketServer> server_;
84  SocketServerScope scope_;
85  bool fail_accept_;
86};
87
88SOCKET FakeSocketDispatcher::DoAccept(SOCKET socket,
89                                      sockaddr* addr,
90                                      socklen_t* addrlen) {
91  FakePhysicalSocketServer* ss =
92      static_cast<FakePhysicalSocketServer*>(socketserver());
93  if (ss->GetTest()->FailAccept()) {
94    return INVALID_SOCKET;
95  }
96
97  return SocketDispatcher::DoAccept(socket, addr, addrlen);
98}
99
100TEST_F(PhysicalSocketTest, TestConnectIPv4) {
101  SocketTest::TestConnectIPv4();
102}
103
104// Crashes on Linux. See webrtc:4923.
105#if defined(WEBRTC_LINUX)
106#define MAYBE_TestConnectIPv6 DISABLED_TestConnectIPv6
107#else
108#define MAYBE_TestConnectIPv6 TestConnectIPv6
109#endif
110TEST_F(PhysicalSocketTest, MAYBE_TestConnectIPv6) {
111  SocketTest::TestConnectIPv6();
112}
113
114TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
115  SocketTest::TestConnectWithDnsLookupIPv4();
116}
117
118TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
119  SocketTest::TestConnectWithDnsLookupIPv6();
120}
121
122TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
123  SocketTest::TestConnectFailIPv4();
124}
125
126void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) {
127  testing::StreamSink sink;
128  SocketAddress accept_addr;
129
130  // Create two clients.
131  scoped_ptr<AsyncSocket> client1(server_->CreateAsyncSocket(loopback.family(),
132                                                             SOCK_STREAM));
133  sink.Monitor(client1.get());
134  EXPECT_EQ(AsyncSocket::CS_CLOSED, client1->GetState());
135  EXPECT_PRED1(IsUnspecOrEmptyIP, client1->GetLocalAddress().ipaddr());
136
137  scoped_ptr<AsyncSocket> client2(server_->CreateAsyncSocket(loopback.family(),
138                                                             SOCK_STREAM));
139  sink.Monitor(client2.get());
140  EXPECT_EQ(AsyncSocket::CS_CLOSED, client2->GetState());
141  EXPECT_PRED1(IsUnspecOrEmptyIP, client2->GetLocalAddress().ipaddr());
142
143  // Create server and listen.
144  scoped_ptr<AsyncSocket> server(
145      server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
146  sink.Monitor(server.get());
147  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
148  EXPECT_EQ(0, server->Listen(5));
149  EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
150
151  // Ensure no pending server connections, since we haven't done anything yet.
152  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
153  EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
154  EXPECT_TRUE(accept_addr.IsNil());
155
156  // Attempt first connect to listening socket.
157  EXPECT_EQ(0, client1->Connect(server->GetLocalAddress()));
158  EXPECT_FALSE(client1->GetLocalAddress().IsNil());
159  EXPECT_NE(server->GetLocalAddress(), client1->GetLocalAddress());
160
161  // Client is connecting, outcome not yet determined.
162  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client1->GetState());
163  EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_OPEN));
164  EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_CLOSE));
165
166  // Server has pending connection, try to accept it (will fail).
167  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
168  // Simulate "::accept" returning an error.
169  SetFailAccept(true);
170  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
171  EXPECT_FALSE(accepted);
172  ASSERT_TRUE(accept_addr.IsNil());
173
174  // Ensure no more pending server connections.
175  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
176  EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
177  EXPECT_TRUE(accept_addr.IsNil());
178
179  // Attempt second connect to listening socket.
180  EXPECT_EQ(0, client2->Connect(server->GetLocalAddress()));
181  EXPECT_FALSE(client2->GetLocalAddress().IsNil());
182  EXPECT_NE(server->GetLocalAddress(), client2->GetLocalAddress());
183
184  // Client is connecting, outcome not yet determined.
185  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client2->GetState());
186  EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_OPEN));
187  EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_CLOSE));
188
189  // Server has pending connection, try to accept it (will succeed).
190  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
191  SetFailAccept(false);
192  scoped_ptr<AsyncSocket> accepted2(server->Accept(&accept_addr));
193  ASSERT_TRUE(accepted2);
194  EXPECT_FALSE(accept_addr.IsNil());
195  EXPECT_EQ(accepted2->GetRemoteAddress(), accept_addr);
196}
197
198TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv4) {
199  ConnectInternalAcceptError(kIPv4Loopback);
200}
201
202// Crashes on Linux. See webrtc:4923.
203#if defined(WEBRTC_LINUX)
204#define MAYBE_TestConnectAcceptErrorIPv6 DISABLED_TestConnectAcceptErrorIPv6
205#else
206#define MAYBE_TestConnectAcceptErrorIPv6 TestConnectAcceptErrorIPv6
207#endif
208TEST_F(PhysicalSocketTest, MAYBE_TestConnectAcceptErrorIPv6) {
209  ConnectInternalAcceptError(kIPv6Loopback);
210}
211
212// Crashes on Linux. See webrtc:4923.
213#if defined(WEBRTC_LINUX)
214#define MAYBE_TestConnectFailIPv6 DISABLED_TestConnectFailIPv6
215#else
216#define MAYBE_TestConnectFailIPv6 TestConnectFailIPv6
217#endif
218TEST_F(PhysicalSocketTest, MAYBE_TestConnectFailIPv6) {
219  SocketTest::TestConnectFailIPv6();
220}
221
222TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
223  SocketTest::TestConnectWithDnsLookupFailIPv4();
224}
225
226// Crashes on Linux. See webrtc:4923.
227#if defined(WEBRTC_LINUX)
228#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
229  DISABLED_TestConnectWithDnsLookupFailIPv6
230#else
231#define MAYBE_TestConnectWithDnsLookupFailIPv6 \
232  TestConnectWithDnsLookupFailIPv6
233#endif
234TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithDnsLookupFailIPv6) {
235  SocketTest::TestConnectWithDnsLookupFailIPv6();
236}
237
238
239TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
240  SocketTest::TestConnectWithClosedSocketIPv4();
241}
242
243// Crashes on Linux. See webrtc:4923.
244#if defined(WEBRTC_LINUX)
245#define MAYBE_TestConnectWithClosedSocketIPv6 \
246  DISABLED_TestConnectWithClosedSocketIPv6
247#else
248#define MAYBE_TestConnectWithClosedSocketIPv6 TestConnectWithClosedSocketIPv6
249#endif
250TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithClosedSocketIPv6) {
251  SocketTest::TestConnectWithClosedSocketIPv6();
252}
253
254TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
255  SocketTest::TestConnectWhileNotClosedIPv4();
256}
257
258// Crashes on Linux. See webrtc:4923.
259#if defined(WEBRTC_LINUX)
260#define MAYBE_TestConnectWhileNotClosedIPv6 \
261  DISABLED_TestConnectWhileNotClosedIPv6
262#else
263#define MAYBE_TestConnectWhileNotClosedIPv6 TestConnectWhileNotClosedIPv6
264#endif
265TEST_F(PhysicalSocketTest, MAYBE_TestConnectWhileNotClosedIPv6) {
266  SocketTest::TestConnectWhileNotClosedIPv6();
267}
268
269TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
270  SocketTest::TestServerCloseDuringConnectIPv4();
271}
272
273// Crashes on Linux. See webrtc:4923.
274#if defined(WEBRTC_LINUX)
275#define MAYBE_TestServerCloseDuringConnectIPv6 \
276  DISABLED_TestServerCloseDuringConnectIPv6
277#else
278#define MAYBE_TestServerCloseDuringConnectIPv6 TestServerCloseDuringConnectIPv6
279#endif
280TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseDuringConnectIPv6) {
281  SocketTest::TestServerCloseDuringConnectIPv6();
282}
283
284TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
285  SocketTest::TestClientCloseDuringConnectIPv4();
286}
287
288// Crashes on Linux. See webrtc:4923.
289#if defined(WEBRTC_LINUX)
290#define MAYBE_TestClientCloseDuringConnectIPv6 \
291  DISABLED_TestClientCloseDuringConnectIPv6
292#else
293#define MAYBE_TestClientCloseDuringConnectIPv6 TestClientCloseDuringConnectIPv6
294#endif
295TEST_F(PhysicalSocketTest, MAYBE_TestClientCloseDuringConnectIPv6) {
296  SocketTest::TestClientCloseDuringConnectIPv6();
297}
298
299TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
300  SocketTest::TestServerCloseIPv4();
301}
302
303// Crashes on Linux. See webrtc:4923.
304#if defined(WEBRTC_LINUX)
305#define MAYBE_TestServerCloseIPv6 DISABLED_TestServerCloseIPv6
306#else
307#define MAYBE_TestServerCloseIPv6 TestServerCloseIPv6
308#endif
309TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseIPv6) {
310  SocketTest::TestServerCloseIPv6();
311}
312
313TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
314  SocketTest::TestCloseInClosedCallbackIPv4();
315}
316
317// Crashes on Linux. See webrtc:4923.
318#if defined(WEBRTC_LINUX)
319#define MAYBE_TestCloseInClosedCallbackIPv6 \
320  DISABLED_TestCloseInClosedCallbackIPv6
321#else
322#define MAYBE_TestCloseInClosedCallbackIPv6 TestCloseInClosedCallbackIPv6
323#endif
324TEST_F(PhysicalSocketTest, MAYBE_TestCloseInClosedCallbackIPv6) {
325  SocketTest::TestCloseInClosedCallbackIPv6();
326}
327
328TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
329  SocketTest::TestSocketServerWaitIPv4();
330}
331
332// Crashes on Linux. See webrtc:4923.
333#if defined(WEBRTC_LINUX)
334#define MAYBE_TestSocketServerWaitIPv6 DISABLED_TestSocketServerWaitIPv6
335#else
336#define MAYBE_TestSocketServerWaitIPv6 TestSocketServerWaitIPv6
337#endif
338TEST_F(PhysicalSocketTest, MAYBE_TestSocketServerWaitIPv6) {
339  SocketTest::TestSocketServerWaitIPv6();
340}
341
342TEST_F(PhysicalSocketTest, TestTcpIPv4) {
343  SocketTest::TestTcpIPv4();
344}
345
346// Crashes on Linux. See webrtc:4923.
347#if defined(WEBRTC_LINUX)
348#define MAYBE_TestTcpIPv6 DISABLED_TestTcpIPv6
349#else
350#define MAYBE_TestTcpIPv6 TestTcpIPv6
351#endif
352TEST_F(PhysicalSocketTest, MAYBE_TestTcpIPv6) {
353  SocketTest::TestTcpIPv6();
354}
355
356TEST_F(PhysicalSocketTest, TestUdpIPv4) {
357  SocketTest::TestUdpIPv4();
358}
359
360// Crashes on Linux. See webrtc:4923.
361#if defined(WEBRTC_LINUX)
362#define MAYBE_TestUdpIPv6 DISABLED_TestUdpIPv6
363#else
364#define MAYBE_TestUdpIPv6 TestUdpIPv6
365#endif
366TEST_F(PhysicalSocketTest, MAYBE_TestUdpIPv6) {
367  SocketTest::TestUdpIPv6();
368}
369
370// Disable for TSan v2, see
371// https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
372// Also disable for MSan, see:
373// https://code.google.com/p/webrtc/issues/detail?id=4958
374// TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
375// Also disable for ASan.
376// Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
377// Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233
378#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
379    defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) ||  \
380    defined(WEBRTC_LINUX)
381#define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
382#else
383#define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
384#endif
385TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
386  SocketTest::TestUdpReadyToSendIPv4();
387}
388
389TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
390  SocketTest::TestUdpReadyToSendIPv6();
391}
392
393TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
394  SocketTest::TestGetSetOptionsIPv4();
395}
396
397TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
398  SocketTest::TestGetSetOptionsIPv6();
399}
400
401#if defined(WEBRTC_POSIX)
402
403class PosixSignalDeliveryTest : public testing::Test {
404 public:
405  static void RecordSignal(int signum) {
406    signals_received_.push_back(signum);
407    signaled_thread_ = Thread::Current();
408  }
409
410 protected:
411  void SetUp() {
412    ss_.reset(new PhysicalSocketServer());
413  }
414
415  void TearDown() {
416    ss_.reset(NULL);
417    signals_received_.clear();
418    signaled_thread_ = NULL;
419  }
420
421  bool ExpectSignal(int signum) {
422    if (signals_received_.empty()) {
423      LOG(LS_ERROR) << "ExpectSignal(): No signal received";
424      return false;
425    }
426    if (signals_received_[0] != signum) {
427      LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
428          signals_received_[0] << ", expected " << signum;
429      return false;
430    }
431    signals_received_.erase(signals_received_.begin());
432    return true;
433  }
434
435  bool ExpectNone() {
436    bool ret = signals_received_.empty();
437    if (!ret) {
438      LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
439          << ", expected none";
440    }
441    return ret;
442  }
443
444  static std::vector<int> signals_received_;
445  static Thread *signaled_thread_;
446
447  scoped_ptr<PhysicalSocketServer> ss_;
448};
449
450std::vector<int> PosixSignalDeliveryTest::signals_received_;
451Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
452
453// Test receiving a synchronous signal while not in Wait() and then entering
454// Wait() afterwards.
455TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
456  ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
457  raise(SIGTERM);
458  EXPECT_TRUE(ss_->Wait(0, true));
459  EXPECT_TRUE(ExpectSignal(SIGTERM));
460  EXPECT_TRUE(ExpectNone());
461}
462
463// Test that we can handle getting tons of repeated signals and that we see all
464// the different ones.
465TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
466  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
467  ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
468  for (int i = 0; i < 10000; ++i) {
469    raise(SIGTERM);
470  }
471  raise(SIGINT);
472  EXPECT_TRUE(ss_->Wait(0, true));
473  // Order will be lowest signal numbers first.
474  EXPECT_TRUE(ExpectSignal(SIGINT));
475  EXPECT_TRUE(ExpectSignal(SIGTERM));
476  EXPECT_TRUE(ExpectNone());
477}
478
479// Test that a signal during a Wait() call is detected.
480TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
481  ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
482  alarm(1);
483  EXPECT_TRUE(ss_->Wait(1500, true));
484  EXPECT_TRUE(ExpectSignal(SIGALRM));
485  EXPECT_TRUE(ExpectNone());
486}
487
488class RaiseSigTermRunnable : public Runnable {
489  void Run(Thread *thread) {
490    thread->socketserver()->Wait(1000, false);
491
492    // Allow SIGTERM. This will be the only thread with it not masked so it will
493    // be delivered to us.
494    sigset_t mask;
495    sigemptyset(&mask);
496    pthread_sigmask(SIG_SETMASK, &mask, NULL);
497
498    // Raise it.
499    raise(SIGTERM);
500  }
501};
502
503// Test that it works no matter what thread the kernel chooses to give the
504// signal to (since it's not guaranteed to be the one that Wait() runs on).
505TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
506  ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
507  // Mask out SIGTERM so that it can't be delivered to this thread.
508  sigset_t mask;
509  sigemptyset(&mask);
510  sigaddset(&mask, SIGTERM);
511  EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
512  // Start a new thread that raises it. It will have to be delivered to that
513  // thread. Our implementation should safely handle it and dispatch
514  // RecordSignal() on this thread.
515  scoped_ptr<Thread> thread(new Thread());
516  scoped_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
517  thread->Start(runnable.get());
518  EXPECT_TRUE(ss_->Wait(1500, true));
519  EXPECT_TRUE(ExpectSignal(SIGTERM));
520  EXPECT_EQ(Thread::Current(), signaled_thread_);
521  EXPECT_TRUE(ExpectNone());
522}
523
524#endif
525
526}  // namespace rtc
527