// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/socket/client_socket_pool_manager.h"

#include <string>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/stringprintf.h"
#include "net/base/load_flags.h"
#include "net/http/http_proxy_client_socket_pool.h"
#include "net/http/http_request_info.h"
#include "net/http/http_stream_factory.h"
#include "net/proxy/proxy_info.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/socks_client_socket_pool.h"
#include "net/socket/ssl_client_socket_pool.h"
#include "net/socket/transport_client_socket_pool.h"

namespace net {

namespace {

// Limit of sockets of each socket pool.
int g_max_sockets_per_pool[] = {
  256,  // NORMAL_SOCKET_POOL
  256   // WEBSOCKET_SOCKET_POOL
};

COMPILE_ASSERT(arraysize(g_max_sockets_per_pool) ==
                   HttpNetworkSession::NUM_SOCKET_POOL_TYPES,
               max_sockets_per_pool_length_mismatch);

// Default to allow up to 6 connections per host. Experiment and tuning may
// try other values (greater than 0).  Too large may cause many problems, such
// as home routers blocking the connections!?!?  See http://crbug.com/12066.
//
// WebSocket connections are long-lived, and should be treated differently
// than normal other connections. 6 connections per group sounded too small
// for such use, thus we use a larger limit which was determined somewhat
// arbitrarily.
// TODO(yutak): Look at the usage and determine the right value after
// WebSocket protocol stack starts to work.
int g_max_sockets_per_group[] = {
  6,  // NORMAL_SOCKET_POOL
  30  // WEBSOCKET_SOCKET_POOL
};

COMPILE_ASSERT(arraysize(g_max_sockets_per_group) ==
                   HttpNetworkSession::NUM_SOCKET_POOL_TYPES,
               max_sockets_per_group_length_mismatch);

// The max number of sockets to allow per proxy server.  This applies both to
// http and SOCKS proxies.  See http://crbug.com/12066 and
// http://crbug.com/44501 for details about proxy server connection limits.
int g_max_sockets_per_proxy_server[] = {
  kDefaultMaxSocketsPerProxyServer,  // NORMAL_SOCKET_POOL
  kDefaultMaxSocketsPerProxyServer   // WEBSOCKET_SOCKET_POOL
};

COMPILE_ASSERT(arraysize(g_max_sockets_per_proxy_server) ==
                   HttpNetworkSession::NUM_SOCKET_POOL_TYPES,
               max_sockets_per_proxy_server_length_mismatch);

// The meat of the implementation for the InitSocketHandleForHttpRequest,
// InitSocketHandleForRawConnect and PreconnectSocketsForHttpRequest methods.
int InitSocketPoolHelper(const GURL& request_url,
                         const HttpRequestHeaders& request_extra_headers,
                         int request_load_flags,
                         RequestPriority request_priority,
                         HttpNetworkSession* session,
                         const ProxyInfo& proxy_info,
                         bool force_spdy_over_ssl,
                         bool want_spdy_over_npn,
                         const SSLConfig& ssl_config_for_origin,
                         const SSLConfig& ssl_config_for_proxy,
                         bool force_tunnel,
                         const BoundNetLog& net_log,
                         int num_preconnect_streams,
                         ClientSocketHandle* socket_handle,
                         const OnHostResolutionCallback& resolution_callback,
                         const CompletionCallback& callback) {
  scoped_refptr<TransportSocketParams> tcp_params;
  scoped_refptr<HttpProxySocketParams> http_proxy_params;
  scoped_refptr<SOCKSSocketParams> socks_params;
  scoped_ptr<HostPortPair> proxy_host_port;

  bool using_ssl = request_url.SchemeIs("https") || force_spdy_over_ssl;

  HostPortPair origin_host_port =
      HostPortPair(request_url.HostNoBrackets(),
                   request_url.EffectiveIntPort());

  if (!using_ssl && session->params().testing_fixed_http_port != 0) {
    origin_host_port.set_port(session->params().testing_fixed_http_port);
  } else if (using_ssl && session->params().testing_fixed_https_port != 0) {
    origin_host_port.set_port(session->params().testing_fixed_https_port);
  }

  bool disable_resolver_cache =
      request_load_flags & LOAD_BYPASS_CACHE ||
      request_load_flags & LOAD_VALIDATE_CACHE ||
      request_load_flags & LOAD_DISABLE_CACHE;

  int load_flags = request_load_flags;
  if (session->params().ignore_certificate_errors)
    load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS;

  // Build the string used to uniquely identify connections of this type.
  // Determine the host and port to connect to.
  std::string connection_group = origin_host_port.ToString();
  DCHECK(!connection_group.empty());
  if (using_ssl) {
    // All connections in a group should use the same SSLConfig settings.
    // Encode version_max in the connection group's name, unless it's the
    // default version_max. (We want the common case to use the shortest
    // encoding). A version_max of TLS 1.1 is encoded as "ssl(max:3.2)/"
    // rather than "tlsv1.1/" because the actual protocol version, which
    // is selected by the server, may not be TLS 1.1. Do not encode
    // version_min in the connection group's name because version_min
    // should be the same for all connections, whereas version_max may
    // change for version fallbacks.
    std::string prefix = "ssl/";
    if (ssl_config_for_origin.version_max !=
        SSLConfigService::default_version_max()) {
      switch (ssl_config_for_origin.version_max) {
        case SSL_PROTOCOL_VERSION_TLS1_2:
          prefix = "ssl(max:3.3)/";
          break;
        case SSL_PROTOCOL_VERSION_TLS1_1:
          prefix = "ssl(max:3.2)/";
          break;
        case SSL_PROTOCOL_VERSION_TLS1:
          prefix = "ssl(max:3.1)/";
          break;
        case SSL_PROTOCOL_VERSION_SSL3:
          prefix = "sslv3/";
          break;
        default:
          CHECK(false);
          break;
      }
    }
    connection_group = prefix + connection_group;
  }

  bool ignore_limits = (request_load_flags & LOAD_IGNORE_LIMITS) != 0;
  if (proxy_info.is_direct()) {
    tcp_params = new TransportSocketParams(origin_host_port,
                                           request_priority,
                                           disable_resolver_cache,
                                           ignore_limits,
                                           resolution_callback);
  } else {
    ProxyServer proxy_server = proxy_info.proxy_server();
    proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair()));
    scoped_refptr<TransportSocketParams> proxy_tcp_params(
        new TransportSocketParams(*proxy_host_port,
                                  request_priority,
                                  disable_resolver_cache,
                                  ignore_limits,
                                  resolution_callback));

