Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: net/socket/tcp_socket_win.cc

Issue 2539833003: Call WSAGetLastError immediately after the potentially failing call. (Closed)
Patch Set: No global namespace ::WSAGetLastError for consistency with rest of file. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698