// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fidl/fuchsia.net.name/cpp/wire.h>
#include <fidl/fuchsia.net/cpp/wire.h>
#include <fidl/fuchsia.posix.socket.packet/cpp/wire.h>
#include <fidl/fuchsia.posix.socket.raw/cpp/wire.h>
#include <ifaddrs.h>
#include <lib/zx/channel.h>
#include <lib/zx/eventpair.h>
#include <lib/zxio/bsdsocket.h>
#include <lib/zxio/ops.h>
#include <lib/zxio/types.h>
#include <lib/zxio/watcher.h>
#include <lib/zxio/zxio.h>
#include <string.h>
#include <zircon/syscalls.h>

#include <atomic>
#include <new>
#include <type_traits>

#include <netpacket/packet.h>

#include "private.h"

namespace fsocket = fuchsia_posix_socket;
namespace frawsocket = fuchsia_posix_socket_raw;
namespace fpacketsocket = fuchsia_posix_socket_packet;

// The private fields of a |zxio_t| object.
//
// In |ops.h|, the |zxio_t| struct is defined as opaque. Clients of the zxio
// library are forbidden from relying upon the structure of |zxio_t| objects.
// To avoid temptation, the details of the structure are defined only in this
// implementation file and are not visible in the header.
using zxio_internal_t = struct zxio_internal {
  explicit zxio_internal(const zxio_ops_t* ops) : ops(ops) {}

  const zxio_ops_t* ops;

  // When adding fields to the |zxio_internal_t| struct, one may take from
  // the reserved bytes here to ensure that the ABI stays compatible.
  uint64_t reserved[3];
};

static_assert(sizeof(zxio_t) == sizeof(zxio_internal_t), "zxio_t should match zxio_internal_t");

// Converters from the public (opaque) types to the internal (implementation) types.
namespace {

zxio_internal_t* to_internal(zxio_t* io) { return reinterpret_cast<zxio_internal_t*>(io); }

const zxio_internal_t* to_internal(const zxio_t* io) {
  return reinterpret_cast<const zxio_internal_t*>(io);
}

}  // namespace

bool zxio_is_valid(const zxio_t* io) {
  if (io == nullptr) {
    return false;
  }
  const zxio_internal_t* zio = to_internal(io);
  return zio->ops != nullptr;
}

void zxio_init(zxio_t* io, const zxio_ops_t* ops) { new (io) zxio_internal_t(ops); }

const zxio_ops_t* zxio_get_ops(zxio_t* io) {
  const zxio_internal_t* zio = to_internal(io);
  return zio->ops;
}

zx_status_t zxio_close(zxio_t* io, const bool should_wait) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  static_assert(std::is_trivially_destructible<zxio_internal_t>::value,
                "zxio_internal_t must have trivial destructor");
  zxio_internal_t* zio = to_internal(io);
  zx_status_t status = zio->ops->close(io, should_wait);
  // Poison the object. Double destruction is undefined behavior.
  zio->ops = nullptr;
  return status;
}

zx_status_t zxio_release(zxio_t* io, zx_handle_t* out_handle) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->release(io, out_handle);
}

zx_status_t zxio_borrow(zxio_t* io, zx_handle_t* out_handle) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->borrow(io, out_handle);
}

zx_status_t zxio_clone(zxio_t* io, zx_handle_t* out_handle) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->clone(io, out_handle);
}

zx_status_t zxio_wait_one(zxio_t* io, zxio_signals_t signals, zx_time_t deadline,
                          zxio_signals_t* out_observed) {
  if (!zxio_is_valid(io)) {
    *out_observed = ZXIO_SIGNAL_NONE;
    return ZX_ERR_BAD_HANDLE;
  }
  zx_handle_t handle = ZX_HANDLE_INVALID;
  zx_signals_t zx_signals = ZX_SIGNAL_NONE;
  zxio_wait_begin(io, signals, &handle, &zx_signals);
  if (handle == ZX_HANDLE_INVALID) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_signals_t zx_observed = ZX_SIGNAL_NONE;
  zx_status_t status = zx_object_wait_one(handle, zx_signals, deadline, &zx_observed);
  if (status != ZX_OK) {
    return status;
  }
  zxio_wait_end(io, zx_signals, out_observed);
  return ZX_OK;
}

