Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / socket / client_socket_factory.cc
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.
4
5 #include "net/socket/client_socket_factory.h"
6
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"
17 #endif
18 #include "net/socket/tcp_client_socket.h"
19 #include "net/udp/udp_client_socket.h"
20
21 namespace net {
22
23 class X509Certificate;
24
25 namespace {
26
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
36
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);
48     }
49
50     CertDatabase::GetInstance()->AddObserver(this);
51   }
52
53   ~DefaultClientSocketFactory() override {
54     // Note: This code never runs, as the factory is defined as a Leaky
55     // singleton.
56     CertDatabase::GetInstance()->RemoveObserver(this);
57   }
58
59   void OnCertAdded(const X509Certificate* cert) override {
60     ClearSSLSessionCache();
61   }
62
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();
68   }
69
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));
77   }
78
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));
85   }
86
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.
95     //
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();
105
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(),
114                                host_and_port,
115                                ssl_config,
116                                context));
117 #else
118     NOTIMPLEMENTED();
119     return scoped_ptr<SSLClientSocket>();
120 #endif
121   }
122
123   void ClearSSLSessionCache() override { SSLClientSocket::ClearSessionCache(); }
124
125  private:
126   scoped_refptr<base::SequencedWorkerPool> worker_pool_;
127   scoped_refptr<base::SequencedTaskRunner> nss_thread_task_runner_;
128 };
129
130 static base::LazyInstance<DefaultClientSocketFactory>::Leaky
131     g_default_client_socket_factory = LAZY_INSTANCE_INITIALIZER;
132
133 }  // namespace
134
135 // static
136 ClientSocketFactory* ClientSocketFactory::GetDefaultFactory() {
137   return g_default_client_socket_factory.Pointer();
138 }
139
140 }  // namespace net