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(); |
eroman
2016/11/29 19:51:00
For these two cases, does the re-ordering make a d
Sigurður Ásgeirsson
2016/11/29 20:27:55
This is purely for consistency. Note that C++ can
| |
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: |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 Close(); | 272 Close(); |
270 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); | 273 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); |
271 } | 274 } |
272 | 275 |
273 int TCPSocketWin::Open(AddressFamily family) { | 276 int TCPSocketWin::Open(AddressFamily family) { |
274 DCHECK(CalledOnValidThread()); | 277 DCHECK(CalledOnValidThread()); |
275 DCHECK_EQ(socket_, INVALID_SOCKET); | 278 DCHECK_EQ(socket_, INVALID_SOCKET); |
276 | 279 |
277 socket_ = CreatePlatformSocket(ConvertAddressFamily(family), SOCK_STREAM, | 280 socket_ = CreatePlatformSocket(ConvertAddressFamily(family), SOCK_STREAM, |
278 IPPROTO_TCP); | 281 IPPROTO_TCP); |
282 int os_error = WSAGetLastError(); | |
eroman
2016/11/29 19:51:00
Same issue as for base::SetNonBlocking() -- relies
Sigurður Ásgeirsson
2016/11/29 20:27:55
I don't know whether this works the same on other
| |
279 if (socket_ == INVALID_SOCKET) { | 283 if (socket_ == INVALID_SOCKET) { |
280 PLOG(ERROR) << "CreatePlatformSocket() returned an error"; | 284 PLOG(ERROR) << "CreatePlatformSocket() returned an error"; |
281 return MapSystemError(WSAGetLastError()); | 285 return MapSystemError(os_error); |
282 } | 286 } |
283 | 287 |
284 if (!base::SetNonBlocking(socket_)) { | 288 if (!base::SetNonBlocking(socket_)) { |
285 int result = MapSystemError(WSAGetLastError()); | 289 os_error = WSAGetLastError(); |
290 int result = MapSystemError(os_error); | |
286 Close(); | 291 Close(); |
287 return result; | 292 return result; |
288 } | 293 } |
289 | 294 |
290 return OK; | 295 return OK; |
291 } | 296 } |
292 | 297 |
293 int TCPSocketWin::AdoptConnectedSocket(SOCKET socket, | 298 int TCPSocketWin::AdoptConnectedSocket(SOCKET socket, |
294 const IPEndPoint& peer_address) { | 299 const IPEndPoint& peer_address) { |
295 DCHECK(CalledOnValidThread()); | 300 DCHECK(CalledOnValidThread()); |
296 DCHECK_EQ(socket_, INVALID_SOCKET); | 301 DCHECK_EQ(socket_, INVALID_SOCKET); |
297 DCHECK(!core_.get()); | 302 DCHECK(!core_.get()); |
298 | 303 |
299 socket_ = socket; | 304 socket_ = socket; |
300 | 305 |
301 if (!base::SetNonBlocking(socket_)) { | 306 if (!base::SetNonBlocking(socket_)) { |
302 int result = MapSystemError(WSAGetLastError()); | 307 int os_error = WSAGetLastError(); |
eroman
2016/11/29 19:51:00
Given this is called 3 times, I would suggest addi
Sigurður Ásgeirsson
2016/11/29 20:27:55
Done.
| |
308 int result = MapSystemError(os_error); | |
303 Close(); | 309 Close(); |
304 return result; | 310 return result; |
305 } | 311 } |
306 | 312 |
307 core_ = new Core(this); | 313 core_ = new Core(this); |
308 peer_address_.reset(new IPEndPoint(peer_address)); | 314 peer_address_.reset(new IPEndPoint(peer_address)); |
309 | 315 |
310 return OK; | 316 return OK; |
311 } | 317 } |
312 | 318 |
313 int TCPSocketWin::AdoptListenSocket(SOCKET socket) { | 319 int TCPSocketWin::AdoptListenSocket(SOCKET socket) { |
314 DCHECK(CalledOnValidThread()); | 320 DCHECK(CalledOnValidThread()); |
315 DCHECK_EQ(socket_, INVALID_SOCKET); | 321 DCHECK_EQ(socket_, INVALID_SOCKET); |
316 | 322 |
317 socket_ = socket; | 323 socket_ = socket; |
318 | 324 |
319 if (!base::SetNonBlocking(socket_)) { | 325 if (!base::SetNonBlocking(socket_)) { |
320 int result = MapSystemError(WSAGetLastError()); | 326 int os_error = WSAGetLastError(); |
327 int result = MapSystemError(os_error); | |
321 Close(); | 328 Close(); |
322 return result; | 329 return result; |
323 } | 330 } |
324 | 331 |
325 // |core_| is not needed for sockets that are used to accept connections. | 332 // |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. | 333 // The operation here is more like Open but with an existing socket. |
327 | 334 |
328 return OK; | 335 return OK; |
329 } | 336 } |
330 | 337 |
331 int TCPSocketWin::Bind(const IPEndPoint& address) { | 338 int TCPSocketWin::Bind(const IPEndPoint& address) { |
332 DCHECK(CalledOnValidThread()); | 339 DCHECK(CalledOnValidThread()); |
333 DCHECK_NE(socket_, INVALID_SOCKET); | 340 DCHECK_NE(socket_, INVALID_SOCKET); |
334 | 341 |
335 SockaddrStorage storage; | 342 SockaddrStorage storage; |
336 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) | 343 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
337 return ERR_ADDRESS_INVALID; | 344 return ERR_ADDRESS_INVALID; |
338 | 345 |
339 int result = bind(socket_, storage.addr, storage.addr_len); | 346 int result = bind(socket_, storage.addr, storage.addr_len); |
347 int os_error = WSAGetLastError(); | |
340 if (result < 0) { | 348 if (result < 0) { |
341 PLOG(ERROR) << "bind() returned an error"; | 349 PLOG(ERROR) << "bind() returned an error"; |
342 return MapSystemError(WSAGetLastError()); | 350 return MapSystemError(os_error); |
343 } | 351 } |
344 | 352 |
345 return OK; | 353 return OK; |
346 } | 354 } |
347 | 355 |
348 int TCPSocketWin::Listen(int backlog) { | 356 int TCPSocketWin::Listen(int backlog) { |
349 DCHECK(CalledOnValidThread()); | 357 DCHECK(CalledOnValidThread()); |
350 DCHECK_GT(backlog, 0); | 358 DCHECK_GT(backlog, 0); |
351 DCHECK_NE(socket_, INVALID_SOCKET); | 359 DCHECK_NE(socket_, INVALID_SOCKET); |
352 DCHECK_EQ(accept_event_, WSA_INVALID_EVENT); | 360 DCHECK_EQ(accept_event_, WSA_INVALID_EVENT); |
353 | 361 |
354 accept_event_ = WSACreateEvent(); | 362 accept_event_ = WSACreateEvent(); |
363 int os_error = WSAGetLastError(); | |
355 if (accept_event_ == WSA_INVALID_EVENT) { | 364 if (accept_event_ == WSA_INVALID_EVENT) { |
356 PLOG(ERROR) << "WSACreateEvent()"; | 365 PLOG(ERROR) << "WSACreateEvent()"; |
357 return MapSystemError(WSAGetLastError()); | 366 return MapSystemError(os_error); |
358 } | 367 } |
359 | 368 |
360 int result = listen(socket_, backlog); | 369 int result = listen(socket_, backlog); |
370 os_error = WSAGetLastError(); | |
361 if (result < 0) { | 371 if (result < 0) { |
362 PLOG(ERROR) << "listen() returned an error"; | 372 PLOG(ERROR) << "listen() returned an error"; |
363 return MapSystemError(WSAGetLastError()); | 373 return MapSystemError(os_error); |
364 } | 374 } |
365 | 375 |
366 return OK; | 376 return OK; |
367 } | 377 } |
368 | 378 |
369 int TCPSocketWin::Accept(std::unique_ptr<TCPSocketWin>* socket, | 379 int TCPSocketWin::Accept(std::unique_ptr<TCPSocketWin>* socket, |
370 IPEndPoint* address, | 380 IPEndPoint* address, |
371 const CompletionCallback& callback) { | 381 const CompletionCallback& callback) { |
372 DCHECK(CalledOnValidThread()); | 382 DCHECK(CalledOnValidThread()); |
373 DCHECK(socket); | 383 DCHECK(socket); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 | 441 |
432 if (socket_ == INVALID_SOCKET || waiting_connect_) | 442 if (socket_ == INVALID_SOCKET || waiting_connect_) |
433 return false; | 443 return false; |
434 | 444 |
435 if (waiting_read_) | 445 if (waiting_read_) |
436 return true; | 446 return true; |
437 | 447 |
438 // Check if connection is alive. | 448 // Check if connection is alive. |
439 char c; | 449 char c; |
440 int rv = recv(socket_, &c, 1, MSG_PEEK); | 450 int rv = recv(socket_, &c, 1, MSG_PEEK); |
451 int os_error = WSAGetLastError(); | |
441 if (rv == 0) | 452 if (rv == 0) |
442 return false; | 453 return false; |
443 if (rv == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) | 454 if (rv == SOCKET_ERROR && os_error != WSAEWOULDBLOCK) |
444 return false; | 455 return false; |
445 | 456 |
446 return true; | 457 return true; |
447 } | 458 } |
448 | 459 |
449 bool TCPSocketWin::IsConnectedAndIdle() const { | 460 bool TCPSocketWin::IsConnectedAndIdle() const { |
450 DCHECK(CalledOnValidThread()); | 461 DCHECK(CalledOnValidThread()); |
451 | 462 |
452 if (socket_ == INVALID_SOCKET || waiting_connect_) | 463 if (socket_ == INVALID_SOCKET || waiting_connect_) |
453 return false; | 464 return false; |
454 | 465 |
455 if (waiting_read_) | 466 if (waiting_read_) |
456 return true; | 467 return true; |
457 | 468 |
458 // Check if connection is alive and we haven't received any data | 469 // Check if connection is alive and we haven't received any data |
459 // unexpectedly. | 470 // unexpectedly. |
460 char c; | 471 char c; |
461 int rv = recv(socket_, &c, 1, MSG_PEEK); | 472 int rv = recv(socket_, &c, 1, MSG_PEEK); |
473 int os_error = WSAGetLastError(); | |
462 if (rv >= 0) | 474 if (rv >= 0) |
463 return false; | 475 return false; |
464 if (WSAGetLastError() != WSAEWOULDBLOCK) | 476 if (os_error != WSAEWOULDBLOCK) |
465 return false; | 477 return false; |
466 | 478 |
467 return true; | 479 return true; |
468 } | 480 } |
469 | 481 |
470 int TCPSocketWin::Read(IOBuffer* buf, | 482 int TCPSocketWin::Read(IOBuffer* buf, |
471 int buf_len, | 483 int buf_len, |
472 const CompletionCallback& callback) { | 484 const CompletionCallback& callback) { |
473 DCHECK(CalledOnValidThread()); | 485 DCHECK(CalledOnValidThread()); |
474 DCHECK_NE(socket_, INVALID_SOCKET); | 486 DCHECK_NE(socket_, INVALID_SOCKET); |
(...skipping 16 matching lines...) Expand all Loading... | |
491 | 503 |
492 WSABUF write_buffer; | 504 WSABUF write_buffer; |
493 write_buffer.len = buf_len; | 505 write_buffer.len = buf_len; |
494 write_buffer.buf = buf->data(); | 506 write_buffer.buf = buf->data(); |
495 | 507 |
496 // TODO(wtc): Remove the assertion after enough testing. | 508 // TODO(wtc): Remove the assertion after enough testing. |
497 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 509 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
498 DWORD num; | 510 DWORD num; |
499 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, | 511 int rv = WSASend(socket_, &write_buffer, 1, &num, 0, |
500 &core_->write_overlapped_, NULL); | 512 &core_->write_overlapped_, NULL); |
513 int os_error = WSAGetLastError(); | |
501 if (rv == 0) { | 514 if (rv == 0) { |
502 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 515 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
503 rv = static_cast<int>(num); | 516 rv = static_cast<int>(num); |
504 if (rv > buf_len || rv < 0) { | 517 if (rv > buf_len || rv < 0) { |
505 // It seems that some winsock interceptors report that more was written | 518 // It seems that some winsock interceptors report that more was written |
506 // than was available. Treat this as an error. http://crbug.com/27870 | 519 // than was available. Treat this as an error. http://crbug.com/27870 |
507 LOG(ERROR) << "Detected broken LSP: Asked to write " << buf_len | 520 LOG(ERROR) << "Detected broken LSP: Asked to write " << buf_len |
508 << " bytes, but " << rv << " bytes reported."; | 521 << " bytes, but " << rv << " bytes reported."; |
509 return ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; | 522 return ERR_WINSOCK_UNEXPECTED_WRITTEN_BYTES; |
510 } | 523 } |
511 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_SENT, rv, | 524 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_SENT, rv, |
512 buf->data()); | 525 buf->data()); |
513 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv); | 526 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv); |
514 return rv; | 527 return rv; |
515 } | 528 } |
516 } else { | 529 } else { |
517 int os_error = WSAGetLastError(); | |
518 if (os_error != WSA_IO_PENDING) { | 530 if (os_error != WSA_IO_PENDING) { |
519 int net_error = MapSystemError(os_error); | 531 int net_error = MapSystemError(os_error); |
520 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, | 532 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, |
521 CreateNetLogSocketErrorCallback(net_error, os_error)); | 533 CreateNetLogSocketErrorCallback(net_error, os_error)); |
522 return net_error; | 534 return net_error; |
523 } | 535 } |
524 } | 536 } |
525 waiting_write_ = true; | 537 waiting_write_ = true; |
526 write_callback_ = callback; | 538 write_callback_ = callback; |
527 core_->write_iobuffer_ = buf; | 539 core_->write_iobuffer_ = buf; |
528 core_->write_buffer_length_ = buf_len; | 540 core_->write_buffer_length_ = buf_len; |
529 core_->WatchForWrite(); | 541 core_->WatchForWrite(); |
530 return ERR_IO_PENDING; | 542 return ERR_IO_PENDING; |
531 } | 543 } |
532 | 544 |
533 int TCPSocketWin::GetLocalAddress(IPEndPoint* address) const { | 545 int TCPSocketWin::GetLocalAddress(IPEndPoint* address) const { |
534 DCHECK(CalledOnValidThread()); | 546 DCHECK(CalledOnValidThread()); |
535 DCHECK(address); | 547 DCHECK(address); |
536 | 548 |
537 SockaddrStorage storage; | 549 SockaddrStorage storage; |
538 if (getsockname(socket_, storage.addr, &storage.addr_len)) | 550 if (getsockname(socket_, storage.addr, &storage.addr_len)) { |
539 return MapSystemError(WSAGetLastError()); | 551 int os_error = WSAGetLastError(); |
552 return MapSystemError(os_error); | |
553 } | |
540 if (!address->FromSockAddr(storage.addr, storage.addr_len)) | 554 if (!address->FromSockAddr(storage.addr, storage.addr_len)) |
541 return ERR_ADDRESS_INVALID; | 555 return ERR_ADDRESS_INVALID; |
542 | 556 |
543 return OK; | 557 return OK; |
544 } | 558 } |
545 | 559 |
546 int TCPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 560 int TCPSocketWin::GetPeerAddress(IPEndPoint* address) const { |
547 DCHECK(CalledOnValidThread()); | 561 DCHECK(CalledOnValidThread()); |
548 DCHECK(address); | 562 DCHECK(address); |
549 if (!IsConnected()) | 563 if (!IsConnected()) |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
682 logging_multiple_connect_attempts_ = false; | 696 logging_multiple_connect_attempts_ = false; |
683 } else { | 697 } else { |
684 NOTREACHED(); | 698 NOTREACHED(); |
685 } | 699 } |
686 } | 700 } |
687 | 701 |
688 int TCPSocketWin::AcceptInternal(std::unique_ptr<TCPSocketWin>* socket, | 702 int TCPSocketWin::AcceptInternal(std::unique_ptr<TCPSocketWin>* socket, |
689 IPEndPoint* address) { | 703 IPEndPoint* address) { |
690 SockaddrStorage storage; | 704 SockaddrStorage storage; |
691 int new_socket = accept(socket_, storage.addr, &storage.addr_len); | 705 int new_socket = accept(socket_, storage.addr, &storage.addr_len); |
706 int os_error = WSAGetLastError(); | |
692 if (new_socket < 0) { | 707 if (new_socket < 0) { |
693 int net_error = MapSystemError(WSAGetLastError()); | 708 int net_error = MapSystemError(os_error); |
694 if (net_error != ERR_IO_PENDING) | 709 if (net_error != ERR_IO_PENDING) |
695 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_ACCEPT, net_error); | 710 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_ACCEPT, net_error); |
696 return net_error; | 711 return net_error; |
697 } | 712 } |
698 | 713 |
699 IPEndPoint ip_end_point; | 714 IPEndPoint ip_end_point; |
700 if (!ip_end_point.FromSockAddr(storage.addr, storage.addr_len)) { | 715 if (!ip_end_point.FromSockAddr(storage.addr, storage.addr_len)) { |
701 NOTREACHED(); | 716 NOTREACHED(); |
702 if (closesocket(new_socket) < 0) | 717 if (closesocket(new_socket) < 0) |
703 PLOG(ERROR) << "closesocket"; | 718 PLOG(ERROR) << "closesocket"; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
756 | 771 |
757 // WSAEventSelect sets the socket to non-blocking mode as a side effect. | 772 // 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. | 773 // Our connect() and recv() calls require that the socket be non-blocking. |
759 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); | 774 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); |
760 | 775 |
761 SockaddrStorage storage; | 776 SockaddrStorage storage; |
762 if (!peer_address_->ToSockAddr(storage.addr, &storage.addr_len)) | 777 if (!peer_address_->ToSockAddr(storage.addr, &storage.addr_len)) |
763 return ERR_ADDRESS_INVALID; | 778 return ERR_ADDRESS_INVALID; |
764 | 779 |
765 int result; | 780 int result; |
781 int os_error; | |
766 { | 782 { |
767 // TODO(ricea): Remove ScopedTracker below once crbug.com/436634 is fixed. | 783 // TODO(ricea): Remove ScopedTracker below once crbug.com/436634 is fixed. |
768 tracked_objects::ScopedTracker tracking_profile( | 784 tracked_objects::ScopedTracker tracking_profile( |
769 FROM_HERE_WITH_EXPLICIT_FUNCTION("436634 connect()")); | 785 FROM_HERE_WITH_EXPLICIT_FUNCTION("436634 connect()")); |
770 result = connect(socket_, storage.addr, storage.addr_len); | 786 result = connect(socket_, storage.addr, storage.addr_len); |
787 os_error = WSAGetLastError(); | |
771 } | 788 } |
772 | 789 |
773 if (!result) { | 790 if (!result) { |
774 // Connected without waiting! | 791 // Connected without waiting! |
775 // | 792 // |
776 // The MSDN page for connect says: | 793 // The MSDN page for connect says: |
777 // With a nonblocking socket, the connection attempt cannot be completed | 794 // With a nonblocking socket, the connection attempt cannot be completed |
778 // immediately. In this case, connect will return SOCKET_ERROR, and | 795 // immediately. In this case, connect will return SOCKET_ERROR, and |
779 // WSAGetLastError will return WSAEWOULDBLOCK. | 796 // WSAGetLastError will return WSAEWOULDBLOCK. |
780 // which implies that for a nonblocking socket, connect never returns 0. | 797 // 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 | 798 // 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 | 799 // if connect does return 0. So the code below is essentially dead code |
783 // and we don't know if it's correct. | 800 // and we don't know if it's correct. |
784 NOTREACHED(); | 801 NOTREACHED(); |
785 | 802 |
786 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) | 803 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) |
787 return OK; | 804 return OK; |
788 } else { | 805 } else { |
789 int os_error = WSAGetLastError(); | |
790 if (os_error != WSAEWOULDBLOCK) { | 806 if (os_error != WSAEWOULDBLOCK) { |
791 LOG(ERROR) << "connect failed: " << os_error; | 807 LOG(ERROR) << "connect failed: " << os_error; |
792 connect_os_error_ = os_error; | 808 connect_os_error_ = os_error; |
793 int rv = MapConnectError(os_error); | 809 int rv = MapConnectError(os_error); |
794 CHECK_NE(ERR_IO_PENDING, rv); | 810 CHECK_NE(ERR_IO_PENDING, rv); |
795 return rv; | 811 return rv; |
796 } | 812 } |
797 } | 813 } |
798 | 814 |
799 // TODO(ricea): Remove ScopedTracker below once crbug.com/436634 is fixed. | 815 // 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) { | 843 void TCPSocketWin::LogConnectEnd(int net_error) { |
828 if (net_error != OK) { | 844 if (net_error != OK) { |
829 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, net_error); | 845 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, net_error); |
830 return; | 846 return; |
831 } | 847 } |
832 | 848 |
833 struct sockaddr_storage source_address; | 849 struct sockaddr_storage source_address; |
834 socklen_t addrlen = sizeof(source_address); | 850 socklen_t addrlen = sizeof(source_address); |
835 int rv = getsockname( | 851 int rv = getsockname( |
836 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); | 852 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); |
853 int os_error = WSAGetLastError(); | |
837 if (rv != 0) { | 854 if (rv != 0) { |
838 LOG(ERROR) << "getsockname() [rv: " << rv | 855 LOG(ERROR) << "getsockname() [rv: " << rv << "] error: " << os_error; |
839 << "] error: " << WSAGetLastError(); | |
840 NOTREACHED(); | 856 NOTREACHED(); |
841 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, rv); | 857 net_log_.EndEventWithNetErrorCode(NetLogEventType::TCP_CONNECT, rv); |
842 return; | 858 return; |
843 } | 859 } |
844 | 860 |
845 net_log_.EndEvent( | 861 net_log_.EndEvent( |
846 NetLogEventType::TCP_CONNECT, | 862 NetLogEventType::TCP_CONNECT, |
847 CreateNetLogSourceAddressCallback( | 863 CreateNetLogSourceAddressCallback( |
848 reinterpret_cast<const struct sockaddr*>(&source_address), | 864 reinterpret_cast<const struct sockaddr*>(&source_address), |
849 sizeof(source_address))); | 865 sizeof(source_address))); |
850 } | 866 } |
851 | 867 |
852 int TCPSocketWin::DoRead(IOBuffer* buf, int buf_len, | 868 int TCPSocketWin::DoRead(IOBuffer* buf, int buf_len, |
853 const CompletionCallback& callback) { | 869 const CompletionCallback& callback) { |
854 if (!core_->non_blocking_reads_initialized_) { | 870 if (!core_->non_blocking_reads_initialized_) { |
855 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, | 871 WSAEventSelect(socket_, core_->read_overlapped_.hEvent, |
856 FD_READ | FD_CLOSE); | 872 FD_READ | FD_CLOSE); |
857 core_->non_blocking_reads_initialized_ = true; | 873 core_->non_blocking_reads_initialized_ = true; |
858 } | 874 } |
859 int rv = recv(socket_, buf->data(), buf_len, 0); | 875 int rv = recv(socket_, buf->data(), buf_len, 0); |
876 int os_error = WSAGetLastError(); | |
860 if (rv == SOCKET_ERROR) { | 877 if (rv == SOCKET_ERROR) { |
861 int os_error = WSAGetLastError(); | |
862 if (os_error != WSAEWOULDBLOCK) { | 878 if (os_error != WSAEWOULDBLOCK) { |
863 int net_error = MapSystemError(os_error); | 879 int net_error = MapSystemError(os_error); |
864 net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR, | 880 net_log_.AddEvent(NetLogEventType::SOCKET_READ_ERROR, |
865 CreateNetLogSocketErrorCallback(net_error, os_error)); | 881 CreateNetLogSocketErrorCallback(net_error, os_error)); |
866 return net_error; | 882 return net_error; |
867 } | 883 } |
868 } else { | 884 } else { |
869 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_RECEIVED, rv, | 885 net_log_.AddByteTransferEvent(NetLogEventType::SOCKET_BYTES_RECEIVED, rv, |
870 buf->data()); | 886 buf->data()); |
871 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); | 887 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv); |
872 return rv; | 888 return rv; |
873 } | 889 } |
874 | 890 |
875 waiting_read_ = true; | 891 waiting_read_ = true; |
876 read_callback_ = callback; | 892 read_callback_ = callback; |
877 core_->read_iobuffer_ = buf; | 893 core_->read_iobuffer_ = buf; |
878 core_->read_buffer_length_ = buf_len; | 894 core_->read_buffer_length_ = buf_len; |
879 core_->WatchForRead(); | 895 core_->WatchForRead(); |
880 return ERR_IO_PENDING; | 896 return ERR_IO_PENDING; |
881 } | 897 } |
882 | 898 |
883 void TCPSocketWin::DidCompleteConnect() { | 899 void TCPSocketWin::DidCompleteConnect() { |
884 DCHECK(waiting_connect_); | 900 DCHECK(waiting_connect_); |
885 DCHECK(!read_callback_.is_null()); | 901 DCHECK(!read_callback_.is_null()); |
886 int result; | 902 int result; |
887 | 903 |
888 WSANETWORKEVENTS events; | 904 WSANETWORKEVENTS events; |
889 int rv; | 905 int rv; |
906 int os_error = 0; | |
890 { | 907 { |
891 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462784 is | 908 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462784 is |
892 // fixed. | 909 // fixed. |
893 tracked_objects::ScopedTracker tracking_profile1( | 910 tracked_objects::ScopedTracker tracking_profile1( |
894 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 911 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
895 "462784 TCPSocketWin::DidCompleteConnect -> WSAEnumNetworkEvents")); | 912 "462784 TCPSocketWin::DidCompleteConnect -> WSAEnumNetworkEvents")); |
896 rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, &events); | 913 rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, &events); |
914 os_error = WSAGetLastError(); | |
897 } | 915 } |
898 int os_error = 0; | |
899 if (rv == SOCKET_ERROR) { | 916 if (rv == SOCKET_ERROR) { |
900 NOTREACHED(); | 917 NOTREACHED(); |
901 os_error = WSAGetLastError(); | |
902 result = MapSystemError(os_error); | 918 result = MapSystemError(os_error); |
903 } else if (events.lNetworkEvents & FD_CONNECT) { | 919 } else if (events.lNetworkEvents & FD_CONNECT) { |
904 os_error = events.iErrorCode[FD_CONNECT_BIT]; | 920 os_error = events.iErrorCode[FD_CONNECT_BIT]; |
905 result = MapConnectError(os_error); | 921 result = MapConnectError(os_error); |
906 } else { | 922 } else { |
907 NOTREACHED(); | 923 NOTREACHED(); |
908 result = ERR_UNEXPECTED; | 924 result = ERR_UNEXPECTED; |
909 } | 925 } |
910 | 926 |
911 connect_os_error_ = os_error; | 927 connect_os_error_ = os_error; |
912 DoConnectComplete(result); | 928 DoConnectComplete(result); |
913 waiting_connect_ = false; | 929 waiting_connect_ = false; |
914 | 930 |
915 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462784 is fixed. | 931 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462784 is fixed. |
916 tracked_objects::ScopedTracker tracking_profile4( | 932 tracked_objects::ScopedTracker tracking_profile4( |
917 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 933 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
918 "462784 TCPSocketWin::DidCompleteConnect -> read_callback_")); | 934 "462784 TCPSocketWin::DidCompleteConnect -> read_callback_")); |
919 DCHECK_NE(result, ERR_IO_PENDING); | 935 DCHECK_NE(result, ERR_IO_PENDING); |
920 base::ResetAndReturn(&read_callback_).Run(result); | 936 base::ResetAndReturn(&read_callback_).Run(result); |
921 } | 937 } |
922 | 938 |
923 void TCPSocketWin::DidCompleteWrite() { | 939 void TCPSocketWin::DidCompleteWrite() { |
924 DCHECK(waiting_write_); | 940 DCHECK(waiting_write_); |
925 DCHECK(!write_callback_.is_null()); | 941 DCHECK(!write_callback_.is_null()); |
926 | 942 |
927 DWORD num_bytes, flags; | 943 DWORD num_bytes, flags; |
928 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 944 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
929 &num_bytes, FALSE, &flags); | 945 &num_bytes, FALSE, &flags); |
930 WSAResetEvent(core_->write_overlapped_.hEvent); | 946 WSAResetEvent(core_->write_overlapped_.hEvent); |
947 int os_error = WSAGetLastError(); | |
eroman
2016/11/29 19:51:00
Based on the conditional where this is used, I thi
Sigurður Ásgeirsson
2016/11/29 20:27:55
Done, though this probably does change semantics i
| |
931 waiting_write_ = false; | 948 waiting_write_ = false; |
932 int rv; | 949 int rv; |
933 if (!ok) { | 950 if (!ok) { |
934 int os_error = WSAGetLastError(); | |
935 rv = MapSystemError(os_error); | 951 rv = MapSystemError(os_error); |
936 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, | 952 net_log_.AddEvent(NetLogEventType::SOCKET_WRITE_ERROR, |
937 CreateNetLogSocketErrorCallback(rv, os_error)); | 953 CreateNetLogSocketErrorCallback(rv, os_error)); |
938 } else { | 954 } else { |
939 rv = static_cast<int>(num_bytes); | 955 rv = static_cast<int>(num_bytes); |
940 if (rv > core_->write_buffer_length_ || rv < 0) { | 956 if (rv > core_->write_buffer_length_ || rv < 0) { |
941 // It seems that some winsock interceptors report that more was written | 957 // It seems that some winsock interceptors report that more was written |
942 // than was available. Treat this as an error. http://crbug.com/27870 | 958 // than was available. Treat this as an error. http://crbug.com/27870 |
943 LOG(ERROR) << "Detected broken LSP: Asked to write " | 959 LOG(ERROR) << "Detected broken LSP: Asked to write " |
944 << core_->write_buffer_length_ << " bytes, but " << rv | 960 << core_->write_buffer_length_ << " bytes, but " << rv |
(...skipping 13 matching lines...) Expand all Loading... | |
958 } | 974 } |
959 | 975 |
960 void TCPSocketWin::DidSignalRead() { | 976 void TCPSocketWin::DidSignalRead() { |
961 DCHECK(waiting_read_); | 977 DCHECK(waiting_read_); |
962 DCHECK(!read_callback_.is_null()); | 978 DCHECK(!read_callback_.is_null()); |
963 | 979 |
964 int os_error = 0; | 980 int os_error = 0; |
965 WSANETWORKEVENTS network_events; | 981 WSANETWORKEVENTS network_events; |
966 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, | 982 int rv = WSAEnumNetworkEvents(socket_, core_->read_overlapped_.hEvent, |
967 &network_events); | 983 &network_events); |
984 os_error = WSAGetLastError(); | |
985 | |
968 if (rv == SOCKET_ERROR) { | 986 if (rv == SOCKET_ERROR) { |
969 os_error = WSAGetLastError(); | |
970 rv = MapSystemError(os_error); | 987 rv = MapSystemError(os_error); |
971 } else if (network_events.lNetworkEvents) { | 988 } else if (network_events.lNetworkEvents) { |
972 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462778 is | 989 // TODO(pkasting): Remove ScopedTracker below once crbug.com/462778 is |
973 // fixed. | 990 // fixed. |
974 tracked_objects::ScopedTracker tracking_profile2( | 991 tracked_objects::ScopedTracker tracking_profile2( |
975 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 992 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
976 "462778 TCPSocketWin::DidSignalRead -> DoRead")); | 993 "462778 TCPSocketWin::DidSignalRead -> DoRead")); |
977 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); | 994 DCHECK_EQ(network_events.lNetworkEvents & ~(FD_READ | FD_CLOSE), 0); |
978 // If network_events.lNetworkEvents is FD_CLOSE and | 995 // If network_events.lNetworkEvents is FD_CLOSE and |
979 // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful | 996 // network_events.iErrorCode[FD_CLOSE_BIT] is 0, it is a graceful |
(...skipping 29 matching lines...) Expand all Loading... | |
1009 } | 1026 } |
1010 | 1027 |
1011 bool TCPSocketWin::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const { | 1028 bool TCPSocketWin::GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const { |
1012 DCHECK(out_rtt); | 1029 DCHECK(out_rtt); |
1013 // TODO(bmcquade): Consider implementing using | 1030 // TODO(bmcquade): Consider implementing using |
1014 // GetPerTcpConnectionEStats/GetPerTcp6ConnectionEStats. | 1031 // GetPerTcpConnectionEStats/GetPerTcp6ConnectionEStats. |
1015 return false; | 1032 return false; |
1016 } | 1033 } |
1017 | 1034 |
1018 } // namespace net | 1035 } // namespace net |
OLD | NEW |