// Copyright (c) 2017, 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_base.h"

#include <errno.h>  // NOLINT

#include "bin/dartutils.h"
#include "bin/io_buffer.h"
#include "bin/isolate_data.h"
#include "bin/lockers.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 {

int SocketAddress::GetType() {
  switch (addr_.ss.ss_family) {
    case AF_INET6:
      return TYPE_IPV6;
    case AF_INET:
      return TYPE_IPV4;
    case AF_UNIX:
      return TYPE_UNIX;
    default:
      UNREACHABLE();
      return TYPE_ANY;
  }
}

intptr_t SocketAddress::GetAddrLength(const RawAddr& addr,
                                      bool unnamed_unix_socket) {
  ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6) ||
         (addr.ss.ss_family == AF_UNIX));
  switch (addr.ss.ss_family) {
    case AF_INET6:
      return sizeof(struct sockaddr_in6);
    case AF_INET:
      return sizeof(struct sockaddr_in);
    case AF_UNIX: {
      // For an abstract UNIX socket, trailing null bytes in the name are
      // meaningful. That is, the bytes '\0/tmp/dbus-xxxx' are a different name
      // than '\0/tmp/dbus-xxxx\0\0\0...'. The length of the address structure
      // passed to connect() etc. tells those calls how many bytes of the name
      // to look at. Therefore, when computing the length of the address in
      // this case, any trailing null bytes are trimmed.
      // TODO(dart:io): Support abstract UNIX socket addresses that have
      // trailing null bytes on purpose.
      // https://github.com/dart-lang/sdk/issues/46158
      intptr_t nulls = 0;
      if (!unnamed_unix_socket && addr.un.sun_path[0] == '\0') {
        intptr_t i = sizeof(addr.un.sun_path) - 1;
        while (addr.un.sun_path[i] == '\0') {
          nulls++;
          i--;
        }
      }
      return sizeof(struct sockaddr_un) - nulls;
    }
    default:
      UNREACHABLE();
      return 0;
  }
}

intptr_t SocketAddress::GetInAddrLength(const RawAddr& addr) {
  ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
  return (addr.ss.ss_family == AF_INET6) ? sizeof(struct in6_addr)
                                         : sizeof(struct in_addr);
}

bool SocketAddress::AreAddressesEqual(const RawAddr& a, const RawAddr& b) {
  if (a.ss.ss_family != b.ss.ss_family) {
    return false;
  }
  if (a.ss.ss_family == AF_INET) {
    return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0;
  } else if (a.ss.ss_family == AF_INET6) {
    return memcmp(&a.in6.sin6_addr, &b.in6.sin6_addr,
                  sizeof(a.in6.sin6_addr)) == 0 &&
           a.in6.sin6_scope_id == b.in6.sin6_scope_id;
  } else if (a.ss.ss_family == AF_UNIX) {
    // This is not used anywhere. The comparison of file path is done via
    // File::AreIdentical().
    int len = sizeof(a.un.sun_path);
    for (int i = 0; i < len; i++) {
      if (a.un.sun_path[i] != b.un.sun_path[i]) return false;
      if (a.un.sun_path[i] == '\0') return true;
    }
    return true;
  } else {
    UNREACHABLE();
    return false;
  }
}

void SocketAddress::GetSockAddr(Dart_Handle obj, RawAddr* addr) {
  Dart_TypedData_Type data_type;
  uint8_t* data = nullptr;
  intptr_t len;
  Dart_Handle result = Dart_TypedDataAcquireData(
      obj, &data_type, reinterpret_cast<void**>(&data), &len);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  if ((data_type != Dart_TypedData_kUint8) ||
      ((len != sizeof(in_addr)) && (len != sizeof(in6_addr)))) {
    Dart_PropagateError(Dart_NewApiError("Unexpected type for socket address"));
  }
  memset(reinterpret_cast<void*>(addr), 0, sizeof(RawAddr));
  if (len == sizeof(in_addr)) {
    addr->in.sin_family = AF_INET;
    memmove(reinterpret_cast<void*>(&addr->in.sin_addr), data, len);
  } else {
    ASSERT(len == sizeof(in6_addr));
    addr->in6.sin6_family = AF_INET6;
    memmove(reinterpret_cast<void*>(&addr->in6.sin6_addr), data, len);
  }
  Dart_TypedDataReleaseData(obj);
}

