OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 #endif | 37 #endif |
38 | 38 |
39 #include <algorithm> | 39 #include <algorithm> |
40 #include <map> | 40 #include <map> |
41 | 41 |
42 #include "webrtc/base/arraysize.h" | 42 #include "webrtc/base/arraysize.h" |
43 #include "webrtc/base/basictypes.h" | 43 #include "webrtc/base/basictypes.h" |
44 #include "webrtc/base/byteorder.h" | 44 #include "webrtc/base/byteorder.h" |
45 #include "webrtc/base/common.h" | 45 #include "webrtc/base/common.h" |
46 #include "webrtc/base/logging.h" | 46 #include "webrtc/base/logging.h" |
47 #include "webrtc/base/nethelpers.h" | |
48 #include "webrtc/base/physicalsocketserver.h" | 47 #include "webrtc/base/physicalsocketserver.h" |
49 #include "webrtc/base/timeutils.h" | 48 #include "webrtc/base/timeutils.h" |
50 #include "webrtc/base/winping.h" | 49 #include "webrtc/base/winping.h" |
51 #include "webrtc/base/win32socketinit.h" | 50 #include "webrtc/base/win32socketinit.h" |
52 | 51 |
53 // stm: this will tell us if we are on OSX | 52 // stm: this will tell us if we are on OSX |
54 #ifdef HAVE_CONFIG_H | 53 #ifdef HAVE_CONFIG_H |
55 #include "config.h" | 54 #include "config.h" |
56 #endif | 55 #endif |
57 | 56 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 68, // Official minimum | 89 68, // Official minimum |
91 0, // End of list marker | 90 0, // End of list marker |
92 }; | 91 }; |
93 | 92 |
94 static const int IP_HEADER_SIZE = 20u; | 93 static const int IP_HEADER_SIZE = 20u; |
95 static const int IPV6_HEADER_SIZE = 40u; | 94 static const int IPV6_HEADER_SIZE = 40u; |
96 static const int ICMP_HEADER_SIZE = 8u; | 95 static const int ICMP_HEADER_SIZE = 8u; |
97 static const int ICMP_PING_TIMEOUT_MILLIS = 10000u; | 96 static const int ICMP_PING_TIMEOUT_MILLIS = 10000u; |
98 #endif | 97 #endif |
99 | 98 |
100 class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> { | 99 PhysicalSocket::PhysicalSocket(PhysicalSocketServer* ss, SOCKET s) |
101 public: | 100 : ss_(ss), s_(s), enabled_events_(0), error_(0), |
102 PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET) | 101 state_((s == INVALID_SOCKET) ? CS_CLOSED : CS_CONNECTED), |
103 : ss_(ss), s_(s), enabled_events_(0), error_(0), | 102 resolver_(nullptr) { |
104 state_((s == INVALID_SOCKET) ? CS_CLOSED : CS_CONNECTED), | |
105 resolver_(NULL) { | |
106 #if defined(WEBRTC_WIN) | 103 #if defined(WEBRTC_WIN) |
107 // EnsureWinsockInit() ensures that winsock is initialized. The default | 104 // EnsureWinsockInit() ensures that winsock is initialized. The default |
108 // version of this function doesn't do anything because winsock is | 105 // version of this function doesn't do anything because winsock is |
109 // initialized by constructor of a static object. If neccessary libjingle | 106 // initialized by constructor of a static object. If neccessary libjingle |
110 // users can link it with a different version of this function by replacing | 107 // users can link it with a different version of this function by replacing |
111 // win32socketinit.cc. See win32socketinit.cc for more details. | 108 // win32socketinit.cc. See win32socketinit.cc for more details. |
112 EnsureWinsockInit(); | 109 EnsureWinsockInit(); |
113 #endif | 110 #endif |
114 if (s_ != INVALID_SOCKET) { | 111 if (s_ != INVALID_SOCKET) { |
115 enabled_events_ = DE_READ | DE_WRITE; | 112 enabled_events_ = DE_READ | DE_WRITE; |
116 | 113 |
117 int type = SOCK_STREAM; | 114 int type = SOCK_STREAM; |
118 socklen_t len = sizeof(type); | 115 socklen_t len = sizeof(type); |
119 VERIFY(0 == getsockopt(s_, SOL_SOCKET, SO_TYPE, (SockOptArg)&type, &len)); | 116 VERIFY(0 == getsockopt(s_, SOL_SOCKET, SO_TYPE, (SockOptArg)&type, &len)); |
120 udp_ = (SOCK_DGRAM == type); | |
121 } | |
122 } | |
123 | |
124 ~PhysicalSocket() override { | |
125 Close(); | |
126 } | |
127 | |
128 // Creates the underlying OS socket (same as the "socket" function). | |
129 virtual bool Create(int family, int type) { | |
130 Close(); | |
131 s_ = ::socket(family, type, 0); | |
132 udp_ = (SOCK_DGRAM == type); | 117 udp_ = (SOCK_DGRAM == type); |
133 UpdateLastError(); | 118 } |
134 if (udp_) | 119 } |
135 enabled_events_ = DE_READ | DE_WRITE; | 120 |
136 return s_ != INVALID_SOCKET; | 121 PhysicalSocket::~PhysicalSocket() { |
137 } | 122 Close(); |
138 | 123 } |
139 SocketAddress GetLocalAddress() const override { | 124 |
140 sockaddr_storage addr_storage = {0}; | 125 bool PhysicalSocket::Create(int family, int type) { |
141 socklen_t addrlen = sizeof(addr_storage); | 126 Close(); |
142 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); | 127 s_ = ::socket(family, type, 0); |
143 int result = ::getsockname(s_, addr, &addrlen); | 128 udp_ = (SOCK_DGRAM == type); |
144 SocketAddress address; | 129 UpdateLastError(); |
145 if (result >= 0) { | 130 if (udp_) |
146 SocketAddressFromSockAddrStorage(addr_storage, &address); | 131 enabled_events_ = DE_READ | DE_WRITE; |
147 } else { | 132 return s_ != INVALID_SOCKET; |
148 LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket=" | 133 } |
149 << s_; | 134 |
150 } | 135 SocketAddress PhysicalSocket::GetLocalAddress() const { |
151 return address; | 136 sockaddr_storage addr_storage = {0}; |
152 } | 137 socklen_t addrlen = sizeof(addr_storage); |
153 | 138 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); |
154 SocketAddress GetRemoteAddress() const override { | 139 int result = ::getsockname(s_, addr, &addrlen); |
155 sockaddr_storage addr_storage = {0}; | 140 SocketAddress address; |
156 socklen_t addrlen = sizeof(addr_storage); | 141 if (result >= 0) { |
157 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); | 142 SocketAddressFromSockAddrStorage(addr_storage, &address); |
158 int result = ::getpeername(s_, addr, &addrlen); | 143 } else { |
159 SocketAddress address; | 144 LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket=" |
160 if (result >= 0) { | 145 << s_; |
161 SocketAddressFromSockAddrStorage(addr_storage, &address); | 146 } |
162 } else { | 147 return address; |
163 LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket=" | 148 } |
164 << s_; | 149 |
165 } | 150 SocketAddress PhysicalSocket::GetRemoteAddress() const { |
166 return address; | 151 sockaddr_storage addr_storage = {0}; |
167 } | 152 socklen_t addrlen = sizeof(addr_storage); |
168 | 153 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); |
169 int Bind(const SocketAddress& bind_addr) override { | 154 int result = ::getpeername(s_, addr, &addrlen); |
170 sockaddr_storage addr_storage; | 155 SocketAddress address; |
171 size_t len = bind_addr.ToSockAddrStorage(&addr_storage); | 156 if (result >= 0) { |
172 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); | 157 SocketAddressFromSockAddrStorage(addr_storage, &address); |
173 int err = ::bind(s_, addr, static_cast<int>(len)); | 158 } else { |
174 UpdateLastError(); | 159 LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket=" |
| 160 << s_; |
| 161 } |
| 162 return address; |
| 163 } |
| 164 |
| 165 int 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(); |
175 #if !defined(NDEBUG) | 171 #if !defined(NDEBUG) |
176 if (0 == err) { | 172 if (0 == err) { |
177 dbg_addr_ = "Bound @ "; | 173 dbg_addr_ = "Bound @ "; |
178 dbg_addr_.append(GetLocalAddress().ToString()); | 174 dbg_addr_.append(GetLocalAddress().ToString()); |
179 } | 175 } |
180 #endif | 176 #endif |
181 return err; | 177 return err; |
182 } | 178 } |
183 | 179 |
184 int Connect(const SocketAddress& addr) override { | 180 int PhysicalSocket::Connect(const SocketAddress& addr) { |
185 // TODO: Implicit creation is required to reconnect... | 181 // TODO: Implicit creation is required to reconnect... |
186 // ...but should we make it more explicit? | 182 // ...but should we make it more explicit? |
187 if (state_ != CS_CLOSED) { | 183 if (state_ != CS_CLOSED) { |
188 SetError(EALREADY); | 184 SetError(EALREADY); |
189 return SOCKET_ERROR; | 185 return SOCKET_ERROR; |
190 } | 186 } |
191 if (addr.IsUnresolvedIP()) { | 187 if (addr.IsUnresolvedIP()) { |
192 LOG(LS_VERBOSE) << "Resolving addr in PhysicalSocket::Connect"; | 188 LOG(LS_VERBOSE) << "Resolving addr in PhysicalSocket::Connect"; |
193 resolver_ = new AsyncResolver(); | 189 resolver_ = new AsyncResolver(); |
194 resolver_->SignalDone.connect(this, &PhysicalSocket::OnResolveResult); | 190 resolver_->SignalDone.connect(this, &PhysicalSocket::OnResolveResult); |
195 resolver_->Start(addr); | 191 resolver_->Start(addr); |
196 state_ = CS_CONNECTING; | 192 state_ = CS_CONNECTING; |
| 193 return 0; |
| 194 } |
| 195 |
| 196 return DoConnect(addr); |
| 197 } |
| 198 |
| 199 int 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; |
| 216 } |
| 217 |
| 218 enabled_events_ |= DE_READ | DE_WRITE; |
| 219 return 0; |
| 220 } |
| 221 |
| 222 int PhysicalSocket::GetError() const { |
| 223 CritScope cs(&crit_); |
| 224 return error_; |
| 225 } |
| 226 |
| 227 void PhysicalSocket::SetError(int error) { |
| 228 CritScope cs(&crit_); |
| 229 error_ = error; |
| 230 } |
| 231 |
| 232 int PhysicalSocket::GetOption(Option opt, int* value) { |
| 233 int slevel; |
| 234 int sopt; |
| 235 if (TranslateOption(opt, &slevel, &sopt) == -1) |
| 236 return -1; |
| 237 socklen_t optlen = sizeof(*value); |
| 238 int ret = ::getsockopt(s_, slevel, sopt, (SockOptArg)value, &optlen); |
| 239 if (ret != -1 && opt == OPT_DONTFRAGMENT) { |
| 240 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) |
| 241 *value = (*value != IP_PMTUDISC_DONT) ? 1 : 0; |
| 242 #endif |
| 243 } |
| 244 return ret; |
| 245 } |
| 246 |
| 247 int PhysicalSocket::SetOption(Option opt, int value) { |
| 248 int slevel; |
| 249 int sopt; |
| 250 if (TranslateOption(opt, &slevel, &sopt) == -1) |
| 251 return -1; |
| 252 if (opt == OPT_DONTFRAGMENT) { |
| 253 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) |
| 254 value = (value) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; |
| 255 #endif |
| 256 } |
| 257 return ::setsockopt(s_, slevel, sopt, (SockOptArg)&value, sizeof(value)); |
| 258 } |
| 259 |
| 260 int PhysicalSocket::Send(const void* pv, size_t cb) { |
| 261 int sent = ::send(s_, reinterpret_cast<const char *>(pv), (int)cb, |
| 262 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) |
| 263 // Suppress SIGPIPE. Without this, attempting to send on a socket whose |
| 264 // other end is closed will result in a SIGPIPE signal being raised to |
| 265 // our process, which by default will terminate the process, which we |
| 266 // don't want. By specifying this flag, we'll just get the error EPIPE |
| 267 // instead and can handle the error gracefully. |
| 268 MSG_NOSIGNAL |
| 269 #else |
| 270 0 |
| 271 #endif |
| 272 ); |
| 273 UpdateLastError(); |
| 274 MaybeRemapSendError(); |
| 275 // We have seen minidumps where this may be false. |
| 276 ASSERT(sent <= static_cast<int>(cb)); |
| 277 if ((sent < 0) && IsBlockingError(GetError())) { |
| 278 enabled_events_ |= DE_WRITE; |
| 279 } |
| 280 return sent; |
| 281 } |
| 282 |
| 283 int PhysicalSocket::SendTo(const void* buffer, |
| 284 size_t length, |
| 285 const SocketAddress& addr) { |
| 286 sockaddr_storage saddr; |
| 287 size_t len = addr.ToSockAddrStorage(&saddr); |
| 288 int sent = ::sendto( |
| 289 s_, static_cast<const char *>(buffer), static_cast<int>(length), |
| 290 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) |
| 291 // Suppress SIGPIPE. See above for explanation. |
| 292 MSG_NOSIGNAL, |
| 293 #else |
| 294 0, |
| 295 #endif |
| 296 reinterpret_cast<sockaddr*>(&saddr), static_cast<int>(len)); |
| 297 UpdateLastError(); |
| 298 MaybeRemapSendError(); |
| 299 // We have seen minidumps where this may be false. |
| 300 ASSERT(sent <= static_cast<int>(length)); |
| 301 if ((sent < 0) && IsBlockingError(GetError())) { |
| 302 enabled_events_ |= DE_WRITE; |
| 303 } |
| 304 return sent; |
| 305 } |
| 306 |
| 307 int PhysicalSocket::Recv(void* buffer, size_t length) { |
| 308 int received = ::recv(s_, static_cast<char*>(buffer), |
| 309 static_cast<int>(length), 0); |
| 310 if ((received == 0) && (length != 0)) { |
| 311 // Note: on graceful shutdown, recv can return 0. In this case, we |
| 312 // pretend it is blocking, and then signal close, so that simplifying |
| 313 // assumptions can be made about Recv. |
| 314 LOG(LS_WARNING) << "EOF from socket; deferring close event"; |
| 315 // Must turn this back on so that the select() loop will notice the close |
| 316 // event. |
| 317 enabled_events_ |= DE_READ; |
| 318 SetError(EWOULDBLOCK); |
| 319 return SOCKET_ERROR; |
| 320 } |
| 321 UpdateLastError(); |
| 322 int error = GetError(); |
| 323 bool success = (received >= 0) || IsBlockingError(error); |
| 324 if (udp_ || success) { |
| 325 enabled_events_ |= DE_READ; |
| 326 } |
| 327 if (!success) { |
| 328 LOG_F(LS_VERBOSE) << "Error = " << error; |
| 329 } |
| 330 return received; |
| 331 } |
| 332 |
| 333 int PhysicalSocket::RecvFrom(void* buffer, |
| 334 size_t length, |
| 335 SocketAddress* out_addr) { |
| 336 sockaddr_storage addr_storage; |
| 337 socklen_t addr_len = sizeof(addr_storage); |
| 338 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); |
| 339 int received = ::recvfrom(s_, static_cast<char*>(buffer), |
| 340 static_cast<int>(length), 0, addr, &addr_len); |
| 341 UpdateLastError(); |
| 342 if ((received >= 0) && (out_addr != nullptr)) |
| 343 SocketAddressFromSockAddrStorage(addr_storage, out_addr); |
| 344 int error = GetError(); |
| 345 bool success = (received >= 0) || IsBlockingError(error); |
| 346 if (udp_ || success) { |
| 347 enabled_events_ |= DE_READ; |
| 348 } |
| 349 if (!success) { |
| 350 LOG_F(LS_VERBOSE) << "Error = " << error; |
| 351 } |
| 352 return received; |
| 353 } |
| 354 |
| 355 int PhysicalSocket::Listen(int backlog) { |
| 356 int err = ::listen(s_, backlog); |
| 357 UpdateLastError(); |
| 358 if (err == 0) { |
| 359 state_ = CS_CONNECTING; |
| 360 enabled_events_ |= DE_ACCEPT; |
| 361 #if !defined(NDEBUG) |
| 362 dbg_addr_ = "Listening @ "; |
| 363 dbg_addr_.append(GetLocalAddress().ToString()); |
| 364 #endif |
| 365 } |
| 366 return err; |
| 367 } |
| 368 |
| 369 AsyncSocket* PhysicalSocket::Accept(SocketAddress* out_addr) { |
| 370 // Always re-subscribe DE_ACCEPT to make sure new incoming connections will |
| 371 // trigger an event even if DoAccept returns an error here. |
| 372 enabled_events_ |= DE_ACCEPT; |
| 373 sockaddr_storage addr_storage; |
| 374 socklen_t addr_len = sizeof(addr_storage); |
| 375 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); |
| 376 SOCKET s = DoAccept(s_, addr, &addr_len); |
| 377 UpdateLastError(); |
| 378 if (s == INVALID_SOCKET) |
| 379 return nullptr; |
| 380 if (out_addr != nullptr) |
| 381 SocketAddressFromSockAddrStorage(addr_storage, out_addr); |
| 382 return ss_->WrapSocket(s); |
| 383 } |
| 384 |
| 385 int PhysicalSocket::Close() { |
| 386 if (s_ == INVALID_SOCKET) |
| 387 return 0; |
| 388 int err = ::closesocket(s_); |
| 389 UpdateLastError(); |
| 390 s_ = INVALID_SOCKET; |
| 391 state_ = CS_CLOSED; |
| 392 enabled_events_ = 0; |
| 393 if (resolver_) { |
| 394 resolver_->Destroy(false); |
| 395 resolver_ = nullptr; |
| 396 } |
| 397 return err; |
| 398 } |
| 399 |
| 400 int PhysicalSocket::EstimateMTU(uint16_t* mtu) { |
| 401 SocketAddress addr = GetRemoteAddress(); |
| 402 if (addr.IsAnyIP()) { |
| 403 SetError(ENOTCONN); |
| 404 return -1; |
| 405 } |
| 406 |
| 407 #if defined(WEBRTC_WIN) |
| 408 // Gets the interface MTU (TTL=1) for the interface used to reach |addr|. |
| 409 WinPing ping; |
| 410 if (!ping.IsValid()) { |
| 411 SetError(EINVAL); // can't think of a better error ID |
| 412 return -1; |
| 413 } |
| 414 int header_size = ICMP_HEADER_SIZE; |
| 415 if (addr.family() == AF_INET6) { |
| 416 header_size += IPV6_HEADER_SIZE; |
| 417 } else if (addr.family() == AF_INET) { |
| 418 header_size += IP_HEADER_SIZE; |
| 419 } |
| 420 |
| 421 for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) { |
| 422 int32_t size = PACKET_MAXIMUMS[level] - header_size; |
| 423 WinPing::PingResult result = ping.Ping(addr.ipaddr(), size, |
| 424 ICMP_PING_TIMEOUT_MILLIS, |
| 425 1, false); |
| 426 if (result == WinPing::PING_FAIL) { |
| 427 SetError(EINVAL); // can't think of a better error ID |
| 428 return -1; |
| 429 } else if (result != WinPing::PING_TOO_LARGE) { |
| 430 *mtu = PACKET_MAXIMUMS[level]; |
197 return 0; | 431 return 0; |
198 } | 432 } |
199 | 433 } |
200 return DoConnect(addr); | 434 |
201 } | 435 ASSERT(false); |
202 | 436 return -1; |
203 int DoConnect(const SocketAddress& connect_addr) { | 437 #elif defined(WEBRTC_MAC) |
204 if ((s_ == INVALID_SOCKET) && | 438 // No simple way to do this on Mac OS X. |
205 !Create(connect_addr.family(), SOCK_STREAM)) { | 439 // SIOCGIFMTU would work if we knew which interface would be used, but |
206 return SOCKET_ERROR; | 440 // figuring that out is pretty complicated. For now we'll return an error |
207 } | 441 // and let the caller pick a default MTU. |
208 sockaddr_storage addr_storage; | 442 SetError(EINVAL); |
209 size_t len = connect_addr.ToSockAddrStorage(&addr_storage); | 443 return -1; |
210 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); | 444 #elif defined(WEBRTC_LINUX) |
211 int err = ::connect(s_, addr, static_cast<int>(len)); | 445 // Gets the path MTU. |
| 446 int value; |
| 447 socklen_t vlen = sizeof(value); |
| 448 int err = getsockopt(s_, IPPROTO_IP, IP_MTU, &value, &vlen); |
| 449 if (err < 0) { |
212 UpdateLastError(); | 450 UpdateLastError(); |
213 if (err == 0) { | 451 return err; |
214 state_ = CS_CONNECTED; | 452 } |
215 } else if (IsBlockingError(GetError())) { | 453 |
216 state_ = CS_CONNECTING; | 454 ASSERT((0 <= value) && (value <= 65536)); |
217 enabled_events_ |= DE_CONNECT; | 455 *mtu = value; |
218 } else { | 456 return 0; |
219 return SOCKET_ERROR; | 457 #elif defined(__native_client__) |
220 } | 458 // Most socket operations, including this, will fail in NaCl's sandbox. |
221 | 459 error_ = EACCES; |
222 enabled_events_ |= DE_READ | DE_WRITE; | 460 return -1; |
223 return 0; | 461 #endif |
224 } | 462 } |
225 | 463 |
226 int GetError() const override { | 464 |
227 CritScope cs(&crit_); | 465 SOCKET PhysicalSocket::DoAccept(SOCKET socket, |
228 return error_; | 466 sockaddr* addr, |
229 } | 467 socklen_t* addrlen) { |
230 | 468 return ::accept(socket, addr, addrlen); |
231 void SetError(int error) override { | 469 } |
232 CritScope cs(&crit_); | 470 |
233 error_ = error; | 471 void PhysicalSocket::OnResolveResult(AsyncResolverInterface* resolver) { |
234 } | 472 if (resolver != resolver_) { |
235 | 473 return; |
236 ConnState GetState() const override { return state_; } | 474 } |
237 | 475 |
238 int GetOption(Option opt, int* value) override { | 476 int error = resolver_->GetError(); |
239 int slevel; | 477 if (error == 0) { |
240 int sopt; | 478 error = DoConnect(resolver_->address()); |
241 if (TranslateOption(opt, &slevel, &sopt) == -1) | 479 } else { |
| 480 Close(); |
| 481 } |
| 482 |
| 483 if (error) { |
| 484 SetError(error); |
| 485 SignalCloseEvent(this, error); |
| 486 } |
| 487 } |
| 488 |
| 489 void PhysicalSocket::UpdateLastError() { |
| 490 SetError(LAST_SYSTEM_ERROR); |
| 491 } |
| 492 |
| 493 void PhysicalSocket::MaybeRemapSendError() { |
| 494 #if defined(WEBRTC_MAC) |
| 495 // https://developer.apple.com/library/mac/documentation/Darwin/ |
| 496 // Reference/ManPages/man2/sendto.2.html |
| 497 // ENOBUFS - The output queue for a network interface is full. |
| 498 // This generally indicates that the interface has stopped sending, |
| 499 // but may be caused by transient congestion. |
| 500 if (GetError() == ENOBUFS) { |
| 501 SetError(EWOULDBLOCK); |
| 502 } |
| 503 #endif |
| 504 } |
| 505 |
| 506 int PhysicalSocket::TranslateOption(Option opt, int* slevel, int* sopt) { |
| 507 switch (opt) { |
| 508 case OPT_DONTFRAGMENT: |
| 509 #if defined(WEBRTC_WIN) |
| 510 *slevel = IPPROTO_IP; |
| 511 *sopt = IP_DONTFRAGMENT; |
| 512 break; |
| 513 #elif defined(WEBRTC_MAC) || defined(BSD) || defined(__native_client__) |
| 514 LOG(LS_WARNING) << "Socket::OPT_DONTFRAGMENT not supported."; |
242 return -1; | 515 return -1; |
243 socklen_t optlen = sizeof(*value); | 516 #elif defined(WEBRTC_POSIX) |
244 int ret = ::getsockopt(s_, slevel, sopt, (SockOptArg)value, &optlen); | 517 *slevel = IPPROTO_IP; |
245 if (ret != -1 && opt == OPT_DONTFRAGMENT) { | 518 *sopt = IP_MTU_DISCOVER; |
246 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) | 519 break; |
247 *value = (*value != IP_PMTUDISC_DONT) ? 1 : 0; | 520 #endif |
248 #endif | 521 case OPT_RCVBUF: |
249 } | 522 *slevel = SOL_SOCKET; |
250 return ret; | 523 *sopt = SO_RCVBUF; |
251 } | 524 break; |
252 | 525 case OPT_SNDBUF: |
253 int SetOption(Option opt, int value) override { | 526 *slevel = SOL_SOCKET; |
254 int slevel; | 527 *sopt = SO_SNDBUF; |
255 int sopt; | 528 break; |
256 if (TranslateOption(opt, &slevel, &sopt) == -1) | 529 case OPT_NODELAY: |
| 530 *slevel = IPPROTO_TCP; |
| 531 *sopt = TCP_NODELAY; |
| 532 break; |
| 533 case OPT_DSCP: |
| 534 LOG(LS_WARNING) << "Socket::OPT_DSCP not supported."; |
257 return -1; | 535 return -1; |
258 if (opt == OPT_DONTFRAGMENT) { | 536 case OPT_RTP_SENDTIME_EXTN_ID: |
259 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) | 537 return -1; // No logging is necessary as this not a OS socket option. |
260 value = (value) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; | 538 default: |
261 #endif | 539 ASSERT(false); |
262 } | |
263 return ::setsockopt(s_, slevel, sopt, (SockOptArg)&value, sizeof(value)); | |
264 } | |
265 | |
266 int Send(const void* pv, size_t cb) override { | |
267 int sent = ::send(s_, reinterpret_cast<const char *>(pv), (int)cb, | |
268 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) | |
269 // Suppress SIGPIPE. Without this, attempting to send on a socket whose | |
270 // other end is closed will result in a SIGPIPE signal being raised to | |
271 // our process, which by default will terminate the process, which we | |
272 // don't want. By specifying this flag, we'll just get the error EPIPE | |
273 // instead and can handle the error gracefully. | |
274 MSG_NOSIGNAL | |
275 #else | |
276 0 | |
277 #endif | |
278 ); | |
279 UpdateLastError(); | |
280 MaybeRemapSendError(); | |
281 // We have seen minidumps where this may be false. | |
282 ASSERT(sent <= static_cast<int>(cb)); | |
283 if ((sent < 0) && IsBlockingError(GetError())) { | |
284 enabled_events_ |= DE_WRITE; | |
285 } | |
286 return sent; | |
287 } | |
288 | |
289 int SendTo(const void* buffer, | |
290 size_t length, | |
291 const SocketAddress& addr) override { | |
292 sockaddr_storage saddr; | |
293 size_t len = addr.ToSockAddrStorage(&saddr); | |
294 int sent = ::sendto( | |
295 s_, static_cast<const char *>(buffer), static_cast<int>(length), | |
296 #if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) | |
297 // Suppress SIGPIPE. See above for explanation. | |
298 MSG_NOSIGNAL, | |
299 #else | |
300 0, | |
301 #endif | |
302 reinterpret_cast<sockaddr*>(&saddr), static_cast<int>(len)); | |
303 UpdateLastError(); | |
304 MaybeRemapSendError(); | |
305 // We have seen minidumps where this may be false. | |
306 ASSERT(sent <= static_cast<int>(length)); | |
307 if ((sent < 0) && IsBlockingError(GetError())) { | |
308 enabled_events_ |= DE_WRITE; | |
309 } | |
310 return sent; | |
311 } | |
312 | |
313 int Recv(void* buffer, size_t length) override { | |
314 int received = ::recv(s_, static_cast<char*>(buffer), | |
315 static_cast<int>(length), 0); | |
316 if ((received == 0) && (length != 0)) { | |
317 // Note: on graceful shutdown, recv can return 0. In this case, we | |
318 // pretend it is blocking, and then signal close, so that simplifying | |
319 // assumptions can be made about Recv. | |
320 LOG(LS_WARNING) << "EOF from socket; deferring close event"; | |
321 // Must turn this back on so that the select() loop will notice the close | |
322 // event. | |
323 enabled_events_ |= DE_READ; | |
324 SetError(EWOULDBLOCK); | |
325 return SOCKET_ERROR; | |
326 } | |
327 UpdateLastError(); | |
328 int error = GetError(); | |
329 bool success = (received >= 0) || IsBlockingError(error); | |
330 if (udp_ || success) { | |
331 enabled_events_ |= DE_READ; | |
332 } | |
333 if (!success) { | |
334 LOG_F(LS_VERBOSE) << "Error = " << error; | |
335 } | |
336 return received; | |
337 } | |
338 | |
339 int RecvFrom(void* buffer, size_t length, SocketAddress* out_addr) override { | |
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 != NULL)) | |
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 | |
359 int Listen(int backlog) override { | |
360 int err = ::listen(s_, backlog); | |
361 UpdateLastError(); | |
362 if (err == 0) { | |
363 state_ = CS_CONNECTING; | |
364 enabled_events_ |= DE_ACCEPT; | |
365 #if !defined(NDEBUG) | |
366 dbg_addr_ = "Listening @ "; | |
367 dbg_addr_.append(GetLocalAddress().ToString()); | |
368 #endif | |
369 } | |
370 return err; | |
371 } | |
372 | |
373 AsyncSocket* Accept(SocketAddress* out_addr) override { | |
374 sockaddr_storage addr_storage; | |
375 socklen_t addr_len = sizeof(addr_storage); | |
376 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); | |
377 SOCKET s = ::accept(s_, addr, &addr_len); | |
378 UpdateLastError(); | |
379 if (s == INVALID_SOCKET) | |
380 return NULL; | |
381 enabled_events_ |= DE_ACCEPT; | |
382 if (out_addr != NULL) | |
383 SocketAddressFromSockAddrStorage(addr_storage, out_addr); | |
384 return ss_->WrapSocket(s); | |
385 } | |
386 | |
387 int Close() override { | |
388 if (s_ == INVALID_SOCKET) | |
389 return 0; | |
390 int err = ::closesocket(s_); | |
391 UpdateLastError(); | |
392 s_ = INVALID_SOCKET; | |
393 state_ = CS_CLOSED; | |
394 enabled_events_ = 0; | |
395 if (resolver_) { | |
396 resolver_->Destroy(false); | |
397 resolver_ = NULL; | |
398 } | |
399 return err; | |
400 } | |
401 | |
402 int EstimateMTU(uint16_t* mtu) override { | |
403 SocketAddress addr = GetRemoteAddress(); | |
404 if (addr.IsAnyIP()) { | |
405 SetError(ENOTCONN); | |
406 return -1; | 540 return -1; |
407 } | 541 } |
408 | 542 return 0; |
409 #if defined(WEBRTC_WIN) | 543 } |
410 // Gets the interface MTU (TTL=1) for the interface used to reach |addr|. | |
411 WinPing ping; | |
412 if (!ping.IsValid()) { | |
413 SetError(EINVAL); // can't think of a better error ID | |
414 return -1; | |
415 } | |
416 int header_size = ICMP_HEADER_SIZE; | |
417 if (addr.family() == AF_INET6) { | |
418 header_size += IPV6_HEADER_SIZE; | |
419 } else if (addr.family() == AF_INET) { | |
420 header_size += IP_HEADER_SIZE; | |
421 } | |
422 | |
423 for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) { | |
424 int32_t size = PACKET_MAXIMUMS[level] - header_size; | |
425 WinPing::PingResult result = ping.Ping(addr.ipaddr(), size, | |
426 ICMP_PING_TIMEOUT_MILLIS, | |
427 1, false); | |
428 if (result == WinPing::PING_FAIL) { | |
429 SetError(EINVAL); // can't think of a better error ID | |
430 return -1; | |
431 } else if (result != WinPing::PING_TOO_LARGE) { | |
432 *mtu = PACKET_MAXIMUMS[level]; | |
433 return 0; | |
434 } | |
435 } | |
436 | |
437 ASSERT(false); | |
438 return -1; | |
439 #elif defined(WEBRTC_MAC) | |
440 // No simple way to do this on Mac OS X. | |
441 // SIOCGIFMTU would work if we knew which interface would be used, but | |
442 // figuring that out is pretty complicated. For now we'll return an error | |
443 // and let the caller pick a default MTU. | |
444 SetError(EINVAL); | |
445 return -1; | |
446 #elif defined(WEBRTC_LINUX) | |
447 // Gets the path MTU. | |
448 int value; | |
449 socklen_t vlen = sizeof(value); | |
450 int err = getsockopt(s_, IPPROTO_IP, IP_MTU, &value, &vlen); | |
451 if (err < 0) { | |
452 UpdateLastError(); | |
453 return err; | |
454 } | |
455 | |
456 ASSERT((0 <= value) && (value <= 65536)); | |
457 *mtu = value; | |
458 return 0; | |
459 #elif defined(__native_client__) | |
460 // Most socket operations, including this, will fail in NaCl's sandbox. | |
461 error_ = EACCES; | |
462 return -1; | |
463 #endif | |
464 } | |
465 | |
466 SocketServer* socketserver() { return ss_; } | |
467 | |
468 protected: | |
469 void OnResolveResult(AsyncResolverInterface* resolver) { | |
470 if (resolver != resolver_) { | |
471 return; | |
472 } | |
473 | |
474 int error = resolver_->GetError(); | |
475 if (error == 0) { | |
476 error = DoConnect(resolver_->address()); | |
477 } else { | |
478 Close(); | |
479 } | |
480 | |
481 if (error) { | |
482 SetError(error); | |
483 SignalCloseEvent(this, error); | |
484 } | |
485 } | |
486 | |
487 void UpdateLastError() { | |
488 SetError(LAST_SYSTEM_ERROR); | |
489 } | |
490 | |
491 void MaybeRemapSendError() { | |
492 #if defined(WEBRTC_MAC) | |
493 // https://developer.apple.com/library/mac/documentation/Darwin/ | |
494 // Reference/ManPages/man2/sendto.2.html | |
495 // ENOBUFS - The output queue for a network interface is full. | |
496 // This generally indicates that the interface has stopped sending, | |
497 // but may be caused by transient congestion. | |
498 if (GetError() == ENOBUFS) { | |
499 SetError(EWOULDBLOCK); | |
500 } | |
501 #endif | |
502 } | |
503 | |
504 static int TranslateOption(Option opt, int* slevel, int* sopt) { | |
505 switch (opt) { | |
506 case OPT_DONTFRAGMENT: | |
507 #if defined(WEBRTC_WIN) | |
508 *slevel = IPPROTO_IP; | |
509 *sopt = IP_DONTFRAGMENT; | |
510 break; | |
511 #elif defined(WEBRTC_MAC) || defined(BSD) || defined(__native_client__) | |
512 LOG(LS_WARNING) << "Socket::OPT_DONTFRAGMENT not supported."; | |
513 return -1; | |
514 #elif defined(WEBRTC_POSIX) | |
515 *slevel = IPPROTO_IP; | |
516 *sopt = IP_MTU_DISCOVER; | |
517 break; | |
518 #endif | |
519 case OPT_RCVBUF: | |
520 *slevel = SOL_SOCKET; | |
521 *sopt = SO_RCVBUF; | |
522 break; | |
523 case OPT_SNDBUF: | |
524 *slevel = SOL_SOCKET; | |
525 *sopt = SO_SNDBUF; | |
526 break; | |
527 case OPT_NODELAY: | |
528 *slevel = IPPROTO_TCP; | |
529 *sopt = TCP_NODELAY; | |
530 break; | |
531 case OPT_DSCP: | |
532 LOG(LS_WARNING) << "Socket::OPT_DSCP not supported."; | |
533 return -1; | |
534 case OPT_RTP_SENDTIME_EXTN_ID: | |
535 return -1; // No logging is necessary as this not a OS socket option. | |
536 default: | |
537 ASSERT(false); | |
538 return -1; | |
539 } | |
540 return 0; | |
541 } | |
542 | |
543 PhysicalSocketServer* ss_; | |
544 SOCKET s_; | |
545 uint8_t enabled_events_; | |
546 bool udp_; | |
547 int error_; | |
548 // Protects |error_| that is accessed from different threads. | |
549 mutable CriticalSection crit_; | |
550 ConnState state_; | |
551 AsyncResolver* resolver_; | |
552 | |
553 #if !defined(NDEBUG) | |
554 std::string dbg_addr_; | |
555 #endif | |
556 }; | |
557 | 544 |
558 #if defined(WEBRTC_POSIX) | 545 #if defined(WEBRTC_POSIX) |
559 class EventDispatcher : public Dispatcher { | 546 class EventDispatcher : public Dispatcher { |
560 public: | 547 public: |
561 EventDispatcher(PhysicalSocketServer* ss) : ss_(ss), fSignaled_(false) { | 548 EventDispatcher(PhysicalSocketServer* ss) : ss_(ss), fSignaled_(false) { |
562 if (pipe(afd_) < 0) | 549 if (pipe(afd_) < 0) |
563 LOG(LERROR) << "pipe failed"; | 550 LOG(LERROR) << "pipe failed"; |
564 ss_->Add(this); | 551 ss_->Add(this); |
565 } | 552 } |
566 | 553 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 } | 771 } |
785 | 772 |
786 private: | 773 private: |
787 typedef std::map<int, void (*)(int)> HandlerMap; | 774 typedef std::map<int, void (*)(int)> HandlerMap; |
788 | 775 |
789 HandlerMap handlers_; | 776 HandlerMap handlers_; |
790 // Our owner. | 777 // Our owner. |
791 PhysicalSocketServer *owner_; | 778 PhysicalSocketServer *owner_; |
792 }; | 779 }; |
793 | 780 |
794 class SocketDispatcher : public Dispatcher, public PhysicalSocket { | 781 SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss) |
795 public: | 782 : PhysicalSocket(ss) { |
796 explicit SocketDispatcher(PhysicalSocketServer *ss) : PhysicalSocket(ss) { | 783 } |
797 } | |
798 SocketDispatcher(SOCKET s, PhysicalSocketServer *ss) : PhysicalSocket(ss, s) { | |
799 } | |
800 | 784 |
801 ~SocketDispatcher() override { | 785 SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss) |
802 Close(); | 786 : PhysicalSocket(ss, s) { |
803 } | 787 } |
804 | 788 |
805 bool Initialize() { | 789 SocketDispatcher::~SocketDispatcher() { |
806 ss_->Add(this); | 790 Close(); |
807 fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK); | 791 } |
| 792 |
| 793 bool SocketDispatcher::Initialize() { |
| 794 ss_->Add(this); |
| 795 fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK); |
| 796 return true; |
| 797 } |
| 798 |
| 799 bool SocketDispatcher::Create(int type) { |
| 800 return Create(AF_INET, type); |
| 801 } |
| 802 |
| 803 bool SocketDispatcher::Create(int family, int type) { |
| 804 // Change the socket to be non-blocking. |
| 805 if (!PhysicalSocket::Create(family, type)) |
| 806 return false; |
| 807 |
| 808 return Initialize(); |
| 809 } |
| 810 |
| 811 bool SocketDispatcher::IsDescriptorClosed() { |
| 812 // We don't have a reliable way of distinguishing end-of-stream |
| 813 // from readability. So test on each readable call. Is this |
| 814 // inefficient? Probably. |
| 815 char ch; |
| 816 ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK); |
| 817 if (res > 0) { |
| 818 // Data available, so not closed. |
| 819 return false; |
| 820 } else if (res == 0) { |
| 821 // EOF, so closed. |
808 return true; | 822 return true; |
809 } | 823 } else { // error |
810 | 824 switch (errno) { |
811 virtual bool Create(int type) { | 825 // Returned if we've already closed s_. |
812 return Create(AF_INET, type); | 826 case EBADF: |
813 } | 827 // Returned during ungraceful peer shutdown. |
814 | 828 case ECONNRESET: |
815 bool Create(int family, int type) override { | 829 return true; |
816 // Change the socket to be non-blocking. | 830 default: |
817 if (!PhysicalSocket::Create(family, type)) | 831 // Assume that all other errors are just blocking errors, meaning the |
818 return false; | 832 // connection is still good but we just can't read from it right now. |
819 | 833 // This should only happen when connecting (and at most once), because |
820 return Initialize(); | 834 // in all other cases this function is only called if the file |
821 } | 835 // descriptor is already known to be in the readable state. However, |
822 | 836 // it's not necessary a problem if we spuriously interpret a |
823 int GetDescriptor() override { return s_; } | 837 // "connection lost"-type error as a blocking error, because typically |
824 | 838 // the next recv() will get EOF, so we'll still eventually notice that |
825 bool IsDescriptorClosed() override { | 839 // the socket is closed. |
826 // We don't have a reliable way of distinguishing end-of-stream | 840 LOG_ERR(LS_WARNING) << "Assuming benign blocking error"; |
827 // from readability. So test on each readable call. Is this | 841 return false; |
828 // inefficient? Probably. | |
829 char ch; | |
830 ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK); | |
831 if (res > 0) { | |
832 // Data available, so not closed. | |
833 return false; | |
834 } else if (res == 0) { | |
835 // EOF, so closed. | |
836 return true; | |
837 } else { // error | |
838 switch (errno) { | |
839 // Returned if we've already closed s_. | |
840 case EBADF: | |
841 // Returned during ungraceful peer shutdown. | |
842 case ECONNRESET: | |
843 return true; | |
844 default: | |
845 // Assume that all other errors are just blocking errors, meaning the | |
846 // connection is still good but we just can't read from it right now. | |
847 // This should only happen when connecting (and at most once), because | |
848 // in all other cases this function is only called if the file | |
849 // descriptor is already known to be in the readable state. However, | |
850 // it's not necessary a problem if we spuriously interpret a | |
851 // "connection lost"-type error as a blocking error, because typically | |
852 // the next recv() will get EOF, so we'll still eventually notice that | |
853 // the socket is closed. | |
854 LOG_ERR(LS_WARNING) << "Assuming benign blocking error"; | |
855 return false; | |
856 } | |
857 } | 842 } |
858 } | 843 } |
| 844 } |
859 | 845 |
860 uint32_t GetRequestedEvents() override { return enabled_events_; } | 846 void SocketDispatcher::OnPreEvent(uint32_t ff) { |
| 847 if ((ff & DE_CONNECT) != 0) |
| 848 state_ = CS_CONNECTED; |
| 849 if ((ff & DE_CLOSE) != 0) |
| 850 state_ = CS_CLOSED; |
| 851 } |
861 | 852 |
862 void OnPreEvent(uint32_t ff) override { | 853 void SocketDispatcher::OnEvent(uint32_t ff, int err) { |
863 if ((ff & DE_CONNECT) != 0) | 854 // Make sure we deliver connect/accept first. Otherwise, consumers may see |
864 state_ = CS_CONNECTED; | 855 // something like a READ followed by a CONNECT, which would be odd. |
865 if ((ff & DE_CLOSE) != 0) | 856 if ((ff & DE_CONNECT) != 0) { |
866 state_ = CS_CLOSED; | 857 enabled_events_ &= ~DE_CONNECT; |
| 858 SignalConnectEvent(this); |
867 } | 859 } |
| 860 if ((ff & DE_ACCEPT) != 0) { |
| 861 enabled_events_ &= ~DE_ACCEPT; |
| 862 SignalReadEvent(this); |
| 863 } |
| 864 if ((ff & DE_READ) != 0) { |
| 865 enabled_events_ &= ~DE_READ; |
| 866 SignalReadEvent(this); |
| 867 } |
| 868 if ((ff & DE_WRITE) != 0) { |
| 869 enabled_events_ &= ~DE_WRITE; |
| 870 SignalWriteEvent(this); |
| 871 } |
| 872 if ((ff & DE_CLOSE) != 0) { |
| 873 // The socket is now dead to us, so stop checking it. |
| 874 enabled_events_ = 0; |
| 875 SignalCloseEvent(this, err); |
| 876 } |
| 877 } |
868 | 878 |
869 void OnEvent(uint32_t ff, int err) override { | 879 int SocketDispatcher::Close() { |
870 // Make sure we deliver connect/accept first. Otherwise, consumers may see | 880 if (s_ == INVALID_SOCKET) |
871 // something like a READ followed by a CONNECT, which would be odd. | 881 return 0; |
872 if ((ff & DE_CONNECT) != 0) { | |
873 enabled_events_ &= ~DE_CONNECT; | |
874 SignalConnectEvent(this); | |
875 } | |
876 if ((ff & DE_ACCEPT) != 0) { | |
877 enabled_events_ &= ~DE_ACCEPT; | |
878 SignalReadEvent(this); | |
879 } | |
880 if ((ff & DE_READ) != 0) { | |
881 enabled_events_ &= ~DE_READ; | |
882 SignalReadEvent(this); | |
883 } | |
884 if ((ff & DE_WRITE) != 0) { | |
885 enabled_events_ &= ~DE_WRITE; | |
886 SignalWriteEvent(this); | |
887 } | |
888 if ((ff & DE_CLOSE) != 0) { | |
889 // The socket is now dead to us, so stop checking it. | |
890 enabled_events_ = 0; | |
891 SignalCloseEvent(this, err); | |
892 } | |
893 } | |
894 | 882 |
895 int Close() override { | 883 ss_->Remove(this); |
896 if (s_ == INVALID_SOCKET) | 884 return PhysicalSocket::Close(); |
897 return 0; | 885 } |
898 | |
899 ss_->Remove(this); | |
900 return PhysicalSocket::Close(); | |
901 } | |
902 }; | |
903 | 886 |
904 class FileDispatcher: public Dispatcher, public AsyncFile { | 887 class FileDispatcher: public Dispatcher, public AsyncFile { |
905 public: | 888 public: |
906 FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) { | 889 FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) { |
907 set_readable(true); | 890 set_readable(true); |
908 | 891 |
909 ss_->Add(this); | 892 ss_->Add(this); |
910 | 893 |
911 fcntl(fd_, F_SETFL, fcntl(fd_, F_GETFL, 0) | O_NONBLOCK); | 894 fcntl(fd_, F_SETFL, fcntl(fd_, F_GETFL, 0) | O_NONBLOCK); |
912 } | 895 } |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 Socket* PhysicalSocketServer::CreateSocket(int type) { | 1166 Socket* PhysicalSocketServer::CreateSocket(int type) { |
1184 return CreateSocket(AF_INET, type); | 1167 return CreateSocket(AF_INET, type); |
1185 } | 1168 } |
1186 | 1169 |
1187 Socket* PhysicalSocketServer::CreateSocket(int family, int type) { | 1170 Socket* PhysicalSocketServer::CreateSocket(int family, int type) { |
1188 PhysicalSocket* socket = new PhysicalSocket(this); | 1171 PhysicalSocket* socket = new PhysicalSocket(this); |
1189 if (socket->Create(family, type)) { | 1172 if (socket->Create(family, type)) { |
1190 return socket; | 1173 return socket; |
1191 } else { | 1174 } else { |
1192 delete socket; | 1175 delete socket; |
1193 return 0; | 1176 return nullptr; |
1194 } | 1177 } |
1195 } | 1178 } |
1196 | 1179 |
1197 AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int type) { | 1180 AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int type) { |
1198 return CreateAsyncSocket(AF_INET, type); | 1181 return CreateAsyncSocket(AF_INET, type); |
1199 } | 1182 } |
1200 | 1183 |
1201 AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int family, int type) { | 1184 AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int family, int type) { |
1202 SocketDispatcher* dispatcher = new SocketDispatcher(this); | 1185 SocketDispatcher* dispatcher = new SocketDispatcher(this); |
1203 if (dispatcher->Create(family, type)) { | 1186 if (dispatcher->Create(family, type)) { |
1204 return dispatcher; | 1187 return dispatcher; |
1205 } else { | 1188 } else { |
1206 delete dispatcher; | 1189 delete dispatcher; |
1207 return 0; | 1190 return nullptr; |
1208 } | 1191 } |
1209 } | 1192 } |
1210 | 1193 |
1211 AsyncSocket* PhysicalSocketServer::WrapSocket(SOCKET s) { | 1194 AsyncSocket* PhysicalSocketServer::WrapSocket(SOCKET s) { |
1212 SocketDispatcher* dispatcher = new SocketDispatcher(s, this); | 1195 SocketDispatcher* dispatcher = new SocketDispatcher(s, this); |
1213 if (dispatcher->Initialize()) { | 1196 if (dispatcher->Initialize()) { |
1214 return dispatcher; | 1197 return dispatcher; |
1215 } else { | 1198 } else { |
1216 delete dispatcher; | 1199 delete dispatcher; |
1217 return 0; | 1200 return nullptr; |
1218 } | 1201 } |
1219 } | 1202 } |
1220 | 1203 |
1221 void PhysicalSocketServer::Add(Dispatcher *pdispatcher) { | 1204 void PhysicalSocketServer::Add(Dispatcher *pdispatcher) { |
1222 CritScope cs(&crit_); | 1205 CritScope cs(&crit_); |
1223 // Prevent duplicates. This can cause dead dispatchers to stick around. | 1206 // Prevent duplicates. This can cause dead dispatchers to stick around. |
1224 DispatcherList::iterator pos = std::find(dispatchers_.begin(), | 1207 DispatcherList::iterator pos = std::find(dispatchers_.begin(), |
1225 dispatchers_.end(), | 1208 dispatchers_.end(), |
1226 pdispatcher); | 1209 pdispatcher); |
1227 if (pos != dispatchers_.end()) | 1210 if (pos != dispatchers_.end()) |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1628 break; | 1611 break; |
1629 } | 1612 } |
1630 } | 1613 } |
1631 | 1614 |
1632 // Done | 1615 // Done |
1633 return true; | 1616 return true; |
1634 } | 1617 } |
1635 #endif // WEBRTC_WIN | 1618 #endif // WEBRTC_WIN |
1636 | 1619 |
1637 } // namespace rtc | 1620 } // namespace rtc |
OLD | NEW |