Index: chrome/browser/sync/tools/chrome_async_socket.h |
diff --git a/chrome/browser/sync/tools/chrome_async_socket.h b/chrome/browser/sync/tools/chrome_async_socket.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..63e1c3b336ab3eab660e6175f51df9b8db31e517 |
--- /dev/null |
+++ b/chrome/browser/sync/tools/chrome_async_socket.h |
@@ -0,0 +1,226 @@ |
+// 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. |
+// |
+// An implementation of buzz::AsyncSocket that uses Chrome sockets. |
+ |
+#ifndef CHROME_BROWSER_SYNC_TOOLS_CHROME_ASYNC_SOCKET_H_ |
+#define CHROME_BROWSER_SYNC_TOOLS_CHROME_ASYNC_SOCKET_H_ |
+ |
+#if !defined(FEATURE_ENABLE_SSL) |
+#error ChromeAsyncSocket expects FEATURE_ENABLE_SSL to be defined |
+#endif |
+ |
+#include <string> |
+#include <vector> |
+ |
+#include "base/basictypes.h" |
+#include "base/ref_counted.h" |
+#include "base/scoped_ptr.h" |
+#include "base/task.h" |
+#include "net/base/completion_callback.h" |
+#include "net/base/net_errors.h" |
+#include "net/base/net_log.h" |
+#include "net/base/ssl_config_service.h" |
+#include "talk/xmpp/asyncsocket.h" |
+ |
+namespace net { |
+class ClientSocket; |
+class ClientSocketFactory; |
+class IOBufferWithSize; |
+} // namespace net |
+ |
+namespace sync_tools { |
+ |
+class ChromeAsyncSocket : public buzz::AsyncSocket { |
+ public: |
+ // Does not take ownership of |client_socket_factory| or |net_log|. |
+ // |net_log| may be NULL. |
+ ChromeAsyncSocket(net::ClientSocketFactory* client_socket_factory, |
+ const net::SSLConfig& ssl_config, |
+ size_t read_buf_size, |
+ size_t write_buf_size, |
+ net::NetLog* net_log); |
+ |
+ // Does not raise any signals. |
+ virtual ~ChromeAsyncSocket(); |
+ |
+ // buzz::AsyncSocket implementation. |
+ |
+ // The current state (see buzz::AsyncSocket::State; all but |
+ // STATE_CLOSING is used). |
+ virtual State state(); |
+ |
+ // The last generated error. Errors are generated when the main |
+ // functions below return false or when SignalClosed is raised due |
+ // to an asynchronous error. |
+ virtual Error error(); |
+ |
+ // GetError() (which is of type net::Error) != net::OK only when |
+ // error() == ERROR_WINSOCK. |
+ virtual int GetError(); |
+ |
+ // Tries to connect to the given address. |
+ // |
+ // If state() is not STATE_CLOSED, sets error to ERROR_WRONGSTATE |
+ // and returns false. |
+ // |
+ // If |address| is not resolved, sets error to ERROR_DNS and returns |
+ // false. |
+ // |
+ // Otherwise, starts the connection process and returns true. |
+ // SignalConnected will be raised when the connection is successful; |
+ // otherwise, SignalClosed will be raised with a net error set. |
+ virtual bool Connect(const talk_base::SocketAddress& address); |
+ |
+ // Tries to read at most |len| bytes into |data|. |
+ // |
+ // If state() is not STATE_TLS_CONNECTING, STATE_OPEN, or |
+ // STATE_TLS_OPEN, sets error to ERROR_WRONGSTATE and returns false. |
+ // |
+ // Otherwise, fills in |len_read| with the number of bytes read and |
+ // returns true. If this is called when state() is |
+ // STATE_TLS_CONNECTING, reads 0 bytes. (We have to handle this |
+ // case because StartTls() is called during a slot connected to |
+ // SignalRead after parsing the final non-TLS reply from the server |
+ // [see XmppClient::Private::OnSocketRead()].) |
+ virtual bool Read(char* data, size_t len, size_t* len_read); |
+ |
+ // Queues up |len| bytes of |data| for writing. |
+ // |
+ // If state() is not STATE_TLS_CONNECTING, STATE_OPEN, or |
+ // STATE_TLS_OPEN, sets error to ERROR_WRONGSTATE and returns false. |
+ // |
+ // If the given data is too big for the internal write buffer, sets |
+ // error to ERROR_WINSOCK/net::ERR_INSUFFICIENT_RESOURCES and |
+ // returns false. |
+ // |
+ // Otherwise, queues up the data and returns true. If this is |
+ // called when state() == STATE_TLS_CONNECTING, the data is will be |
+ // sent only after the TLS connection succeeds. (See StartTls() |
+ // below for why this happens.) |
+ // |
+ // Note that there's no guarantee that the data will actually be |
+ // sent; however, it is guaranteed that the any data sent will be |
+ // sent in FIFO order. |
+ virtual bool Write(const char* data, size_t len); |
+ |
+ // If the socket is not already closed, closes the socket and raises |
+ // SignalClosed. Always returns true. |
+ virtual bool Close(); |
+ |
+ // Tries to change to a TLS connection with the given domain name. |
+ // |
+ // If state() is not STATE_OPEN or there are pending reads or |
+ // writes, sets error to ERROR_WRONGSTATE and returns false. (In |
+ // practice, this means that StartTls() can only be called from a |
+ // slot connected to SignalRead.) |
+ // |
+ // Otherwise, starts the TLS connection process and returns true. |
+ // SignalSSLConnected will be raised when the connection is |
+ // successful; otherwise, SignalClosed will be raised with a net |
+ // error set. |
+ virtual bool StartTls(const std::string& domain_name); |
+ |
+ // Signal behavior: |
+ // |
+ // SignalConnected: raised whenever the connect initiated by a call |
+ // to Connect() is complete. |
+ // |
+ // SignalSSLConnected: raised whenever the connect initiated by a |
+ // call to StartTls() is complete. Not actually used by |
+ // XmppClient. (It just assumes that if SignalRead is raised after a |
+ // call to StartTls(), the connection has been successfully |
+ // upgraded.) |
+ // |
+ // SignalClosed: raised whenever the socket is closed, either due to |
+ // an asynchronous error, the other side closing the connection, or |
+ // when Close() is called. |
+ // |
+ // SignalRead: raised whenever the next call to Read() will succeed |
+ // with a non-zero |len_read| (assuming nothing else happens in the |
+ // meantime). |
+ // |
+ // SignalError: not used. |
+ |
+ private: |
+ enum AsyncIOState { |
+ // An I/O op is not in progress. |
+ IDLE, |
+ // A function has been posted to do the I/O. |
+ POSTED, |
+ // An async I/O operation is pending. |
+ PENDING, |
+ }; |
+ |
+ bool IsOpen() const; |
+ |
+ // Error functions. |
+ void DoNonNetError(Error error); |
+ void DoNetError(net::Error net_error); |
+ void DoNetErrorFromStatus(int status); |
+ |
+ // Connection functions. |
+ void ProcessConnectDone(int status); |
+ |
+ // Read loop functions. |
+ void PostDoRead(); |
+ void DoRead(); |
+ void ProcessReadDone(int status); |
+ |
+ // Write loop functions. |
+ void PostDoWrite(); |
+ void DoWrite(); |
+ void ProcessWriteDone(int status); |
+ |
+ // SSL/TLS connection functions. |
+ void ProcessSSLConnectDone(int status); |
+ |
+ // Close functions. |
+ void DoClose(); |
+ |
+ // Callbacks passed to |transport_socket_|. |
+ net::CompletionCallbackImpl<ChromeAsyncSocket> connect_callback_; |
+ net::CompletionCallbackImpl<ChromeAsyncSocket> read_callback_; |
+ net::CompletionCallbackImpl<ChromeAsyncSocket> write_callback_; |
+ net::CompletionCallbackImpl<ChromeAsyncSocket> ssl_connect_callback_; |
+ |
+ // Weak pointer. |
+ net::ClientSocketFactory* const client_socket_factory_; |
+ const net::SSLConfig ssl_config_; |
+ net::BoundNetLog bound_net_log_; |
+ |
+ // buzz::AsyncSocket state. |
+ buzz::AsyncSocket::State state_; |
+ buzz::AsyncSocket::Error error_; |
+ net::Error net_error_; |
+ |
+ // Used by read/write loops. |
+ ScopedRunnableMethodFactory<ChromeAsyncSocket> |
+ scoped_runnable_method_factory_; |
+ |
+ // NULL iff state() == STATE_CLOSED. |
+ // |
+ // TODO(akalin): Use ClientSocketPool. |
+ scoped_ptr<net::ClientSocket> transport_socket_; |
+ |
+ // State for the read loop. |read_start_| <= |read_end_| <= |
+ // |read_buf_->size()|. There's a read in flight (i.e., |
+ // |read_state_| != IDLE) iff |read_end_| == 0. |
+ AsyncIOState read_state_; |
+ scoped_refptr<net::IOBufferWithSize> read_buf_; |
+ size_t read_start_, read_end_; |
+ |
+ // State for the write loop. |write_end_| <= |write_buf_->size()|. |
+ // There's a write in flight (i.e., |write_state_| != IDLE) iff |
+ // |write_end_| > 0. |
+ AsyncIOState write_state_; |
+ scoped_refptr<net::IOBufferWithSize> write_buf_; |
+ size_t write_end_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ChromeAsyncSocket); |
+}; |
+ |
+} // namespace sync_tools |
+ |
+#endif // CHROME_BROWSER_SYNC_TOOLS_CHROME_ASYNC_SOCKET_H_ |