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

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: Merge 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 equivalent to
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);
202 } 224 }
203 225
204 Error MountNodeSocket::RecvFrom(void* buf, 226 Error MountNodeSocket::RecvFrom(void* buf,
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(buf, 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* buf,
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 //TODO(noelallen) BUG=295177
257 //For UDP we should support filtering packets when using connect
258 EventListenerLock wait(GetEventEmitter());
259 Error err = wait.WaitOnEvent(POLLIN, ms);
260
261 // Timeout is treated as a would block for sockets.
262 if (ETIMEDOUT == err)
263 return EWOULDBLOCK;
264
265 if (err)
266 return err;
267
268 err = Recv_Locked(buf, len, addr, out_len);
269
270 // We must have read from then inputbuffer, so Q up some receive work.
271 if ((err == 0) && *out_len)
272 QueueInput();
273 return err;
274 }
275
276
213 Error MountNodeSocket::Send(const void* buf, 277 Error MountNodeSocket::Send(const void* buf,
214 size_t len, 278 size_t len,
215 int flags, 279 int flags,
216 int* out_len) { 280 int* out_len) {
217 return EOPNOTSUPP; 281 return SendHelper(buf, len, flags, remote_addr_, out_len);
218 } 282 }
219 283
220 Error MountNodeSocket::SendTo(const void* buf, 284 Error MountNodeSocket::SendTo(const void* buf,
221 size_t len, 285 size_t len,
222 int flags, 286 int flags,
223 const struct sockaddr* dest_addr, 287 const struct sockaddr* dest_addr,
224 socklen_t addrlen, 288 socklen_t addrlen,
225 int* out_len) { 289 int* out_len) {
226 return EOPNOTSUPP; 290 if ((NULL == dest_addr) && (0 == remote_addr_))
291 return EDESTADDRREQ;
292
293 PP_Resource addr = SockAddrToResource(dest_addr, addrlen);
294 if (addr) {
295 Error err = SendHelper(buf, len, flags, addr, out_len);
296 mount_->ppapi()->ReleaseResource(addr);
297 return err;
298 }
299
300 return EINVAL;
301 }
302
303 Error MountNodeSocket::SendHelper(const void* buf,
304 size_t len,
305 int flags,
306 PP_Resource addr,
307 int* out_len) {
308 if (0 == socket_resource_)
309 return EBADF;
310
311 if (0 == addr)
312 return ENOTCONN;
313
314 int ms = write_timeout_;
315 if ((flags & MSG_DONTWAIT) || (GetMode() & O_NONBLOCK))
316 ms = 0;
317
318 EventListenerLock wait(GetEventEmitter());
319 Error err = wait.WaitOnEvent(POLLOUT, ms);
320
321 // Timeout is treated as a would block for sockets.
322 if (ETIMEDOUT == err)
323 return EWOULDBLOCK;
324
325 if (err)
326 return err;
327
328 err = Send_Locked(buf, len, addr, out_len);
329
330 // We must have added to the output buffer, so Q up some transmit work.
331 if ((err == 0) && *out_len)
332 QueueOutput();
333 return err;
334 }
335
336 void MountNodeSocket::SetError_Locked(int pp_error_num) {
337 SetStreamFlags(SSF_ERROR | SSF_CLOSED);
338 ClearStreamFlags(SSF_CAN_SEND | SSF_CAN_RECV);
339 last_errno_ = PPErrorToErrno(pp_error_num);
227 } 340 }
228 341
229 Error MountNodeSocket::Shutdown(int how) { 342 Error MountNodeSocket::Shutdown(int how) {
230 return EOPNOTSUPP; 343 return EOPNOTSUPP;
231 } 344 }
232 345
233 346
234 Error MountNodeSocket::GetPeerName(struct sockaddr* addr, socklen_t* len) { 347 Error MountNodeSocket::GetPeerName(struct sockaddr* addr, socklen_t* len) {
235 if (NULL == addr || NULL == len) 348 if (NULL == addr || NULL == len)
236 return EFAULT; 349 return EFAULT;
(...skipping 13 matching lines...) Expand all
250 363
251 AUTO_LOCK(node_lock_); 364 AUTO_LOCK(node_lock_);
252 if (local_addr_ != 0) { 365 if (local_addr_ != 0) {
253 *len = ResourceToSockAddr(local_addr_, *len, addr); 366 *len = ResourceToSockAddr(local_addr_, *len, addr);
254 return 0; 367 return 0;
255 } 368 }
256 369
257 return ENOTCONN; 370 return ENOTCONN;
258 } 371 }
259 372
260
261 } // namespace nacl_io 373 } // namespace nacl_io
262 374
263 #endif // PROVIDES_SOCKET_API 375 #endif // PROVIDES_SOCKET_API
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698