blob: 524617221c894ee8d5530d4167f1a45ac9b3f387 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#if defined(_MSC_VER) && _MSC_VER < 1300
12#pragma warning(disable:4786)
13#endif
14
15#include <assert.h>
16
pbos@webrtc.org27e58982014-10-07 17:56:53 +000017#ifdef MEMORY_SANITIZER
18#include <sanitizer/msan_interface.h>
19#endif
20
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000021#if defined(WEBRTC_POSIX)
22#include <string.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <sys/time.h>
26#include <sys/select.h>
27#include <unistd.h>
28#include <signal.h>
29#endif
30
31#if defined(WEBRTC_WIN)
32#define WIN32_LEAN_AND_MEAN
33#include <windows.h>
34#include <winsock2.h>
35#include <ws2tcpip.h>
36#undef SetPort
37#endif
38
39#include <algorithm>
40#include <map>
41
tfarina5237aaf2015-11-10 23:44:30 -080042#include "webrtc/base/arraysize.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000043#include "webrtc/base/basictypes.h"
44#include "webrtc/base/byteorder.h"
45#include "webrtc/base/common.h"
46#include "webrtc/base/logging.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047#include "webrtc/base/physicalsocketserver.h"
48#include "webrtc/base/timeutils.h"
49#include "webrtc/base/winping.h"
50#include "webrtc/base/win32socketinit.h"
51
52// stm: this will tell us if we are on OSX
53#ifdef HAVE_CONFIG_H
54#include "config.h"
55#endif
56
57#if defined(WEBRTC_POSIX)
58#include <netinet/tcp.h> // for TCP_NODELAY
59#define IP_MTU 14 // Until this is integrated from linux/in.h to netinet/in.h
60typedef void* SockOptArg;
61#endif // WEBRTC_POSIX
62
63#if defined(WEBRTC_WIN)
64typedef char* SockOptArg;
65#endif
66
67namespace rtc {
68
69#if defined(WEBRTC_WIN)
70// Standard MTUs, from RFC 1191
Peter Boström0c4e06b2015-10-07 12:23:21 +020071const uint16_t PACKET_MAXIMUMS[] = {
72 65535, // Theoretical maximum, Hyperchannel
73 32000, // Nothing
74 17914, // 16Mb IBM Token Ring
75 8166, // IEEE 802.4
76 // 4464, // IEEE 802.5 (4Mb max)
77 4352, // FDDI
78 // 2048, // Wideband Network
79 2002, // IEEE 802.5 (4Mb recommended)
80 // 1536, // Expermental Ethernet Networks
81 // 1500, // Ethernet, Point-to-Point (default)
82 1492, // IEEE 802.3
83 1006, // SLIP, ARPANET
84 // 576, // X.25 Networks
85 // 544, // DEC IP Portal
86 // 512, // NETBIOS
87 508, // IEEE 802/Source-Rt Bridge, ARCNET
88 296, // Point-to-Point (low delay)
89 68, // Official minimum
90 0, // End of list marker
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000091};
92
93static const int IP_HEADER_SIZE = 20u;
94static const int IPV6_HEADER_SIZE = 40u;
95static const int ICMP_HEADER_SIZE = 8u;
96static const int ICMP_PING_TIMEOUT_MILLIS = 10000u;
97#endif
98
jbauch095ae152015-12-18 01:39:55 -080099PhysicalSocket::PhysicalSocket(PhysicalSocketServer* ss, SOCKET s)
100 : ss_(ss), s_(s), enabled_events_(0), error_(0),
101 state_((s == INVALID_SOCKET) ? CS_CLOSED : CS_CONNECTED),
102 resolver_(nullptr) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000103#if defined(WEBRTC_WIN)
jbauch095ae152015-12-18 01:39:55 -0800104 // EnsureWinsockInit() ensures that winsock is initialized. The default
105 // version of this function doesn't do anything because winsock is
106 // initialized by constructor of a static object. If neccessary libjingle
107 // users can link it with a different version of this function by replacing
108 // win32socketinit.cc. See win32socketinit.cc for more details.
109 EnsureWinsockInit();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000110#endif
jbauch095ae152015-12-18 01:39:55 -0800111 if (s_ != INVALID_SOCKET) {
112 enabled_events_ = DE_READ | DE_WRITE;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000113
jbauch095ae152015-12-18 01:39:55 -0800114 int type = SOCK_STREAM;
115 socklen_t len = sizeof(type);
116 VERIFY(0 == getsockopt(s_, SOL_SOCKET, SO_TYPE, (SockOptArg)&type, &len));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000117 udp_ = (SOCK_DGRAM == type);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000118 }
jbauch095ae152015-12-18 01:39:55 -0800119}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000120
jbauch095ae152015-12-18 01:39:55 -0800121PhysicalSocket::~PhysicalSocket() {
122 Close();
123}
124
125bool PhysicalSocket::Create(int family, int type) {
126 Close();
127 s_ = ::socket(family, type, 0);
128 udp_ = (SOCK_DGRAM == type);
129 UpdateLastError();
130 if (udp_)
131 enabled_events_ = DE_READ | DE_WRITE;
132 return s_ != INVALID_SOCKET;
133}
134
135SocketAddress PhysicalSocket::GetLocalAddress() const {
136 sockaddr_storage addr_storage = {0};
137 socklen_t addrlen = sizeof(addr_storage);
138 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
139 int result = ::getsockname(s_, addr, &addrlen);
140 SocketAddress address;
141 if (result >= 0) {
142 SocketAddressFromSockAddrStorage(addr_storage, &address);
143 } else {
144 LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket="
145 << s_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000146 }
jbauch095ae152015-12-18 01:39:55 -0800147 return address;
148}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000149
jbauch095ae152015-12-18 01:39:55 -0800150SocketAddress PhysicalSocket::GetRemoteAddress() const {
151 sockaddr_storage addr_storage = {0};
152 socklen_t addrlen = sizeof(addr_storage);
153 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
154 int result = ::getpeername(s_, addr, &addrlen);
155 SocketAddress address;
156 if (result >= 0) {
157 SocketAddressFromSockAddrStorage(addr_storage, &address);
158 } else {
159 LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket="
160 << s_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000161 }
jbauch095ae152015-12-18 01:39:55 -0800162 return address;
163}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000164
jbauch095ae152015-12-18 01:39:55 -0800165int PhysicalSocket::Bind(const SocketAddress& bind_addr) {
166 sockaddr_storage addr_storage;
167 size_t len = bind_addr.ToSockAddrStorage(&addr_storage);
168 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
169 int err = ::bind(s_, addr, static_cast<int>(len));
170 UpdateLastError();
tfarinaa41ab932015-10-30 16:08:48 -0700171#if !defined(NDEBUG)
jbauch095ae152015-12-18 01:39:55 -0800172 if (0 == err) {
173 dbg_addr_ = "Bound @ ";
174 dbg_addr_.append(GetLocalAddress().ToString());
175 }
tfarinaa41ab932015-10-30 16:08:48 -0700176#endif
jbauch095ae152015-12-18 01:39:55 -0800177 return err;
178}
179
180int PhysicalSocket::Connect(const SocketAddress& addr) {
181 // TODO(pthatcher): Implicit creation is required to reconnect...
182 // ...but should we make it more explicit?
183 if (state_ != CS_CLOSED) {
184 SetError(EALREADY);
185 return SOCKET_ERROR;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000186 }
jbauch095ae152015-12-18 01:39:55 -0800187 if (addr.IsUnresolvedIP()) {
188 LOG(LS_VERBOSE) << "Resolving addr in PhysicalSocket::Connect";
189 resolver_ = new AsyncResolver();
190 resolver_->SignalDone.connect(this, &PhysicalSocket::OnResolveResult);
191 resolver_->Start(addr);
192 state_ = CS_CONNECTING;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000193 return 0;
194 }
195
jbauch095ae152015-12-18 01:39:55 -0800196 return DoConnect(addr);
197}
198
199int PhysicalSocket::DoConnect(const SocketAddress& connect_addr) {
200 if ((s_ == INVALID_SOCKET) &&
201 !Create(connect_addr.family(), SOCK_STREAM)) {
202 return SOCKET_ERROR;
203 }
204 sockaddr_storage addr_storage;
205 size_t len = connect_addr.ToSockAddrStorage(&addr_storage);
206 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
207 int err = ::connect(s_, addr, static_cast<int>(len));
208 UpdateLastError();
209 if (err == 0) {
210 state_ = CS_CONNECTED;
211 } else if (IsBlockingError(GetError())) {
212 state_ = CS_CONNECTING;
213 enabled_events_ |= DE_CONNECT;
214 } else {
215 return SOCKET_ERROR;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000216 }
217
jbauch095ae152015-12-18 01:39:55 -0800218 enabled_events_ |= DE_READ | DE_WRITE;
219 return 0;
220}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000221
jbauch095ae152015-12-18 01:39:55 -0800222int PhysicalSocket::GetError() const {
223 CritScope cs(&crit_);
224 return error_;
225}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000226
jbauch095ae152015-12-18 01:39:55 -0800227void PhysicalSocket::SetError(int error) {
228 CritScope cs(&crit_);
229 error_ = error;
230}
231
232AsyncSocket::ConnState PhysicalSocket::GetState() const {
233 return state_;
234}
235
236int PhysicalSocket::GetOption(Option opt, int* value) {
237 int slevel;
238 int sopt;
239 if (TranslateOption(opt, &slevel, &sopt) == -1)
240 return -1;
241 socklen_t optlen = sizeof(*value);
242 int ret = ::getsockopt(s_, slevel, sopt, (SockOptArg)value, &optlen);
243 if (ret != -1 && opt == OPT_DONTFRAGMENT) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000244#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
jbauch095ae152015-12-18 01:39:55 -0800245 *value = (*value != IP_PMTUDISC_DONT) ? 1 : 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000246#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000247 }
jbauch095ae152015-12-18 01:39:55 -0800248 return ret;
249}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000250
jbauch095ae152015-12-18 01:39:55 -0800251int PhysicalSocket::SetOption(Option opt, int value) {
252 int slevel;
253 int sopt;
254 if (TranslateOption(opt, &slevel, &sopt) == -1)
255 return -1;
256 if (opt == OPT_DONTFRAGMENT) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000257#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
jbauch095ae152015-12-18 01:39:55 -0800258 value = (value) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000259#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000260 }
jbauch095ae152015-12-18 01:39:55 -0800261 return ::setsockopt(s_, slevel, sopt, (SockOptArg)&value, sizeof(value));
262}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000263
jbauch095ae152015-12-18 01:39:55 -0800264int PhysicalSocket::Send(const void* pv, size_t cb) {
265 int sent = ::send(s_, reinterpret_cast<const char *>(pv), (int)cb,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000266#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
jbauch095ae152015-12-18 01:39:55 -0800267 // Suppress SIGPIPE. Without this, attempting to send on a socket whose
268 // other end is closed will result in a SIGPIPE signal being raised to
269 // our process, which by default will terminate the process, which we
270 // don't want. By specifying this flag, we'll just get the error EPIPE
271 // instead and can handle the error gracefully.
272 MSG_NOSIGNAL
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000273#else
jbauch095ae152015-12-18 01:39:55 -0800274 0
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000275#endif
jbauch095ae152015-12-18 01:39:55 -0800276 );
277 UpdateLastError();
278 MaybeRemapSendError();
279 // We have seen minidumps where this may be false.
280 ASSERT(sent <= static_cast<int>(cb));
281 if ((sent < 0) && IsBlockingError(GetError())) {
282 enabled_events_ |= DE_WRITE;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000283 }
jbauch095ae152015-12-18 01:39:55 -0800284 return sent;
285}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000286
jbauch095ae152015-12-18 01:39:55 -0800287int PhysicalSocket::SendTo(const void* buffer,
288 size_t length,
289 const SocketAddress& addr) {
290 sockaddr_storage saddr;
291 size_t len = addr.ToSockAddrStorage(&saddr);
292 int sent = ::sendto(
293 s_, static_cast<const char *>(buffer), static_cast<int>(length),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000294#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
jbauch095ae152015-12-18 01:39:55 -0800295 // Suppress SIGPIPE. See above for explanation.
296 MSG_NOSIGNAL,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000297#else
jbauch095ae152015-12-18 01:39:55 -0800298 0,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000299#endif
jbauch095ae152015-12-18 01:39:55 -0800300 reinterpret_cast<sockaddr*>(&saddr), static_cast<int>(len));
301 UpdateLastError();
302 MaybeRemapSendError();
303 // We have seen minidumps where this may be false.
304 ASSERT(sent <= static_cast<int>(length));
305 if ((sent < 0) && IsBlockingError(GetError())) {
306 enabled_events_ |= DE_WRITE;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000307 }
jbauch095ae152015-12-18 01:39:55 -0800308 return sent;
309}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000310
jbauch095ae152015-12-18 01:39:55 -0800311int PhysicalSocket::Recv(void* buffer, size_t length) {
312 int received = ::recv(s_, static_cast<char*>(buffer),
313 static_cast<int>(length), 0);
314 if ((received == 0) && (length != 0)) {
315 // Note: on graceful shutdown, recv can return 0. In this case, we
316 // pretend it is blocking, and then signal close, so that simplifying
317 // assumptions can be made about Recv.
318 LOG(LS_WARNING) << "EOF from socket; deferring close event";
319 // Must turn this back on so that the select() loop will notice the close
320 // event.
321 enabled_events_ |= DE_READ;
322 SetError(EWOULDBLOCK);
323 return SOCKET_ERROR;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000324 }
jbauch095ae152015-12-18 01:39:55 -0800325 UpdateLastError();
326 int error = GetError();
327 bool success = (received >= 0) || IsBlockingError(error);
328 if (udp_ || success) {
329 enabled_events_ |= DE_READ;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000330 }
jbauch095ae152015-12-18 01:39:55 -0800331 if (!success) {
332 LOG_F(LS_VERBOSE) << "Error = " << error;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000333 }
jbauch095ae152015-12-18 01:39:55 -0800334 return received;
335}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000336
jbauch095ae152015-12-18 01:39:55 -0800337int PhysicalSocket::RecvFrom(void* buffer,
338 size_t length,
339 SocketAddress* out_addr) {
340 sockaddr_storage addr_storage;
341 socklen_t addr_len = sizeof(addr_storage);
342 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
343 int received = ::recvfrom(s_, static_cast<char*>(buffer),
344 static_cast<int>(length), 0, addr, &addr_len);
345 UpdateLastError();
346 if ((received >= 0) && (out_addr != nullptr))
347 SocketAddressFromSockAddrStorage(addr_storage, out_addr);
348 int error = GetError();
349 bool success = (received >= 0) || IsBlockingError(error);
350 if (udp_ || success) {
351 enabled_events_ |= DE_READ;
352 }
353 if (!success) {
354 LOG_F(LS_VERBOSE) << "Error = " << error;
355 }
356 return received;
357}
358
359int PhysicalSocket::Listen(int backlog) {
360 int err = ::listen(s_, backlog);
361 UpdateLastError();
362 if (err == 0) {
363 state_ = CS_CONNECTING;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000364 enabled_events_ |= DE_ACCEPT;
jbauch095ae152015-12-18 01:39:55 -0800365#if !defined(NDEBUG)
366 dbg_addr_ = "Listening @ ";
367 dbg_addr_.append(GetLocalAddress().ToString());
368#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000369 }
jbauch095ae152015-12-18 01:39:55 -0800370 return err;
371}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000372
jbauch095ae152015-12-18 01:39:55 -0800373AsyncSocket* PhysicalSocket::Accept(SocketAddress* out_addr) {
374 // Always re-subscribe DE_ACCEPT to make sure new incoming connections will
375 // trigger an event even if DoAccept returns an error here.
376 enabled_events_ |= DE_ACCEPT;
377 sockaddr_storage addr_storage;
378 socklen_t addr_len = sizeof(addr_storage);
379 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
380 SOCKET s = DoAccept(s_, addr, &addr_len);
381 UpdateLastError();
382 if (s == INVALID_SOCKET)
383 return nullptr;
384 if (out_addr != nullptr)
385 SocketAddressFromSockAddrStorage(addr_storage, out_addr);
386 return ss_->WrapSocket(s);
387}
388
389int PhysicalSocket::Close() {
390 if (s_ == INVALID_SOCKET)
391 return 0;
392 int err = ::closesocket(s_);
393 UpdateLastError();
394 s_ = INVALID_SOCKET;
395 state_ = CS_CLOSED;
396 enabled_events_ = 0;
397 if (resolver_) {
398 resolver_->Destroy(false);
399 resolver_ = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000400 }
jbauch095ae152015-12-18 01:39:55 -0800401 return err;
402}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000403
jbauch095ae152015-12-18 01:39:55 -0800404int PhysicalSocket::EstimateMTU(uint16_t* mtu) {
405 SocketAddress addr = GetRemoteAddress();
406 if (addr.IsAnyIP()) {
407 SetError(ENOTCONN);
408 return -1;
409 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000410
411#if defined(WEBRTC_WIN)
jbauch095ae152015-12-18 01:39:55 -0800412 // Gets the interface MTU (TTL=1) for the interface used to reach |addr|.
413 WinPing ping;
414 if (!ping.IsValid()) {
415 SetError(EINVAL); // can't think of a better error ID
416 return -1;
417 }
418 int header_size = ICMP_HEADER_SIZE;
419 if (addr.family() == AF_INET6) {
420 header_size += IPV6_HEADER_SIZE;
421 } else if (addr.family() == AF_INET) {
422 header_size += IP_HEADER_SIZE;
423 }
424
425 for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) {
426 int32_t size = PACKET_MAXIMUMS[level] - header_size;
427 WinPing::PingResult result = ping.Ping(addr.ipaddr(), size,
428 ICMP_PING_TIMEOUT_MILLIS,
429 1, false);
430 if (result == WinPing::PING_FAIL) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000431 SetError(EINVAL); // can't think of a better error ID
432 return -1;
jbauch095ae152015-12-18 01:39:55 -0800433 } else if (result != WinPing::PING_TOO_LARGE) {
434 *mtu = PACKET_MAXIMUMS[level];
435 return 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000436 }
jbauch095ae152015-12-18 01:39:55 -0800437 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000438
jbauch095ae152015-12-18 01:39:55 -0800439 ASSERT(false);
440 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000441#elif defined(WEBRTC_MAC)
jbauch095ae152015-12-18 01:39:55 -0800442 // No simple way to do this on Mac OS X.
443 // SIOCGIFMTU would work if we knew which interface would be used, but
444 // figuring that out is pretty complicated. For now we'll return an error
445 // and let the caller pick a default MTU.
446 SetError(EINVAL);
447 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000448#elif defined(WEBRTC_LINUX)
jbauch095ae152015-12-18 01:39:55 -0800449 // Gets the path MTU.
450 int value;
451 socklen_t vlen = sizeof(value);
452 int err = getsockopt(s_, IPPROTO_IP, IP_MTU, &value, &vlen);
453 if (err < 0) {
454 UpdateLastError();
455 return err;
456 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000457
jbauch095ae152015-12-18 01:39:55 -0800458 ASSERT((0 <= value) && (value <= 65536));
459 *mtu = value;
460 return 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000461#elif defined(__native_client__)
jbauch095ae152015-12-18 01:39:55 -0800462 // Most socket operations, including this, will fail in NaCl's sandbox.
463 error_ = EACCES;
464 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000465#endif
jbauch095ae152015-12-18 01:39:55 -0800466}
467
468
469SOCKET PhysicalSocket::DoAccept(SOCKET socket,
470 sockaddr* addr,
471 socklen_t* addrlen) {
472 return ::accept(socket, addr, addrlen);
473}
474
475void PhysicalSocket::OnResolveResult(AsyncResolverInterface* resolver) {
476 if (resolver != resolver_) {
477 return;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000478 }
479
jbauch095ae152015-12-18 01:39:55 -0800480 int error = resolver_->GetError();
481 if (error == 0) {
482 error = DoConnect(resolver_->address());
483 } else {
484 Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000485 }
486
jbauch095ae152015-12-18 01:39:55 -0800487 if (error) {
488 SetError(error);
489 SignalCloseEvent(this, error);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000490 }
jbauch095ae152015-12-18 01:39:55 -0800491}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000492
jbauch095ae152015-12-18 01:39:55 -0800493void PhysicalSocket::UpdateLastError() {
494 SetError(LAST_SYSTEM_ERROR);
495}
496
497void PhysicalSocket::MaybeRemapSendError() {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000498#if defined(WEBRTC_MAC)
jbauch095ae152015-12-18 01:39:55 -0800499 // https://developer.apple.com/library/mac/documentation/Darwin/
500 // Reference/ManPages/man2/sendto.2.html
501 // ENOBUFS - The output queue for a network interface is full.
502 // This generally indicates that the interface has stopped sending,
503 // but may be caused by transient congestion.
504 if (GetError() == ENOBUFS) {
505 SetError(EWOULDBLOCK);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000506 }
jbauch095ae152015-12-18 01:39:55 -0800507#endif
508}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000509
jbauch095ae152015-12-18 01:39:55 -0800510int PhysicalSocket::TranslateOption(Option opt, int* slevel, int* sopt) {
511 switch (opt) {
512 case OPT_DONTFRAGMENT:
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000513#if defined(WEBRTC_WIN)
jbauch095ae152015-12-18 01:39:55 -0800514 *slevel = IPPROTO_IP;
515 *sopt = IP_DONTFRAGMENT;
516 break;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000517#elif defined(WEBRTC_MAC) || defined(BSD) || defined(__native_client__)
jbauch095ae152015-12-18 01:39:55 -0800518 LOG(LS_WARNING) << "Socket::OPT_DONTFRAGMENT not supported.";
519 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000520#elif defined(WEBRTC_POSIX)
jbauch095ae152015-12-18 01:39:55 -0800521 *slevel = IPPROTO_IP;
522 *sopt = IP_MTU_DISCOVER;
523 break;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000524#endif
jbauch095ae152015-12-18 01:39:55 -0800525 case OPT_RCVBUF:
526 *slevel = SOL_SOCKET;
527 *sopt = SO_RCVBUF;
528 break;
529 case OPT_SNDBUF:
530 *slevel = SOL_SOCKET;
531 *sopt = SO_SNDBUF;
532 break;
533 case OPT_NODELAY:
534 *slevel = IPPROTO_TCP;
535 *sopt = TCP_NODELAY;
536 break;
537 case OPT_DSCP:
538 LOG(LS_WARNING) << "Socket::OPT_DSCP not supported.";
539 return -1;
540 case OPT_RTP_SENDTIME_EXTN_ID:
541 return -1; // No logging is necessary as this not a OS socket option.
542 default:
543 ASSERT(false);
544 return -1;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000545 }
jbauch095ae152015-12-18 01:39:55 -0800546 return 0;
547}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000548
549#if defined(WEBRTC_POSIX)
550class EventDispatcher : public Dispatcher {
551 public:
552 EventDispatcher(PhysicalSocketServer* ss) : ss_(ss), fSignaled_(false) {
553 if (pipe(afd_) < 0)
554 LOG(LERROR) << "pipe failed";
555 ss_->Add(this);
556 }
557
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000558 ~EventDispatcher() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000559 ss_->Remove(this);
560 close(afd_[0]);
561 close(afd_[1]);
562 }
563
564 virtual void Signal() {
565 CritScope cs(&crit_);
566 if (!fSignaled_) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200567 const uint8_t b[1] = {0};
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000568 if (VERIFY(1 == write(afd_[1], b, sizeof(b)))) {
569 fSignaled_ = true;
570 }
571 }
572 }
573
Peter Boström0c4e06b2015-10-07 12:23:21 +0200574 uint32_t GetRequestedEvents() override { return DE_READ; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000575
Peter Boström0c4e06b2015-10-07 12:23:21 +0200576 void OnPreEvent(uint32_t ff) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000577 // It is not possible to perfectly emulate an auto-resetting event with
578 // pipes. This simulates it by resetting before the event is handled.
579
580 CritScope cs(&crit_);
581 if (fSignaled_) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200582 uint8_t b[4]; // Allow for reading more than 1 byte, but expect 1.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000583 VERIFY(1 == read(afd_[0], b, sizeof(b)));
584 fSignaled_ = false;
585 }
586 }
587
Peter Boström0c4e06b2015-10-07 12:23:21 +0200588 void OnEvent(uint32_t ff, int err) override { ASSERT(false); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000589
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000590 int GetDescriptor() override { return afd_[0]; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000591
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000592 bool IsDescriptorClosed() override { return false; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000593
594 private:
595 PhysicalSocketServer *ss_;
596 int afd_[2];
597 bool fSignaled_;
598 CriticalSection crit_;
599};
600
601// These two classes use the self-pipe trick to deliver POSIX signals to our
602// select loop. This is the only safe, reliable, cross-platform way to do
603// non-trivial things with a POSIX signal in an event-driven program (until
604// proper pselect() implementations become ubiquitous).
605
606class PosixSignalHandler {
607 public:
608 // POSIX only specifies 32 signals, but in principle the system might have
609 // more and the programmer might choose to use them, so we size our array
610 // for 128.
611 static const int kNumPosixSignals = 128;
612
613 // There is just a single global instance. (Signal handlers do not get any
614 // sort of user-defined void * parameter, so they can't access anything that
615 // isn't global.)
616 static PosixSignalHandler* Instance() {
Andrew MacDonald469c2c02015-05-22 17:50:26 -0700617 RTC_DEFINE_STATIC_LOCAL(PosixSignalHandler, instance, ());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000618 return &instance;
619 }
620
621 // Returns true if the given signal number is set.
622 bool IsSignalSet(int signum) const {
tfarina5237aaf2015-11-10 23:44:30 -0800623 ASSERT(signum < static_cast<int>(arraysize(received_signal_)));
624 if (signum < static_cast<int>(arraysize(received_signal_))) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000625 return received_signal_[signum];
626 } else {
627 return false;
628 }
629 }
630
631 // Clears the given signal number.
632 void ClearSignal(int signum) {
tfarina5237aaf2015-11-10 23:44:30 -0800633 ASSERT(signum < static_cast<int>(arraysize(received_signal_)));
634 if (signum < static_cast<int>(arraysize(received_signal_))) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000635 received_signal_[signum] = false;
636 }
637 }
638
639 // Returns the file descriptor to monitor for signal events.
640 int GetDescriptor() const {
641 return afd_[0];
642 }
643
644 // This is called directly from our real signal handler, so it must be
645 // signal-handler-safe. That means it cannot assume anything about the
646 // user-level state of the process, since the handler could be executed at any
647 // time on any thread.
648 void OnPosixSignalReceived(int signum) {
tfarina5237aaf2015-11-10 23:44:30 -0800649 if (signum >= static_cast<int>(arraysize(received_signal_))) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000650 // We don't have space in our array for this.
651 return;
652 }
653 // Set a flag saying we've seen this signal.
654 received_signal_[signum] = true;
655 // Notify application code that we got a signal.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200656 const uint8_t b[1] = {0};
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000657 if (-1 == write(afd_[1], b, sizeof(b))) {
658 // Nothing we can do here. If there's an error somehow then there's
659 // nothing we can safely do from a signal handler.
660 // No, we can't even safely log it.
661 // But, we still have to check the return value here. Otherwise,
662 // GCC 4.4.1 complains ignoring return value. Even (void) doesn't help.
663 return;
664 }
665 }
666
667 private:
668 PosixSignalHandler() {
669 if (pipe(afd_) < 0) {
670 LOG_ERR(LS_ERROR) << "pipe failed";
671 return;
672 }
673 if (fcntl(afd_[0], F_SETFL, O_NONBLOCK) < 0) {
674 LOG_ERR(LS_WARNING) << "fcntl #1 failed";
675 }
676 if (fcntl(afd_[1], F_SETFL, O_NONBLOCK) < 0) {
677 LOG_ERR(LS_WARNING) << "fcntl #2 failed";
678 }
679 memset(const_cast<void *>(static_cast<volatile void *>(received_signal_)),
680 0,
681 sizeof(received_signal_));
682 }
683
684 ~PosixSignalHandler() {
685 int fd1 = afd_[0];
686 int fd2 = afd_[1];
687 // We clobber the stored file descriptor numbers here or else in principle
688 // a signal that happens to be delivered during application termination
689 // could erroneously write a zero byte to an unrelated file handle in
690 // OnPosixSignalReceived() if some other file happens to be opened later
691 // during shutdown and happens to be given the same file descriptor number
692 // as our pipe had. Unfortunately even with this precaution there is still a
693 // race where that could occur if said signal happens to be handled
694 // concurrently with this code and happens to have already read the value of
695 // afd_[1] from memory before we clobber it, but that's unlikely.
696 afd_[0] = -1;
697 afd_[1] = -1;
698 close(fd1);
699 close(fd2);
700 }
701
702 int afd_[2];
703 // These are boolean flags that will be set in our signal handler and read
704 // and cleared from Wait(). There is a race involved in this, but it is
705 // benign. The signal handler sets the flag before signaling the pipe, so
706 // we'll never end up blocking in select() while a flag is still true.
707 // However, if two of the same signal arrive close to each other then it's
708 // possible that the second time the handler may set the flag while it's still
709 // true, meaning that signal will be missed. But the first occurrence of it
710 // will still be handled, so this isn't a problem.
711 // Volatile is not necessary here for correctness, but this data _is_ volatile
712 // so I've marked it as such.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200713 volatile uint8_t received_signal_[kNumPosixSignals];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000714};
715
716class PosixSignalDispatcher : public Dispatcher {
717 public:
718 PosixSignalDispatcher(PhysicalSocketServer *owner) : owner_(owner) {
719 owner_->Add(this);
720 }
721
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000722 ~PosixSignalDispatcher() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000723 owner_->Remove(this);
724 }
725
Peter Boström0c4e06b2015-10-07 12:23:21 +0200726 uint32_t GetRequestedEvents() override { return DE_READ; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000727
Peter Boström0c4e06b2015-10-07 12:23:21 +0200728 void OnPreEvent(uint32_t ff) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000729 // Events might get grouped if signals come very fast, so we read out up to
730 // 16 bytes to make sure we keep the pipe empty.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200731 uint8_t b[16];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000732 ssize_t ret = read(GetDescriptor(), b, sizeof(b));
733 if (ret < 0) {
734 LOG_ERR(LS_WARNING) << "Error in read()";
735 } else if (ret == 0) {
736 LOG(LS_WARNING) << "Should have read at least one byte";
737 }
738 }
739
Peter Boström0c4e06b2015-10-07 12:23:21 +0200740 void OnEvent(uint32_t ff, int err) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000741 for (int signum = 0; signum < PosixSignalHandler::kNumPosixSignals;
742 ++signum) {
743 if (PosixSignalHandler::Instance()->IsSignalSet(signum)) {
744 PosixSignalHandler::Instance()->ClearSignal(signum);
745 HandlerMap::iterator i = handlers_.find(signum);
746 if (i == handlers_.end()) {
747 // This can happen if a signal is delivered to our process at around
748 // the same time as we unset our handler for it. It is not an error
749 // condition, but it's unusual enough to be worth logging.
750 LOG(LS_INFO) << "Received signal with no handler: " << signum;
751 } else {
752 // Otherwise, execute our handler.
753 (*i->second)(signum);
754 }
755 }
756 }
757 }
758
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000759 int GetDescriptor() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000760 return PosixSignalHandler::Instance()->GetDescriptor();
761 }
762
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000763 bool IsDescriptorClosed() override { return false; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000764
765 void SetHandler(int signum, void (*handler)(int)) {
766 handlers_[signum] = handler;
767 }
768
769 void ClearHandler(int signum) {
770 handlers_.erase(signum);
771 }
772
773 bool HasHandlers() {
774 return !handlers_.empty();
775 }
776
777 private:
778 typedef std::map<int, void (*)(int)> HandlerMap;
779
780 HandlerMap handlers_;
781 // Our owner.
782 PhysicalSocketServer *owner_;
783};
784
jbauch095ae152015-12-18 01:39:55 -0800785SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss)
786 : PhysicalSocket(ss) {
787}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000788
jbauch095ae152015-12-18 01:39:55 -0800789SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss)
790 : PhysicalSocket(ss, s) {
791}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000792
jbauch095ae152015-12-18 01:39:55 -0800793SocketDispatcher::~SocketDispatcher() {
794 Close();
795}
796
797bool SocketDispatcher::Initialize() {
798 ss_->Add(this);
799 fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK);
800 return true;
801}
802
803bool SocketDispatcher::Create(int type) {
804 return Create(AF_INET, type);
805}
806
807bool SocketDispatcher::Create(int family, int type) {
808 // Change the socket to be non-blocking.
809 if (!PhysicalSocket::Create(family, type))
810 return false;
811
812 return Initialize();
813}
814
815int SocketDispatcher::GetDescriptor() {
816 return s_;
817}
818
819bool SocketDispatcher::IsDescriptorClosed() {
820 // We don't have a reliable way of distinguishing end-of-stream
821 // from readability. So test on each readable call. Is this
822 // inefficient? Probably.
823 char ch;
824 ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK);
825 if (res > 0) {
826 // Data available, so not closed.
827 return false;
828 } else if (res == 0) {
829 // EOF, so closed.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000830 return true;
jbauch095ae152015-12-18 01:39:55 -0800831 } else { // error
832 switch (errno) {
833 // Returned if we've already closed s_.
834 case EBADF:
835 // Returned during ungraceful peer shutdown.
836 case ECONNRESET:
837 return true;
838 default:
839 // Assume that all other errors are just blocking errors, meaning the
840 // connection is still good but we just can't read from it right now.
841 // This should only happen when connecting (and at most once), because
842 // in all other cases this function is only called if the file
843 // descriptor is already known to be in the readable state. However,
844 // it's not necessary a problem if we spuriously interpret a
845 // "connection lost"-type error as a blocking error, because typically
846 // the next recv() will get EOF, so we'll still eventually notice that
847 // the socket is closed.
848 LOG_ERR(LS_WARNING) << "Assuming benign blocking error";
849 return false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000850 }
851 }
jbauch095ae152015-12-18 01:39:55 -0800852}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000853
jbauch095ae152015-12-18 01:39:55 -0800854uint32_t SocketDispatcher::GetRequestedEvents() {
855 return enabled_events_;
856}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000857
jbauch095ae152015-12-18 01:39:55 -0800858void SocketDispatcher::OnPreEvent(uint32_t ff) {
859 if ((ff & DE_CONNECT) != 0)
860 state_ = CS_CONNECTED;
861 if ((ff & DE_CLOSE) != 0)
862 state_ = CS_CLOSED;
863}
864
865void SocketDispatcher::OnEvent(uint32_t ff, int err) {
866 // Make sure we deliver connect/accept first. Otherwise, consumers may see
867 // something like a READ followed by a CONNECT, which would be odd.
868 if ((ff & DE_CONNECT) != 0) {
869 enabled_events_ &= ~DE_CONNECT;
870 SignalConnectEvent(this);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000871 }
jbauch095ae152015-12-18 01:39:55 -0800872 if ((ff & DE_ACCEPT) != 0) {
873 enabled_events_ &= ~DE_ACCEPT;
874 SignalReadEvent(this);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000875 }
jbauch095ae152015-12-18 01:39:55 -0800876 if ((ff & DE_READ) != 0) {
877 enabled_events_ &= ~DE_READ;
878 SignalReadEvent(this);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000879 }
jbauch095ae152015-12-18 01:39:55 -0800880 if ((ff & DE_WRITE) != 0) {
881 enabled_events_ &= ~DE_WRITE;
882 SignalWriteEvent(this);
883 }
884 if ((ff & DE_CLOSE) != 0) {
885 // The socket is now dead to us, so stop checking it.
886 enabled_events_ = 0;
887 SignalCloseEvent(this, err);
888 }
889}
890
891int SocketDispatcher::Close() {
892 if (s_ == INVALID_SOCKET)
893 return 0;
894
895 ss_->Remove(this);
896 return PhysicalSocket::Close();
897}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000898
899class FileDispatcher: public Dispatcher, public AsyncFile {
900 public:
901 FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) {
902 set_readable(true);
903
904 ss_->Add(this);
905
906 fcntl(fd_, F_SETFL, fcntl(fd_, F_GETFL, 0) | O_NONBLOCK);
907 }
908
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000909 ~FileDispatcher() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000910 ss_->Remove(this);
911 }
912
913 SocketServer* socketserver() { return ss_; }
914
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000915 int GetDescriptor() override { return fd_; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000916
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000917 bool IsDescriptorClosed() override { return false; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000918
Peter Boström0c4e06b2015-10-07 12:23:21 +0200919 uint32_t GetRequestedEvents() override { return flags_; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000920
Peter Boström0c4e06b2015-10-07 12:23:21 +0200921 void OnPreEvent(uint32_t ff) override {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000922
Peter Boström0c4e06b2015-10-07 12:23:21 +0200923 void OnEvent(uint32_t ff, int err) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000924 if ((ff & DE_READ) != 0)
925 SignalReadEvent(this);
926 if ((ff & DE_WRITE) != 0)
927 SignalWriteEvent(this);
928 if ((ff & DE_CLOSE) != 0)
929 SignalCloseEvent(this, err);
930 }
931
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000932 bool readable() override { return (flags_ & DE_READ) != 0; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000933
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000934 void set_readable(bool value) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000935 flags_ = value ? (flags_ | DE_READ) : (flags_ & ~DE_READ);
936 }
937
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000938 bool writable() override { return (flags_ & DE_WRITE) != 0; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000939
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000940 void set_writable(bool value) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000941 flags_ = value ? (flags_ | DE_WRITE) : (flags_ & ~DE_WRITE);
942 }
943
944 private:
945 PhysicalSocketServer* ss_;
946 int fd_;
947 int flags_;
948};
949
950AsyncFile* PhysicalSocketServer::CreateFile(int fd) {
951 return new FileDispatcher(fd, this);
952}
953
954#endif // WEBRTC_POSIX
955
956#if defined(WEBRTC_WIN)
Peter Boström0c4e06b2015-10-07 12:23:21 +0200957static uint32_t FlagsToEvents(uint32_t events) {
958 uint32_t ffFD = FD_CLOSE;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000959 if (events & DE_READ)
960 ffFD |= FD_READ;
961 if (events & DE_WRITE)
962 ffFD |= FD_WRITE;
963 if (events & DE_CONNECT)
964 ffFD |= FD_CONNECT;
965 if (events & DE_ACCEPT)
966 ffFD |= FD_ACCEPT;
967 return ffFD;
968}
969
970class EventDispatcher : public Dispatcher {
971 public:
972 EventDispatcher(PhysicalSocketServer *ss) : ss_(ss) {
973 hev_ = WSACreateEvent();
974 if (hev_) {
975 ss_->Add(this);
976 }
977 }
978
979 ~EventDispatcher() {
980 if (hev_ != NULL) {
981 ss_->Remove(this);
982 WSACloseEvent(hev_);
983 hev_ = NULL;
984 }
985 }
986
987 virtual void Signal() {
988 if (hev_ != NULL)
989 WSASetEvent(hev_);
990 }
991
Peter Boström0c4e06b2015-10-07 12:23:21 +0200992 virtual uint32_t GetRequestedEvents() { return 0; }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000993
Peter Boström0c4e06b2015-10-07 12:23:21 +0200994 virtual void OnPreEvent(uint32_t ff) { WSAResetEvent(hev_); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000995
Peter Boström0c4e06b2015-10-07 12:23:21 +0200996 virtual void OnEvent(uint32_t ff, int err) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000997
998 virtual WSAEVENT GetWSAEvent() {
999 return hev_;
1000 }
1001
1002 virtual SOCKET GetSocket() {
1003 return INVALID_SOCKET;
1004 }
1005
1006 virtual bool CheckSignalClose() { return false; }
1007
1008private:
1009 PhysicalSocketServer* ss_;
1010 WSAEVENT hev_;
1011};
1012
jbauch095ae152015-12-18 01:39:55 -08001013SocketDispatcher::SocketDispatcher(PhysicalSocketServer* ss)
1014 : PhysicalSocket(ss),
1015 id_(0),
1016 signal_close_(false) {
1017}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001018
jbauch095ae152015-12-18 01:39:55 -08001019SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer* ss)
1020 : PhysicalSocket(ss, s),
1021 id_(0),
1022 signal_close_(false) {
1023}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001024
jbauch095ae152015-12-18 01:39:55 -08001025SocketDispatcher::~SocketDispatcher() {
1026 Close();
1027}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001028
jbauch095ae152015-12-18 01:39:55 -08001029bool SocketDispatcher::Initialize() {
1030 ASSERT(s_ != INVALID_SOCKET);
1031 // Must be a non-blocking
1032 u_long argp = 1;
1033 ioctlsocket(s_, FIONBIO, &argp);
1034 ss_->Add(this);
1035 return true;
1036}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001037
jbauch095ae152015-12-18 01:39:55 -08001038bool SocketDispatcher::Create(int type) {
1039 return Create(AF_INET, type);
1040}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001041
jbauch095ae152015-12-18 01:39:55 -08001042bool SocketDispatcher::Create(int family, int type) {
1043 // Create socket
1044 if (!PhysicalSocket::Create(family, type))
1045 return false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001046
jbauch095ae152015-12-18 01:39:55 -08001047 if (!Initialize())
1048 return false;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001049
jbauch095ae152015-12-18 01:39:55 -08001050 do { id_ = ++next_id_; } while (id_ == 0);
1051 return true;
1052}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001053
jbauch095ae152015-12-18 01:39:55 -08001054int SocketDispatcher::Close() {
1055 if (s_ == INVALID_SOCKET)
1056 return 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001057
jbauch095ae152015-12-18 01:39:55 -08001058 id_ = 0;
1059 signal_close_ = false;
1060 ss_->Remove(this);
1061 return PhysicalSocket::Close();
1062}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001063
jbauch095ae152015-12-18 01:39:55 -08001064uint32_t SocketDispatcher::GetRequestedEvents() {
1065 return enabled_events_;
1066}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001067
jbauch095ae152015-12-18 01:39:55 -08001068void SocketDispatcher::OnPreEvent(uint32_t ff) {
1069 if ((ff & DE_CONNECT) != 0)
1070 state_ = CS_CONNECTED;
1071 // We set CS_CLOSED from CheckSignalClose.
1072}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001073
jbauch095ae152015-12-18 01:39:55 -08001074void SocketDispatcher::OnEvent(uint32_t ff, int err) {
1075 int cache_id = id_;
1076 // Make sure we deliver connect/accept first. Otherwise, consumers may see
1077 // something like a READ followed by a CONNECT, which would be odd.
1078 if (((ff & DE_CONNECT) != 0) && (id_ == cache_id)) {
1079 if (ff != DE_CONNECT)
1080 LOG(LS_VERBOSE) << "Signalled with DE_CONNECT: " << ff;
1081 enabled_events_ &= ~DE_CONNECT;
tfarinaa41ab932015-10-30 16:08:48 -07001082#if !defined(NDEBUG)
jbauch095ae152015-12-18 01:39:55 -08001083 dbg_addr_ = "Connected @ ";
1084 dbg_addr_.append(GetRemoteAddress().ToString());
tfarinaa41ab932015-10-30 16:08:48 -07001085#endif
jbauch095ae152015-12-18 01:39:55 -08001086 SignalConnectEvent(this);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001087 }
jbauch095ae152015-12-18 01:39:55 -08001088 if (((ff & DE_ACCEPT) != 0) && (id_ == cache_id)) {
1089 enabled_events_ &= ~DE_ACCEPT;
1090 SignalReadEvent(this);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001091 }
jbauch095ae152015-12-18 01:39:55 -08001092 if ((ff & DE_READ) != 0) {
1093 enabled_events_ &= ~DE_READ;
1094 SignalReadEvent(this);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001095 }
jbauch095ae152015-12-18 01:39:55 -08001096 if (((ff & DE_WRITE) != 0) && (id_ == cache_id)) {
1097 enabled_events_ &= ~DE_WRITE;
1098 SignalWriteEvent(this);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001099 }
jbauch095ae152015-12-18 01:39:55 -08001100 if (((ff & DE_CLOSE) != 0) && (id_ == cache_id)) {
1101 signal_close_ = true;
1102 signal_err_ = err;
1103 }
1104}
1105
1106WSAEVENT SocketDispatcher::GetWSAEvent() {
1107 return WSA_INVALID_EVENT;
1108}
1109
1110SOCKET SocketDispatcher::GetSocket() {
1111 return s_;
1112}
1113
1114bool SocketDispatcher::CheckSignalClose() {
1115 if (!signal_close_)
1116 return false;
1117
1118 char ch;
1119 if (recv(s_, &ch, 1, MSG_PEEK) > 0)
1120 return false;
1121
1122 state_ = CS_CLOSED;
1123 signal_close_ = false;
1124 SignalCloseEvent(this, signal_err_);
1125 return true;
1126}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001127
1128int SocketDispatcher::next_id_ = 0;
1129
1130#endif // WEBRTC_WIN
1131
1132// Sets the value of a boolean value to false when signaled.
1133class Signaler : public EventDispatcher {
1134 public:
1135 Signaler(PhysicalSocketServer* ss, bool* pf)
1136 : EventDispatcher(ss), pf_(pf) {
1137 }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +00001138 ~Signaler() override { }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001139
Peter Boström0c4e06b2015-10-07 12:23:21 +02001140 void OnEvent(uint32_t ff, int err) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001141 if (pf_)
1142 *pf_ = false;
1143 }
1144
1145 private:
1146 bool *pf_;
1147};
1148
1149PhysicalSocketServer::PhysicalSocketServer()
1150 : fWait_(false) {
1151 signal_wakeup_ = new Signaler(this, &fWait_);
1152#if defined(WEBRTC_WIN)
1153 socket_ev_ = WSACreateEvent();
1154#endif
1155}
1156
1157PhysicalSocketServer::~PhysicalSocketServer() {
1158#if defined(WEBRTC_WIN)
1159 WSACloseEvent(socket_ev_);
1160#endif
1161#if defined(WEBRTC_POSIX)
1162 signal_dispatcher_.reset();
1163#endif
1164 delete signal_wakeup_;
1165 ASSERT(dispatchers_.empty());
1166}
1167
1168void PhysicalSocketServer::WakeUp() {
1169 signal_wakeup_->Signal();
1170}
1171
1172Socket* PhysicalSocketServer::CreateSocket(int type) {
1173 return CreateSocket(AF_INET, type);
1174}
1175
1176Socket* PhysicalSocketServer::CreateSocket(int family, int type) {
1177 PhysicalSocket* socket = new PhysicalSocket(this);
1178 if (socket->Create(family, type)) {
1179 return socket;
1180 } else {
1181 delete socket;
jbauch095ae152015-12-18 01:39:55 -08001182 return nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001183 }
1184}
1185
1186AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int type) {
1187 return CreateAsyncSocket(AF_INET, type);
1188}
1189
1190AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int family, int type) {
1191 SocketDispatcher* dispatcher = new SocketDispatcher(this);
1192 if (dispatcher->Create(family, type)) {
1193 return dispatcher;
1194 } else {
1195 delete dispatcher;
jbauch095ae152015-12-18 01:39:55 -08001196 return nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001197 }
1198}
1199
1200AsyncSocket* PhysicalSocketServer::WrapSocket(SOCKET s) {
1201 SocketDispatcher* dispatcher = new SocketDispatcher(s, this);
1202 if (dispatcher->Initialize()) {
1203 return dispatcher;
1204 } else {
1205 delete dispatcher;
jbauch095ae152015-12-18 01:39:55 -08001206 return nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001207 }
1208}
1209
1210void PhysicalSocketServer::Add(Dispatcher *pdispatcher) {
1211 CritScope cs(&crit_);
1212 // Prevent duplicates. This can cause dead dispatchers to stick around.
1213 DispatcherList::iterator pos = std::find(dispatchers_.begin(),
1214 dispatchers_.end(),
1215 pdispatcher);
1216 if (pos != dispatchers_.end())
1217 return;
1218 dispatchers_.push_back(pdispatcher);
1219}
1220
1221void PhysicalSocketServer::Remove(Dispatcher *pdispatcher) {
1222 CritScope cs(&crit_);
1223 DispatcherList::iterator pos = std::find(dispatchers_.begin(),
1224 dispatchers_.end(),
1225 pdispatcher);
1226 // We silently ignore duplicate calls to Add, so we should silently ignore
1227 // the (expected) symmetric calls to Remove. Note that this may still hide
1228 // a real issue, so we at least log a warning about it.
1229 if (pos == dispatchers_.end()) {
1230 LOG(LS_WARNING) << "PhysicalSocketServer asked to remove a unknown "
1231 << "dispatcher, potentially from a duplicate call to Add.";
1232 return;
1233 }
1234 size_t index = pos - dispatchers_.begin();
1235 dispatchers_.erase(pos);
1236 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end();
1237 ++it) {
1238 if (index < **it) {
1239 --**it;
1240 }
1241 }
1242}
1243
1244#if defined(WEBRTC_POSIX)
1245bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) {
1246 // Calculate timing information
1247
1248 struct timeval *ptvWait = NULL;
1249 struct timeval tvWait;
1250 struct timeval tvStop;
1251 if (cmsWait != kForever) {
1252 // Calculate wait timeval
1253 tvWait.tv_sec = cmsWait / 1000;
1254 tvWait.tv_usec = (cmsWait % 1000) * 1000;
1255 ptvWait = &tvWait;
1256
1257 // Calculate when to return in a timeval
1258 gettimeofday(&tvStop, NULL);
1259 tvStop.tv_sec += tvWait.tv_sec;
1260 tvStop.tv_usec += tvWait.tv_usec;
1261 if (tvStop.tv_usec >= 1000000) {
1262 tvStop.tv_usec -= 1000000;
1263 tvStop.tv_sec += 1;
1264 }
1265 }
1266
1267 // Zero all fd_sets. Don't need to do this inside the loop since
1268 // select() zeros the descriptors not signaled
1269
1270 fd_set fdsRead;
1271 FD_ZERO(&fdsRead);
1272 fd_set fdsWrite;
1273 FD_ZERO(&fdsWrite);
pbos@webrtc.org27e58982014-10-07 17:56:53 +00001274 // Explicitly unpoison these FDs on MemorySanitizer which doesn't handle the
1275 // inline assembly in FD_ZERO.
1276 // http://crbug.com/344505
1277#ifdef MEMORY_SANITIZER
1278 __msan_unpoison(&fdsRead, sizeof(fdsRead));
1279 __msan_unpoison(&fdsWrite, sizeof(fdsWrite));
1280#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001281
1282 fWait_ = true;
1283
1284 while (fWait_) {
1285 int fdmax = -1;
1286 {
1287 CritScope cr(&crit_);
1288 for (size_t i = 0; i < dispatchers_.size(); ++i) {
1289 // Query dispatchers for read and write wait state
1290 Dispatcher *pdispatcher = dispatchers_[i];
1291 ASSERT(pdispatcher);
1292 if (!process_io && (pdispatcher != signal_wakeup_))
1293 continue;
1294 int fd = pdispatcher->GetDescriptor();
1295 if (fd > fdmax)
1296 fdmax = fd;
1297
Peter Boström0c4e06b2015-10-07 12:23:21 +02001298 uint32_t ff = pdispatcher->GetRequestedEvents();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001299 if (ff & (DE_READ | DE_ACCEPT))
1300 FD_SET(fd, &fdsRead);
1301 if (ff & (DE_WRITE | DE_CONNECT))
1302 FD_SET(fd, &fdsWrite);
1303 }
1304 }
1305
1306 // Wait then call handlers as appropriate
1307 // < 0 means error
1308 // 0 means timeout
1309 // > 0 means count of descriptors ready
1310 int n = select(fdmax + 1, &fdsRead, &fdsWrite, NULL, ptvWait);
1311
1312 // If error, return error.
1313 if (n < 0) {
1314 if (errno != EINTR) {
1315 LOG_E(LS_ERROR, EN, errno) << "select";
1316 return false;
1317 }
1318 // Else ignore the error and keep going. If this EINTR was for one of the
1319 // signals managed by this PhysicalSocketServer, the
1320 // PosixSignalDeliveryDispatcher will be in the signaled state in the next
1321 // iteration.
1322 } else if (n == 0) {
1323 // If timeout, return success
1324 return true;
1325 } else {
1326 // We have signaled descriptors
1327 CritScope cr(&crit_);
1328 for (size_t i = 0; i < dispatchers_.size(); ++i) {
1329 Dispatcher *pdispatcher = dispatchers_[i];
1330 int fd = pdispatcher->GetDescriptor();
Peter Boström0c4e06b2015-10-07 12:23:21 +02001331 uint32_t ff = 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001332 int errcode = 0;
1333
1334 // Reap any error code, which can be signaled through reads or writes.
jbauch095ae152015-12-18 01:39:55 -08001335 // TODO(pthatcher): Should we set errcode if getsockopt fails?
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001336 if (FD_ISSET(fd, &fdsRead) || FD_ISSET(fd, &fdsWrite)) {
1337 socklen_t len = sizeof(errcode);
1338 ::getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &len);
1339 }
1340
1341 // Check readable descriptors. If we're waiting on an accept, signal
1342 // that. Otherwise we're waiting for data, check to see if we're
1343 // readable or really closed.
jbauch095ae152015-12-18 01:39:55 -08001344 // TODO(pthatcher): Only peek at TCP descriptors.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001345 if (FD_ISSET(fd, &fdsRead)) {
1346 FD_CLR(fd, &fdsRead);
1347 if (pdispatcher->GetRequestedEvents() & DE_ACCEPT) {
1348 ff |= DE_ACCEPT;
1349 } else if (errcode || pdispatcher->IsDescriptorClosed()) {
1350 ff |= DE_CLOSE;
1351 } else {
1352 ff |= DE_READ;
1353 }
1354 }
1355
1356 // Check writable descriptors. If we're waiting on a connect, detect
1357 // success versus failure by the reaped error code.
1358 if (FD_ISSET(fd, &fdsWrite)) {
1359 FD_CLR(fd, &fdsWrite);
1360 if (pdispatcher->GetRequestedEvents() & DE_CONNECT) {
1361 if (!errcode) {
1362 ff |= DE_CONNECT;
1363 } else {
1364 ff |= DE_CLOSE;
1365 }
1366 } else {
1367 ff |= DE_WRITE;
1368 }
1369 }
1370
1371 // Tell the descriptor about the event.
1372 if (ff != 0) {
1373 pdispatcher->OnPreEvent(ff);
1374 pdispatcher->OnEvent(ff, errcode);
1375 }
1376 }
1377 }
1378
1379 // Recalc the time remaining to wait. Doing it here means it doesn't get
1380 // calced twice the first time through the loop
1381 if (ptvWait) {
1382 ptvWait->tv_sec = 0;
1383 ptvWait->tv_usec = 0;
1384 struct timeval tvT;
1385 gettimeofday(&tvT, NULL);
1386 if ((tvStop.tv_sec > tvT.tv_sec)
1387 || ((tvStop.tv_sec == tvT.tv_sec)
1388 && (tvStop.tv_usec > tvT.tv_usec))) {
1389 ptvWait->tv_sec = tvStop.tv_sec - tvT.tv_sec;
1390 ptvWait->tv_usec = tvStop.tv_usec - tvT.tv_usec;
1391 if (ptvWait->tv_usec < 0) {
1392 ASSERT(ptvWait->tv_sec > 0);
1393 ptvWait->tv_usec += 1000000;
1394 ptvWait->tv_sec -= 1;
1395 }
1396 }
1397 }
1398 }
1399
1400 return true;
1401}
1402
1403static void GlobalSignalHandler(int signum) {
1404 PosixSignalHandler::Instance()->OnPosixSignalReceived(signum);
1405}
1406
1407bool PhysicalSocketServer::SetPosixSignalHandler(int signum,
1408 void (*handler)(int)) {
1409 // If handler is SIG_IGN or SIG_DFL then clear our user-level handler,
1410 // otherwise set one.
1411 if (handler == SIG_IGN || handler == SIG_DFL) {
1412 if (!InstallSignal(signum, handler)) {
1413 return false;
1414 }
1415 if (signal_dispatcher_) {
1416 signal_dispatcher_->ClearHandler(signum);
1417 if (!signal_dispatcher_->HasHandlers()) {
1418 signal_dispatcher_.reset();
1419 }
1420 }
1421 } else {
1422 if (!signal_dispatcher_) {
1423 signal_dispatcher_.reset(new PosixSignalDispatcher(this));
1424 }
1425 signal_dispatcher_->SetHandler(signum, handler);
1426 if (!InstallSignal(signum, &GlobalSignalHandler)) {
1427 return false;
1428 }
1429 }
1430 return true;
1431}
1432
1433Dispatcher* PhysicalSocketServer::signal_dispatcher() {
1434 return signal_dispatcher_.get();
1435}
1436
1437bool PhysicalSocketServer::InstallSignal(int signum, void (*handler)(int)) {
1438 struct sigaction act;
1439 // It doesn't really matter what we set this mask to.
1440 if (sigemptyset(&act.sa_mask) != 0) {
1441 LOG_ERR(LS_ERROR) << "Couldn't set mask";
1442 return false;
1443 }
1444 act.sa_handler = handler;
1445#if !defined(__native_client__)
1446 // Use SA_RESTART so that our syscalls don't get EINTR, since we don't need it
1447 // and it's a nuisance. Though some syscalls still return EINTR and there's no
1448 // real standard for which ones. :(
1449 act.sa_flags = SA_RESTART;
1450#else
1451 act.sa_flags = 0;
1452#endif
1453 if (sigaction(signum, &act, NULL) != 0) {
1454 LOG_ERR(LS_ERROR) << "Couldn't set sigaction";
1455 return false;
1456 }
1457 return true;
1458}
1459#endif // WEBRTC_POSIX
1460
1461#if defined(WEBRTC_WIN)
1462bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) {
1463 int cmsTotal = cmsWait;
1464 int cmsElapsed = 0;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001465 uint32_t msStart = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001466
1467 fWait_ = true;
1468 while (fWait_) {
1469 std::vector<WSAEVENT> events;
1470 std::vector<Dispatcher *> event_owners;
1471
1472 events.push_back(socket_ev_);
1473
1474 {
1475 CritScope cr(&crit_);
1476 size_t i = 0;
1477 iterators_.push_back(&i);
1478 // Don't track dispatchers_.size(), because we want to pick up any new
1479 // dispatchers that were added while processing the loop.
1480 while (i < dispatchers_.size()) {
1481 Dispatcher* disp = dispatchers_[i++];
1482 if (!process_io && (disp != signal_wakeup_))
1483 continue;
1484 SOCKET s = disp->GetSocket();
1485 if (disp->CheckSignalClose()) {
1486 // We just signalled close, don't poll this socket
1487 } else if (s != INVALID_SOCKET) {
1488 WSAEventSelect(s,
1489 events[0],
1490 FlagsToEvents(disp->GetRequestedEvents()));
1491 } else {
1492 events.push_back(disp->GetWSAEvent());
1493 event_owners.push_back(disp);
1494 }
1495 }
1496 ASSERT(iterators_.back() == &i);
1497 iterators_.pop_back();
1498 }
1499
1500 // Which is shorter, the delay wait or the asked wait?
1501
1502 int cmsNext;
1503 if (cmsWait == kForever) {
1504 cmsNext = cmsWait;
1505 } else {
andresp@webrtc.orgff689be2015-02-12 11:54:26 +00001506 cmsNext = std::max(0, cmsTotal - cmsElapsed);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001507 }
1508
1509 // Wait for one of the events to signal
1510 DWORD dw = WSAWaitForMultipleEvents(static_cast<DWORD>(events.size()),
1511 &events[0],
1512 false,
1513 cmsNext,
1514 false);
1515
1516 if (dw == WSA_WAIT_FAILED) {
1517 // Failed?
jbauch095ae152015-12-18 01:39:55 -08001518 // TODO(pthatcher): need a better strategy than this!
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001519 WSAGetLastError();
1520 ASSERT(false);
1521 return false;
1522 } else if (dw == WSA_WAIT_TIMEOUT) {
1523 // Timeout?
1524 return true;
1525 } else {
1526 // Figure out which one it is and call it
1527 CritScope cr(&crit_);
1528 int index = dw - WSA_WAIT_EVENT_0;
1529 if (index > 0) {
1530 --index; // The first event is the socket event
1531 event_owners[index]->OnPreEvent(0);
1532 event_owners[index]->OnEvent(0, 0);
1533 } else if (process_io) {
1534 size_t i = 0, end = dispatchers_.size();
1535 iterators_.push_back(&i);
1536 iterators_.push_back(&end); // Don't iterate over new dispatchers.
1537 while (i < end) {
1538 Dispatcher* disp = dispatchers_[i++];
1539 SOCKET s = disp->GetSocket();
1540 if (s == INVALID_SOCKET)
1541 continue;
1542
1543 WSANETWORKEVENTS wsaEvents;
1544 int err = WSAEnumNetworkEvents(s, events[0], &wsaEvents);
1545 if (err == 0) {
1546
1547#if LOGGING
1548 {
1549 if ((wsaEvents.lNetworkEvents & FD_READ) &&
1550 wsaEvents.iErrorCode[FD_READ_BIT] != 0) {
1551 LOG(WARNING) << "PhysicalSocketServer got FD_READ_BIT error "
1552 << wsaEvents.iErrorCode[FD_READ_BIT];
1553 }
1554 if ((wsaEvents.lNetworkEvents & FD_WRITE) &&
1555 wsaEvents.iErrorCode[FD_WRITE_BIT] != 0) {
1556 LOG(WARNING) << "PhysicalSocketServer got FD_WRITE_BIT error "
1557 << wsaEvents.iErrorCode[FD_WRITE_BIT];
1558 }
1559 if ((wsaEvents.lNetworkEvents & FD_CONNECT) &&
1560 wsaEvents.iErrorCode[FD_CONNECT_BIT] != 0) {
1561 LOG(WARNING) << "PhysicalSocketServer got FD_CONNECT_BIT error "
1562 << wsaEvents.iErrorCode[FD_CONNECT_BIT];
1563 }
1564 if ((wsaEvents.lNetworkEvents & FD_ACCEPT) &&
1565 wsaEvents.iErrorCode[FD_ACCEPT_BIT] != 0) {
1566 LOG(WARNING) << "PhysicalSocketServer got FD_ACCEPT_BIT error "
1567 << wsaEvents.iErrorCode[FD_ACCEPT_BIT];
1568 }
1569 if ((wsaEvents.lNetworkEvents & FD_CLOSE) &&
1570 wsaEvents.iErrorCode[FD_CLOSE_BIT] != 0) {
1571 LOG(WARNING) << "PhysicalSocketServer got FD_CLOSE_BIT error "
1572 << wsaEvents.iErrorCode[FD_CLOSE_BIT];
1573 }
1574 }
1575#endif
Peter Boström0c4e06b2015-10-07 12:23:21 +02001576 uint32_t ff = 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001577 int errcode = 0;
1578 if (wsaEvents.lNetworkEvents & FD_READ)
1579 ff |= DE_READ;
1580 if (wsaEvents.lNetworkEvents & FD_WRITE)
1581 ff |= DE_WRITE;
1582 if (wsaEvents.lNetworkEvents & FD_CONNECT) {
1583 if (wsaEvents.iErrorCode[FD_CONNECT_BIT] == 0) {
1584 ff |= DE_CONNECT;
1585 } else {
1586 ff |= DE_CLOSE;
1587 errcode = wsaEvents.iErrorCode[FD_CONNECT_BIT];
1588 }
1589 }
1590 if (wsaEvents.lNetworkEvents & FD_ACCEPT)
1591 ff |= DE_ACCEPT;
1592 if (wsaEvents.lNetworkEvents & FD_CLOSE) {
1593 ff |= DE_CLOSE;
1594 errcode = wsaEvents.iErrorCode[FD_CLOSE_BIT];
1595 }
1596 if (ff != 0) {
1597 disp->OnPreEvent(ff);
1598 disp->OnEvent(ff, errcode);
1599 }
1600 }
1601 }
1602 ASSERT(iterators_.back() == &end);
1603 iterators_.pop_back();
1604 ASSERT(iterators_.back() == &i);
1605 iterators_.pop_back();
1606 }
1607
1608 // Reset the network event until new activity occurs
1609 WSAResetEvent(socket_ev_);
1610 }
1611
1612 // Break?
1613 if (!fWait_)
1614 break;
1615 cmsElapsed = TimeSince(msStart);
1616 if ((cmsWait != kForever) && (cmsElapsed >= cmsWait)) {
1617 break;
1618 }
1619 }
1620
1621 // Done
1622 return true;
1623}
1624#endif // WEBRTC_WIN
1625
1626} // namespace rtc