// Copyright (c) 2012 The Chromium 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 "build/build_config.h"

#if defined(OS_POSIX)
#if defined(OS_MACOSX)
extern "C" {
#include <sandbox.h>
}
#endif
#include <fcntl.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>

#include <queue>

#include "base/callback.h"
#include "base/file_descriptor_posix.h"
#include "base/location.h"
#include "base/pickle.h"
#include "base/posix/eintr_wrapper.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "ipc/ipc_message_attachment_set.h"
#include "ipc/ipc_message_utils.h"
#include "ipc/ipc_test_base.h"

#if defined(OS_POSIX)
#include "base/macros.h"
#endif

namespace {

const unsigned kNumFDsToSend = 7;  // per message
const unsigned kNumMessages = 20;
const char* kDevZeroPath = "/dev/zero";

#if defined(OS_POSIX)
static_assert(kNumFDsToSend ==
                  IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage,
              "The number of FDs to send must be kMaxDescriptorsPerMessage.");
#endif

class MyChannelDescriptorListenerBase : public IPC::Listener {
 public:
  bool OnMessageReceived(const IPC::Message& message) override {
    base::PickleIterator iter(message);
    base::FileDescriptor descriptor;
    while (IPC::ParamTraits<base::FileDescriptor>::Read(
               &message, &iter, &descriptor)) {
      HandleFD(descriptor.fd);
    }
    return true;
  }

 protected:
  virtual void HandleFD(int fd) = 0;
};

class MyChannelDescriptorListener : public MyChannelDescriptorListenerBase {
 public:
  explicit MyChannelDescriptorListener(ino_t expected_inode_num)
      : MyChannelDescriptorListenerBase(),
        expected_inode_num_(expected_inode_num),
        num_fds_received_(0) {
  }

  bool GotExpectedNumberOfDescriptors() const {
    return num_fds_received_ == kNumFDsToSend * kNumMessages;
  }

  void OnChannelError() override {
    base::MessageLoop::current()->QuitWhenIdle();
  }

 protected:
  void HandleFD(int fd) override {
    ASSERT_GE(fd, 0);
    // Check that we can read from the FD.
    char buf;
    ssize_t amt_read = read(fd, &buf, 1);
    ASSERT_EQ(amt_read, 1);
    ASSERT_EQ(buf, 0);  // /dev/zero always reads 0 bytes.

    struct stat st;
    ASSERT_EQ(fstat(fd, &st), 0);

    ASSERT_EQ(close(fd), 0);

    // Compare inode numbers to check that the file sent over the wire is
    // actually the one expected.
    ASSERT_EQ(expected_inode_num_, st.st_ino);

    ++num_fds_received_;
    if (num_fds_received_ == kNumFDsToSend * kNumMessages)
      base::MessageLoop::current()->QuitWhenIdle();
  }

 private:
  ino_t expected_inode_num_;
  unsigned num_fds_received_;
};


class IPCSendFdsTest : public IPCTestBase {
 protected:
  void RunServer() {
    // Set up IPC channel and start client.
    MyChannelDescriptorListener listener(-1);
    CreateChannel(&listener);
    ASSERT_TRUE(ConnectChannel());
    ASSERT_TRUE(StartClient());

    for (unsigned i = 0; i < kNumMessages; ++i) {
      IPC::Message* message =
          new IPC::Message(0, 3, IPC::Message::PRIORITY_NORMAL);
      for (unsigned j = 0; j < kNumFDsToSend; ++j) {
        const int fd = open(kDevZeroPath, O_RDONLY);
        ASSERT_GE(fd, 0);
        base::FileDescriptor descriptor(fd, true);
        IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor);
      }
      ASSERT_TRUE(sender()->Send(message));
    }

    // Run message loop.
    base::MessageLoop::current()->Run();

    // Close the channel so the client's OnChannelError() gets fired.
    channel()->Close();

    EXPECT_TRUE(WaitForClientShutdown());
    DestroyChannel();
  }
};

