Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_client_socket.h" | 5 #include "net/socket/tcp_client_socket.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <netdb.h> | 9 #include <netdb.h> |
| 10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 | 38 |
| 39 // DisableNagle turns off buffering in the kernel. By default, TCP sockets will | 39 // DisableNagle turns off buffering in the kernel. By default, TCP sockets will |
| 40 // wait up to 200ms for more data to complete a packet before transmitting. | 40 // wait up to 200ms for more data to complete a packet before transmitting. |
| 41 // After calling this function, the kernel will not wait. See TCP_NODELAY in | 41 // After calling this function, the kernel will not wait. See TCP_NODELAY in |
| 42 // `man 7 tcp`. | 42 // `man 7 tcp`. |
| 43 int DisableNagle(int fd) { | 43 int DisableNagle(int fd) { |
| 44 int on = 1; | 44 int on = 1; |
| 45 return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); | 45 return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); |
| 46 } | 46 } |
| 47 | 47 |
| 48 // SetTCPKeepAlive sets SO_KEEPALIVE. | |
| 49 void SetTCPKeepAlive(int fd) { | |
| 50 int optval = 1; | |
| 51 socklen_t optlen = sizeof(optval); | |
| 52 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen)) { | |
| 53 PLOG(ERROR) << "Failed to set SO_KEEPALIVE on fd: " << fd; | |
| 54 return; | |
| 55 } | |
| 56 #if defined(OS_LINUX) | |
| 57 // Set seconds until first TCP keep alive. | |
| 58 optval = 45; | |
| 59 if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &optval, optlen)) { | |
| 60 PLOG(ERROR) << "Failed to set TCP_KEEPIDLE on fd: " << fd; | |
| 61 return; | |
| 62 } | |
| 63 // Set seconds between TCP keep alives. | |
| 64 if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &optval, optlen)) { | |
| 65 PLOG(ERROR) << "Failed to set TCP_KEEPINTVL on fd: " << fd; | |
| 66 return; | |
| 67 } | |
| 68 #endif | |
| 69 } | |
| 70 | |
| 48 // Convert values from <errno.h> to values from "net/base/net_errors.h" | 71 // Convert values from <errno.h> to values from "net/base/net_errors.h" |
| 49 int MapPosixError(int os_error) { | 72 int MapPosixError(int os_error) { |
| 50 // There are numerous posix error codes, but these are the ones we thus far | 73 // There are numerous posix error codes, but these are the ones we thus far |
| 51 // find interesting. | 74 // find interesting. |
| 52 switch (os_error) { | 75 switch (os_error) { |
| 53 case EAGAIN: | 76 case EAGAIN: |
| 54 #if EWOULDBLOCK != EAGAIN | 77 #if EWOULDBLOCK != EAGAIN |
| 55 case EWOULDBLOCK: | 78 case EWOULDBLOCK: |
| 56 #endif | 79 #endif |
| 57 return ERR_IO_PENDING; | 80 return ERR_IO_PENDING; |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 if (SetNonBlocking(socket_)) { | 509 if (SetNonBlocking(socket_)) { |
| 487 const int err = errno; | 510 const int err = errno; |
| 488 close(socket_); | 511 close(socket_); |
| 489 socket_ = kInvalidSocket; | 512 socket_ = kInvalidSocket; |
| 490 return err; | 513 return err; |
| 491 } | 514 } |
| 492 | 515 |
| 493 // This mirrors the behaviour on Windows. See the comment in | 516 // This mirrors the behaviour on Windows. See the comment in |
| 494 // tcp_client_socket_win.cc after searching for "NODELAY". | 517 // tcp_client_socket_win.cc after searching for "NODELAY". |
| 495 DisableNagle(socket_); // If DisableNagle fails, we don't care. | 518 DisableNagle(socket_); // If DisableNagle fails, we don't care. |
| 519 SetTCPKeepAlive(socket_); | |
|
wtc
2011/01/18 20:22:48
Please add a comment to explain why we need to set
| |
| 496 | 520 |
| 497 return 0; | 521 return 0; |
| 498 } | 522 } |
| 499 | 523 |
| 500 void TCPClientSocketLibevent::LogConnectCompletion(int net_error) { | 524 void TCPClientSocketLibevent::LogConnectCompletion(int net_error) { |
| 501 scoped_refptr<NetLog::EventParameters> params; | 525 scoped_refptr<NetLog::EventParameters> params; |
| 502 if (net_error != OK) | 526 if (net_error != OK) |
| 503 params = new NetLogIntegerParameter("net_error", net_error); | 527 params = new NetLogIntegerParameter("net_error", net_error); |
| 504 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, params); | 528 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, params); |
| 505 } | 529 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 623 | 647 |
| 624 bool TCPClientSocketLibevent::WasEverUsed() const { | 648 bool TCPClientSocketLibevent::WasEverUsed() const { |
| 625 return use_history_.was_used_to_convey_data(); | 649 return use_history_.was_used_to_convey_data(); |
| 626 } | 650 } |
| 627 | 651 |
| 628 bool TCPClientSocketLibevent::UsingTCPFastOpen() const { | 652 bool TCPClientSocketLibevent::UsingTCPFastOpen() const { |
| 629 return use_tcp_fastopen_; | 653 return use_tcp_fastopen_; |
| 630 } | 654 } |
| 631 | 655 |
| 632 } // namespace net | 656 } // namespace net |
| OLD | NEW |