// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/socket.h"

#include "bin/dartutils.h"
#include "bin/eventhandler.h"
#include "bin/file.h"
#include "bin/io_buffer.h"
#include "bin/isolate_data.h"
#include "bin/lockers.h"
#include "bin/process.h"
#include "bin/thread.h"
#include "bin/typed_data_utils.h"
#include "bin/utils.h"

#include "include/dart_api.h"

#include "platform/globals.h"
#include "platform/utils.h"

namespace dart {
namespace bin {

static constexpr int kSocketIdNativeField = 0;

ListeningSocketRegistry* globalTcpListeningSocketRegistry = nullptr;

bool Socket::short_socket_read_ = false;
bool Socket::short_socket_write_ = false;

void ListeningSocketRegistry::Initialize() {
  ASSERT(globalTcpListeningSocketRegistry == nullptr);
  globalTcpListeningSocketRegistry = new ListeningSocketRegistry();
}

ListeningSocketRegistry* ListeningSocketRegistry::Instance() {
  return globalTcpListeningSocketRegistry;
}

void ListeningSocketRegistry::Cleanup() {
  delete globalTcpListeningSocketRegistry;
  globalTcpListeningSocketRegistry = nullptr;
}

ListeningSocketRegistry::OSSocket* ListeningSocketRegistry::LookupByPort(
    intptr_t port) {
  SimpleHashMap::Entry* entry = sockets_by_port_.Lookup(
      GetHashmapKeyFromIntptr(port), GetHashmapHashFromIntptr(port), false);
  if (entry == nullptr) {
    return nullptr;
  }
  return reinterpret_cast<OSSocket*>(entry->value);
}

void ListeningSocketRegistry::InsertByPort(intptr_t port, OSSocket* socket) {
  SimpleHashMap::Entry* entry = sockets_by_port_.Lookup(
      GetHashmapKeyFromIntptr(port), GetHashmapHashFromIntptr(port), true);
  ASSERT(entry != nullptr);
  entry->value = reinterpret_cast<void*>(socket);
}

void ListeningSocketRegistry::RemoveByPort(intptr_t port) {
  sockets_by_port_.Remove(GetHashmapKeyFromIntptr(port),
                          GetHashmapHashFromIntptr(port));
}

ListeningSocketRegistry::OSSocket* ListeningSocketRegistry::LookupByFd(
    Socket* fd) {
  SimpleHashMap::Entry* entry = sockets_by_fd_.Lookup(
      GetHashmapKeyFromIntptr(reinterpret_cast<intptr_t>(fd)),
      GetHashmapHashFromIntptr(reinterpret_cast<intptr_t>(fd)), false);
  if (entry == nullptr) {
    return nullptr;
  }
  return reinterpret_cast<OSSocket*>(entry->value);
}

void ListeningSocketRegistry::InsertByFd(Socket* fd, OSSocket* socket) {
  SimpleHashMap::Entry* entry = sockets_by_fd_.Lookup(
      GetHashmapKeyFromIntptr(reinterpret_cast<intptr_t>(fd)),
      GetHashmapHashFromIntptr(reinterpret_cast<intptr_t>(fd)), true);
  ASSERT(entry != nullptr);
  entry->value = reinterpret_cast<void*>(socket);
}

void ListeningSocketRegistry::RemoveByFd(Socket* fd) {
  sockets_by_fd_.Remove(
      GetHashmapKeyFromIntptr(reinterpret_cast<intptr_t>(fd)),
      GetHashmapHashFromIntptr(reinterpret_cast<intptr_t>(fd)));
}

Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object,
                                                      const RawAddr& addr,
                                                      intptr_t backlog,
                                                      bool v6_only,
                                                      bool shared) {
  MutexLocker ml(&mutex_);

  OSSocket* first_os_socket = nullptr;
  intptr_t port = SocketAddress::GetAddrPort(addr);
  if (port > 0) {
    first_os_socket = LookupByPort(port);
    if (first_os_socket != nullptr) {
      // There is already a socket listening on this port. We need to ensure
      // that if there is one also listening on the same address, it was created
      // with `shared = true`, ...
      OSSocket* os_socket = first_os_socket;
      OSSocket* os_socket_same_addr = FindOSSocketWithAddress(os_socket, addr);

      if (os_socket_same_addr != nullptr) {
        if (!os_socket_same_addr->shared || !shared) {
          OSError os_error(-1,
                           "The shared flag to bind() needs to be `true` if "
                           "binding multiple times on the same (address, port) "
                           "combination.",
                           OSError::kUnknown);
          return DartUtils::NewDartOSError(&os_error);
        }
        if (os_socket_same_addr->v6_only != v6_only) {
          OSError os_error(-1,
                           "The v6Only flag to bind() needs to be the same if "
                           "binding multiple times on the same (address, port) "
                           "combination.",
                           OSError::kUnknown);
          return DartUtils::NewDartOSError(&os_error);
        }

        // This socket creation is the exact same as the one which originally
        // created the socket. Feed same fd and store it into native field
        // of dart socket_object. Sockets here will share same fd but contain a
        // different port() through EventHandler_SendData.
        Socket* socketfd = new Socket(os_socket_same_addr->fd);
        os_socket_same_addr->ref_count++;
        // We set as a side-effect the file descriptor on the dart
        // socket_object.
        Socket::ReuseSocketIdNativeField(socket_object, socketfd,
                                         Socket::kFinalizerListening);
        InsertByFd(socketfd, os_socket_same_addr);
        return Dart_True();
      }
    }
  }

  // There is no socket listening on that (address, port), so we create new one.
  intptr_t fd = ServerSocket::CreateBindListen(addr, backlog, v6_only);
  if (fd == -5) {
    OSError os_error(-1, "Invalid host", OSError::kUnknown);
    return DartUtils::NewDartOSError(&os_error);
  }
  if (fd < 0) {
    OSError error;
    return DartUtils::NewDartOSError(&error);
  }
  if (!ServerSocket::StartAccept(fd)) {
    OSError os_error(-1, "Failed to start accept", OSError::kUnknown);
    return DartUtils::NewDartOSError(&os_error);
  }
  intptr_t allocated_port = SocketBase::GetPort(fd);
  ASSERT(allocated_port > 0);

  if (allocated_port != port) {
    // There are two cases to consider:
    //
    //   a) The user requested (address, port) where port != 0 which means
    //      we re-use an existing socket if available (and it is shared) or we
    //      create a new one. The new socket is guaranteed to have that
    //      selected port.
    //
    //   b) The user requested (address, 0). This will make us *always* create a
    //      new socket. The OS will assign it a new `allocated_port` and we will
    //      insert into our data structures. *BUT* There might already be an
    //      existing (address2, `allocated_port`) where address != address2. So
    //      we need to do another `LookupByPort(allocated_port)` and link them
    //      via `OSSocket->next`.
    ASSERT(port == 0);
    first_os_socket = LookupByPort(allocated_port);
  }

  Socket* socketfd = new Socket(fd);
  OSSocket* os_socket =
      new OSSocket(addr, allocated_port, v6_only, shared, socketfd, nullptr);
  os_socket->ref_count = 1;
  os_socket->next = first_os_socket;

  InsertByPort(allocated_port, os_socket);
  InsertByFd(socketfd, os_socket);

  // We set as a side-effect the port on the dart socket_object.
  Socket::ReuseSocketIdNativeField(socket_object, socketfd,
                                   Socket::kFinalizerListening);

  return Dart_True();
}

Dart_Handle ListeningSocketRegistry::CreateUnixDomainBindListen(
    Dart_Handle socket_object,
    Namespace* namespc,
    const char* path,
    intptr_t backlog,
    bool shared) {
  MutexLocker ml(&mutex_);

  RawAddr addr;
  Dart_Handle result =
      SocketAddress::GetUnixDomainSockAddr(path, namespc, &addr);
  if (!Dart_IsNull(result)) {
    return result;
  }

  if (unix_domain_sockets_ != nullptr) {
    // If there is a socket listening on this file. Ensure
    // that it was created with `shared` mode and current `shared`
    // is also true.
    OSSocket* os_socket_same_addr =
        FindMatchingUnixDomainSocket(unix_domain_sockets_, namespc, addr);
    if (os_socket_same_addr != nullptr) {
      if (!os_socket_same_addr->shared || !shared) {
        OSError os_error(-1,
                         "The shared flag to bind() needs to be `true` if "
                         "binding multiple times on the same path.",
                         OSError::kUnknown);
        return DartUtils::NewDartOSError(&os_error);
      }

      // This socket creation is the exact same as the one which originally
      // created the socket. Feed the same fd and store it into the native
      // field of dart socket_object. Sockets here will share same fd but
      // contain a different port() through EventHandler_SendData.
      Socket* socketfd = new Socket(os_socket_same_addr->fd);
      os_socket_same_addr->ref_count++;
      // We set as a side-effect the file descriptor on the dart
      // socket_object.
      Socket::ReuseSocketIdNativeField(socket_object, socketfd,
                                       Socket::kFinalizerListening);
      InsertByFd(socketfd, os_socket_same_addr);
      return Dart_True();
    }
  }

  if (addr.is_pathname_unix_socket() &&
      File::GetType(namespc, addr.un.sun_path, /*follow_links=*/false) !=
          File::kDoesNotExist) {
    // Unix domain socket by default doesn't allow binding to an existing file.
    // An error (EADDRINUSE) will be returned back. However, hanging is noticed
    // on Android so we throw an exception for all platforms.
    OSError os_error(-1, "File exists with given unix domain address",
                     OSError::kUnknown);
    return DartUtils::NewDartOSError(&os_error);
  }

  // There is no socket listening on that path, so we create new one.
  intptr_t fd = ServerSocket::CreateUnixDomainBindListen(addr, backlog);
  if (fd < 0) {
    return DartUtils::NewDartOSError();
  }
  if (!ServerSocket::StartAccept(fd)) {
    OSError os_error(-1, "Failed to start accept", OSError::kUnknown);
    return DartUtils::NewDartOSError(&os_error);
  }
  Socket* socketfd = new Socket(fd);
  OSSocket* os_socket =
      new OSSocket(addr, -1, false, shared, socketfd, namespc);
  os_socket->ref_count = 1;
  os_socket->next = unix_domain_sockets_;
  unix_domain_sockets_ = os_socket;
  InsertByFd(socketfd, os_socket);

  Socket::ReuseSocketIdNativeField(socket_object, socketfd,
                                   Socket::kFinalizerListening);

  return Dart_True();
}

bool ListeningSocketRegistry::CloseOneSafe(OSSocket* os_socket,
                                           Socket* socket) {
  ASSERT(!mutex_.TryLock());
  ASSERT(os_socket != nullptr);
  ASSERT(os_socket->ref_count > 0);
  os_socket->ref_count--;
  RemoveByFd(socket);
  if (os_socket->ref_count > 0) {
    return false;
  }
  // Unlink the socket file, if os_socket contains unix domain sockets.
  if (os_socket->address.addr.sa_family == AF_UNIX) {
#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
    // If the socket is abstract, which has a path starting with a null byte,
    // unlink() is not necessary because the file doesn't exist.
    if (os_socket->address.un.sun_path[0] != '\0') {
      Utils::Unlink(os_socket->address.un.sun_path);
    }
#else
    Utils::Unlink(os_socket->address.un.sun_path);
#endif  // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
    // Remove os_socket from unix_domain_sockets_ list.
    OSSocket* prev = nullptr;
    OSSocket* current = unix_domain_sockets_;
    while (current != nullptr) {
      if (current == os_socket) {
        if (prev == nullptr) {
          unix_domain_sockets_ = unix_domain_sockets_->next;
        } else {
          prev->next = current->next;
        }
        break;
      }
      prev = current;
      current = current->next;
    }
    delete os_socket;
    return true;
  }
  OSSocket* prev = nullptr;
  OSSocket* current = LookupByPort(os_socket->port);
  while (current != os_socket) {
    ASSERT(current != nullptr);
    prev = current;
    current = current->next;
  }

  if ((prev == nullptr) && (current->next == nullptr)) {
    // Remove last element from the list.
    RemoveByPort(os_socket->port);
  } else if (prev == nullptr) {
    // Remove first element of the list.
    InsertByPort(os_socket->port, current->next);
  } else {
    // Remove element from the list which is not the first one.
    prev->next = os_socket->next;
  }

  ASSERT(os_socket->ref_count == 0);
  delete os_socket;
  return true;
}

void ListeningSocketRegistry::CloseAllSafe() {
  MutexLocker ml(&mutex_);
  for (SimpleHashMap::Entry* cursor = sockets_by_fd_.Start(); cursor != nullptr;
       cursor = sockets_by_fd_.Next(cursor)) {
    OSSocket* os_socket = reinterpret_cast<OSSocket*>(cursor->value);
    ASSERT(os_socket != nullptr);
    delete os_socket;
  }
}

bool ListeningSocketRegistry::CloseSafe(Socket* socketfd) {
  ASSERT(!mutex_.TryLock());
  OSSocket* os_socket = LookupByFd(socketfd);
  if (os_socket != nullptr) {
    return CloseOneSafe(os_socket, socketfd);
  } else {
    // A finalizer may direct the event handler to close a listening socket
    // that it has never seen before. In this case, we return true to direct
    // the eventhandler to clean up the socket.
    return true;
  }
}

void FUNCTION_NAME(Socket_CreateConnect)(Dart_NativeArguments args) {
  RawAddr addr;
  SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
  Dart_Handle port_arg = Dart_GetNativeArgument(args, 2);
  int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
  SocketAddress::SetAddrPort(&addr, static_cast<intptr_t>(port));
  if (addr.addr.sa_family == AF_INET6) {
    Dart_Handle scope_id_arg = Dart_GetNativeArgument(args, 3);
    int64_t scope_id =
        DartUtils::GetInt64ValueCheckRange(scope_id_arg, 0, 65535);
    SocketAddress::SetAddrScope(&addr, scope_id);
  }
  intptr_t socket = Socket::CreateConnect(addr);
  OSError error;
  if (socket >= 0) {
    Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
                                   Socket::kFinalizerNormal);
    Dart_SetReturnValue(args, Dart_True());
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
  }
}

