Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: ppapi/proxy/tcp_socket_resource_base.cc

Issue 24195004: PPB_TCPSocket: add support for TCP server socket operations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/tcp_socket_resource_base.h ('k') | ppapi/shared_impl/ppb_tcp_socket_shared.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ppapi/proxy/tcp_socket_resource_base.h" 5 #include "ppapi/proxy/tcp_socket_resource_base.h"
6 6
7 #include <cstring> 7 #include <cstring>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 14 matching lines...) Expand all
25 25
26 const int32_t TCPSocketResourceBase::kMaxReadSize = 1024 * 1024; 26 const int32_t TCPSocketResourceBase::kMaxReadSize = 1024 * 1024;
27 const int32_t TCPSocketResourceBase::kMaxWriteSize = 1024 * 1024; 27 const int32_t TCPSocketResourceBase::kMaxWriteSize = 1024 * 1024;
28 const int32_t TCPSocketResourceBase::kMaxSendBufferSize = 28 const int32_t TCPSocketResourceBase::kMaxSendBufferSize =
29 1024 * TCPSocketResourceBase::kMaxWriteSize; 29 1024 * TCPSocketResourceBase::kMaxWriteSize;
30 const int32_t TCPSocketResourceBase::kMaxReceiveBufferSize = 30 const int32_t TCPSocketResourceBase::kMaxReceiveBufferSize =
31 1024 * TCPSocketResourceBase::kMaxReadSize; 31 1024 * TCPSocketResourceBase::kMaxReadSize;
32 32
33 TCPSocketResourceBase::TCPSocketResourceBase(Connection connection, 33 TCPSocketResourceBase::TCPSocketResourceBase(Connection connection,
34 PP_Instance instance, 34 PP_Instance instance,
35 bool private_api) 35 TCPSocketVersion version)
36 : PluginResource(connection, instance), 36 : PluginResource(connection, instance),
37 connection_state_(BEFORE_CONNECT), 37 state_(TCPSocketState::INITIAL),
38 read_buffer_(NULL), 38 read_buffer_(NULL),
39 bytes_to_read_(-1), 39 bytes_to_read_(-1),
40 private_api_(private_api) { 40 accepted_tcp_socket_(NULL),
41 version_(version) {
41 local_addr_.size = 0; 42 local_addr_.size = 0;
42 memset(local_addr_.data, 0, 43 memset(local_addr_.data, 0,
43 arraysize(local_addr_.data) * sizeof(*local_addr_.data)); 44 arraysize(local_addr_.data) * sizeof(*local_addr_.data));
44 remote_addr_.size = 0; 45 remote_addr_.size = 0;
45 memset(remote_addr_.data, 0, 46 memset(remote_addr_.data, 0,
46 arraysize(remote_addr_.data) * sizeof(*remote_addr_.data)); 47 arraysize(remote_addr_.data) * sizeof(*remote_addr_.data));
47 } 48 }
48 49
49 TCPSocketResourceBase::TCPSocketResourceBase( 50 TCPSocketResourceBase::TCPSocketResourceBase(
50 Connection connection, 51 Connection connection,
51 PP_Instance instance, 52 PP_Instance instance,
52 bool private_api, 53 TCPSocketVersion version,
53 const PP_NetAddress_Private& local_addr, 54 const PP_NetAddress_Private& local_addr,
54 const PP_NetAddress_Private& remote_addr) 55 const PP_NetAddress_Private& remote_addr)
55 : PluginResource(connection, instance), 56 : PluginResource(connection, instance),
56 connection_state_(CONNECTED), 57 state_(TCPSocketState::CONNECTED),
57 read_buffer_(NULL), 58 read_buffer_(NULL),
58 bytes_to_read_(-1), 59 bytes_to_read_(-1),
59 local_addr_(local_addr), 60 local_addr_(local_addr),
60 remote_addr_(remote_addr), 61 remote_addr_(remote_addr),
61 private_api_(private_api) { 62 accepted_tcp_socket_(NULL),
63 version_(version) {
62 } 64 }
63 65
64 TCPSocketResourceBase::~TCPSocketResourceBase() { 66 TCPSocketResourceBase::~TCPSocketResourceBase() {
67 CloseImpl();
68 }
69
70 int32_t TCPSocketResourceBase::BindImpl(
71 const PP_NetAddress_Private* addr,
72 scoped_refptr<TrackedCallback> callback) {
73 if (!addr)
74 return PP_ERROR_BADARGUMENT;
75 if (state_.IsPending(TCPSocketState::BIND))
76 return PP_ERROR_INPROGRESS;
77 if (!state_.IsValidTransition(TCPSocketState::BIND))
78 return PP_ERROR_FAILED;
79
80 bind_callback_ = callback;
81 state_.SetPendingTransition(TCPSocketState::BIND);
82
83 Call<PpapiPluginMsg_TCPSocket_BindReply>(
84 BROWSER,
85 PpapiHostMsg_TCPSocket_Bind(*addr),
86 base::Bind(&TCPSocketResourceBase::OnPluginMsgBindReply,
87 base::Unretained(this)));
88 return PP_OK_COMPLETIONPENDING;
65 } 89 }
66 90
67 int32_t TCPSocketResourceBase::ConnectImpl( 91 int32_t TCPSocketResourceBase::ConnectImpl(
68 const char* host, 92 const char* host,
69 uint16_t port, 93 uint16_t port,
70 scoped_refptr<TrackedCallback> callback) { 94 scoped_refptr<TrackedCallback> callback) {
71 if (!host) 95 if (!host)
72 return PP_ERROR_BADARGUMENT; 96 return PP_ERROR_BADARGUMENT;
73 if (connection_state_ != BEFORE_CONNECT) 97 if (state_.IsPending(TCPSocketState::CONNECT))
98 return PP_ERROR_INPROGRESS;
99 if (!state_.IsValidTransition(TCPSocketState::CONNECT))
74 return PP_ERROR_FAILED; 100 return PP_ERROR_FAILED;
75 if (TrackedCallback::IsPending(connect_callback_))
76 return PP_ERROR_INPROGRESS; // Can only have one pending request.
77 101
78 connect_callback_ = callback; 102 connect_callback_ = callback;
103 state_.SetPendingTransition(TCPSocketState::CONNECT);
79 104
80 Call<PpapiPluginMsg_TCPSocket_ConnectReply>( 105 Call<PpapiPluginMsg_TCPSocket_ConnectReply>(
81 BROWSER, 106 BROWSER,
82 PpapiHostMsg_TCPSocket_Connect(host, port), 107 PpapiHostMsg_TCPSocket_Connect(host, port),
83 base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply, 108 base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply,
84 base::Unretained(this))); 109 base::Unretained(this)));
85 return PP_OK_COMPLETIONPENDING; 110 return PP_OK_COMPLETIONPENDING;
86 } 111 }
87 112
88 int32_t TCPSocketResourceBase::ConnectWithNetAddressImpl( 113 int32_t TCPSocketResourceBase::ConnectWithNetAddressImpl(
89 const PP_NetAddress_Private* addr, 114 const PP_NetAddress_Private* addr,
90 scoped_refptr<TrackedCallback> callback) { 115 scoped_refptr<TrackedCallback> callback) {
91 if (!addr) 116 if (!addr)
92 return PP_ERROR_BADARGUMENT; 117 return PP_ERROR_BADARGUMENT;
93 if (connection_state_ != BEFORE_CONNECT) 118 if (state_.IsPending(TCPSocketState::CONNECT))
119 return PP_ERROR_INPROGRESS;
120 if (!state_.IsValidTransition(TCPSocketState::CONNECT))
94 return PP_ERROR_FAILED; 121 return PP_ERROR_FAILED;
95 if (TrackedCallback::IsPending(connect_callback_))
96 return PP_ERROR_INPROGRESS; // Can only have one pending request.
97 122
98 connect_callback_ = callback; 123 connect_callback_ = callback;
124 state_.SetPendingTransition(TCPSocketState::CONNECT);
99 125
100 Call<PpapiPluginMsg_TCPSocket_ConnectReply>( 126 Call<PpapiPluginMsg_TCPSocket_ConnectReply>(
101 BROWSER, 127 BROWSER,
102 PpapiHostMsg_TCPSocket_ConnectWithNetAddress(*addr), 128 PpapiHostMsg_TCPSocket_ConnectWithNetAddress(*addr),
103 base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply, 129 base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply,
104 base::Unretained(this))); 130 base::Unretained(this)));
105 return PP_OK_COMPLETIONPENDING; 131 return PP_OK_COMPLETIONPENDING;
106 } 132 }
107 133
108 PP_Bool TCPSocketResourceBase::GetLocalAddressImpl( 134 PP_Bool TCPSocketResourceBase::GetLocalAddressImpl(
109 PP_NetAddress_Private* local_addr) { 135 PP_NetAddress_Private* local_addr) {
110 if (!IsConnected() || !local_addr) 136 if (!state_.IsBound() || !local_addr)
111 return PP_FALSE; 137 return PP_FALSE;
112 *local_addr = local_addr_; 138 *local_addr = local_addr_;
113 return PP_TRUE; 139 return PP_TRUE;
114 } 140 }
115 141
116 PP_Bool TCPSocketResourceBase::GetRemoteAddressImpl( 142 PP_Bool TCPSocketResourceBase::GetRemoteAddressImpl(
117 PP_NetAddress_Private* remote_addr) { 143 PP_NetAddress_Private* remote_addr) {
118 if (!IsConnected() || !remote_addr) 144 if (!state_.IsConnected() || !remote_addr)
119 return PP_FALSE; 145 return PP_FALSE;
120 *remote_addr = remote_addr_; 146 *remote_addr = remote_addr_;
121 return PP_TRUE; 147 return PP_TRUE;
122 } 148 }
123 149
124 int32_t TCPSocketResourceBase::SSLHandshakeImpl( 150 int32_t TCPSocketResourceBase::SSLHandshakeImpl(
125 const char* server_name, 151 const char* server_name,
126 uint16_t server_port, 152 uint16_t server_port,
127 scoped_refptr<TrackedCallback> callback) { 153 scoped_refptr<TrackedCallback> callback) {
128 if (!server_name) 154 if (!server_name)
129 return PP_ERROR_BADARGUMENT; 155 return PP_ERROR_BADARGUMENT;
130 156
131 if (connection_state_ != CONNECTED) 157 if (state_.IsPending(TCPSocketState::SSL_CONNECT) ||
132 return PP_ERROR_FAILED;
133 if (TrackedCallback::IsPending(ssl_handshake_callback_) ||
134 TrackedCallback::IsPending(read_callback_) || 158 TrackedCallback::IsPending(read_callback_) ||
135 TrackedCallback::IsPending(write_callback_)) { 159 TrackedCallback::IsPending(write_callback_)) {
136 return PP_ERROR_INPROGRESS; 160 return PP_ERROR_INPROGRESS;
137 } 161 }
162 if (!state_.IsValidTransition(TCPSocketState::SSL_CONNECT))
163 return PP_ERROR_FAILED;
138 164
139 ssl_handshake_callback_ = callback; 165 ssl_handshake_callback_ = callback;
166 state_.SetPendingTransition(TCPSocketState::SSL_CONNECT);
140 167
141 Call<PpapiPluginMsg_TCPSocket_SSLHandshakeReply>( 168 Call<PpapiPluginMsg_TCPSocket_SSLHandshakeReply>(
142 BROWSER, 169 BROWSER,
143 PpapiHostMsg_TCPSocket_SSLHandshake(server_name, 170 PpapiHostMsg_TCPSocket_SSLHandshake(server_name,
144 server_port, 171 server_port,
145 trusted_certificates_, 172 trusted_certificates_,
146 untrusted_certificates_), 173 untrusted_certificates_),
147 base::Bind(&TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply, 174 base::Bind(&TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply,
148 base::Unretained(this))); 175 base::Unretained(this)));
149 return PP_OK_COMPLETIONPENDING; 176 return PP_OK_COMPLETIONPENDING;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 return success; 213 return success;
187 } 214 }
188 215
189 int32_t TCPSocketResourceBase::ReadImpl( 216 int32_t TCPSocketResourceBase::ReadImpl(
190 char* buffer, 217 char* buffer,
191 int32_t bytes_to_read, 218 int32_t bytes_to_read,
192 scoped_refptr<TrackedCallback> callback) { 219 scoped_refptr<TrackedCallback> callback) {
193 if (!buffer || bytes_to_read <= 0) 220 if (!buffer || bytes_to_read <= 0)
194 return PP_ERROR_BADARGUMENT; 221 return PP_ERROR_BADARGUMENT;
195 222
196 if (!IsConnected()) 223 if (!state_.IsConnected())
197 return PP_ERROR_FAILED; 224 return PP_ERROR_FAILED;
198 if (TrackedCallback::IsPending(read_callback_) || 225 if (TrackedCallback::IsPending(read_callback_) ||
199 TrackedCallback::IsPending(ssl_handshake_callback_)) 226 state_.IsPending(TCPSocketState::SSL_CONNECT))
200 return PP_ERROR_INPROGRESS; 227 return PP_ERROR_INPROGRESS;
201 read_buffer_ = buffer; 228 read_buffer_ = buffer;
202 bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize); 229 bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize);
203 read_callback_ = callback; 230 read_callback_ = callback;
204 231
205 Call<PpapiPluginMsg_TCPSocket_ReadReply>( 232 Call<PpapiPluginMsg_TCPSocket_ReadReply>(
206 BROWSER, 233 BROWSER,
207 PpapiHostMsg_TCPSocket_Read(bytes_to_read_), 234 PpapiHostMsg_TCPSocket_Read(bytes_to_read_),
208 base::Bind(&TCPSocketResourceBase::OnPluginMsgReadReply, 235 base::Bind(&TCPSocketResourceBase::OnPluginMsgReadReply,
209 base::Unretained(this))); 236 base::Unretained(this)));
210 return PP_OK_COMPLETIONPENDING; 237 return PP_OK_COMPLETIONPENDING;
211 } 238 }
212 239
213 int32_t TCPSocketResourceBase::WriteImpl( 240 int32_t TCPSocketResourceBase::WriteImpl(
214 const char* buffer, 241 const char* buffer,
215 int32_t bytes_to_write, 242 int32_t bytes_to_write,
216 scoped_refptr<TrackedCallback> callback) { 243 scoped_refptr<TrackedCallback> callback) {
217 if (!buffer || bytes_to_write <= 0) 244 if (!buffer || bytes_to_write <= 0)
218 return PP_ERROR_BADARGUMENT; 245 return PP_ERROR_BADARGUMENT;
219 246
220 if (!IsConnected()) 247 if (!state_.IsConnected())
221 return PP_ERROR_FAILED; 248 return PP_ERROR_FAILED;
222 if (TrackedCallback::IsPending(write_callback_) || 249 if (TrackedCallback::IsPending(write_callback_) ||
223 TrackedCallback::IsPending(ssl_handshake_callback_)) 250 state_.IsPending(TCPSocketState::SSL_CONNECT))
224 return PP_ERROR_INPROGRESS; 251 return PP_ERROR_INPROGRESS;
225 252
226 if (bytes_to_write > kMaxWriteSize) 253 if (bytes_to_write > kMaxWriteSize)
227 bytes_to_write = kMaxWriteSize; 254 bytes_to_write = kMaxWriteSize;
228 255
229 write_callback_ = callback; 256 write_callback_ = callback;
230 257
231 Call<PpapiPluginMsg_TCPSocket_WriteReply>( 258 Call<PpapiPluginMsg_TCPSocket_WriteReply>(
232 BROWSER, 259 BROWSER,
233 PpapiHostMsg_TCPSocket_Write(std::string(buffer, bytes_to_write)), 260 PpapiHostMsg_TCPSocket_Write(std::string(buffer, bytes_to_write)),
234 base::Bind(&TCPSocketResourceBase::OnPluginMsgWriteReply, 261 base::Bind(&TCPSocketResourceBase::OnPluginMsgWriteReply,
235 base::Unretained(this))); 262 base::Unretained(this)));
236 return PP_OK_COMPLETIONPENDING; 263 return PP_OK_COMPLETIONPENDING;
237 } 264 }
238 265
239 void TCPSocketResourceBase::DisconnectImpl() { 266 int32_t TCPSocketResourceBase::ListenImpl(
240 if (connection_state_ == DISCONNECTED) 267 int32_t backlog,
268 scoped_refptr<TrackedCallback> callback) {
269 if (backlog <= 0)
270 return PP_ERROR_BADARGUMENT;
271 if (state_.IsPending(TCPSocketState::LISTEN))
272 return PP_ERROR_INPROGRESS;
273 if (!state_.IsValidTransition(TCPSocketState::LISTEN))
274 return PP_ERROR_FAILED;
275
276 listen_callback_ = callback;
277 state_.SetPendingTransition(TCPSocketState::LISTEN);
278
279 Call<PpapiPluginMsg_TCPSocket_ListenReply>(
280 BROWSER,
281 PpapiHostMsg_TCPSocket_Listen(backlog),
282 base::Bind(&TCPSocketResourceBase::OnPluginMsgListenReply,
283 base::Unretained(this)));
284 return PP_OK_COMPLETIONPENDING;
285 }
286
287 int32_t TCPSocketResourceBase::AcceptImpl(
288 PP_Resource* accepted_tcp_socket,
289 scoped_refptr<TrackedCallback> callback) {
290 if (!accepted_tcp_socket)
291 return PP_ERROR_BADARGUMENT;
292 if (TrackedCallback::IsPending(accept_callback_))
293 return PP_ERROR_INPROGRESS;
294 if (state_.state() != TCPSocketState::LISTENING)
295 return PP_ERROR_FAILED;
296
297 accept_callback_ = callback;
298 accepted_tcp_socket_ = accepted_tcp_socket;
299
300 Call<PpapiPluginMsg_TCPSocket_AcceptReply>(
301 BROWSER,
302 PpapiHostMsg_TCPSocket_Accept(),
303 base::Bind(&TCPSocketResourceBase::OnPluginMsgAcceptReply,
304 base::Unretained(this)));
305 return PP_OK_COMPLETIONPENDING;
306 }
307
308 void TCPSocketResourceBase::CloseImpl() {
309 if (state_.state() == TCPSocketState::CLOSED)
241 return; 310 return;
242 311
243 connection_state_ = DISCONNECTED; 312 state_.DoTransition(TCPSocketState::CLOSE, true);
244 313
245 Post(BROWSER, PpapiHostMsg_TCPSocket_Disconnect()); 314 Post(BROWSER, PpapiHostMsg_TCPSocket_Close());
246 315
316 PostAbortIfNecessary(&bind_callback_);
247 PostAbortIfNecessary(&connect_callback_); 317 PostAbortIfNecessary(&connect_callback_);
248 PostAbortIfNecessary(&ssl_handshake_callback_); 318 PostAbortIfNecessary(&ssl_handshake_callback_);
249 PostAbortIfNecessary(&read_callback_); 319 PostAbortIfNecessary(&read_callback_);
250 PostAbortIfNecessary(&write_callback_); 320 PostAbortIfNecessary(&write_callback_);
321 PostAbortIfNecessary(&listen_callback_);
322 PostAbortIfNecessary(&accept_callback_);
251 read_buffer_ = NULL; 323 read_buffer_ = NULL;
252 bytes_to_read_ = -1; 324 bytes_to_read_ = -1;
253 server_certificate_ = NULL; 325 server_certificate_ = NULL;
326 accepted_tcp_socket_ = NULL;
254 } 327 }
255 328
256 int32_t TCPSocketResourceBase::SetOptionImpl( 329 int32_t TCPSocketResourceBase::SetOptionImpl(
257 PP_TCPSocket_Option name, 330 PP_TCPSocket_Option name,
258 const PP_Var& value, 331 const PP_Var& value,
259 scoped_refptr<TrackedCallback> callback) { 332 scoped_refptr<TrackedCallback> callback) {
260 if (!IsConnected())
261 return PP_ERROR_FAILED;
262
263 SocketOptionData option_data; 333 SocketOptionData option_data;
264 switch (name) { 334 switch (name) {
265 case PP_TCPSOCKET_OPTION_NO_DELAY: { 335 case PP_TCPSOCKET_OPTION_NO_DELAY: {
336 if (!state_.IsConnected())
337 return PP_ERROR_FAILED;
338
266 if (value.type != PP_VARTYPE_BOOL) 339 if (value.type != PP_VARTYPE_BOOL)
267 return PP_ERROR_BADARGUMENT; 340 return PP_ERROR_BADARGUMENT;
268 option_data.SetBool(PP_ToBool(value.value.as_bool)); 341 option_data.SetBool(PP_ToBool(value.value.as_bool));
269 break; 342 break;
270 } 343 }
271 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: 344 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE:
272 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { 345 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: {
346 if (!state_.IsConnected())
347 return PP_ERROR_FAILED;
348
273 if (value.type != PP_VARTYPE_INT32) 349 if (value.type != PP_VARTYPE_INT32)
274 return PP_ERROR_BADARGUMENT; 350 return PP_ERROR_BADARGUMENT;
275 option_data.SetInt32(value.value.as_int); 351 option_data.SetInt32(value.value.as_int);
276 break; 352 break;
277 } 353 }
354 case PP_TCPSOCKET_OPTION_ADDRESS_REUSE: {
355 if (version_ != TCP_SOCKET_VERSION_1_1_OR_ABOVE)
356 return PP_ERROR_NOTSUPPORTED;
357 if (state_.state() != TCPSocketState::INITIAL)
358 return PP_ERROR_FAILED;
359
360 if (value.type != PP_VARTYPE_BOOL)
361 return PP_ERROR_BADARGUMENT;
362 option_data.SetBool(PP_ToBool(value.value.as_bool));
363 break;
364 }
278 default: { 365 default: {
279 NOTREACHED(); 366 NOTREACHED();
280 return PP_ERROR_BADARGUMENT; 367 return PP_ERROR_BADARGUMENT;
281 } 368 }
282 } 369 }
283 370
284 set_option_callbacks_.push(callback); 371 set_option_callbacks_.push(callback);
285 372
286 Call<PpapiPluginMsg_TCPSocket_SetOptionReply>( 373 Call<PpapiPluginMsg_TCPSocket_SetOptionReply>(
287 BROWSER, 374 BROWSER,
288 PpapiHostMsg_TCPSocket_SetOption(name, option_data), 375 PpapiHostMsg_TCPSocket_SetOption(name, option_data),
289 base::Bind(&TCPSocketResourceBase::OnPluginMsgSetOptionReply, 376 base::Bind(&TCPSocketResourceBase::OnPluginMsgSetOptionReply,
290 base::Unretained(this))); 377 base::Unretained(this)));
291 return PP_OK_COMPLETIONPENDING; 378 return PP_OK_COMPLETIONPENDING;
292 } 379 }
293 380
294 bool TCPSocketResourceBase::IsConnected() const {
295 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED;
296 }
297
298 void TCPSocketResourceBase::PostAbortIfNecessary( 381 void TCPSocketResourceBase::PostAbortIfNecessary(
299 scoped_refptr<TrackedCallback>* callback) { 382 scoped_refptr<TrackedCallback>* callback) {
300 if (TrackedCallback::IsPending(*callback)) 383 if (TrackedCallback::IsPending(*callback))
301 (*callback)->PostAbort(); 384 (*callback)->PostAbort();
302 } 385 }
303 386
387 void TCPSocketResourceBase::OnPluginMsgBindReply(
388 const ResourceMessageReplyParams& params,
389 const PP_NetAddress_Private& local_addr) {
390 // It is possible that CloseImpl() has been called. We don't want to update
391 // class members in this case.
392 if (!state_.IsPending(TCPSocketState::BIND))
393 return;
394
395 DCHECK(TrackedCallback::IsPending(bind_callback_));
396 if (params.result() == PP_OK) {
397 local_addr_ = local_addr;
398 state_.CompletePendingTransition(true);
399 } else {
400 state_.CompletePendingTransition(false);
401 }
402 RunCallback(bind_callback_, params.result());
403 }
404
304 void TCPSocketResourceBase::OnPluginMsgConnectReply( 405 void TCPSocketResourceBase::OnPluginMsgConnectReply(
305 const ResourceMessageReplyParams& params, 406 const ResourceMessageReplyParams& params,
306 const PP_NetAddress_Private& local_addr, 407 const PP_NetAddress_Private& local_addr,
307 const PP_NetAddress_Private& remote_addr) { 408 const PP_NetAddress_Private& remote_addr) {
308 // It is possible that |connect_callback_| is pending while 409 // It is possible that CloseImpl() has been called. We don't want to update
309 // |connection_state_| is not BEFORE_CONNECT: DisconnectImpl() has been 410 // class members in this case.
310 // called, but a ConnectCompleted notification came earlier than the task to 411 if (!state_.IsPending(TCPSocketState::CONNECT))
311 // abort |connect_callback_|. We don't want to update |connection_state_| or
312 // other members in that case.
313 if (connection_state_ != BEFORE_CONNECT ||
314 !TrackedCallback::IsPending(connect_callback_)) {
315 return; 412 return;
316 }
317 413
414 DCHECK(TrackedCallback::IsPending(connect_callback_));
318 if (params.result() == PP_OK) { 415 if (params.result() == PP_OK) {
319 local_addr_ = local_addr; 416 local_addr_ = local_addr;
320 remote_addr_ = remote_addr; 417 remote_addr_ = remote_addr;
321 connection_state_ = CONNECTED; 418 state_.CompletePendingTransition(true);
419 } else {
420 if (version_ == TCP_SOCKET_VERSION_1_1_OR_ABOVE) {
421 state_.CompletePendingTransition(false);
422 } else {
423 // In order to maintain backward compatibility, allow to connect the
424 // socket again.
425 state_ = TCPSocketState(TCPSocketState::INITIAL);
426 }
322 } 427 }
323 RunCallback(connect_callback_, params.result()); 428 RunCallback(connect_callback_, params.result());
324 } 429 }
325 430
326 void TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply( 431 void TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply(
327 const ResourceMessageReplyParams& params, 432 const ResourceMessageReplyParams& params,
328 const PPB_X509Certificate_Fields& certificate_fields) { 433 const PPB_X509Certificate_Fields& certificate_fields) {
329 // It is possible that |ssl_handshake_callback_| is pending while 434 // It is possible that CloseImpl() has been called. We don't want to
330 // |connection_state_| is not CONNECT: DisconnectImpl() has been 435 // update class members in this case.
331 // called, but a SSLHandshakeCompleted notification came earlier than the task 436 if (!state_.IsPending(TCPSocketState::SSL_CONNECT))
332 // to abort |ssl_handshake_callback_|. We don't want to update
333 // |connection_state_| or other members in that case.
334 if (connection_state_ != CONNECTED ||
335 !TrackedCallback::IsPending(ssl_handshake_callback_)) {
336 return; 437 return;
337 }
338 438
439 DCHECK(TrackedCallback::IsPending(ssl_handshake_callback_));
339 if (params.result() == PP_OK) { 440 if (params.result() == PP_OK) {
340 connection_state_ = SSL_CONNECTED; 441 state_.CompletePendingTransition(true);
341 server_certificate_ = new PPB_X509Certificate_Private_Shared( 442 server_certificate_ = new PPB_X509Certificate_Private_Shared(
342 OBJECT_IS_PROXY, 443 OBJECT_IS_PROXY,
343 pp_instance(), 444 pp_instance(),
344 certificate_fields); 445 certificate_fields);
345 RunCallback(ssl_handshake_callback_, params.result());
346 } else { 446 } else {
347 // The resource might be released in the callback so we need to hold 447 state_.CompletePendingTransition(false);
348 // a reference so we can Disconnect() first.
349 AddRef();
350 RunCallback(ssl_handshake_callback_, params.result());
351 DisconnectImpl();
352 Release();
353 } 448 }
449 RunCallback(ssl_handshake_callback_, params.result());
354 } 450 }
355 451
356 void TCPSocketResourceBase::OnPluginMsgReadReply( 452 void TCPSocketResourceBase::OnPluginMsgReadReply(
357 const ResourceMessageReplyParams& params, 453 const ResourceMessageReplyParams& params,
358 const std::string& data) { 454 const std::string& data) {
359 // It is possible that |read_callback_| is pending while |read_buffer_| is 455 // It is possible that CloseImpl() has been called. We shouldn't access the
360 // NULL: DisconnectImpl() has been called, but a ReadCompleted notification 456 // buffer in that case. The user may have released it.
361 // came earlier than the task to abort |read_callback_|. We shouldn't access 457 if (!state_.IsConnected() || !TrackedCallback::IsPending(read_callback_) ||
362 // the buffer in that case. The user may have released it. 458 !read_buffer_) {
363 if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_)
364 return; 459 return;
460 }
365 461
366 const bool succeeded = params.result() == PP_OK; 462 const bool succeeded = params.result() == PP_OK;
367 if (succeeded) { 463 if (succeeded) {
368 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_); 464 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
369 if (!data.empty()) 465 if (!data.empty())
370 memmove(read_buffer_, data.c_str(), data.size()); 466 memmove(read_buffer_, data.c_str(), data.size());
371 } 467 }
372 read_buffer_ = NULL; 468 read_buffer_ = NULL;
373 bytes_to_read_ = -1; 469 bytes_to_read_ = -1;
374 470
375 read_callback_->Run(succeeded ? 471 RunCallback(read_callback_,
376 static_cast<int32_t>(data.size()) : 472 succeeded ? static_cast<int32_t>(data.size()) : params.result());
377 ConvertNetworkAPIErrorForCompatibility(params.result(),
378 private_api_));
379 } 473 }
380 474
381 void TCPSocketResourceBase::OnPluginMsgWriteReply( 475 void TCPSocketResourceBase::OnPluginMsgWriteReply(
382 const ResourceMessageReplyParams& params) { 476 const ResourceMessageReplyParams& params) {
383 if (!TrackedCallback::IsPending(write_callback_)) 477 if (!state_.IsConnected() || !TrackedCallback::IsPending(write_callback_))
384 return; 478 return;
385 RunCallback(write_callback_, params.result()); 479 RunCallback(write_callback_, params.result());
386 } 480 }
387 481
482 void TCPSocketResourceBase::OnPluginMsgListenReply(
483 const ResourceMessageReplyParams& params) {
484 if (!state_.IsPending(TCPSocketState::LISTEN))
485 return;
486
487 DCHECK(TrackedCallback::IsPending(listen_callback_));
488 state_.CompletePendingTransition(params.result() == PP_OK);
489
490 RunCallback(listen_callback_, params.result());
491 }
492
493 void TCPSocketResourceBase::OnPluginMsgAcceptReply(
494 const ResourceMessageReplyParams& params,
495 int pending_host_id,
496 const PP_NetAddress_Private& local_addr,
497 const PP_NetAddress_Private& remote_addr) {
498 // It is possible that CloseImpl() has been called. We shouldn't access the
499 // output parameter in that case. The user may have released it.
500 if (state_.state() != TCPSocketState::LISTENING ||
501 !TrackedCallback::IsPending(accept_callback_) || !accepted_tcp_socket_) {
502 return;
503 }
504
505 if (params.result() == PP_OK) {
506 *accepted_tcp_socket_ = CreateAcceptedSocket(pending_host_id, local_addr,
507 remote_addr);
508 }
509 accepted_tcp_socket_ = NULL;
510 RunCallback(accept_callback_, params.result());
511 }
512
388 void TCPSocketResourceBase::OnPluginMsgSetOptionReply( 513 void TCPSocketResourceBase::OnPluginMsgSetOptionReply(
389 const ResourceMessageReplyParams& params) { 514 const ResourceMessageReplyParams& params) {
390 if (set_option_callbacks_.empty()) { 515 if (set_option_callbacks_.empty()) {
391 NOTREACHED(); 516 NOTREACHED();
392 return; 517 return;
393 } 518 }
394 scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front(); 519 scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front();
395 set_option_callbacks_.pop(); 520 set_option_callbacks_.pop();
396 if (TrackedCallback::IsPending(callback)) 521 if (TrackedCallback::IsPending(callback))
397 RunCallback(callback, params.result()); 522 RunCallback(callback, params.result());
398 } 523 }
399 524
400 void TCPSocketResourceBase::RunCallback(scoped_refptr<TrackedCallback> callback, 525 void TCPSocketResourceBase::RunCallback(scoped_refptr<TrackedCallback> callback,
401 int32_t pp_result) { 526 int32_t pp_result) {
402 callback->Run(ConvertNetworkAPIErrorForCompatibility(pp_result, 527 callback->Run(ConvertNetworkAPIErrorForCompatibility(
403 private_api_)); 528 pp_result, version_ == TCP_SOCKET_VERSION_PRIVATE));
404 } 529 }
405 530
406 } // namespace ppapi 531 } // namespace ppapi
407 } // namespace proxy 532 } // namespace proxy
OLDNEW
« no previous file with comments | « ppapi/proxy/tcp_socket_resource_base.h ('k') | ppapi/shared_impl/ppb_tcp_socket_shared.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698