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 3 // found in the LICENSE file. 4 5 #include "net/socket/tcp_socket.h" 6 7 #include "base/file_util.h" 8 #include "base/files/file_path.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/threading/worker_pool.h" 11 12 namespace net { 13 14 namespace { 15 16 bool g_tcp_fastopen_enabled = false; 17 18 #if defined(OS_LINUX) || defined(OS_ANDROID) 19 20 typedef base::RefCountedData<bool> SharedBoolean; 21 22 // Checks to see if the system supports TCP FastOpen. Notably, it requires 23 // kernel support. Additionally, this checks system configuration to ensure that 24 // it's enabled. SystemSupportsTCPFastOpen(scoped_refptr<SharedBoolean> supported)25void SystemSupportsTCPFastOpen(scoped_refptr<SharedBoolean> supported) { 26 supported->data = false; 27 static const base::FilePath::CharType kTCPFastOpenProcFilePath[] = 28 "/proc/sys/net/ipv4/tcp_fastopen"; 29 std::string system_enabled_tcp_fastopen; 30 if (!base::ReadFileToString(base::FilePath(kTCPFastOpenProcFilePath), 31 &system_enabled_tcp_fastopen)) { 32 return; 33 } 34 35 // As per http://lxr.linux.no/linux+v3.7.7/include/net/tcp.h#L225 36 // TFO_CLIENT_ENABLE is the LSB 37 if (system_enabled_tcp_fastopen.empty() || 38 (system_enabled_tcp_fastopen[0] & 0x1) == 0) { 39 return; 40 } 41 42 supported->data = true; 43 } 44 EnableCallback(scoped_refptr<SharedBoolean> supported)45void EnableCallback(scoped_refptr<SharedBoolean> supported) { 46 g_tcp_fastopen_enabled = supported->data; 47 } 48 49 // This is asynchronous because it needs to do file IO, and it isn't allowed to 50 // do that on the IO thread. EnableFastOpenIfSupported()51void EnableFastOpenIfSupported() { 52 scoped_refptr<SharedBoolean> supported = new SharedBoolean; 53 base::WorkerPool::PostTaskAndReply( 54 FROM_HERE, 55 base::Bind(SystemSupportsTCPFastOpen, supported), 56 base::Bind(EnableCallback, supported), 57 false); 58 } 59 60 #else 61 EnableFastOpenIfSupported()62void EnableFastOpenIfSupported() { 63 g_tcp_fastopen_enabled = false; 64 } 65 66 #endif 67 68 } // namespace 69 SetTCPFastOpenEnabled(bool value)70void SetTCPFastOpenEnabled(bool value) { 71 if (value) { 72 EnableFastOpenIfSupported(); 73 } else { 74 g_tcp_fastopen_enabled = false; 75 } 76 } 77 IsTCPFastOpenEnabled()78bool IsTCPFastOpenEnabled() { 79 return g_tcp_fastopen_enabled; 80 } 81 82 } // namespace net 83