// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/socket/unix_domain_server_socket_posix.h"

#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <utility>

#include "base/functional/bind.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "net/base/net_errors.h"
#include "net/base/sockaddr_storage.h"
#include "net/base/sockaddr_util_posix.h"
#include "net/socket/socket_posix.h"
#include "net/socket/unix_domain_client_socket_posix.h"

namespace net {

UnixDomainServerSocket::UnixDomainServerSocket(
    const AuthCallback& auth_callback,
    bool use_abstract_namespace)
    : auth_callback_(auth_callback),
      use_abstract_namespace_(use_abstract_namespace) {
  DCHECK(!auth_callback_.is_null());
}

UnixDomainServerSocket::~UnixDomainServerSocket() = default;

// static
bool UnixDomainServerSocket::GetPeerCredentials(SocketDescriptor socket,
                                                Credentials* credentials) {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
    BUILDFLAG(IS_FUCHSIA)
  struct ucred user_cred;
  socklen_t len = sizeof(user_cred);
  if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &user_cred, &len) < 0)
    return false;
  credentials->process_id = user_cred.pid;
  credentials->user_id = user_cred.uid;
  credentials->group_id = user_cred.gid;
  return true;
#else
  return getpeereid(
      socket, &credentials->user_id, &credentials->group_id) == 0;
#endif
}

int UnixDomainServerSocket::Listen(const IPEndPoint& address,
                                   int backlog,
                                   absl::optional<bool> ipv6_only) {
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

int UnixDomainServerSocket::ListenWithAddressAndPort(
    const std::string& address_string,
    uint16_t port,
    int backlog) {
  NOTIMPLEMENTED();
  return ERR_NOT_IMPLEMENTED;
}

int UnixDomainServerSocket::BindAndListen(const std::string& socket_path,
                                          int backlog) {
  DCHECK(!listen_socket_);

  SockaddrStorage address;
  if (!FillUnixAddress(socket_path, use_abstract_namespace_, &address)) {
    return ERR_ADDRESS_INVALID;
  }

  auto socket = std::make_unique<SocketPosix>();
  int rv = socket->Open(AF_UNIX);
  DCHECK_NE(ERR_IO_PENDING, rv);
  if (rv != OK)
    return rv;

  rv = socket->Bind(address);
  DCHECK_NE(ERR_IO_PENDING, rv);
  if (rv != OK) {
    PLOG(ERROR)
        << "Could not bind unix domain socket to " << socket_path
        << (use_abstract_namespace_ ? " (with abstract namespace)" : "");
    return rv;
  }

  rv = socket->Listen(backlog);
  DCHECK_NE(ERR_IO_PENDING, rv);
  if (rv != OK)
    return rv;

  listen_socket_.swap(socket);
  return rv;
}

int UnixDomainServerSocket::GetLocalAddress(IPEndPoint* address) const {
  DCHECK(address);

  // Unix domain sockets have no valid associated addr/port;
  // return address invalid.
  return ERR_ADDRESS_INVALID;
}

int UnixDomainServerSocket::Accept(std::unique_ptr<StreamSocket>* socket,
                                   CompletionOnceCallback callback) {
  DCHECK(socket);
  DCHECK(callback);
  DCHECK(!callback_ && !out_socket_.stream && !out_socket_.descriptor);

  out_socket_ = {socket, nullptr};
  int rv = DoAccept();
  if (rv == ERR_IO_PENDING)
    callback_ = std::move(callback);
  else
    CancelCallback();
  return rv;
}

int UnixDomainServerSocket::AcceptSocketDescriptor(
    SocketDescriptor* socket,
    CompletionOnceCallback callback) {
  DCHECK(socket);
  DCHECK(callback);
  DCHECK(!callback_ && !out_socket_.stream && !out_socket_.descriptor);

  out_socket_ = {nullptr, socket};
  int rv = DoAccept();
  if (rv == ERR_IO_PENDING)
    callback_ = std::move(callback);
  else
    CancelCallback();
  return rv;
}

int UnixDomainServerSocket::DoAccept() {
  DCHECK(listen_socket_);
  DCHECK(!accept_socket_);

  while (true) {
    int rv = listen_socket_->Accept(
        &accept_socket_,
        base::BindOnce(&UnixDomainServerSocket::AcceptCompleted,
                       base::Unretained(this)));
    if (rv != OK)
      return rv;
    if (AuthenticateAndGetStreamSocket())
      return OK;
    // Accept another socket because authentication error should be transparent
    // to the caller.
  }
}

void UnixDomainServerSocket::AcceptCompleted(int rv) {
  DCHECK(!callback_.is_null());

  if (rv != OK) {
    RunCallback(rv);
    return;
  }

  if (AuthenticateAndGetStreamSocket()) {
    RunCallback(OK);
    return;
  }

  // Accept another socket because authentication error should be transparent
  // to the caller.
  rv = DoAccept();
  if (rv != ERR_IO_PENDING)
    RunCallback(rv);
}

bool UnixDomainServerSocket::AuthenticateAndGetStreamSocket() {
  DCHECK(accept_socket_);

  Credentials credentials;
  if (!GetPeerCredentials(accept_socket_->socket_fd(), &credentials) ||
      !auth_callback_.Run(credentials)) {
    accept_socket_.reset();
    return false;
  }

  SetSocketResult(std::move(accept_socket_));
  return true;
}

void UnixDomainServerSocket::SetSocketResult(
    std::unique_ptr<SocketPosix> accepted_socket) {
  // Exactly one of the output pointers should be set.
  DCHECK_NE(!!out_socket_.stream, !!out_socket_.descriptor);

  // Pass ownership of |accepted_socket|.
  if (out_socket_.descriptor) {
    *out_socket_.descriptor = accepted_socket->ReleaseConnectedSocket();
    return;
  }
  *out_socket_.stream =
      std::make_unique<UnixDomainClientSocket>(std::move(accepted_socket));
}

void UnixDomainServerSocket::RunCallback(int rv) {
  out_socket_ = SocketDestination();
  std::move(callback_).Run(rv);
}

void UnixDomainServerSocket::CancelCallback() {
  out_socket_ = SocketDestination();
  callback_.Reset();
}

}  // namespace net
