1// Copyright 2017 The Fuchsia 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 <poll.h> 6#include <stddef.h> 7#include <stdlib.h> 8#include <stdio.h> 9#include <string.h> 10#include <sys/ioctl.h> 11 12#include <zircon/processargs.h> 13#include <zircon/syscalls.h> 14 15#include <lib/fdio/io.h> 16#include <lib/fdio/remoteio.h> 17#include <lib/fdio/socket.h> 18#include <lib/fdio/util.h> 19 20#include "private-socket.h" 21 22static bool is_rio_message_valid(zxsio_msg_t* msg) { 23 if ((msg->datalen > ZXSIO_PAYLOAD_SZ) || 24 (msg->hcount > 0)) { 25 return false; 26 } 27 return true; 28} 29 30static bool is_rio_message_reply_valid(zxsio_msg_t* msg, uint32_t size) { 31 if ((size < ZXSIO_HDR_SZ) || 32 (msg->datalen != (size - ZXSIO_HDR_SZ))) { 33 return false; 34 } 35 return is_rio_message_valid(msg); 36} 37 38zx_status_t zxsio_accept(fdio_t* io, zx_handle_t* s2) { 39 zxsio_t* sio = (zxsio_t*)io; 40 41 if (!(sio->flags & ZXSIO_DID_LISTEN)) { 42 return ZX_ERR_BAD_STATE; 43 } 44 45 zx_status_t r; 46 for (;;) { 47 r = zx_socket_accept(sio->s, s2); 48 if (r == ZX_ERR_SHOULD_WAIT) { 49 if (io->ioflag & IOFLAG_NONBLOCK) { 50 return ZX_ERR_SHOULD_WAIT; 51 } 52 53 // wait for an incoming connection 54 zx_signals_t pending; 55 r = zx_object_wait_one(sio->s, ZX_SOCKET_ACCEPT | ZX_SOCKET_PEER_CLOSED, ZX_TIME_INFINITE, &pending); 56 if (r < 0) { 57 return r; 58 } 59 if (pending & ZX_SOCKET_ACCEPT) { 60 continue; 61 } 62 if (pending & ZX_SOCKET_PEER_CLOSED) { 63 return ZX_ERR_PEER_CLOSED; 64 } 65 // impossible 66 return ZX_ERR_INTERNAL; 67 } 68 break; 69 } 70 return r; 71} 72 73static ssize_t zxsio_read_stream(fdio_t* io, void* data, size_t len) { 74 zxsio_t* sio = (zxsio_t*)io; 75 int nonblock = sio->io.ioflag & IOFLAG_NONBLOCK; 76 77 // TODO: let the generic read() to do this loop 78 for (;;) { 79 ssize_t r; 80 size_t bytes_read; 81 if ((r = zx_socket_read(sio->s, 0, data, len, &bytes_read)) == ZX_OK) { 82 // zx_socket_read() sets *actual to the number of bytes in the buffer when data is NULL 83 // and len is 0. read() should return 0 in that case. 84 if (len == 0) { 85 return 0; 86 } else { 87 return (ssize_t)bytes_read; 88 } 89 } 90 if (r == ZX_ERR_PEER_CLOSED || r == ZX_ERR_BAD_STATE) { 91 return 0; 92 } else if (r == ZX_ERR_SHOULD_WAIT && !nonblock) { 93 zx_signals_t pending; 94 r = zx_object_wait_one(sio->s, 95 ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED | ZX_SOCKET_READ_DISABLED, 96 ZX_TIME_INFINITE, &pending); 97 if (r < 0) { 98 return r; 99 } 100 if (pending & ZX_SOCKET_READABLE) { 101 continue; 102 } 103 if (pending & (ZX_SOCKET_PEER_CLOSED | ZX_SOCKET_READ_DISABLED)) { 104 return 0; 105 } 106 // impossible 107 return ZX_ERR_INTERNAL; 108 } 109 return r; 110 } 111} 112 113static ssize_t zxsio_recvfrom(fdio_t* io, void* data, size_t len, int flags, 114 struct sockaddr* restrict addr, 115 socklen_t* restrict addrlen) { 116 struct iovec iov; 117 iov.iov_base = data; 118 iov.iov_len = len; 119 120 struct msghdr msg; 121 msg.msg_name = addr; 122 // the caller (recvfrom) checks if addrlen is NULL. 123 msg.msg_namelen = (addr == NULL) ? 0 : *addrlen; 124 msg.msg_iov = &iov; 125 msg.msg_iovlen = 1; 126 msg.msg_control = NULL; 127 msg.msg_controllen = 0; 128 msg.msg_flags = 0; 129 130 ssize_t r = io->ops->recvmsg(io, &msg, flags); 131 if (addr != NULL) 132 *addrlen = msg.msg_namelen; 133 134 return r; 135} 136 137static ssize_t zxsio_write_stream(fdio_t* io, const void* data, size_t len) { 138 zxsio_t* sio = (zxsio_t*)io; 139 int nonblock = sio->io.ioflag & IOFLAG_NONBLOCK; 140 141 // TODO: let the generic write() to do this loop 142 for (;;) { 143 ssize_t r; 144 if ((r = zx_socket_write(sio->s, 0, data, len, &len)) == ZX_OK) { 145 return (ssize_t) len; 146 } 147 if (r == ZX_ERR_SHOULD_WAIT && !nonblock) { 148 zx_signals_t pending; 149 r = zx_object_wait_one(sio->s, 150 ZX_SOCKET_WRITABLE | ZX_SOCKET_WRITE_DISABLED | ZX_SOCKET_PEER_CLOSED, 151 ZX_TIME_INFINITE, &pending); 152 if (r < 0) { 153 return r; 154 } 155 if (pending & (ZX_SOCKET_WRITE_DISABLED | ZX_SOCKET_PEER_CLOSED)) { 156 return ZX_ERR_PEER_CLOSED; 157 } 158 if (pending & ZX_SOCKET_WRITABLE) { 159 continue; 160 } 161 // impossible 162 return ZX_ERR_INTERNAL; 163 } 164 return r; 165 } 166} 167 168static ssize_t zxsio_sendto(fdio_t* io, const void* data, size_t len, int flags, const struct sockaddr* addr, socklen_t addrlen) { 169 struct iovec iov; 170 iov.iov_base = (void*)data; 171 iov.iov_len = len; 172 173 struct msghdr msg; 174 msg.msg_name = (void*)addr; 175 msg.msg_namelen = addrlen; 176 msg.msg_iov = &iov; 177 msg.msg_iovlen = 1; 178 msg.msg_control = NULL; 179 msg.msg_controllen = 0; 180 msg.msg_flags = 0; // this field is ignored 181 182 return io->ops->sendmsg(io, &msg, flags); 183} 184 185 186static ssize_t zxsio_recvmsg_stream(fdio_t* io, struct msghdr* msg, int flags) { 187 if (flags != 0) { 188 // TODO: support MSG_OOB 189 return ZX_ERR_NOT_SUPPORTED; 190 } 191 if (!(io->ioflag & IOFLAG_SOCKET_CONNECTED)) { 192 return ZX_ERR_BAD_STATE; 193 } 194 // we ignore msg_name and msg_namelen members. 195 // (this is a consistent behavior with other OS implementations for TCP protocol) 196 ssize_t total = 0; 197 for (int i = 0; i < msg->msg_iovlen; i++) { 198 struct iovec *iov = &msg->msg_iov[i]; 199 ssize_t n = zxsio_read_stream(io, iov->iov_base, iov->iov_len); 200 if (n < 0) { 201 if (total == 0) { 202 return n; 203 } 204 return total; 205 } 206 total += n; 207 if ((size_t)n != iov->iov_len) { 208 break; 209 } 210 } 211 return total; 212} 213 214static ssize_t zxsio_sendmsg_stream(fdio_t* io, const struct msghdr* msg, int flags) { 215 if (flags != 0) { 216 // TODO: support MSG_OOB 217 return ZX_ERR_NOT_SUPPORTED; 218 } 219 // TODO: support flags and control messages 220 if (io->ioflag & IOFLAG_SOCKET_CONNECTED) { 221 // if connected, can't specify address 222 if (msg->msg_name != NULL || msg->msg_namelen != 0) { 223 return ZX_ERR_ALREADY_EXISTS; 224 } 225 } else { 226 return ZX_ERR_BAD_STATE; 227 } 228 ssize_t total = 0; 229 for (int i = 0; i < msg->msg_iovlen; i++) { 230 struct iovec *iov = &msg->msg_iov[i]; 231 if (iov->iov_len <= 0) { 232 return ZX_ERR_INVALID_ARGS; 233 } 234 ssize_t n = zxsio_write_stream(io, iov->iov_base, iov->iov_len); 235 if (n < 0) { 236 return n; 237 } 238 total += n; 239 if ((size_t)n != iov->iov_len) { 240 break; 241 } 242 } 243 return total; 244} 245 246static zx_status_t zxsio_clone(fdio_t* io, zx_handle_t* handles, uint32_t* types) { 247 // TODO: support unconnected sockets 248 if (!(io->ioflag & IOFLAG_SOCKET_CONNECTED)) { 249 return ZX_ERR_BAD_STATE; 250 } 251 zxsio_t* sio = (void*)io; 252 zx_status_t r = zx_handle_duplicate(sio->s, ZX_RIGHT_SAME_RIGHTS, handles); 253 if (r < 0) { 254 return r; 255 } 256 types[0] = PA_FDIO_SOCKET; 257 return 1; 258} 259 260static zx_status_t zxsio_unwrap(fdio_t* io, zx_handle_t* handles, uint32_t* types) { 261 // TODO: support unconnected sockets 262 if (!(io->ioflag & IOFLAG_SOCKET_CONNECTED)) { 263 return ZX_ERR_BAD_STATE; 264 } 265 zxsio_t* sio = (void*)io; 266 zx_status_t r; 267 handles[0] = sio->s; 268 types[0] = PA_FDIO_SOCKET; 269 r = 1; 270 return r; 271} 272 273static void zxsio_wait_begin_stream(fdio_t* io, uint32_t events, zx_handle_t* handle, zx_signals_t* _signals) { 274 zxsio_t* sio = (void*)io; 275 *handle = sio->s; 276 // TODO: locking for flags/state 277 if (io->ioflag & IOFLAG_SOCKET_CONNECTING) { 278 // check the connection state 279 zx_signals_t observed; 280 zx_status_t r; 281 r = zx_object_wait_one(sio->s, ZXSIO_SIGNAL_CONNECTED, 0u, 282 &observed); 283 if (r == ZX_OK || r == ZX_ERR_TIMED_OUT) { 284 if (observed & ZXSIO_SIGNAL_CONNECTED) { 285 io->ioflag &= ~IOFLAG_SOCKET_CONNECTING; 286 io->ioflag |= IOFLAG_SOCKET_CONNECTED; 287 } 288 } 289 } 290 zx_signals_t signals = ZXSIO_SIGNAL_ERROR; 291 if (io->ioflag & IOFLAG_SOCKET_CONNECTED) { 292 // if socket is connected 293 if (events & POLLIN) { 294 signals |= ZX_SOCKET_READABLE | ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED; 295 } 296 if (events & POLLOUT) { 297 signals |= ZX_SOCKET_WRITABLE | ZX_SOCKET_WRITE_DISABLED; 298 } 299 } else { 300 // if socket is not connected 301 if (events & POLLIN) { 302 // signal when a listening socket gets an incoming connection 303 // or a connecting socket gets connected and receives data 304 signals |= ZX_SOCKET_ACCEPT | 305 ZX_SOCKET_READABLE | ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED; 306 } 307 if (events & POLLOUT) { 308 // signal when connect() operation is finished 309 signals |= ZXSIO_SIGNAL_OUTGOING; 310 } 311 } 312 if (events & POLLRDHUP) { 313 signals |= ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED; 314 } 315 *_signals = signals; 316} 317 318static void zxsio_wait_end_stream(fdio_t* io, zx_signals_t signals, uint32_t* _events) { 319 // check the connection state 320 if (io->ioflag & IOFLAG_SOCKET_CONNECTING) { 321 if (signals & ZXSIO_SIGNAL_CONNECTED) { 322 io->ioflag &= ~IOFLAG_SOCKET_CONNECTING; 323 io->ioflag |= IOFLAG_SOCKET_CONNECTED; 324 } 325 } 326 uint32_t events = 0; 327 if (io->ioflag & IOFLAG_SOCKET_CONNECTED) { 328 if (signals & (ZX_SOCKET_READABLE | ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED)) { 329 events |= POLLIN; 330 } 331 if (signals & (ZX_SOCKET_WRITABLE | ZX_SOCKET_WRITE_DISABLED)) { 332 events |= POLLOUT; 333 } 334 } else { 335 if (signals & (ZX_SOCKET_ACCEPT | ZX_SOCKET_PEER_CLOSED)) { 336 events |= POLLIN; 337 } 338 if (signals & ZXSIO_SIGNAL_OUTGOING) { 339 events |= POLLOUT; 340 } 341 } 342 if (signals & ZXSIO_SIGNAL_ERROR) { 343 events |= POLLERR; 344 } 345 if (signals & (ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED)) { 346 events |= POLLRDHUP; 347 } 348 *_events = events; 349} 350 351static ssize_t zxsio_posix_ioctl_stream(fdio_t* io, int req, va_list va) { 352 zxsio_t* sio = (zxsio_t*)io; 353 switch (req) { 354 case FIONREAD: { 355 zx_status_t r; 356 size_t avail; 357 if ((r = zx_socket_read(sio->s, 0, NULL, 0, &avail)) < 0) { 358 return r; 359 } 360 if (avail > INT_MAX) { 361 avail = INT_MAX; 362 } 363 int* actual = va_arg(va, int*); 364 *actual = avail; 365 return ZX_OK; 366 } 367 default: 368 return ZX_ERR_NOT_SUPPORTED; 369 } 370} 371 372static ssize_t zxsio_rx_dgram(fdio_t* io, void* buf, size_t buflen) { 373 return zxsio_read_stream(io, buf, buflen); 374} 375 376static ssize_t zxsio_tx_dgram(fdio_t* io, const void* buf, size_t buflen) { 377 zx_status_t r = zxsio_write_stream(io, buf, buflen); 378 return (r < 0) ? r : ZX_OK; 379} 380 381static ssize_t zxsio_recvmsg_dgram(fdio_t* io, struct msghdr* msg, int flags); 382static ssize_t zxsio_sendmsg_dgram(fdio_t* io, const struct msghdr* msg, int flags); 383 384static ssize_t zxsio_read_dgram(fdio_t* io, void* data, size_t len) { 385 struct iovec iov; 386 iov.iov_base = data; 387 iov.iov_len = len; 388 389 struct msghdr msg; 390 msg.msg_name = NULL; 391 msg.msg_namelen = 0; 392 msg.msg_iov = &iov; 393 msg.msg_iovlen = 1; 394 msg.msg_control = NULL; 395 msg.msg_controllen = 0; 396 msg.msg_flags = 0; 397 398 return zxsio_recvmsg_dgram(io, &msg, 0); 399} 400 401static ssize_t zxsio_write_dgram(fdio_t* io, const void* data, size_t len) { 402 struct iovec iov; 403 iov.iov_base = (void*)data; 404 iov.iov_len = len; 405 406 struct msghdr msg; 407 msg.msg_name = NULL; 408 msg.msg_namelen = 0; 409 msg.msg_iov = &iov; 410 msg.msg_iovlen = 1; 411 msg.msg_control = NULL; 412 msg.msg_controllen = 0; 413 msg.msg_flags = 0; 414 415 return zxsio_sendmsg_dgram(io, &msg, 0); 416} 417 418static ssize_t zxsio_recvmsg_dgram(fdio_t* io, struct msghdr* msg, int flags) { 419 if (flags != 0) { 420 // TODO: support MSG_OOB 421 return ZX_ERR_NOT_SUPPORTED; 422 } 423 // Read 1 extra byte to detect if the buffer is too small to fit the whole 424 // packet, so we can set MSG_TRUNC flag if necessary. 425 size_t mlen = FDIO_SOCKET_MSG_HEADER_SIZE + 1; 426 for (int i = 0; i < msg->msg_iovlen; i++) { 427 struct iovec *iov = &msg->msg_iov[i]; 428 if (iov->iov_len <= 0) { 429 return ZX_ERR_INVALID_ARGS; 430 } 431 mlen += iov->iov_len; 432 } 433 434 // TODO: avoid malloc 435 fdio_socket_msg_t* m = malloc(mlen); 436 ssize_t n = zxsio_rx_dgram(io, m, mlen); 437 if (n < 0) { 438 free(m); 439 return n; 440 } 441 if ((size_t)n < FDIO_SOCKET_MSG_HEADER_SIZE) { 442 free(m); 443 return ZX_ERR_INTERNAL; 444 } 445 n -= FDIO_SOCKET_MSG_HEADER_SIZE; 446 if (msg->msg_name != NULL) { 447 int bytes_to_copy = (msg->msg_namelen < m->addrlen) ? msg->msg_namelen : m->addrlen; 448 memcpy(msg->msg_name, &m->addr, bytes_to_copy); 449 } 450 msg->msg_namelen = m->addrlen; 451 msg->msg_flags = m->flags; 452 char* data = m->data; 453 size_t resid = n; 454 for (int i = 0; i < msg->msg_iovlen; i++) { 455 struct iovec *iov = &msg->msg_iov[i]; 456 if (resid == 0) { 457 iov->iov_len = 0; 458 } else { 459 if (resid < iov->iov_len) 460 iov->iov_len = resid; 461 memcpy(iov->iov_base, data, iov->iov_len); 462 data += iov->iov_len; 463 resid -= iov->iov_len; 464 } 465 } 466 467 if (resid > 0) { 468 msg->msg_flags |= MSG_TRUNC; 469 n -= resid; 470 } 471 472 free(m); 473 return n; 474} 475 476static ssize_t zxsio_sendmsg_dgram(fdio_t* io, const struct msghdr* msg, int flags) { 477 if (flags != 0) { 478 // TODO: MSG_OOB 479 return ZX_ERR_NOT_SUPPORTED; 480 } 481 // TODO: support flags and control messages 482 if (io->ioflag & IOFLAG_SOCKET_CONNECTED) { 483 // if connected, can't specify address 484 if (msg->msg_name != NULL || msg->msg_namelen != 0) { 485 return ZX_ERR_ALREADY_EXISTS; 486 } 487 } 488 ssize_t n = 0; 489 for (int i = 0; i < msg->msg_iovlen; i++) { 490 struct iovec *iov = &msg->msg_iov[i]; 491 if (iov->iov_len <= 0) { 492 return ZX_ERR_INVALID_ARGS; 493 } 494 n += iov->iov_len; 495 } 496 size_t mlen = n + FDIO_SOCKET_MSG_HEADER_SIZE; 497 498 // TODO: avoid malloc m 499 fdio_socket_msg_t* m = malloc(mlen); 500 if (msg->msg_name != NULL) { 501 memcpy(&m->addr, msg->msg_name, msg->msg_namelen); 502 } 503 m->addrlen = msg->msg_namelen; 504 m->flags = flags; 505 char* data = m->data; 506 for (int i = 0; i < msg->msg_iovlen; i++) { 507 struct iovec *iov = &msg->msg_iov[i]; 508 memcpy(data, iov->iov_base, iov->iov_len); 509 data += iov->iov_len; 510 } 511 ssize_t r = zxsio_tx_dgram(io, m, mlen); 512 free(m); 513 return r == ZX_OK ? n : r; 514} 515 516static void zxsio_wait_begin_dgram(fdio_t* io, uint32_t events, zx_handle_t* handle, zx_signals_t* _signals) { 517 zxsio_t* sio = (void*)io; 518 *handle = sio->s; 519 zx_signals_t signals = ZXSIO_SIGNAL_ERROR; 520 if (events & POLLIN) { 521 signals |= ZX_SOCKET_READABLE | ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED; 522 } 523 if (events & POLLOUT) { 524 signals |= ZX_SOCKET_WRITABLE | ZX_SOCKET_WRITE_DISABLED; 525 } 526 if (events & POLLRDHUP) { 527 signals |= ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED; 528 } 529 *_signals = signals; 530} 531 532static void zxsio_wait_end_dgram(fdio_t* io, zx_signals_t signals, uint32_t* _events) { 533 uint32_t events = 0; 534 if (signals & (ZX_SOCKET_READABLE | ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED)) { 535 events |= POLLIN; 536 } 537 if (signals & (ZX_SOCKET_WRITABLE | ZX_SOCKET_WRITE_DISABLED)) { 538 events |= POLLOUT; 539 } 540 if (signals & ZXSIO_SIGNAL_ERROR) { 541 events |= POLLERR; 542 } 543 if (signals & (ZX_SOCKET_READ_DISABLED | ZX_SOCKET_PEER_CLOSED)) { 544 events |= POLLRDHUP; 545 } 546 *_events = events; 547} 548 549static zx_status_t zxsio_write_control(zxsio_t* sio, zxsio_msg_t* msg) { 550 for (;;) { 551 ssize_t r; 552 size_t len = ZXSIO_HDR_SZ + msg->datalen; 553 if ((r = zx_socket_write(sio->s, ZX_SOCKET_CONTROL, msg, len, &len)) == ZX_OK) { 554 return (ssize_t) len; 555 } 556 // If the socket has no control plane then control messages are not 557 // supported. 558 if (r == ZX_ERR_BAD_STATE) { 559 return ZX_ERR_NOT_SUPPORTED; 560 } 561 if (r == ZX_ERR_SHOULD_WAIT) { 562 zx_signals_t pending; 563 r = zx_object_wait_one(sio->s, 564 ZX_SOCKET_CONTROL_WRITABLE | ZX_SOCKET_PEER_CLOSED, 565 ZX_TIME_INFINITE, &pending); 566 if (r < 0) { 567 return r; 568 } 569 if (pending & ZX_SOCKET_PEER_CLOSED) { 570 return ZX_ERR_PEER_CLOSED; 571 } 572 if (pending & ZX_SOCKET_CONTROL_WRITABLE) { 573 continue; 574 } 575 // impossible 576 return ZX_ERR_INTERNAL; 577 } 578 return r; 579 } 580} 581 582static ssize_t zxsio_read_control(zxsio_t* sio, void* data, size_t len) { 583 // TODO: let the generic read() to do this loop 584 for (;;) { 585 ssize_t r; 586 size_t bytes_read; 587 if ((r = zx_socket_read(sio->s, ZX_SOCKET_CONTROL, data, len, &bytes_read)) == ZX_OK) { 588 // zx_socket_read() sets *actual to the number of bytes in the buffer when data is NULL 589 // and len is 0. read() should return 0 in that case. 590 if (len == 0) { 591 return 0; 592 } else { 593 return (ssize_t)bytes_read; 594 } 595 } 596 if (r == ZX_ERR_PEER_CLOSED || r == ZX_ERR_BAD_STATE) { 597 return 0; 598 } else if (r == ZX_ERR_SHOULD_WAIT) { 599 zx_signals_t pending; 600 r = zx_object_wait_one(sio->s, 601 ZX_SOCKET_CONTROL_READABLE | ZX_SOCKET_PEER_CLOSED, 602 ZX_TIME_INFINITE, &pending); 603 if (r < 0) { 604 return r; 605 } 606 if (pending & ZX_SOCKET_CONTROL_READABLE) { 607 continue; 608 } 609 if (pending & ZX_SOCKET_PEER_CLOSED) { 610 return 0; 611 } 612 // impossible 613 return ZX_ERR_INTERNAL; 614 } 615 return r; 616 } 617} 618 619static zx_status_t zxsio_txn(zxsio_t* sio, zxsio_msg_t* msg) { 620 if (!is_rio_message_valid(msg)) { 621 return ZX_ERR_INVALID_ARGS; 622 } 623 624 zx_status_t r = zxsio_write_control(sio, msg); 625 if (r < 0) 626 return r; 627 628 const uint32_t request_op = msg->op; 629 r = zxsio_read_control(sio, msg, sizeof(*msg)); 630 if (r < 0) 631 return r; 632 633 size_t dsize = (size_t)r; 634 // check for protocol errors 635 if (!is_rio_message_reply_valid(msg, dsize) || (msg->op != request_op)) { 636 return ZX_ERR_IO; 637 } 638 return msg->arg; 639} 640 641static zx_status_t zxsio_misc(fdio_t* io, uint32_t op, int64_t off, 642 uint32_t maxreply, void* ptr, size_t len) { 643 zxsio_t* sio = (zxsio_t*)io; 644 zxsio_msg_t msg; 645 zx_status_t r; 646 647 if ((len > ZXSIO_PAYLOAD_SZ) || (maxreply > ZXSIO_PAYLOAD_SZ)) { 648 return ZX_ERR_INVALID_ARGS; 649 } 650 651 switch (op) { 652 case ZXSIO_GETSOCKNAME: 653 case ZXSIO_GETPEERNAME: 654 case ZXSIO_GETSOCKOPT: 655 case ZXSIO_SETSOCKOPT: 656 case ZXSIO_CONNECT: 657 case ZXSIO_BIND: 658 case ZXSIO_LISTEN: 659 break; 660 default: 661 return ZX_ERR_NOT_SUPPORTED; 662 } 663 664 memset(&msg, 0, ZXSIO_HDR_SZ); 665 msg.op = op; 666 msg.arg = maxreply; 667 msg.arg2.off = off; 668 msg.datalen = len; 669 if (ptr && len > 0) { 670 memcpy(msg.data, ptr, len); 671 } 672 673 if ((r = zxsio_txn(sio, &msg)) < 0) { 674 return r; 675 } 676 if (msg.datalen > maxreply) { 677 return ZX_ERR_IO; 678 } 679 if (ptr && msg.datalen > 0) { 680 memcpy(ptr, msg.data, msg.datalen); 681 } 682 683 if (op == ZXSIO_LISTEN && r == ZX_OK) { 684 sio->flags |= ZXSIO_DID_LISTEN; 685 } 686 687 return r; 688} 689 690static zx_status_t zxsio_close(fdio_t* io) { 691 zxsio_t* sio = (zxsio_t*)io; 692 zxsio_msg_t msg; 693 zx_status_t r; 694 695 memset(&msg, 0, ZXSIO_HDR_SZ); 696 msg.op = ZXSIO_CLOSE; 697 r = zxsio_txn(sio, &msg); 698 699 zx_handle_t h = sio->s; 700 sio->s = 0; 701 zx_handle_close(h); 702 703 return r; 704} 705 706static ssize_t zxsio_ioctl(fdio_t* io, uint32_t op, const void* in_buf, 707 size_t in_len, void* out_buf, size_t out_len) { 708 zxsio_t* sio = (zxsio_t*)io; 709 const uint8_t* data = in_buf; 710 zx_status_t r = 0; 711 zxsio_msg_t msg; 712 713 if (in_len > ZXSIO_PAYLOAD_SZ || out_len > ZXSIO_PAYLOAD_SZ) { 714 return ZX_ERR_INVALID_ARGS; 715 } 716 717 if (IOCTL_KIND(op) != IOCTL_KIND_DEFAULT) { 718 return ZX_ERR_NOT_SUPPORTED; 719 } 720 721 memset(&msg, 0, ZXSIO_HDR_SZ); 722 msg.op = ZXSIO_IOCTL; 723 msg.datalen = in_len; 724 msg.arg = out_len; 725 msg.arg2.op = op; 726 memcpy(msg.data, data, in_len); 727 728 if ((r = zxsio_txn(sio, &msg)) < 0) { 729 return r; 730 } 731 732 size_t copy_len = msg.datalen; 733 if (msg.datalen > out_len) { 734 copy_len = out_len; 735 } 736 737 memcpy(out_buf, msg.data, copy_len); 738 return r; 739} 740 741static zx_status_t fdio_socket_shutdown(fdio_t* io, int how) { 742 if (!(io->ioflag & IOFLAG_SOCKET_CONNECTED)) { 743 return ZX_ERR_BAD_STATE; 744 } 745 zxsio_t* sio = (zxsio_t*)io; 746 if (how == SHUT_WR || how == SHUT_RDWR) { 747 // netstack expects this user signal to be set - raise it to keep that code working until 748 // it learns about the read/write disabled signals. 749 zx_object_signal_peer(sio->s, 0u, ZXSIO_SIGNAL_HALFCLOSED); 750 } 751 uint32_t options = 0; 752 switch (how) { 753 case SHUT_RD: 754 options = ZX_SOCKET_SHUTDOWN_READ; 755 break; 756 case SHUT_WR: 757 options = ZX_SOCKET_SHUTDOWN_WRITE; 758 break; 759 case SHUT_RDWR: 760 options = ZX_SOCKET_SHUTDOWN_READ | ZX_SOCKET_SHUTDOWN_WRITE; 761 break; 762 } 763 return zx_socket_write(sio->s, options, NULL, 0, NULL); 764} 765 766static fdio_ops_t fdio_socket_stream_ops = { 767 .read = zxsio_read_stream, 768 .read_at = fdio_default_read_at, 769 .write = zxsio_write_stream, 770 .write_at = fdio_default_write_at, 771 .seek = fdio_default_seek, 772 .misc = zxsio_misc, 773 .close = zxsio_close, 774 .open = fdio_default_open, 775 .clone = zxsio_clone, 776 .ioctl = zxsio_ioctl, 777 .wait_begin = zxsio_wait_begin_stream, 778 .wait_end = zxsio_wait_end_stream, 779 .unwrap = zxsio_unwrap, 780 .posix_ioctl = zxsio_posix_ioctl_stream, 781 .get_vmo = fdio_default_get_vmo, 782 .get_token = fdio_default_get_token, 783 .get_attr = fdio_default_get_attr, 784 .set_attr = fdio_default_set_attr, 785 .sync = fdio_default_sync, 786 .readdir = fdio_default_readdir, 787 .rewind = fdio_default_rewind, 788 .unlink = fdio_default_unlink, 789 .truncate = fdio_default_truncate, 790 .rename = fdio_default_rename, 791 .link = fdio_default_link, 792 .get_flags = fdio_default_get_flags, 793 .set_flags = fdio_default_set_flags, 794 .recvfrom = zxsio_recvfrom, 795 .sendto = zxsio_sendto, 796 .recvmsg = zxsio_recvmsg_stream, 797 .sendmsg = zxsio_sendmsg_stream, 798 .shutdown = fdio_socket_shutdown, 799}; 800 801static fdio_ops_t fdio_socket_dgram_ops = { 802 .read = zxsio_read_dgram, 803 .read_at = fdio_default_read_at, 804 .write = zxsio_write_dgram, 805 .write_at = fdio_default_write_at, 806 .seek = fdio_default_seek, 807 .misc = zxsio_misc, 808 .close = zxsio_close, 809 .open = fdio_default_open, 810 .clone = zxsio_clone, 811 .ioctl = zxsio_ioctl, 812 .wait_begin = zxsio_wait_begin_dgram, 813 .wait_end = zxsio_wait_end_dgram, 814 .unwrap = zxsio_unwrap, 815 .posix_ioctl = fdio_default_posix_ioctl, // not supported 816 .get_vmo = fdio_default_get_vmo, 817 .get_token = fdio_default_get_token, 818 .get_attr = fdio_default_get_attr, 819 .set_attr = fdio_default_set_attr, 820 .sync = fdio_default_sync, 821 .readdir = fdio_default_readdir, 822 .rewind = fdio_default_rewind, 823 .unlink = fdio_default_unlink, 824 .truncate = fdio_default_truncate, 825 .rename = fdio_default_rename, 826 .link = fdio_default_link, 827 .get_flags = fdio_default_get_flags, 828 .set_flags = fdio_default_set_flags, 829 .recvfrom = zxsio_recvfrom, 830 .sendto = zxsio_sendto, 831 .recvmsg = zxsio_recvmsg_dgram, 832 .sendmsg = zxsio_sendmsg_dgram, 833 .shutdown = fdio_socket_shutdown, 834}; 835 836static fdio_t* fdio_socket_create(zx_handle_t s, int flags, fdio_ops_t* ops) { 837 zxsio_t* sio = calloc(1, sizeof(*sio)); 838 if (sio == NULL) { 839 zx_handle_close(s); 840 return NULL; 841 } 842 sio->io.ops = ops; 843 sio->io.magic = FDIO_MAGIC; 844 sio->io.refcount = 1; 845 sio->io.ioflag = IOFLAG_SOCKET | flags; 846 sio->s = s; 847 sio->flags = 0; 848 return &sio->io; 849} 850 851fdio_t* fdio_socket_create_stream(zx_handle_t s, int flags) { 852 return fdio_socket_create(s, flags, &fdio_socket_stream_ops); 853} 854 855fdio_t* fdio_socket_create_datagram(zx_handle_t s, int flags) { 856 return fdio_socket_create(s, flags, &fdio_socket_dgram_ops); 857} 858