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

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

Issue 22587003: [NaCl SDK] Add UDP and TCP Sockets (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Running tests on package 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "nacl_io/ossocket.h"
6 #ifdef PROVIDES_SOCKET_API
7
8 #include <errno.h>
9 #include <string.h>
10
11 #include "nacl_io/mount.h"
12 #include "nacl_io/mount_node_socket.h"
13 #include "nacl_io/pepper_interface.h"
14
15 #include "ppapi/c/pp_resource.h"
16 #include "ppapi/c/ppb_net_address.h"
17
18 const uint32_t DEFAULT_MAX_BUFFER = 65536 * 2;
binji 2013/08/09 19:28:06 make this static or put in an anonymous namespace.
binji 2013/08/09 19:28:06 Also, kDefaultMaxBuffer
noelallen1 2013/08/09 22:53:22 Done.
19
20 namespace nacl_io {
21
22 MountNodeSocket::MountNodeSocket(Mount* mount)
23 : MountNode(mount),
24 socket_resource_(0),
25 local_addr_(0),
26 remote_addr_(0) {
27 stat_.st_mode |= S_IFSOCK;
28 }
29
30 void MountNodeSocket::Destroy() {
31 if (socket_resource_)
32 mount_->ppapi()->ReleaseResource(socket_resource_);
33 if (local_addr_)
34 mount_->ppapi()->ReleaseResource(local_addr_);
35 if (remote_addr_)
36 mount_->ppapi()->ReleaseResource(remote_addr_);
37 }
38
39 // Declared in EventEmitter, default to regular files which always return
40 // a ready of TRUE for read, write, or error.
binji 2013/08/09 19:28:06 incorrect comment?
noelallen1 2013/08/09 22:53:22 Done.
41 uint32_t MountNodeSocket::GetEventStatus() {
42 return POLLIN | POLLOUT;
43 }
44
45 // Assume that |addr| and |out_addr| are non-NULL.
46 Error MountNodeSocket::MMap(void* addr,
47 size_t length,
48 int prot,
49 int flags,
50 size_t offset,
51 void** out_addr) {
52 return EACCES;
53 }
54
55 // Normal read/write operations on a file
56 Error MountNodeSocket::Read(size_t offs,
57 void* buf,
58 size_t count,
59 int* out_bytes) {
60 return Recv(buf, count, 0, out_bytes);
61 }
62
63 Error MountNodeSocket::Write(size_t offs,
64 const void* buf,
65 size_t count,
66 int* out_bytes) {
67 if (0 == remote_addr_)
68 return EDESTADDRREQ;
69
70 return Send(buf, count, 0, out_bytes);
71 }
72
73 NetAddressInterface* MountNodeSocket::NetAddress() {
74 return mount_->ppapi()->GetNetAddressInterface();
75 }
76
77 Error MountNodeSocket::PPErrorToErrno(int error) {
binji 2013/08/09 19:28:06 can you extend the one in pepper_interface.cc inst
noelallen1 2013/08/09 22:53:22 Didn't know there was one. :) Done.
78 if (error >= 0)
79 return error;
80
81 switch(error) {
82 case PP_ERROR_NOACCESS:
83 return EACCES;
84
85 case PP_ERROR_FAILED:
86 case PP_ERROR_BADARGUMENT:
87 return EINVAL;
88
89 case PP_ERROR_CONNECTION_ABORTED:
90 return ECONNABORTED;
91
92 case PP_ERROR_CONNECTION_REFUSED:
93 case PP_ERROR_CONNECTION_FAILED:
94 return ECONNREFUSED;
95
96 case PP_ERROR_CONNECTION_TIMEDOUT:
97 return ETIMEDOUT;
98
99 case PP_ERROR_ADDRESS_UNREACHABLE:
100 return ENETUNREACH;
101
102 case PP_ERROR_ADDRESS_IN_USE:
103 return EADDRINUSE;
104 }
105
106 return EINVAL;
107 }
108
109 PP_Resource MountNodeSocket::SockAddrToResource(const struct sockaddr* addr,
110 socklen_t len) {
111 if (AF_INET == addr->sa_family) {
112 PP_NetAddress_IPv4 addr4;
113 const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(addr);
114
115 if (len != sizeof(sockaddr_in))
116 return 0;
117
118 memset(&addr4, 0, sizeof(addr4));
119
120 addr4.port = sin->sin_port;
121 memcpy(addr4.addr, &sin->sin_addr, sizeof(addr4.addr));
122 return mount_->ppapi()->GetNetAddressInterface()->CreateFromIPv4Address(
123 mount_->ppapi()->GetInstance(), &addr4);
binji 2013/08/09 19:28:06 nit: weird indent. Just indent 4 spaces. (same for
noelallen1 2013/08/09 22:53:22 Done.
124 }
125
126 if (AF_INET6 == addr->sa_family) {
127 PP_NetAddress_IPv6 addr6;
128 const sockaddr_in6* sin = reinterpret_cast<const sockaddr_in6*>(addr);
129
130 if (len != sizeof(sockaddr_in6))
131 return 0;
132
133 memset(&addr6, 0, sizeof(addr6));
134
135 addr6.port = sin->sin6_port;
136 memcpy(addr6.addr, &sin->sin6_addr, sizeof(addr6.addr));
137 return mount_->ppapi()->GetNetAddressInterface()->CreateFromIPv6Address(
138 mount_->ppapi()->GetInstance(), &addr6);
139 }
140 return 0;
141 }
142
143
144 socklen_t MountNodeSocket::ResourceToSockAddr(PP_Resource addr,
145 socklen_t len,
146 struct sockaddr* out_addr) {
147 if (0 == addr)
148 return 0;
149
150 PP_NetAddress_IPv4 ipv4;
151 PP_NetAddress_IPv6 ipv6;
152
153 if (PP_TRUE == NetAddress()->DescribeAsIPv4Address(addr, &ipv4)) {
154 sockaddr_in addr4;
155 addr4.sin_family = AF_INET;
156 addr4.sin_port = ipv4.port;
157 memcpy(&addr4.sin_addr, ipv4.addr, sizeof(ipv4.addr));
158 memcpy(out_addr, &addr4, len);
159 return sizeof(sockaddr_in);
binji 2013/08/09 19:28:06 I was a bit surprised that this returns the socket
noelallen1 2013/08/09 22:53:22 Done.
160 }
161
162 if (PP_TRUE == NetAddress()->DescribeAsIPv6Address(addr, &ipv6)) {
163 sockaddr_in6 addr6;
164 addr6.sin6_family = AF_INET6;
165 addr6.sin6_port = ipv6.port;
166 memcpy(&addr6.sin6_addr, ipv6.addr, sizeof(ipv6.addr));
167 memcpy(out_addr, &addr6, len);
168 return sizeof(sockaddr_in6);
169 }
170
171 return 0;
172 }
173
174 bool MountNodeSocket::EquivalentAddress(PP_Resource addr1, PP_Resource addr2) {
175 if (addr1 == addr2)
176 return true;
177
178 char data1[sizeof(sockaddr_in6)];
179 char data2[sizeof(sockaddr_in6)];
180
181 sockaddr* saddr1 = (sockaddr*) data1;
binji 2013/08/09 19:28:06 reinterpret_cast
noelallen1 2013/08/09 22:53:22 Done.
182 sockaddr* saddr2 = (sockaddr*) data2;
183
184 socklen_t len1 = ResourceToSockAddr(addr1, sizeof(data1), saddr1);
185 socklen_t len2 = ResourceToSockAddr(addr2, sizeof(data2), saddr2);
186
187 if (len1 != len2)
188 return false;
189
190 return memcmp(saddr1, saddr2, len1) == 0;
191 }
192
193
194 Error MountNodeSocket::Accept(const struct sockaddr* addr, socklen_t len) {
195 // Firewall forbids
196 return EPERM;
binji 2013/08/09 19:28:06 Why EPERM? maybe just ENOSYS for now, because it's
noelallen1 2013/08/09 22:53:22 Done.
197 }
198
199 Error MountNodeSocket::Connect(const struct sockaddr* addr, socklen_t len) {
200 if (len < 1)
201 return EINVAL;
202
203 if (NULL == addr)
204 return EFAULT;
205
206 return EOPNOTSUPP;
207 }
208
209 Error MountNodeSocket::Listen(int backlog) {
210 return EOPNOTSUPP;
211 }
212
213 Error MountNodeSocket::GetSockOpt(int lvl,
214 int optname,
215 void* optval,
216 socklen_t* len) {
217 return EINVAL;
218 }
219
220 Error MountNodeSocket::SetSockOpt(int lvl,
221 int optname,
222 const void* optval,
223 socklen_t len) {
224 return EINVAL;
225 }
226
227 Error MountNodeSocket::Bind(const struct sockaddr* addr, socklen_t len) {
228 return EINVAL;
229 }
230
231 Error MountNodeSocket::Recv(void* buf, size_t len, int flags, int* out_len) {
232 return EINVAL;
233 }
234
235 Error MountNodeSocket::RecvFrom(void* buf,
236 size_t len,
237 int flags,
238 struct sockaddr* src_addr,
239 socklen_t* addrlen,
240 int* out_len) {
241 return EISCONN;
binji 2013/08/09 19:28:06 why EISCONN?
noelallen1 2013/08/09 22:53:22 Done.
242 }
243
244 Error MountNodeSocket::Send(const void* buf,
245 size_t len,
246 int flags,
247 int* out_len) {
248 return ENOTCONN;
249 }
250
251 Error MountNodeSocket::SendTo(const void* buf,
252 size_t len,
253 int flags,
254 const struct sockaddr* dest_addr,
255 socklen_t addrlen,
256 int* out_len) {
257 return EISCONN;
binji 2013/08/09 19:28:06 why EISCONN?
noelallen1 2013/08/09 22:53:22 Done.
258 }
259
260 Error MountNodeSocket::Shutdown(int how) {
261 return ENOTCONN;
262 }
263
264
265 Error MountNodeSocket::GetPeerName(struct sockaddr* addr, socklen_t* len) {
266 if (NULL == addr || NULL == len)
267 return EFAULT;
268
269 if (*len < 1)
binji 2013/08/09 19:28:06 0 is invalid? linux man pages say len can't be neg
noelallen1 2013/08/09 22:53:22 We define socklet_t as unsigned int, but it could
270 return EINVAL;
271
272 AUTO_LOCK(node_lock_);
273 if (remote_addr_ != 0) {
274 *len = ResourceToSockAddr(remote_addr_, *len, addr);
275 return 0;
276 }
277
278 return ENOTCONN;
279 }
280
281 Error MountNodeSocket::GetSockName(struct sockaddr* addr, socklen_t* len) {
282 if (NULL == addr || NULL == len)
283 return EFAULT;
284
285 if (*len < 1)
286 return EINVAL;
287
288 AUTO_LOCK(node_lock_);
289 if (local_addr_ != 0) {
290 *len = ResourceToSockAddr(local_addr_, *len, addr);
291 return 0;
292 }
293
294 return ENOTCONN;
295 }
296
297
298 } // namespace nacl_io
299
300 #endif // PROVIDES_SOCKET_API
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698