#if defined(OS_ANDROID)
#define MAYBE_DescriptorTest DISABLED_DescriptorTest
#else
#define MAYBE_DescriptorTest DescriptorTest
#endif
TEST_F(IPCSendFdsTest, MAYBE_DescriptorTest) {
  Init("SendFdsClient");
  RunServer();
}

int SendFdsClientCommon(const std::string& test_client_name,
                        ino_t expected_inode_num) {
  base::MessageLoopForIO main_message_loop;
  MyChannelDescriptorListener listener(expected_inode_num);

  // Set up IPC channel.
  scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
      IPCTestBase::GetChannelName(test_client_name), &listener));
  CHECK(channel->Connect());

  // Run message loop.
  base::MessageLoop::current()->Run();

  // Verify that the message loop was exited due to getting the correct number
  // of descriptors, and not because of the channel closing unexpectedly.
  CHECK(listener.GotExpectedNumberOfDescriptors());

  return 0;
}

MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsClient) {
  struct stat st;
  int fd = open(kDevZeroPath, O_RDONLY);
  fstat(fd, &st);
  EXPECT_GE(IGNORE_EINTR(close(fd)), 0);
  return SendFdsClientCommon("SendFdsClient", st.st_ino);
}

#if defined(OS_MACOSX)
// Test that FDs are correctly sent to a sandboxed process.
// TODO(port): Make this test cross-platform.
TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) {
  Init("SendFdsSandboxedClient");
  RunServer();
}

MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsSandboxedClient) {
  struct stat st;
  const int fd = open(kDevZeroPath, O_RDONLY);
  fstat(fd, &st);
  if (IGNORE_EINTR(close(fd)) < 0)
    return -1;

  // Enable the sandbox.
  char* error_buff = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  int error = sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED,
                           &error_buff);
  bool success = (error == 0 && error_buff == NULL);
  if (!success)
    return -1;

  sandbox_free_error(error_buff);
#pragma clang diagnostic pop

  // Make sure sandbox is really enabled.
  if (open(kDevZeroPath, O_RDONLY) != -1) {
    LOG(ERROR) << "Sandbox wasn't properly enabled";
    return -1;
  }

  // See if we can receive a file descriptor.
  return SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino);
}
#endif  // defined(OS_MACOSX)


class MyCBListener : public MyChannelDescriptorListenerBase {
 public:
  MyCBListener(base::Callback<void(int)> cb, int fds_to_send)
      : MyChannelDescriptorListenerBase(),
        cb_(cb) {
    }

 protected:
  void HandleFD(int fd) override { cb_.Run(fd); }
 private:
  base::Callback<void(int)> cb_;
};

std::pair<int, int> make_socket_pair() {
  int pipe_fds[2];
  CHECK_EQ(0, HANDLE_EINTR(socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds)));
  return std::pair<int, int>(pipe_fds[0], pipe_fds[1]);
}

static void null_cb(int unused_fd) {
  NOTREACHED();
}

class PipeChannelHelper {
 public:
  PipeChannelHelper(base::Thread* in_thread,
                    base::Thread* out_thread,
                    base::Callback<void(int)> cb,
                    int fds_to_send) :
      in_thread_(in_thread),
      out_thread_(out_thread),
      cb_listener_(cb, fds_to_send),
      null_listener_(base::Bind(&null_cb), 0) {
  }

  void Init() {
    IPC::ChannelHandle in_handle("IN");
    in = IPC::Channel::CreateServer(in_handle, &null_listener_);
    IPC::ChannelHandle out_handle(
        "OUT", base::FileDescriptor(in->TakeClientFileDescriptor()));
    out = IPC::Channel::CreateClient(out_handle, &cb_listener_);
    // PostTask the connect calls to make sure the callbacks happens
    // on the right threads.
    in_thread_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&PipeChannelHelper::Connect, in.get()));
    out_thread_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&PipeChannelHelper::Connect, out.get()));
  }

  static void DestroyChannel(scoped_ptr<IPC::Channel> *c,
                             base::WaitableEvent *event) {
    c->reset(0);
    event->Signal();
  }

  ~PipeChannelHelper() {
    base::WaitableEvent a(true, false);
    base::WaitableEvent b(true, false);
    in_thread_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&PipeChannelHelper::DestroyChannel, &in, &a));
    out_thread_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&PipeChannelHelper::DestroyChannel, &out, &b));
    a.Wait();
    b.Wait();
  }

  static void Connect(IPC::Channel *channel) {
    EXPECT_TRUE(channel->Connect());
  }

  void Send(int fd) {
    CHECK_EQ(base::MessageLoop::current(), in_thread_->message_loop());

    ASSERT_GE(fd, 0);
    base::FileDescriptor descriptor(fd, true);

    IPC::Message* message =
        new IPC::Message(0, 3, IPC::Message::PRIORITY_NORMAL);
    IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor);
    ASSERT_TRUE(in->Send(message));
  }

 private:
  scoped_ptr<IPC::Channel> in, out;
  base::Thread* in_thread_;
  base::Thread* out_thread_;
  MyCBListener cb_listener_;
  MyCBListener null_listener_;
};

