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

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

Issue 23064006: Test issue. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Refactored PepperMessageFilter. Created 7 years, 4 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_base_resource.h ('k') | ppapi/proxy/tcp_socket_private_resource.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/shared_impl/tcp_socket_shared.h" 5 #include "ppapi/proxy/tcp_socket_base_resource.h"
6 6
7 #include <string.h> 7 #include <cstring>
8 8
9 #include <algorithm>
10
11 #include "base/basictypes.h"
12 #include "base/bind.h"
13 #include "base/logging.h"
14 #include "ppapi/c/pp_bool.h"
15 #include "ppapi/c/pp_completion_callback.h"
16 #include "ppapi/c/pp_errors.h" 9 #include "ppapi/c/pp_errors.h"
17 #include "ppapi/shared_impl/ppapi_globals.h" 10 #include "ppapi/proxy/ppapi_messages.h"
18 #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" 11 #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
19 #include "ppapi/shared_impl/socket_option_data.h" 12 #include "ppapi/shared_impl/socket_option_data.h"
13 #include "ppapi/shared_impl/var.h"
20 #include "ppapi/shared_impl/var_tracker.h" 14 #include "ppapi/shared_impl/var_tracker.h"
21 #include "ppapi/shared_impl/var.h"
22 #include "ppapi/thunk/enter.h" 15 #include "ppapi/thunk/enter.h"
23 #include "ppapi/thunk/ppb_x509_certificate_private_api.h"
24 16
25 namespace ppapi { 17 namespace ppapi {
18 namespace proxy {
26 19
27 const int32_t TCPSocketShared::kMaxReadSize = 1024 * 1024; 20 namespace {
28 const int32_t TCPSocketShared::kMaxWriteSize = 1024 * 1024;
29 const int32_t TCPSocketShared::kMaxSendBufferSize =
30 1024 * TCPSocketShared::kMaxWriteSize;
31 const int32_t TCPSocketShared::kMaxReceiveBufferSize =
32 1024 * TCPSocketShared::kMaxReadSize;
33 21
34 TCPSocketShared::TCPSocketShared(ResourceObjectType resource_type, 22 int32_t ConvertPPError(int32_t pp_error, bool private_api) {
35 uint32 socket_id) 23 // The private API doesn't return network-specific error codes or
36 : resource_type_(resource_type) { 24 // PP_ERROR_NOACCESS. In order to preserve the behavior, we convert those to
37 Init(socket_id); 25 // PP_ERROR_FAILED.
38 } 26 if (private_api &&
39 27 (pp_error <= PP_ERROR_CONNECTION_CLOSED ||
40 TCPSocketShared::~TCPSocketShared() { 28 pp_error == PP_ERROR_NOACCESS)) {
41 } 29 return PP_ERROR_FAILED;
42
43 void TCPSocketShared::OnConnectCompleted(
44 int32_t result,
45 const PP_NetAddress_Private& local_addr,
46 const PP_NetAddress_Private& remote_addr) {
47 // It is possible that |connect_callback_| is pending while
48 // |connection_state_| is not BEFORE_CONNECT: DisconnectImpl() has been
49 // called, but a ConnectCompleted notification came earlier than the task to
50 // abort |connect_callback_|. We don't want to update |connection_state_| or
51 // other members in that case.
52 if (connection_state_ != BEFORE_CONNECT ||
53 !TrackedCallback::IsPending(connect_callback_)) {
54 return;
55 } 30 }
56
57 result = OverridePPError(result);
58 if (result == PP_OK) {
59 local_addr_ = local_addr;
60 remote_addr_ = remote_addr;
61 connection_state_ = CONNECTED;
62 }
63 connect_callback_->Run(result);
64 }
65
66 void TCPSocketShared::OnSSLHandshakeCompleted(
67 bool succeeded,
68 const PPB_X509Certificate_Fields& certificate_fields) {
69 // It is possible that |ssl_handshake_callback_| is pending while
70 // |connection_state_| is not CONNECT: DisconnectImpl() has been
71 // called, but a SSLHandshakeCompleted notification came earlier than the task
72 // to abort |ssl_handshake_callback_|. We don't want to update
73 // |connection_state_| or other members in that case.
74 if (connection_state_ != CONNECTED ||
75 !TrackedCallback::IsPending(ssl_handshake_callback_)) {
76 return;
77 }
78
79 if (succeeded) {
80 connection_state_ = SSL_CONNECTED;
81 server_certificate_ = new PPB_X509Certificate_Private_Shared(
82 resource_type_,
83 GetOwnerResource()->pp_instance(),
84 certificate_fields);
85 ssl_handshake_callback_->Run(PP_OK);
86 } else {
87 // The resource might be released in the callback so we need to hold
88 // a reference so we can Disconnect() first.
89 GetOwnerResource()->AddRef();
90 ssl_handshake_callback_->Run(PP_ERROR_FAILED);
91 DisconnectImpl();
92 GetOwnerResource()->Release();
93 }
94 }
95
96 void TCPSocketShared::OnReadCompleted(int32_t result,
97 const std::string& data) {
98 // It is possible that |read_callback_| is pending while |read_buffer_| is
99 // NULL: DisconnectImpl() has been called, but a ReadCompleted notification
100 // came earlier than the task to abort |read_callback_|. We shouldn't access
101 // the buffer in that case. The user may have released it.
102 if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_)
103 return;
104
105 result = OverridePPError(result);
106 bool succeeded = result == PP_OK;
107 if (succeeded) {
108 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
109 if (!data.empty())
110 memcpy(read_buffer_, data.c_str(), data.size());
111 }
112 read_buffer_ = NULL;
113 bytes_to_read_ = -1;
114
115 read_callback_->Run(
116 succeeded ? static_cast<int32_t>(data.size()) : result);
117 }
118
119 void TCPSocketShared::OnWriteCompleted(int32_t result) {
120 if (!TrackedCallback::IsPending(write_callback_))
121 return;
122
123 result = OverridePPError(result);
124 write_callback_->Run(result);
125 }
126
127 void TCPSocketShared::OnSetOptionCompleted(int32_t result) {
128 if (set_option_callbacks_.empty()) {
129 NOTREACHED();
130 return;
131 }
132
133 result = OverridePPError(result);
134 scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front();
135 set_option_callbacks_.pop();
136
137 if (TrackedCallback::IsPending(callback))
138 callback->Run(result);
139 }
140
141 int32_t TCPSocketShared::OverridePPError(int32_t pp_error) {
142 return pp_error; 31 return pp_error;
143 } 32 }
144 33
145 int32_t TCPSocketShared::ConnectImpl(const char* host, 34 } // namespace
146 uint16_t port, 35
147 scoped_refptr<TrackedCallback> callback) { 36 const int32_t TCPSocketBaseResource::kMaxReadSize = 1024 * 1024;
37 const int32_t TCPSocketBaseResource::kMaxWriteSize = 1024 * 1024;
38 const int32_t TCPSocketBaseResource::kMaxSendBufferSize =
39 1024 * TCPSocketBaseResource::kMaxWriteSize;
40 const int32_t TCPSocketBaseResource::kMaxReceiveBufferSize =
41 1024 * TCPSocketBaseResource::kMaxReadSize;
42
43 TCPSocketBaseResource::TCPSocketBaseResource(Connection connection,
44 PP_Instance instance,
45 bool private_api)
46 : PluginResource(connection, instance),
47 connection_state_(BEFORE_CONNECT),
48 read_buffer_(NULL),
49 bytes_to_read_(-1),
50 private_api_(private_api) {
51 local_addr_.size = 0;
52 memset(local_addr_.data, 0,
53 arraysize(local_addr_.data) * sizeof(*local_addr_.data));
54 remote_addr_.size = 0;
55 memset(remote_addr_.data, 0,
56 arraysize(remote_addr_.data) * sizeof(*remote_addr_.data));
57 }
58
59 TCPSocketBaseResource::TCPSocketBaseResource(
60 Connection connection,
61 PP_Instance instance,
62 bool private_api,
63 const PP_NetAddress_Private& local_addr,
64 const PP_NetAddress_Private& remote_addr)
65 : PluginResource(connection, instance),
66 connection_state_(CONNECTED),
67 read_buffer_(NULL),
68 bytes_to_read_(-1),
69 private_api_(private_api) {
70 local_addr_ = local_addr_;
71 remote_addr_ = remote_addr_;
72 }
73
74 TCPSocketBaseResource::~TCPSocketBaseResource() {
75 }
76
77 int32_t TCPSocketBaseResource::ConnectImpl(
78 const char* host,
79 uint16_t port,
80 scoped_refptr<TrackedCallback> callback) {
148 if (!host) 81 if (!host)
149 return PP_ERROR_BADARGUMENT; 82 return PP_ERROR_BADARGUMENT;
150 if (connection_state_ != BEFORE_CONNECT) 83 if (connection_state_ != BEFORE_CONNECT)
151 return PP_ERROR_FAILED; 84 return PP_ERROR_FAILED;
152 if (TrackedCallback::IsPending(connect_callback_)) 85 if (TrackedCallback::IsPending(connect_callback_))
153 return PP_ERROR_INPROGRESS; // Can only have one pending request. 86 return PP_ERROR_INPROGRESS; // Can only have one pending request.
154 87
155 connect_callback_ = callback; 88 connect_callback_ = callback;
156 // Send the request, the browser will call us back via ConnectACK. 89
157 SendConnect(host, port); 90 Call<PpapiPluginMsg_TCPSocket_ConnectReply>(
91 BROWSER,
92 PpapiHostMsg_TCPSocket_Connect(host, port),
93 base::Bind(&TCPSocketBaseResource::OnPluginMsgConnectReply,
94 base::Unretained(this)));
158 return PP_OK_COMPLETIONPENDING; 95 return PP_OK_COMPLETIONPENDING;
159 } 96 }
160 97
161 int32_t TCPSocketShared::ConnectWithNetAddressImpl( 98 int32_t TCPSocketBaseResource::ConnectWithNetAddressImpl(
162 const PP_NetAddress_Private* addr, 99 const PP_NetAddress_Private* addr,
163 scoped_refptr<TrackedCallback> callback) { 100 scoped_refptr<TrackedCallback> callback) {
164 if (!addr) 101 if (!addr)
165 return PP_ERROR_BADARGUMENT; 102 return PP_ERROR_BADARGUMENT;
166 if (connection_state_ != BEFORE_CONNECT) 103 if (connection_state_ != BEFORE_CONNECT)
167 return PP_ERROR_FAILED; 104 return PP_ERROR_FAILED;
168 if (TrackedCallback::IsPending(connect_callback_)) 105 if (TrackedCallback::IsPending(connect_callback_))
169 return PP_ERROR_INPROGRESS; // Can only have one pending request. 106 return PP_ERROR_INPROGRESS; // Can only have one pending request.
170 107
171 connect_callback_ = callback; 108 connect_callback_ = callback;
172 // Send the request, the browser will call us back via ConnectACK. 109
173 SendConnectWithNetAddress(*addr); 110 Call<PpapiPluginMsg_TCPSocket_ConnectReply>(
111 BROWSER,
112 PpapiHostMsg_TCPSocket_ConnectWithNetAddress(*addr),
113 base::Bind(&TCPSocketBaseResource::OnPluginMsgConnectReply,
114 base::Unretained(this)));
174 return PP_OK_COMPLETIONPENDING; 115 return PP_OK_COMPLETIONPENDING;
175 } 116 }
176 117
177 PP_Bool TCPSocketShared::GetLocalAddressImpl( 118 PP_Bool TCPSocketBaseResource::GetLocalAddressImpl(
178 PP_NetAddress_Private* local_addr) { 119 PP_NetAddress_Private* local_addr) {
179 if (!IsConnected() || !local_addr) 120 if (!IsConnected() || !local_addr)
180 return PP_FALSE; 121 return PP_FALSE;
181
182 *local_addr = local_addr_; 122 *local_addr = local_addr_;
183 return PP_TRUE; 123 return PP_TRUE;
184 } 124 }
185 125
186 PP_Bool TCPSocketShared::GetRemoteAddressImpl( 126 PP_Bool TCPSocketBaseResource::GetRemoteAddressImpl(
187 PP_NetAddress_Private* remote_addr) { 127 PP_NetAddress_Private* remote_addr) {
188 if (!IsConnected() || !remote_addr) 128 if (!IsConnected() || !remote_addr)
189 return PP_FALSE; 129 return PP_FALSE;
190
191 *remote_addr = remote_addr_; 130 *remote_addr = remote_addr_;
192 return PP_TRUE; 131 return PP_TRUE;
193 } 132 }
194 133
195 int32_t TCPSocketShared::SSLHandshakeImpl( 134 int32_t TCPSocketBaseResource::SSLHandshakeImpl(
196 const char* server_name, 135 const char* server_name,
197 uint16_t server_port, 136 uint16_t server_port,
198 scoped_refptr<TrackedCallback> callback) { 137 scoped_refptr<TrackedCallback> callback) {
199 if (!server_name) 138 if (!server_name)
200 return PP_ERROR_BADARGUMENT; 139 return PP_ERROR_BADARGUMENT;
201 140
202 if (connection_state_ != CONNECTED) 141 if (connection_state_ != CONNECTED)
203 return PP_ERROR_FAILED; 142 return PP_ERROR_FAILED;
204 if (TrackedCallback::IsPending(ssl_handshake_callback_) || 143 if (TrackedCallback::IsPending(ssl_handshake_callback_) ||
205 TrackedCallback::IsPending(read_callback_) || 144 TrackedCallback::IsPending(read_callback_) ||
206 TrackedCallback::IsPending(write_callback_)) 145 TrackedCallback::IsPending(write_callback_)) {
207 return PP_ERROR_INPROGRESS; 146 return PP_ERROR_INPROGRESS;
147 }
208 148
209 ssl_handshake_callback_ = callback; 149 ssl_handshake_callback_ = callback;
210 150
211 // Send the request, the browser will call us back via SSLHandshakeACK. 151 Call<PpapiPluginMsg_TCPSocket_SSLHandshakeReply>(
212 SendSSLHandshake(server_name, server_port, trusted_certificates_, 152 BROWSER,
213 untrusted_certificates_); 153 PpapiHostMsg_TCPSocket_SSLHandshake(server_name,
154 server_port,
155 trusted_certificates_,
156 untrusted_certificates_),
157 base::Bind(&TCPSocketBaseResource::OnPluginMsgSSLHandshakeReply,
158 base::Unretained(this)));
214 return PP_OK_COMPLETIONPENDING; 159 return PP_OK_COMPLETIONPENDING;
215 } 160 }
216 161
217 PP_Resource TCPSocketShared::GetServerCertificateImpl() { 162 PP_Resource TCPSocketBaseResource::GetServerCertificateImpl() {
218 if (!server_certificate_.get()) 163 if (!server_certificate_.get())
219 return 0; 164 return 0;
220 return server_certificate_->GetReference(); 165 return server_certificate_->GetReference();
221 } 166 }
222 167
223 PP_Bool TCPSocketShared::AddChainBuildingCertificateImpl( 168 PP_Bool TCPSocketBaseResource::AddChainBuildingCertificateImpl(
224 PP_Resource certificate, 169 PP_Resource certificate,
225 PP_Bool trusted) { 170 PP_Bool trusted) {
226 // TODO(raymes): The plumbing for this functionality is implemented but the 171 // TODO(raymes): The plumbing for this functionality is implemented but the
227 // certificates aren't yet used for the connection, so just return false for 172 // certificates aren't yet used for the connection, so just return false for
228 // now. 173 // now.
229 return PP_FALSE; 174 return PP_FALSE;
230 175
231 thunk::EnterResourceNoLock<thunk::PPB_X509Certificate_Private_API> 176 thunk::EnterResourceNoLock<thunk::PPB_X509Certificate_Private_API>
232 enter_cert(certificate, true); 177 enter_cert(certificate, true);
233 if (enter_cert.failed()) 178 if (enter_cert.failed())
(...skipping 10 matching lines...) Expand all
244 if (PP_ToBool(trusted)) 189 if (PP_ToBool(trusted))
245 trusted_certificates_.push_back(der); 190 trusted_certificates_.push_back(der);
246 else 191 else
247 untrusted_certificates_.push_back(der); 192 untrusted_certificates_.push_back(der);
248 success = PP_TRUE; 193 success = PP_TRUE;
249 } 194 }
250 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(der_var); 195 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(der_var);
251 return success; 196 return success;
252 } 197 }
253 198
254 int32_t TCPSocketShared::ReadImpl(char* buffer, 199 int32_t TCPSocketBaseResource::ReadImpl(
255 int32_t bytes_to_read, 200 char* buffer,
256 scoped_refptr<TrackedCallback> callback) { 201 int32_t bytes_to_read,
202 scoped_refptr<TrackedCallback> callback) {
257 if (!buffer || bytes_to_read <= 0) 203 if (!buffer || bytes_to_read <= 0)
258 return PP_ERROR_BADARGUMENT; 204 return PP_ERROR_BADARGUMENT;
259 205
260 if (!IsConnected()) 206 if (!IsConnected())
261 return PP_ERROR_FAILED; 207 return PP_ERROR_FAILED;
262 if (TrackedCallback::IsPending(read_callback_) || 208 if (TrackedCallback::IsPending(read_callback_) ||
263 TrackedCallback::IsPending(ssl_handshake_callback_)) 209 TrackedCallback::IsPending(ssl_handshake_callback_))
264 return PP_ERROR_INPROGRESS; 210 return PP_ERROR_INPROGRESS;
265 read_buffer_ = buffer; 211 read_buffer_ = buffer;
266 bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize); 212 bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize);
267 read_callback_ = callback; 213 read_callback_ = callback;
268 214
269 // Send the request, the browser will call us back via ReadACK. 215 Call<PpapiPluginMsg_TCPSocket_ReadReply>(
270 SendRead(bytes_to_read_); 216 BROWSER,
217 PpapiHostMsg_TCPSocket_Read(bytes_to_read),
218 base::Bind(&TCPSocketBaseResource::OnPluginMsgReadReply,
219 base::Unretained(this)));
271 return PP_OK_COMPLETIONPENDING; 220 return PP_OK_COMPLETIONPENDING;
272 } 221 }
273 222
274 int32_t TCPSocketShared::WriteImpl(const char* buffer, 223 int32_t TCPSocketBaseResource::WriteImpl(
275 int32_t bytes_to_write, 224 const char* buffer,
276 scoped_refptr<TrackedCallback> callback) { 225 int32_t bytes_to_write,
226 scoped_refptr<TrackedCallback> callback) {
277 if (!buffer || bytes_to_write <= 0) 227 if (!buffer || bytes_to_write <= 0)
278 return PP_ERROR_BADARGUMENT; 228 return PP_ERROR_BADARGUMENT;
279 229
280 if (!IsConnected()) 230 if (!IsConnected())
281 return PP_ERROR_FAILED; 231 return PP_ERROR_FAILED;
282 if (TrackedCallback::IsPending(write_callback_) || 232 if (TrackedCallback::IsPending(write_callback_) ||
283 TrackedCallback::IsPending(ssl_handshake_callback_)) 233 TrackedCallback::IsPending(ssl_handshake_callback_))
284 return PP_ERROR_INPROGRESS; 234 return PP_ERROR_INPROGRESS;
285 235
286 if (bytes_to_write > kMaxWriteSize) 236 if (bytes_to_write > kMaxWriteSize)
287 bytes_to_write = kMaxWriteSize; 237 bytes_to_write = kMaxWriteSize;
288 238
289 write_callback_ = callback; 239 write_callback_ = callback;
290 240
291 // Send the request, the browser will call us back via WriteACK. 241 Call<PpapiPluginMsg_TCPSocket_WriteReply>(
292 SendWrite(std::string(buffer, bytes_to_write)); 242 BROWSER,
243 PpapiHostMsg_TCPSocket_Write(std::string(buffer, bytes_to_write)),
244 base::Bind(&TCPSocketBaseResource::OnPluginMsgWriteReply,
245 base::Unretained(this)));
293 return PP_OK_COMPLETIONPENDING; 246 return PP_OK_COMPLETIONPENDING;
294 } 247 }
295 248
296 void TCPSocketShared::DisconnectImpl() { 249 void TCPSocketBaseResource::DisconnectImpl() {
297 if (connection_state_ == DISCONNECTED) 250 if (connection_state_ == DISCONNECTED)
298 return; 251 return;
299 252
300 connection_state_ = DISCONNECTED; 253 connection_state_ = DISCONNECTED;
301 254
302 SendDisconnect(); 255 Post(BROWSER, PpapiHostMsg_TCPSocket_Disconnect());
303 socket_id_ = 0;
304 256
305 PostAbortIfNecessary(&connect_callback_); 257 PostAbortIfNecessary(&connect_callback_);
306 PostAbortIfNecessary(&ssl_handshake_callback_); 258 PostAbortIfNecessary(&ssl_handshake_callback_);
307 PostAbortIfNecessary(&read_callback_); 259 PostAbortIfNecessary(&read_callback_);
308 PostAbortIfNecessary(&write_callback_); 260 PostAbortIfNecessary(&write_callback_);
309 read_buffer_ = NULL; 261 read_buffer_ = NULL;
310 bytes_to_read_ = -1; 262 bytes_to_read_ = -1;
311 server_certificate_ = NULL; 263 server_certificate_ = NULL;
312 } 264 }
313 265
314 int32_t TCPSocketShared::SetOptionImpl( 266 int32_t TCPSocketBaseResource::SetOptionImpl(
315 PP_TCPSocket_Option name, 267 PP_TCPSocket_Option name,
316 const PP_Var& value, 268 const PP_Var& value,
317 scoped_refptr<TrackedCallback> callback) { 269 scoped_refptr<TrackedCallback> callback) {
318 if (!IsConnected()) 270 if (!IsConnected())
319 return PP_ERROR_FAILED; 271 return PP_ERROR_FAILED;
320 272
321 SocketOptionData option_data; 273 SocketOptionData option_data;
322 switch (name) { 274 switch (name) {
323 case PP_TCPSOCKET_OPTION_NO_DELAY: { 275 case PP_TCPSOCKET_OPTION_NO_DELAY: {
324 if (value.type != PP_VARTYPE_BOOL) 276 if (value.type != PP_VARTYPE_BOOL)
325 return PP_ERROR_BADARGUMENT; 277 return PP_ERROR_BADARGUMENT;
326 option_data.SetBool(PP_ToBool(value.value.as_bool)); 278 option_data.SetBool(PP_ToBool(value.value.as_bool));
327 break; 279 break;
328 } 280 }
329 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: 281 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE:
330 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { 282 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: {
331 if (value.type != PP_VARTYPE_INT32) 283 if (value.type != PP_VARTYPE_INT32)
332 return PP_ERROR_BADARGUMENT; 284 return PP_ERROR_BADARGUMENT;
333 option_data.SetInt32(value.value.as_int); 285 option_data.SetInt32(value.value.as_int);
334 break; 286 break;
335 } 287 }
336 default: { 288 default: {
337 NOTREACHED(); 289 NOTREACHED();
338 return PP_ERROR_BADARGUMENT; 290 return PP_ERROR_BADARGUMENT;
339 } 291 }
340 } 292 }
341 293
342 set_option_callbacks_.push(callback); 294 set_option_callbacks_.push(callback);
343 SendSetOption(name, option_data); 295
296 Call<PpapiPluginMsg_TCPSocket_SetOptionReply>(
297 BROWSER,
298 PpapiHostMsg_TCPSocket_SetOption(name, option_data),
299 base::Bind(&TCPSocketBaseResource::OnPluginMsgSetOptionReply,
300 base::Unretained(this)));
344 return PP_OK_COMPLETIONPENDING; 301 return PP_OK_COMPLETIONPENDING;
345 } 302 }
346 303
347 void TCPSocketShared::Init(uint32 socket_id) { 304 bool TCPSocketBaseResource::IsConnected() const {
348 DCHECK(socket_id != 0);
349 socket_id_ = socket_id;
350 connection_state_ = BEFORE_CONNECT;
351 read_buffer_ = NULL;
352 bytes_to_read_ = -1;
353
354 local_addr_.size = 0;
355 memset(local_addr_.data, 0,
356 arraysize(local_addr_.data) * sizeof(*local_addr_.data));
357 remote_addr_.size = 0;
358 memset(remote_addr_.data, 0,
359 arraysize(remote_addr_.data) * sizeof(*remote_addr_.data));
360 }
361
362 bool TCPSocketShared::IsConnected() const {
363 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED; 305 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED;
364 } 306 }
365 307
366 void TCPSocketShared::PostAbortIfNecessary( 308 void TCPSocketBaseResource::PostAbortIfNecessary(
367 scoped_refptr<TrackedCallback>* callback) { 309 scoped_refptr<TrackedCallback>* callback) {
368 if (TrackedCallback::IsPending(*callback)) 310 if (TrackedCallback::IsPending(*callback))
369 (*callback)->PostAbort(); 311 (*callback)->PostAbort();
370 } 312 }
371 313
314 void TCPSocketBaseResource::OnPluginMsgConnectReply(
315 const ResourceMessageReplyParams& params,
316 const PP_NetAddress_Private& local_addr,
317 const PP_NetAddress_Private& remote_addr) {
318 // It is possible that |connect_callback_| is pending while
319 // |connection_state_| is not BEFORE_CONNECT: DisconnectImpl() has been
320 // called, but a ConnectCompleted notification came earlier than the task to
321 // abort |connect_callback_|. We don't want to update |connection_state_| or
322 // other members in that case.
323 if (connection_state_ != BEFORE_CONNECT ||
324 !TrackedCallback::IsPending(connect_callback_)) {
325 return;
326 }
327
328 if (params.result() == PP_OK) {
329 local_addr_ = local_addr;
330 remote_addr_ = remote_addr;
331 connection_state_ = CONNECTED;
332 }
333 RunCallback(connect_callback_, params.result());
334 }
335
336 void TCPSocketBaseResource::OnPluginMsgSSLHandshakeReply(
337 const ResourceMessageReplyParams& params,
338 const PPB_X509Certificate_Fields& certificate_fields) {
339 // It is possible that |ssl_handshake_callback_| is pending while
340 // |connection_state_| is not CONNECT: DisconnectImpl() has been
341 // called, but a SSLHandshakeCompleted notification came earlier than the task
342 // to abort |ssl_handshake_callback_|. We don't want to update
343 // |connection_state_| or other members in that case.
344 if (connection_state_ != CONNECTED ||
345 !TrackedCallback::IsPending(ssl_handshake_callback_)) {
346 return;
347 }
348
349 if (params.result() == PP_OK) {
350 connection_state_ = SSL_CONNECTED;
351 server_certificate_ = new PPB_X509Certificate_Private_Shared(
352 OBJECT_IS_PROXY,
353 pp_instance(),
354 certificate_fields);
355 RunCallback(ssl_handshake_callback_, params.result());
356 } else {
357 // The resource might be released in the callback so we need to hold
358 // a reference so we can Disconnect() first.
359 AddRef();
360 RunCallback(ssl_handshake_callback_, params.result());
361 DisconnectImpl();
362 Release();
363 }
364 }
365
366 void TCPSocketBaseResource::OnPluginMsgReadReply(
367 const ResourceMessageReplyParams& params,
368 const std::string& data) {
369 // It is possible that |read_callback_| is pending while |read_buffer_| is
370 // NULL: DisconnectImpl() has been called, but a ReadCompleted notification
371 // came earlier than the task to abort |read_callback_|. We shouldn't access
372 // the buffer in that case. The user may have released it.
373 if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_)
374 return;
375
376 const bool succeeded = params.result() == PP_OK;
377 if (succeeded) {
378 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
379 if (!data.empty())
380 memcpy(read_buffer_, data.c_str(), data.size());
381 }
382 read_buffer_ = NULL;
383 bytes_to_read_ = -1;
384
385 read_callback_->Run(
386 succeeded ?
387 static_cast<int32_t>(data.size()) :
388 ConvertPPError(params.result(), private_api_));
389 }
390
391 void TCPSocketBaseResource::OnPluginMsgWriteReply(
392 const ResourceMessageReplyParams& params) {
393 if (!TrackedCallback::IsPending(write_callback_))
394 return;
395 RunCallback(write_callback_, params.result());
396 }
397
398 void TCPSocketBaseResource::OnPluginMsgSetOptionReply(
399 const ResourceMessageReplyParams& params) {
400 if (set_option_callbacks_.empty()) {
401 NOTREACHED();
402 return;
403 }
404 scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front();
405 set_option_callbacks_.pop();
406 if (TrackedCallback::IsPending(callback))
407 RunCallback(callback, params.result());
408 }
409
410 void TCPSocketBaseResource::RunCallback(scoped_refptr<TrackedCallback> callback,
411 int32_t pp_result) {
412 callback->Run(ConvertPPError(pp_result, private_api_));
413 }
414
372 } // namespace ppapi 415 } // namespace ppapi
416 } // namespace proxy
OLDNEW
« no previous file with comments | « ppapi/proxy/tcp_socket_base_resource.h ('k') | ppapi/proxy/tcp_socket_private_resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698