Home | History | Annotate | Download | only in socket
      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   virtual ~DefaultClientSocketFactory() {
     54     // Note: This code never runs, as the factory is defined as a Leaky
     55     // singleton.
     56     CertDatabase::GetInstance()->RemoveObserver(this);
     57   }
     58 
     59   virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE {
     60     ClearSSLSessionCache();
     61   }
     62 
     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();
     68   }
     69 
     70   virtual 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   virtual 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   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.
     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   virtual void ClearSSLSessionCache() OVERRIDE {
    124     SSLClientSocket::ClearSessionCache();
    125   }
    126 
    127  private:
    128   scoped_refptr<base::SequencedWorkerPool> worker_pool_;
    129   scoped_refptr<base::SequencedTaskRunner> nss_thread_task_runner_;
    130 };
    131 
    132 static base::LazyInstance<DefaultClientSocketFactory>::Leaky
    133     g_default_client_socket_factory = LAZY_INSTANCE_INITIALIZER;
    134 
    135 }  // namespace
    136 
    137 // static
    138 ClientSocketFactory* ClientSocketFactory::GetDefaultFactory() {
    139   return g_default_client_socket_factory.Pointer();
    140 }
    141 
    142 }  // namespace net
    143