void zxio_wait_begin(zxio_t* io, zxio_signals_t zxio_signals, zx_handle_t* out_handle,
                     zx_signals_t* out_zx_signals) {
  if (!zxio_is_valid(io)) {
    *out_handle = ZX_HANDLE_INVALID;
    *out_zx_signals = ZX_SIGNAL_NONE;
    return;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->wait_begin(io, zxio_signals, out_handle, out_zx_signals);
}

void zxio_wait_end(zxio_t* io, zx_signals_t zx_signals, zxio_signals_t* out_zxio_signals) {
  if (!zxio_is_valid(io)) {
    *out_zxio_signals = ZXIO_SIGNAL_NONE;
    return;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->wait_end(io, zx_signals, out_zxio_signals);
}

zx_status_t zxio_sync(zxio_t* io) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->sync(io);
}

zx_status_t zxio_attr_get(zxio_t* io, zxio_node_attributes_t* out_attr) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->attr_get(io, out_attr);
}

zx_status_t zxio_attr_set(zxio_t* io, const zxio_node_attributes_t* attr) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->attr_set(io, attr);
}

zx_status_t zxio_read(zxio_t* io, void* buffer, size_t capacity, zxio_flags_t flags,
                      size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  const zx_iovec_t vector = {
      .buffer = buffer,
      .capacity = capacity,
  };
  return zxio_readv(io, &vector, 1, flags, out_actual);
}

zx_status_t zxio_read_at(zxio_t* io, zx_off_t offset, void* buffer, size_t capacity,
                         zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  const zx_iovec_t vector = {
      .buffer = buffer,
      .capacity = capacity,
  };
  return zxio_readv_at(io, offset, &vector, 1, flags, out_actual);
}

zx_status_t zxio_write(zxio_t* io, const void* buffer, size_t capacity, zxio_flags_t flags,
                       size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  const zx_iovec_t vector = {
      .buffer = const_cast<void*>(buffer),
      .capacity = capacity,
  };
  return zxio_writev(io, &vector, 1, flags, out_actual);
}

zx_status_t zxio_write_at(zxio_t* io, zx_off_t offset, const void* buffer, size_t capacity,
                          zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  const zx_iovec_t vector = {
      .buffer = const_cast<void*>(buffer),
      .capacity = capacity,
  };
  return zxio_writev_at(io, offset, &vector, 1, flags, out_actual);
}

zx_status_t zxio_readv(zxio_t* io, const zx_iovec_t* vector, size_t vector_count,
                       zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->readv(io, vector, vector_count, flags, out_actual);
}

zx_status_t zxio_readv_at(zxio_t* io, zx_off_t offset, const zx_iovec_t* vector,
                          size_t vector_count, zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->readv_at(io, offset, vector, vector_count, flags, out_actual);
}

zx_status_t zxio_writev(zxio_t* io, const zx_iovec_t* vector, size_t vector_count,
                        zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->writev(io, vector, vector_count, flags, out_actual);
}

zx_status_t zxio_writev_at(zxio_t* io, zx_off_t offset, const zx_iovec_t* vector,
                           size_t vector_count, zxio_flags_t flags, size_t* out_actual) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->writev_at(io, offset, vector, vector_count, flags, out_actual);
}

static_assert(ZX_STREAM_SEEK_ORIGIN_START == ZXIO_SEEK_ORIGIN_START, "ZXIO should match ZX");
static_assert(ZX_STREAM_SEEK_ORIGIN_CURRENT == ZXIO_SEEK_ORIGIN_CURRENT, "ZXIO should match ZX");
static_assert(ZX_STREAM_SEEK_ORIGIN_END == ZXIO_SEEK_ORIGIN_END, "ZXIO should match ZX");

zx_status_t zxio_seek(zxio_t* io, zxio_seek_origin_t start, int64_t offset, size_t* out_offset) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->seek(io, start, offset, out_offset);
}

zx_status_t zxio_truncate(zxio_t* io, uint64_t length) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->truncate(io, length);
}

