blob: 4cea0403df59b1a62842273364cfd4ea0e24144e [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 */
honghaizcec0a082016-01-15 14:49:09 -080010#include "webrtc/base/physicalsocketserver.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000011
12#if defined(_MSC_VER) && _MSC_VER < 1300
13#pragma warning(disable:4786)
14#endif
15
16#include <assert.h>
17
pbos@webrtc.org27e58982014-10-07 17:56:53 +000018#ifdef MEMORY_SANITIZER
19#include <sanitizer/msan_interface.h>
20#endif
21
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000022#if defined(WEBRTC_POSIX)
23#include <string.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <sys/time.h>
27#include <sys/select.h>
28#include <unistd.h>
29#include <signal.h>
30#endif
31
32#if defined(WEBRTC_WIN)
33#define WIN32_LEAN_AND_MEAN
34#include <windows.h>
35#include <winsock2.h>
36#include <ws2tcpip.h>
37#undef SetPort
38#endif
39
40#include <algorithm>
41#include <map>
42
tfarina5237aaf2015-11-10 23:44:30 -080043#include "webrtc/base/arraysize.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000044#include "webrtc/base/basictypes.h"
45#include "webrtc/base/byteorder.h"
46#include "webrtc/base/common.h"
47#include "webrtc/base/logging.h"
honghaizcec0a082016-01-15 14:49:09 -080048#include "webrtc/base/networkmonitor.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000049#include "webrtc/base/timeutils.h"
50#include "webrtc/base/winping.h"
51#include "webrtc/base/win32socketinit.h"
52
53// stm: this will tell us if we are on OSX
54#ifdef HAVE_CONFIG_H
55#include "config.h"
56#endif
57
58#if defined(WEBRTC_POSIX)
59#include <netinet/tcp.h> // for TCP_NODELAY
60#define IP_MTU 14 // Until this is integrated from linux/in.h to netinet/in.h
61typedef void* SockOptArg;
62#endif // WEBRTC_POSIX
63
64#if defined(WEBRTC_WIN)
65typedef char* SockOptArg;
66#endif
67
68namespace rtc {
69
70#if defined(WEBRTC_WIN)
71// Standard MTUs, from RFC 1191
Peter Boström0c4e06b2015-10-07 12:23:21 +020072const uint16_t PACKET_MAXIMUMS[] = {
73 65535, // Theoretical maximum, Hyperchannel
74 32000, // Nothing
75 17914, // 16Mb IBM Token Ring
76 8166, // IEEE 802.4
77 // 4464, // IEEE 802.5 (4Mb max)
78 4352, // FDDI
79 // 2048, // Wideband Network
80 2002, // IEEE 802.5 (4Mb recommended)
81 // 1536, // Expermental Ethernet Networks
82 // 1500, // Ethernet, Point-to-Point (default)
83 1492, // IEEE 802.3
84 1006, // SLIP, ARPANET
85 // 576, // X.25 Networks
86 // 544, // DEC IP Portal
87 // 512, // NETBIOS
88 508, // IEEE 802/Source-Rt Bridge, ARCNET
89 296, // Point-to-Point (low delay)
90 68, // Official minimum
91 0, // End of list marker
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000092};
93
94static const int IP_HEADER_SIZE = 20u;
95static const int IPV6_HEADER_SIZE = 40u;
96static const int ICMP_HEADER_SIZE = 8u;
97static const int ICMP_PING_TIMEOUT_MILLIS = 10000u;
98#endif
99
jbauch095ae152015-12-18 01:39:55 -0800100PhysicalSocket::PhysicalSocket(PhysicalSocketServer* ss, SOCKET s)
101 : ss_(ss), s_(s), enabled_events_(0), error_(0),
102 state_((s == INVALID_SOCKET) ? CS_CLOSED : CS_CONNECTED),
103 resolver_(nullptr) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000104#if defined(WEBRTC_WIN)
jbauch095ae152015-12-18 01:39:55 -0800105 // EnsureWinsockInit() ensures that winsock is initialized. The default
106 // version of this function doesn't do anything because winsock is
107 // initialized by constructor of a static object. If neccessary libjingle
108 // users can link it with a different version of this function by replacing
109 // win32socketinit.cc. See win32socketinit.cc for more details.
110 EnsureWinsockInit();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000111#endif
jbauch095ae152015-12-18 01:39:55 -0800112 if (s_ != INVALID_SOCKET) {
113 enabled_events_ = DE_READ | DE_WRITE;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000114
jbauch095ae152015-12-18 01:39:55 -0800115 int type = SOCK_STREAM;
116 socklen_t len = sizeof(type);
117 VERIFY(0 == getsockopt(s_, SOL_SOCKET, SO_TYPE, (SockOptArg)&type, &len));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000118 udp_ = (SOCK_DGRAM == type);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000119 }
jbauch095ae152015-12-18 01:39:55 -0800120}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000121
jbauch095ae152015-12-18 01:39:55 -0800122PhysicalSocket::~PhysicalSocket() {
123 Close();
124}
125
126bool PhysicalSocket::Create(int family, int type) {
127 Close();
128 s_ = ::socket(family, type, 0);
129 udp_ = (SOCK_DGRAM == type);
130 UpdateLastError();
131 if (udp_)
132 enabled_events_ = DE_READ | DE_WRITE;
133 return s_ != INVALID_SOCKET;
134}
135
136SocketAddress PhysicalSocket::GetLocalAddress() const {
137 sockaddr_storage addr_storage = {0};
138 socklen_t addrlen = sizeof(addr_storage);
139 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
140 int result = ::getsockname(s_, addr, &addrlen);
141 SocketAddress address;
142 if (result >= 0) {
143 SocketAddressFromSockAddrStorage(addr_storage, &address);
144 } else {
145 LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket="
146 << s_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000147 }
jbauch095ae152015-12-18 01:39:55 -0800148 return address;
149}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000150
jbauch095ae152015-12-18 01:39:55 -0800151SocketAddress PhysicalSocket::GetRemoteAddress() const {
152 sockaddr_storage addr_storage = {0};
153 socklen_t addrlen = sizeof(addr_storage);
154 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
155 int result = ::getpeername(s_, addr, &addrlen);
156 SocketAddress address;
157 if (result >= 0) {
158 SocketAddressFromSockAddrStorage(addr_storage, &address);
159 } else {
160 LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket="
161 << s_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000162 }
jbauch095ae152015-12-18 01:39:55 -0800163 return address;
164}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000165
jbauch095ae152015-12-18 01:39:55 -0800166int PhysicalSocket::Bind(const SocketAddress& bind_addr) {
167 sockaddr_storage addr_storage;
168 size_t len = bind_addr.ToSockAddrStorage(&addr_storage);
169 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
170 int err = ::bind(s_, addr, static_cast<int>(len));
171 UpdateLastError();
tfarinaa41ab932015-10-30 16:08:48 -0700172#if !defined(NDEBUG)
jbauch095ae152015-12-18 01:39:55 -0800173 if (0 == err) {
174 dbg_addr_ = "Bound @ ";
175 dbg_addr_.append(GetLocalAddress().ToString());
176 }
tfarinaa41ab932015-10-30 16:08:48 -0700177#endif
honghaizcec0a082016-01-15 14:49:09 -0800178 if (ss_->network_binder()) {
179 int result =
180 ss_->network_binder()->BindSocketToNetwork(s_, bind_addr.ipaddr());
181 if (result < 0) {
182 LOG(LS_INFO) << "Binding socket to network address "
183 << bind_addr.ipaddr().ToString() << " result " << result;
184 }
185 }
jbauch095ae152015-12-18 01:39:55 -0800186 return err;
187}
188
189int PhysicalSocket::Connect(const SocketAddress& addr) {
190 // TODO(pthatcher): Implicit creation is required to reconnect...
191 // ...but should we make it more explicit?
192 if (state_ != CS_CLOSED) {
193 SetError(EALREADY);
194 return SOCKET_ERROR;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000195 }
jbauch095ae152015-12-18 01:39:55 -0800196 if (addr.IsUnresolvedIP()) {
197 LOG(LS_VERBOSE) << "Resolving addr in PhysicalSocket::Connect";
198 resolver_ = new AsyncResolver();
199 resolver_->SignalDone.connect(this, &PhysicalSocket::OnResolveResult);
200 resolver_->Start(addr);
201 state_ = CS_CONNECTING;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000202 return 0;
203 }
204
jbauch095ae152015-12-18 01:39:55 -0800205 return DoConnect(addr);
206}
207
208int PhysicalSocket::DoConnect(const SocketAddress& connect_addr) {
209 if ((s_ == INVALID_SOCKET) &&
210 !Create(connect_addr.family(), SOCK_STREAM)) {
211 return SOCKET_ERROR;
212 }
213 sockaddr_storage addr_storage;
214 size_t len = connect_addr.ToSockAddrStorage(&addr_storage);
215 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
216 int err = ::connect(s_, addr, static_cast<int>(len));
217 UpdateLastError();
218 if (err == 0) {
219 state_ = CS_CONNECTED;
220 } else if (IsBlockingError(GetError())) {
221 state_ = CS_CONNECTING;
222 enabled_events_ |= DE_CONNECT;
223 } else {
224 return SOCKET_ERROR;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000225 }
226
jbauch095ae152015-12-18 01:39:55 -0800227 enabled_events_ |= DE_READ | DE_WRITE;
228 return 0;
229}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000230
jbauch095ae152015-12-18 01:39:55 -0800231int PhysicalSocket::GetError() const {
232 CritScope cs(&crit_);
233 return error_;
234}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000235
jbauch095ae152015-12-18 01:39:55 -0800236void PhysicalSocket::SetError(int error) {
237 CritScope cs(&crit_);
238 error_ = error;
239}
240
241AsyncSocket::ConnState PhysicalSocket::GetState() const {
242 return state_;
243}
244
245int PhysicalSocket::GetOption(Option opt, int* value) {
246 int slevel;
247 int sopt;
248 if (TranslateOption(opt, &slevel, &sopt) == -1)
249 return -1;
250 socklen_t optlen = sizeof(*value);
251 int ret = ::getsockopt(s_, slevel, sopt, (SockOptArg)value, &optlen);
252 if (ret != -1 && opt == OPT_DONTFRAGMENT) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000253#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
jbauch095ae152015-12-18 01:39:55 -0800254 *value = (*value != IP_PMTUDISC_DONT) ? 1 : 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000255#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000256 }
jbauch095ae152015-12-18 01:39:55 -0800257 return ret;
258}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000259
jbauch095ae152015-12-18 01:39:55 -0800260int PhysicalSocket::SetOption(Option opt, int value) {
261 int slevel;
262 int sopt;
263 if (TranslateOption(opt, &slevel, &sopt) == -1)
264 return -1;
265 if (opt == OPT_DONTFRAGMENT) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000266#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
jbauch095ae152015-12-18 01:39:55 -0800267 value = (value) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000268#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000269 }
jbauch095ae152015-12-18 01:39:55 -0800270 return ::setsockopt(s_, slevel, sopt, (SockOptArg)&value, sizeof(value));
271}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000272
jbauch095ae152015-12-18 01:39:55 -0800273int PhysicalSocket::Send(const void* pv, size_t cb) {
jbauchf2a2bf42016-02-03 16:45:32 -0800274 int sent = DoSend(s_, reinterpret_cast<const char *>(pv),
275 static_cast<int>(cb),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000276#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
jbauch095ae152015-12-18 01:39:55 -0800277 // Suppress SIGPIPE. Without this, attempting to send on a socket whose
278 // other end is closed will result in a SIGPIPE signal being raised to
279 // our process, which by default will terminate the process, which we
280 // don't want. By specifying this flag, we'll just get the error EPIPE
281 // instead and can handle the error gracefully.
282 MSG_NOSIGNAL
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000283#else
jbauch095ae152015-12-18 01:39:55 -0800284 0
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000285#endif
jbauch095ae152015-12-18 01:39:55 -0800286 );
287 UpdateLastError();
288 MaybeRemapSendError();
289 // We have seen minidumps where this may be false.
290 ASSERT(sent <= static_cast<int>(cb));
jbauchf2a2bf42016-02-03 16:45:32 -0800291 if ((sent > 0 && sent < static_cast<int>(cb)) ||
292 (sent < 0 && IsBlockingError(GetError()))) {
jbauch095ae152015-12-18 01:39:55 -0800293 enabled_events_ |= DE_WRITE;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000294 }
jbauch095ae152015-12-18 01:39:55 -0800295 return sent;
296}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000297
jbauch095ae152015-12-18 01:39:55 -0800298int PhysicalSocket::SendTo(const void* buffer,
299 size_t length,
300 const SocketAddress& addr) {
301 sockaddr_storage saddr;
302 size_t len = addr.ToSockAddrStorage(&saddr);
jbauchf2a2bf42016-02-03 16:45:32 -0800303 int sent = DoSendTo(
jbauch095ae152015-12-18 01:39:55 -0800304 s_, static_cast<const char *>(buffer), static_cast<int>(length),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000305#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
jbauch095ae152015-12-18 01:39:55 -0800306 // Suppress SIGPIPE. See above for explanation.
307 MSG_NOSIGNAL,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000308#else
jbauch095ae152015-12-18 01:39:55 -0800309 0,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000310#endif
jbauch095ae152015-12-18 01:39:55 -0800311 reinterpret_cast<sockaddr*>(&saddr), static_cast<int>(len));
312 UpdateLastError();
313 MaybeRemapSendError();
314 // We have seen minidumps where this may be false.
315 ASSERT(sent <= static_cast<int>(length));
jbauchf2a2bf42016-02-03 16:45:32 -0800316 if ((sent > 0 && sent < static_cast<int>(length)) ||
317 (sent < 0 && IsBlockingError(GetError()))) {
jbauch095ae152015-12-18 01:39:55 -0800318 enabled_events_ |= DE_WRITE;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000319 }
jbauch095ae152015-12-18 01:39:55 -0800320 return sent;
321}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000322
jbauch095ae152015-12-18 01:39:55 -0800323int PhysicalSocket::Recv(void* buffer, size_t length) {
324 int received = ::recv(s_, static_cast<char*>(buffer),
325 static_cast<int>(length), 0);
326 if ((received == 0) && (length != 0)) {
327 // Note: on graceful shutdown, recv can return 0. In this case, we
328 // pretend it is blocking, and then signal close, so that simplifying
329 // assumptions can be made about Recv.
330 LOG(LS_WARNING) << "EOF from socket; deferring close event";
331 // Must turn this back on so that the select() loop will notice the close
332 // event.
333 enabled_events_ |= DE_READ;
334 SetError(EWOULDBLOCK);
335 return SOCKET_ERROR;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000336 }
jbauch095ae152015-12-18 01:39:55 -0800337 UpdateLastError();
338 int error = GetError();
339 bool success = (received >= 0) || IsBlockingError(error);
340 if (udp_ || success) {
341 enabled_events_ |= DE_READ;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000342 }
jbauch095ae152015-12-18 01:39:55 -0800343 if (!success) {
344 LOG_F(LS_VERBOSE) << "Error = " << error;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000345 }
jbauch095ae152015-12-18 01:39:55 -0800346 return received;
347}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000348
jbauch095ae152015-12-18 01:39:55 -0800349int PhysicalSocket::RecvFrom(void* buffer,
350 size_t length,
351 SocketAddress* out_addr) {
352 sockaddr_storage addr_storage;
353 socklen_t addr_len = sizeof(addr_storage);
354 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
355 int received = ::recvfrom(s_, static_cast<char*>(buffer),
356 static_cast<int>(length), 0, addr, &addr_len);
357 UpdateLastError();
358 if ((received >= 0) && (out_addr != nullptr))
359 SocketAddressFromSockAddrStorage(addr_storage, out_addr);
360 int error = GetError();
361 bool success = (received >= 0) || IsBlockingError(error);
362 if (udp_ || success) {
363 enabled_events_ |= DE_READ;
364 }
365 if (!success) {
366 LOG_F(LS_VERBOSE) << "Error = " << error;
367 }
368 return received;
369}
370
371int PhysicalSocket::Listen(int backlog) {
372 int err = ::listen(s_, backlog);
373 UpdateLastError();
374 if (err == 0) {
375 state_ = CS_CONNECTING;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000376 enabled_events_ |= DE_ACCEPT;
jbauch095ae152015-12-18 01:39:55 -0800377#if !defined(NDEBUG)
378 dbg_addr_ = "Listening @ ";
379 dbg_addr_.append(GetLocalAddress().ToString());
380#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000381 }
jbauch095ae152015-12-18 01:39:55 -0800382 return err;
383}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000384
jbauch095ae152015-12-18 01:39:55 -0800385AsyncSocket* PhysicalSocket::Accept(SocketAddress* out_addr) {
386 // Always re-subscribe DE_ACCEPT to make sure new incoming connections will
387 // trigger an event even if DoAccept returns an error here.
388 enabled_events_ |= DE_ACCEPT;
389 sockaddr_storage addr_storage;
390 socklen_t addr_len = sizeof(addr_storage);
391 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
392 SOCKET s = DoAccept(s_, addr, &addr_len);
393 UpdateLastError();
394 if (s == INVALID_SOCKET)
395 return nullptr;
396 if (out_addr != nullptr)
397 SocketAddressFromSockAddrStorage(addr_storage, out_addr);
398 return ss_->WrapSocket(s);
399}
400
401int PhysicalSocket::Close() {
402 if (s_ == INVALID_SOCKET)
403 return 0;
404 int err = ::closesocket(s_);
405 UpdateLastError();
406 s_ = INVALID_SOCKET;
407 state_ = CS_CLOSED;
408 enabled_events_ = 0;
409 if (resolver_) {
410 resolver_->Destroy(false);
411 resolver_ = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000412 }
jbauch095ae152015-12-18 01:39:55 -0800413 return err;
414}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000415
jbauch095ae152015-12-18 01:39:55 -0800416int PhysicalSocket::EstimateMTU(uint16_t* mtu) {
417 SocketAddress addr = GetRemoteAddress();
418 if (addr.IsAnyIP()) {
419 SetError(ENOTCONN);
420 return -1;
421 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000422
423#if defined(WEBRTC_WIN)
jbauch095ae152015-12-18 01:39:55 -0800424 // Gets the interface MTU (TTL=1) for the interface used to reach |addr|.
425 WinPing ping;
426 if (!ping.IsValid()) {
427 SetError(EINVAL); // can't think of a better error ID
428 return -1;
429 }
430 int header_size = ICMP_HEADER_SIZE;
431 if (addr.family() == AF_INET6) {
432 header_size += IPV6_HEADER_SIZE;
433 } else if (addr.family() == AF_INET) {
434 header_size += IP_HEADER_SIZE;
435 }
436
437 for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) {
438 int32_t size = PACKET_MAXIMUMS[level] - header_size;
439 WinPing::PingResult result = ping.Ping(addr.ipaddr(), size,
440 ICMP_PING_TIMEOUT_MILLIS,
441 1, false);
442 if (result == WinPing::PING_FAIL) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000443 SetError(EINVAL); // can't think of a better error ID
444 return -1;
jbauch095ae152015-12-18 01:39:55 -0800445 } else if (result != WinPing::PING_TOO_LARGE) {
446 *mtu = PACKET_MAXIMUMS[level];
447 return 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000448 }
jbauch095ae152015-12-18 01:39:55 -0800449 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000450
jbauch095ae152015-12-18 01:39:55 -0800451 ASSERT(false);
452 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000453#elif defined(WEBRTC_MAC)
jbauch095ae152015-12-18 01:39:55 -0800454 // No simple way to do this on Mac OS X.
455 // SIOCGIFMTU would work if we knew which interface would be used, but
456 // figuring that out is pretty complicated. For now we'll return an error
457 // and let the caller pick a default MTU.
458 SetError(EINVAL);
459 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000460#elif defined(WEBRTC_LINUX)
jbauch095ae152015-12-18 01:39:55 -0800461 // Gets the path MTU.
462 int value;
463 socklen_t vlen = sizeof(value);
464 int err = getsockopt(s_, IPPROTO_IP, IP_MTU, &value, &vlen);
465 if (err < 0) {
466 UpdateLastError();
467 return err;
468 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000469
jbauch095ae152015-12-18 01:39:55 -0800470 ASSERT((0 <= value) && (value <= 65536));
471 *mtu = value;
472 return 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000473#elif defined(__native_client__)
jbauch095ae152015-12-18 01:39:55 -0800474 // Most socket operations, including this, will fail in NaCl's sandbox.
475 error_ = EACCES;
476 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000477#endif
jbauch095ae152015-12-18 01:39:55 -0800478}
479
jbauch095ae152015-12-18 01:39:55 -0800480SOCKET PhysicalSocket::DoAccept(SOCKET socket,
481 sockaddr* addr,
482 socklen_t* addrlen) {
483 return ::accept(socket, addr, addrlen);
484}
485
jbauchf2a2bf42016-02-03 16:45:32 -0800486int PhysicalSocket::DoSend(SOCKET socket, const char* buf, int len, int flags) {
487 return ::send(socket, buf, len, flags);
488}
489
490int PhysicalSocket::DoSendTo(SOCKET socket,
491 const char* buf,
492 int len,
493 int flags,
494 const struct sockaddr* dest_addr,
495 socklen_t addrlen) {
496 return ::sendto(socket, buf, len, flags, dest_addr, addrlen);
497}
498
jbauch095ae152015-12-18 01:39:55 -0800499void PhysicalSocket::OnResolveResult(AsyncResolverInterface* resolver) {
500 if (resolver != resolver_) {
501 return;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000502 }
503
jbauch095ae152015-12-18 01:39:55 -0800504 int error = resolver_->GetError();
505 if (error == 0) {
506 error = DoConnect(resolver_->address());
507 } else {
508 Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000509 }
510
jbauch095ae152015-12-18 01:39:55 -0800511 if (error) {
512 SetError(error);
513 SignalCloseEvent(this, error);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000514 }
jbauch095ae152015-12-18 01:39:55 -0800515}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000516
jbauch095ae152015-12-18 01:39:55 -0800517void PhysicalSocket::UpdateLastError() {
518 SetError(LAST_SYSTEM_ERROR);
519}
520
521void PhysicalSocket::MaybeRemapSendError() {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000522#if defined(WEBRTC_MAC)
jbauch095ae152015-12-18 01:39:55 -0800523 // https://developer.apple.com/library/mac/documentation/Darwin/
524 // Reference/ManPages/man2/sendto.2.html
525 // ENOBUFS - The output queue for a network interface is full.
526 // This generally indicates that the interface has stopped sending,
527 // but may be caused by transient congestion.
528 if (GetError() == ENOBUFS) {
529 SetError(EWOULDBLOCK);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000530 }
jbauch095ae152015-12-18 01:39:55 -0800531#endif
532}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000533
jbauch095ae152015-12-18 01:39:55 -0800534int PhysicalSocket::TranslateOption(Option opt, int* slevel, int* sopt) {
535 switch (opt) {
536 case OPT_DONTFRAGMENT:
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000537#if defined(WEBRTC_WIN)
jbauch095ae152015-12-18 01:39:55 -0800538 *slevel = IPPROTO_IP;
539 *sopt = IP_DONTFRAGMENT;
540 break;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000541#elif defined(WEBRTC_MAC) || defined(BSD) || defined(__native_client__)
jbauch095ae152015-12-18 01:39:55 -0800542 LOG(LS_WARNING) << "Socket::OPT_DONTFRAGMENT not supported.";
543 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000544#elif defined(WEBRTC_POSIX)
jbauch095ae152015-12-18 01:39:55 -0800545 *slevel = IPPROTO_IP;
546 *sopt = IP_MTU_DISCOVER;
547 break;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000548#endif
jbauch095ae152015-12-18 01:39:55 -0800549 case OPT_RCVBUF:
550 *slevel = SOL_SOCKET;
551 *sopt = SO_RCVBUF;
552 break;
553 case OPT_SNDBUF:
554 *slevel = SOL_SOCKET;
555 *sopt = SO_SNDBUF;
556 break;
557 case OPT_NODELAY:
558 *slevel = IPPROTO_TCP;
559 *sopt = TCP_NODELAY;
560 break;
561 case OPT_DSCP:
562 LOG(LS_WARNING) << "Socket::OPT_DSCP not supported.";
563 return -1;
564 case OPT_RTP_SENDTIME_EXTN_ID:
565 return -1; // No logging is necessary as this not a OS socket option.
566 default:
567 ASSERT(false);
568 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000569 }
jbauch095ae152015-12-18 01:39:55 -0800570 return 0;
571}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000572
jbauch4331fcd2016-01-06 22:20:28 -0800573SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss)
574#if defined(WEBRTC_WIN)
575 : PhysicalSocket(ss), id_(0), signal_close_(false)
576#else
577 : PhysicalSocket(ss)
578#endif
579{
580}
581
582SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss)
583#if defined(WEBRTC_WIN)
584 : PhysicalSocket(ss, s), id_(0), signal_close_(false)
585#else
586 : PhysicalSocket(ss, s)
587#endif
588{
589}
590
591SocketDispatcher::~SocketDispatcher() {
592 Close();
593}
594
595bool SocketDispatcher::Initialize() {
596 ASSERT(s_ != INVALID_SOCKET);
597 // Must be a non-blocking
598#if defined(WEBRTC_WIN)
599 u_long argp = 1;
600 ioctlsocket(s_, FIONBIO, &argp);
601#elif defined(WEBRTC_POSIX)
602 fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK);
603#endif
604 ss_->Add(this);
605 return true;
606}
607
608bool SocketDispatcher::Create(int type) {
609 return Create(AF_INET, type);
610}
611
612bool SocketDispatcher::Create(int family, int type) {
613 // Change the socket to be non-blocking.
614 if (!PhysicalSocket::Create(family, type))
615 return false;
616
617 if (!Initialize())
618 return false;
619
620#if defined(WEBRTC_WIN)
621 do { id_ = ++next_id_; } while (id_ == 0);
622#endif
623 return true;
624}
625
626#if defined(WEBRTC_WIN)
627
628WSAEVENT SocketDispatcher::GetWSAEvent() {
629 return WSA_INVALID_EVENT;
630}
631
632SOCKET SocketDispatcher::GetSocket() {
633 return s_;
634}
635
636bool SocketDispatcher::CheckSignalClose() {
637 if (!signal_close_)
638 return false;
639
640 char ch;
641 if (recv(s_, &ch, 1, MSG_PEEK) > 0)
642 return false;
643
644 state_ = CS_CLOSED;
645 signal_close_ = false;
646 SignalCloseEvent(this, signal_err_);
647 return true;
648}
649
650int SocketDispatcher::next_id_ = 0;
651
652#elif defined(WEBRTC_POSIX)
653
654int SocketDispatcher::GetDescriptor() {
655 return s_;
656}
657
658bool SocketDispatcher::IsDescriptorClosed() {
659 // We don't have a reliable way of distinguishing end-of-stream
660 // from readability. So test on each readable call. Is this
661 // inefficient? Probably.
662 char ch;
663 ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK);
664 if (res > 0) {
665 // Data available, so not closed.
666 return false;
667 } else if (res == 0) {
668 // EOF, so closed.
669 return true;
670 } else { // error
671 switch (errno) {
672 // Returned if we've already closed s_.
673 case EBADF:
674 // Returned during ungraceful peer shutdown.
675 case ECONNRESET:
676 return true;
677 default:
678 // Assume that all other errors are just blocking errors, meaning the
679 // connection is still good but we just can't read from it right now.
680 // This should only happen when connecting (and at most once), because
681 // in all other cases this function is only called if the file
682 // descriptor is already known to be in the readable state. However,
683 // it's not necessary a problem if we spuriously interpret a
684 // "connection lost"-type error as a blocking error, because typically
685 // the next recv() will get EOF, so we'll still eventually notice that
686 // the socket is closed.
687 LOG_ERR(LS_WARNING) << "Assuming benign blocking error";
688 return false;
689 }
690 }
691}
692
693#endif // WEBRTC_POSIX
694
695uint32_t SocketDispatcher::GetRequestedEvents() {
696 return enabled_events_;
697}
698
699void SocketDispatcher::OnPreEvent(uint32_t ff) {
700 if ((ff & DE_CONNECT) != 0)
701 state_ = CS_CONNECTED;
702
703#if defined(WEBRTC_WIN)
704 // We set CS_CLOSED from CheckSignalClose.
705#elif defined(WEBRTC_POSIX)
706 if ((ff & DE_CLOSE) != 0)
707 state_ = CS_CLOSED;
708#endif
709}
710
711#if defined(WEBRTC_WIN)
712
713void SocketDispatcher::OnEvent(uint32_t ff, int err) {
714 int cache_id = id_;
715 // Make sure we deliver connect/accept first. Otherwise, consumers may see
716 // something like a READ followed by a CONNECT, which would be odd.
717 if (((ff & DE_CONNECT) != 0) && (id_ == cache_id)) {
718 if (ff != DE_CONNECT)
719 LOG(LS_VERBOSE) << "Signalled with DE_CONNECT: " << ff;
720 enabled_events_ &= ~DE_CONNECT;
721#if !defined(NDEBUG)
722 dbg_addr_ = "Connected @ ";
723 dbg_addr_.append(GetRemoteAddress().ToString());
724#endif
725 SignalConnectEvent(this);
726 }
727 if (((ff & DE_ACCEPT) != 0) && (id_ == cache_id)) {
728 enabled_events_ &= ~DE_ACCEPT;
729 SignalReadEvent(this);
730 }
731 if ((ff & DE_READ) != 0) {
732 enabled_events_ &= ~DE_READ;
733 SignalReadEvent(this);
734 }
735 if (((ff & DE_WRITE) != 0) && (id_ == cache_id)) {
736 enabled_events_ &= ~DE_WRITE;
737 SignalWriteEvent(this);
738 }
739 if (((ff & DE_CLOSE) != 0) && (id_ == cache_id)) {
740 signal_close_ = true;
741 signal_err_ = err;
742 }
743}
744
745#elif defined(WEBRTC_POSIX)
746
747void SocketDispatcher::OnEvent(uint32_t ff, int err) {
748 // Make sure we deliver connect/accept first. Otherwise, consumers may see
749 // something like a READ followed by a CONNECT, which would be odd.
750 if ((ff & DE_CONNECT) != 0) {
751 enabled_events_ &= ~DE_CONNECT;
752 SignalConnectEvent(this);
753 }
754 if ((ff & DE_ACCEPT) != 0) {
755 enabled_events_ &= ~DE_ACCEPT;
756 SignalReadEvent(this);
757 }
758 if ((ff & DE_READ) != 0) {
759 enabled_events_ &= ~DE_READ;
760 SignalReadEvent(this);
761 }
762 if ((ff & DE_WRITE) != 0) {
763 enabled_events_ &= ~DE_WRITE;
764 SignalWriteEvent(this);
765 }
766 if ((ff & DE_CLOSE) != 0) {
767 // The socket is now dead to us, so stop checking it.
768 enabled_events_ = 0;
769 SignalCloseEvent(this, err);
770 }
771}
772
773#endif // WEBRTC_POSIX
774
775int SocketDispatcher::Close() {
776 if (s_ == INVALID_SOCKET)
777 return 0;
778
779#if defined(WEBRTC_WIN)
780 id_ = 0;
781 signal_close_ = false;
782#endif
783 ss_->Remove(this);
784 return PhysicalSocket::Close();
785}
786
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000787#if defined(WEBRTC_POSIX)
788class EventDispatcher : public Dispatcher {
789 public:
790 EventDispatcher(PhysicalSocketServer* ss) : ss_(ss), fSignaled_(false) {
791 if (pipe(afd_) < 0)
792 LOG(LERROR) << "pipe failed";
793 ss_->Add(this);
794 }
795
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000796 ~EventDispatcher() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000797 ss_->Remove(this);
798 close(afd_[0]);
799 close(afd_[1]);
800 }
801
802 virtual void Signal() {
803 CritScope cs(&crit_);
804 if (!fSignaled_) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200805 const uint8_t b[1] = {0};
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000806 if (VERIFY(1 == write(afd_[1], b, sizeof(b)))) {
807 fSignaled_ = true;
808 }
809 }
810 }
811
Peter Boström0c4e06b2015-10-07 12:23:21 +0200812 uint32_t GetRequestedEvents() override { return DE_READ; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000813
Peter Boström0c4e06b2015-10-07 12:23:21 +0200814 void OnPreEvent(uint32_t ff) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000815 // It is not possible to perfectly emulate an auto-resetting event with
816 // pipes. This simulates it by resetting before the event is handled.
817
818 CritScope cs(&crit_);
819 if (fSignaled_) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200820 uint8_t b[4]; // Allow for reading more than 1 byte, but expect 1.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000821 VERIFY(1 == read(afd_[0], b, sizeof(b)));
822 fSignaled_ = false;
823 }
824 }
825
Peter Boström0c4e06b2015-10-07 12:23:21 +0200826 void OnEvent(uint32_t ff, int err) override { ASSERT(false); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000827
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000828 int GetDescriptor() override { return afd_[0]; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000829
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000830 bool IsDescriptorClosed() override { return false; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000831
832 private:
833 PhysicalSocketServer *ss_;
834 int afd_[2];
835 bool fSignaled_;
836 CriticalSection crit_;
837};
838
839// These two classes use the self-pipe trick to deliver POSIX signals to our
840// select loop. This is the only safe, reliable, cross-platform way to do
841// non-trivial things with a POSIX signal in an event-driven program (until
842// proper pselect() implementations become ubiquitous).
843
844class PosixSignalHandler {
845 public:
846 // POSIX only specifies 32 signals, but in principle the system might have
847 // more and the programmer might choose to use them, so we size our array
848 // for 128.
849 static const int kNumPosixSignals = 128;
850
851 // There is just a single global instance. (Signal handlers do not get any
852 // sort of user-defined void * parameter, so they can't access anything that
853 // isn't global.)
854 static PosixSignalHandler* Instance() {
Andrew MacDonald469c2c02015-05-22 17:50:26 -0700855 RTC_DEFINE_STATIC_LOCAL(PosixSignalHandler, instance, ());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000856 return &instance;
857 }
858
859 // Returns true if the given signal number is set.
860 bool IsSignalSet(int signum) const {
tfarina5237aaf2015-11-10 23:44:30 -0800861 ASSERT(signum < static_cast<int>(arraysize(received_signal_)));
862 if (signum < static_cast<int>(arraysize(received_signal_))) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000863 return received_signal_[signum];
864 } else {
865 return false;
866 }
867 }
868
869 // Clears the given signal number.
870 void ClearSignal(int signum) {
tfarina5237aaf2015-11-10 23:44:30 -0800871 ASSERT(signum < static_cast<int>(arraysize(received_signal_)));
872 if (signum < static_cast<int>(arraysize(received_signal_))) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000873 received_signal_[signum] = false;
874 }
875 }
876
877 // Returns the file descriptor to monitor for signal events.
878 int GetDescriptor() const {
879 return afd_[0];
880 }
881
882 // This is called directly from our real signal handler, so it must be
883 // signal-handler-safe. That means it cannot assume anything about the
884 // user-level state of the process, since the handler could be executed at any
885 // time on any thread.
886 void OnPosixSignalReceived(int signum) {
tfarina5237aaf2015-11-10 23:44:30 -0800887 if (signum >= static_cast<int>(arraysize(received_signal_))) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000888 // We don't have space in our array for this.
889 return;
890 }
891 // Set a flag saying we've seen this signal.
892 received_signal_[signum] = true;
893 // Notify application code that we got a signal.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200894 const uint8_t b[1] = {0};
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000895 if (-1 == write(afd_[1], b, sizeof(b))) {
896 // Nothing we can do here. If there's an error somehow then there's
897 // nothing we can safely do from a signal handler.
898 // No, we can't even safely log it.
899 // But, we still have to check the return value here. Otherwise,
900 // GCC 4.4.1 complains ignoring return value. Even (void) doesn't help.
901 return;
902 }
903 }
904
905 private:
906 PosixSignalHandler() {
907 if (pipe(afd_) < 0) {
908 LOG_ERR(LS_ERROR) << "pipe failed";
909 return;
910 }
911 if (fcntl(afd_[0], F_SETFL, O_NONBLOCK) < 0) {
912 LOG_ERR(LS_WARNING) << "fcntl #1 failed";
913 }
914 if (fcntl(afd_[1], F_SETFL, O_NONBLOCK) < 0) {
915 LOG_ERR(LS_WARNING) << "fcntl #2 failed";
916 }
917 memset(const_cast<void *>(static_cast<volatile void *>(received_signal_)),
918 0,
919 sizeof(received_signal_));
920 }
921
922 ~PosixSignalHandler() {
923 int fd1 = afd_[0];
924 int fd2 = afd_[1];
925 // We clobber the stored file descriptor numbers here or else in principle
926 // a signal that happens to be delivered during application termination
927 // could erroneously write a zero byte to an unrelated file handle in
928 // OnPosixSignalReceived() if some other file happens to be opened later
929 // during shutdown and happens to be given the same file descriptor number
930 // as our pipe had. Unfortunately even with this precaution there is still a
931 // race where that could occur if said signal happens to be handled
932 // concurrently with this code and happens to have already read the value of
933 // afd_[1] from memory before we clobber it, but that's unlikely.
934 afd_[0] = -1;
935 afd_[1] = -1;
936 close(fd1);
937 close(fd2);
938 }
939
940 int afd_[2];
941 // These are boolean flags that will be set in our signal handler and read
942 // and cleared from Wait(). There is a race involved in this, but it is
943 // benign. The signal handler sets the flag before signaling the pipe, so
944 // we'll never end up blocking in select() while a flag is still true.
945 // However, if two of the same signal arrive close to each other then it's
946 // possible that the second time the handler may set the flag while it's still
947 // true, meaning that signal will be missed. But the first occurrence of it
948 // will still be handled, so this isn't a problem.
949 // Volatile is not necessary here for correctness, but this data _is_ volatile
950 // so I've marked it as such.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200951 volatile uint8_t received_signal_[kNumPosixSignals];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000952};
953
954class PosixSignalDispatcher : public Dispatcher {
955 public:
956 PosixSignalDispatcher(PhysicalSocketServer *owner) : owner_(owner) {
957 owner_->Add(this);
958 }
959
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000960 ~PosixSignalDispatcher() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000961 owner_->Remove(this);
962 }
963
Peter Boström0c4e06b2015-10-07 12:23:21 +0200964 uint32_t GetRequestedEvents() override { return DE_READ; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000965
Peter Boström0c4e06b2015-10-07 12:23:21 +0200966 void OnPreEvent(uint32_t ff) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000967 // Events might get grouped if signals come very fast, so we read out up to
968 // 16 bytes to make sure we keep the pipe empty.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200969 uint8_t b[16];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000970 ssize_t ret = read(GetDescriptor(), b, sizeof(b));
971 if (ret < 0) {
972 LOG_ERR(LS_WARNING) << "Error in read()";
973 } else if (ret == 0) {
974 LOG(LS_WARNING) << "Should have read at least one byte";
975 }
976 }
977
Peter Boström0c4e06b2015-10-07 12:23:21 +0200978 void OnEvent(uint32_t ff, int err) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000979 for (int signum = 0; signum < PosixSignalHandler::kNumPosixSignals;
980 ++signum) {
981 if (PosixSignalHandler::Instance()->IsSignalSet(signum)) {
982 PosixSignalHandler::Instance()->ClearSignal(signum);
983 HandlerMap::iterator i = handlers_.find(signum);
984 if (i == handlers_.end()) {
985 // This can happen if a signal is delivered to our process at around
986 // the same time as we unset our handler for it. It is not an error
987 // condition, but it's unusual enough to be worth logging.
988 LOG(LS_INFO) << "Received signal with no handler: " << signum;
989 } else {
990 // Otherwise, execute our handler.
991 (*i->second)(signum);
992 }
993 }
994 }
995 }
996
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000997 int GetDescriptor() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000998 return PosixSignalHandler::Instance()->GetDescriptor();
999 }
1000
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001001 bool IsDescriptorClosed() override { return false; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001002
1003 void SetHandler(int signum, void (*handler)(int)) {
1004 handlers_[signum] = handler;
1005 }
1006
1007 void ClearHandler(int signum) {
1008 handlers_.erase(signum);
1009 }
1010
1011 bool HasHandlers() {
1012 return !handlers_.empty();
1013 }
1014
1015 private:
1016 typedef std::map<int, void (*)(int)> HandlerMap;
1017
1018 HandlerMap handlers_;
1019 // Our owner.
1020 PhysicalSocketServer *owner_;
1021};
1022
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001023class FileDispatcher: public Dispatcher, public AsyncFile {
1024 public:
1025 FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) {
1026 set_readable(true);
1027
1028 ss_->Add(this);
1029
1030 fcntl(fd_, F_SETFL, fcntl(fd_, F_GETFL, 0) | O_NONBLOCK);
1031 }
1032
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001033 ~FileDispatcher() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001034 ss_->Remove(this);
1035 }
1036
1037 SocketServer* socketserver() { return ss_; }
1038
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001039 int GetDescriptor() override { return fd_; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001040
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001041 bool IsDescriptorClosed() override { return false; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001042
Peter Boström0c4e06b2015-10-07 12:23:21 +02001043 uint32_t GetRequestedEvents() override { return flags_; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001044
Peter Boström0c4e06b2015-10-07 12:23:21 +02001045 void OnPreEvent(uint32_t ff) override {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001046
Peter Boström0c4e06b2015-10-07 12:23:21 +02001047 void OnEvent(uint32_t ff, int err) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001048 if ((ff & DE_READ) != 0)
1049 SignalReadEvent(this);
1050 if ((ff & DE_WRITE) != 0)
1051 SignalWriteEvent(this);
1052 if ((ff & DE_CLOSE) != 0)
1053 SignalCloseEvent(this, err);
1054 }
1055
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001056 bool readable() override { return (flags_ & DE_READ) != 0; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001057
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001058 void set_readable(bool value) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001059 flags_ = value ? (flags_ | DE_READ) : (flags_ & ~DE_READ);
1060 }
1061
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001062 bool writable() override { return (flags_ & DE_WRITE) != 0; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001063
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001064 void set_writable(bool value) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001065 flags_ = value ? (flags_ | DE_WRITE) : (flags_ & ~DE_WRITE);
1066 }
1067
1068 private:
1069 PhysicalSocketServer* ss_;
1070 int fd_;
1071 int flags_;
1072};
1073
1074AsyncFile* PhysicalSocketServer::CreateFile(int fd) {
1075 return new FileDispatcher(fd, this);
1076}
1077
1078#endif // WEBRTC_POSIX
1079
1080#if defined(WEBRTC_WIN)
Peter Boström0c4e06b2015-10-07 12:23:21 +02001081static uint32_t FlagsToEvents(uint32_t events) {
1082 uint32_t ffFD = FD_CLOSE;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001083 if (events & DE_READ)
1084 ffFD |= FD_READ;
1085 if (events & DE_WRITE)
1086 ffFD |= FD_WRITE;
1087 if (events & DE_CONNECT)
1088 ffFD |= FD_CONNECT;
1089 if (events & DE_ACCEPT)
1090 ffFD |= FD_ACCEPT;
1091 return ffFD;
1092}
1093
1094class EventDispatcher : public Dispatcher {
1095 public:
1096 EventDispatcher(PhysicalSocketServer *ss) : ss_(ss) {
1097 hev_ = WSACreateEvent();
1098 if (hev_) {
1099 ss_->Add(this);
1100 }
1101 }
1102
1103 ~EventDispatcher() {
1104 if (hev_ != NULL) {
1105 ss_->Remove(this);
1106 WSACloseEvent(hev_);
1107 hev_ = NULL;
1108 }
1109 }
1110
1111 virtual void Signal() {
1112 if (hev_ != NULL)
1113 WSASetEvent(hev_);
1114 }
1115
Peter Boström0c4e06b2015-10-07 12:23:21 +02001116 virtual uint32_t GetRequestedEvents() { return 0; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001117
Peter Boström0c4e06b2015-10-07 12:23:21 +02001118 virtual void OnPreEvent(uint32_t ff) { WSAResetEvent(hev_); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001119
Peter Boström0c4e06b2015-10-07 12:23:21 +02001120 virtual void OnEvent(uint32_t ff, int err) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001121
1122 virtual WSAEVENT GetWSAEvent() {
1123 return hev_;
1124 }
1125
1126 virtual SOCKET GetSocket() {
1127 return INVALID_SOCKET;
1128 }
1129
1130 virtual bool CheckSignalClose() { return false; }
1131
1132private:
1133 PhysicalSocketServer* ss_;
1134 WSAEVENT hev_;
1135};
honghaizcec0a082016-01-15 14:49:09 -08001136#endif // WEBRTC_WIN
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001137
1138// Sets the value of a boolean value to false when signaled.
1139class Signaler : public EventDispatcher {
1140 public:
1141 Signaler(PhysicalSocketServer* ss, bool* pf)
1142 : EventDispatcher(ss), pf_(pf) {
1143 }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001144 ~Signaler() override { }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001145
Peter Boström0c4e06b2015-10-07 12:23:21 +02001146 void OnEvent(uint32_t ff, int err) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001147 if (pf_)
1148 *pf_ = false;
1149 }
1150
1151 private:
1152 bool *pf_;
1153};
1154
1155PhysicalSocketServer::PhysicalSocketServer()
1156 : fWait_(false) {
1157 signal_wakeup_ = new Signaler(this, &fWait_);
1158#if defined(WEBRTC_WIN)
1159 socket_ev_ = WSACreateEvent();
1160#endif
1161}
1162
1163PhysicalSocketServer::~PhysicalSocketServer() {
1164#if defined(WEBRTC_WIN)
1165 WSACloseEvent(socket_ev_);
1166#endif
1167#if defined(WEBRTC_POSIX)
1168 signal_dispatcher_.reset();
1169#endif
1170 delete signal_wakeup_;
1171 ASSERT(dispatchers_.empty());
1172}
1173
1174void PhysicalSocketServer::WakeUp() {
1175 signal_wakeup_->Signal();
1176}
1177
1178Socket* PhysicalSocketServer::CreateSocket(int type) {
1179 return CreateSocket(AF_INET, type);
1180}
1181
1182Socket* PhysicalSocketServer::CreateSocket(int family, int type) {
1183 PhysicalSocket* socket = new PhysicalSocket(this);
1184 if (socket->Create(family, type)) {
1185 return socket;
1186 } else {
1187 delete socket;
jbauch095ae152015-12-18 01:39:55 -08001188 return nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001189 }
1190}
1191
1192AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int type) {
1193 return CreateAsyncSocket(AF_INET, type);
1194}
1195
1196AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int family, int type) {
1197 SocketDispatcher* dispatcher = new SocketDispatcher(this);
1198 if (dispatcher->Create(family, type)) {
1199 return dispatcher;
1200 } else {
1201 delete dispatcher;
jbauch095ae152015-12-18 01:39:55 -08001202 return nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001203 }
1204}
1205
1206AsyncSocket* PhysicalSocketServer::WrapSocket(SOCKET s) {
1207 SocketDispatcher* dispatcher = new SocketDispatcher(s, this);
1208 if (dispatcher->Initialize()) {
1209 return dispatcher;
1210 } else {
1211 delete dispatcher;
jbauch095ae152015-12-18 01:39:55 -08001212 return nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001213 }
1214}
1215
1216void PhysicalSocketServer::Add(Dispatcher *pdispatcher) {
1217 CritScope cs(&crit_);
1218 // Prevent duplicates. This can cause dead dispatchers to stick around.
1219 DispatcherList::iterator pos = std::find(dispatchers_.begin(),
1220 dispatchers_.end(),
1221 pdispatcher);
1222 if (pos != dispatchers_.end())
1223 return;
1224 dispatchers_.push_back(pdispatcher);
1225}
1226
1227void PhysicalSocketServer::Remove(Dispatcher *pdispatcher) {
1228 CritScope cs(&crit_);
1229 DispatcherList::iterator pos = std::find(dispatchers_.begin(),
1230 dispatchers_.end(),
1231 pdispatcher);
1232 // We silently ignore duplicate calls to Add, so we should silently ignore
1233 // the (expected) symmetric calls to Remove. Note that this may still hide
1234 // a real issue, so we at least log a warning about it.
1235 if (pos == dispatchers_.end()) {
1236 LOG(LS_WARNING) << "PhysicalSocketServer asked to remove a unknown "
1237 << "dispatcher, potentially from a duplicate call to Add.";
1238 return;
1239 }
1240 size_t index = pos - dispatchers_.begin();
1241 dispatchers_.erase(pos);
1242 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end();
1243 ++it) {
1244 if (index < **it) {
1245 --**it;
1246 }
1247 }
1248}
1249
1250#if defined(WEBRTC_POSIX)
1251bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) {
1252 // Calculate timing information
1253
1254 struct timeval *ptvWait = NULL;
1255 struct timeval tvWait;
1256 struct timeval tvStop;
1257 if (cmsWait != kForever) {
1258 // Calculate wait timeval
1259 tvWait.tv_sec = cmsWait / 1000;
1260 tvWait.tv_usec = (cmsWait % 1000) * 1000;
1261 ptvWait = &tvWait;
1262
1263 // Calculate when to return in a timeval
1264 gettimeofday(&tvStop, NULL);
1265 tvStop.tv_sec += tvWait.tv_sec;
1266 tvStop.tv_usec += tvWait.tv_usec;
1267 if (tvStop.tv_usec >= 1000000) {
1268 tvStop.tv_usec -= 1000000;
1269 tvStop.tv_sec += 1;
1270 }
1271 }
1272
1273 // Zero all fd_sets. Don't need to do this inside the loop since
1274 // select() zeros the descriptors not signaled
1275
1276 fd_set fdsRead;
1277 FD_ZERO(&fdsRead);
1278 fd_set fdsWrite;
1279 FD_ZERO(&fdsWrite);
pbos@webrtc.org27e58982014-10-07 17:56:53 +00001280 // Explicitly unpoison these FDs on MemorySanitizer which doesn't handle the
1281 // inline assembly in FD_ZERO.
1282 // http://crbug.com/344505
1283#ifdef MEMORY_SANITIZER
1284 __msan_unpoison(&fdsRead, sizeof(fdsRead));
1285 __msan_unpoison(&fdsWrite, sizeof(fdsWrite));
1286#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001287
1288 fWait_ = true;
1289
1290 while (fWait_) {
1291 int fdmax = -1;
1292 {
1293 CritScope cr(&crit_);
1294 for (size_t i = 0; i < dispatchers_.size(); ++i) {
1295 // Query dispatchers for read and write wait state
1296 Dispatcher *pdispatcher = dispatchers_[i];
1297 ASSERT(pdispatcher);
1298 if (!process_io && (pdispatcher != signal_wakeup_))
1299 continue;
1300 int fd = pdispatcher->GetDescriptor();
1301 if (fd > fdmax)
1302 fdmax = fd;
1303
Peter Boström0c4e06b2015-10-07 12:23:21 +02001304 uint32_t ff = pdispatcher->GetRequestedEvents();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001305 if (ff & (DE_READ | DE_ACCEPT))
1306 FD_SET(fd, &fdsRead);
1307 if (ff & (DE_WRITE | DE_CONNECT))
1308 FD_SET(fd, &fdsWrite);
1309 }
1310 }
1311
1312 // Wait then call handlers as appropriate
1313 // < 0 means error
1314 // 0 means timeout
1315 // > 0 means count of descriptors ready
1316 int n = select(fdmax + 1, &fdsRead, &fdsWrite, NULL, ptvWait);
1317
1318 // If error, return error.
1319 if (n < 0) {
1320 if (errno != EINTR) {
1321 LOG_E(LS_ERROR, EN, errno) << "select";
1322 return false;
1323 }
1324 // Else ignore the error and keep going. If this EINTR was for one of the
1325 // signals managed by this PhysicalSocketServer, the
1326 // PosixSignalDeliveryDispatcher will be in the signaled state in the next
1327 // iteration.
1328 } else if (n == 0) {
1329 // If timeout, return success
1330 return true;
1331 } else {
1332 // We have signaled descriptors
1333 CritScope cr(&crit_);
1334 for (size_t i = 0; i < dispatchers_.size(); ++i) {
1335 Dispatcher *pdispatcher = dispatchers_[i];
1336 int fd = pdispatcher->GetDescriptor();
Peter Boström0c4e06b2015-10-07 12:23:21 +02001337 uint32_t ff = 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001338 int errcode = 0;
1339
1340 // Reap any error code, which can be signaled through reads or writes.
jbauch095ae152015-12-18 01:39:55 -08001341 // TODO(pthatcher): Should we set errcode if getsockopt fails?
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001342 if (FD_ISSET(fd, &fdsRead) || FD_ISSET(fd, &fdsWrite)) {
1343 socklen_t len = sizeof(errcode);
1344 ::getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &len);
1345 }
1346
1347 // Check readable descriptors. If we're waiting on an accept, signal
1348 // that. Otherwise we're waiting for data, check to see if we're
1349 // readable or really closed.
jbauch095ae152015-12-18 01:39:55 -08001350 // TODO(pthatcher): Only peek at TCP descriptors.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001351 if (FD_ISSET(fd, &fdsRead)) {
1352 FD_CLR(fd, &fdsRead);
1353 if (pdispatcher->GetRequestedEvents() & DE_ACCEPT) {
1354 ff |= DE_ACCEPT;
1355 } else if (errcode || pdispatcher->IsDescriptorClosed()) {
1356 ff |= DE_CLOSE;
1357 } else {
1358 ff |= DE_READ;
1359 }
1360 }
1361
1362 // Check writable descriptors. If we're waiting on a connect, detect
1363 // success versus failure by the reaped error code.
1364 if (FD_ISSET(fd, &fdsWrite)) {
1365 FD_CLR(fd, &fdsWrite);
1366 if (pdispatcher->GetRequestedEvents() & DE_CONNECT) {
1367 if (!errcode) {
1368 ff |= DE_CONNECT;
1369 } else {
1370 ff |= DE_CLOSE;
1371 }
1372 } else {
1373 ff |= DE_WRITE;
1374 }
1375 }
1376
1377 // Tell the descriptor about the event.
1378 if (ff != 0) {
1379 pdispatcher->OnPreEvent(ff);
1380 pdispatcher->OnEvent(ff, errcode);
1381 }
1382 }
1383 }
1384
1385 // Recalc the time remaining to wait. Doing it here means it doesn't get
1386 // calced twice the first time through the loop
1387 if (ptvWait) {
1388 ptvWait->tv_sec = 0;
1389 ptvWait->tv_usec = 0;
1390 struct timeval tvT;
1391 gettimeofday(&tvT, NULL);
1392 if ((tvStop.tv_sec > tvT.tv_sec)
1393 || ((tvStop.tv_sec == tvT.tv_sec)
1394 && (tvStop.tv_usec > tvT.tv_usec))) {
1395 ptvWait->tv_sec = tvStop.tv_sec - tvT.tv_sec;
1396 ptvWait->tv_usec = tvStop.tv_usec - tvT.tv_usec;
1397 if (ptvWait->tv_usec < 0) {
1398 ASSERT(ptvWait->tv_sec > 0);
1399 ptvWait->tv_usec += 1000000;
1400 ptvWait->tv_sec -= 1;
1401 }
1402 }
1403 }
1404 }
1405
1406 return true;
1407}
1408
1409static void GlobalSignalHandler(int signum) {
1410 PosixSignalHandler::Instance()->OnPosixSignalReceived(signum);
1411}
1412
1413bool PhysicalSocketServer::SetPosixSignalHandler(int signum,
1414 void (*handler)(int)) {
1415 // If handler is SIG_IGN or SIG_DFL then clear our user-level handler,
1416 // otherwise set one.
1417 if (handler == SIG_IGN || handler == SIG_DFL) {
1418 if (!InstallSignal(signum, handler)) {
1419 return false;
1420 }
1421 if (signal_dispatcher_) {
1422 signal_dispatcher_->ClearHandler(signum);
1423 if (!signal_dispatcher_->HasHandlers()) {
1424 signal_dispatcher_.reset();
1425 }
1426 }
1427 } else {
1428 if (!signal_dispatcher_) {
1429 signal_dispatcher_.reset(new PosixSignalDispatcher(this));
1430 }
1431 signal_dispatcher_->SetHandler(signum, handler);
1432 if (!InstallSignal(signum, &GlobalSignalHandler)) {
1433 return false;
1434 }
1435 }
1436 return true;
1437}
1438
1439Dispatcher* PhysicalSocketServer::signal_dispatcher() {
1440 return signal_dispatcher_.get();
1441}
1442
1443bool PhysicalSocketServer::InstallSignal(int signum, void (*handler)(int)) {
1444 struct sigaction act;
1445 // It doesn't really matter what we set this mask to.
1446 if (sigemptyset(&act.sa_mask) != 0) {
1447 LOG_ERR(LS_ERROR) << "Couldn't set mask";
1448 return false;
1449 }
1450 act.sa_handler = handler;
1451#if !defined(__native_client__)
1452 // Use SA_RESTART so that our syscalls don't get EINTR, since we don't need it
1453 // and it's a nuisance. Though some syscalls still return EINTR and there's no
1454 // real standard for which ones. :(
1455 act.sa_flags = SA_RESTART;
1456#else
1457 act.sa_flags = 0;
1458#endif
1459 if (sigaction(signum, &act, NULL) != 0) {
1460 LOG_ERR(LS_ERROR) << "Couldn't set sigaction";
1461 return false;
1462 }
1463 return true;
1464}
1465#endif // WEBRTC_POSIX
1466
1467#if defined(WEBRTC_WIN)
1468bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) {
1469 int cmsTotal = cmsWait;
1470 int cmsElapsed = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001471 uint32_t msStart = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001472
1473 fWait_ = true;
1474 while (fWait_) {
1475 std::vector<WSAEVENT> events;
1476 std::vector<Dispatcher *> event_owners;
1477
1478 events.push_back(socket_ev_);
1479
1480 {
1481 CritScope cr(&crit_);
1482 size_t i = 0;
1483 iterators_.push_back(&i);
1484 // Don't track dispatchers_.size(), because we want to pick up any new
1485 // dispatchers that were added while processing the loop.
1486 while (i < dispatchers_.size()) {
1487 Dispatcher* disp = dispatchers_[i++];
1488 if (!process_io && (disp != signal_wakeup_))
1489 continue;
1490 SOCKET s = disp->GetSocket();
1491 if (disp->CheckSignalClose()) {
1492 // We just signalled close, don't poll this socket
1493 } else if (s != INVALID_SOCKET) {
1494 WSAEventSelect(s,
1495 events[0],
1496 FlagsToEvents(disp->GetRequestedEvents()));
1497 } else {
1498 events.push_back(disp->GetWSAEvent());
1499 event_owners.push_back(disp);
1500 }
1501 }
1502 ASSERT(iterators_.back() == &i);
1503 iterators_.pop_back();
1504 }
1505
1506 // Which is shorter, the delay wait or the asked wait?
1507
1508 int cmsNext;
1509 if (cmsWait == kForever) {
1510 cmsNext = cmsWait;
1511 } else {
andresp@webrtc.orgff689be2015-02-12 11:54:26 +00001512 cmsNext = std::max(0, cmsTotal - cmsElapsed);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001513 }
1514
1515 // Wait for one of the events to signal
1516 DWORD dw = WSAWaitForMultipleEvents(static_cast<DWORD>(events.size()),
1517 &events[0],
1518 false,
1519 cmsNext,
1520 false);
1521
1522 if (dw == WSA_WAIT_FAILED) {
1523 // Failed?
jbauch095ae152015-12-18 01:39:55 -08001524 // TODO(pthatcher): need a better strategy than this!
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001525 WSAGetLastError();
1526 ASSERT(false);
1527 return false;
1528 } else if (dw == WSA_WAIT_TIMEOUT) {
1529 // Timeout?
1530 return true;
1531 } else {
1532 // Figure out which one it is and call it
1533 CritScope cr(&crit_);
1534 int index = dw - WSA_WAIT_EVENT_0;
1535 if (index > 0) {
1536 --index; // The first event is the socket event
1537 event_owners[index]->OnPreEvent(0);
1538 event_owners[index]->OnEvent(0, 0);
1539 } else if (process_io) {
1540 size_t i = 0, end = dispatchers_.size();
1541 iterators_.push_back(&i);
1542 iterators_.push_back(&end); // Don't iterate over new dispatchers.
1543 while (i < end) {
1544 Dispatcher* disp = dispatchers_[i++];
1545 SOCKET s = disp->GetSocket();
1546 if (s == INVALID_SOCKET)
1547 continue;
1548
1549 WSANETWORKEVENTS wsaEvents;
1550 int err = WSAEnumNetworkEvents(s, events[0], &wsaEvents);
1551 if (err == 0) {
1552
1553#if LOGGING
1554 {
1555 if ((wsaEvents.lNetworkEvents & FD_READ) &&
1556 wsaEvents.iErrorCode[FD_READ_BIT] != 0) {
1557 LOG(WARNING) << "PhysicalSocketServer got FD_READ_BIT error "
1558 << wsaEvents.iErrorCode[FD_READ_BIT];
1559 }
1560 if ((wsaEvents.lNetworkEvents & FD_WRITE) &&
1561 wsaEvents.iErrorCode[FD_WRITE_BIT] != 0) {
1562 LOG(WARNING) << "PhysicalSocketServer got FD_WRITE_BIT error "
1563 << wsaEvents.iErrorCode[FD_WRITE_BIT];
1564 }
1565 if ((wsaEvents.lNetworkEvents & FD_CONNECT) &&
1566 wsaEvents.iErrorCode[FD_CONNECT_BIT] != 0) {
1567 LOG(WARNING) << "PhysicalSocketServer got FD_CONNECT_BIT error "
1568 << wsaEvents.iErrorCode[FD_CONNECT_BIT];
1569 }
1570 if ((wsaEvents.lNetworkEvents & FD_ACCEPT) &&
1571 wsaEvents.iErrorCode[FD_ACCEPT_BIT] != 0) {
1572 LOG(WARNING) << "PhysicalSocketServer got FD_ACCEPT_BIT error "
1573 << wsaEvents.iErrorCode[FD_ACCEPT_BIT];
1574 }
1575 if ((wsaEvents.lNetworkEvents & FD_CLOSE) &&
1576 wsaEvents.iErrorCode[FD_CLOSE_BIT] != 0) {
1577 LOG(WARNING) << "PhysicalSocketServer got FD_CLOSE_BIT error "
1578 << wsaEvents.iErrorCode[FD_CLOSE_BIT];
1579 }
1580 }
1581#endif
Peter Boström0c4e06b2015-10-07 12:23:21 +02001582 uint32_t ff = 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001583 int errcode = 0;
1584 if (wsaEvents.lNetworkEvents & FD_READ)
1585 ff |= DE_READ;
1586 if (wsaEvents.lNetworkEvents & FD_WRITE)
1587 ff |= DE_WRITE;
1588 if (wsaEvents.lNetworkEvents & FD_CONNECT) {
1589 if (wsaEvents.iErrorCode[FD_CONNECT_BIT] == 0) {
1590 ff |= DE_CONNECT;
1591 } else {
1592 ff |= DE_CLOSE;
1593 errcode = wsaEvents.iErrorCode[FD_CONNECT_BIT];
1594 }
1595 }
1596 if (wsaEvents.lNetworkEvents & FD_ACCEPT)
1597 ff |= DE_ACCEPT;
1598 if (wsaEvents.lNetworkEvents & FD_CLOSE) {
1599 ff |= DE_CLOSE;
1600 errcode = wsaEvents.iErrorCode[FD_CLOSE_BIT];
1601 }
1602 if (ff != 0) {
1603 disp->OnPreEvent(ff);
1604 disp->OnEvent(ff, errcode);
1605 }
1606 }
1607 }
1608 ASSERT(iterators_.back() == &end);
1609 iterators_.pop_back();
1610 ASSERT(iterators_.back() == &i);
1611 iterators_.pop_back();
1612 }
1613
1614 // Reset the network event until new activity occurs
1615 WSAResetEvent(socket_ev_);
1616 }
1617
1618 // Break?
1619 if (!fWait_)
1620 break;
1621 cmsElapsed = TimeSince(msStart);
1622 if ((cmsWait != kForever) && (cmsElapsed >= cmsWait)) {
1623 break;
1624 }
1625 }
1626
1627 // Done
1628 return true;
1629}
honghaizcec0a082016-01-15 14:49:09 -08001630#endif // WEBRTC_WIN
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001631
1632} // namespace rtc