1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // 5 // An implementation of jingle_xmpp::AsyncSocket that uses Chrome Network Service 6 // sockets. 7 8 #ifndef JINGLE_GLUE_NETWORK_SERVICE_ASYNC_SOCKET_H_ 9 #define JINGLE_GLUE_NETWORK_SERVICE_ASYNC_SOCKET_H_ 10 11 #include <stddef.h> 12 13 #include <memory> 14 #include <string> 15 #include <vector> 16 17 #include "base/macros.h" 18 #include "base/memory/ref_counted.h" 19 #include "base/memory/weak_ptr.h" 20 #include "jingle/glue/network_service_config.h" 21 #include "mojo/public/cpp/bindings/pending_receiver.h" 22 #include "mojo/public/cpp/bindings/receiver.h" 23 #include "mojo/public/cpp/bindings/remote.h" 24 #include "mojo/public/cpp/system/data_pipe.h" 25 #include "mojo/public/cpp/system/simple_watcher.h" 26 #include "net/base/host_port_pair.h" 27 #include "net/traffic_annotation/network_traffic_annotation.h" 28 #include "services/network/public/mojom/proxy_resolving_socket.mojom.h" 29 #include "services/network/public/mojom/tcp_socket.mojom.h" 30 #include "services/network/public/mojom/tls_socket.mojom.h" 31 #include "third_party/libjingle_xmpp/xmpp/asyncsocket.h" 32 33 namespace jingle_glue { 34 35 class NetworkServiceAsyncSocket : public jingle_xmpp::AsyncSocket, 36 public network::mojom::SocketObserver { 37 public: 38 NetworkServiceAsyncSocket( 39 GetProxyResolvingSocketFactoryCallback get_socket_factory_callback, 40 bool use_fake_tls_handshake, 41 size_t read_buf_size, 42 size_t write_buf_size, 43 const net::NetworkTrafficAnnotationTag& traffic_annotation); 44 45 // Does not raise any signals. 46 ~NetworkServiceAsyncSocket() override; 47 48 // jingle_xmpp::AsyncSocket implementation. 49 50 // The current state (see jingle_xmpp::AsyncSocket::State; all but 51 // STATE_CLOSING is used). 52 State state() override; 53 54 // The last generated error. Errors are generated when the main 55 // functions below return false or when SignalClosed is raised due 56 // to an asynchronous error. 57 Error error() override; 58 59 // GetError() (which is of type net::Error) != net::OK only when 60 // error() == ERROR_WINSOCK. 61 int GetError() override; 62 63 // Tries to connect to the given address. 64 // 65 // If state() is not STATE_CLOSED, sets error to ERROR_WRONGSTATE 66 // and returns false. 67 // 68 // If |address| has an empty hostname or a zero port, sets error to 69 // ERROR_DNS and returns false. (We don't use the IP address even 70 // if it's present, as DNS resolution is done by the network service). 71 // But it's perfectly fine if the hostname is a stringified IP address.) 72 // 73 // Otherwise, starts the connection process and returns true. 74 // SignalConnected will be raised when the connection is successful; 75 // otherwise, SignalClosed will be raised with a net error set. 76 bool Connect(const net::HostPortPair& address) override; 77 78 // Tries to read at most |len| bytes into |data|. 79 // 80 // If state() is not STATE_TLS_CONNECTING, STATE_OPEN, or 81 // STATE_TLS_OPEN, sets error to ERROR_WRONGSTATE and returns false. 82 // 83 // Otherwise, fills in |len_read| with the number of bytes read and 84 // returns true. If this is called when state() is 85 // STATE_TLS_CONNECTING, reads 0 bytes. (We have to handle this 86 // case because StartTls() is called during a slot connected to 87 // SignalRead after parsing the final non-TLS reply from the server 88 // [see XmppClient::Private::OnSocketRead()].) 89 bool Read(char* data, size_t len, size_t* len_read) override; 90 91 // Queues up |len| bytes of |data| for writing. 92 // 93 // If state() is not STATE_TLS_CONNECTING, STATE_OPEN, or 94 // STATE_TLS_OPEN, sets error to ERROR_WRONGSTATE and returns false. 95 // 96 // If the given data is too big for the internal write buffer, sets 97 // error to ERROR_WINSOCK/net::ERR_INSUFFICIENT_RESOURCES and 98 // returns false. 99 // 100 // Otherwise, queues up the data and returns true. If this is 101 // called when state() == STATE_TLS_CONNECTING, the data is will be 102 // sent only after the TLS connection succeeds. (See StartTls() 103 // below for why this happens.) 104 // 105 // Note that there's no guarantee that the data will actually be 106 // sent; however, it is guaranteed that the any data sent will be 107 // sent in FIFO order. 108 bool Write(const char* data, size_t len) override; 109 110 // If the socket is not already closed, closes the socket and raises 111 // SignalClosed. Always returns true. 112 bool Close() override; 113 114 // Tries to change to a TLS connection with the given domain name. 115 // 116 // If state() is not STATE_OPEN or there are pending reads or 117 // writes, sets error to ERROR_WRONGSTATE and returns false. (In 118 // practice, this means that StartTls() can only be called from a 119 // slot connected to SignalRead.) 120 // 121 // Otherwise, starts the TLS connection process and returns true. 122 // SignalSSLConnected will be raised when the connection is 123 // successful; otherwise, SignalClosed will be raised with a net 124 // error set. 125 bool StartTls(const std::string& domain_name) override; 126 127 // Signal behavior: 128 // 129 // SignalConnected: raised whenever the connect initiated by a call 130 // to Connect() is complete. 131 // 132 // SignalSSLConnected: raised whenever the connect initiated by a 133 // call to StartTls() is complete. Not actually used by 134 // XmppClient. (It just assumes that if SignalRead is raised after a 135 // call to StartTls(), the connection has been successfully 136 // upgraded.) 137 // 138 // SignalClosed: raised whenever the socket is closed, either due to 139 // an asynchronous error, the other side closing the connection, or 140 // when Close() is called. 141 // 142 // SignalRead: raised whenever the next call to Read() will succeed 143 // with a non-zero |len_read| (assuming nothing else happens in the 144 // meantime). 145 // 146 // SignalError: not used. 147 148 private: 149 enum AsyncIOState { 150 // An I/O op is not in progress or has been handed over to the network 151 // service. 152 IDLE, 153 // Waiting for network service to be ready to handle an operation. 154 WAITING, 155 }; 156 157 bool IsOpen() const; 158 159 // Error functions. 160 void DoNonNetError(Error error); 161 void DoNetError(net::Error net_error); 162 void DoNetErrorFromStatus(int status); 163 void ProcessSocketObserverError(); 164 165 // SocketObserver implementation 166 void OnReadError(int32_t net_error) override; 167 void OnWriteError(int32_t net_error) override; 168 169 // Connection functions. 170 void ProcessConnectDone(mojo::PendingReceiver<network::mojom::SocketObserver> 171 socket_observer_receiver, 172 int status, 173 const base::Optional<net::IPEndPoint>& local_addr, 174 const base::Optional<net::IPEndPoint>& peer_addr, 175 mojo::ScopedDataPipeConsumerHandle receive_stream, 176 mojo::ScopedDataPipeProducerHandle send_stream); 177 178 // Read loop functions. 179 void WatchForReadReady(); 180 void ProcessReadReady(MojoResult result, 181 const mojo::HandleSignalsState& state); 182 void ReportReadError(int net_error); 183 184 // Write loop functions. 185 void WatchForWriteReady(); 186 void ProcessWriteReady(MojoResult result, 187 const mojo::HandleSignalsState& state); 188 void ProcessWriteClosed(MojoResult result, 189 const mojo::HandleSignalsState& state); 190 191 // SSL/TLS connection functions. 192 void ProcessSSLConnectDone( 193 mojo::PendingReceiver<network::mojom::SocketObserver> 194 socket_observer_receiver, 195 int status, 196 mojo::ScopedDataPipeConsumerHandle receive_stream, 197 mojo::ScopedDataPipeProducerHandle send_stream); 198 199 // Close functions. 200 void DoClose(); 201 202 void ConnectPipes(mojo::ScopedDataPipeConsumerHandle receive_stream, 203 mojo::ScopedDataPipeProducerHandle send_stream); 204 void BindSocketObserver(mojo::PendingReceiver<network::mojom::SocketObserver> 205 socket_observer_receiver); 206 207 // |socket_factory_| is recreated every time via |get_socket_factory_callback| 208 // to handle network service restarts after crashes. 209 GetProxyResolvingSocketFactoryCallback get_socket_factory_callback_; 210 mojo::Remote<network::mojom::ProxyResolvingSocketFactory> socket_factory_; 211 // The handle to the proxy resolving socket for the current connection, if one 212 // exists. 213 mojo::Remote<network::mojom::ProxyResolvingSocket> socket_; 214 // TLS socket, if StartTls has been called. 215 mojo::Remote<network::mojom::TLSClientSocket> tls_socket_; 216 217 // Used to route error notifications here. 218 mojo::Receiver<network::mojom::SocketObserver> socket_observer_receiver_{ 219 this}; 220 221 bool use_fake_tls_handshake_; 222 223 // jingle_xmpp::AsyncSocket state. 224 jingle_xmpp::AsyncSocket::State state_; 225 jingle_xmpp::AsyncSocket::Error error_; 226 net::Error net_error_; 227 228 // State for the read loop. |read_start_| <= |read_end_| <= 229 // |read_buf_->size()|. There's a read in flight (i.e., 230 // |read_state_| != IDLE) iff |read_end_| == 0. 231 AsyncIOState read_state_; 232 std::vector<char> read_buf_; 233 size_t read_start_, read_end_; 234 mojo::ScopedDataPipeConsumerHandle read_pipe_; 235 std::unique_ptr<mojo::SimpleWatcher> read_watcher_; 236 237 // Handling read errors is a bit tricky since the status is reported via 238 // |socket_observer_receiver_|, which is unordered compared to |read_pipe_|, 239 // so it's possible to see an end of file (or an error) there while there is 240 // still useful data pending. As a result, the code waits to see both happen 241 // before reporting error statuses (including EOF). Likewise for write pipes. 242 // 243 bool saw_error_on_read_pipe_; 244 bool saw_error_on_write_pipe_; 245 246 // This is != net::ERR_IO_PENDING (including possibly net::OK for end-of-file) 247 // if a read error was reported via socket observer interface. 248 int saw_read_error_on_socket_observer_pipe_; 249 int saw_write_error_on_socket_observer_pipe_; 250 251 // State for the write loop. |write_end_| <= |write_buf_->size()|. 252 // There's a write in flight (i.e., |write_state_| != IDLE) iff 253 // |write_end_| > 0. 254 AsyncIOState write_state_; 255 std::vector<char> write_buf_; 256 size_t write_end_; 257 mojo::ScopedDataPipeProducerHandle write_pipe_; 258 std::unique_ptr<mojo::SimpleWatcher> write_watcher_; 259 std::unique_ptr<mojo::SimpleWatcher> write_close_watcher_; 260 261 // Network traffic annotation for downstream socket write. 262 // NetworkServiceAsyncSocket is not reused, hence annotation can be added in 263 // constructor and used in all subsequent writes. 264 const net::NetworkTrafficAnnotationTag traffic_annotation_; 265 266 DISALLOW_COPY_AND_ASSIGN(NetworkServiceAsyncSocket); 267 }; 268 269 } // namespace jingle_glue 270 271 #endif // JINGLE_GLUE_NETWORK_SERVICE_ASYNC_SOCKET_H_ 272