Dart_Handle SocketAddress::GetUnixDomainSockAddr(const char* path,
                                                 Namespace* namespc,
                                                 RawAddr* addr) {
#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
  NamespaceScope ns(namespc, path);
  path = ns.path();
  bool is_abstract = (path[0] == '@');
  if (is_abstract) {
    // The following 107 bytes after the leading null byte represents the name
    // of unix domain socket. Without reseting, even users provide the same path
    // for bind and connect, they actually represent two different address and
    // connection will be rejected.
    bzero(addr->un.sun_path, sizeof(addr->un.sun_path));
  }
#endif  // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
  if (sizeof(path) > sizeof(addr->un.sun_path)) {
    OSError os_error(-1,
                     "The length of path exceeds the limit. "
                     "Check out man 7 unix page",
                     OSError::kUnknown);
    return DartUtils::NewDartOSError(&os_error);
  }
  addr->un.sun_family = AF_UNIX;
  Utils::SNPrint(addr->un.sun_path, sizeof(addr->un.sun_path), "%s", path);
#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
  // In case of abstract namespace, transfer the leading '@' into a null byte.
  if (is_abstract) {
    addr->un.sun_path[0] = '\0';
  }
#endif  // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
  return Dart_Null();
}

int16_t SocketAddress::FromType(int type) {
  if (type == TYPE_ANY) {
    return AF_UNSPEC;
  }
  if (type == TYPE_IPV4) {
    return AF_INET;
  }
  if (type == TYPE_UNIX) {
    return AF_UNIX;
  }
  ASSERT((type == TYPE_IPV6) && "Invalid type");
  return AF_INET6;
}

void SocketAddress::SetAddrPort(RawAddr* addr, intptr_t port) {
  if (addr->ss.ss_family == AF_INET) {
    addr->in.sin_port = htons(port);
  } else if (addr->ss.ss_family == AF_INET6) {
    addr->in6.sin6_port = htons(port);
  } else {
    UNREACHABLE();
  }
}

intptr_t SocketAddress::GetAddrPort(const RawAddr& addr) {
  if (addr.ss.ss_family == AF_INET) {
    return ntohs(addr.in.sin_port);
  } else if (addr.ss.ss_family == AF_INET6) {
    return ntohs(addr.in6.sin6_port);
  } else if (addr.ss.ss_family == AF_UNIX) {
    return 0;
  } else {
    UNREACHABLE();
    return -1;
  }
}

Dart_Handle SocketAddress::ToTypedData(const RawAddr& addr) {
  int len = GetInAddrLength(addr);
  Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  Dart_Handle err;
  if (addr.addr.sa_family == AF_INET6) {
    err = Dart_ListSetAsBytes(
        result, 0, reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr), len);
  } else {
    err = Dart_ListSetAsBytes(
        result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len);
  }
  if (Dart_IsError(err)) {
    Dart_PropagateError(err);
  }
  return result;
}

CObjectUint8Array* SocketAddress::ToCObject(const RawAddr& addr) {
  int in_addr_len = SocketAddress::GetInAddrLength(addr);
  const void* in_addr;
  if (addr.addr.sa_family == AF_INET6) {
    in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr);
  } else {
    in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr);
  }
  CObjectUint8Array* data =
      new CObjectUint8Array(CObject::NewUint8Array(in_addr, in_addr_len));
  return data;
}
void SocketAddress::SetAddrScope(RawAddr* addr, intptr_t scope_id) {
  if (addr->addr.sa_family != AF_INET6) return;
  addr->in6.sin6_scope_id = scope_id;
}

intptr_t SocketAddress::GetAddrScope(const RawAddr& addr) {
  if (addr.addr.sa_family == AF_INET6) {
    return addr.in6.sin6_scope_id;
  } else {
    return 0;
  }
}