// This function will abort if sourceAddr is a Unix domain socket.
// The family ("sa_family") of the socket address is inferred from the length
// of the address. Unix domain sockets addresses are the bytes of their file
// system path so they have variable length. They cannot, therefore, be
// differentiated from other address types in this function.
void FUNCTION_NAME(Socket_CreateBindConnect)(Dart_NativeArguments args) {
  RawAddr addr;
  SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
  Dart_Handle port_arg = Dart_GetNativeArgument(args, 2);
  int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
  SocketAddress::SetAddrPort(&addr, static_cast<intptr_t>(port));
  RawAddr sourceAddr;
  SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 3), &sourceAddr);
  Dart_Handle source_port_arg = Dart_GetNativeArgument(args, 4);
  int64_t source_port =
      DartUtils::GetInt64ValueCheckRange(source_port_arg, 0, 65535);
  SocketAddress::SetAddrPort(&sourceAddr, static_cast<intptr_t>(source_port));

  if (addr.addr.sa_family == AF_INET6) {
    Dart_Handle scope_id_arg = Dart_GetNativeArgument(args, 5);
    int64_t scope_id =
        DartUtils::GetInt64ValueCheckRange(scope_id_arg, 0, 65535);
    SocketAddress::SetAddrScope(&addr, scope_id);
  }
  intptr_t socket = Socket::CreateBindConnect(addr, sourceAddr);
  OSError error;
  if (socket >= 0) {
    Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
                                   Socket::kFinalizerNormal);
    Dart_SetReturnValue(args, Dart_True());
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
  }
}