zx_status_t zxio_flags_get(zxio_t* io, uint32_t* out_flags) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->flags_get(io, out_flags);
}

zx_status_t zxio_flags_set(zxio_t* io, uint32_t flags) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->flags_set(io, flags);
}

zx_status_t zxio_token_get(zxio_t* io, zx_handle_t* out_token) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->token_get(io, out_token);
}

zx_status_t zxio_vmo_get(zxio_t* io, zxio_vmo_flags_t flags, zx_handle_t* out_vmo) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->vmo_get(io, flags, out_vmo);
}

zx_status_t zxio_on_mapped(zxio_t* io, void* ptr) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->on_mapped(io, ptr);
}

zx_status_t zxio_get_read_buffer_available(zxio_t* io, size_t* out_available) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->get_read_buffer_available(io, out_available);
}

zx_status_t zxio_shutdown(zxio_t* io, zxio_shutdown_options_t options, int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->shutdown(io, options, out_code);
}

zx_status_t zxio_open(zxio_t* directory, uint32_t flags, const char* path, size_t path_len,
                      zxio_storage_t* storage) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->open(directory, flags, path, path_len, storage);
}

zx_status_t zxio_open2(zxio_t* directory, const char* path, size_t path_len,
                       const zxio_open_options_t* options, zxio_node_attributes_t* inout_attr,
                       zxio_storage_t* storage) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->open2(directory, path, path_len, options, inout_attr, storage);
}

zx_status_t zxio_open_async(zxio_t* directory, uint32_t flags, const char* path, size_t path_len,
                            zx_handle_t request) {
  if (!zxio_is_valid(directory)) {
    zx_handle_close(request);
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->open_async(directory, flags, path, path_len, request);
}

zx_status_t zxio_unlink(zxio_t* directory, const char* name, size_t name_len, int flags) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->unlink(directory, name, name_len, flags);
}

