// 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.

#ifndef RUNTIME_BIN_SOCKET_BASE_H_
#define RUNTIME_BIN_SOCKET_BASE_H_

#include "platform/globals.h"
// Declare the OS-specific types ahead of defining the generic class.
#if defined(DART_HOST_OS_FUCHSIA)
#include "bin/socket_base_fuchsia.h"
#elif defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
#include "bin/socket_base_linux.h"
#ifdef __BIONIC__
// The Android standard library allows leading zeros in IPv4 adresses.
// The GLIBC, uClibc[-NG] and Musl LibC libraries should not do so.
#define INET_PTON_FLAWED
#endif
#elif defined(DART_HOST_OS_MACOS)
#include "bin/socket_base_macos.h"
// MacOS inet_pton allows leading zeros in IPv4 addresses.
#define INET_PTON_FLAWED
#elif defined(DART_HOST_OS_WINDOWS)
#include "bin/socket_base_win.h"
#else
#error Unknown target os.
#endif

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "platform/allocation.h"
#include "platform/hashmap.h"

namespace dart {
namespace bin {

struct RawAddr {
  union {
    sockaddr_in in;
    sockaddr_in6 in6;
    sockaddr_un un;
    sockaddr_storage ss;
    sockaddr addr;
  };
  socklen_t size = sizeof(sockaddr_storage);

  static RawAddr FromInet4or6(const sockaddr* sa) {
    RawAddr raw;
    switch (sa->sa_family) {
      case AF_INET:
        raw.size = sizeof(sockaddr_in);
        break;
      case AF_INET6:
        raw.size = sizeof(sockaddr_in6);
        break;

      default:
        UNREACHABLE();
    }
    memmove(&raw.addr, sa, raw.size);
    return raw;
  }

  bool is_pathname_unix_socket() const {
    return ss.ss_family == AF_UNIX && !is_unnamed_unix_socket() &&
           un.sun_path[0] != '\0';
  }

  bool is_abstract_unix_socket() const {
    return ss.ss_family == AF_UNIX && !is_unnamed_unix_socket() &&
           un.sun_path[0] == '\0';
  }

  bool is_unnamed_unix_socket() const {
    // Socket is unnamed if its sockaddr contains exactly |ss.ss_family|
    // and no sun_path data at all.
    return ss.ss_family == AF_UNIX && size == sizeof(decltype(ss.ss_family));
  }
};

class SocketAddress {
 public:
  enum {
    TYPE_ANY = -1,
    TYPE_IPV4,
    TYPE_IPV6,
    TYPE_UNIX,
  };

  enum {
    ADDRESS_LOOPBACK_IP_V4,
    ADDRESS_LOOPBACK_IP_V6,
    ADDRESS_ANY_IP_V4,
    ADDRESS_ANY_IP_V6,
    ADDRESS_FIRST = ADDRESS_LOOPBACK_IP_V4,
    ADDRESS_LAST = ADDRESS_ANY_IP_V6,
  };

  explicit SocketAddress(const RawAddr& addr);

  ~SocketAddress() {}

  int GetType() const;

  const char* as_string() const { return as_string_; }
  const RawAddr& addr() const { return addr_; }

  static intptr_t GetInAddrLength(const RawAddr& addr);
  static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b);
  static void GetSockAddr(Dart_Handle obj, RawAddr* addr);
  static Dart_Handle GetUnixDomainSockAddr(const char* path,
                                           Namespace* namespc,
                                           RawAddr* addr);
  static int16_t FromType(int type);
  static void SetAddrPort(RawAddr* addr, intptr_t port);
  static intptr_t GetAddrPort(const RawAddr& addr);
  static Dart_Handle ToTypedData(const RawAddr& addr);
  static CObjectUint8Array* ToCObject(const RawAddr& addr);
  static void SetAddrScope(RawAddr* addr, intptr_t scope_id);
  static intptr_t GetAddrScope(const RawAddr& addr);

#if !defined(DART_HOST_OS_FUCHSIA)
  static constexpr intptr_t kMaxAddressStringLength =
      sizeof(decltype(sockaddr_un::sun_path));
#else
  static constexpr intptr_t kMaxAddressStringLength = INET6_ADDRSTRLEN;
#endif  // !defined(DART_HOST_OS_FUCHSIA)
  static_assert(kMaxAddressStringLength >= INET6_ADDRSTRLEN);
  static_assert(kMaxAddressStringLength >= INET_ADDRSTRLEN);

