blob: 2930b4778913ae6b701c5b110668fddfcccbcd03 [file] [log] [blame]
// Copyright (c) 2011 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.
#ifndef REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_
#define REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/stream_socket.h"
#include "third_party/libjingle/source/talk/base/asyncsocket.h"
#include "third_party/libjingle/source/talk/base/ssladapter.h"
namespace net {
class CertVerifier;
} // namespace net
namespace remoting {
class SSLSocketAdapter;
// TODO(sergeyu): Write unittests for this code!
// This class provides a wrapper to libjingle's talk_base::AsyncSocket that
// implements Chromium's net::StreamSocket interface. It's used by
// SSLSocketAdapter to enable Chromium's SSL implementation to work over
// libjingle's socket class.
class TransportSocket : public net::StreamSocket, public sigslot::has_slots<> {
public:
TransportSocket(talk_base::AsyncSocket* socket,
SSLSocketAdapter *ssl_adapter);
virtual ~TransportSocket();
void set_addr(const talk_base::SocketAddress& addr) {
addr_ = addr;
}
// net::StreamSocket implementation
virtual int Connect(net::OldCompletionCallback* callback);
virtual void Disconnect();
virtual bool IsConnected() const;
virtual bool IsConnectedAndIdle() const;
virtual int GetPeerAddress(net::AddressList* address) const;
virtual int GetLocalAddress(net::IPEndPoint* address) const;
virtual const net::BoundNetLog& NetLog() const;
virtual void SetSubresourceSpeculation();
virtual void SetOmniboxSpeculation();
virtual bool WasEverUsed() const;
virtual bool UsingTCPFastOpen() const;
virtual int64 NumBytesRead() const;
virtual base::TimeDelta GetConnectTimeMicros() const;
// net::Socket implementation
virtual int Read(net::IOBuffer* buf, int buf_len,
net::OldCompletionCallback* callback);
virtual int Write(net::IOBuffer* buf, int buf_len,
net::OldCompletionCallback* callback);
virtual bool SetReceiveBufferSize(int32 size);
virtual bool SetSendBufferSize(int32 size);
private:
friend class SSLSocketAdapter;
void OnReadEvent(talk_base::AsyncSocket* socket);
void OnWriteEvent(talk_base::AsyncSocket* socket);
net::OldCompletionCallback* read_callback_;
net::OldCompletionCallback* write_callback_;
scoped_refptr<net::IOBuffer> read_buffer_;
int read_buffer_len_;
scoped_refptr<net::IOBuffer> write_buffer_;
int write_buffer_len_;
net::BoundNetLog net_log_;
talk_base::AsyncSocket *socket_;
talk_base::SocketAddress addr_;
bool was_used_to_convey_data_;
DISALLOW_COPY_AND_ASSIGN(TransportSocket);
};
// This provides a talk_base::AsyncSocketAdapter interface around Chromium's
// net::SSLClientSocket class. This allows remoting to use Chromium's SSL
// implementation instead of OpenSSL.
class SSLSocketAdapter : public talk_base::SSLAdapter {
public:
explicit SSLSocketAdapter(talk_base::AsyncSocket* socket);
virtual ~SSLSocketAdapter();
// StartSSL returns 0 if successful, or non-zero on failure.
// If StartSSL is called while the socket is closed or connecting, the SSL
// negotiation will begin as soon as the socket connects.
//
// restartable is not implemented, and must be set to false.
virtual int StartSSL(const char* hostname, bool restartable);
// Create the default SSL adapter for this platform.
static SSLSocketAdapter* Create(AsyncSocket* socket);
virtual int Send(const void* pv, size_t cb);
virtual int Recv(void* pv, size_t cb);
private:
friend class TransportSocket;
enum SSLState {
SSLSTATE_NONE,
SSLSTATE_WAIT,
SSLSTATE_CONNECTED,
};
enum IOState {
IOSTATE_NONE,
IOSTATE_PENDING,
IOSTATE_COMPLETE,
};
void OnConnected(int result);
void OnRead(int result);
void OnWrite(int result);
virtual void OnConnectEvent(talk_base::AsyncSocket* socket);
int BeginSSL();
bool ignore_bad_cert_;
std::string hostname_;
TransportSocket* transport_socket_;
// |cert_verifier_| must be defined before |ssl_socket_|, so that
// it's destroyed after |ssl_socket_|.
scoped_ptr<net::CertVerifier> cert_verifier_;
scoped_ptr<net::SSLClientSocket> ssl_socket_;
net::OldCompletionCallbackImpl<SSLSocketAdapter> connected_callback_;
net::OldCompletionCallbackImpl<SSLSocketAdapter> read_callback_;
net::OldCompletionCallbackImpl<SSLSocketAdapter> write_callback_;
SSLState ssl_state_;
IOState read_state_;
IOState write_state_;
scoped_refptr<net::IOBuffer> transport_buf_;
int data_transferred_;
DISALLOW_COPY_AND_ASSIGN(SSLSocketAdapter);
};
} // namespace remoting
#endif // REMOTING_JINGLE_GLUE_SSL_SOCKET_ADAPTER_H_