void FUNCTION_NAME(Socket_CreateUnixDomainBindConnect)(
    Dart_NativeArguments args) {
#if defined(DART_HOST_OS_FUCHSIA)
  OSError os_error(
      -1, "Unix domain sockets are not available on this operating system.",
      OSError::kUnknown);
  Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
#else
  RawAddr addr;
  Dart_Handle address = Dart_GetNativeArgument(args, 1);
  if (Dart_IsNull(address)) {
    Dart_SetReturnValue(args, DartUtils::NewDartArgumentError(
                                  "expect address to be of type String"));
  }
  Dart_Handle result = SocketAddress::GetUnixDomainSockAddr(
      DartUtils::GetStringValue(address), Namespace::GetNamespace(args, 3),
      &addr);
  if (!Dart_IsNull(result)) {
    return Dart_SetReturnValue(args, result);
  }

  RawAddr sourceAddr;
  address = Dart_GetNativeArgument(args, 2);
  if (Dart_IsNull(address)) {
    return Dart_SetReturnValue(
        args,
        DartUtils::NewDartArgumentError("expect address to be of type String"));
  }
  result = SocketAddress::GetUnixDomainSockAddr(
      DartUtils::GetStringValue(address), Namespace::GetNamespace(args, 3),
      &sourceAddr);
  if (!Dart_IsNull(result)) {
    return Dart_SetReturnValue(args, result);
  }

  intptr_t socket = Socket::CreateUnixDomainBindConnect(addr, sourceAddr);
  if (socket >= 0) {
    Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
                                   Socket::kFinalizerNormal);
    Dart_SetReturnValue(args, Dart_True());
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
#endif  // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
}

void FUNCTION_NAME(Socket_CreateUnixDomainConnect)(Dart_NativeArguments args) {
#if defined(DART_HOST_OS_FUCHSIA)
  OSError os_error(
      -1, "Unix domain sockets are not available on this operating system.",
      OSError::kUnknown);
  Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
#else
  RawAddr addr;
  Dart_Handle address = Dart_GetNativeArgument(args, 1);
  if (Dart_IsNull(address)) {
    return Dart_SetReturnValue(
        args,
        DartUtils::NewDartArgumentError("expect address to be of type String"));
  }
  Dart_Handle result = SocketAddress::GetUnixDomainSockAddr(
      DartUtils::GetStringValue(address), Namespace::GetNamespace(args, 2),
      &addr);
  if (!Dart_IsNull(result)) {
    return Dart_SetReturnValue(args, result);
  }
  intptr_t socket = Socket::CreateUnixDomainConnect(addr);
  if (socket >= 0) {
    Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
                                   Socket::kFinalizerNormal);
    Dart_SetReturnValue(args, Dart_True());
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
#endif  // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
}

void FUNCTION_NAME(Socket_CreateBindDatagram)(Dart_NativeArguments args) {
  RawAddr addr;
  SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
  Dart_Handle port_arg = Dart_GetNativeArgument(args, 2);
  int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
  SocketAddress::SetAddrPort(&addr, port);
  bool reuse_addr = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3));
  bool reuse_port = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
  int ttl = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 5));
  intptr_t socket =
      Socket::CreateBindDatagram(addr, reuse_addr, reuse_port, ttl);
  if (socket >= 0) {
    Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
                                   Socket::kFinalizerNormal);
    Dart_SetReturnValue(args, Dart_True());
  } else {
    OSError error;
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
  }
}

void FUNCTION_NAME(Socket_Available)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  intptr_t available = SocketBase::Available(socket->fd());
  if (available >= 0) {
    Dart_SetIntegerReturnValue(args, available);
  } else {
    // Available failed. Mark socket as having data, to trigger a future read
    // event where the actual error can be reported.
    Dart_SetIntegerReturnValue(args, 1);
  }
}

void FUNCTION_NAME(Socket_Read)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  int64_t length = 0;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length) &&
      (length >= 0)) {
    if (Socket::short_socket_read()) {
      length = (length + 1) / 2;
    }
    uint8_t* buffer = nullptr;
    Dart_Handle result = IOBuffer::Allocate(length, &buffer);
    if (Dart_IsNull(result)) {
      Dart_ThrowException(DartUtils::NewDartOSError());
    }
    if (Dart_IsError(result)) {
      Dart_PropagateError(result);
    }
    ASSERT(buffer != nullptr);
    intptr_t bytes_read =
        SocketBase::Read(socket->fd(), buffer, length, SocketBase::kAsync);
    if (bytes_read == length) {
      Dart_SetReturnValue(args, result);
    } else if (bytes_read > 0) {
      uint8_t* new_buffer = nullptr;
      Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer);
      if (Dart_IsNull(new_result)) {
        Dart_ThrowException(DartUtils::NewDartOSError());
      }
      if (Dart_IsError(new_result)) {
        Dart_PropagateError(new_result);
      }
      ASSERT(new_buffer != nullptr);
      memmove(new_buffer, buffer, bytes_read);
      Dart_SetReturnValue(args, new_result);
    } else if (bytes_read == 0) {
      // On MacOS when reading from a tty Ctrl-D will result in reading one
      // less byte then reported as available.
      Dart_SetReturnValue(args, Dart_Null());
    } else {
      ASSERT(bytes_read == -1);
      Dart_ThrowException(DartUtils::NewDartOSError());
    }
  } else {
    Dart_Handle exception;
    {
      // Make sure OSError destructor is called.
      OSError os_error(-1, "Invalid argument", OSError::kUnknown);
      exception = DartUtils::NewDartOSError(&os_error);
    }
    Dart_ThrowException(exception);
  }
}

void FUNCTION_NAME(Socket_RecvFrom)(Dart_NativeArguments args) {
  // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can
  // handle 64k datagrams.
  const int kReceiveBufferLen = 65536;
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));

  // Ensure that a receive buffer for the UDP socket exists.
  ASSERT(socket != nullptr);
  uint8_t* recv_buffer = socket->udp_receive_buffer();
  if (recv_buffer == nullptr) {
    recv_buffer = reinterpret_cast<uint8_t*>(malloc(kReceiveBufferLen));
    socket->set_udp_receive_buffer(recv_buffer);
  }

  // Read data into the buffer.
  RawAddr addr;
  const intptr_t bytes_read = SocketBase::RecvFrom(
      socket->fd(), recv_buffer, kReceiveBufferLen, &addr, SocketBase::kAsync);
  if (bytes_read == 0) {
    Dart_SetReturnValue(args, Dart_Null());
    return;
  }
  if (bytes_read < 0) {
    ASSERT(bytes_read == -1);
    Dart_ThrowException(DartUtils::NewDartOSError());
  }

  // Datagram data read. Copy into buffer of the exact size,
  ASSERT(bytes_read >= 0);
  uint8_t* data_buffer = nullptr;
  Dart_Handle data = IOBuffer::Allocate(bytes_read, &data_buffer);
  if (Dart_IsNull(data)) {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
  if (Dart_IsError(data)) {
    Dart_PropagateError(data);
  }
  ASSERT(data_buffer != nullptr);
  memmove(data_buffer, recv_buffer, bytes_read);

  // Get the port and clear it in the sockaddr structure.
  int port = SocketAddress::GetAddrPort(addr);
  // TODO(21403): Add checks for AF_UNIX, if unix domain sockets
  // are used in SOCK_DGRAM.
  enum internet_type { IPv4, IPv6 };
  internet_type type;
  if (addr.addr.sa_family == AF_INET) {
    addr.in.sin_port = 0;
    type = IPv4;
  } else {
    ASSERT(addr.addr.sa_family == AF_INET6);
    addr.in6.sin6_port = 0;
    type = IPv6;
  }
  // Format the address to a string using the numeric format.
  char numeric_address[SocketAddress::kMaxAddressStringLength];
  SocketBase::FormatNumericAddress(addr, numeric_address,
                                   ARRAY_SIZE(numeric_address));

  // Create a Datagram object with the data and sender address and port.
  const int kNumArgs = 5;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = data;
  dart_args[1] = Dart_NewStringFromCString(numeric_address);
  if (Dart_IsError(dart_args[1])) {
    Dart_PropagateError(dart_args[1]);
  }
  dart_args[2] = SocketAddress::ToTypedData(addr);
  dart_args[3] = Dart_NewInteger(port);
  dart_args[4] = Dart_NewInteger(type);
  if (Dart_IsError(dart_args[3])) {
    Dart_PropagateError(dart_args[3]);
  }
  // TODO(sgjesse): Cache the _makeDatagram function somewhere.
  Dart_Handle io_lib = Dart_LookupLibrary(DartUtils::NewString("dart:io"));
  if (Dart_IsError(io_lib)) {
    Dart_PropagateError(io_lib);
  }
  Dart_Handle result = Dart_Invoke(
      io_lib, DartUtils::NewString("_makeDatagram"), kNumArgs, dart_args);
  Dart_SetReturnValue(args, result);
}

