diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-10 16:53:42 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-10 16:53:42 +0000 |
commit | ba62fbd428232eee1815d4b4d63fc65cb3ead566 (patch) | |
tree | 56d05f663fe81afc7c7f6c232d1f650994bbe8ed /remoting | |
parent | a538b1cdbd69c307ef672b5176c8ac9039981c41 (diff) | |
download | chromium_src-ba62fbd428232eee1815d4b4d63fc65cb3ead566.zip chromium_src-ba62fbd428232eee1815d4b4d63fc65cb3ead566.tar.gz chromium_src-ba62fbd428232eee1815d4b4d63fc65cb3ead566.tar.bz2 |
Revert r59012 which started using Chrome sockets for sync.
This caused us to write to ChromeNetLog from the sync thread. ChromeNetLog is not thread safe, so this causes problems.
BUG=55116,54146
TEST=Start up chrome. Does not repeatedly hit DCHECKs on ChromeNetLog::AddEntry().
Review URL: http://codereview.chromium.org/3358028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59104 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/DEPS | 1 | ||||
-rw-r--r-- | remoting/jingle_glue/jingle_client.cc | 4 | ||||
-rw-r--r-- | remoting/jingle_glue/ssl_adapter.cc | 27 | ||||
-rw-r--r-- | remoting/jingle_glue/ssl_adapter.h | 33 | ||||
-rw-r--r-- | remoting/jingle_glue/ssl_socket_adapter.cc | 386 | ||||
-rw-r--r-- | remoting/jingle_glue/ssl_socket_adapter.h | 145 | ||||
-rw-r--r-- | remoting/jingle_glue/xmpp_socket_adapter.cc | 428 | ||||
-rw-r--r-- | remoting/jingle_glue/xmpp_socket_adapter.h | 87 | ||||
-rw-r--r-- | remoting/remoting.gyp | 6 |
9 files changed, 2 insertions, 1115 deletions
diff --git a/remoting/DEPS b/remoting/DEPS index 6bfe57b..4370b43 100644 --- a/remoting/DEPS +++ b/remoting/DEPS @@ -3,7 +3,6 @@ include_rules = [ "+gfx", "+google/protobuf", "+media/base", - "+net", "+jingle", diff --git a/remoting/jingle_glue/jingle_client.cc b/remoting/jingle_glue/jingle_client.cc index d3ca67e..01e607b 100644 --- a/remoting/jingle_glue/jingle_client.cc +++ b/remoting/jingle_glue/jingle_client.cc @@ -7,10 +7,10 @@ #include "base/logging.h" #include "base/message_loop.h" #include "jingle/notifier/communicator/gaia_token_pre_xmpp_auth.h" +#include "jingle/notifier/communicator/xmpp_socket_adapter.h" #include "remoting/jingle_glue/iq_request.h" #include "remoting/jingle_glue/jingle_thread.h" #include "remoting/jingle_glue/relay_port_allocator.h" -#include "remoting/jingle_glue/xmpp_socket_adapter.h" #include "third_party/libjingle/source/talk/base/asyncsocket.h" #include "third_party/libjingle/source/talk/base/ssladapter.h" #include "third_party/libjingle/source/talk/p2p/base/sessionmanager.h" @@ -94,7 +94,7 @@ void JingleClient::DoInitialize(const std::string& username, client_->SignalStateChange.connect( this, &JingleClient::OnConnectionStateChanged); - buzz::AsyncSocket* socket = new XmppSocketAdapter(settings, false); + buzz::AsyncSocket* socket = new notifier::XmppSocketAdapter(settings, false); client_->Connect(settings, "", socket, CreatePreXmppAuth(settings)); client_->Start(); diff --git a/remoting/jingle_glue/ssl_adapter.cc b/remoting/jingle_glue/ssl_adapter.cc deleted file mode 100644 index 68d350c..0000000 --- a/remoting/jingle_glue/ssl_adapter.cc +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2009 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_adapter.h" - -#if defined(OS_WIN) -#include "talk/base/ssladapter.h" -#else -#include "remoting/jingle_glue/ssl_socket_adapter.h" -#endif - -namespace remoting { - -talk_base::SSLAdapter* CreateSSLAdapter(talk_base::AsyncSocket* socket) { - talk_base::SSLAdapter* ssl_adapter = -#if defined(OS_WIN) - talk_base::SSLAdapter::Create(socket); -#else - remoting::SSLSocketAdapter::Create(socket); -#endif - DCHECK(ssl_adapter); - return ssl_adapter; -} - -} // namespace remoting - diff --git a/remoting/jingle_glue/ssl_adapter.h b/remoting/jingle_glue/ssl_adapter.h deleted file mode 100644 index 56b03be..0000000 --- a/remoting/jingle_glue/ssl_adapter.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2009 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_ADAPTER_H_ -#define REMOTING_JINGLE_GLUE_SSL_ADAPTER_H_ - -namespace talk_base { -class AsyncSocket; -class SSLAdapter; -} // namespace talk_base - -namespace remoting { - -// Wraps the given socket in a platform-dependent SSLAdapter -// implementation. -talk_base::SSLAdapter* CreateSSLAdapter(talk_base::AsyncSocket* socket); - -// Utility template class that overrides CreateSSLAdapter() to use the -// above function. -template <class SocketFactory> -class SSLAdapterSocketFactory : public SocketFactory { - public: - virtual talk_base::SSLAdapter* CreateSSLAdapter( - talk_base::AsyncSocket* socket) { - return ::remoting::CreateSSLAdapter(socket); - } -}; - -} // namespace remoting - -#endif // REMOTING_JINGLE_GLUE_SSL_ADAPTER_H_ - diff --git a/remoting/jingle_glue/ssl_socket_adapter.cc b/remoting/jingle_glue/ssl_socket_adapter.cc deleted file mode 100644 index 3ea404b..0000000 --- a/remoting/jingle_glue/ssl_socket_adapter.cc +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright (c) 2010 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/compiler_specific.h" -#include "base/message_loop.h" -#include "net/base/address_list.h" -#include "net/base/net_errors.h" -#include "net/base/ssl_config_service.h" -#include "net/base/sys_addrinfo.h" -#include "net/socket/client_socket_factory.h" -#include "net/url_request/url_request_context.h" - -namespace remoting { - -namespace { - -// Convert values from <errno.h> to values from "net/base/net_errors.h" -int MapPosixError(int err) { - // There are numerous posix error codes, but these are the ones we thus far - // find interesting. - switch (err) { - case EAGAIN: -#if EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: -#endif - return net::ERR_IO_PENDING; - case ENETDOWN: - return net::ERR_INTERNET_DISCONNECTED; - case ETIMEDOUT: - return net::ERR_TIMED_OUT; - case ECONNRESET: - case ENETRESET: // Related to keep-alive - return net::ERR_CONNECTION_RESET; - case ECONNABORTED: - return net::ERR_CONNECTION_ABORTED; - case ECONNREFUSED: - return net::ERR_CONNECTION_REFUSED; - case EHOSTUNREACH: - case ENETUNREACH: - return net::ERR_ADDRESS_UNREACHABLE; - case EADDRNOTAVAIL: - return net::ERR_ADDRESS_INVALID; - case 0: - return net::OK; - default: - LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; - return net::ERR_FAILED; - } -} - -} // namespace - -SSLSocketAdapter* SSLSocketAdapter::Create(AsyncSocket* socket) { - return new SSLSocketAdapter(socket); -} - -SSLSocketAdapter::SSLSocketAdapter(AsyncSocket* socket) - : SSLAdapter(socket), - ignore_bad_cert_(false), - ALLOW_THIS_IN_INITIALIZER_LIST( - connected_callback_(this, &SSLSocketAdapter::OnConnected)), - ALLOW_THIS_IN_INITIALIZER_LIST( - read_callback_(this, &SSLSocketAdapter::OnRead)), - ALLOW_THIS_IN_INITIALIZER_LIST( - write_callback_(this, &SSLSocketAdapter::OnWrite)), - ssl_state_(SSLSTATE_NONE), - read_state_(IOSTATE_NONE), - write_state_(IOSTATE_NONE) { - 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; - transport_socket_->set_addr(talk_base::SocketAddress(hostname_, 0)); - ssl_socket_.reset( - net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket( - transport_socket_, hostname_.c_str(), ssl_config)); - - int result = ssl_socket_->Connect(&connected_callback_); - - 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_CONNECTED) { - return AsyncSocketAdapter::Send(buf, len); - } else { - scoped_refptr<net::IOBuffer> transport_buf = new net::IOBuffer(len); - memcpy(transport_buf->data(), buf, len); - - int result = ssl_socket_->Write(transport_buf, len, NULL); - if (result == net::ERR_IO_PENDING) { - SetError(EWOULDBLOCK); - } - transport_buf = NULL; - return result; - } -} - -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: - switch (read_state_) { - case IOSTATE_NONE: { - transport_buf_ = new net::IOBuffer(len); - int result = ssl_socket_->Read(transport_buf_, len, &read_callback_); - if (result >= 0) { - memcpy(buf, transport_buf_->data(), len); - } - - if (result == net::ERR_IO_PENDING) { - read_state_ = IOSTATE_PENDING; - SetError(EWOULDBLOCK); - } else { - if (result < 0) { - SetError(result); - LOG(INFO) << "Socket error " << result; - } - transport_buf_ = NULL; - } - return result; - } - case IOSTATE_PENDING: - SetError(EWOULDBLOCK); - return -1; - - case IOSTATE_COMPLETE: - memcpy(buf, transport_buf_->data(), len); - transport_buf_ = NULL; - read_state_ = IOSTATE_NONE; - return data_transferred_; - } - } - - 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_state_ == IOSTATE_PENDING); - read_state_ = IOSTATE_COMPLETE; - data_transferred_ = result; - AsyncSocketAdapter::OnReadEvent(this); -} - -void SSLSocketAdapter::OnWrite(int result) { - DCHECK(write_state_ == IOSTATE_PENDING); - write_state_ = IOSTATE_COMPLETE; - data_transferred_ = result; - AsyncSocketAdapter::OnWriteEvent(this); -} - -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_callback_(NULL), - write_callback_(NULL), - 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(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::AddressList* address) const { - talk_base::SocketAddress socket_address = socket_->GetRemoteAddress(); - - // libjingle supports only IPv4 addresses. - sockaddr_in ipv4addr; - socket_address.ToSockAddr(&ipv4addr); - - struct addrinfo ai; - memset(&ai, 0, sizeof(ai)); - ai.ai_family = ipv4addr.sin_family; - ai.ai_socktype = SOCK_STREAM; - ai.ai_protocol = IPPROTO_TCP; - ai.ai_addr = reinterpret_cast<struct sockaddr*>(&ipv4addr); - ai.ai_addrlen = sizeof(ipv4addr); - - address->Copy(&ai, false); - return net::OK; -} - -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_; -} - -int TransportSocket::Read(net::IOBuffer* buf, int buf_len, - net::CompletionCallback* callback) { - DCHECK(buf); - DCHECK(!read_callback_); - DCHECK(!read_buffer_.get()); - int result = socket_->Recv(buf->data(), buf_len); - if (result < 0) { - result = MapPosixError(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, - net::CompletionCallback* callback) { - DCHECK(buf); - DCHECK(!write_callback_); - DCHECK(!write_buffer_.get()); - int result = socket_->Send(buf->data(), buf_len); - if (result < 0) { - result = MapPosixError(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_) { - DCHECK(read_buffer_.get()); - net::CompletionCallback* callback = read_callback_; - scoped_refptr<net::IOBuffer> buffer = read_buffer_; - int buffer_len = read_buffer_len_; - - read_callback_ = NULL; - read_buffer_ = NULL; - read_buffer_len_ = 0; - - int result = socket_->Recv(buffer->data(), buffer_len); - if (result < 0) { - result = MapPosixError(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->RunWithParams(Tuple1<int>(result)); - } -} - -void TransportSocket::OnWriteEvent(talk_base::AsyncSocket* socket) { - if (write_callback_) { - DCHECK(write_buffer_.get()); - net::CompletionCallback* callback = write_callback_; - scoped_refptr<net::IOBuffer> buffer = write_buffer_; - int buffer_len = write_buffer_len_; - - write_callback_ = NULL; - write_buffer_ = NULL; - write_buffer_len_ = 0; - - int result = socket_->Send(buffer->data(), buffer_len); - if (result < 0) { - result = MapPosixError(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->RunWithParams(Tuple1<int>(result)); - } -} - -} // namespace remoting diff --git a/remoting/jingle_glue/ssl_socket_adapter.h b/remoting/jingle_glue/ssl_socket_adapter.h deleted file mode 100644 index a22e2b7..0000000 --- a/remoting/jingle_glue/ssl_socket_adapter.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2010 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/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/client_socket.h" -#include "net/socket/ssl_client_socket.h" -#include "talk/base/asyncsocket.h" -#include "talk/base/ssladapter.h" - -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::ClientSocket interface. It's used by -// SSLSocketAdapter to enable Chromium's SSL implementation to work over -// libjingle's socket class. -class TransportSocket : public net::ClientSocket, public sigslot::has_slots<> { - public: - TransportSocket(talk_base::AsyncSocket* socket, - SSLSocketAdapter *ssl_adapter); - ~TransportSocket(); - - void set_addr(const talk_base::SocketAddress& addr) { - addr_ = addr; - } - - // net::ClientSocket implementation - - virtual int Connect(net::CompletionCallback* callback); - virtual void Disconnect(); - virtual bool IsConnected() const; - virtual bool IsConnectedAndIdle() const; - virtual int GetPeerAddress(net::AddressList* address) const; - virtual const net::BoundNetLog& NetLog() const { return net_log_; } - virtual void SetSubresourceSpeculation(); - virtual void SetOmniboxSpeculation(); - virtual bool WasEverUsed() const; - - // net::Socket implementation - - virtual int Read(net::IOBuffer* buf, int buf_len, - net::CompletionCallback* callback); - virtual int Write(net::IOBuffer* buf, int buf_len, - net::CompletionCallback* 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::CompletionCallback* read_callback_; - net::CompletionCallback* 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); - ~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_; - scoped_ptr<net::SSLClientSocket> ssl_socket_; - net::CompletionCallbackImpl<SSLSocketAdapter> connected_callback_; - net::CompletionCallbackImpl<SSLSocketAdapter> read_callback_; - net::CompletionCallbackImpl<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_ diff --git a/remoting/jingle_glue/xmpp_socket_adapter.cc b/remoting/jingle_glue/xmpp_socket_adapter.cc deleted file mode 100644 index 08f72aa..0000000 --- a/remoting/jingle_glue/xmpp_socket_adapter.cc +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright (c) 2009 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/xmpp_socket_adapter.h" - -#include <iomanip> -#include <string> - -#include "base/logging.h" -#include "remoting/jingle_glue/ssl_adapter.h" -#include "talk/base/byteorder.h" -#include "talk/base/common.h" -#include "talk/base/firewallsocketserver.h" -#include "talk/base/logging.h" -#include "talk/base/socketadapters.h" -#include "talk/base/ssladapter.h" -#include "talk/base/thread.h" -#include "talk/xmpp/xmppengine.h" - -namespace remoting { - -XmppSocketAdapter::XmppSocketAdapter(const buzz::XmppClientSettings& xcs, - bool allow_unverified_certs) - : state_(STATE_CLOSED), - error_(ERROR_NONE), - wsa_error_(0), - socket_(NULL), - protocol_(xcs.protocol()), - firewall_(false), - write_buffer_(NULL), - write_buffer_length_(0), - write_buffer_capacity_(0), - allow_unverified_certs_(allow_unverified_certs) { - proxy_.type = xcs.proxy(); - proxy_.address.SetIP(xcs.proxy_host()); - proxy_.address.SetPort(xcs.proxy_port()); - proxy_.username = xcs.proxy_user(); - proxy_.password = xcs.proxy_pass(); -} - -XmppSocketAdapter::~XmppSocketAdapter() { - FreeState(); - - // Clean up any previous socket - cannot delete socket on close because close - // happens during the child socket's stack callback. - if (socket_) { - delete socket_; - socket_ = NULL; - } -} - -bool XmppSocketAdapter::FreeState() { - int code = 0; - - // Clean up the socket. - if (socket_ && !(state_ == STATE_CLOSED || state_ == STATE_CLOSING)) { - code = socket_->Close(); - } - - delete[] write_buffer_; - write_buffer_ = NULL; - write_buffer_length_ = 0; - write_buffer_capacity_ = 0; - - if (code) { - SetWSAError(code); - return false; - } - return true; -} - -bool XmppSocketAdapter::Connect(const talk_base::SocketAddress& addr) { - if (state_ != STATE_CLOSED) { - SetError(ERROR_WRONGSTATE); - return false; - } - - LOG(INFO) << "XmppSocketAdapter::Connect(" << addr.ToString() << ")"; - - // Clean up any previous socket - cannot delete socket on close because close - // happens during the child socket's stack callback. - if (socket_) { - delete socket_; - socket_ = NULL; - } - - talk_base::AsyncSocket* socket = - talk_base::Thread::Current()->socketserver()->CreateAsyncSocket( - SOCK_STREAM); - if (!socket) { - SetWSAError(WSA_NOT_ENOUGH_MEMORY); - return false; - } - - if (firewall_) { - // TODO(sync): Change this to make WSAAsyncSockets support current thread - // socket server. - talk_base::FirewallSocketServer* fw = - static_cast<talk_base::FirewallSocketServer*>( - talk_base::Thread::Current()->socketserver()); - socket = fw->WrapSocket(socket, SOCK_STREAM); - } - - if (proxy_.type) { - talk_base::AsyncSocket* proxy_socket = 0; - if (proxy_.type == talk_base::PROXY_SOCKS5) { - proxy_socket = new talk_base::AsyncSocksProxySocket( - socket, proxy_.address, proxy_.username, proxy_.password); - } else { - // Note: we are trying unknown proxies as HTTPS currently. - proxy_socket = new talk_base::AsyncHttpsProxySocket(socket, - "chromoting", proxy_.address, proxy_.username, - proxy_.password); - } - if (!proxy_socket) { - SetWSAError(WSA_NOT_ENOUGH_MEMORY); - delete socket; - return false; - } - socket = proxy_socket; // For our purposes the proxy is now the socket. - } - - if (protocol_ == cricket::PROTO_SSLTCP) { - talk_base::AsyncSocket *fake_ssl_socket = - new talk_base::AsyncSSLSocket(socket); - if (!fake_ssl_socket) { - SetWSAError(WSA_NOT_ENOUGH_MEMORY); - delete socket; - return false; - } - socket = fake_ssl_socket; // For our purposes the SSL socket is the socket. - } - -#if defined(FEATURE_ENABLE_SSL) - talk_base::SSLAdapter* ssl_adapter = remoting::CreateSSLAdapter(socket); - socket = ssl_adapter; // For our purposes the SSL adapter is the socket. -#endif - - socket->SignalReadEvent.connect(this, &XmppSocketAdapter::OnReadEvent); - socket->SignalWriteEvent.connect(this, &XmppSocketAdapter::OnWriteEvent); - socket->SignalConnectEvent.connect(this, &XmppSocketAdapter::OnConnectEvent); - socket->SignalCloseEvent.connect(this, &XmppSocketAdapter::OnCloseEvent); - - // The linux implementation of socket::Connect returns an error when the - // connect didn't complete yet. This can be distinguished from a failure - // because socket::IsBlocking is true. Perhaps, the linux implementation - // should be made to behave like the windows version which doesn't do this, - // but it seems to be a pattern with these methods that they return an error - // if the operation didn't complete in a sync fashion and one has to check - // IsBlocking to tell if was a "real" error. - if (socket->Connect(addr) == SOCKET_ERROR && !socket->IsBlocking()) { - SetWSAError(socket->GetError()); - delete socket; - return false; - } - - socket_ = socket; - state_ = STATE_CONNECTING; - return true; -} - -bool XmppSocketAdapter::Read(char* data, size_t len, size_t* len_read) { - if (len_read) - *len_read = 0; - - if (state_ <= STATE_CLOSING) { - SetError(ERROR_WRONGSTATE); - return false; - } - - DCHECK(socket_); - - if (IsOpen()) { - int result = socket_->Recv(data, len); - if (result < 0) { - if (!socket_->IsBlocking()) { - SetWSAError(socket_->GetError()); - return false; - } - - result = 0; - } - - if (len_read) - *len_read = result; - } - - return true; -} - -bool XmppSocketAdapter::Write(const char* data, size_t len) { - if (state_ <= STATE_CLOSING) { - // There may be data in a buffer that gets lost. Too bad! - SetError(ERROR_WRONGSTATE); - return false; - } - - DCHECK(socket_); - - size_t sent = 0; - - // Try an immediate write when there is no buffer and we aren't in SSL mode - // or opening the connection. - if (write_buffer_length_ == 0 && IsOpen()) { - int result = socket_->Send(data, len); - if (result < 0) { - if (!socket_->IsBlocking()) { - SetWSAError(socket_->GetError()); - return false; - } - result = 0; - } - - sent = static_cast<size_t>(result); - } - - // Buffer what we didn't send. - if (sent < len) { - QueueWriteData(data + sent, len - sent); - } - - // Service the socket right away to push the written data out in SSL mode. - return HandleWritable(); -} - -bool XmppSocketAdapter::Close() { - if (state_ == STATE_CLOSING) { - return false; // Avoid recursion, but not unexpected. - } - if (state_ == STATE_CLOSED) { - // In theory should not be trying to re-InternalClose. - SetError(ERROR_WRONGSTATE); - return false; - } - - // TODO(sync): deal with flushing close (flush, don't do reads, clean ssl). - - // If we've gotten to the point where we really do have a socket underneath - // then close it. It should call us back to tell us it is closed, and - // NotifyClose will be called. We indicate "closing" state so that we - // do not recusively try to keep closing the socket. - if (socket_) { - state_ = STATE_CLOSING; - socket_->Close(); - } - - // If we didn't get the callback, then we better make sure we signal - // closed. - if (state_ != STATE_CLOSED) { - // The socket was closed manually, not directly due to error. - if (error_ != ERROR_NONE) { - LOG(INFO) << "XmppSocketAdapter::Close - previous Error: " << error_ - << " WSAError: " << wsa_error_; - error_ = ERROR_NONE; - wsa_error_ = 0; - } - NotifyClose(); - } - return true; -} - -void XmppSocketAdapter::NotifyClose() { - if (state_ == STATE_CLOSED) { - SetError(ERROR_WRONGSTATE); - } else { - LOG(INFO) << "XmppSocketAdapter::NotifyClose - Error: " << error_ - << " WSAError: " << wsa_error_; - state_ = STATE_CLOSED; - SignalClosed(); - FreeState(); - } -} - -void XmppSocketAdapter::OnConnectEvent(talk_base::AsyncSocket *socket) { - if (state_ == STATE_CONNECTING) { - state_ = STATE_OPEN; - LOG(INFO) << "XmppSocketAdapter::OnConnectEvent - STATE_OPEN"; - SignalConnected(); -#if defined(FEATURE_ENABLE_SSL) - } else if (state_ == STATE_TLS_CONNECTING) { - state_ = STATE_TLS_OPEN; - LOG(INFO) << "XmppSocketAdapter::OnConnectEvent - STATE_TLS_OPEN"; - SignalSSLConnected(); - if (write_buffer_length_ > 0) { - HandleWritable(); - } -#endif // defined(FEATURE_ENABLE_SSL) - } else { - LOG(DFATAL) << "unexpected XmppSocketAdapter::OnConnectEvent state: " - << state_; - } -} - -void XmppSocketAdapter::OnReadEvent(talk_base::AsyncSocket *socket) { - HandleReadable(); -} - -void XmppSocketAdapter::OnWriteEvent(talk_base::AsyncSocket *socket) { - HandleWritable(); -} - -void XmppSocketAdapter::OnCloseEvent(talk_base::AsyncSocket *socket, - int error) { - LOG(INFO) << "XmppSocketAdapter::OnCloseEvent(" << error << ")"; - SetWSAError(error); - if (error == SOCKET_EACCES) { - SignalAuthenticationError(); // Proxy needs authentication. - } - NotifyClose(); -} - -#if defined(FEATURE_ENABLE_SSL) -bool XmppSocketAdapter::StartTls(const std::string& verify_host_name) { - if (state_ != STATE_OPEN) { - SetError(ERROR_WRONGSTATE); - return false; - } - - state_ = STATE_TLS_CONNECTING; - - DCHECK_EQ(write_buffer_length_, 0U); - - talk_base::SSLAdapter* ssl_adapter = - static_cast<talk_base::SSLAdapter*>(socket_); - - if (allow_unverified_certs_) { - ssl_adapter->set_ignore_bad_cert(true); - } - - if (ssl_adapter->StartSSL(verify_host_name.c_str(), false) != 0) { - state_ = STATE_OPEN; - SetError(ERROR_SSL); - return false; - } - - return true; -} -#endif // defined(FEATURE_ENABLE_SSL) - -void XmppSocketAdapter::QueueWriteData(const char* data, size_t len) { - // Expand buffer if needed. - if (write_buffer_length_ + len > write_buffer_capacity_) { - size_t new_capacity = 1024; - while (new_capacity < write_buffer_length_ + len) { - new_capacity = new_capacity * 2; - } - char* new_buffer = new char[new_capacity]; - DCHECK_LE(write_buffer_length_, 64000U); - memcpy(new_buffer, write_buffer_, write_buffer_length_); - delete[] write_buffer_; - write_buffer_ = new_buffer; - write_buffer_capacity_ = new_capacity; - } - - // Copy data into the end of buffer. - memcpy(write_buffer_ + write_buffer_length_, data, len); - write_buffer_length_ += len; -} - -void XmppSocketAdapter::FlushWriteQueue(Error* error, int* wsa_error) { - DCHECK(error); - DCHECK(wsa_error); - - size_t flushed = 0; - while (flushed < write_buffer_length_) { - int sent = socket_->Send(write_buffer_ + flushed, - static_cast<int>(write_buffer_length_ - flushed)); - if (sent < 0) { - if (!socket_->IsBlocking()) { - *error = ERROR_WINSOCK; - *wsa_error = socket_->GetError(); - } - break; - } - flushed += static_cast<size_t>(sent); - } - - // Remove flushed memory. - write_buffer_length_ -= flushed; - memmove(write_buffer_, write_buffer_ + flushed, write_buffer_length_); - - // When everything is flushed, deallocate the buffer if it's gotten big. - if (write_buffer_length_ == 0) { - if (write_buffer_capacity_ > 8192) { - delete[] write_buffer_; - write_buffer_ = NULL; - write_buffer_capacity_ = 0; - } - } -} - -void XmppSocketAdapter::SetError(Error error) { - if (error_ == ERROR_NONE) { - error_ = error; - } -} - -void XmppSocketAdapter::SetWSAError(int error) { - if (error_ == ERROR_NONE && error != 0) { - error_ = ERROR_WINSOCK; - wsa_error_ = error; - } -} - -bool XmppSocketAdapter::HandleReadable() { - if (!IsOpen()) - return false; - - SignalRead(); - return true; -} - -bool XmppSocketAdapter::HandleWritable() { - if (!IsOpen()) - return false; - - Error error = ERROR_NONE; - int wsa_error = 0; - FlushWriteQueue(&error, &wsa_error); - if (error != ERROR_NONE) { - Close(); - return false; - } - return true; -} - -} // namespace remoting diff --git a/remoting/jingle_glue/xmpp_socket_adapter.h b/remoting/jingle_glue/xmpp_socket_adapter.h deleted file mode 100644 index d1a6f65..0000000 --- a/remoting/jingle_glue/xmpp_socket_adapter.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2009 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_XMPP_SOCKET_ADAPTER_H_ -#define REMOTING_JINGLE_GLUE_XMPP_SOCKET_ADAPTER_H_ - -#include <string> - -#include "talk/base/asyncsocket.h" -#include "talk/xmpp/asyncsocket.h" -#include "talk/xmpp/xmppclientsettings.h" -#include "talk/xmpp/xmppengine.h" - -#ifndef _WIN32 -// Additional errors used by us from Win32 headers. -#define SEC_E_CERT_EXPIRED static_cast<int>(0x80090328L) -#define WSA_NOT_ENOUGH_MEMORY ENOMEM -#endif - -namespace remoting { - -class XmppSocketAdapter : public buzz::AsyncSocket, - public sigslot::has_slots<> { - public: - XmppSocketAdapter(const buzz::XmppClientSettings& xcs, - bool allow_unverified_certs); - virtual ~XmppSocketAdapter(); - - virtual State state() { return state_; } - virtual Error error() { return error_; } - virtual int GetError() { return wsa_error_; } - - void set_firewall(bool firewall) { firewall_ = firewall; } - - virtual bool Connect(const talk_base::SocketAddress& addr); - virtual bool Read(char* data, size_t len, size_t* len_read); - virtual bool Write(const char* data, size_t len); - virtual bool Close(); - -#if defined(FEATURE_ENABLE_SSL) - bool StartTls(const std::string& domainname); - bool IsOpen() const { return state_ == STATE_OPEN - || state_ == STATE_TLS_OPEN; } -#else - bool IsOpen() const { return state_ == STATE_OPEN; } -#endif - - sigslot::signal0<> SignalAuthenticationError; - - private: - // Return false if the socket is closed. - bool HandleReadable(); - bool HandleWritable(); - - State state_; - Error error_; - int wsa_error_; - - talk_base::AsyncSocket* socket_; - cricket::ProtocolType protocol_; - talk_base::ProxyInfo proxy_; - bool firewall_; - char* write_buffer_; - size_t write_buffer_length_; - size_t write_buffer_capacity_; - bool allow_unverified_certs_; - - bool FreeState(); - void NotifyClose(); - - void OnReadEvent(talk_base::AsyncSocket* socket); - void OnWriteEvent(talk_base::AsyncSocket* socket); - void OnConnectEvent(talk_base::AsyncSocket* socket); - void OnCloseEvent(talk_base::AsyncSocket* socket, int error); - - void QueueWriteData(const char* data, size_t len); - void FlushWriteQueue(Error* error, int* wsa_error); - - void SetError(Error error); - void SetWSAError(int error); - DISALLOW_COPY_AND_ASSIGN(XmppSocketAdapter); -}; - -} // namespace remoting - -#endif // REMOTING_JINGLE_GLUE_XMPP_SOCKET_ADAPTER_H_ diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index b0c52e2..71b81d0 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -316,12 +316,6 @@ 'jingle_glue/jingle_thread.h', 'jingle_glue/relay_port_allocator.cc', 'jingle_glue/relay_port_allocator.h', - 'jingle_glue/ssl_adapter.h', - 'jingle_glue/ssl_adapter.cc', - 'jingle_glue/ssl_socket_adapter.cc', - 'jingle_glue/ssl_socket_adapter.h', - 'jingle_glue/xmpp_socket_adapter.cc', - 'jingle_glue/xmpp_socket_adapter.h', ], }, # end of target 'chromoting_jingle_glue' |