zx_status_t zxio_rename(zxio_t* old_directory, const char* old_path, size_t old_path_len,
                        zx_handle_t new_directory_token, const char* new_path,
                        size_t new_path_len) {
  if (!zxio_is_valid(old_directory)) {
    zx_handle_close(new_directory_token);
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(old_directory);
  return zio->ops->rename(old_directory, old_path, old_path_len, new_directory_token, new_path,
                          new_path_len);
}

zx_status_t zxio_link(zxio_t* src_directory, const char* src_path, size_t src_path_len,
                      zx_handle_t dst_directory_token, const char* dst_path, size_t dst_path_len) {
  if (!zxio_is_valid(src_directory)) {
    zx_handle_close(dst_directory_token);
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(src_directory);
  return zio->ops->link(src_directory, src_path, src_path_len, dst_directory_token, dst_path,
                        dst_path_len);
}

zx_status_t zxio_link_into(zxio_t* object, zx_handle_t dst_directory_token, const char* dst_path,
                           size_t dst_path_len) {
  if (!zxio_is_valid(object)) {
    zx_handle_close(dst_directory_token);
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(object);
  return zio->ops->link_into(object, dst_directory_token, dst_path, dst_path_len);
}

zx_status_t zxio_dirent_iterator_init(zxio_dirent_iterator_t* iterator, zxio_t* directory) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  if (iterator == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->dirent_iterator_init(directory, iterator);
}

zx_status_t zxio_dirent_iterator_next(zxio_dirent_iterator_t* iterator,
                                      zxio_dirent_t* inout_entry) {
  if (!zxio_is_valid(iterator->io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  if (inout_entry == nullptr || inout_entry->name == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  zxio_internal_t* zio = to_internal(iterator->io);
  return zio->ops->dirent_iterator_next(iterator->io, iterator, inout_entry);
}

zx_status_t zxio_dirent_iterator_rewind(zxio_dirent_iterator_t* iterator) {
  if (!zxio_is_valid(iterator->io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(iterator->io);
  return zio->ops->dirent_iterator_rewind(iterator->io, iterator);
}

void zxio_dirent_iterator_destroy(zxio_dirent_iterator_t* iterator) {
  if (!zxio_is_valid(iterator->io)) {
    return;
  }
  zxio_internal_t* zio = to_internal(iterator->io);
  zio->ops->dirent_iterator_destroy(iterator->io, iterator);
}

zx_status_t zxio_isatty(zxio_t* io, bool* tty) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->isatty(io, tty);
}

zx_status_t zxio_get_window_size(zxio_t* io, uint32_t* width, uint32_t* height) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  if (width == nullptr || height == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->get_window_size(io, width, height);
}

zx_status_t zxio_set_window_size(zxio_t* io, uint32_t width, uint32_t height) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->set_window_size(io, width, height);
}

zx_status_t zxio_ioctl(zxio_t* io, int request, int16_t* out_code, va_list va) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->ioctl(io, request, out_code, va);
}

zx_status_t zxio_watch_directory(zxio_t* directory, zxio_watch_directory_cb cb, zx_time_t deadline,
                                 void* context) {
  if (!zxio_is_valid(directory)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(directory);
  return zio->ops->watch_directory(directory, cb, deadline, context);
}

zx_status_t zxio_bind(zxio_t* io, const struct sockaddr* addr, socklen_t addrlen,
                      int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->bind(io, addr, addrlen, out_code);
}

zx_status_t zxio_connect(zxio_t* io, const struct sockaddr* addr, socklen_t addrlen,
                         int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->connect(io, addr, addrlen, out_code);
}

zx_status_t zxio_listen(zxio_t* io, int backlog, int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->listen(io, backlog, out_code);
}

zx_status_t zxio_accept(zxio_t* io, struct sockaddr* addr, socklen_t* addrlen,
                        zxio_storage_t* out_storage, int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->accept(io, addr, addrlen, out_storage, out_code);
}

zx_status_t zxio_getsockname(zxio_t* io, struct sockaddr* addr, socklen_t* addrlen,
                             int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->getsockname(io, addr, addrlen, out_code);
}

zx_status_t zxio_getpeername(zxio_t* io, struct sockaddr* addr, socklen_t* addrlen,
                             int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->getpeername(io, addr, addrlen, out_code);
}

zx_status_t zxio_getsockopt(zxio_t* io, int level, int optname, void* optval, socklen_t* optlen,
                            int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->getsockopt(io, level, optname, optval, optlen, out_code);
}

zx_status_t zxio_setsockopt(zxio_t* io, int level, int optname, const void* optval,
                            socklen_t optlen, int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->setsockopt(io, level, optname, optval, optlen, out_code);
}

zx_status_t zxio_recvmsg(zxio_t* io, struct msghdr* msg, int flags, size_t* out_actual,
                         int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->recvmsg(io, msg, flags, out_actual, out_code);
}

zx_status_t zxio_sendmsg(zxio_t* io, const struct msghdr* msg, int flags, size_t* out_actual,
                         int16_t* out_code) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }

  zxio_internal_t* zio = to_internal(io);
  return zio->ops->sendmsg(io, msg, flags, out_actual, out_code);
}

template <typename T>
zx::result<fidl::UnownedClientEnd<T>> connect_socket_provider(
    zxio_service_connector service_connector) {
  zx_handle_t socket_provider_handle;
  zx_status_t status =
      service_connector(fidl::DiscoverableProtocolName<T>, &socket_provider_handle);
  if (status != ZX_OK) {
    return zx::error(status);
  }
  return zx::ok(fidl::UnownedClientEnd<T>(zx::unowned_channel(socket_provider_handle)));
}

zx_status_t zxio_socket(zxio_service_connector service_connector, int domain, int type,
                        int protocol, zxio_storage_alloc allocator, void** out_context,
                        int16_t* out_code) {
  zxio_storage_t* zxio_storage = nullptr;
  fsocket::wire::Domain sock_domain;
  switch (domain) {
    case AF_PACKET: {
      if ((protocol > std::numeric_limits<uint16_t>::max()) ||
          (protocol < std::numeric_limits<uint16_t>::min())) {
        return ZX_ERR_INVALID_ARGS;
      }

      fpacketsocket::wire::Kind kind;
      switch (type) {
        case SOCK_DGRAM:
          kind = fpacketsocket::wire::Kind::kNetwork;
          break;
        case SOCK_RAW:
          kind = fpacketsocket::wire::Kind::kLink;
          break;
        default:
          return ZX_ERR_INVALID_ARGS;
      }

      zx::result<fidl::UnownedClientEnd<fpacketsocket::Provider>> provider =
          connect_socket_provider<fpacketsocket::Provider>(service_connector);
      if (provider.is_error()) {
        return ZX_ERR_IO;
      }
      fidl::WireResult socket_result = fidl::WireCall(provider.value())->Socket(kind);
      if (!socket_result.ok()) {
        return socket_result.status();
      }
      if (socket_result->is_error()) {
        *out_code = static_cast<int16_t>(socket_result->error_value());
        return ZX_OK;
      }
      fidl::ClientEnd<fpacketsocket::Socket>& control = socket_result->value()->socket;
      fidl::WireResult result = fidl::WireCall(control)->Describe();
      if (!result.ok()) {
        return result.status();
      }
      fidl::WireResponse response = result.value();
      if (!response.has_event()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      if (zx_status_t status =
              allocator(ZXIO_OBJECT_TYPE_PACKET_SOCKET, &zxio_storage, out_context);
          status != ZX_OK || zxio_storage == nullptr) {
        return ZX_ERR_NO_MEMORY;
      }
      if (zx_status_t status = zxio_packet_socket_init(zxio_storage, std::move(response.event()),
                                                       std::move(control));
          status != ZX_OK) {
        return status;
      }
      const sockaddr_ll sll = {
          .sll_family = AF_PACKET,
          // NB: protocol is in network byte order.
          .sll_protocol = static_cast<uint16_t>(protocol),
      };

      if (sll.sll_protocol != 0) {
        // We successfully created the packet socket but the caller wants the
        // socket to be associated with some protocol so we do that now.
        if (zx_status_t status = zxio_bind(
                &zxio_storage->io, reinterpret_cast<const sockaddr*>(&sll), sizeof(sll), out_code);
            status != ZX_OK) {
          return status;
        }
      }
      *out_code = 0;
      return ZX_OK;
    }
    case AF_INET:
      sock_domain = fsocket::wire::Domain::kIpv4;
      break;
    case AF_INET6:
      sock_domain = fsocket::wire::Domain::kIpv6;
      break;
    default:
      return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
  }

  switch (type) {
    case SOCK_STREAM:
      switch (protocol) {
        case IPPROTO_IP:
        case IPPROTO_TCP: {
          zx::result<fidl::UnownedClientEnd<fsocket::Provider>> provider =
              connect_socket_provider<fsocket::Provider>(service_connector);
          if (provider.is_error()) {
            return ZX_ERR_IO;
          }
          auto socket_result =
              fidl::WireCall(provider.value())
                  ->StreamSocket(sock_domain, fsocket::wire::StreamSocketProtocol::kTcp);
          if (socket_result.status() != ZX_OK) {
            return socket_result.status();
          }
          if (socket_result->is_error()) {
            *out_code = static_cast<int16_t>(socket_result->error_value());
            return ZX_OK;
          }

          fidl::ClientEnd<fsocket::StreamSocket>& control = socket_result->value()->s;
          fidl::WireResult result = fidl::WireCall(control)->Describe();
          if (!result.ok()) {
            return result.status();
          }
          fidl::WireResponse response = result.value();
          if (!response.has_socket()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          zx_info_socket_t info;
          zx::socket& socket = response.socket();
          if (zx_status_t status =
                  socket.get_info(ZX_INFO_SOCKET, &info, sizeof(info), nullptr, nullptr);
              status != ZX_OK) {
            return status;
          }
          if (zx_status_t status =
                  allocator(ZXIO_OBJECT_TYPE_STREAM_SOCKET, &zxio_storage, out_context);
              status != ZX_OK || zxio_storage == nullptr) {
            return ZX_ERR_NO_MEMORY;
          }
          if (zx_status_t status = zxio_stream_socket_init(
                  zxio_storage, std::move(response.socket()), info, false, std::move(control));
              status != ZX_OK) {
            return status;
          }

        } break;
        default:
          return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
      }
      break;
    case SOCK_DGRAM: {
      fsocket::wire::DatagramSocketProtocol proto;
      switch (protocol) {
        case IPPROTO_IP:
        case IPPROTO_UDP:
          proto = fsocket::wire::DatagramSocketProtocol::kUdp;
          break;
        case IPPROTO_ICMP:
          if (sock_domain != fsocket::wire::Domain::kIpv4) {
            return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
          }
          proto = fsocket::wire::DatagramSocketProtocol::kIcmpEcho;
          break;
        case IPPROTO_ICMPV6:
          if (sock_domain != fsocket::wire::Domain::kIpv6) {
            return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
          }
          proto = fsocket::wire::DatagramSocketProtocol::kIcmpEcho;
          break;
        default:
          return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
      }

      zx::result<fidl::UnownedClientEnd<fsocket::Provider>> provider =
          connect_socket_provider<fsocket::Provider>(service_connector);
      if (provider.is_error()) {
        return ZX_ERR_IO;
      }

      fidl::WireResult socket_result =
          fidl::WireCall(provider.value())->DatagramSocket(sock_domain, proto);
      if (socket_result.status() != ZX_OK) {
        return socket_result.status();
      }
      if (socket_result->is_error()) {
        *out_code = static_cast<int16_t>(socket_result->error_value());
        return ZX_OK;
      }
      fsocket::wire::ProviderDatagramSocketResponse& response = *socket_result->value();
      if (response.has_invalid_tag()) {
        return ZX_ERR_IO;
      }
      switch (response.Which()) {
        case fsocket::wire::ProviderDatagramSocketResponse::Tag::kDatagramSocket: {
          fidl::ClientEnd<fsocket::DatagramSocket>& control = response.datagram_socket();
          fidl::WireResult result = fidl::WireCall(control)->Describe();
          if (!result.ok()) {
            return result.status();
          }
          fidl::WireResponse response = result.value();
          if (!response.has_socket()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          if (!response.has_tx_meta_buf_size()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          if (!response.has_rx_meta_buf_size()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          if (!(response.has_metadata_encoding_protocol_version() &&
                response.metadata_encoding_protocol_version() ==
                    fsocket::UdpMetadataEncodingProtocolVersion::kZero)) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          zx::socket& socket = response.socket();
          zx_info_socket_t info;
          if (zx_status_t status =
                  socket.get_info(ZX_INFO_SOCKET, &info, sizeof(info), nullptr, nullptr);
              status != ZX_OK) {
            return status;
          }
          if (zx_status_t status =
                  allocator(ZXIO_OBJECT_TYPE_DATAGRAM_SOCKET, &zxio_storage, out_context);
              status != ZX_OK || zxio_storage == nullptr) {
            return ZX_ERR_NO_MEMORY;
          }
          if (zx_status_t status = zxio_datagram_socket_init(zxio_storage, std::move(socket), info,
                                                             {
                                                                 response.tx_meta_buf_size(),
                                                                 response.rx_meta_buf_size(),
                                                             },
                                                             std::move(control));
              status != ZX_OK) {
            return status;
          }
        } break;
        case fsocket::wire::ProviderDatagramSocketResponse::Tag::kSynchronousDatagramSocket: {
          fidl::ClientEnd<fsocket::SynchronousDatagramSocket>& control =
              response.synchronous_datagram_socket();
          fidl::WireResult result = fidl::WireCall(control)->Describe();
          if (!result.ok()) {
            return result.status();
          }
          fidl::WireResponse response = result.value();
          if (!response.has_event()) {
            return ZX_ERR_NOT_SUPPORTED;
          }
          if (zx_status_t status = allocator(ZXIO_OBJECT_TYPE_SYNCHRONOUS_DATAGRAM_SOCKET,
                                             &zxio_storage, out_context);
              status != ZX_OK || zxio_storage == nullptr) {
            return ZX_ERR_NO_MEMORY;
          }
          if (zx_status_t status = zxio_synchronous_datagram_socket_init(
                  zxio_storage, std::move(response.event()), std::move(control));
              status != ZX_OK) {
            return status;
          }
        } break;
      }
    } break;
    case SOCK_RAW: {
      if (protocol == 0) {
        return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
      }
      if ((protocol > std::numeric_limits<uint8_t>::max()) ||
          (protocol < std::numeric_limits<uint8_t>::min())) {
        return ZX_ERR_INVALID_ARGS;
      }
      frawsocket::wire::ProtocolAssociation proto_assoc;
      uint8_t sock_protocol = static_cast<uint8_t>(protocol);
      // Sockets created with IPPROTO_RAW are only used to send packets as per
      // https://linux.die.net/man/7/raw,
      //
      //   A protocol of IPPROTO_RAW implies enabled IP_HDRINCL and is able to
      //   send any IP protocol that is specified in the passed header. Receiving
      //   of all IP protocols via IPPROTO_RAW is not possible using raw sockets.
      if (protocol == IPPROTO_RAW) {
        proto_assoc = frawsocket::wire::ProtocolAssociation::WithUnassociated({});
      } else {
        proto_assoc = frawsocket::wire::ProtocolAssociation::WithAssociated(sock_protocol);
      }

      zx::result<fidl::UnownedClientEnd<frawsocket::Provider>> provider =
          connect_socket_provider<frawsocket::Provider>(service_connector);
      if (provider.is_error()) {
        return ZX_ERR_IO;
      }
      fidl::WireResult socket_result =
          fidl::WireCall(provider.value())->Socket(sock_domain, proto_assoc);
      if (!socket_result.ok()) {
        return ZX_ERR_PEER_CLOSED;
      }
      if (socket_result->is_error()) {
        *out_code = static_cast<int16_t>(socket_result->error_value());
        return ZX_OK;
      }
      fidl::ClientEnd<frawsocket::Socket>& control = socket_result->value()->s;
      fidl::WireResult result = fidl::WireCall(control)->Describe();
      if (!result.ok()) {
        return result.status();
      }
      fidl::WireResponse response = result.value();
      if (!response.has_event()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      if (zx_status_t status = allocator(ZXIO_OBJECT_TYPE_RAW_SOCKET, &zxio_storage, out_context);
          status != ZX_OK || zxio_storage == nullptr) {
        return ZX_ERR_NO_MEMORY;
      }
      if (zx_status_t status =
              zxio_raw_socket_init(zxio_storage, std::move(response.event()), std::move(control));
          status != ZX_OK) {
        return status;
      }
    } break;
    default:
      return ZX_ERR_PROTOCOL_NOT_SUPPORTED;
  }

  *out_code = 0;
  return ZX_OK;
}

zx_status_t zxio_read_link(zxio_t* io, const uint8_t** out_target, size_t* out_target_len) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->read_link(io, out_target, out_target_len);
}

zx_status_t zxio_create_symlink(zxio_t* io, const char* name, size_t name_len,
                                const uint8_t* target, size_t target_len, zxio_storage_t* storage) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->create_symlink(io, name, name_len, target, target_len, storage);
}

zx_status_t zxio_xattr_list(zxio_t* io,
                            void (*callback)(void* context, const uint8_t* name, size_t name_len),
                            void* context) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->xattr_list(io, callback, context);
}

zx_status_t zxio_xattr_get(zxio_t* io, const uint8_t* name, size_t name_len,
                           zx_status_t (*callback)(void* context, zxio_xattr_data_t data),
                           void* context) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->xattr_get(io, name, name_len, callback, context);
}

zx_status_t zxio_xattr_set(zxio_t* io, const uint8_t* name, size_t name_len, const uint8_t* value,
                           size_t value_len, zxio_xattr_set_mode_t mode) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->xattr_set(io, name, name_len, value, value_len, mode);
}

zx_status_t zxio_xattr_remove(zxio_t* io, const uint8_t* name, size_t name_len) {
  if (!zxio_is_valid(io)) {
    return ZX_ERR_BAD_HANDLE;
  }
  zxio_internal_t* zio = to_internal(io);
  return zio->ops->xattr_remove(io, name, name_len);
}