// This test is meant to provoke a kernel bug on OSX, and to prove
// that the workaround for it is working. It sets up two pipes and three
// threads, the producer thread creates socketpairs and sends one of the fds
// over pipe1 to the middleman thread. The middleman thread simply takes the fd
// sends it over pipe2 to the consumer thread. The consumer thread writes a byte
// to each fd it receives and then closes the pipe. The producer thread reads
// the bytes back from each pair of pipes and make sure that everything worked.
// This feedback mechanism makes sure that not too many file descriptors are
// in flight at the same time. For more info on the bug, see:
// http://crbug.com/298276
class IPCMultiSendingFdsTest : public testing::Test {
 public:
  IPCMultiSendingFdsTest() : received_(true, false) {}

  void Producer(PipeChannelHelper* dest,
                base::Thread* t,
                int pipes_to_send) {
    for (int i = 0; i < pipes_to_send; i++) {
      received_.Reset();
      std::pair<int, int> pipe_fds = make_socket_pair();
      t->task_runner()->PostTask(
          FROM_HERE, base::Bind(&PipeChannelHelper::Send,
                                base::Unretained(dest), pipe_fds.second));
      char tmp = 'x';
      CHECK_EQ(1, HANDLE_EINTR(write(pipe_fds.first, &tmp, 1)));
      CHECK_EQ(0, IGNORE_EINTR(close(pipe_fds.first)));
      received_.Wait();
    }
  }

  void ConsumerHandleFD(int fd) {
    char tmp = 'y';
    CHECK_EQ(1, HANDLE_EINTR(read(fd, &tmp, 1)));
    CHECK_EQ(tmp, 'x');
    CHECK_EQ(0, IGNORE_EINTR(close(fd)));
    received_.Signal();
  }

  base::Thread* CreateThread(const char* name) {
    base::Thread* ret = new base::Thread(name);
    base::Thread::Options options;
    options.message_loop_type = base::MessageLoop::TYPE_IO;
    ret->StartWithOptions(options);
    return ret;
  }

  void Run() {
    // On my mac, this test fails roughly 35 times per
    // million sends with low load, but much more with high load.
    // Unless the workaround is in place. With 10000 sends, we
    // should see at least a 3% failure rate.
    const int pipes_to_send = 20000;
    scoped_ptr<base::Thread> producer(CreateThread("producer"));
    scoped_ptr<base::Thread> middleman(CreateThread("middleman"));
    scoped_ptr<base::Thread> consumer(CreateThread("consumer"));
    PipeChannelHelper pipe1(
        middleman.get(),
        consumer.get(),
        base::Bind(&IPCMultiSendingFdsTest::ConsumerHandleFD,
                   base::Unretained(this)),
        pipes_to_send);
    PipeChannelHelper pipe2(
        producer.get(),
        middleman.get(),
        base::Bind(&PipeChannelHelper::Send, base::Unretained(&pipe1)),
        pipes_to_send);
    pipe1.Init();
    pipe2.Init();
    Producer(&pipe2, producer.get(), pipes_to_send);
  }

 private:
  base::WaitableEvent received_;
};

TEST_F(IPCMultiSendingFdsTest, StressTest) {
  Run();
}

}  // namespace

#endif  // defined(OS_POSIX)