void FUNCTION_NAME(Socket_ReceiveMessage)(Dart_NativeArguments args) {
  Socket* socket = Socket::GetSocketIdNativeField(
      ThrowIfError(Dart_GetNativeArgument(args, 0)));
  ASSERT(socket != nullptr);

  int64_t buffer_num_bytes = 0;
  DartUtils::GetInt64Value(ThrowIfError(Dart_GetNativeArgument(args, 1)),
                           &buffer_num_bytes);
  int64_t buffer_num_bytes_allocated = buffer_num_bytes;
  uint8_t* buffer = nullptr;
  Dart_Handle data = IOBuffer::Allocate(buffer_num_bytes, &buffer);
  if (Dart_IsNull(data)) {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
  ASSERT(buffer != nullptr);

  // Can't rely on RAII since Dart_ThrowException won't call destructors.
  OSError* os_error = new OSError();
  SocketControlMessage* control_messages;
  const intptr_t messages_read = SocketBase::ReceiveMessage(
      socket->fd(), buffer, &buffer_num_bytes, &control_messages,
      SocketBase::kAsync, os_error);
  if (messages_read < 0) {
    ASSERT(messages_read == -1);
    Dart_Handle error = DartUtils::NewDartOSError(os_error);
    delete os_error;
    Dart_ThrowException(error);
  }
  delete os_error;
  if (buffer_num_bytes > 0 && buffer_num_bytes != buffer_num_bytes_allocated) {
    // If received fewer than allocated buffer size, truncate buffer.
    uint8_t* new_buffer = nullptr;
    Dart_Handle new_data = IOBuffer::Allocate(buffer_num_bytes, &new_buffer);
    if (Dart_IsNull(new_data)) {
      Dart_ThrowException(DartUtils::NewDartOSError());
    }
    ASSERT(new_buffer != nullptr);
    memmove(new_buffer, buffer, buffer_num_bytes);
    data = new_data;
  }

  // returned list has a (level, type, message bytes) triple for every message,
  // plus last element is raw data uint8list.
  Dart_Handle list = ThrowIfError(Dart_NewList(messages_read * 3 + 1));
  int j = 0;
  for (intptr_t i = 0; i < messages_read; i++) {
    SocketControlMessage* message = control_messages + i;
    Dart_Handle uint8list_message_data = ThrowIfError(
        DartUtils::MakeUint8Array(message->data(), message->data_length()));
    ThrowIfError(Dart_ListSetAt(
        list, j++, ThrowIfError(Dart_NewInteger(message->level()))));
    ThrowIfError(Dart_ListSetAt(
        list, j++, ThrowIfError(Dart_NewInteger(message->type()))));
    ThrowIfError(Dart_ListSetAt(list, j++, uint8list_message_data));
  }
  ThrowIfError(Dart_ListSetAt(list, j, data));
  Dart_SetReturnValue(args, list);
}

void FUNCTION_NAME(Socket_HasPendingWrite)(Dart_NativeArguments args) {
#if defined(DART_HOST_OS_WINDOWS)
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  const bool result = SocketBase::HasPendingWrite(socket->fd());
#else
  const bool result = false;
#endif  // defined(DART_HOST_OS_WINDOWS)
  Dart_SetReturnValue(args, Dart_NewBoolean(result));
}

void FUNCTION_NAME(Socket_WriteList)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
  ASSERT(Dart_IsList(buffer_obj));
  intptr_t offset = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
  intptr_t length = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
  bool short_write = false;
  if (Socket::short_socket_write()) {
    if (length > 1) {
      short_write = true;
    }
    length = (length + 1) / 2;
  }
  Dart_TypedData_Type type;
  uint8_t* buffer = nullptr;
  intptr_t len;
  Dart_Handle result = Dart_TypedDataAcquireData(
      buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  ASSERT((offset + length) <= len);
  buffer += offset;
  intptr_t bytes_written =
      SocketBase::Write(socket->fd(), buffer, length, SocketBase::kAsync);
  if (bytes_written >= 0) {
    Dart_TypedDataReleaseData(buffer_obj);
    if (short_write) {
      // If the write was forced 'short', indicate by returning the negative
      // number of bytes. A forced short write may not trigger a write event.
      Dart_SetIntegerReturnValue(args, -bytes_written);
    } else {
      Dart_SetIntegerReturnValue(args, bytes_written);
    }
  } else {
    // Extract OSError before we release data, as it may override the error.
    Dart_Handle error;
    {
      OSError os_error;
      Dart_TypedDataReleaseData(buffer_obj);
      error = DartUtils::NewDartOSError(&os_error);
    }
    Dart_ThrowException(error);
  }
}

void FUNCTION_NAME(Socket_SendMessage)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  intptr_t offset = DartUtils::GetNativeIntptrArgument(args, 2);
  intptr_t length = DartUtils::GetNativeIntptrArgument(args, 3);

  // List of triples <level, type, data> arranged to minimize dart api use in
  // native methods.
  Dart_Handle control_message_list_dart =
      ThrowIfError(Dart_GetNativeArgument(args, 4));
  ASSERT(Dart_IsList(control_message_list_dart));
  intptr_t num_control_messages_pieces;
  ThrowIfError(
      Dart_ListLength(control_message_list_dart, &num_control_messages_pieces));
  intptr_t num_control_messages = num_control_messages_pieces / 3;
  ASSERT((num_control_messages * 3) == num_control_messages_pieces);
  SocketControlMessage* control_messages =
      reinterpret_cast<SocketControlMessage*>(Dart_ScopeAllocate(
          sizeof(SocketControlMessage) * num_control_messages));
  ASSERT(control_messages != nullptr);

  SocketControlMessage* control_message = control_messages;
  intptr_t j = 0;
  for (intptr_t i = 0; i < num_control_messages; i++, control_message++) {
    int level = DartUtils::GetIntegerValue(
        ThrowIfError(Dart_ListGetAt(control_message_list_dart, j++)));
    int type = DartUtils::GetIntegerValue(
        ThrowIfError(Dart_ListGetAt(control_message_list_dart, j++)));
    Dart_Handle uint8list_dart =
        ThrowIfError(Dart_ListGetAt(control_message_list_dart, j++));

    TypedDataScope data(uint8list_dart);
    void* copied_data = Dart_ScopeAllocate(data.size_in_bytes());
    ASSERT(copied_data != nullptr);
    memmove(copied_data, data.data(), data.size_in_bytes());
    new (control_message)
        SocketControlMessage(level, type, copied_data, data.size_in_bytes());
  }

  // Can't rely on RAII since Dart_ThrowException won't call destructors.
  OSError* os_error = new OSError();
  intptr_t bytes_written;
  {
    Dart_Handle buffer_dart = Dart_GetNativeArgument(args, 1);
    TypedDataScope data(buffer_dart);

    ASSERT((offset + length) <= data.size_in_bytes());
    uint8_t* buffer_at_offset =
        reinterpret_cast<uint8_t*>(data.data()) + offset;
    bytes_written = SocketBase::SendMessage(
        socket->fd(), buffer_at_offset, length, control_messages,
        num_control_messages, SocketBase::kAsync, os_error);
  }

  if (bytes_written < 0) {
    Dart_Handle error = DartUtils::NewDartOSError(os_error);
    delete os_error;
    Dart_ThrowException(error);
  }
  delete os_error;

  Dart_SetIntegerReturnValue(args, bytes_written);
}

