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

Unified Diff: net/socket/tcp_socket_libevent.cc

Issue 451383002: Plumbing for TCP FastOpen for SSL sockets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased to master. Created 6 years, 3 months 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 side-by-side diff with in-line comments
Download patch
Index: net/socket/tcp_socket_libevent.cc
diff --git a/net/socket/tcp_socket_libevent.cc b/net/socket/tcp_socket_libevent.cc
index 426c8b0dd3505e99acc51920ae40b4511c87bc03..dd643159149ab32ae0247aeaba1052c1c06f7615 100644
--- a/net/socket/tcp_socket_libevent.cc
+++ b/net/socket/tcp_socket_libevent.cc
@@ -13,6 +13,8 @@
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/task_runner_util.h"
+#include "base/threading/worker_pool.h"
#include "net/base/address_list.h"
#include "net/base/connection_type_histograms.h"
#include "net/base/io_buffer.h"
@@ -28,6 +30,12 @@
#define TCPI_OPT_SYN_DATA 32
#endif
+// True if OS supports TCP FastOpen.
+bool g_tcp_fastopen_supported = false;
+// True if TCP FastOpen is user-enabled for all connections.
+// TODO(jri): Change global variable to param in HttpNetworkSession::Params.
+bool g_tcp_fastopen_user_enabled = false;
+
namespace net {
namespace {
@@ -69,13 +77,55 @@ bool SetTCPKeepAlive(int fd, bool enable, int delay) {
return true;
}
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+// Checks if the kernel supports TCP FastOpen.
+bool SystemSupportsTCPFastOpen() {
+ static const base::FilePath::CharType kTCPFastOpenProcFilePath[] =
mmenke 2014/09/05 19:36:42 I seem to recall reading on Chromium dev that stat
Jana 2014/09/05 20:38:57 Hmm. I don't know why this is static in the first
+ "/proc/sys/net/ipv4/tcp_fastopen";
+ std::string system_supports_tcp_fastopen;
+ if (!base::ReadFileToString(base::FilePath(kTCPFastOpenProcFilePath),
+ &system_supports_tcp_fastopen)) {
+ return false;
+ }
+ // The read from /proc should return '1' if TCP FastOpen is enabled in the OS.
+ if (system_supports_tcp_fastopen.empty() ||
+ (system_supports_tcp_fastopen[0] != '1')) {
+ return false;
+ }
+ return true;
+}
+
+void CallbackForTCPFastOpenCheck(bool user_enabled,
mmenke 2014/09/05 19:36:42 Functions should generally be named after what the
Jana 2014/09/05 20:38:57 Good suggestion -- done. (RegisterTCPFastOpenInten
+ bool system_supported) {
+ g_tcp_fastopen_supported = system_supported;
+ g_tcp_fastopen_user_enabled = user_enabled;
+}
+#endif
+
+// Check if TCP FastOpen option is supported by the OS.
+bool IsTCPFastOpenSupported() {
+ return g_tcp_fastopen_supported;
+}
+
} // namespace
//-----------------------------------------------------------------------------
+// This is asynchronous because it needs to do file IO, and it isn't allowed to
+// do that on the IO thread.
+void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) {
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+ base::PostTaskAndReplyWithResult(
+ base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false),
mmenke 2014/09/05 19:36:42 File IO isn't considered slow?
Jana 2014/09/05 20:38:57 (This was the code prior to me touching it... don'
+ FROM_HERE,
+ base::Bind(SystemSupportsTCPFastOpen),
+ base::Bind(CallbackForTCPFastOpenCheck, user_enabled));
+#endif
+}
+
TCPSocketLibevent::TCPSocketLibevent(NetLog* net_log,
const NetLog::Source& source)
- : use_tcp_fastopen_(IsTCPFastOpenEnabled()),
+ : use_tcp_fastopen_if_supported_(false),
tcp_fastopen_connected_(false),
fast_open_status_(FAST_OPEN_STATUS_UNKNOWN),
logging_multiple_connect_attempts_(false),
@@ -167,7 +217,7 @@ int TCPSocketLibevent::Connect(const IPEndPoint& address,
if (!address.ToSockAddr(storage.addr, &storage.addr_len))
return ERR_ADDRESS_INVALID;
- if (use_tcp_fastopen_) {
+ if (use_tcp_fastopen_if_supported_) {
// With TCP FastOpen, we pretend that the socket is connected.
DCHECK(!tcp_fastopen_connected_);
socket_->SetPeerAddress(storage);
@@ -186,7 +236,7 @@ bool TCPSocketLibevent::IsConnected() const {
if (!socket_)
return false;
- if (use_tcp_fastopen_ && !tcp_fastopen_connected_ &&
+ if (use_tcp_fastopen_if_supported_ && !tcp_fastopen_connected_ &&
socket_->HasPeerAddress()) {
// With TCP FastOpen, we pretend that the socket is connected.
// This allows GetPeerAddress() to return peer_address_.
@@ -235,7 +285,7 @@ int TCPSocketLibevent::Write(IOBuffer* buf,
// ownership of buf to socket.
base::Unretained(this), make_scoped_refptr(buf), callback);
int rv;
- if (use_tcp_fastopen_ && !tcp_fastopen_connected_) {
+ if (use_tcp_fastopen_if_supported_ && !tcp_fastopen_connected_) {
rv = TcpFastOpenWrite(buf, buf_len, write_callback);
} else {
rv = socket_->Write(buf, buf_len, write_callback);
@@ -366,7 +416,12 @@ void TCPSocketLibevent::Close() {
}
bool TCPSocketLibevent::UsingTCPFastOpen() const {
- return use_tcp_fastopen_;
+ return use_tcp_fastopen_if_supported_;
+}
+
+void TCPSocketLibevent::EnableTCPFastOpen() {
+ if (!use_tcp_fastopen_if_supported_ && IsTCPFastOpenSupported())
mmenke 2014/09/05 19:36:42 The "use_tcp_fastopen_if_supported_" check isn't n
Jana 2014/09/05 20:38:57 Good catch -- Done.
+ use_tcp_fastopen_if_supported_ = true;
mmenke 2014/09/05 19:36:42 This variable should be renamed to use_tcp_fastope
Jana 2014/09/05 20:38:56 Good suggestion -- done.
}
bool TCPSocketLibevent::IsValid() const {
@@ -495,7 +550,7 @@ void TCPSocketLibevent::ReadCompleted(const scoped_refptr<IOBuffer>& buf,
const CompletionCallback& callback,
int rv) {
DCHECK_NE(ERR_IO_PENDING, rv);
- // Records fast open status regardless of error in asynchronous case.
+ // Records TCP FastOpen status regardless of error in asynchronous case.
// TODO(rdsmith,jri): Change histogram name to indicate it could be called on
// error.
RecordFastOpenStatus();
@@ -590,14 +645,14 @@ int TCPSocketLibevent::TcpFastOpenWrite(
}
void TCPSocketLibevent::RecordFastOpenStatus() {
- if (use_tcp_fastopen_ &&
+ if (use_tcp_fastopen_if_supported_ &&
(fast_open_status_ == FAST_OPEN_FAST_CONNECT_RETURN ||
fast_open_status_ == FAST_OPEN_SLOW_CONNECT_RETURN)) {
DCHECK_NE(FAST_OPEN_STATUS_UNKNOWN, fast_open_status_);
bool getsockopt_success(false);
bool server_acked_data(false);
#if defined(TCP_INFO)
- // Probe to see the if the socket used TCP Fast Open.
+ // Probe to see the if the socket used TCP FastOpen.
tcp_info info;
socklen_t info_len = sizeof(tcp_info);
getsockopt_success =

Powered by Google App Engine
This is Rietveld 408576698