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

#include "vm_tools/syslog/collector.h"

#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <string.h>
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/un.h>

#include <linux/vm_sockets.h>  // Needs to come after sys/socket.h

#include <string>
#include <utility>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/callback.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/posix/eintr_wrapper.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_piece.h>
#include <base/strings/stringprintf.h>
#include <base/threading/thread_task_runner_handle.h>
#include <base/time/time.h>
#include <chromeos/scoped_minijail.h>
#include <grpcpp/grpcpp.h>

#include "vm_tools/syslog/forwarder.h"
#include "vm_tools/syslog/parser.h"

using std::string;

namespace pb = google::protobuf;

namespace vm_tools {
namespace syslog {
namespace {

// Maximum size the buffer can reach before logs are immediately flushed.
constexpr size_t kBufferThreshold = 4096;

// Size of the largest syslog record as defined by RFC3164.
constexpr size_t kMaxSyslogRecord = 1024;

// Max number of records we should attempt to read out of the socket at a time.
constexpr int kMaxRecordCount = 11;

const char kProcPath[] = "/proc/self/fd/%d/%s";

}  // namespace

Collector::~Collector() = default;

bool Collector::BindLogSocket(const base::FilePath& name) {
  // Start listening on the syslog socket.
  syslog_fd_.reset(socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0));

  if (!syslog_fd_.is_valid()) {
    PLOG(ERROR) << "Failed to create unix domain socket";
    return false;
  }

  struct sockaddr_un sun = {
      .sun_family = AF_UNIX,
  };

  base::ScopedFD dir_fd;
  std::string short_name;
  if (name.value().size() > sizeof(sun.sun_path)) {
    // If the socket path is too long, we can shorten it by replacing the
    // directory paths with /proc/self/fd/${dir_fd}/socket_name to try and get
    // it under the limit.
    dir_fd.reset(HANDLE_EINTR(open(name.DirName().value().c_str(),
                                   O_PATH | O_DIRECTORY | O_CLOEXEC)));
    if (!dir_fd.is_valid()) {
      PLOG(ERROR) << "Failed to open logging directory";
      return false;
    }

    short_name = base::StringPrintf(kProcPath, dir_fd.get(),
                                    name.BaseName().value().c_str());
  } else {
    short_name = name.value();
  }

  if (short_name.size() > sizeof(sun.sun_path)) {
    LOG(ERROR) << "Socket path too long even after shortening";
    return false;
  }

  // Make sure that any previous socket is cleaned up before attempting to bind
  // to it again.  We don't really care whether the unlink succeeds or not.
  HANDLE_EINTR(unlink(short_name.c_str()));

  strncpy(sun.sun_path, short_name.c_str(), sizeof(sun.sun_path));

  if (bind(syslog_fd_.get(), reinterpret_cast<struct sockaddr*>(&sun),
           sizeof(sun)) != 0) {
    PLOG(ERROR) << "Failed to bind logging socket";
    return false;
  }

  // Give everyone write permissions to the socket.
  if (chmod(sun.sun_path, 0666) != 0) {
    PLOG(ERROR) << "Unable to change permissions for syslog socket";
    return false;
  }
  LOG(INFO) << "Bound socket fd " << syslog_fd_.get() << " at " << name;
  return true;
}

void Collector::SetSyslogFDForTesting(base::ScopedFD syslog_fd) {
  CHECK(syslog_fd.is_valid());
  syslog_fd_ = std::move(syslog_fd);
}

bool Collector::StartWatcher(base::TimeDelta flush_period) {
  syslog_controller_ = base::FileDescriptorWatcher::WatchReadable(
      syslog_fd_.get(), base::BindRepeating(&Collector::OnSyslogReadable,
                                            base::Unretained(this)));
  if (!syslog_controller_) {
    LOG(ERROR) << "Failed to watch syslog file descriptor";
    return false;
  }

  // Start a timer to periodically flush logs.
  timer_.Start(FROM_HERE, flush_period,
               base::Bind(&Collector::FlushLogs, weak_factory_.GetWeakPtr()));

  // Start a new log request buffer.
  syslog_request_ = pb::Arena::CreateMessage<vm_tools::LogRequest>(&arena_);
  buffered_size_ = 0;

  // Everything succeeded.
  return true;
}

void Collector::OnSyslogReadable() {
  bool more = true;
  for (int i = 0; i < kMaxRecordCount && more; ++i) {
    more = ReadOneSyslogRecord();

    // Send all buffered records immediately if we've crossed the threshold.
    if (buffered_size_ > kBufferThreshold) {
      FlushLogs();
      timer_.Reset();
    }
  }
}

void Collector::FlushLogs() {
  if (syslog_request_->records_size() <= 0) {
    // Nothing to do.  Just return.
    return;
  }

  if (syslog_request_->records_size() > 0) {
    if (!SendUserLogs()) {
      // Try again later - maybe logs are being rotated.
      return;
    }
  }

  // Reset everything.
  arena_.Reset();
  syslog_request_ = pb::Arena::CreateMessage<vm_tools::LogRequest>(&arena_);
  buffered_size_ = 0;
}

bool Collector::ReadOneSyslogRecord() {
  char buf[kMaxSyslogRecord + 1];
  ssize_t ret =
      HANDLE_EINTR(recv(syslog_fd_.get(), buf, kMaxSyslogRecord, MSG_DONTWAIT));
  if (ret < 0) {
    if (errno != EAGAIN && errno != EWOULDBLOCK) {
      static int log_count = 0;
      PLOG_IF(ERROR, log_count < 10)
          << "Failed to read from syslog socket " << syslog_fd_.get();
      ++log_count;
    }
    return false;
  }

  if (ret == 0) {
    // We didn't read anything but that doesn't necessarily mean there was an
    // error.
    return true;
  }
  // Make sure the buffer is properly terminated.
  buf[ret] = '\0';

  // Attempt to parse the record.
  auto* record = pb::Arena::CreateMessage<vm_tools::LogRecord>(&arena_);
  if (!ParseSyslogRecord(buf, ret, record)) {
    LOG(ERROR) << "Failed to parse syslog record";

    // Return true here because while we failed to parse this message there may
    // still be more messages pending in the kernel buffer.
    return true;
  }

  // We have a valid entry. Update the buffered message count and store the
  // message.
  buffered_size_ += record->ByteSizeLong();

  // Safe because |record| was created by the same Arena that owns
  // |syslog_request_|.
  syslog_request_->add_records()->UnsafeArenaSwap(record);

  return true;
}

}  // namespace syslog
}  // namespace vm_tools