 private:
  char as_string_[kMaxAddressStringLength];
  RawAddr addr_;

  DISALLOW_COPY_AND_ASSIGN(SocketAddress);
};

class InterfaceSocketAddress {
 public:
  InterfaceSocketAddress(const RawAddr& addr,
                         const char* interface_name,
                         intptr_t interface_index,
                         intptr_t prefix_length)
      : socket_address_(new SocketAddress(addr)),
        interface_name_(interface_name),
        interface_index_(interface_index),
        prefix_length_(prefix_length) {}

  ~InterfaceSocketAddress() { delete socket_address_; }

  SocketAddress* socket_address() const { return socket_address_; }
  const char* interface_name() const { return interface_name_; }
  intptr_t interface_index() const { return interface_index_; }
  intptr_t prefix_length() const { return prefix_length_; }

 private:
  SocketAddress* socket_address_;
  const char* interface_name_;
  intptr_t interface_index_;
  intptr_t prefix_length_;

  DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress);
};

template <typename T>
class AddressList {
 public:
  explicit AddressList(intptr_t count)
      : count_(count), addresses_(new T*[count_]) {}

  ~AddressList() {
    for (intptr_t i = 0; i < count_; i++) {
      delete addresses_[i];
    }
    delete[] addresses_;
  }

  intptr_t count() const { return count_; }
  T* GetAt(intptr_t i) const { return addresses_[i]; }
  void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; }

 private:
  const intptr_t count_;
  T** addresses_;

  DISALLOW_COPY_AND_ASSIGN(AddressList);
};

class SocketControlMessage {
 public:
  SocketControlMessage(intptr_t level,
                       intptr_t type,
                       void* data,
                       size_t data_length)
      : level_(level), type_(type), data_(data), data_length_(data_length) {}

  intptr_t level() const { return level_; }
  intptr_t type() const { return type_; }
  void* data() const { return data_; }
  size_t data_length() const { return data_length_; }

  inline bool is_file_descriptors_control_message();

 private:
  const intptr_t level_;
  const intptr_t type_;
  void* data_;
  const size_t data_length_;

  DISALLOW_COPY_AND_ASSIGN(SocketControlMessage);
};

class SocketBase : public AllStatic {
 public:
  enum SocketRequest {
    kLookupRequest = 0,
    kListInterfacesRequest = 1,
    kReverseLookupRequest = 2,
  };

  enum SocketOpKind {
    kSync,
    kAsync,
  };

  // TODO(dart:io): Convert these to instance methods where possible.
  static bool Initialize();
  static intptr_t Available(intptr_t fd);
  static intptr_t Read(intptr_t fd,
                       void* buffer,
                       intptr_t num_bytes,
                       SocketOpKind sync);
  static intptr_t Write(intptr_t fd,
                        const void* buffer,
                        intptr_t num_bytes,
                        SocketOpKind sync);

  // Send data on a socket. The port to send to is specified in the port
  // component of the passed RawAddr structure. The RawAddr structure is only
  // used for datagram sockets.
  static intptr_t SendTo(intptr_t fd,
                         const void* buffer,
                         intptr_t num_bytes,
                         const RawAddr& addr,
                         SocketOpKind sync);
  static intptr_t SendMessage(intptr_t fd,
                              void* buffer,
                              size_t buffer_num_bytes,
                              SocketControlMessage* messages,
                              intptr_t num_messages,
                              SocketOpKind sync,
                              OSError* p_oserror);
  static intptr_t RecvFrom(intptr_t fd,
                           void* buffer,
                           intptr_t num_bytes,
                           RawAddr* addr,
                           SocketOpKind sync);
  static intptr_t ReceiveMessage(intptr_t fd,
                                 void* buffer,
                                 int64_t* p_buffer_num_bytes,
                                 SocketControlMessage** p_messages,
                                 SocketOpKind sync,
                                 OSError* p_oserror);
  static bool AvailableDatagram(intptr_t fd, void* buffer, intptr_t num_bytes);
  // Returns true if the given error-number is because the system was not able
  // to bind the socket to a specific IP.
  static bool IsBindError(intptr_t error_number);
  static intptr_t GetPort(intptr_t fd);
  static bool GetSocketName(intptr_t fd, RawAddr* raw);
  static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port);
  static void GetError(intptr_t fd, OSError* os_error);
  static int GetType(intptr_t fd);
  static intptr_t GetStdioHandle(intptr_t num);
  static void Close(intptr_t fd);
  static bool GetNoDelay(intptr_t fd, bool* enabled);
  static bool SetNoDelay(intptr_t fd, bool enabled);
  static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled);
  static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled);
  static bool GetMulticastHops(intptr_t fd, intptr_t protocol, int* value);
  static bool SetMulticastHops(intptr_t fd, intptr_t protocol, int value);
  static bool GetBroadcast(intptr_t fd, bool* value);
  static bool SetBroadcast(intptr_t fd, bool value);
  static bool GetOption(intptr_t fd,
                        int level,
                        int option,
                        char* data,
                        unsigned int* length);
  static bool SetOption(intptr_t fd,
                        int level,
                        int option,
                        const char* data,
                        int length);
  static bool JoinMulticast(intptr_t fd,
                            const RawAddr& addr,
                            const RawAddr& interface,
                            int interfaceIndex);
  static bool LeaveMulticast(intptr_t fd,
                             const RawAddr& addr,
                             const RawAddr& interface,
                             int interfaceIndex);

