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

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc

Issue 23498015: [NaCl SDK] Support non blocking TCP/UDP (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed issues, UDP ok, dbing TCP 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 "nacl_io/ossocket.h" 5 #include "nacl_io/ossocket.h"
6 #ifdef PROVIDES_SOCKET_API 6 #ifdef PROVIDES_SOCKET_API
7 7
8 #include <errno.h> 8 #include <errno.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/fcntl.h>
10 11
11 #include "nacl_io/mount.h" 12 #include "nacl_io/mount.h"
12 #include "nacl_io/mount_node_socket.h" 13 #include "nacl_io/mount_node_socket.h"
13 #include "nacl_io/pepper_interface.h" 14 #include "nacl_io/pepper_interface.h"
14 15
15 #include "ppapi/c/pp_resource.h" 16 #include "ppapi/c/pp_resource.h"
16 #include "ppapi/c/ppb_net_address.h" 17 #include "ppapi/c/ppb_net_address.h"
17 18
18 namespace nacl_io { 19 namespace nacl_io {
19 20
20 MountNodeSocket::MountNodeSocket(Mount* mount) 21 MountNodeSocket::MountNodeSocket(Mount* mount)
21 : MountNode(mount), 22 : MountNodeStream(mount),
22 socket_resource_(0), 23 socket_resource_(0),
23 local_addr_(0), 24 local_addr_(0),
24 remote_addr_(0) { 25 remote_addr_(0),
26 socket_flags_(0),
27 last_errno_(0) {
25 stat_.st_mode |= S_IFSOCK; 28 stat_.st_mode |= S_IFSOCK;
26 } 29 }
27 30
28 void MountNodeSocket::Destroy() { 31 void MountNodeSocket::Destroy() {
29 if (socket_resource_) 32 if (socket_resource_)
30 mount_->ppapi()->ReleaseResource(socket_resource_); 33 mount_->ppapi()->ReleaseResource(socket_resource_);
31 if (local_addr_) 34 if (local_addr_)
32 mount_->ppapi()->ReleaseResource(local_addr_); 35 mount_->ppapi()->ReleaseResource(local_addr_);
33 if (remote_addr_) 36 if (remote_addr_)
34 mount_->ppapi()->ReleaseResource(remote_addr_); 37 mount_->ppapi()->ReleaseResource(remote_addr_);
35 }
36 38
37 // Default to always signaled, until socket select support is added. 39 socket_resource_ = 0;
38 uint32_t MountNodeSocket::GetEventStatus() { 40 local_addr_ = 0;
39 return POLLIN | POLLOUT; 41 remote_addr_ = 0;
40 } 42 }
41 43
42 // Assume that |addr| and |out_addr| are non-NULL. 44 // Assume that |addr| and |out_addr| are non-NULL.
43 Error MountNodeSocket::MMap(void* addr, 45 Error MountNodeSocket::MMap(void* addr,
44 size_t length, 46 size_t length,
45 int prot, 47 int prot,
46 int flags, 48 int flags,
47 size_t offset, 49 size_t offset,
48 void** out_addr) { 50 void** out_addr) {
49 return EACCES; 51 return EACCES;
50 } 52 }
51 53
52 // Normal read/write operations on a file 54 // Normal read/write operations on a Socket are equivelent to
binji 2013/09/19 22:40:25 sp: equivalent
noelallen1 2013/09/20 00:51:27 Done.
55 // send/recv with a flag value of 0.
53 Error MountNodeSocket::Read(size_t offs, 56 Error MountNodeSocket::Read(size_t offs,
54 void* buf, 57 void* buf,
55 size_t count, 58 size_t count,
56 int* out_bytes) { 59 int* out_bytes) {
57 return Recv(buf, count, 0, out_bytes); 60 return Recv(buf, count, 0, out_bytes);
58 } 61 }
59 62
60 Error MountNodeSocket::Write(size_t offs, 63 Error MountNodeSocket::Write(size_t offs,
61 const void* buf, 64 const void* buf,
62 size_t count, 65 size_t count,
63 int* out_bytes) { 66 int* out_bytes) {
64 if (0 == remote_addr_)
65 return EDESTADDRREQ;
66
67 return Send(buf, count, 0, out_bytes); 67 return Send(buf, count, 0, out_bytes);
68 } 68 }
69 69
70 NetAddressInterface* MountNodeSocket::NetAddress() { 70
71 NetAddressInterface* MountNodeSocket::NetInterface() {
72 if (mount_->ppapi() == NULL)
73 return NULL;
74
71 return mount_->ppapi()->GetNetAddressInterface(); 75 return mount_->ppapi()->GetNetAddressInterface();
72 } 76 }
73 77
78 TCPSocketInterface* MountNodeSocket::TCPInterface() {
79 if (mount_->ppapi() == NULL)
80 return NULL;
81
82 return mount_->ppapi()->GetTCPSocketInterface();
83 }
84
85 UDPSocketInterface* MountNodeSocket::UDPInterface() {
86 if (mount_->ppapi() == NULL)
87 return NULL;
88
89 return mount_->ppapi()->GetUDPSocketInterface();
90 }
91
74 PP_Resource MountNodeSocket::SockAddrToResource(const struct sockaddr* addr, 92 PP_Resource MountNodeSocket::SockAddrToResource(const struct sockaddr* addr,
75 socklen_t len) { 93 socklen_t len) {
94 if (NULL == addr)
95 return 0;
96
76 if (AF_INET == addr->sa_family) { 97 if (AF_INET == addr->sa_family) {
77 PP_NetAddress_IPv4 addr4; 98 PP_NetAddress_IPv4 addr4;
78 const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(addr); 99 const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(addr);
79 100
80 if (len != sizeof(sockaddr_in)) 101 if (len != sizeof(sockaddr_in))
81 return 0; 102 return 0;
82 103
83 memset(&addr4, 0, sizeof(addr4)); 104 memset(&addr4, 0, sizeof(addr4));
84 105
85 addr4.port = sin->sin_port; 106 addr4.port = sin->sin_port;
(...skipping 22 matching lines...) Expand all
108 129
109 socklen_t MountNodeSocket::ResourceToSockAddr(PP_Resource addr, 130 socklen_t MountNodeSocket::ResourceToSockAddr(PP_Resource addr,
110 socklen_t len, 131 socklen_t len,
111 struct sockaddr* out_addr) { 132 struct sockaddr* out_addr) {
112 if (0 == addr) 133 if (0 == addr)
113 return 0; 134 return 0;
114 135
115 PP_NetAddress_IPv4 ipv4; 136 PP_NetAddress_IPv4 ipv4;
116 PP_NetAddress_IPv6 ipv6; 137 PP_NetAddress_IPv6 ipv6;
117 138
118 if (PP_TRUE == NetAddress()->DescribeAsIPv4Address(addr, &ipv4)) { 139 if (PP_TRUE == NetInterface()->DescribeAsIPv4Address(addr, &ipv4)) {
119 sockaddr_in addr4; 140 sockaddr_in addr4;
120 addr4.sin_family = AF_INET; 141 addr4.sin_family = AF_INET;
121 addr4.sin_port = ipv4.port; 142 addr4.sin_port = ipv4.port;
122 memcpy(&addr4.sin_addr, ipv4.addr, sizeof(ipv4.addr)); 143 memcpy(&addr4.sin_addr, ipv4.addr, sizeof(ipv4.addr));
123 memcpy(out_addr, &addr4, len); 144 memcpy(out_addr, &addr4, len);
124 145
125 // Returns required size not copied size like getpeername/getsockname. 146 // Returns required size not copied size like getpeername/getsockname.
126 return sizeof(sockaddr_in); 147 return sizeof(sockaddr_in);
127 } 148 }
128 149
129 if (PP_TRUE == NetAddress()->DescribeAsIPv6Address(addr, &ipv6)) { 150 if (PP_TRUE == NetInterface()->DescribeAsIPv6Address(addr, &ipv6)) {
130 sockaddr_in6 addr6; 151 sockaddr_in6 addr6;
131 addr6.sin6_family = AF_INET6; 152 addr6.sin6_family = AF_INET6;
132 addr6.sin6_port = ipv6.port; 153 addr6.sin6_port = ipv6.port;
133 memcpy(&addr6.sin6_addr, ipv6.addr, sizeof(ipv6.addr)); 154 memcpy(&addr6.sin6_addr, ipv6.addr, sizeof(ipv6.addr));
134 memcpy(out_addr, &addr6, len); 155 memcpy(out_addr, &addr6, len);
135 156
136 // Returns required size not copied size like getpeername/getsockname. 157 // Returns required size not copied size like getpeername/getsockname.
137 return sizeof(sockaddr_in6); 158 return sizeof(sockaddr_in6);
138 } 159 }
139 160
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 int optname, 211 int optname,
191 const void* optval, 212 const void* optval,
192 socklen_t len) { 213 socklen_t len) {
193 return EINVAL; 214 return EINVAL;
194 } 215 }
195 216
196 Error MountNodeSocket::Bind(const struct sockaddr* addr, socklen_t len) { 217 Error MountNodeSocket::Bind(const struct sockaddr* addr, socklen_t len) {
197 return EINVAL; 218 return EINVAL;
198 } 219 }
199 220
221
200 Error MountNodeSocket::Recv(void* buf, size_t len, int flags, int* out_len) { 222 Error MountNodeSocket::Recv(void* buf, size_t len, int flags, int* out_len) {
201 return EINVAL; 223 return RecvFrom(buf, len, flags, NULL, 0, out_len);
binji 2013/09/19 22:40:25 forward to RecvHelper directly? Send() forwards to
noelallen1 2013/09/20 00:51:27 Send forward directly because of a small differenc
202 } 224 }
203 225
204 Error MountNodeSocket::RecvFrom(void* buf, 226 Error MountNodeSocket::RecvFrom(void* buffer,
binji 2013/09/19 22:40:25 buffer vs. buf? Either is fine, but might as well
noelallen1 2013/09/20 00:51:27 Done.
205 size_t len, 227 size_t len,
206 int flags, 228 int flags,
207 struct sockaddr* src_addr, 229 struct sockaddr* src_addr,
208 socklen_t* addrlen, 230 socklen_t* addrlen,
209 int* out_len) { 231 int* out_len) {
210 return EOPNOTSUPP; 232 PP_Resource addr;
233 Error err = RecvHelper(buffer, len, flags, &addr, out_len);
234 if (0 != addr) {
235 if (src_addr)
236 *addrlen = ResourceToSockAddr(addr, *addrlen, src_addr);
237
238 mount_->ppapi()->ReleaseResource(addr);
239 }
240
241 return err;
211 } 242 }
212 243
244 Error MountNodeSocket::RecvHelper(void* buffer,
245 size_t len,
246 int flags,
247 PP_Resource* addr,
248 int* out_len) {
249 if (0 == socket_resource_)
250 return EBADF;
251
252 int ms = read_timeout_;
253 if ((flags & MSG_DONTWAIT) || (GetMode() & O_NONBLOCK))
254 ms = 0;
255
256 EventListenerLock wait(GetEventEmitter());
257 Error err = wait.WaitOnEvent(POLLIN, ms);
258
259 // Timeout is treated as a would block for sockets.
260 if (ETIMEDOUT == err)
261 return EWOULDBLOCK;
262
263 if (err)
264 return err;
265
266 err = Recv_Locked(buffer, len, addr, out_len);
267
268 // We must have read from then inputbuffer, so Q up some receive work.
269 if ((err == 0) && *out_len)
270 QueueInput();
271 return err;
272 }
273
274
213 Error MountNodeSocket::Send(const void* buf, 275 Error MountNodeSocket::Send(const void* buf,
214 size_t len, 276 size_t len,
215 int flags, 277 int flags,
216 int* out_len) { 278 int* out_len) {
217 return EOPNOTSUPP; 279 return SendHelper(buf, len, flags, remote_addr_, out_len);
218 } 280 }
219 281
220 Error MountNodeSocket::SendTo(const void* buf, 282 Error MountNodeSocket::SendTo(const void* buf,
221 size_t len, 283 size_t len,
222 int flags, 284 int flags,
223 const struct sockaddr* dest_addr, 285 const struct sockaddr* dest_addr,
224 socklen_t addrlen, 286 socklen_t addrlen,
225 int* out_len) { 287 int* out_len) {
226 return EOPNOTSUPP; 288 if ((NULL == dest_addr) && (0 == remote_addr_))
289 return EDESTADDRREQ;
290
291 PP_Resource out_addr = SockAddrToResource(dest_addr, addrlen);
binji 2013/09/19 22:40:25 out_addr makes it look like an output parameter. M
noelallen1 2013/09/20 00:51:27 Done.
292 if (out_addr) {
293 Error err = SendHelper(buf, len, flags, out_addr, out_len);
294 mount_->ppapi()->ReleaseResource(out_addr);
295 return err;
296 }
297
298 return EINVAL;
299 }
300
301 Error MountNodeSocket::SendHelper(const void* buffer,
302 size_t len,
303 int flags,
304 PP_Resource addr,
305 int* out_len) {
306 if (0 == socket_resource_)
307 return EBADF;
308
309 if (0 == addr)
310 return ENOTCONN;
311
312 int ms = write_timeout_;
313 if ((flags & MSG_DONTWAIT) || (GetMode() & O_NONBLOCK))
314 ms = 0;
315
316 EventListenerLock wait(GetEventEmitter());
317 Error err = wait.WaitOnEvent(POLLOUT, ms);
318
319 // Timeout is treated as a would block for sockets.
320 if (ETIMEDOUT == err)
321 return EWOULDBLOCK;
322
323 if (err)
324 return err;
325
326 err = Send_Locked(buffer, len, addr, out_len);
327
328 // We must have added to the output buffer, so Q up some transmit work.
329 if ((err == 0) && *out_len)
330 QueueOutput();
331 return err;
332 }
333
334 void MountNodeSocket::SetError(int pp_error_num) {
335 SetStreamFlags(SSF_ERROR | SSF_CLOSED);
binji 2013/09/19 22:40:25 OK for all these changes to be unlocked? Ah, it s
noelallen1 2013/09/20 00:51:27 Done.
336 ClearStreamFlags(SSF_CAN_SEND | SSF_CAN_RECV);
337 last_errno_ = PPErrorToErrno(pp_error_num);
227 } 338 }
228 339
229 Error MountNodeSocket::Shutdown(int how) { 340 Error MountNodeSocket::Shutdown(int how) {
230 return EOPNOTSUPP; 341 return EOPNOTSUPP;
231 } 342 }
232 343
233 344
234 Error MountNodeSocket::GetPeerName(struct sockaddr* addr, socklen_t* len) { 345 Error MountNodeSocket::GetPeerName(struct sockaddr* addr, socklen_t* len) {
235 if (NULL == addr || NULL == len) 346 if (NULL == addr || NULL == len)
236 return EFAULT; 347 return EFAULT;
(...skipping 13 matching lines...) Expand all
250 361
251 AUTO_LOCK(node_lock_); 362 AUTO_LOCK(node_lock_);
252 if (local_addr_ != 0) { 363 if (local_addr_ != 0) {
253 *len = ResourceToSockAddr(local_addr_, *len, addr); 364 *len = ResourceToSockAddr(local_addr_, *len, addr);
254 return 0; 365 return 0;
255 } 366 }
256 367
257 return ENOTCONN; 368 return ENOTCONN;
258 } 369 }
259 370
260
261 } // namespace nacl_io 371 } // namespace nacl_io
262 372
263 #endif // PROVIDES_SOCKET_API 373 #endif // PROVIDES_SOCKET_API
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698