void FUNCTION_NAME(Socket_SendTo)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
  intptr_t offset = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
  intptr_t length = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
  Dart_Handle address_obj = Dart_GetNativeArgument(args, 4);
  ASSERT(Dart_IsList(address_obj));
  RawAddr addr;
  SocketAddress::GetSockAddr(address_obj, &addr);
  int64_t port = DartUtils::GetInt64ValueCheckRange(
      Dart_GetNativeArgument(args, 5), 0, 65535);
  SocketAddress::SetAddrPort(&addr, port);
  Dart_TypedData_Type type;
  uint8_t* buffer = nullptr;
  intptr_t len;
  Dart_Handle result = Dart_TypedDataAcquireData(
      buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  ASSERT((offset + length) <= len);
  buffer += offset;
  intptr_t bytes_written = SocketBase::SendTo(socket->fd(), buffer, length,
                                              addr, SocketBase::kAsync);
  if (bytes_written >= 0) {
    Dart_TypedDataReleaseData(buffer_obj);
    Dart_SetIntegerReturnValue(args, bytes_written);
  } else {
    // Extract OSError before we release data, as it may override the error.
    Dart_Handle error;
    {
      OSError os_error;
      Dart_TypedDataReleaseData(buffer_obj);
      error = DartUtils::NewDartOSError(&os_error);
    }
    Dart_ThrowException(error);
  }
}

void FUNCTION_NAME(Socket_GetPort)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  intptr_t port = SocketBase::GetPort(socket->fd());
  if (port > 0) {
    Dart_SetIntegerReturnValue(args, port);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(Socket_GetRemotePeer)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  intptr_t port = 0;
  SocketAddress* addr = SocketBase::GetRemotePeer(socket->fd(), &port);
  if (addr != nullptr) {
    Dart_Handle list = Dart_NewList(2);
    int type = addr->GetType();
    Dart_Handle entry;
    if (type == SocketAddress::TYPE_UNIX) {
      entry = Dart_NewList(2);
    } else {
      entry = Dart_NewList(3);
      Dart_ListSetAt(entry, 2, SocketAddress::ToTypedData(addr->addr()));
    }
    Dart_ListSetAt(entry, 0, Dart_NewInteger(type));
    Dart_ListSetAt(entry, 1, Dart_NewStringFromCString(addr->as_string()));

    Dart_ListSetAt(list, 0, entry);
    Dart_ListSetAt(list, 1, Dart_NewInteger(port));
    Dart_SetReturnValue(args, list);
    delete addr;
  } else {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(Socket_GetError)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  OSError os_error;
  SocketBase::GetError(socket->fd(), &os_error);
  if (os_error.code() != 0) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
  } else {
    Dart_SetReturnValue(args, Dart_Null());
  }
}

void FUNCTION_NAME(Socket_Fatal)(Dart_NativeArguments args) {
  Dart_Handle msg = Dart_GetNativeArgument(args, 0);
  const char* msgStr =
      (!Dart_IsNull(msg)) ? DartUtils::GetStringValue(msg) : nullptr;
  FATAL("Fatal error in dart:io (socket): %s", msgStr);
}

void FUNCTION_NAME(Socket_GetFD)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  Dart_SetIntegerReturnValue(args, socket->fd());
}

void FUNCTION_NAME(Socket_GetType)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  if (socket->fd() < 0) {
    OSError os_error(-1, "Socket is closed.", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
    return;
  }
  OSError os_error;
  intptr_t type = SocketBase::GetType(socket->fd());
  if (type >= 0) {
    Dart_SetIntegerReturnValue(args, type);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(Socket_GetStdioHandle)(Dart_NativeArguments args) {
  int64_t num =
      DartUtils::GetInt64ValueCheckRange(Dart_GetNativeArgument(args, 1), 0, 2);
  intptr_t socket = SocketBase::GetStdioHandle(num);
  Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
                                 Socket::kFinalizerStdio);
  Dart_SetReturnValue(args, Dart_NewBoolean(socket >= 0));
}

void FUNCTION_NAME(Socket_GetSocketId)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  intptr_t id = reinterpret_cast<intptr_t>(socket);
  Dart_SetIntegerReturnValue(args, id);
}

void FUNCTION_NAME(Socket_SetSocketId)(Dart_NativeArguments args) {
  intptr_t id = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
  intptr_t type_flag =
      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
  Socket::SocketFinalizer finalizer;
  if (Socket::IsSignalSocketFlag(type_flag)) {
    finalizer = Socket::kFinalizerSignal;
  } else {
    finalizer = Socket::kFinalizerNormal;
  }
  Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), id,
                                 finalizer);
}

void FUNCTION_NAME(ServerSocket_CreateBindListen)(Dart_NativeArguments args) {
  RawAddr addr;
  SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
  int64_t port = DartUtils::GetInt64ValueCheckRange(
      Dart_GetNativeArgument(args, 2), 0, 65535);
  SocketAddress::SetAddrPort(&addr, port);
  int64_t backlog = DartUtils::GetInt64ValueCheckRange(
      Dart_GetNativeArgument(args, 3), 0, 65535);
  bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
  bool shared = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
  if (addr.addr.sa_family == AF_INET6) {
    Dart_Handle scope_id_arg = Dart_GetNativeArgument(args, 6);
    int64_t scope_id =
        DartUtils::GetInt64ValueCheckRange(scope_id_arg, 0, 65535);
    SocketAddress::SetAddrScope(&addr, scope_id);
  }

  Dart_Handle socket_object = Dart_GetNativeArgument(args, 0);
  Dart_Handle result = ListeningSocketRegistry::Instance()->CreateBindListen(
      socket_object, addr, backlog, v6_only, shared);
  Dart_SetReturnValue(args, result);
}

void FUNCTION_NAME(ServerSocket_CreateUnixDomainBindListen)(
    Dart_NativeArguments args) {
#if defined(DART_HOST_OS_FUCHSIA)
  OSError os_error(
      -1, "Unix domain sockets are not available on this operating system.",
      OSError::kUnknown);
  Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
#else
  Dart_Handle address = Dart_GetNativeArgument(args, 1);
  if (Dart_IsNull(address)) {
    Dart_SetReturnValue(args, DartUtils::NewDartArgumentError(
                                  "expect address to be of type String"));
  }
  const char* path = DartUtils::GetStringValue(address);
  int64_t backlog = DartUtils::GetInt64ValueCheckRange(
      Dart_GetNativeArgument(args, 2), 0, 65535);
  bool shared = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3));
  Namespace* namespc = Namespace::GetNamespace(args, 4);
  Dart_Handle socket_object = Dart_GetNativeArgument(args, 0);
  Dart_Handle result =
      ListeningSocketRegistry::Instance()->CreateUnixDomainBindListen(
          socket_object, namespc, path, backlog, shared);
  Dart_SetReturnValue(args, result);
#endif  // defined(DART_HOST_OS_WINDOWS)
}

void FUNCTION_NAME(ServerSocket_Accept)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  intptr_t new_socket = ServerSocket::Accept(socket->fd());
  if (new_socket >= 0) {
    Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 1), new_socket,
                                   Socket::kFinalizerNormal);
    Dart_SetReturnValue(args, Dart_True());
  } else {
    Dart_SetReturnValue(args, Dart_False());
  }
}

