class Redis::Connection::SSLSocket

def self.connect(host, port, timeout, ssl_params)

def self.connect(host, port, timeout, ssl_params)
  # Note: this is using Redis::Connection::TCPSocket
  tcp_sock = TCPSocket.connect(host, port, timeout)
  ctx = OpenSSL::SSL::SSLContext.new
  ctx.set_params(ssl_params) if ssl_params && !ssl_params.empty?
  ssl_sock = new(tcp_sock, ctx)
  ssl_sock.hostname = host
  begin
    # Initiate the socket connection in the background. If it doesn't fail
    # immediately it will raise an IO::WaitWritable (Errno::EINPROGRESS)
    # indicating the connection is in progress.
    # Unlike waiting for a tcp socket to connect, you can't time out ssl socket
    # connections during the connect phase properly, because IO.select only partially works.
    # Instead, you have to retry.
    ssl_sock.connect_nonblock
  rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable
    if IO.select([ssl_sock], nil, nil, timeout)
      retry
    else
      raise TimeoutError
    end
  rescue IO::WaitWritable
    if IO.select(nil, [ssl_sock], nil, timeout)
      retry
    else
      raise TimeoutError
    end
  end
  unless ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE || (ctx.respond_to?(:verify_hostname) && !ctx.verify_hostname)
    ssl_sock.post_connection_check(host)
  end
  ssl_sock
end