| 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 |