OLD | NEW |
| (Empty) |
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 #include "content/browser/renderer_host/pepper_tcp_server_socket.h" | |
6 | |
7 #include <cstddef> | |
8 | |
9 #include "base/logging.h" | |
10 #include "content/browser/renderer_host/pepper_message_filter.h" | |
11 #include "content/public/browser/browser_thread.h" | |
12 #include "net/base/ip_endpoint.h" | |
13 #include "net/base/net_errors.h" | |
14 #include "net/socket/tcp_client_socket.h" | |
15 #include "net/socket/tcp_server_socket.h" | |
16 #include "ppapi/c/pp_errors.h" | |
17 #include "ppapi/proxy/ppapi_messages.h" | |
18 #include "ppapi/shared_impl/private/net_address_private_impl.h" | |
19 | |
20 using content::BrowserThread; | |
21 using ppapi::NetAddressPrivateImpl; | |
22 | |
23 PepperTCPServerSocket::PepperTCPServerSocket( | |
24 PepperMessageFilter* manager, | |
25 int32 routing_id, | |
26 uint32 plugin_dispatcher_id, | |
27 PP_Resource socket_resource, | |
28 uint32 socket_id) | |
29 : manager_(manager), | |
30 routing_id_(routing_id), | |
31 plugin_dispatcher_id_(plugin_dispatcher_id), | |
32 socket_resource_(socket_resource), | |
33 socket_id_(socket_id), | |
34 state_(BEFORE_LISTENING) { | |
35 DCHECK(manager); | |
36 } | |
37 | |
38 PepperTCPServerSocket::~PepperTCPServerSocket() { | |
39 } | |
40 | |
41 void PepperTCPServerSocket::Listen(const PP_NetAddress_Private& addr, | |
42 int32 backlog) { | |
43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
44 | |
45 net::IPEndPoint ip_end_point; | |
46 if (state_ != BEFORE_LISTENING || | |
47 !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &ip_end_point)) { | |
48 CancelListenRequest(); | |
49 return; | |
50 } | |
51 | |
52 state_ = LISTEN_IN_PROGRESS; | |
53 | |
54 socket_.reset(new net::TCPServerSocket(NULL, net::NetLog::Source())); | |
55 int result = socket_->Listen(ip_end_point, backlog); | |
56 if (result != net::ERR_IO_PENDING) | |
57 OnListenCompleted(result); | |
58 } | |
59 | |
60 void PepperTCPServerSocket::Accept(int32 tcp_client_socket_routing_id) { | |
61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
62 | |
63 if (state_ != LISTENING) { | |
64 SendAcceptACKError(); | |
65 return; | |
66 } | |
67 | |
68 state_ = ACCEPT_IN_PROGRESS; | |
69 | |
70 int result = socket_->Accept( | |
71 &socket_buffer_, | |
72 base::Bind(&PepperTCPServerSocket::OnAcceptCompleted, | |
73 base::Unretained(this), | |
74 tcp_client_socket_routing_id)); | |
75 if (result != net::ERR_IO_PENDING) | |
76 OnAcceptCompleted(tcp_client_socket_routing_id, result); | |
77 } | |
78 | |
79 void PepperTCPServerSocket::CancelListenRequest() { | |
80 manager_->Send(new PpapiMsg_PPBTCPServerSocket_ListenACK( | |
81 routing_id_, | |
82 plugin_dispatcher_id_, | |
83 socket_resource_, | |
84 0, | |
85 PP_ERROR_FAILED)); | |
86 BrowserThread::PostTask( | |
87 BrowserThread::IO, | |
88 FROM_HERE, | |
89 base::Bind(&PepperMessageFilter::RemoveTCPServerSocket, manager_, | |
90 socket_id_)); | |
91 } | |
92 | |
93 void PepperTCPServerSocket::SendAcceptACKError() { | |
94 manager_->Send(new PpapiMsg_PPBTCPServerSocket_AcceptACK( | |
95 routing_id_, | |
96 plugin_dispatcher_id_, | |
97 socket_id_, | |
98 0, | |
99 NetAddressPrivateImpl::kInvalidNetAddress, | |
100 NetAddressPrivateImpl::kInvalidNetAddress)); | |
101 } | |
102 | |
103 void PepperTCPServerSocket::OnListenCompleted(int result) { | |
104 DCHECK(state_ == LISTEN_IN_PROGRESS && socket_.get()); | |
105 | |
106 if (result != net::OK) { | |
107 CancelListenRequest(); | |
108 } else { | |
109 manager_->Send(new PpapiMsg_PPBTCPServerSocket_ListenACK( | |
110 routing_id_, | |
111 plugin_dispatcher_id_, | |
112 socket_resource_, | |
113 socket_id_, | |
114 PP_OK)); | |
115 state_ = LISTENING; | |
116 } | |
117 } | |
118 | |
119 void PepperTCPServerSocket::OnAcceptCompleted( | |
120 int32 tcp_client_socket_routing_id, | |
121 int result) { | |
122 DCHECK(state_ == ACCEPT_IN_PROGRESS && socket_buffer_.get()); | |
123 | |
124 if (result != net::OK) { | |
125 SendAcceptACKError(); | |
126 } else { | |
127 scoped_ptr<net::StreamSocket> socket(socket_buffer_.release()); | |
128 | |
129 net::IPEndPoint ip_end_point_local; | |
130 net::IPEndPoint ip_end_point_remote; | |
131 PP_NetAddress_Private local_addr = | |
132 NetAddressPrivateImpl::kInvalidNetAddress; | |
133 PP_NetAddress_Private remote_addr = | |
134 NetAddressPrivateImpl::kInvalidNetAddress; | |
135 | |
136 if (socket->GetLocalAddress(&ip_end_point_local) != net::OK || | |
137 !NetAddressPrivateImpl::IPEndPointToNetAddress(ip_end_point_local, | |
138 &local_addr) || | |
139 socket->GetPeerAddress(&ip_end_point_remote) != net::OK || | |
140 !NetAddressPrivateImpl::IPEndPointToNetAddress(ip_end_point_remote, | |
141 &remote_addr)) { | |
142 SendAcceptACKError(); | |
143 } else { | |
144 uint32 accepted_socket_id = | |
145 manager_->AddAcceptedTCPSocket(tcp_client_socket_routing_id, | |
146 plugin_dispatcher_id_, | |
147 socket.release()); | |
148 if (accepted_socket_id != 0) { | |
149 manager_->Send(new PpapiMsg_PPBTCPServerSocket_AcceptACK( | |
150 routing_id_, | |
151 plugin_dispatcher_id_, | |
152 socket_id_, | |
153 accepted_socket_id, | |
154 local_addr, | |
155 remote_addr)); | |
156 } else { | |
157 SendAcceptACKError(); | |
158 } | |
159 } | |
160 } | |
161 | |
162 state_ = LISTENING; | |
163 } | |
OLD | NEW |