CObject* Socket::LookupRequest(const CObjectArray& request) {
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsInt32()) {
    CObjectString host(request[0]);
    CObjectInt32 type(request[1]);
    CObject* result = nullptr;
    OSError* os_error = nullptr;
    AddressList<SocketAddress>* addresses =
        SocketBase::LookupAddress(host.CString(), type.Value(), &os_error);
    if (addresses != nullptr) {
      CObjectArray* array =
          new CObjectArray(CObject::NewArray(addresses->count() + 1));
      array->SetAt(0, new CObjectInt32(CObject::NewInt32(0)));
      for (intptr_t i = 0; i < addresses->count(); i++) {
        SocketAddress* addr = addresses->GetAt(i);
        CObjectArray* entry = new CObjectArray(CObject::NewArray(4));

        CObjectInt32* type =
            new CObjectInt32(CObject::NewInt32(addr->GetType()));
        entry->SetAt(0, type);

        CObjectString* as_string =
            new CObjectString(CObject::NewString(addr->as_string()));
        entry->SetAt(1, as_string);

        const auto& raw = addr->addr();
        CObjectUint8Array* data = SocketAddress::ToCObject(raw);
        entry->SetAt(2, data);

        CObjectInt64* scope_id = new CObjectInt64(
            CObject::NewInt64(SocketAddress::GetAddrScope(raw)));
        entry->SetAt(3, scope_id);

        array->SetAt(i + 1, entry);
      }
      result = array;
      delete addresses;
    } else {
      result = CObject::NewOSError(os_error);
      delete os_error;
    }
    return result;
  }
  return CObject::IllegalArgumentError();
}

CObject* Socket::ReverseLookupRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsTypedData()) {
    CObjectUint8Array addr_object(request[0]);
    RawAddr addr;
    int len = addr_object.Length();
    memset(reinterpret_cast<void*>(&addr), 0, sizeof(RawAddr));
    if (len == sizeof(in_addr)) {
      addr.in.sin_family = AF_INET;
      addr.size = sizeof(sockaddr_in);
      memmove(reinterpret_cast<void*>(&addr.in.sin_addr), addr_object.Buffer(),
              len);
    } else {
      ASSERT(len == sizeof(in6_addr));
      addr.in6.sin6_family = AF_INET6;
      addr.size = sizeof(sockaddr_in6);
      memmove(reinterpret_cast<void*>(&addr.in6.sin6_addr),
              addr_object.Buffer(), len);
    }

    OSError* os_error = nullptr;
    const intptr_t kMaxHostLength = 1025;
    char host[kMaxHostLength];
    if (SocketBase::ReverseLookup(addr, host, kMaxHostLength, &os_error)) {
      return new CObjectString(CObject::NewString(host));
    } else {
      CObject* result = CObject::NewOSError(os_error);
      delete os_error;
      return result;
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* Socket::ListInterfacesRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsInt32()) {
    CObjectInt32 type(request[0]);
    CObject* result = nullptr;
    OSError* os_error = nullptr;
    AddressList<InterfaceSocketAddress>* addresses =
        SocketBase::ListInterfaces(type.Value(), &os_error);
    if (addresses != nullptr) {
      CObjectArray* array =
          new CObjectArray(CObject::NewArray(addresses->count() + 1));
      array->SetAt(0, new CObjectInt32(CObject::NewInt32(0)));
      for (intptr_t i = 0; i < addresses->count(); i++) {
        InterfaceSocketAddress* interface = addresses->GetAt(i);
        SocketAddress* addr = interface->socket_address();
        CObjectArray* entry = new CObjectArray(CObject::NewArray(5));

        CObjectInt32* type =
            new CObjectInt32(CObject::NewInt32(addr->GetType()));
        entry->SetAt(0, type);

        CObjectString* as_string =
            new CObjectString(CObject::NewString(addr->as_string()));
        entry->SetAt(1, as_string);

        const auto& raw = addr->addr();
        CObjectUint8Array* data = SocketAddress::ToCObject(raw);
        entry->SetAt(2, data);

        CObjectString* interface_name =
            new CObjectString(CObject::NewString(interface->interface_name()));
        entry->SetAt(3, interface_name);

        CObjectInt64* interface_index =
            new CObjectInt64(CObject::NewInt64(interface->interface_index()));
        entry->SetAt(4, interface_index);

        array->SetAt(i + 1, entry);
      }
      result = array;
      delete addresses;
    } else {
      result = CObject::NewOSError(os_error);
      delete os_error;
    }
    return result;
  }
  return CObject::IllegalArgumentError();
}

