Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |