| 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 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 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); |
| 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 Loading... |
| 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 |
| OLD | NEW |