    if (proxy_info.is_http() || proxy_info.is_https()) {
      std::string user_agent;
      request_extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
                                      &user_agent);
      scoped_refptr<SSLSocketParams> ssl_params;
      if (proxy_info.is_https()) {
        // Set ssl_params, and unset proxy_tcp_params
        ssl_params = new SSLSocketParams(proxy_tcp_params,
                                         NULL,
                                         NULL,
                                         ProxyServer::SCHEME_DIRECT,
                                         *proxy_host_port.get(),
                                         ssl_config_for_proxy,
                                         load_flags,
                                         force_spdy_over_ssl,
                                         want_spdy_over_npn);
        proxy_tcp_params = NULL;
      }

      http_proxy_params =
          new HttpProxySocketParams(proxy_tcp_params,
                                    ssl_params,
                                    request_url,
                                    user_agent,
                                    origin_host_port,
                                    session->http_auth_cache(),
                                    session->http_auth_handler_factory(),
                                    session->spdy_session_pool(),
                                    force_tunnel || using_ssl);
    } else {
      DCHECK(proxy_info.is_socks());
      char socks_version;
      if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5)
        socks_version = '5';
      else
        socks_version = '4';
      connection_group = base::StringPrintf(
          "socks%c/%s", socks_version, connection_group.c_str());

      socks_params = new SOCKSSocketParams(proxy_tcp_params,
                                           socks_version == '5',
                                           origin_host_port,
                                           request_priority);
    }
  }

  // Deal with SSL - which layers on top of any given proxy.
  if (using_ssl) {
    scoped_refptr<SSLSocketParams> ssl_params =
        new SSLSocketParams(tcp_params,
                            socks_params,
                            http_proxy_params,
                            proxy_info.proxy_server().scheme(),
                            origin_host_port,
                            ssl_config_for_origin,
                            load_flags,
                            force_spdy_over_ssl,
                            want_spdy_over_npn);
    SSLClientSocketPool* ssl_pool = NULL;
    if (proxy_info.is_direct()) {
      ssl_pool = session->GetSSLSocketPool(
          HttpNetworkSession::NORMAL_SOCKET_POOL);
    } else {
      ssl_pool = session->GetSocketPoolForSSLWithProxy(
          HttpNetworkSession::NORMAL_SOCKET_POOL,
          *proxy_host_port);
    }

    if (num_preconnect_streams) {
      RequestSocketsForPool(ssl_pool, connection_group, ssl_params,
                            num_preconnect_streams, net_log);
      return OK;
    }

    return socket_handle->Init(connection_group, ssl_params,
                               request_priority, callback, ssl_pool,
                               net_log);
  }

  // Finally, get the connection started.

  if (proxy_info.is_http() || proxy_info.is_https()) {
    HttpProxyClientSocketPool* pool =
        session->GetSocketPoolForHTTPProxy(
            HttpNetworkSession::NORMAL_SOCKET_POOL,
            *proxy_host_port);
    if (num_preconnect_streams) {
      RequestSocketsForPool(pool, connection_group, http_proxy_params,
                            num_preconnect_streams, net_log);
      return OK;
    }

    return socket_handle->Init(connection_group, http_proxy_params,
                               request_priority, callback,
                               pool, net_log);
  }

  if (proxy_info.is_socks()) {
    SOCKSClientSocketPool* pool =
        session->GetSocketPoolForSOCKSProxy(
            HttpNetworkSession::NORMAL_SOCKET_POOL,
            *proxy_host_port);
    if (num_preconnect_streams) {
      RequestSocketsForPool(pool, connection_group, socks_params,
                            num_preconnect_streams, net_log);
      return OK;
    }

    return socket_handle->Init(connection_group, socks_params,
                               request_priority, callback, pool,
                               net_log);
  }

  DCHECK(proxy_info.is_direct());

  TransportClientSocketPool* pool =
      session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL);
  if (num_preconnect_streams) {
    RequestSocketsForPool(pool, connection_group, tcp_params,
                          num_preconnect_streams, net_log);
    return OK;
  }

  return socket_handle->Init(connection_group, tcp_params,
                             request_priority, callback,
                             pool, net_log);
}

}  // namespace

ClientSocketPoolManager::ClientSocketPoolManager() {}
ClientSocketPoolManager::~ClientSocketPoolManager() {}

// static
int ClientSocketPoolManager::max_sockets_per_pool(
    HttpNetworkSession::SocketPoolType pool_type) {
  DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
  return g_max_sockets_per_pool[pool_type];
}

// static
void ClientSocketPoolManager::set_max_sockets_per_pool(
    HttpNetworkSession::SocketPoolType pool_type,
    int socket_count) {
  DCHECK_LT(0, socket_count);
  DCHECK_GT(1000, socket_count);  // Sanity check.
  DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
  g_max_sockets_per_pool[pool_type] = socket_count;
  DCHECK_GE(g_max_sockets_per_pool[pool_type],
            g_max_sockets_per_group[pool_type]);
}

// static
int ClientSocketPoolManager::max_sockets_per_group(
    HttpNetworkSession::SocketPoolType pool_type) {
  DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
  return g_max_sockets_per_group[pool_type];
}

