Landing Recent QUIC changes until 8/19/2015 17:00 UTC.
[chromium-blink-merge.git] / net / socket / client_socket_factory.cc
blobcb5d85104869ab0da191117667a19609c16150e1
1 // Copyright (c) 2012 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.
5 #include "net/socket/client_socket_factory.h"
7 #include "base/lazy_instance.h"
8 #include "base/thread_task_runner_handle.h"
9 #include "base/threading/sequenced_worker_pool.h"
10 #include "build/build_config.h"
11 #include "net/cert/cert_database.h"
12 #include "net/socket/client_socket_handle.h"
13 #if defined(USE_OPENSSL)
14 #include "net/socket/ssl_client_socket_openssl.h"
15 #elif defined(USE_NSS_CERTS) || defined(OS_MACOSX) || defined(OS_WIN)
16 #include "net/socket/ssl_client_socket_nss.h"
17 #endif
18 #include "net/socket/tcp_client_socket.h"
19 #include "net/udp/udp_client_socket.h"
21 namespace net {
23 class X509Certificate;
25 namespace {
27 // ChromeOS and Linux may require interaction with smart cards or TPMs, which
28 // may cause NSS functions to block for upwards of several seconds. To avoid
29 // blocking all activity on the current task runner, such as network or IPC
30 // traffic, run NSS SSL functions on a dedicated thread.
31 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
32 bool g_use_dedicated_nss_thread = true;
33 #else
34 bool g_use_dedicated_nss_thread = false;
35 #endif
37 class DefaultClientSocketFactory : public ClientSocketFactory,
38 public CertDatabase::Observer {
39 public:
40 DefaultClientSocketFactory() {
41 if (g_use_dedicated_nss_thread) {
42 // Use a single thread for the worker pool.
43 worker_pool_ = new base::SequencedWorkerPool(1, "NSS SSL Thread");
44 nss_thread_task_runner_ =
45 worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior(
46 worker_pool_->GetSequenceToken(),
47 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
50 CertDatabase::GetInstance()->AddObserver(this);
53 ~DefaultClientSocketFactory() override {
54 // Note: This code never runs, as the factory is defined as a Leaky
55 // singleton.
56 CertDatabase::GetInstance()->RemoveObserver(this);
59 void OnCertAdded(const X509Certificate* cert) override {
60 ClearSSLSessionCache();
63 void OnCACertChanged(const X509Certificate* cert) override {
64 // Per wtc, we actually only need to flush when trust is reduced.
65 // Always flush now because OnCACertChanged does not tell us this.
66 // See comments in ClientSocketPoolManager::OnCACertChanged.
67 ClearSSLSessionCache();
70 scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
71 DatagramSocket::BindType bind_type,
72 const RandIntCallback& rand_int_cb,
73 NetLog* net_log,
74 const NetLog::Source& source) override {
75 return scoped_ptr<DatagramClientSocket>(
76 new UDPClientSocket(bind_type, rand_int_cb, net_log, source));
79 scoped_ptr<StreamSocket> CreateTransportClientSocket(
80 const AddressList& addresses,
81 NetLog* net_log,
82 const NetLog::Source& source) override {
83 return scoped_ptr<StreamSocket>(
84 new TCPClientSocket(addresses, net_log, source));
87 scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
88 scoped_ptr<ClientSocketHandle> transport_socket,
89 const HostPortPair& host_and_port,
90 const SSLConfig& ssl_config,
91 const SSLClientSocketContext& context) override {
92 // nss_thread_task_runner_ may be NULL if g_use_dedicated_nss_thread is
93 // false or if the dedicated NSS thread failed to start. If so, cause NSS
94 // functions to execute on the current task runner.
96 // Note: The current task runner is obtained on each call due to unit
97 // tests, which may create and tear down the current thread's TaskRunner
98 // between each test. Because the DefaultClientSocketFactory is leaky, it
99 // may span multiple tests, and thus the current task runner may change
100 // from call to call.
101 scoped_refptr<base::SequencedTaskRunner> nss_task_runner(
102 nss_thread_task_runner_);
103 if (!nss_task_runner.get())
104 nss_task_runner = base::ThreadTaskRunnerHandle::Get();
106 #if defined(USE_OPENSSL)
107 return scoped_ptr<SSLClientSocket>(
108 new SSLClientSocketOpenSSL(transport_socket.Pass(), host_and_port,
109 ssl_config, context));
110 #elif defined(USE_NSS_CERTS) || defined(OS_MACOSX) || defined(OS_WIN)
111 return scoped_ptr<SSLClientSocket>(
112 new SSLClientSocketNSS(nss_task_runner.get(),
113 transport_socket.Pass(),
114 host_and_port,
115 ssl_config,
116 context));
117 #else
118 NOTIMPLEMENTED();
119 return scoped_ptr<SSLClientSocket>();
120 #endif
123 void ClearSSLSessionCache() override { SSLClientSocket::ClearSessionCache(); }
125 private:
126 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
127 scoped_refptr<base::SequencedTaskRunner> nss_thread_task_runner_;
130 static base::LazyInstance<DefaultClientSocketFactory>::Leaky
131 g_default_client_socket_factory = LAZY_INSTANCE_INITIALIZER;
133 } // namespace
135 // static
136 ClientSocketFactory* ClientSocketFactory::GetDefaultFactory() {
137 return g_default_client_socket_factory.Pointer();
140 } // namespace net