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

#ifndef IPC_IPC_CHANNEL_POSIX_H_
#define IPC_IPC_CHANNEL_POSIX_H_

#include "ipc/ipc_channel.h"

#include <sys/socket.h>  // for CMSG macros

#include <queue>
#include <string>
#include <vector>

#include "base/message_loop.h"
#include "base/process.h"
#include "ipc/file_descriptor_set_posix.h"
#include "ipc/ipc_channel_reader.h"

#if !defined(OS_MACOSX)
// On Linux, the seccomp sandbox makes it very expensive to call
// recvmsg() and sendmsg(). The restriction on calling read() and write(), which
// are cheap, is that we can't pass file descriptors over them.
//
// As we cannot anticipate when the sender will provide us with file
// descriptors, we have to make the decision about whether we call read() or
// recvmsg() before we actually make the call. The easiest option is to
// create a dedicated socketpair() for exchanging file descriptors. Any file
// descriptors are split out of a message, with the non-file-descriptor payload
// going over the normal connection, and the file descriptors being sent
// separately over the other channel. When read()ing from a channel, we'll
// notice if the message was supposed to have come with file descriptors and
// use recvmsg on the other socketpair to retrieve them and combine them
// back with the rest of the message.
//
// Mac can also run in IPC_USES_READWRITE mode if necessary, but at this time
// doesn't take a performance hit from recvmsg and sendmsg, so it doesn't
// make sense to waste resources on having the separate dedicated socketpair.
// It is however useful for debugging between Linux and Mac to be able to turn
// this switch 'on' on the Mac as well.
//
// The HELLO message from the client to the server is always sent using
// sendmsg because it will contain the file descriptor that the server
// needs to send file descriptors in later messages.
#define IPC_USES_READWRITE 1
#endif

namespace IPC {

class Channel::ChannelImpl : public internal::ChannelReader,
                             public MessageLoopForIO::Watcher {
 public:
  // Mirror methods of Channel, see ipc_channel.h for description.
  ChannelImpl(const IPC::ChannelHandle& channel_handle, Mode mode,
              Listener* listener);
  virtual ~ChannelImpl();
  bool Connect();
  void Close();
  bool Send(Message* message);
  int GetClientFileDescriptor();
  int TakeClientFileDescriptor();
  void CloseClientFileDescriptor();
  bool AcceptsConnections() const;
  bool HasAcceptedConnection() const;
  bool GetClientEuid(uid_t* client_euid) const;
  void ResetToAcceptingConnectionState();
  base::ProcessId peer_pid() const { return peer_pid_; }
  static bool IsNamedServerInitialized(const std::string& channel_id);
#if defined(OS_LINUX)
  static void SetGlobalPid(int pid);
#endif  // OS_LINUX

 private:
  bool CreatePipe(const IPC::ChannelHandle& channel_handle);

  bool ProcessOutgoingMessages();

  bool AcceptConnection();
  void ClosePipeOnError();
  int GetHelloMessageProcId();
  void QueueHelloMessage();

  // ChannelReader implementation.
  virtual ReadState ReadData(char* buffer,
                             int buffer_len,
                             int* bytes_read) OVERRIDE;
  virtual bool WillDispatchInputMessage(Message* msg) OVERRIDE;
  virtual bool DidEmptyInputBuffers() OVERRIDE;
  virtual void HandleHelloMessage(const Message& msg) OVERRIDE;

#if defined(IPC_USES_READWRITE)
  // Reads the next message from the fd_pipe_ and appends them to the
  // input_fds_ queue. Returns false if there was a message receiving error.
  // True means there was a message and it was processed properly, or there was
  // no messages.
  bool ReadFileDescriptorsFromFDPipe();
#endif

  // Finds the set of file descriptors in the given message.  On success,
  // appends the descriptors to the input_fds_ member and returns true
  //
  // Returns false if the message was truncated. In this case, any handles that
  // were sent will be closed.
  bool ExtractFileDescriptorsFromMsghdr(msghdr* msg);

  // Closes all handles in the input_fds_ list and clears the list. This is
  // used to clean up handles in error conditions to avoid leaking the handles.
  void ClearInputFDs();

  // MessageLoopForIO::Watcher implementation.
  virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
  virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;

  Mode mode_;

  base::ProcessId peer_pid_;

  // After accepting one client connection on our server socket we want to
  // stop listening.
  MessageLoopForIO::FileDescriptorWatcher server_listen_connection_watcher_;
  MessageLoopForIO::FileDescriptorWatcher read_watcher_;
  MessageLoopForIO::FileDescriptorWatcher write_watcher_;

  // Indicates whether we're currently blocked waiting for a write to complete.
  bool is_blocked_on_write_;
  bool waiting_connect_;

  // If sending a message blocks then we use this variable
  // to keep track of where we are.
  size_t message_send_bytes_written_;

  // File descriptor we're listening on for new connections if we listen
  // for connections.
  int server_listen_pipe_;

  // The pipe used for communication.
  int pipe_;

  // For a server, the client end of our socketpair() -- the other end of our
  // pipe_ that is passed to the client.
  int client_pipe_;
  base::Lock client_pipe_lock_;  // Lock that protects |client_pipe_|.

#if defined(IPC_USES_READWRITE)
  // Linux/BSD use a dedicated socketpair() for passing file descriptors.
  int fd_pipe_;
  int remote_fd_pipe_;
#endif

  // The "name" of our pipe.  On Windows this is the global identifier for
  // the pipe.  On POSIX it's used as a key in a local map of file descriptors.
  std::string pipe_name_;

  // Messages to be sent are queued here.
  std::queue<Message*> output_queue_;

  // We assume a worst case: kReadBufferSize bytes of messages, where each
  // message has no payload and a full complement of descriptors.
  static const size_t kMaxReadFDs =
      (Channel::kReadBufferSize / sizeof(IPC::Message::Header)) *
      FileDescriptorSet::kMaxDescriptorsPerMessage;

  // Buffer size for file descriptors used for recvmsg. On Mac the CMSG macros
  // don't seem to be constant so we have to pick a "large enough" value.
#if defined(OS_MACOSX)
  static const size_t kMaxReadFDBuffer = 1024;
#else
  static const size_t kMaxReadFDBuffer = CMSG_SPACE(sizeof(int) * kMaxReadFDs);
#endif

  // Temporary buffer used to receive the file descriptors from recvmsg.
  // Code that writes into this should immediately read them out and save
  // them to input_fds_, since this buffer will be re-used anytime we call
  // recvmsg.
  char input_cmsg_buf_[kMaxReadFDBuffer];

  // File descriptors extracted from messages coming off of the channel. The
  // handles may span messages and come off different channels from the message
  // data (in the case of READWRITE), and are processed in FIFO here.
  // NOTE: The implementation assumes underlying storage here is contiguous, so
  // don't change to something like std::deque<> without changing the
  // implementation!
  std::vector<int> input_fds_;

  // True if we are responsible for unlinking the unix domain socket file.
  bool must_unlink_;

#if defined(OS_LINUX)
  // If non-zero, overrides the process ID sent in the hello message.
  static int global_pid_;
#endif  // OS_LINUX

  DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelImpl);
};

// The maximum length of the name of a pipe for MODE_NAMED_SERVER or
// MODE_NAMED_CLIENT if you want to pass in your own socket.
// The standard size on linux is 108, mac is 104. To maintain consistency
// across platforms we standardize on the smaller value.
static const size_t kMaxPipeNameLength = 104;

}  // namespace IPC

#endif  // IPC_IPC_CHANNEL_POSIX_H_
