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) || defined(OS_MACOSX) || defined(OS_WIN)
16 #include "net/socket/ssl_client_socket_nss.h"
18 #include "net/socket/tcp_client_socket.h"
19 #include "net/udp/udp_client_socket.h"
23 class X509Certificate
;
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;
34 bool g_use_dedicated_nss_thread
= false;
37 class DefaultClientSocketFactory
: public ClientSocketFactory
,
38 public CertDatabase::Observer
{
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 virtual ~DefaultClientSocketFactory() {
54 // Note: This code never runs, as the factory is defined as a Leaky
56 CertDatabase::GetInstance()->RemoveObserver(this);
59 virtual void OnCertAdded(const X509Certificate
* cert
) OVERRIDE
{
60 ClearSSLSessionCache();
63 virtual 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 virtual scoped_ptr
<DatagramClientSocket
> CreateDatagramClientSocket(
71 DatagramSocket::BindType bind_type
,
72 const RandIntCallback
& rand_int_cb
,
74 const NetLog::Source
& source
) OVERRIDE
{
75 return scoped_ptr
<DatagramClientSocket
>(
76 new UDPClientSocket(bind_type
, rand_int_cb
, net_log
, source
));
79 virtual scoped_ptr
<StreamSocket
> CreateTransportClientSocket(
80 const AddressList
& addresses
,
82 const NetLog::Source
& source
) OVERRIDE
{
83 return scoped_ptr
<StreamSocket
>(
84 new TCPClientSocket(addresses
, net_log
, source
));
87 virtual 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) || defined(OS_MACOSX) || defined(OS_WIN)
111 return scoped_ptr
<SSLClientSocket
>(
112 new SSLClientSocketNSS(nss_task_runner
.get(),
113 transport_socket
.Pass(),
119 return scoped_ptr
<SSLClientSocket
>();
123 virtual void ClearSSLSessionCache() OVERRIDE
{
124 SSLClientSocket::ClearSessionCache();
128 scoped_refptr
<base::SequencedWorkerPool
> worker_pool_
;
129 scoped_refptr
<base::SequencedTaskRunner
> nss_thread_task_runner_
;
132 static base::LazyInstance
<DefaultClientSocketFactory
>::Leaky
133 g_default_client_socket_factory
= LAZY_INSTANCE_INITIALIZER
;
138 ClientSocketFactory
* ClientSocketFactory::GetDefaultFactory() {
139 return g_default_client_socket_factory
.Pointer();