1 // Copyright 2014 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 #ifndef EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ 6 #define EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <string> 12 13 #include "base/memory/weak_ptr.h" 14 #include "base/sequenced_task_runner.h" 15 #include "extensions/browser/api/socket/socket.h" 16 #include "extensions/browser/api/socket/tcp_socket.h" 17 #include "extensions/common/api/socket.h" 18 #include "mojo/public/cpp/bindings/pending_receiver.h" 19 #include "mojo/public/cpp/bindings/pending_remote.h" 20 #include "mojo/public/cpp/bindings/remote.h" 21 #include "net/base/completion_once_callback.h" 22 #include "services/network/public/mojom/network_service.mojom.h" 23 #include "services/network/public/mojom/tcp_socket.mojom.h" 24 #include "services/network/public/mojom/tls_socket.mojom.h" 25 26 namespace content { 27 class BrowserContext; 28 class StoragePartition; 29 } 30 31 namespace extensions { 32 33 class MojoDataPump; 34 35 class TCPSocket : public Socket { 36 public: 37 using UpgradeToTLSCallback = base::OnceCallback<void( 38 int, 39 mojo::PendingRemote<network::mojom::TLSClientSocket>, 40 const net::IPEndPoint&, 41 const net::IPEndPoint&, 42 mojo::ScopedDataPipeConsumerHandle, 43 mojo::ScopedDataPipeProducerHandle)>; 44 45 // Constuctor for when |socket_mode_| is unknown. The |socket_mode_| will be 46 // filled in when the consumer calls Listen/Connect. 47 TCPSocket(content::BrowserContext* browser_context, 48 const std::string& owner_extension_id); 49 50 // Created using TCPServerSocket::Accept(). 51 TCPSocket(mojo::PendingRemote<network::mojom::TCPConnectedSocket> socket, 52 mojo::ScopedDataPipeConsumerHandle receive_stream, 53 mojo::ScopedDataPipeProducerHandle send_stream, 54 const base::Optional<net::IPEndPoint>& remote_addr, 55 const std::string& owner_extension_id); 56 57 ~TCPSocket() override; 58 59 void Connect(const net::AddressList& address, 60 net::CompletionOnceCallback callback) override; 61 void Disconnect(bool socket_destroying) override; 62 void Bind(const std::string& address, 63 uint16_t port, 64 net::CompletionOnceCallback callback) override; 65 void Read(int count, ReadCompletionCallback callback) override; 66 void RecvFrom(int count, RecvFromCompletionCallback callback) override; 67 void SendTo(scoped_refptr<net::IOBuffer> io_buffer, 68 int byte_count, 69 const net::IPEndPoint& address, 70 net::CompletionOnceCallback callback) override; 71 void SetKeepAlive(bool enable, 72 int delay, 73 SetKeepAliveCallback callback) override; 74 void SetNoDelay(bool no_delay, SetNoDelayCallback callback) override; 75 void Listen(const std::string& address, 76 uint16_t port, 77 int backlog, 78 ListenCallback callback) override; 79 void Accept(AcceptCompletionCallback callback) override; 80 81 bool IsConnected() override; 82 83 bool GetPeerAddress(net::IPEndPoint* address) override; 84 bool GetLocalAddress(net::IPEndPoint* address) override; 85 86 Socket::SocketType GetSocketType() const override; 87 88 void UpgradeToTLS(api::socket::SecureOptions* options, 89 UpgradeToTLSCallback callback); 90 SetStoragePartitionForTest(content::StoragePartition * storage_partition)91 void SetStoragePartitionForTest( 92 content::StoragePartition* storage_partition) { 93 storage_partition_ = storage_partition; 94 } 95 96 protected: 97 int WriteImpl(net::IOBuffer* io_buffer, 98 int io_buffer_size, 99 net::CompletionOnceCallback callback) override; 100 101 private: 102 // Connects a client TCP socket. This is done on the UI thread because 103 // StoragePartition::GetNetworkContext() needs to happen on the UI thread. 104 // The completion callback is posted back to the thread on which |this| lives. 105 static void ConnectOnUIThread( 106 content::StoragePartition* storage_partition, 107 content::BrowserContext* browser_context, 108 const net::AddressList& remote_address_list, 109 mojo::PendingReceiver<network::mojom::TCPConnectedSocket> receiver, 110 network::mojom::NetworkContext::CreateTCPConnectedSocketCallback 111 callback); 112 static void OnConnectCompleteOnUIThread( 113 scoped_refptr<base::SequencedTaskRunner> original_task_runner, 114 network::mojom::NetworkContext::CreateTCPConnectedSocketCallback callback, 115 int result, 116 const base::Optional<net::IPEndPoint>& local_addr, 117 const base::Optional<net::IPEndPoint>& peer_addr, 118 mojo::ScopedDataPipeConsumerHandle receive_stream, 119 mojo::ScopedDataPipeProducerHandle send_stream); 120 void OnConnectComplete(int result, 121 const base::Optional<net::IPEndPoint>& local_addr, 122 const base::Optional<net::IPEndPoint>& peer_addr, 123 mojo::ScopedDataPipeConsumerHandle receive_stream, 124 mojo::ScopedDataPipeProducerHandle send_stream); 125 126 // Connects a server TCP socket. This is done on the UI thread because 127 // StoragePartition::GetNetworkContext() needs to happen on the UI thread. 128 // The completion callback is posted back to the thread on which |this| lives. 129 static void ListenOnUIThread( 130 content::StoragePartition* storage_partition, 131 content::BrowserContext* browser_context, 132 const net::IPEndPoint& local_addr, 133 int backlog, 134 mojo::PendingReceiver<network::mojom::TCPServerSocket> receiver, 135 network::mojom::NetworkContext::CreateTCPServerSocketCallback callback); 136 static void OnListenCompleteOnUIThread( 137 const scoped_refptr<base::SequencedTaskRunner>& original_task_runner, 138 network::mojom::NetworkContext::CreateTCPServerSocketCallback callback, 139 int result, 140 const base::Optional<net::IPEndPoint>& local_addr); 141 void OnListenComplete(int result, 142 const base::Optional<net::IPEndPoint>& local_addr); 143 void OnAccept( 144 int result, 145 const base::Optional<net::IPEndPoint>& remote_addr, 146 mojo::PendingRemote<network::mojom::TCPConnectedSocket> connected_socket, 147 mojo::ScopedDataPipeConsumerHandle receive_stream, 148 mojo::ScopedDataPipeProducerHandle send_stream); 149 void OnWriteComplete(net::CompletionOnceCallback callback, int result); 150 void OnReadComplete(int result, scoped_refptr<net::IOBuffer> io_buffer); 151 void OnUpgradeToTLSComplete( 152 UpgradeToTLSCallback callback, 153 mojo::PendingRemote<network::mojom::TLSClientSocket> tls_socket, 154 const net::IPEndPoint& local_addr, 155 const net::IPEndPoint& peer_addr, 156 int result, 157 mojo::ScopedDataPipeConsumerHandle receive_stream, 158 mojo::ScopedDataPipeProducerHandle send_stream, 159 const base::Optional<net::SSLInfo>& ssl_info); 160 161 content::StoragePartition* GetStoragePartitionHelper(); 162 163 enum SocketMode { 164 UNKNOWN = 0, 165 CLIENT, 166 SERVER, 167 }; 168 169 // |this| doesn't outlive |browser_context_| because |this| is owned by 170 // ApiResourceManager which is a BrowserContextKeyedAPI. 171 content::BrowserContext* browser_context_; 172 173 SocketMode socket_mode_; 174 175 // CLIENT mode. 176 mojo::Remote<network::mojom::TCPConnectedSocket> client_socket_; 177 // SERVER mode. 178 mojo::Remote<network::mojom::TCPServerSocket> server_socket_; 179 180 net::CompletionOnceCallback connect_callback_; 181 ListenCallback listen_callback_; 182 AcceptCompletionCallback accept_callback_; 183 ReadCompletionCallback read_callback_; 184 185 std::unique_ptr<MojoDataPump> mojo_data_pump_; 186 187 scoped_refptr<base::SequencedTaskRunner> task_runner_; 188 189 base::Optional<net::IPEndPoint> local_addr_; 190 base::Optional<net::IPEndPoint> peer_addr_; 191 192 // Only used in tests. 193 content::StoragePartition* storage_partition_ = nullptr; 194 195 // WeakPtr is used when posting tasks to |task_runner_| which might outlive 196 // |this|. 197 base::WeakPtrFactory<TCPSocket> weak_factory_{this}; 198 199 DISALLOW_COPY_AND_ASSIGN(TCPSocket); 200 }; 201 202 // TCP Socket instances from the "sockets.tcp" namespace. These are regular 203 // socket objects with additional properties related to the behavior defined in 204 // the "sockets.tcp" namespace. 205 class ResumableTCPSocket : public TCPSocket { 206 public: 207 ResumableTCPSocket(content::BrowserContext* browser_context, 208 const std::string& owner_extension_id); 209 // Created using TCPServerSocket::Accept(). 210 ResumableTCPSocket( 211 mojo::PendingRemote<network::mojom::TCPConnectedSocket> socket, 212 mojo::ScopedDataPipeConsumerHandle receive_stream, 213 mojo::ScopedDataPipeProducerHandle send_stream, 214 const base::Optional<net::IPEndPoint>& remote_addr, 215 const std::string& owner_extension_id); 216 217 ~ResumableTCPSocket() override; 218 219 // Overriden from ApiResource 220 bool IsPersistent() const override; 221 name()222 const std::string& name() const { return name_; } set_name(const std::string & name)223 void set_name(const std::string& name) { name_ = name; } 224 persistent()225 bool persistent() const { return persistent_; } set_persistent(bool persistent)226 void set_persistent(bool persistent) { persistent_ = persistent; } 227 buffer_size()228 int buffer_size() const { return buffer_size_; } set_buffer_size(int buffer_size)229 void set_buffer_size(int buffer_size) { buffer_size_ = buffer_size; } 230 paused()231 bool paused() const { return paused_; } set_paused(bool paused)232 void set_paused(bool paused) { paused_ = paused; } 233 234 private: 235 friend class ApiResourceManager<ResumableTCPSocket>; service_name()236 static const char* service_name() { return "ResumableTCPSocketManager"; } 237 238 // Application-defined string - see sockets_tcp.idl. 239 std::string name_; 240 // Flag indicating whether the socket is left open when the application is 241 // suspended - see sockets_tcp.idl. 242 bool persistent_; 243 // The size of the buffer used to receive data - see sockets_tcp.idl. 244 int buffer_size_; 245 // Flag indicating whether a connected socket blocks its peer from sending 246 // more data - see sockets_tcp.idl. 247 bool paused_; 248 }; 249 250 // TCP Socket instances from the "sockets.tcpServer" namespace. These are 251 // regular socket objects with additional properties related to the behavior 252 // defined in the "sockets.tcpServer" namespace. 253 class ResumableTCPServerSocket : public TCPSocket { 254 public: 255 ResumableTCPServerSocket(content::BrowserContext* browser_context, 256 const std::string& owner_extension_id); 257 258 // Overriden from ApiResource 259 bool IsPersistent() const override; 260 name()261 const std::string& name() const { return name_; } set_name(const std::string & name)262 void set_name(const std::string& name) { name_ = name; } 263 persistent()264 bool persistent() const { return persistent_; } set_persistent(bool persistent)265 void set_persistent(bool persistent) { persistent_ = persistent; } 266 paused()267 bool paused() const { return paused_; } set_paused(bool paused)268 void set_paused(bool paused) { paused_ = paused; } 269 270 private: 271 friend class ApiResourceManager<ResumableTCPServerSocket>; service_name()272 static const char* service_name() { 273 return "ResumableTCPServerSocketManager"; 274 } 275 276 // Application-defined string - see sockets_tcp_server.idl. 277 std::string name_; 278 // Flag indicating whether the socket is left open when the application is 279 // suspended - see sockets_tcp_server.idl. 280 bool persistent_; 281 // Flag indicating whether a connected socket blocks its peer from sending 282 // more data - see sockets_tcp_server.idl. 283 bool paused_; 284 }; 285 286 } // namespace extensions 287 288 #endif // EXTENSIONS_BROWSER_API_SOCKET_TCP_SOCKET_H_ 289