void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
  const char* address =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  ASSERT(address != nullptr);
  RawAddr raw;
  memset(&raw, 0, sizeof(raw));
  int type = strchr(address, ':') == nullptr ? SocketAddress::TYPE_IPV4
                                             : SocketAddress::TYPE_IPV6;
  if (type == SocketAddress::TYPE_IPV4) {
    raw.addr.sa_family = AF_INET;
  } else {
    raw.addr.sa_family = AF_INET6;
  }
  bool ok = SocketBase::ParseAddress(type, address, &raw);
  if (!ok) {
    Dart_SetReturnValue(args, Dart_Null());
  } else {
    Dart_SetReturnValue(args, SocketAddress::ToTypedData(raw));
  }
}

void FUNCTION_NAME(InternetAddress_ParseScopedLinkLocalAddress)(
    Dart_NativeArguments args) {
  const char* address =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  // This must be an IPv6 address.
  intptr_t type = 1;
  ASSERT(address != nullptr);
  OSError* os_error = nullptr;
  AddressList<SocketAddress>* addresses =
      SocketBase::LookupAddress(address, type, &os_error);
  if (addresses != nullptr) {
    SocketAddress* addr = addresses->GetAt(0);
    Dart_SetReturnValue(
        args, Dart_NewInteger(SocketAddress::GetAddrScope(addr->addr())));
    delete addresses;
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(os_error));
    delete os_error;
  }
}

void FUNCTION_NAME(InternetAddress_RawAddrToString)(Dart_NativeArguments args) {
  RawAddr addr;
  SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 0), &addr);
  // INET6_ADDRSTRLEN is larger than INET_ADDRSTRLEN
  char str[INET6_ADDRSTRLEN];
  bool ok = SocketBase::RawAddrToString(&addr, str);
  if (!ok) {
    str[0] = '\0';
  }
  Dart_SetReturnValue(args, ThrowIfError(DartUtils::NewString(str)));
}

void FUNCTION_NAME(SocketBase_IsBindError)(Dart_NativeArguments args) {
  intptr_t error_number =
      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
  bool is_bind_error = SocketBase::IsBindError(error_number);
  Dart_SetBooleanReturnValue(args, is_bind_error ? true : false);
}

bool SocketBase::IsValidAddress(const char* address) {
  ASSERT(address != nullptr);
  RawAddr raw;
  memset(&raw, 0, sizeof(raw));
  int type = strchr(address, ':') == nullptr ? SocketAddress::TYPE_IPV4
                                             : SocketAddress::TYPE_IPV6;
  if (type == SocketAddress::TYPE_IPV4) {
    raw.addr.sa_family = AF_INET;
  } else {
    raw.addr.sa_family = AF_INET6;
  }
  return SocketBase::ParseAddress(type, address, &raw);
}

#if !defined(DART_HOST_OS_WINDOWS)
intptr_t SocketBase::Write(intptr_t fd,
                           const void* buffer,
                           intptr_t num_bytes,
                           SocketOpKind sync) {
  // For non-blocking sockets we must write as many bytes as possible into
  // the output to trigger EAGAIN otherwise we are not guaranteed to
  // receive an event from epoll which we are using in edge-triggering
  // (EPOLLET) mode. See man epoll for more information and guidelines.
  ssize_t num_bytes_left = num_bytes;
  while (num_bytes_left > 0) {
    ssize_t written_bytes = WriteImpl(fd, buffer, num_bytes_left, sync);
    static_assert(EAGAIN == EWOULDBLOCK);
    if (written_bytes == -1) {
      if ((sync == kAsync) && (errno == EWOULDBLOCK)) {
        break;
      }

      return -1;  // Error occurred.
    }

    num_bytes_left -= written_bytes;
    buffer = static_cast<const char*>(buffer) + written_bytes;
  }

  return num_bytes - num_bytes_left;
}
#endif

}  // namespace bin
}  // namespace dart
