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

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

Powered by Google App Engine
This is Rietveld 408576698