1 // Copyright 2013 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.
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_
15 #include "base/compiler_specific.h"
16 #include "base/macros.h"
17 #include "base/memory/ref_counted.h"
18 #include "build/build_config.h"
19 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
20 #include "content/browser/renderer_host/pepper/ssl_context_helper.h"
21 #include "content/common/content_export.h"
22 #include "net/base/address_list.h"
23 #include "net/base/ip_endpoint.h"
24 #include "net/dns/host_resolver.h"
25 #include "net/socket/tcp_socket.h"
26 #include "ppapi/c/pp_instance.h"
27 #include "ppapi/c/ppb_tcp_socket.h"
28 #include "ppapi/c/private/ppb_net_address_private.h"
29 #include "ppapi/host/resource_message_filter.h"
30 #include "ppapi/shared_impl/ppb_tcp_socket_shared.h"
32 #if defined(OS_CHROMEOS)
33 #include "chromeos/network/firewall_hole.h"
34 #include "content/public/browser/browser_thread.h"
35 #endif // defined(OS_CHROMEOS)
39 class DrainableIOBuffer;
41 class SSLClientSocket;
45 class SocketOptionData;
49 struct ReplyMessageContext;
55 class BrowserPpapiHostImpl;
56 class ContentBrowserPepperHostFactory;
57 class ResourceContext;
59 class CONTENT_EXPORT PepperTCPSocketMessageFilter
60 : public ppapi::host::ResourceMessageFilter,
61 public BrowserPpapiHostImpl::InstanceObserver {
63 PepperTCPSocketMessageFilter(ContentBrowserPepperHostFactory* factory,
64 BrowserPpapiHostImpl* host,
66 ppapi::TCPSocketVersion version);
68 // Used for creating already connected sockets.
69 PepperTCPSocketMessageFilter(BrowserPpapiHostImpl* host,
71 ppapi::TCPSocketVersion version,
72 std::unique_ptr<net::TCPSocket> socket);
74 static size_t GetNumInstances();
78 SOCKET_OPTION_NODELAY = 1 << 0,
79 SOCKET_OPTION_RCVBUF_SIZE = 1 << 1,
80 SOCKET_OPTION_SNDBUF_SIZE = 1 << 2
83 ~PepperTCPSocketMessageFilter() override;
85 // ppapi::host::ResourceMessageFilter overrides.
86 scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
87 const IPC::Message& message) override;
88 int32_t OnResourceMessageReceived(
89 const IPC::Message& msg,
90 ppapi::host::HostMessageContext* context) override;
92 // BrowserPpapiHostImpl::InstanceObserver overrides.
93 void OnThrottleStateChanged(bool is_throttled) override;
94 void OnHostDestroyed() override;
96 int32_t OnMsgBind(const ppapi::host::HostMessageContext* context,
97 const PP_NetAddress_Private& net_addr);
98 int32_t OnMsgConnect(const ppapi::host::HostMessageContext* context,
99 const std::string& host,
101 int32_t OnMsgConnectWithNetAddress(
102 const ppapi::host::HostMessageContext* context,
103 const PP_NetAddress_Private& net_addr);
104 int32_t OnMsgSSLHandshake(
105 const ppapi::host::HostMessageContext* context,
106 const std::string& server_name,
107 uint16_t server_port,
108 const std::vector<std::vector<char> >& trusted_certs,
109 const std::vector<std::vector<char> >& untrusted_certs);
110 int32_t OnMsgRead(const ppapi::host::HostMessageContext* context,
111 int32_t bytes_to_read);
112 int32_t OnMsgWrite(const ppapi::host::HostMessageContext* context,
113 const std::string& data);
114 int32_t OnMsgListen(const ppapi::host::HostMessageContext* context,
116 int32_t OnMsgAccept(const ppapi::host::HostMessageContext* context);
117 int32_t OnMsgClose(const ppapi::host::HostMessageContext* context);
118 int32_t OnMsgSetOption(const ppapi::host::HostMessageContext* context,
119 PP_TCPSocket_Option name,
120 const ppapi::SocketOptionData& value);
122 void DoBind(const ppapi::host::ReplyMessageContext& context,
123 const PP_NetAddress_Private& net_addr);
124 void DoConnect(const ppapi::host::ReplyMessageContext& context,
125 const std::string& host,
127 ResourceContext* resource_context);
128 void DoConnectWithNetAddress(const ppapi::host::ReplyMessageContext& context,
129 const PP_NetAddress_Private& net_addr);
130 void DoWrite(const ppapi::host::ReplyMessageContext& context);
131 void DoListen(const ppapi::host::ReplyMessageContext& context,
134 void OnResolveCompleted(const ppapi::host::ReplyMessageContext& context,
136 void StartConnect(const ppapi::host::ReplyMessageContext& context);
138 void OnConnectCompleted(const ppapi::host::ReplyMessageContext& context,
140 void OnSSLHandshakeCompleted(const ppapi::host::ReplyMessageContext& context,
142 void OnReadCompleted(const ppapi::host::ReplyMessageContext& context,
144 void OnWriteCompleted(const ppapi::host::ReplyMessageContext& context,
146 void OnAcceptCompleted(const ppapi::host::ReplyMessageContext& context,
149 void OnListenCompleted(const ppapi::host::ReplyMessageContext& context,
151 #if defined(OS_CHROMEOS)
152 void OpenFirewallHole(const ppapi::host::ReplyMessageContext& context,
154 void OnFirewallHoleOpened(const ppapi::host::ReplyMessageContext& context,
156 std::unique_ptr<chromeos::FirewallHole> hole);
157 #endif // defined(OS_CHROMEOS)
159 void SendBindReply(const ppapi::host::ReplyMessageContext& context,
161 const PP_NetAddress_Private& local_addr);
162 void SendBindError(const ppapi::host::ReplyMessageContext& context,
164 void SendConnectReply(const ppapi::host::ReplyMessageContext& context,
166 const PP_NetAddress_Private& local_addr,
167 const PP_NetAddress_Private& remote_addr);
168 void SendConnectError(const ppapi::host::ReplyMessageContext& context,
170 void SendSSLHandshakeReply(const ppapi::host::ReplyMessageContext& context,
172 void SendReadReply(const ppapi::host::ReplyMessageContext& context,
174 const std::string& data);
175 void SendReadError(const ppapi::host::ReplyMessageContext& context,
177 void SendWriteReply(const ppapi::host::ReplyMessageContext& context,
179 void SendListenReply(const ppapi::host::ReplyMessageContext& context,
181 void SendAcceptReply(const ppapi::host::ReplyMessageContext& context,
184 const PP_NetAddress_Private& local_addr,
185 const PP_NetAddress_Private& remote_addr);
186 void SendAcceptError(const ppapi::host::ReplyMessageContext& context,
189 bool IsPrivateAPI() const {
190 return version_ == ppapi::TCP_SOCKET_VERSION_PRIVATE;
193 // The following fields are used on both the UI and IO thread.
194 const ppapi::TCPSocketVersion version_;
196 // The following fields are used only on the UI thread.
197 const bool external_plugin_;
199 int render_process_id_;
200 int render_frame_id_;
202 // The following fields are used only on the IO thread.
204 BrowserPpapiHostImpl* host_;
206 ContentBrowserPepperHostFactory* factory_;
207 PP_Instance instance_;
209 ppapi::TCPSocketState state_;
210 bool end_of_file_reached_;
212 // This is the address requested to bind. Please note that this is not the
213 // bound address. For example, |bind_input_addr_| may have port set to 0.
214 // It is used to check permission for listening.
215 PP_NetAddress_Private bind_input_addr_;
217 #if defined(OS_CHROMEOS)
218 std::unique_ptr<chromeos::FirewallHole,
219 content::BrowserThread::DeleteOnUIThread>
221 #endif // defined(OS_CHROMEOS)
223 // Used for DNS request.
224 std::unique_ptr<net::HostResolver::Request> request_;
226 // Bitwise-or of SocketOption flags. This stores the state about whether
227 // each option is set before Connect() is called.
230 // Locally cached value of buffer size.
231 int32_t rcvbuf_size_;
232 int32_t sndbuf_size_;
234 // |address_list_| may store multiple addresses when
235 // PPB_TCPSocket_Private.Connect() is used, which involves name resolution.
236 // In that case, we will try each address in the list until a connection is
237 // successfully established.
238 net::AddressList address_list_;
239 // Where we are in the above list.
240 size_t address_index_;
242 // Non-null unless an SSL connection is requested.
243 std::unique_ptr<net::TCPSocket> socket_;
244 // Non-null if an SSL connection is requested.
245 std::unique_ptr<net::SSLClientSocket> ssl_socket_;
247 scoped_refptr<net::IOBuffer> read_buffer_;
249 // TCPSocket::Write() may not always write the full buffer, but we would
250 // rather have our DoWrite() do so whenever possible. To do this, we may have
251 // to call the former multiple times for each of the latter. This entails
252 // using a DrainableIOBuffer, which requires an underlying base IOBuffer.
253 scoped_refptr<net::IOBuffer> write_buffer_base_;
254 scoped_refptr<net::DrainableIOBuffer> write_buffer_;
255 scoped_refptr<SSLContextHelper> ssl_context_helper_;
257 bool pending_accept_;
258 std::unique_ptr<net::TCPSocket> accepted_socket_;
259 net::IPEndPoint accepted_address_;
261 // If the plugin is throttled, we defer completing socket reads until
262 // the plugin is unthrottled.
263 bool pending_read_on_unthrottle_;
264 ppapi::host::ReplyMessageContext pending_read_reply_message_context_;
265 int pending_read_net_result_;
267 const bool is_potentially_secure_plugin_context_;
269 DISALLOW_COPY_AND_ASSIGN(PepperTCPSocketMessageFilter);
272 } // namespace content
274 #endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_