Index: remoting/jingle_glue/ssl_socket_adapter.cc |
diff --git a/remoting/jingle_glue/ssl_socket_adapter.cc b/remoting/jingle_glue/ssl_socket_adapter.cc |
deleted file mode 100644 |
index 08ba7859b2c6078765033f265c627fc806ff412d..0000000000000000000000000000000000000000 |
--- a/remoting/jingle_glue/ssl_socket_adapter.cc |
+++ /dev/null |
@@ -1,467 +0,0 @@ |
-// 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 "remoting/jingle_glue/ssl_socket_adapter.h" |
- |
-#include "base/base64.h" |
-#include "base/compiler_specific.h" |
-#include "base/message_loop.h" |
-#include "jingle/glue/utils.h" |
-#include "net/base/address_list.h" |
-#include "net/base/cert_verifier.h" |
-#include "net/base/host_port_pair.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/ssl_config_service.h" |
-#include "net/base/transport_security_state.h" |
-#include "net/socket/client_socket_factory.h" |
-#include "net/url_request/url_request_context.h" |
- |
-namespace remoting { |
- |
-SSLSocketAdapter* SSLSocketAdapter::Create(AsyncSocket* socket) { |
- return new SSLSocketAdapter(socket); |
-} |
- |
-SSLSocketAdapter::SSLSocketAdapter(AsyncSocket* socket) |
- : SSLAdapter(socket), |
- ignore_bad_cert_(false), |
- cert_verifier_(net::CertVerifier::CreateDefault()), |
- transport_security_state_(new net::TransportSecurityState()), |
- ssl_state_(SSLSTATE_NONE), |
- read_pending_(false), |
- write_pending_(false) { |
- transport_socket_ = new TransportSocket(socket, this); |
-} |
- |
-SSLSocketAdapter::~SSLSocketAdapter() { |
-} |
- |
-int SSLSocketAdapter::StartSSL(const char* hostname, bool restartable) { |
- DCHECK(!restartable); |
- hostname_ = hostname; |
- |
- if (socket_->GetState() != Socket::CS_CONNECTED) { |
- ssl_state_ = SSLSTATE_WAIT; |
- return 0; |
- } else { |
- return BeginSSL(); |
- } |
-} |
- |
-int SSLSocketAdapter::BeginSSL() { |
- if (!MessageLoop::current()) { |
- // Certificate verification is done via the Chrome message loop. |
- // Without this check, if we don't have a chrome message loop the |
- // SSL connection just hangs silently. |
- LOG(DFATAL) << "Chrome message loop (needed by SSL certificate " |
- << "verification) does not exist"; |
- return net::ERR_UNEXPECTED; |
- } |
- |
- // SSLConfigService is not thread-safe, and the default values for SSLConfig |
- // are correct for us, so we don't use the config service to initialize this |
- // object. |
- net::SSLConfig ssl_config; |
- net::SSLClientSocketContext context( |
- cert_verifier_.get(), NULL, transport_security_state_.get(), ""); |
- |
- transport_socket_->set_addr(talk_base::SocketAddress(hostname_, 0)); |
- ssl_socket_.reset( |
- net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket( |
- transport_socket_, net::HostPortPair(hostname_, 443), ssl_config, |
- context)); |
- |
- int result = ssl_socket_->Connect( |
- base::Bind(&SSLSocketAdapter::OnConnected, base::Unretained(this))); |
- |
- if (result == net::ERR_IO_PENDING || result == net::OK) { |
- return 0; |
- } else { |
- LOG(ERROR) << "Could not start SSL: " << net::ErrorToString(result); |
- return result; |
- } |
-} |
- |
-int SSLSocketAdapter::Send(const void* buf, size_t len) { |
- if (ssl_state_ == SSLSTATE_ERROR) { |
- SetError(EINVAL); |
- return -1; |
- } |
- |
- if (ssl_state_ == SSLSTATE_NONE) { |
- // Propagate the call to underlying socket if SSL is not connected |
- // yet (connection is not encrypted until StartSSL() is called). |
- return AsyncSocketAdapter::Send(buf, len); |
- } |
- |
- if (write_pending_) { |
- SetError(EWOULDBLOCK); |
- return -1; |
- } |
- |
- write_buffer_ = new net::DrainableIOBuffer(new net::IOBuffer(len), len); |
- memcpy(write_buffer_->data(), buf, len); |
- |
- DoWrite(); |
- |
- return len; |
-} |
- |
-int SSLSocketAdapter::Recv(void* buf, size_t len) { |
- switch (ssl_state_) { |
- case SSLSTATE_NONE: { |
- return AsyncSocketAdapter::Recv(buf, len); |
- } |
- |
- case SSLSTATE_WAIT: { |
- SetError(EWOULDBLOCK); |
- return -1; |
- } |
- |
- case SSLSTATE_CONNECTED: { |
- if (read_pending_) { |
- SetError(EWOULDBLOCK); |
- return -1; |
- } |
- |
- int bytes_read = 0; |
- |
- // Process any data we have left from the previous read. |
- if (read_buffer_) { |
- int size = std::min(read_buffer_->RemainingCapacity(), |
- static_cast<int>(len)); |
- memcpy(buf, read_buffer_->data(), size); |
- read_buffer_->set_offset(read_buffer_->offset() + size); |
- if (!read_buffer_->RemainingCapacity()) |
- read_buffer_ = NULL; |
- |
- if (size == static_cast<int>(len)) |
- return size; |
- |
- // If we didn't fill the caller's buffer then dispatch a new |
- // Read() in case there's more data ready. |
- buf = reinterpret_cast<char*>(buf) + size; |
- len -= size; |
- bytes_read = size; |
- DCHECK(!read_buffer_); |
- } |
- |
- // Dispatch a Read() request to the SSL layer. |
- read_buffer_ = new net::GrowableIOBuffer(); |
- read_buffer_->SetCapacity(len); |
- int result = ssl_socket_->Read( |
- read_buffer_, len, |
- base::Bind(&SSLSocketAdapter::OnRead, base::Unretained(this))); |
- if (result >= 0) |
- memcpy(buf, read_buffer_->data(), len); |
- |
- if (result == net::ERR_IO_PENDING) { |
- read_pending_ = true; |
- if (bytes_read) { |
- return bytes_read; |
- } else { |
- SetError(EWOULDBLOCK); |
- return -1; |
- } |
- } |
- |
- if (result < 0) { |
- SetError(EINVAL); |
- ssl_state_ = SSLSTATE_ERROR; |
- LOG(ERROR) << "Error reading from SSL socket " << result; |
- return -1; |
- } |
- read_buffer_ = NULL; |
- return result + bytes_read; |
- } |
- |
- case SSLSTATE_ERROR: { |
- SetError(EINVAL); |
- return -1; |
- } |
- } |
- |
- NOTREACHED(); |
- return -1; |
-} |
- |
-void SSLSocketAdapter::OnConnected(int result) { |
- if (result == net::OK) { |
- ssl_state_ = SSLSTATE_CONNECTED; |
- OnConnectEvent(this); |
- } else { |
- LOG(WARNING) << "OnConnected failed with error " << result; |
- } |
-} |
- |
-void SSLSocketAdapter::OnRead(int result) { |
- DCHECK(read_pending_); |
- read_pending_ = false; |
- if (result > 0) { |
- DCHECK_GE(read_buffer_->capacity(), result); |
- read_buffer_->SetCapacity(result); |
- } else { |
- if (result < 0) |
- ssl_state_ = SSLSTATE_ERROR; |
- } |
- AsyncSocketAdapter::OnReadEvent(this); |
-} |
- |
-void SSLSocketAdapter::OnWritten(int result) { |
- DCHECK(write_pending_); |
- write_pending_ = false; |
- if (result >= 0) { |
- write_buffer_->DidConsume(result); |
- if (!write_buffer_->BytesRemaining()) { |
- write_buffer_ = NULL; |
- } else { |
- DoWrite(); |
- } |
- } else { |
- ssl_state_ = SSLSTATE_ERROR; |
- } |
- AsyncSocketAdapter::OnWriteEvent(this); |
-} |
- |
-void SSLSocketAdapter::DoWrite() { |
- DCHECK_GT(write_buffer_->BytesRemaining(), 0); |
- DCHECK(!write_pending_); |
- |
- while (true) { |
- int result = ssl_socket_->Write( |
- write_buffer_, write_buffer_->BytesRemaining(), |
- base::Bind(&SSLSocketAdapter::OnWritten, base::Unretained(this))); |
- |
- if (result > 0) { |
- write_buffer_->DidConsume(result); |
- if (!write_buffer_->BytesRemaining()) { |
- write_buffer_ = NULL; |
- return; |
- } |
- continue; |
- } |
- |
- if (result == net::ERR_IO_PENDING) { |
- write_pending_ = true; |
- } else { |
- SetError(EINVAL); |
- ssl_state_ = SSLSTATE_ERROR; |
- } |
- return; |
- } |
-} |
- |
-void SSLSocketAdapter::OnConnectEvent(talk_base::AsyncSocket* socket) { |
- if (ssl_state_ != SSLSTATE_WAIT) { |
- AsyncSocketAdapter::OnConnectEvent(socket); |
- } else { |
- ssl_state_ = SSLSTATE_NONE; |
- int result = BeginSSL(); |
- if (0 != result) { |
- // TODO(zork): Handle this case gracefully. |
- LOG(WARNING) << "BeginSSL() failed with " << result; |
- } |
- } |
-} |
- |
-TransportSocket::TransportSocket(talk_base::AsyncSocket* socket, |
- SSLSocketAdapter *ssl_adapter) |
- : read_buffer_len_(0), |
- write_buffer_len_(0), |
- socket_(socket), |
- was_used_to_convey_data_(false) { |
- socket_->SignalReadEvent.connect(this, &TransportSocket::OnReadEvent); |
- socket_->SignalWriteEvent.connect(this, &TransportSocket::OnWriteEvent); |
-} |
- |
-TransportSocket::~TransportSocket() { |
-} |
- |
-int TransportSocket::Connect(const net::CompletionCallback& callback) { |
- // Connect is never called by SSLClientSocket, instead SSLSocketAdapter |
- // calls Connect() on socket_ directly. |
- NOTREACHED(); |
- return false; |
-} |
- |
-void TransportSocket::Disconnect() { |
- socket_->Close(); |
-} |
- |
-bool TransportSocket::IsConnected() const { |
- return (socket_->GetState() == talk_base::Socket::CS_CONNECTED); |
-} |
- |
-bool TransportSocket::IsConnectedAndIdle() const { |
- // Not implemented. |
- NOTREACHED(); |
- return false; |
-} |
- |
-int TransportSocket::GetPeerAddress(net::IPEndPoint* address) const { |
- talk_base::SocketAddress socket_address = socket_->GetRemoteAddress(); |
- if (jingle_glue::SocketAddressToIPEndPoint(socket_address, address)) { |
- return net::OK; |
- } else { |
- return net::ERR_FAILED; |
- } |
-} |
- |
-int TransportSocket::GetLocalAddress(net::IPEndPoint* address) const { |
- talk_base::SocketAddress socket_address = socket_->GetLocalAddress(); |
- if (jingle_glue::SocketAddressToIPEndPoint(socket_address, address)) { |
- return net::OK; |
- } else { |
- return net::ERR_FAILED; |
- } |
-} |
- |
-const net::BoundNetLog& TransportSocket::NetLog() const { |
- return net_log_; |
-} |
- |
-void TransportSocket::SetSubresourceSpeculation() { |
- NOTREACHED(); |
-} |
- |
-void TransportSocket::SetOmniboxSpeculation() { |
- NOTREACHED(); |
-} |
- |
-bool TransportSocket::WasEverUsed() const { |
- // We don't use this in ClientSocketPools, so this should never be used. |
- NOTREACHED(); |
- return was_used_to_convey_data_; |
-} |
- |
-bool TransportSocket::UsingTCPFastOpen() const { |
- return false; |
-} |
- |
-int64 TransportSocket::NumBytesRead() const { |
- NOTREACHED(); |
- return -1; |
-} |
- |
-base::TimeDelta TransportSocket::GetConnectTimeMicros() const { |
- NOTREACHED(); |
- return base::TimeDelta::FromMicroseconds(-1); |
-} |
- |
-bool TransportSocket::WasNpnNegotiated() const { |
- NOTREACHED(); |
- return false; |
-} |
- |
-net::NextProto TransportSocket::GetNegotiatedProtocol() const { |
- NOTREACHED(); |
- return net::kProtoUnknown; |
-} |
- |
-bool TransportSocket::GetSSLInfo(net::SSLInfo* ssl_info) { |
- NOTREACHED(); |
- return false; |
-} |
- |
-int TransportSocket::Read(net::IOBuffer* buf, int buf_len, |
- const net::CompletionCallback& callback) { |
- DCHECK(buf); |
- DCHECK(read_callback_.is_null()); |
- DCHECK(!read_buffer_.get()); |
- int result = socket_->Recv(buf->data(), buf_len); |
- if (result < 0) { |
- result = net::MapSystemError(socket_->GetError()); |
- if (result == net::ERR_IO_PENDING) { |
- read_callback_ = callback; |
- read_buffer_ = buf; |
- read_buffer_len_ = buf_len; |
- } |
- } |
- if (result != net::ERR_IO_PENDING) |
- was_used_to_convey_data_ = true; |
- return result; |
-} |
- |
-int TransportSocket::Write(net::IOBuffer* buf, int buf_len, |
- const net::CompletionCallback& callback) { |
- DCHECK(buf); |
- DCHECK(write_callback_.is_null()); |
- DCHECK(!write_buffer_.get()); |
- int result = socket_->Send(buf->data(), buf_len); |
- if (result < 0) { |
- result = net::MapSystemError(socket_->GetError()); |
- if (result == net::ERR_IO_PENDING) { |
- write_callback_ = callback; |
- write_buffer_ = buf; |
- write_buffer_len_ = buf_len; |
- } |
- } |
- if (result != net::ERR_IO_PENDING) |
- was_used_to_convey_data_ = true; |
- return result; |
-} |
- |
-bool TransportSocket::SetReceiveBufferSize(int32 size) { |
- // Not implemented. |
- return false; |
-} |
- |
-bool TransportSocket::SetSendBufferSize(int32 size) { |
- // Not implemented. |
- return false; |
-} |
- |
-void TransportSocket::OnReadEvent(talk_base::AsyncSocket* socket) { |
- if (!read_callback_.is_null()) { |
- DCHECK(read_buffer_.get()); |
- net::CompletionCallback callback = read_callback_; |
- scoped_refptr<net::IOBuffer> buffer = read_buffer_; |
- int buffer_len = read_buffer_len_; |
- |
- read_callback_.Reset(); |
- read_buffer_ = NULL; |
- read_buffer_len_ = 0; |
- |
- int result = socket_->Recv(buffer->data(), buffer_len); |
- if (result < 0) { |
- result = net::MapSystemError(socket_->GetError()); |
- if (result == net::ERR_IO_PENDING) { |
- read_callback_ = callback; |
- read_buffer_ = buffer; |
- read_buffer_len_ = buffer_len; |
- return; |
- } |
- } |
- was_used_to_convey_data_ = true; |
- callback.Run(result); |
- } |
-} |
- |
-void TransportSocket::OnWriteEvent(talk_base::AsyncSocket* socket) { |
- if (!write_callback_.is_null()) { |
- DCHECK(write_buffer_.get()); |
- net::CompletionCallback callback = write_callback_; |
- scoped_refptr<net::IOBuffer> buffer = write_buffer_; |
- int buffer_len = write_buffer_len_; |
- |
- write_callback_.Reset(); |
- write_buffer_ = NULL; |
- write_buffer_len_ = 0; |
- |
- int result = socket_->Send(buffer->data(), buffer_len); |
- if (result < 0) { |
- result = net::MapSystemError(socket_->GetError()); |
- if (result == net::ERR_IO_PENDING) { |
- write_callback_ = callback; |
- write_buffer_ = buffer; |
- write_buffer_len_ = buffer_len; |
- return; |
- } |
- } |
- was_used_to_convey_data_ = true; |
- callback.Run(result); |
- } |
-} |
- |
-} // namespace remoting |