// static
void ClientSocketPoolManager::set_max_sockets_per_group(
    HttpNetworkSession::SocketPoolType pool_type,
    int socket_count) {
  DCHECK_LT(0, socket_count);
  // The following is a sanity check... but we should NEVER be near this value.
  DCHECK_GT(100, socket_count);
  DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
  g_max_sockets_per_group[pool_type] = socket_count;

  DCHECK_GE(g_max_sockets_per_pool[pool_type],
            g_max_sockets_per_group[pool_type]);
  DCHECK_GE(g_max_sockets_per_proxy_server[pool_type],
            g_max_sockets_per_group[pool_type]);
}

// static
int ClientSocketPoolManager::max_sockets_per_proxy_server(
    HttpNetworkSession::SocketPoolType pool_type) {
  DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
  return g_max_sockets_per_proxy_server[pool_type];
}

// static
void ClientSocketPoolManager::set_max_sockets_per_proxy_server(
    HttpNetworkSession::SocketPoolType pool_type,
    int socket_count) {
  DCHECK_LT(0, socket_count);
  DCHECK_GT(100, socket_count);  // Sanity check.
  DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
  // Assert this case early on. The max number of sockets per group cannot
  // exceed the max number of sockets per proxy server.
  DCHECK_LE(g_max_sockets_per_group[pool_type], socket_count);
  g_max_sockets_per_proxy_server[pool_type] = socket_count;
}

int InitSocketHandleForHttpRequest(
    const GURL& request_url,
    const HttpRequestHeaders& request_extra_headers,
    int request_load_flags,
    RequestPriority request_priority,
    HttpNetworkSession* session,
    const ProxyInfo& proxy_info,
    bool force_spdy_over_ssl,
    bool want_spdy_over_npn,
    const SSLConfig& ssl_config_for_origin,
    const SSLConfig& ssl_config_for_proxy,
    const BoundNetLog& net_log,
    ClientSocketHandle* socket_handle,
    const OnHostResolutionCallback& resolution_callback,
    const CompletionCallback& callback) {
  DCHECK(socket_handle);
  return InitSocketPoolHelper(
      request_url, request_extra_headers, request_load_flags, request_priority,
      session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn,
      ssl_config_for_origin, ssl_config_for_proxy, false, net_log, 0,
      socket_handle, resolution_callback, callback);
}

int InitSocketHandleForRawConnect(
    const HostPortPair& host_port_pair,
    HttpNetworkSession* session,
    const ProxyInfo& proxy_info,
    const SSLConfig& ssl_config_for_origin,
    const SSLConfig& ssl_config_for_proxy,
    const BoundNetLog& net_log,
    ClientSocketHandle* socket_handle,
    const CompletionCallback& callback) {
  DCHECK(socket_handle);
  // Synthesize an HttpRequestInfo.
  GURL request_url = GURL("http://" + host_port_pair.ToString());
  HttpRequestHeaders request_extra_headers;
  int request_load_flags = 0;
  RequestPriority request_priority = MEDIUM;

  return InitSocketPoolHelper(
      request_url, request_extra_headers, request_load_flags, request_priority,
      session, proxy_info, false, false, ssl_config_for_origin,
      ssl_config_for_proxy, true, net_log, 0, socket_handle,
      OnHostResolutionCallback(), callback);
}

int PreconnectSocketsForHttpRequest(
    const GURL& request_url,
    const HttpRequestHeaders& request_extra_headers,
    int request_load_flags,
    RequestPriority request_priority,
    HttpNetworkSession* session,
    const ProxyInfo& proxy_info,
    bool force_spdy_over_ssl,
    bool want_spdy_over_npn,
    const SSLConfig& ssl_config_for_origin,
    const SSLConfig& ssl_config_for_proxy,
    const BoundNetLog& net_log,
    int num_preconnect_streams) {
  return InitSocketPoolHelper(
      request_url, request_extra_headers, request_load_flags, request_priority,
      session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn,
      ssl_config_for_origin, ssl_config_for_proxy, false, net_log,
      num_preconnect_streams, NULL, OnHostResolutionCallback(),
      CompletionCallback());
}

}  // namespace net