void FUNCTION_NAME(Socket_GetOption)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
  intptr_t protocol = static_cast<intptr_t>(
      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2)));
  bool ok = false;
  switch (option) {
    case 0: {  // TCP_NODELAY.
      bool enabled;
      ok = SocketBase::GetNoDelay(socket->fd(), &enabled);
      if (ok) {
        Dart_SetBooleanReturnValue(args, enabled);
      }
      break;
    }
    case 1: {  // IP_MULTICAST_LOOP.
      bool enabled;
      ok = SocketBase::GetMulticastLoop(socket->fd(), protocol, &enabled);
      if (ok) {
        Dart_SetBooleanReturnValue(args, enabled);
      }
      break;
    }
    case 2: {  // IP_MULTICAST_TTL.
      int value;
      ok = SocketBase::GetMulticastHops(socket->fd(), protocol, &value);
      if (ok) {
        Dart_SetIntegerReturnValue(args, value);
      }
      break;
    }
    case 3: {  // IP_MULTICAST_IF.
      UNIMPLEMENTED();
      break;
    }
    case 4: {  // IP_BROADCAST.
      bool enabled;
      ok = SocketBase::GetBroadcast(socket->fd(), &enabled);
      if (ok) {
        Dart_SetBooleanReturnValue(args, enabled);
      }
      break;
    }
    default:
      UNREACHABLE();
      break;
  }
  // In case of failure the return value is not set above.
  if (!ok) {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(Socket_SetOption)(Dart_NativeArguments args) {
  bool result = false;
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
  intptr_t protocol = static_cast<intptr_t>(
      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2)));
  switch (option) {
    case 0:  // TCP_NODELAY.
      result = SocketBase::SetNoDelay(
          socket->fd(),
          DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
      break;
    case 1:  // IP_MULTICAST_LOOP.
      result = SocketBase::SetMulticastLoop(
          socket->fd(), protocol,
          DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
      break;
    case 2:  // IP_MULTICAST_TTL.
      result = SocketBase::SetMulticastHops(
          socket->fd(), protocol,
          DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3)));
      break;
    case 3: {  // IP_MULTICAST_IF.
      UNIMPLEMENTED();
      break;
    }
    case 4:  // IP_BROADCAST.
      result = SocketBase::SetBroadcast(
          socket->fd(),
          DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
      break;
    default:
      Dart_PropagateError(
          Dart_NewApiError("option to setOption() is outside expected range"));
      break;
  }
  if (!result) {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(Socket_SetRawOption)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  int64_t level = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
  int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
  Dart_Handle data_obj = Dart_GetNativeArgument(args, 3);
  ASSERT(Dart_IsList(data_obj));
  char* data = nullptr;
  intptr_t length;
  Dart_TypedData_Type type;
  Dart_Handle data_result = Dart_TypedDataAcquireData(
      data_obj, &type, reinterpret_cast<void**>(&data), &length);
  if (Dart_IsError(data_result)) {
    Dart_PropagateError(data_result);
  }

  bool result = SocketBase::SetOption(socket->fd(), static_cast<int>(level),
                                      static_cast<int>(option), data,
                                      static_cast<int>(length));

  Dart_TypedDataReleaseData(data_obj);

  if (!result) {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(Socket_GetRawOption)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  int64_t level = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
  int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
  Dart_Handle data_obj = Dart_GetNativeArgument(args, 3);
  ASSERT(Dart_IsList(data_obj));
  char* data = nullptr;
  intptr_t length;
  Dart_TypedData_Type type;
  Dart_Handle data_result = Dart_TypedDataAcquireData(
      data_obj, &type, reinterpret_cast<void**>(&data), &length);
  if (Dart_IsError(data_result)) {
    Dart_PropagateError(data_result);
  }
  unsigned int int_length = static_cast<unsigned int>(length);
  bool result =
      SocketBase::GetOption(socket->fd(), static_cast<int>(level),
                            static_cast<int>(option), data, &int_length);

  Dart_TypedDataReleaseData(data_obj);
  if (!result) {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
}

// Keep in sync with _RawSocketOptions in socket.dart
enum _RawSocketOptions : int64_t {
  DART_SOL_SOCKET = 0,
  DART_IPPROTO_IP = 1,
  DART_IP_MULTICAST_IF = 2,
  DART_IPPROTO_IPV6 = 3,
  DART_IPV6_MULTICAST_IF = 4,
  DART_IPPROTO_TCP = 5,
  DART_IPPROTO_UDP = 6
};

void FUNCTION_NAME(RawSocketOption_GetOptionValue)(Dart_NativeArguments args) {
  _RawSocketOptions key = static_cast<_RawSocketOptions>(
      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0)));
  switch (key) {
    case DART_SOL_SOCKET:
      Dart_SetIntegerReturnValue(args, SOL_SOCKET);
      break;
    case DART_IPPROTO_IP:
      Dart_SetIntegerReturnValue(args, IPPROTO_IP);
      break;
    case DART_IP_MULTICAST_IF:
      Dart_SetIntegerReturnValue(args, IP_MULTICAST_IF);
      break;
    case DART_IPPROTO_IPV6:
      Dart_SetIntegerReturnValue(args, IPPROTO_IPV6);
      break;
    case DART_IPV6_MULTICAST_IF:
      Dart_SetIntegerReturnValue(args, IPV6_MULTICAST_IF);
      break;
    case DART_IPPROTO_TCP:
      Dart_SetIntegerReturnValue(args, IPPROTO_TCP);
      break;
    case DART_IPPROTO_UDP:
      Dart_SetIntegerReturnValue(args, IPPROTO_UDP);
      break;
    default:
      Dart_PropagateError(Dart_NewApiError(
          "option to getOptionValue() is outside expected range"));
      break;
  }
}

void FUNCTION_NAME(Socket_JoinMulticast)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  RawAddr addr;
  SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
  RawAddr interface;
  if (Dart_GetNativeArgument(args, 2) != Dart_Null()) {
    SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 2), &interface);
  }
  int interfaceIndex =
      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
  if (!SocketBase::JoinMulticast(socket->fd(), addr, interface,
                                 interfaceIndex)) {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(Socket_LeaveMulticast)(Dart_NativeArguments args) {
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  RawAddr addr;
  SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
  RawAddr interface;
  if (Dart_GetNativeArgument(args, 2) != Dart_Null()) {
    SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 2), &interface);
  }
  int interfaceIndex =
      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
  if (!SocketBase::LeaveMulticast(socket->fd(), addr, interface,
                                  interfaceIndex)) {
    Dart_ThrowException(DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(Socket_AvailableDatagram)(Dart_NativeArguments args) {
  const int kReceiveBufferLen = 1;
  Socket* socket =
      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
  ASSERT(socket != nullptr);
  // Ensure that a receive buffer for peeking the UDP socket exists.
  uint8_t recv_buffer[kReceiveBufferLen];
  bool available = SocketBase::AvailableDatagram(socket->fd(), recv_buffer,
                                                 kReceiveBufferLen);
  Dart_SetBooleanReturnValue(args, available);
}

static void NormalSocketFinalizer(void* isolate_data, void* data) {
  Socket* socket = reinterpret_cast<Socket*>(data);
  const int64_t flags = 1 << kCloseCommand;
  socket->Retain();  // Bump reference till we send the message.
  EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
                               socket->port(), flags);
  socket->Release();  // Release the reference we just added above.
}

static void ListeningSocketFinalizer(void* isolate_data, void* data) {
  Socket* socket = reinterpret_cast<Socket*>(data);
  const int64_t flags = (1 << kListeningSocket) | (1 << kCloseCommand);
  socket->Retain();  // Bump reference till we send the message.
  EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
                               socket->port(), flags);
  socket->Release();  // Release the reference we just added above.
}

static void StdioSocketFinalizer(void* isolate_data, void* data) {
  Socket* socket = reinterpret_cast<Socket*>(data);
  if (socket->fd() >= 0) {
    socket->CloseFd();
  }
  socket->Release();
}

static void SignalSocketFinalizer(void* isolate_data, void* data) {
  Socket* socket = reinterpret_cast<Socket*>(data);
  const int64_t flags = (1 << kSignalSocket) | (1 << kCloseCommand);
  socket->Retain();  // Bump reference till we send the message.
  EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
                               socket->port(), flags);
  socket->Release();  // Release the reference we just added above.
}

void Socket::ReuseSocketIdNativeField(Dart_Handle handle,
                                      Socket* socket,
                                      SocketFinalizer finalizer) {
  Dart_Handle err = Dart_SetNativeInstanceField(
      handle, kSocketIdNativeField, reinterpret_cast<intptr_t>(socket));
  if (Dart_IsError(err)) {
    Dart_PropagateError(err);
  }
  Dart_HandleFinalizer callback;
  switch (finalizer) {
    case kFinalizerNormal:
      callback = NormalSocketFinalizer;
      break;
    case kFinalizerListening:
      callback = ListeningSocketFinalizer;
      break;
    case kFinalizerStdio:
      callback = StdioSocketFinalizer;
      break;
    case kFinalizerSignal:
      callback = SignalSocketFinalizer;
      break;
    default:
      callback = nullptr;
      UNREACHABLE();
      break;
  }
  if (callback != nullptr) {
    Dart_NewFinalizableHandle(handle, reinterpret_cast<void*>(socket),
                              sizeof(Socket), callback);
  }
}

void Socket::SetSocketIdNativeField(Dart_Handle handle,
                                    intptr_t id,
                                    SocketFinalizer finalizer) {
  Socket* socket = new Socket(id);
  ReuseSocketIdNativeField(handle, socket, finalizer);
}

Socket* Socket::GetSocketIdNativeField(Dart_Handle socket_obj) {
  intptr_t id;
  Dart_Handle err =
      Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &id);
  if (Dart_IsError(err)) {
    Dart_PropagateError(err);
  }
  Socket* socket = reinterpret_cast<Socket*>(id);
  if (socket == nullptr) {
    Dart_PropagateError(Dart_NewUnhandledExceptionError(
        DartUtils::NewInternalError("No native peer")));
  }
  return socket;
}

