OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/tcp_socket.h" | 5 #include "net/socket/tcp_socket.h" |
6 #include "net/socket/tcp_socket_win.h" | 6 #include "net/socket/tcp_socket_win.h" |
7 | 7 |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <mstcpip.h> | 9 #include <mstcpip.h> |
10 | 10 |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 namespace net { | 34 namespace net { |
35 | 35 |
36 namespace { | 36 namespace { |
37 | 37 |
38 const int kTCPKeepAliveSeconds = 45; | 38 const int kTCPKeepAliveSeconds = 45; |
39 | 39 |
40 int SetSocketReceiveBufferSize(SOCKET socket, int32_t size) { | 40 int SetSocketReceiveBufferSize(SOCKET socket, int32_t size) { |
41 int rv = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, | 41 int rv = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, |
42 reinterpret_cast<const char*>(&size), sizeof(size)); | 42 reinterpret_cast<const char*>(&size), sizeof(size)); |
43 int net_error = (rv == 0) ? OK : MapSystemError(WSAGetLastError()); | 43 int os_error = WSAGetLastError(); |
| 44 int net_error = (rv == 0) ? OK : MapSystemError(os_error); |
44 DCHECK(!rv) << "Could not set socket receive buffer size: " << net_error; | 45 DCHECK(!rv) << "Could not set socket receive buffer size: " << net_error; |
45 return net_error; | 46 return net_error; |
46 } | 47 } |
47 | 48 |
48 int SetSocketSendBufferSize(SOCKET socket, int32_t size) { | 49 int SetSocketSendBufferSize(SOCKET socket, int32_t size) { |
49 int rv = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, | 50 int rv = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, |
50 reinterpret_cast<const char*>(&size), sizeof(size)); | 51 reinterpret_cast<const char*>(&size), sizeof(size)); |
51 int net_error = (rv == 0) ? OK : MapSystemError(WSAGetLastError()); | 52 int os_error = WSAGetLastError(); |
| 53 int net_error = (rv == 0) ? OK : MapSystemError(os_error); |
52 DCHECK(!rv) << "Could not set socket send buffer size: " << net_error; | 54 DCHECK(!rv) << "Could not set socket send buffer size: " << net_error; |
53 return net_error; | 55 return net_error; |
54 } | 56 } |
55 | 57 |
56 // Disable Nagle. | 58 // Disable Nagle. |
57 // Enable TCP Keep-Alive to prevent NAT routers from timing out TCP | 59 // Enable TCP Keep-Alive to prevent NAT routers from timing out TCP |
58 // connections. See http://crbug.com/27400 for details. | 60 // connections. See http://crbug.com/27400 for details. |
59 bool SetTCPKeepAlive(SOCKET socket, BOOL enable, int delay_secs) { | 61 bool SetTCPKeepAlive(SOCKET socket, BOOL enable, int delay_secs) { |
60 unsigned delay = delay_secs * 1000; | 62 unsigned delay = delay_secs * 1000; |
61 struct tcp_keepalive keepalive_vals = { | 63 struct tcp_keepalive keepalive_vals = { |
62 enable ? 1u : 0u, // TCP keep-alive on. | 64 enable ? 1u : 0u, // TCP keep-alive on. |
63 delay, // Delay seconds before sending first TCP keep-alive packet. | 65 delay, // Delay seconds before sending first TCP keep-alive packet. |
64 delay, // Delay seconds between sending TCP keep-alive packets. | 66 delay, // Delay seconds between sending TCP keep-alive packets. |
65 }; | 67 }; |
66 DWORD bytes_returned = 0xABAB; | 68 DWORD bytes_returned = 0xABAB; |
67 int rv = WSAIoctl(socket, SIO_KEEPALIVE_VALS, &keepalive_vals, | 69 int rv = WSAIoctl(socket, SIO_KEEPALIVE_VALS, &keepalive_vals, |
68 sizeof(keepalive_vals), NULL, 0, | 70 sizeof(keepalive_vals), NULL, 0, |
69 &bytes_returned, NULL, NULL); | 71 &bytes_returned, NULL, NULL); |
| 72 int os_error = WSAGetLastError(); |
70 DCHECK(!rv) << "Could not enable TCP Keep-Alive for socket: " << socket | 73 DCHECK(!rv) << "Could not enable TCP Keep-Alive for socket: " << socket |
71 << " [error: " << WSAGetLastError() << "]."; | 74 << " [error: " << os_error << "]."; |
72 | 75 |
73 // Disregard any failure in disabling nagle or enabling TCP Keep-Alive. | 76 // Disregard any failure in disabling nagle or enabling TCP Keep-Alive. |
74 return rv == 0; | 77 return rv == 0; |
75 } | 78 } |
76 | 79 |
77 int MapConnectError(int os_error) { | 80 int MapConnectError(int os_error) { |
78 switch (os_error) { | 81 switch (os_error) { |
79 // connect fails with WSAEACCES when Windows Firewall blocks the | 82 // connect fails with WSAEACCES when Windows Firewall blocks the |
80 // connection. | 83 // connection. |
81 case WSAEACCES: | 84 case WSAEACCES: |
82 return ERR_NETWORK_ACCESS_DENIED; | 85 return ERR_NETWORK_ACCESS_DENIED; |
83 case WSAETIMEDOUT: | 86 case WSAETIMEDOUT: |
84 return ERR_CONNECTION_TIMED_OUT; | 87 return ERR_CONNECTION_TIMED_OUT; |
85 default: { | 88 default: { |
86 int net_error = MapSystemError(os_error); | 89 int net_error = MapSystemError(os_error); |
87 if (net_error == ERR_FAILED) | 90 if (net_error == ERR_FAILED) |
88 return ERR_CONNECTION_FAILED; // More specific than ERR_FAILED. | 91 return ERR_CONNECTION_FAILED; // More specific than ERR_FAILED. |
89 | 92 |
90 // Give a more specific error when the user is offline. | 93 // Give a more specific error when the user is offline. |
91 if (net_error == ERR_ADDRESS_UNREACHABLE && | 94 if (net_error == ERR_ADDRESS_UNREACHABLE && |
92 NetworkChangeNotifier::IsOffline()) { | 95 NetworkChangeNotifier::IsOffline()) { |
93 return ERR_INTERNET_DISCONNECTED; | 96 return ERR_INTERNET_DISCONNECTED; |
94 } | 97 } |
95 | 98 |
96 return net_error; | 99 return net_error; |
97 } | 100 } |
98 } | 101 } |
99 } | 102 } |
100 | 103 |
| 104 bool SetNonBlockingAndGetError(int fd, int* os_error) { |
| 105 bool ret = base::SetNonBlocking(fd); |
| 106 *os_error = WSAGetLastError(); |
| 107 |
| 108 return ret; |
| 109 } |
| 110 |
101 } // namespace | 111 } // namespace |
102 | 112 |
103 //----------------------------------------------------------------------------- | 113 //----------------------------------------------------------------------------- |
104 | 114 |
105 // Nothing to do for Windows since it doesn't support TCP FastOpen. | 115 // Nothing to do for Windows since it doesn't support TCP FastOpen. |
106 // TODO(jri): Remove these along with the corresponding global variables. | 116 // TODO(jri): Remove these along with the corresponding global variables. |
107 bool IsTCPFastOpenSupported() { return false; } | 117 bool IsTCPFastOpenSupported() { return false; } |
108 bool IsTCPFastOpenUserEnabled() { return false; } | 118 bool IsTCPFastOpenUserEnabled() { return false; } |
109 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) {} | 119 void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) {} |
110 | 120 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 Close(); | 279 Close(); |
270 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); | 280 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); |
271 } | 281 } |
272 | 282 |
273 int TCPSocketWin::Open(AddressFamily family) { | 283 int TCPSocketWin::Open(AddressFamily family) { |
274 DCHECK(CalledOnValidThread()); | 284 DCHECK(CalledOnValidThread()); |
275 DCHECK_EQ(socket_, INVALID_SOCKET); | 285 DCHECK_EQ(socket_, INVALID_SOCKET); |
276 | 286 |
277 socket_ = CreatePlatformSocket(ConvertAddressFamily(family), SOCK_STREAM, | 287 socket_ = CreatePlatformSocket(ConvertAddressFamily(family), SOCK_STREAM, |
278 IPPROTO_TCP); | 288 IPPROTO_TCP); |
| 289 int os_error = WSAGetLastError(); |
279 if (socket_ == INVALID_SOCKET) { | 290 if (socket_ == INVALID_SOCKET) { |
280 PLOG(ERROR) << "CreatePlatformSocket() returned an error"; | 291 PLOG(ERROR) << "CreatePlatformSocket() returned an error"; |
281 return MapSystemError(WSAGetLastError()); | 292 return MapSystemError(os_error); |
282 } | 293 } |
283 | 294 |
284 if (!base::SetNonBlocking(socket_)) { | 295 if (!SetNonBlockingAndGetError(socket_, &os_error)) { |
285 int result = MapSystemError(WSAGetLastError()); | 296 int result = MapSystemError(os_error); |
286 Close(); | 297 Close(); |
287 return result; | 298 return result; |
288 } | 299 } |
289 | 300 |
290 return OK; | 301 return OK; |
291 } | 302 } |
292 | 303 |
293 int TCPSocketWin::AdoptConnectedSocket(SOCKET socket, | 304 int TCPSocketWin::AdoptConnectedSocket(SOCKET socket, |
294 const IPEndPoint& peer_address) { | 305 const IPEndPoint& peer_address) { |
295 DCHECK(CalledOnValidThread()); | 306 DCHECK(CalledOnValidThread()); |
296 DCHECK_EQ(socket_, INVALID_SOCKET); | 307 DCHECK_EQ(socket_, INVALID_SOCKET); |
297 DCHECK(!core_.get()); | 308 DCHECK(!core_.get()); |
298 | 309 |
299 socket_ = socket; | 310 socket_ = socket; |
300 | 311 |
301 if (!base::SetNonBlocking(socket_)) { | 312 int os_error; |
302 int result = MapSystemError(WSAGetLastError()); | 313 if (!SetNonBlockingAndGetError(socket_, &os_error)) { |
| 314 int result = MapSystemError(os_error); |
303 Close(); | 315 Close(); |
304 return result; | 316 return result; |
305 } | 317 } |
306 | 318 |
307 core_ = new Core(this); | 319 core_ = new Core(this); |
308 peer_address_.reset(new IPEndPoint(peer_address)); | 320 peer_address_.reset(new IPEndPoint(peer_address)); |
309 | 321 |
310 return OK; | 322 return OK; |
311 } | 323 } |
312 | 324 |
313 int TCPSocketWin::AdoptListenSocket(SOCKET socket) { | 325 int TCPSocketWin::AdoptListenSocket(SOCKET socket) { |
314 DCHECK(CalledOnValidThread()); | 326 DCHECK(CalledOnValidThread()); |
315 DCHECK_EQ(socket_, INVALID_SOCKET); | 327 DCHECK_EQ(socket_, INVALID_SOCKET); |
316 | 328 |
317 socket_ = socket; | 329 socket_ = socket; |
318 | 330 |
319 if (!base::SetNonBlocking(socket_)) { | 331 int os_error; |
320 int result = MapSystemError(WSAGetLastError()); | 332 if (!SetNonBlockingAndGetError(socket_, &os_error)) { |
| 333 int result = MapSystemError(os_error); |
321 Close(); | 334 Close(); |
322 return result; | 335 return result; |
323 } | 336 } |
324 | 337 |
325 // |core_| is not needed for sockets that are used to accept connections. | 338 // |core_| is not needed for sockets that are used to accept connections. |
326 // The operation here is more like Open but with an existing socket. | 339 // The operation here is more like Open but with an existing socket. |
327 | 340 |
328 return OK; | 341 return OK; |
329 } | 342 } |
330 | 343 |
331 int TCPSocketWin::Bind(const IPEndPoint& address) { | 344 int TCPSocketWin::Bind(const IPEndPoint& address) { |
332 DCHECK(CalledOnValidThread()); | 345 DCHECK(CalledOnValidThread()); |
333 DCHECK_NE(socket_, INVALID_SOCKET); | 346 DCHECK_NE(socket_, INVALID_SOCKET); |
334 | 347 |
335 SockaddrStorage storage; | 348 SockaddrStorage storage; |
336 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) | 349 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
337 return ERR_ADDRESS_INVALID; | 350 return ERR_ADDRESS_INVALID; |
338 | 351 |
339 int result = bind(socket_, storage.addr, storage.addr_len); | 352 int result = bind(socket_, storage.addr, storage.addr_len); |
| 353 int os_error = WSAGetLastError(); |
340 if (result < 0) { | 354 if (result < 0) { |
341 PLOG(ERROR) << "bind() returned an error"; | 355 PLOG(ERROR) << "bind() returned an error"; |
342 return MapSystemError(WSAGetLastError()); | 356 return MapSystemError(os_error); |
343 } | 357 } |
344 | 358 |
345 return OK; | 359 return OK; |
346 } | 360 } |
347 | 361 |
348 int TCPSocketWin::Listen(int backlog) { | 362 int TCPSocketWin::Listen(int backlog) { |
349 DCHECK(CalledOnValidThread()); | 363 DCHECK(CalledOnValidThread()); |
350 DCHECK_GT(backlog, 0); | 364 DCHECK_GT(backlog, 0); |
351 DCHECK_NE(socket_, INVALID_SOCKET); | 365 DCHECK_NE(socket_, INVALID_SOCKET); |
352 DCHECK_EQ(accept_event_, WSA_INVALID_EVENT); | 366 DCHECK_EQ(accept_event_, WSA_INVALID_EVENT); |
353 | 367 |
354 accept_event_ = WSACreateEvent(); | 368 accept_event_ = WSACreateEvent(); |
| 369 int os_error = WSAGetLastError(); |
355 if (accept_event_ == WSA_INVALID_EVENT) { | 370 if (accept_event_ == WSA_INVALID_EVENT) { |
356 PLOG(ERROR) << "WSACreateEvent()"; | 371 PLOG(ERROR) << "WSACreateEvent()"; |
357 return MapSystemError(WSAGetLastError()); | 372 return MapSystemError(os_error); |
358 } | 373 } |
359 | 374 |
360 int result = listen(socket_, backlog); | 375 int result = listen(socket_, backlog); |
| 376 os_error = WSAGetLastError(); |
361 if (result < 0) { | 377 if (result < 0) { |
362 PLOG(ERROR) << "listen() returned an error"; | 378 PLOG(ERROR) << "listen() returned an error"; |
363 return MapSystemError(WSAGetLastError()); | 379 return MapSystemError(os_error); |
364 } | 380 } |
365 | 381 |
366 return OK; | 382 return OK; |
367 } | 383 } |
368 | 384 |
369 int TCPSocketWin::Accept(std::unique_ptr<TCPSocketWin>* socket, | 385 int TCPSocketWin::Accept(std::unique_ptr<TCPSocketWin>* socket, |
370 IPEndPoint* address, | 386 IPEndPoint* address, |
371 const CompletionCallback& callback) { | 387 const CompletionCallback& callback) { |
372 DCHECK(CalledOnValidThread()); | 388 DCHECK(CalledOnValidThread()); |
373 DCHECK(socket); | 389 DCHECK(socket); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 | 447 |
432 if (socket_ == INVALID_SOCKET || waiting_connect_) | 448 if (socket_ == INVALID_SOCKET || waiting_connect_) |
433 return false; | 449 return false; |
434 | 450 |
435 if (waiting_read_) | 451 if (waiting_read_) |
436 return true; | 452 return true; |
437 | 453 |
438 // Check if connection is alive. | 454 // Check if connection is alive. |
439 char c; | 455 char c; |
440 int rv = recv(socket_, &c, 1, MSG_PEEK); | 456 int rv = recv(socket_, &c, 1, MSG_PEEK); |
| 457 int os_error = WSAGetLastError(); |
441 if (rv == 0) | 458 if (rv == 0) |
442 return false; | 459 return false; |
443 if (rv == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) | 460 if (rv == SOCKET_ERROR && os_error != WSAEWOULDBLOCK) |
444 return false; | 461 return false; |
445 | 462 |
446 return true; | 463 return true; |
447 } | 464 } |
448 | 465 |
449 bool TCPSocketWin::IsConnectedAndIdle() const { | 466 bool TCPSocketWin::IsConnectedAndIdle() const { |
450 DCHECK(CalledOnValidThread()); | 467 DCHECK(CalledOnValidThread()); |
451 | 468 |
452 if (socket_ == INVALID_SOCKET || waiting_connect_) | 469 if (socket_ == INVALID_SOCKET || waiting_connect_) |
453 return false; | 470 return false; |
454 | 471 |
455 if (waiting_read_) | 472 if (waiting_read_) |
456 return true; | 473 return true; |
457 | 474 |
458 // Check if connection is alive and we haven't received any data | 475 // Check if connection is alive and we haven't received any data |
459 // unexpectedly. | 476 // unexpectedly. |
460 char c; | 477 char c; |
461 int rv = recv(socket_, &c, 1, MSG_PEEK); | 478 int rv = recv(socket_, &c, 1, MSG_PEEK); |
| 479 int os_error = WSAGetLastError(); |
462 if (rv >= 0) | 480 if (rv >= 0) |
463 return false; | 481 return false; |
464 if (WSAGetLastError() != WSAEWOULDBLOCK) | 482 if (os_error != WSAEWOULDBLOCK) |
465 return false; | 483 return false; |
466 | 484 |
467 return true; | 485 return true; |
468 } | 486 } |
469 | 487 |
470 int TCPSocketWin::Read(IOBuffer* buf, | 488 int TCPSocketWin::Read(IOBuffer* buf, |
471 int buf_len, | 489 int buf_len, |
472 const CompletionCallback& callback) { | 490 const CompletionCallback& callback) { |
473 DCHECK(CalledOnValidThread()); | 491 DCHECK(CalledOnValidThread()); |
474 DCHECK_NE(socket_, INVALID_SOCKET); | 492 DCHECK_NE(socket_, INVALID_SOCKET); |
(...skipping 16 matching lines...) Expand all Loading... |
491 | 509 |
492 WSABUF write_buffer; | 510 WSABUF write_buffer; |
493 write_buffer.len = buf_len; | 511 write_buffer.len = buf_len; |
494 write_buffer.buf = buf->data(); | 512 write_buffer.buf = buf->data(); |
495 | 513 |
496 // TODO(wtc): Remove the assertion after enough testing. | 514 // TODO(wtc): Remove the assertion after enough testing. |
497 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 515 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
498 DWORD num; | 516 DWORD num; |
499 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, | 517 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, |
500 &core_->write_overlapped_, NULL); | 518 &core_->write_overlapped_, NULL); |
| 519 int os_error = WSAGetLastError(); |
501 if (rv == 0) { | 520 if (rv == 0) { |
502 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 521 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
503 rv = static_cast<int>(num); | 522 rv = static_cast<int>(num); |
504 if (rv > buf_len || rv < 0) { | 523 if (rv > buf_len || rv < 0) { |
505 // It seems that some winsock interceptors report that more was written | 524 // It seems that some winsock interceptors report that more was written |
506 // than was available. Treat this as an error. http://crbug.com/27870 | 525 // than was available. Treat this as an error. http://crbug.com/27870 |
507 LOG(ERROR) << "Detected broken LSP: Asked to write " << buf_len | 526 LOG(ERROR) << "Detected broken LSP: Asked to write " << buf_len |
508 << " bytes, but " << rv << " bytes reported."; | 527 << " bytes, but " << rv << " bytes reported."; |
509 return ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; | 528 return ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; |
510 } | 529 } |
511 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_SENT, rv, | 530 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_SENT, rv, |
512 buf->data()); | 531 buf->data()); |
513 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv); | 532 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv); |
514 return rv; | 533 return rv; |
515 } | 534 } |
516 } else { | 535 } else { |
517 int os_error = WSAGetLastError(); | |
518 if (os_error != WSA_IO_PENDING) { | 536 if (os_error != WSA_IO_PENDING) { |
519 int net_error = MapSystemError(os_error); | 537 int net_error = MapSystemError(os_error); |
520 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, | 538 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, |
521 CreateNetLogSocketErrorCallback(net_error, os_error)); | 539 CreateNetLogSocketErrorCallback(net_error, os_error)); |
522 return net_error; | 540 return net_error; |
523 } | 541 } |
524 } | 542 } |
525 waiting_write_ = true; | 543 waiting_write_ = true; |
526 write_callback_ = callback; | 544 write_callback_ = callback; |
527 core_->write_iobuffer_ = buf; | 545 core_->write_iobuffer_ = buf; |
528 core_->write_buffer_length_ = buf_len; | 546 core_->write_buffer_length_ = buf_len; |
529 core_->WatchForWrite(); | 547 core_->WatchForWrite(); |
530 return ERR_IO_PENDING; | 548 return ERR_IO_PENDING; |
531 } | 549 } |
532 | 550 |
533 int TCPSocketWin::GetLocalAddress(IPEndPoint* address) const { | 551 int TCPSocketWin::GetLocalAddress(IPEndPoint* address) const { |
534 DCHECK(CalledOnValidThread()); | 552 DCHECK(CalledOnValidThread()); |
535 DCHECK(address); | 553 DCHECK(address); |
536 | 554 |
537 SockaddrStorage storage; | 555 SockaddrStorage storage; |
538 if (getsockname(socket_, storage.addr, &storage.addr_len)) | 556 if (getsockname(socket_, storage.addr, &storage.addr_len)) { |
539 return MapSystemError(WSAGetLastError()); | 557 int os_error = WSAGetLastError(); |
| 558 return MapSystemError(os_error); |
| 559 } |
540 if (!address->FromSockAddr(storage.addr, storage.addr_len)) | 560 if (!address->FromSockAddr(storage.addr, storage.addr_len)) |
541 return ERR_ADDRESS_INVALID; | 561 return ERR_ADDRESS_INVALID; |
542 | 562 |
543 return OK; | 563 return OK; |
544 } | 564 } |
545 | 565 |
546 int TCPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 566 int TCPSocketWin::GetPeerAddress(IPEndPoint* address) const { |
547 DCHECK(CalledOnValidThread()); | 567 DCHECK(CalledOnValidThread()); |
548 DCHECK(address); | 568 DCHECK(address); |
549 if (!IsConnected()) | 569 if (!IsConnected()) |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 logging_multiple_connect_attempts_ = false; | 702 logging_multiple_connect_attempts_ = false; |
683 } else { | 703 } else { |
684 NOTREACHED(); | 704 NOTREACHED(); |
685 } | 705 } |
686 } | 706 } |
687 | 707 |
688 int TCPSocketWin::AcceptInternal(std::unique_ptr<TCPSocketWin>* socket, | 708 int TCPSocketWin::AcceptInternal(std::unique_ptr<TCPSocketWin>* socket, |
689 IPEndPoint* address) { | 709 IPEndPoint* address) { |
690 SockaddrStorage storage; | 710 SockaddrStorage storage; |
691 int new_socket = accept(socket_, storage.addr, &storage.addr_len); | 711 int new_socket = accept(socket_, storage.addr, &storage.addr_len); |
| 712 int os_error = WSAGetLastError(); |
692 if (new_socket < 0) { | 713 if (new_socket < 0) { |
693 int net_error = MapSystemError(WSAGetLastError()); | 714 int net_error = MapSystemError(os_error); |
694 if (net_error != ERR_IO_PENDING) | 715 if (net_error != ERR_IO_PENDING) |
695 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_ACCEPT, net_error); | 716 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_ACCEPT, net_error); |
696 return net_error; | 717 return net_error; |
697 } | 718 } |
698 | 719 |
699 IPEndPoint ip_end_point; | 720 IPEndPoint ip_end_point; |
700 if (!ip_end_point.FromSockAddr(storage.addr, storage.addr_len)) { | 721 if (!ip_end_point.FromSockAddr(storage.addr, storage.addr_len)) { |
701 NOTREACHED(); | 722 NOTREACHED(); |
702 if (closesocket(new_socket) < 0) | 723 if (closesocket(new_socket) < 0) |
703 PLOG(ERROR) << "closesocket"; | 724 PLOG(ERROR) << "closesocket"; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 | 777 |
757 // WSAEventSelect sets the socket to non-blocking mode as a side effect. | 778 // WSAEventSelect sets the socket to non-blocking mode as a side effect. |
758 // Our connect() and recv() calls require that the socket be non-blocking. | 779 // Our connect() and recv() calls require that the socket be non-blocking. |
759 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); | 780 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); |
760 | 781 |
761 SockaddrStorage storage; | 782 SockaddrStorage storage; |
762 if (!peer_address_->ToSockAddr(storage.addr, &storage.addr_len)) | 783 if (!peer_address_->ToSockAddr(storage.addr, &storage.addr_len)) |
763 return ERR_ADDRESS_INVALID; | 784 return ERR_ADDRESS_INVALID; |
764 | 785 |
765 int result; | 786 int result; |
| 787 int os_error; |
766 { | 788 { |
767 // TODO(ricea): Remove ScopedTracker below once crbug.com/436634 is fixed. | 789 // TODO(ricea): Remove ScopedTracker below once crbug.com/436634 is fixed. |
768 tracked_objects::ScopedTracker tracking_profile( | 790 tracked_objects::ScopedTracker tracking_profile( |
769 FROM_HERE_WITH_EXPLICIT_FUNCTION("436634 connect()")); | 791 FROM_HERE_WITH_EXPLICIT_FUNCTION("436634 connect()")); |
770 result = connect(socket_, storage.addr, storage.addr_len); | 792 result = connect(socket_, storage.addr, storage.addr_len); |
| 793 os_error = WSAGetLastError(); |
771 } | 794 } |
772 | 795 |
773 if (!result) { | 796 if (!result) { |
774 // Connected without waiting! | 797 // Connected without waiting! |
775 // | 798 // |
776 // The MSDN page for connect says: | 799 // The MSDN page for connect says: |
777 // With a nonblocking socket, the connection attempt cannot be completed | 800 // With a nonblocking socket, the connection attempt cannot be completed |
778 // immediately. In this case, connect will return SOCKET_ERROR, and | 801 // immediately. In this case, connect will return SOCKET_ERROR, and |
779 // WSAGetLastError will return WSAEWOULDBLOCK. | 802 // WSAGetLastError will return WSAEWOULDBLOCK. |
780 // which implies that for a nonblocking socket, connect never returns 0. | 803 // which implies that for a nonblocking socket, connect never returns 0. |
781 // It's not documented whether the event object will be signaled or not | 804 // It's not documented whether the event object will be signaled or not |
782 // if connect does return 0. So the code below is essentially dead code | 805 // if connect does return 0. So the code below is essentially dead code |
783 // and we don't know if it's correct. | 806 // and we don't know if it's correct. |
784 NOTREACHED(); | 807 NOTREACHED(); |
785 | 808 |
786 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) | 809 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) |
787 return OK; | 810 return OK; |
788 } else { | 811 } else { |
789 int os_error = WSAGetLastError(); | |
790 if (os_error != WSAEWOULDBLOCK) { | 812 if (os_error != WSAEWOULDBLOCK) { |
791 LOG(ERROR) << "connect failed: " << os_error; | 813 LOG(ERROR) << "connect failed: " << os_error; |
792 connect_os_error_ = os_error; | 814 connect_os_error_ = os_error; |
793 int rv = MapConnectError(os_error); | 815 int rv = MapConnectError(os_error); |
794 CHECK_NE(ERR_IO_PENDING, rv); | 816 CHECK_NE(ERR_IO_PENDING, rv); |
795 return rv; | 817 return rv; |
796 } | 818 } |
797 } | 819 } |
798 | 820 |
799 // TODO(ricea): Remove ScopedTracker below once crbug.com/436634 is fixed. | 821 // TODO(ricea): Remove ScopedTracker below once crbug.com/436634 is fixed. |
(...skipping 27 matching lines...) Expand all Loading... |
827 void TCPSocketWin::LogConnectEnd(int net_error) { | 849 void TCPSocketWin::LogConnectEnd(int net_error) { |
828 if (net_error != OK) { | 850 if (net_error != OK) { |
829 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, net_error); | 851 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, net_error); |
830 return; | 852 return; |
831 } | 853 } |
832 | 854 |
833 struct sockaddr_storage source_address; | 855 struct sockaddr_storage source_address; |
834 socklen_t addrlen = sizeof(source_address); | 856 socklen_t addrlen = sizeof(source_address); |
835 int rv = getsockname( | 857 int rv = getsockname( |
836 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); | 858 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); |
| 859 int os_error = WSAGetLastError(); |
837 if (rv != 0) { | 860 if (rv != 0) { |
838 LOG(ERROR) << "getsockname() [rv: " << rv | 861 LOG(ERROR) << "getsockname() [rv: " << rv << "] error: " << os_error; |
839 << "] error: " << WSAGetLastError(); | |
840 NOTREACHED(); | 862 NOTREACHED(); |
841 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, rv); | 863 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, rv); |
842 return; | 864 return; |
843 } | 865 } |
844 | 866 |
845 net_log_.EndEvent( | 867 net_log_.EndEvent( |
846 NetLogEventType::TCP_CONNECT, | 868 NetLogEventType::TCP_CONNECT, |
847 CreateNetLogSourceAddressCallback( | 869 CreateNetLogSourceAddressCallback( |
848 reinterpret_cast<const struct sockaddr*>(&source_address), | 870 reinterpret_cast<const struct sockaddr*>(&source_address), |
849 sizeof(source_address))); | 871 sizeof(source_address))); |
850 } | 872 } |
851 | 873 |
852 int TCPSocketWin::DoRead(IOBuffer* buf, int buf_len, | 874 int TCPSocketWin::DoRead(IOBuffer* buf, int buf_len, |
853 const CompletionCallback& callback) { | 875 const CompletionCallback& callback) { |
854 if (!core_->non_blocking_reads_initialized_) { | 876 if (!core_->non_blocking_reads_initialized_) { |
855 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, | 877 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, |
856 FD_READ | FD_CLOSE); | 878 FD_READ | FD_CLOSE); |
857 core_->non_blocking_reads_initialized_ = true; | 879 core_->non_blocking_reads_initialized_ = true; |
858 } | 880 } |
859 int rv = recv(socket_, buf->data(), buf_len, 0); | 881 int rv = recv(socket_, buf->data(), buf_len, 0); |
| 882 int os_error = WSAGetLastError(); |
860 if (rv == SOCKET_ERROR) { | 883 if (rv == SOCKET_ERROR) { |
861 int os_error = WSAGetLastError(); | |
862 if (os_error != WSAEWOULDBLOCK) { | 884 if (os_error != WSAEWOULDBLOCK) { |
863 int net_error = MapSystemError(os_error); | 885 int net_error = MapSystemError(os_error); |
864 net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR, | 886 net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR, |
865 CreateNetLogSocketErrorCallback(net_error, os_error)); | 887 CreateNetLogSocketErrorCallback(net_error, os_error)); |
866 return net_error; | 888 return net_error; |
867 } | 889 } |
868 } else { | 890 } else { |
869 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_RECEIVED, rv, | 891 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_RECEIVED, rv, |
870 buf->data()); | 892 buf->data()); |
871 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | 893 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); |
872 return rv; | 894 return rv; |
873 } | 895 } |
874 | 896 |
875 waiting_read_ = true; | 897 waiting_read_ = true; |
876 read_callback_ = callback; | 898 read_callback_ = callback; |
877 core_->read_iobuffer_ = buf; | 899 core_->read_iobuffer_ = buf; |
878 core_->read_buffer_length_ = buf_len; | 900 core_->read_buffer_length_ = buf_len; |
879 core_->WatchForRead(); | 901 core_->WatchForRead(); |
880 return ERR_IO_PENDING; | 902 return ERR_IO_PENDING; |
881 } | 903 } |
882 | 904 |
883 void TCPSocketWin::DidCompleteConnect() { | 905 void TCPSocketWin::DidCompleteConnect() { |
884 DCHECK(waiting_connect_); | 906 DCHECK(waiting_connect_); |
885 DCHECK(!read_callback_.is_null()); | 907 DCHECK(!read_callback_.is_null()); |
886 int result; | 908 int result; |
887 | 909 |
888 WSANETWORKEVENTS events; | 910 WSANETWORKEVENTS events; |
889 int rv; | 911 int rv; |
| 912 int os_error = 0; |
890 { | 913 { |
891 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462784 is | 914 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462784 is |
892 // fixed. | 915 // fixed. |
893 tracked_objects::ScopedTracker tracking_profile1( | 916 tracked_objects::ScopedTracker tracking_profile1( |
894 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 917 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
895 "462784 TCPSocketWin::DidCompleteConnect -> WSAEnumNetworkEvents")); | 918 "462784 TCPSocketWin::DidCompleteConnect -> WSAEnumNetworkEvents")); |
896 rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, &events); | 919 rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, &events); |
| 920 os_error = WSAGetLastError(); |
897 } | 921 } |
898 int os_error = 0; | |
899 if (rv == SOCKET_ERROR) { | 922 if (rv == SOCKET_ERROR) { |
900 NOTREACHED(); | 923 NOTREACHED(); |
901 os_error = WSAGetLastError(); | |
902 result = MapSystemError(os_error); | 924 result = MapSystemError(os_error); |
903 } else if (events.lNetworkEvents & FD_CONNECT) { | 925 } else if (events.lNetworkEvents & FD_CONNECT) { |
904 os_error = events.iErrorCode[FD_CONNECT_BIT]; | 926 os_error = events.iErrorCode[FD_CONNECT_BIT]; |
905 result = MapConnectError(os_error); | 927 result = MapConnectError(os_error); |
906 } else { | 928 } else { |
907 NOTREACHED(); | 929 NOTREACHED(); |
908 result = ERR_UNEXPECTED; | 930 result = ERR_UNEXPECTED; |
909 } | 931 } |
910 | 932 |
911 connect_os_error_ = os_error; | 933 connect_os_error_ = os_error; |
912 DoConnectComplete(result); | 934 DoConnectComplete(result); |
913 waiting_connect_ = false; | 935 waiting_connect_ = false; |
914 | 936 |
915 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462784 is fixed. | 937 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462784 is fixed. |
916 tracked_objects::ScopedTracker tracking_profile4( | 938 tracked_objects::ScopedTracker tracking_profile4( |
917 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 939 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
918 "462784 TCPSocketWin::DidCompleteConnect -> read_callback_")); | 940 "462784 TCPSocketWin::DidCompleteConnect -> read_callback_")); |
919 DCHECK_NE(result, ERR_IO_PENDING); | 941 DCHECK_NE(result, ERR_IO_PENDING); |
920 base::ResetAndReturn(&read_callback_).Run(result); | 942 base::ResetAndReturn(&read_callback_).Run(result); |
921 } | 943 } |
922 | 944 |
923 void TCPSocketWin::DidCompleteWrite() { | 945 void TCPSocketWin::DidCompleteWrite() { |
924 DCHECK(waiting_write_); | 946 DCHECK(waiting_write_); |
925 DCHECK(!write_callback_.is_null()); | 947 DCHECK(!write_callback_.is_null()); |
926 | 948 |
927 DWORD num_bytes, flags; | 949 DWORD num_bytes, flags; |
928 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 950 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
929 &num_bytes, FALSE, &flags); | 951 &num_bytes, FALSE, &flags); |
| 952 int os_error = WSAGetLastError(); |
930 WSAResetEvent(core_->write_overlapped_.hEvent); | 953 WSAResetEvent(core_->write_overlapped_.hEvent); |
931 waiting_write_ = false; | 954 waiting_write_ = false; |
932 int rv; | 955 int rv; |
933 if (!ok) { | 956 if (!ok) { |
934 int os_error = WSAGetLastError(); | |
935 rv = MapSystemError(os_error); | 957 rv = MapSystemError(os_error); |
936 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, | 958 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, |
937 CreateNetLogSocketErrorCallback(rv, os_error)); | 959 CreateNetLogSocketErrorCallback(rv, os_error)); |
938 } else { | 960 } else { |
939 rv = static_cast<int>(num_bytes); | 961 rv = static_cast<int>(num_bytes); |
940 if (rv > core_->write_buffer_length_ || rv < 0) { | 962 if (rv > core_->write_buffer_length_ || rv < 0) { |
941 // It seems that some winsock interceptors report that more was written | 963 // It seems that some winsock interceptors report that more was written |
942 // than was available. Treat this as an error. http://crbug.com/27870 | 964 // than was available. Treat this as an error. http://crbug.com/27870 |
943 LOG(ERROR) << "Detected broken LSP: Asked to write " | 965 LOG(ERROR) << "Detected broken LSP: Asked to write " |
944 << core_->write_buffer_length_ << " bytes, but " << rv | 966 << core_->write_buffer_length_ << " bytes, but " << rv |
(...skipping 13 matching lines...) Expand all Loading... |
958 } | 980 } |
959 | 981 |
960 void TCPSocketWin::DidSignalRead() { | 982 void TCPSocketWin::DidSignalRead() { |
961 DCHECK(waiting_read_); | 983 DCHECK(waiting_read_); |
962 DCHECK(!read_callback_.is_null()); | 984 DCHECK(!read_callback_.is_null()); |
963 | 985 |
964 int os_error = 0; | 986 int os_error = 0; |
965 WSANETWORKEVENTS network_events; | 987 WSANETWORKEVENTS network_events; |
966 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | 988 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, |
967 &network_events); | 989 &network_events); |
| 990 os_error = WSAGetLastError(); |
| 991 |
968 if (rv == SOCKET_ERROR) { | 992 if (rv == SOCKET_ERROR) { |
969 os_error = WSAGetLastError(); | |
970 rv = MapSystemError(os_error); | 993 rv = MapSystemError(os_error); |
971 } else if (network_events.lNetworkEvents) { | 994 } else if (network_events.lNetworkEvents) { |
972 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462778 is | 995 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462778 is |
973 // fixed. | 996 // fixed. |
974 tracked_objects::ScopedTracker tracking_profile2( | 997 tracked_objects::ScopedTracker tracking_profile2( |
975 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 998 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
976 "462778 TCPSocketWin::DidSignalRead -> DoRead")); | 999 "462778 TCPSocketWin::DidSignalRead -> DoRead")); |
977 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); | 1000 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); |
978 // If network_events.lNetworkEvents is FD_CLOSE and | 1001 // If network_events.lNetworkEvents is FD_CLOSE and |
979 // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful | 1002 // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful |
(...skipping 29 matching lines...) Expand all Loading... |
1009 } | 1032 } |
1010 | 1033 |
1011 bool TCPSocketWin::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const { | 1034 bool TCPSocketWin::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const { |
1012 DCHECK(out_rtt); | 1035 DCHECK(out_rtt); |
1013 // TODO(bmcquade): Consider implementing using | 1036 // TODO(bmcquade): Consider implementing using |
1014 // GetPerTcpConnectionEStats/GetPerTcp6ConnectionEStats. | 1037 // GetPerTcpConnectionEStats/GetPerTcp6ConnectionEStats. |
1015 return false; | 1038 return false; |
1016 } | 1039 } |
1017 | 1040 |
1018 } // namespace net | 1041 } // namespace net |
OLD | NEW |