#if defined(DART_HOST_OS_WINDOWS)
  static bool HasPendingWrite(intptr_t fd);
#endif

  // Perform a hostname lookup. Returns a AddressList of SocketAddress's.
  static AddressList<SocketAddress>* LookupAddress(const char* host,
                                                   int type,
                                                   OSError** os_error);

  static bool ReverseLookup(const RawAddr& addr,
                            char* host,
                            intptr_t host_len,
                            OSError** os_error);

  static bool ParseAddress(int type, const char* address, RawAddr* addr);

  static bool IsValidAddress(const char* address);

  // Convert address from byte representation to human readable string.
  static bool RawAddrToString(RawAddr* addr, char* str);
  static bool FormatNumericAddress(const RawAddr& addr, char* address, int len);

  // List interfaces. Returns a AddressList of InterfaceSocketAddress's.
  static AddressList<InterfaceSocketAddress>* ListInterfaces(
      int type,
      OSError** os_error);

 private:
#if !defined(DART_HOST_OS_WINDOWS)
  static intptr_t WriteImpl(intptr_t fd,
                            const void* buffer,
                            intptr_t num_bytes,
                            SocketOpKind sync);
#endif

#ifdef INET_PTON_FLAWED
  // Checks that an IPv4 address accepted by inet_pton does
  // not have leading zeros.
  //
  // Rejects if the text contains "not-digit, zero-digit, digit"
  // sequence.
  static bool IsIPv4WithoutLeadingZeros(const char* host) {
    // Unlike Linux (using GLIBC), Fuchsia and Windows,
    // the MacOS and Android `inet_pton` accepts `0177.0.0.1` as
    // valid, with `0177` being parsed as decimal 177.
    // The others OSs reject leading zeros.
    //
    // The Posix requirement for `inet_pton` is to only accept
    // `ddd.ddd.ddd.ddd` format, where each part is 1..3 decimal
    // digits with a value in the range 0..255.
    // This allows leading zeros for numbers up to 99, but
    // strict parsers in fx Linux and Windows reject leading zeros.
    // MacOS (derived from BSD) and Android (Linux with Binoic
    // standard library) accepts leading zeros _and_ more than
    // three digits.
    //
    // For safety, we reject any leading zeros, so any IPv4 address
    // has precisely one valid representation as a "dotted quad".
    //
    // (Does not check that it has four parts or only
    // `.`-separated digits, that's assumed to have been checked.)
    const int kNoDigitState = -1;
    const int kLeadingZeroState = 0;
    // Is kNoDigitState at start or after `.`,
    // and is (sum of digits) + (count of digits) - 1 otherwise,
    // which is zero (kLeadingZeroState) only after a leading `0`.
    int state = kNoDigitState;
    char c;
    while ((c = *host) != 0) {
      host++;
      if (c >= '0' && c <= '9') {
        // Digit following zero is only failure condition.
        if (state != kLeadingZeroState) {
          state =
              state + (c - '0') + 1;  // Becomes 0 only if first digit is `0`.
          continue;
        }
      } else {
        // char is '.'.
        state = kNoDigitState;
        continue;
      }
      return false;
    }
    return true;
  }
#endif

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(SocketBase);
};

}  // namespace bin
}  // namespace dart

#endif  // RUNTIME_BIN_SOCKET_BASE_H_