void FUNCTION_NAME(SocketControlMessage_fromHandles)(
    Dart_NativeArguments args) {
#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
  Dart_SetReturnValue(args,
                      DartUtils::NewDartUnsupportedError(
                          "This is not supported on this operating system"));
#else
  ASSERT(Dart_IsNull(Dart_GetNativeArgument(args, 0)));
  Dart_Handle handles_dart = Dart_GetNativeArgument(args, 1);
  if (Dart_IsNull(handles_dart)) {
    Dart_ThrowException(
        DartUtils::NewDartArgumentError("handles list can't be null"));
  }
  ASSERT(Dart_IsList(handles_dart));
  intptr_t num_handles;
  ThrowIfError(Dart_ListLength(handles_dart, &num_handles));
  intptr_t num_bytes = num_handles * sizeof(int);
  int* handles = reinterpret_cast<int*>(Dart_ScopeAllocate(num_bytes));
  Dart_Handle handle_dart_string =
      ThrowIfError(DartUtils::NewString("_handle"));
  for (intptr_t i = 0; i < num_handles; i++) {
    Dart_Handle handle_dart = ThrowIfError(Dart_ListGetAt(handles_dart, i));
    Dart_Handle handle_int_dart =
        ThrowIfError(Dart_GetField(handle_dart, handle_dart_string));
    handles[i] = DartUtils::GetIntegerValue(handle_int_dart);
  }

  Dart_Handle uint8list_dart =
      ThrowIfError(Dart_NewTypedData(Dart_TypedData_kUint8, num_bytes));
  ThrowIfError(Dart_ListSetAsBytes(uint8list_dart, /*offset=*/0,
                                   reinterpret_cast<const uint8_t*>(handles),
                                   num_bytes));
  Dart_Handle dart_new_args[] = {Dart_NewInteger(SOL_SOCKET),
                                 Dart_NewInteger(SCM_RIGHTS), uint8list_dart};

  Dart_Handle socket_control_message_impl = ThrowIfError(DartUtils::GetDartType(
      DartUtils::kIOLibURL, "_SocketControlMessageImpl"));
  Dart_SetReturnValue(
      args,
      Dart_New(socket_control_message_impl,
               /*constructor_name=*/Dart_Null(),
               sizeof(dart_new_args) / sizeof(Dart_Handle), dart_new_args));
#endif  // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
}

void FUNCTION_NAME(SocketControlMessageImpl_extractHandles)(
    Dart_NativeArguments args) {
#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
  Dart_SetReturnValue(args,
                      DartUtils::NewDartUnsupportedError(
                          "This is not supported on this operating system"));
#else
  Dart_Handle handle_type = ThrowIfError(
      DartUtils::GetDartType(DartUtils::kIOLibURL, "ResourceHandle"));

  Dart_Handle message_dart = Dart_GetNativeArgument(args, 0);
  intptr_t level = DartUtils::GetIntegerValue(
      ThrowIfError(Dart_GetField(message_dart, DartUtils::NewString("level"))));
  intptr_t type = DartUtils::GetIntegerValue(
      ThrowIfError(Dart_GetField(message_dart, DartUtils::NewString("type"))));
  if (level != SOL_SOCKET || type != SCM_RIGHTS) {
    Dart_SetReturnValue(args, ThrowIfError(Dart_NewListOfTypeFilled(
                                  handle_type, Dart_Null(), 0)));
    return;
  }

  Dart_Handle data_dart =
      ThrowIfError(Dart_GetField(message_dart, DartUtils::NewString("data")));
  ASSERT(Dart_IsTypedData(data_dart));

  void* data;
  intptr_t bytes_count;
  Dart_TypedData_Type data_type;
  ThrowIfError(
      Dart_TypedDataAcquireData(data_dart, &data_type, &data, &bytes_count));
  ASSERT(data_type == Dart_TypedData_kUint8);
  int* ints_data = reinterpret_cast<int*>(Dart_ScopeAllocate(bytes_count));
  ASSERT(ints_data != nullptr);
  memmove(ints_data, data, bytes_count);
  ThrowIfError(Dart_TypedDataReleaseData(data_dart));
  intptr_t ints_count = bytes_count / sizeof(int);

  Dart_Handle handle_impl_type =
      DartUtils::GetDartType(DartUtils::kIOLibURL, "_ResourceHandleImpl");
  Dart_Handle sentinel = ThrowIfError(
      Dart_GetField(handle_impl_type, DartUtils::NewString("_sentinel")));
  Dart_Handle handle_list =
      ThrowIfError(Dart_NewListOfTypeFilled(handle_type, sentinel, ints_count));
  for (intptr_t i = 0; i < ints_count; i++) {
    Dart_Handle constructor_args[] = {
        ThrowIfError(Dart_NewInteger(*(ints_data + i)))};
    Dart_Handle handle_impl = ThrowIfError(Dart_New(
        handle_impl_type,
        /*constructor_name=*/Dart_Null(),
        sizeof(constructor_args) / sizeof(Dart_Handle), constructor_args));
    ThrowIfError(Dart_ListSetAt(handle_list, i, handle_impl));
  }

  Dart_SetReturnValue(args, handle_list);
#endif  // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
}

void FUNCTION_NAME(ResourceHandleImpl_toFile)(Dart_NativeArguments args) {
#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
  Dart_SetReturnValue(args,
                      DartUtils::NewDartUnsupportedError(
                          "This is not supported on this operating system"));
#else
  Dart_Handle handle_object = ThrowIfError(Dart_GetNativeArgument(args, 0));
  Dart_Handle handle_field = ThrowIfError(
      Dart_GetField(handle_object, DartUtils::NewString("_handle")));
  intptr_t fd = DartUtils::GetIntegerValue(handle_field);

  Dart_Handle random_access_file_type = ThrowIfError(
      DartUtils::GetDartType(DartUtils::kIOLibURL, "_RandomAccessFile"));

  Dart_Handle dart_new_args[2];
  dart_new_args[1] = ThrowIfError(Dart_NewStringFromCString("<handle>"));

  File* file = File::OpenFD(fd);

  Dart_Handle result = Dart_NewInteger(reinterpret_cast<intptr_t>(file));
  if (Dart_IsError(result)) {
    file->Release();
    Dart_PropagateError(result);
  }
  dart_new_args[0] = result;

  Dart_Handle new_random_access_file =
      Dart_New(random_access_file_type,
               /*constructor_name=*/Dart_Null(),
               /*number_of_arguments=*/2, dart_new_args);
  if (Dart_IsError(new_random_access_file)) {
    file->Release();
    Dart_PropagateError(new_random_access_file);
  }

  Dart_SetReturnValue(args, new_random_access_file);
#endif  // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
}

void FUNCTION_NAME(ResourceHandleImpl_toSocket)(Dart_NativeArguments args) {
  Dart_SetReturnValue(args,
                      DartUtils::NewDartUnsupportedError(
                          "This is not supported on this operating system"));
}

void FUNCTION_NAME(ResourceHandleImpl_toRawSocket)(Dart_NativeArguments args) {
#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
  Dart_SetReturnValue(args,
                      DartUtils::NewDartUnsupportedError(
                          "This is not supported on this operating system"));
#else
  Dart_Handle handle_object = ThrowIfError(Dart_GetNativeArgument(args, 0));
  Dart_Handle handle_field = ThrowIfError(
      Dart_GetField(handle_object, DartUtils::NewString("_handle")));
  intptr_t fd = DartUtils::GetIntegerValue(handle_field);

  RawAddr raw;
  if (!SocketBase::GetSocketName(fd, &raw)) {
    OSError os_error(-1, "Failed to get socket address", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
    return;
  }

  const SocketAddress socket_address(raw);

  // return a list describing socket_address: (type, hostname, typed_data_addr,
  // fd)
  Dart_Handle list = ThrowIfError(Dart_NewList(4));
  ThrowIfError(Dart_ListSetAt(
      list, 0, ThrowIfError(Dart_NewInteger(socket_address.GetType()))));
  ThrowIfError(Dart_ListSetAt(
      list, 1,
      ThrowIfError(Dart_NewStringFromCString(socket_address.as_string()))));
  ThrowIfError(Dart_ListSetAt(
      list, 2, SocketAddress::ToTypedData(socket_address.addr())));
  ThrowIfError(Dart_ListSetAt(list, 3, ThrowIfError(Dart_NewInteger(fd))));

  Dart_SetReturnValue(args, list);
#endif  // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_FUCHSIA)
}

void FUNCTION_NAME(ResourceHandleImpl_toRawDatagramSocket)(
    Dart_NativeArguments args) {
  Dart_SetReturnValue(args,
                      DartUtils::NewDartUnsupportedError(
                          "This is not supported on this operating system"));
}

}  // namespace bin
}  // namespace dart
