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 #include "content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/logging.h" 10 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 11 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" 12 #include "content/public/browser/browser_thread.h" 13 #include "content/public/common/socket_permission_request.h" 14 #include "net/base/ip_endpoint.h" 15 #include "net/base/net_errors.h" 16 #include "net/base/net_util.h" 17 #include "net/socket/tcp_client_socket.h" 18 #include "net/socket/tcp_server_socket.h" 19 #include "ppapi/c/pp_errors.h" 20 #include "ppapi/c/private/ppb_net_address_private.h" 21 #include "ppapi/host/dispatch_host_message.h" 22 #include "ppapi/host/error_conversion.h" 23 #include "ppapi/proxy/ppapi_messages.h" 24 #include "ppapi/shared_impl/api_id.h" 25 #include "ppapi/shared_impl/private/net_address_private_impl.h" 26 27 using ppapi::NetAddressPrivateImpl; 28 using ppapi::host::NetErrorToPepperError; 29 30 namespace { 31 32 size_t g_num_instances = 0; 33 34 } // namespace 35 36 namespace content { 37 38 PepperTCPServerSocketMessageFilter::PepperTCPServerSocketMessageFilter( 39 BrowserPpapiHostImpl* host, 40 PP_Instance instance, 41 bool private_api, 42 const scoped_refptr<PepperMessageFilter>& pepper_message_filter) 43 : state_(STATE_BEFORE_LISTENING), 44 pepper_message_filter_(pepper_message_filter), 45 external_plugin_(host->external_plugin()), 46 private_api_(private_api), 47 render_process_id_(0), 48 render_view_id_(0) { 49 ++g_num_instances; 50 DCHECK(host); 51 if (!host->GetRenderViewIDsForInstance(instance, 52 &render_process_id_, 53 &render_view_id_)) { 54 NOTREACHED(); 55 } 56 } 57 58 PepperTCPServerSocketMessageFilter::~PepperTCPServerSocketMessageFilter() { 59 --g_num_instances; 60 } 61 62 // static 63 size_t PepperTCPServerSocketMessageFilter::GetNumInstances() { 64 return g_num_instances; 65 } 66 67 scoped_refptr<base::TaskRunner> 68 PepperTCPServerSocketMessageFilter::OverrideTaskRunnerForMessage( 69 const IPC::Message& message) { 70 switch (message.type()) { 71 case PpapiHostMsg_TCPServerSocket_Listen::ID: 72 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); 73 case PpapiHostMsg_TCPServerSocket_Accept::ID: 74 case PpapiHostMsg_TCPServerSocket_StopListening::ID: 75 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 76 } 77 return NULL; 78 } 79 80 int32_t PepperTCPServerSocketMessageFilter::OnResourceMessageReceived( 81 const IPC::Message& msg, 82 ppapi::host::HostMessageContext* context) { 83 IPC_BEGIN_MESSAGE_MAP(PepperTCPServerSocketMessageFilter, msg) 84 PPAPI_DISPATCH_HOST_RESOURCE_CALL( 85 PpapiHostMsg_TCPServerSocket_Listen, OnMsgListen) 86 PPAPI_DISPATCH_HOST_RESOURCE_CALL( 87 PpapiHostMsg_TCPServerSocket_Accept, OnMsgAccept) 88 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( 89 PpapiHostMsg_TCPServerSocket_StopListening, OnMsgStopListening) 90 IPC_END_MESSAGE_MAP() 91 return PP_ERROR_FAILED; 92 } 93 94 int32_t PepperTCPServerSocketMessageFilter::OnMsgListen( 95 const ppapi::host::HostMessageContext* context, 96 const PP_NetAddress_Private& addr, 97 int32_t backlog) { 98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 99 DCHECK(context); 100 101 SocketPermissionRequest request = 102 pepper_socket_utils::CreateSocketPermissionRequest( 103 content::SocketPermissionRequest::TCP_LISTEN, addr); 104 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 105 private_api_, 106 request, 107 render_process_id_, 108 render_view_id_)) { 109 return PP_ERROR_NOACCESS; 110 } 111 112 BrowserThread::PostTask( 113 BrowserThread::IO, FROM_HERE, 114 base::Bind(&PepperTCPServerSocketMessageFilter::DoListen, this, 115 context->MakeReplyMessageContext(), addr, backlog)); 116 return PP_OK_COMPLETIONPENDING; 117 } 118 119 int32_t PepperTCPServerSocketMessageFilter::OnMsgAccept( 120 const ppapi::host::HostMessageContext* context, 121 uint32 plugin_dispatcher_id) { 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 123 DCHECK(context); 124 125 if (state_ != STATE_LISTENING) 126 return PP_ERROR_FAILED; 127 128 state_ = STATE_ACCEPT_IN_PROGRESS; 129 ppapi::host::ReplyMessageContext reply_context( 130 context->MakeReplyMessageContext()); 131 int net_result = socket_->Accept( 132 &socket_buffer_, 133 base::Bind(&PepperTCPServerSocketMessageFilter::OnAcceptCompleted, 134 base::Unretained(this), 135 reply_context, plugin_dispatcher_id)); 136 if (net_result != net::ERR_IO_PENDING) 137 OnAcceptCompleted(reply_context, plugin_dispatcher_id, net_result); 138 return PP_OK_COMPLETIONPENDING; 139 } 140 141 int32_t PepperTCPServerSocketMessageFilter::OnMsgStopListening( 142 const ppapi::host::HostMessageContext* context) { 143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 144 DCHECK(context); 145 146 state_ = STATE_CLOSED; 147 socket_.reset(); 148 return PP_OK; 149 } 150 151 void PepperTCPServerSocketMessageFilter::DoListen( 152 const ppapi::host::ReplyMessageContext& context, 153 const PP_NetAddress_Private& addr, 154 int32_t backlog) { 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 156 157 net::IPAddressNumber address; 158 int port; 159 if (state_ != STATE_BEFORE_LISTENING || 160 !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { 161 SendListenError(context, PP_ERROR_FAILED); 162 state_ = STATE_CLOSED; 163 return; 164 } 165 166 state_ = STATE_LISTEN_IN_PROGRESS; 167 168 socket_.reset(new net::TCPServerSocket(NULL, net::NetLog::Source())); 169 int net_result = socket_->Listen(net::IPEndPoint(address, port), backlog); 170 if (net_result != net::ERR_IO_PENDING) 171 OnListenCompleted(context, net_result); 172 } 173 174 void PepperTCPServerSocketMessageFilter::OnListenCompleted( 175 const ppapi::host::ReplyMessageContext& context, 176 int net_result) { 177 if (state_ != STATE_LISTEN_IN_PROGRESS) { 178 SendListenError(context, PP_ERROR_FAILED); 179 state_ = STATE_CLOSED; 180 return; 181 } 182 if (net_result != net::OK) { 183 SendListenError(context, NetErrorToPepperError(net_result)); 184 state_ = STATE_BEFORE_LISTENING; 185 return; 186 } 187 188 DCHECK(socket_.get()); 189 190 net::IPEndPoint end_point; 191 PP_NetAddress_Private addr; 192 193 int32_t pp_result = 194 NetErrorToPepperError(socket_->GetLocalAddress(&end_point)); 195 if (pp_result != PP_OK) { 196 SendListenError(context, pp_result); 197 state_ = STATE_BEFORE_LISTENING; 198 return; 199 } 200 if (!NetAddressPrivateImpl::IPEndPointToNetAddress(end_point.address(), 201 end_point.port(), 202 &addr)) { 203 SendListenError(context, PP_ERROR_FAILED); 204 state_ = STATE_BEFORE_LISTENING; 205 return; 206 } 207 208 SendListenReply(context, PP_OK, addr); 209 state_ = STATE_LISTENING; 210 } 211 212 void PepperTCPServerSocketMessageFilter::OnAcceptCompleted( 213 const ppapi::host::ReplyMessageContext& context, 214 uint32 plugin_dispatcher_id, 215 int net_result) { 216 if (state_ != STATE_ACCEPT_IN_PROGRESS) { 217 SendAcceptError(context, PP_ERROR_FAILED); 218 state_ = STATE_CLOSED; 219 return; 220 } 221 222 state_ = STATE_LISTENING; 223 224 if (net_result != net::OK) { 225 SendAcceptError(context, NetErrorToPepperError(net_result)); 226 return; 227 } 228 229 DCHECK(socket_buffer_.get()); 230 231 scoped_ptr<net::StreamSocket> socket(socket_buffer_.release()); 232 net::IPEndPoint ip_end_point_local; 233 net::IPEndPoint ip_end_point_remote; 234 PP_NetAddress_Private local_addr = NetAddressPrivateImpl::kInvalidNetAddress; 235 PP_NetAddress_Private remote_addr = NetAddressPrivateImpl::kInvalidNetAddress; 236 237 int32_t pp_result = 238 NetErrorToPepperError(socket->GetLocalAddress(&ip_end_point_local)); 239 if (pp_result != PP_OK) { 240 SendAcceptError(context, pp_result); 241 return; 242 } 243 if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 244 ip_end_point_local.address(), 245 ip_end_point_local.port(), 246 &local_addr)) { 247 SendAcceptError(context, PP_ERROR_FAILED); 248 return; 249 } 250 pp_result = 251 NetErrorToPepperError(socket->GetPeerAddress(&ip_end_point_remote)); 252 if (pp_result != PP_OK) { 253 SendAcceptError(context, pp_result); 254 return; 255 } 256 if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 257 ip_end_point_remote.address(), 258 ip_end_point_remote.port(), 259 &remote_addr)) { 260 SendAcceptError(context, PP_ERROR_FAILED); 261 return; 262 } 263 if (!pepper_message_filter_.get() || plugin_dispatcher_id == 0) { 264 SendAcceptError(context, PP_ERROR_FAILED); 265 return; 266 } 267 uint32 accepted_socket_id = pepper_message_filter_->AddAcceptedTCPSocket( 268 ppapi::API_ID_PPB_TCPSOCKET_PRIVATE, 269 plugin_dispatcher_id, 270 socket.release()); 271 if (accepted_socket_id != 0) { 272 SendAcceptReply(context, PP_OK, accepted_socket_id, local_addr, 273 remote_addr); 274 } else { 275 SendAcceptError(context, PP_ERROR_NOSPACE); 276 } 277 } 278 279 void PepperTCPServerSocketMessageFilter::SendListenReply( 280 const ppapi::host::ReplyMessageContext& context, 281 int32_t pp_result, 282 const PP_NetAddress_Private& local_addr) { 283 ppapi::host::ReplyMessageContext reply_context(context); 284 reply_context.params.set_result(pp_result); 285 SendReply(reply_context, 286 PpapiPluginMsg_TCPServerSocket_ListenReply(local_addr)); 287 } 288 289 void PepperTCPServerSocketMessageFilter::SendListenError( 290 const ppapi::host::ReplyMessageContext& context, 291 int32_t pp_result) { 292 SendListenReply(context, pp_result, 293 NetAddressPrivateImpl::kInvalidNetAddress); 294 } 295 296 void PepperTCPServerSocketMessageFilter::SendAcceptReply( 297 const ppapi::host::ReplyMessageContext& context, 298 int32_t pp_result, 299 uint32 accepted_socket_id, 300 const PP_NetAddress_Private& local_addr, 301 const PP_NetAddress_Private& remote_addr) { 302 ppapi::host::ReplyMessageContext reply_context(context); 303 reply_context.params.set_result(pp_result); 304 SendReply(reply_context, PpapiPluginMsg_TCPServerSocket_AcceptReply( 305 accepted_socket_id, local_addr, remote_addr)); 306 } 307 308 void PepperTCPServerSocketMessageFilter::SendAcceptError( 309 const ppapi::host::ReplyMessageContext& context, 310 int32_t pp_result) { 311 SendAcceptReply(context, 312 pp_result, 313 0, 314 NetAddressPrivateImpl::kInvalidNetAddress, 315 NetAddressPrivateImpl::kInvalidNetAddress); 316 } 317 318 } // namespace content 319