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.
4
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_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "content/browser/renderer_host/pepper/ssl_context_helper.h"
16#include "content/common/content_export.h"
17#include "net/base/address_list.h"
18#include "net/base/ip_endpoint.h"
19#include "net/socket/tcp_socket.h"
20#include "ppapi/c/pp_instance.h"
21#include "ppapi/c/ppb_tcp_socket.h"
22#include "ppapi/c/private/ppb_net_address_private.h"
23#include "ppapi/host/resource_message_filter.h"
24#include "ppapi/shared_impl/ppb_tcp_socket_shared.h"
25
26namespace net {
27enum AddressFamily;
28class DrainableIOBuffer;
29class IOBuffer;
30class SingleRequestHostResolver;
31class SSLClientSocket;
32}
33
34namespace ppapi {
35class SocketOptionData;
36
37namespace host {
38class PpapiHost;
39struct ReplyMessageContext;
40}
41}
42
43namespace content {
44
45class BrowserPpapiHostImpl;
46class ContentBrowserPepperHostFactory;
47class ResourceContext;
48
49class CONTENT_EXPORT PepperTCPSocketMessageFilter
50    : public ppapi::host::ResourceMessageFilter {
51 public:
52  PepperTCPSocketMessageFilter(ContentBrowserPepperHostFactory* factory,
53                               BrowserPpapiHostImpl* host,
54                               PP_Instance instance,
55                               ppapi::TCPSocketVersion version);
56
57  // Used for creating already connected sockets.
58  PepperTCPSocketMessageFilter(BrowserPpapiHostImpl* host,
59                               PP_Instance instance,
60                               ppapi::TCPSocketVersion version,
61                               scoped_ptr<net::TCPSocket> socket);
62
63  static size_t GetNumInstances();
64
65 private:
66  virtual ~PepperTCPSocketMessageFilter();
67
68  // ppapi::host::ResourceMessageFilter overrides.
69  virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
70      const IPC::Message& message) OVERRIDE;
71  virtual int32_t OnResourceMessageReceived(
72      const IPC::Message& msg,
73      ppapi::host::HostMessageContext* context) OVERRIDE;
74
75  int32_t OnMsgBind(const ppapi::host::HostMessageContext* context,
76                    const PP_NetAddress_Private& net_addr);
77  int32_t OnMsgConnect(const ppapi::host::HostMessageContext* context,
78                       const std::string& host,
79                       uint16_t port);
80  int32_t OnMsgConnectWithNetAddress(
81      const ppapi::host::HostMessageContext* context,
82      const PP_NetAddress_Private& net_addr);
83  int32_t OnMsgSSLHandshake(
84      const ppapi::host::HostMessageContext* context,
85      const std::string& server_name,
86      uint16_t server_port,
87      const std::vector<std::vector<char> >& trusted_certs,
88      const std::vector<std::vector<char> >& untrusted_certs);
89  int32_t OnMsgRead(const ppapi::host::HostMessageContext* context,
90                    int32_t bytes_to_read);
91  int32_t OnMsgWrite(const ppapi::host::HostMessageContext* context,
92                     const std::string& data);
93  int32_t OnMsgListen(const ppapi::host::HostMessageContext* context,
94                      int32_t backlog);
95  int32_t OnMsgAccept(const ppapi::host::HostMessageContext* context);
96  int32_t OnMsgClose(const ppapi::host::HostMessageContext* context);
97  int32_t OnMsgSetOption(const ppapi::host::HostMessageContext* context,
98                         PP_TCPSocket_Option name,
99                         const ppapi::SocketOptionData& value);
100
101  void DoBind(const ppapi::host::ReplyMessageContext& context,
102              const PP_NetAddress_Private& net_addr);
103  void DoConnect(const ppapi::host::ReplyMessageContext& context,
104                 const std::string& host,
105                 uint16_t port,
106                 ResourceContext* resource_context);
107  void DoConnectWithNetAddress(const ppapi::host::ReplyMessageContext& context,
108                               const PP_NetAddress_Private& net_addr);
109  void DoWrite(const ppapi::host::ReplyMessageContext& context);
110  void DoListen(const ppapi::host::ReplyMessageContext& context,
111                int32_t backlog);
112
113  void OnResolveCompleted(const ppapi::host::ReplyMessageContext& context,
114                          int net_result);
115  void StartConnect(const ppapi::host::ReplyMessageContext& context);
116
117  void OnConnectCompleted(const ppapi::host::ReplyMessageContext& context,
118                          int net_result);
119  void OnSSLHandshakeCompleted(const ppapi::host::ReplyMessageContext& context,
120                               int net_result);
121  void OnReadCompleted(const ppapi::host::ReplyMessageContext& context,
122                       int net_result);
123  void OnWriteCompleted(const ppapi::host::ReplyMessageContext& context,
124                        int net_result);
125  void OnAcceptCompleted(const ppapi::host::ReplyMessageContext& context,
126                         int net_result);
127
128  void SendBindReply(const ppapi::host::ReplyMessageContext& context,
129                     int32_t pp_result,
130                     const PP_NetAddress_Private& local_addr);
131  void SendBindError(const ppapi::host::ReplyMessageContext& context,
132                     int32_t pp_error);
133  void SendConnectReply(const ppapi::host::ReplyMessageContext& context,
134                        int32_t pp_result,
135                        const PP_NetAddress_Private& local_addr,
136                        const PP_NetAddress_Private& remote_addr);
137  void SendConnectError(const ppapi::host::ReplyMessageContext& context,
138                        int32_t pp_error);
139  void SendSSLHandshakeReply(const ppapi::host::ReplyMessageContext& context,
140                             int32_t pp_result);
141  void SendReadReply(const ppapi::host::ReplyMessageContext& context,
142                     int32_t pp_result,
143                     const std::string& data);
144  void SendReadError(const ppapi::host::ReplyMessageContext& context,
145                     int32_t pp_error);
146  void SendWriteReply(const ppapi::host::ReplyMessageContext& context,
147                      int32_t pp_result);
148  void SendListenReply(const ppapi::host::ReplyMessageContext& context,
149                       int32_t pp_result);
150  void SendAcceptReply(const ppapi::host::ReplyMessageContext& context,
151                       int32_t pp_result,
152                       int pending_host_id,
153                       const PP_NetAddress_Private& local_addr,
154                       const PP_NetAddress_Private& remote_addr);
155  void SendAcceptError(const ppapi::host::ReplyMessageContext& context,
156                       int32_t pp_error);
157
158  bool IsPrivateAPI() const {
159    return version_ == ppapi::TCP_SOCKET_VERSION_PRIVATE;
160  }
161
162  // The following fields are used on both the UI and IO thread.
163  const ppapi::TCPSocketVersion version_;
164
165  // The following fields are used only on the UI thread.
166  const bool external_plugin_;
167
168  int render_process_id_;
169  int render_frame_id_;
170
171  // The following fields are used only on the IO thread.
172  // Non-owning ptr.
173  ppapi::host::PpapiHost* ppapi_host_;
174  // Non-owning ptr.
175  ContentBrowserPepperHostFactory* factory_;
176  PP_Instance instance_;
177
178  ppapi::TCPSocketState state_;
179  bool end_of_file_reached_;
180
181  // This is the address requested to bind. Please note that this is not the
182  // bound address. For example, |bind_input_addr_| may have port set to 0.
183  // It is used to check permission for listening.
184  PP_NetAddress_Private bind_input_addr_;
185
186  scoped_ptr<net::SingleRequestHostResolver> resolver_;
187
188  // |address_list_| may store multiple addresses when
189  // PPB_TCPSocket_Private.Connect() is used, which involves name resolution.
190  // In that case, we will try each address in the list until a connection is
191  // successfully established.
192  net::AddressList address_list_;
193  // Where we are in the above list.
194  size_t address_index_;
195
196  // Non-null unless an SSL connection is requested.
197  scoped_ptr<net::TCPSocket> socket_;
198  // Non-null if an SSL connection is requested.
199  scoped_ptr<net::SSLClientSocket> ssl_socket_;
200
201  scoped_refptr<net::IOBuffer> read_buffer_;
202
203  // TCPSocket::Write() may not always write the full buffer, but we would
204  // rather have our DoWrite() do so whenever possible. To do this, we may have
205  // to call the former multiple times for each of the latter. This entails
206  // using a DrainableIOBuffer, which requires an underlying base IOBuffer.
207  scoped_refptr<net::IOBuffer> write_buffer_base_;
208  scoped_refptr<net::DrainableIOBuffer> write_buffer_;
209  scoped_refptr<SSLContextHelper> ssl_context_helper_;
210
211  bool pending_accept_;
212  scoped_ptr<net::TCPSocket> accepted_socket_;
213  net::IPEndPoint accepted_address_;
214
215  DISALLOW_COPY_AND_ASSIGN(PepperTCPSocketMessageFilter);
216};
217
218}  // namespace content
219
220#endif  // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_
221