// Copyright 2016 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 "mojo/edk/system/node_channel.h"

#include <cstring>
#include <limits>
#include <sstream>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "mojo/edk/system/channel.h"
#include "mojo/edk/system/request_context.h"

#if defined(OS_MACOSX) && !defined(OS_IOS)
#include "mojo/edk/system/mach_port_relay.h"
#endif

namespace mojo {
namespace edk {

namespace {

template <typename T>
T Align(T t) {
  const auto k = kChannelMessageAlignment;
  return t + (k - (t % k)) % k;
}

// NOTE: Please ONLY append messages to the end of this enum.
enum class MessageType : uint32_t {
  ACCEPT_CHILD,
  ACCEPT_PARENT,
  ADD_BROKER_CLIENT,
  BROKER_CLIENT_ADDED,
  ACCEPT_BROKER_CLIENT,
  PORTS_MESSAGE,
  REQUEST_PORT_MERGE,
  REQUEST_INTRODUCTION,
  INTRODUCE,
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
  RELAY_PORTS_MESSAGE,
#endif
  BROADCAST,
#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
  PORTS_MESSAGE_FROM_RELAY,
#endif
  ACCEPT_PEER,
};

struct Header {
  MessageType type;
  uint32_t padding;
};

static_assert(IsAlignedForChannelMessage(sizeof(Header)),
              "Invalid header size.");

struct AcceptChildData {
  ports::NodeName parent_name;
  ports::NodeName token;
};

struct AcceptParentData {
  ports::NodeName token;
  ports::NodeName child_name;
};

struct AcceptPeerData {
  ports::NodeName token;
  ports::NodeName peer_name;
  ports::PortName port_name;
};

// This message may include a process handle on plaforms that require it.
struct AddBrokerClientData {
  ports::NodeName client_name;
#if !defined(OS_WIN)
  uint32_t process_handle;
  uint32_t padding;
#endif
};

#if !defined(OS_WIN)
static_assert(sizeof(base::ProcessHandle) == sizeof(uint32_t),
              "Unexpected pid size");
static_assert(sizeof(AddBrokerClientData) % kChannelMessageAlignment == 0,
              "Invalid AddBrokerClientData size.");
#endif

// This data is followed by a platform channel handle to the broker.
struct BrokerClientAddedData {
  ports::NodeName client_name;
};

// This data may be followed by a platform channel handle to the broker. If not,
// then the parent is the broker and its channel should be used as such.
struct AcceptBrokerClientData {
  ports::NodeName broker_name;
};

// This is followed by arbitrary payload data which is interpreted as a token
// string for port location.
struct RequestPortMergeData {
  ports::PortName connector_port_name;
};

// Used for both REQUEST_INTRODUCTION and INTRODUCE.
//
// For INTRODUCE the message also includes a valid platform handle for a channel
// the receiver may use to communicate with the named node directly, or an
// invalid platform handle if the node is unknown to the sender or otherwise
// cannot be introduced.
struct IntroductionData {
  ports::NodeName name;
};

#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
// This struct is followed by the full payload of a message to be relayed.
struct RelayPortsMessageData {
  ports::NodeName destination;
};

// This struct is followed by the full payload of a relayed message.
struct PortsMessageFromRelayData {
  ports::NodeName source;
};
#endif

template <typename DataType>
Channel::MessagePtr CreateMessage(MessageType type,
                                  size_t payload_size,
                                  size_t num_handles,
                                  DataType** out_data) {
  Channel::MessagePtr message(
      new Channel::Message(sizeof(Header) + payload_size, num_handles));
  Header* header = reinterpret_cast<Header*>(message->mutable_payload());
  header->type = type;
  header->padding = 0;
  *out_data = reinterpret_cast<DataType*>(&header[1]);
  return message;
}

template <typename DataType>
bool GetMessagePayload(const void* bytes,
                       size_t num_bytes,
                       DataType** out_data) {
  static_assert(sizeof(DataType) > 0, "DataType must have non-zero size.");
  if (num_bytes < sizeof(Header) + sizeof(DataType))
    return false;
  *out_data = reinterpret_cast<const DataType*>(
      static_cast<const char*>(bytes) + sizeof(Header));
  return true;
}

}  // namespace

// static
scoped_refptr<NodeChannel> NodeChannel::Create(
    Delegate* delegate,
    ConnectionParams connection_params,
    scoped_refptr<base::TaskRunner> io_task_runner,
    const ProcessErrorCallback& process_error_callback) {
#if defined(OS_NACL_SFI)
  LOG(FATAL) << "Multi-process not yet supported on NaCl-SFI";
  return nullptr;
#else
  return new NodeChannel(delegate, std::move(connection_params), io_task_runner,
                         process_error_callback);
#endif
}

// static
Channel::MessagePtr NodeChannel::CreatePortsMessage(size_t payload_size,
                                                    void** payload,
                                                    size_t num_handles) {
  return CreateMessage(MessageType::PORTS_MESSAGE, payload_size, num_handles,
                       payload);
}

// static
void NodeChannel::GetPortsMessageData(Channel::Message* message,
                                      void** data,
                                      size_t* num_data_bytes) {
  *data = reinterpret_cast<Header*>(message->mutable_payload()) + 1;
  *num_data_bytes = message->payload_size() - sizeof(Header);
}

void NodeChannel::Start() {
#if defined(OS_MACOSX) && !defined(OS_IOS)
  MachPortRelay* relay = delegate_->GetMachPortRelay();
  if (relay)
    relay->AddObserver(this);
#endif

  base::AutoLock lock(channel_lock_);
  // ShutDown() may have already been called, in which case |channel_| is null.
  if (channel_)
    channel_->Start();
}

void NodeChannel::ShutDown() {
#if defined(OS_MACOSX) && !defined(OS_IOS)
  MachPortRelay* relay = delegate_->GetMachPortRelay();
  if (relay)
    relay->RemoveObserver(this);
#endif

  base::AutoLock lock(channel_lock_);
  if (channel_) {
    channel_->ShutDown();
    channel_ = nullptr;
  }
}

void NodeChannel::LeakHandleOnShutdown() {
  base::AutoLock lock(channel_lock_);
  if (channel_) {
    channel_->LeakHandle();
  }
}

void NodeChannel::NotifyBadMessage(const std::string& error) {
  if (!process_error_callback_.is_null())
    process_error_callback_.Run("Received bad user message: " + error);
}

void NodeChannel::SetRemoteProcessHandle(base::ProcessHandle process_handle) {
  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
  base::AutoLock lock(remote_process_handle_lock_);
  DCHECK_EQ(base::kNullProcessHandle, remote_process_handle_);
  CHECK_NE(remote_process_handle_, base::GetCurrentProcessHandle());
  remote_process_handle_ = process_handle;
#if defined(OS_WIN)
  DCHECK(!scoped_remote_process_handle_.is_valid());
  scoped_remote_process_handle_.reset(PlatformHandle(process_handle));
#endif
}

bool NodeChannel::HasRemoteProcessHandle() {
  base::AutoLock lock(remote_process_handle_lock_);
  return remote_process_handle_ != base::kNullProcessHandle;
}

base::ProcessHandle NodeChannel::CopyRemoteProcessHandle() {
  base::AutoLock lock(remote_process_handle_lock_);
#if defined(OS_WIN)
  if (remote_process_handle_ != base::kNullProcessHandle) {
    // Privileged nodes use this to pass their childrens' process handles to the
    // broker on launch.
    HANDLE handle = remote_process_handle_;
    BOOL result = DuplicateHandle(
        base::GetCurrentProcessHandle(), remote_process_handle_,
        base::GetCurrentProcessHandle(), &handle, 0, FALSE,
        DUPLICATE_SAME_ACCESS);
    DPCHECK(result);
    return handle;
  }
  return base::kNullProcessHandle;
#else
  return remote_process_handle_;
#endif
}

void NodeChannel::SetRemoteNodeName(const ports::NodeName& name) {
  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
  remote_node_name_ = name;
}

void NodeChannel::AcceptChild(const ports::NodeName& parent_name,
                              const ports::NodeName& token) {
  AcceptChildData* data;
  Channel::MessagePtr message = CreateMessage(
      MessageType::ACCEPT_CHILD, sizeof(AcceptChildData), 0, &data);
  data->parent_name = parent_name;
  data->token = token;
  WriteChannelMessage(std::move(message));
}

void NodeChannel::AcceptParent(const ports::NodeName& token,
                               const ports::NodeName& child_name) {
  AcceptParentData* data;
  Channel::MessagePtr message = CreateMessage(
      MessageType::ACCEPT_PARENT, sizeof(AcceptParentData), 0, &data);
  data->token = token;
  data->child_name = child_name;
  WriteChannelMessage(std::move(message));
}

void NodeChannel::AcceptPeer(const ports::NodeName& sender_name,
                             const ports::NodeName& token,
                             const ports::PortName& port_name) {
  AcceptPeerData* data;
  Channel::MessagePtr message =
      CreateMessage(MessageType::ACCEPT_PEER, sizeof(AcceptPeerData), 0, &data);
  data->token = token;
  data->peer_name = sender_name;
  data->port_name = port_name;
  WriteChannelMessage(std::move(message));
}

void NodeChannel::AddBrokerClient(const ports::NodeName& client_name,
                                  base::ProcessHandle process_handle) {
  AddBrokerClientData* data;
  ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector());
#if defined(OS_WIN)
  handles->push_back(PlatformHandle(process_handle));
#endif
  Channel::MessagePtr message = CreateMessage(
      MessageType::ADD_BROKER_CLIENT, sizeof(AddBrokerClientData),
      handles->size(), &data);
  message->SetHandles(std::move(handles));
  data->client_name = client_name;
#if !defined(OS_WIN)
  data->process_handle = process_handle;
  data->padding = 0;
#endif
  WriteChannelMessage(std::move(message));
}

void NodeChannel::BrokerClientAdded(const ports::NodeName& client_name,
                                    ScopedPlatformHandle broker_channel) {
  BrokerClientAddedData* data;
  ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector());
  if (broker_channel.is_valid())
    handles->push_back(broker_channel.release());
  Channel::MessagePtr message = CreateMessage(
      MessageType::BROKER_CLIENT_ADDED, sizeof(BrokerClientAddedData),
      handles->size(), &data);
  message->SetHandles(std::move(handles));
  data->client_name = client_name;
  WriteChannelMessage(std::move(message));
}

void NodeChannel::AcceptBrokerClient(const ports::NodeName& broker_name,
                                     ScopedPlatformHandle broker_channel) {
  AcceptBrokerClientData* data;
  ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector());
  if (broker_channel.is_valid())
    handles->push_back(broker_channel.release());
  Channel::MessagePtr message = CreateMessage(
      MessageType::ACCEPT_BROKER_CLIENT, sizeof(AcceptBrokerClientData),
      handles->size(), &data);
  message->SetHandles(std::move(handles));
  data->broker_name = broker_name;
  WriteChannelMessage(std::move(message));
}

void NodeChannel::PortsMessage(Channel::MessagePtr message) {
  WriteChannelMessage(std::move(message));
}

void NodeChannel::RequestPortMerge(const ports::PortName& connector_port_name,
                                   const std::string& token) {
  RequestPortMergeData* data;
  Channel::MessagePtr message = CreateMessage(
      MessageType::REQUEST_PORT_MERGE,
      sizeof(RequestPortMergeData) + token.size(), 0, &data);
  data->connector_port_name = connector_port_name;
  memcpy(data + 1, token.data(), token.size());
  WriteChannelMessage(std::move(message));
}

void NodeChannel::RequestIntroduction(const ports::NodeName& name) {
  IntroductionData* data;
  Channel::MessagePtr message = CreateMessage(
      MessageType::REQUEST_INTRODUCTION, sizeof(IntroductionData), 0, &data);
  data->name = name;
  WriteChannelMessage(std::move(message));
}

void NodeChannel::Introduce(const ports::NodeName& name,
                            ScopedPlatformHandle channel_handle) {
  IntroductionData* data;
  ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector());
  if (channel_handle.is_valid())
    handles->push_back(channel_handle.release());
  Channel::MessagePtr message = CreateMessage(
      MessageType::INTRODUCE, sizeof(IntroductionData), handles->size(), &data);
  message->SetHandles(std::move(handles));
  data->name = name;
  WriteChannelMessage(std::move(message));
}

void NodeChannel::Broadcast(Channel::MessagePtr message) {
  DCHECK(!message->has_handles());
  void* data;
  Channel::MessagePtr broadcast_message = CreateMessage(
      MessageType::BROADCAST, message->data_num_bytes(), 0, &data);
  memcpy(data, message->data(), message->data_num_bytes());
  WriteChannelMessage(std::move(broadcast_message));
}

#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
void NodeChannel::RelayPortsMessage(const ports::NodeName& destination,
                                    Channel::MessagePtr message) {
#if defined(OS_WIN)
  DCHECK(message->has_handles());

  // Note that this is only used on Windows, and on Windows all platform
  // handles are included in the message data. We blindly copy all the data
  // here and the relay node (the parent) will duplicate handles as needed.
  size_t num_bytes = sizeof(RelayPortsMessageData) + message->data_num_bytes();
  RelayPortsMessageData* data;
  Channel::MessagePtr relay_message = CreateMessage(
      MessageType::RELAY_PORTS_MESSAGE, num_bytes, 0, &data);
  data->destination = destination;
  memcpy(data + 1, message->data(), message->data_num_bytes());

  // When the handles are duplicated in the parent, the source handles will
  // be closed. If the parent never receives this message then these handles
  // will leak, but that means something else has probably broken and the
  // sending process won't likely be around much longer.
  ScopedPlatformHandleVectorPtr handles = message->TakeHandles();
  handles->clear();

#else
  DCHECK(message->has_mach_ports());

  // On OSX, the handles are extracted from the relayed message and attached to
  // the wrapper. The broker then takes the handles attached to the wrapper and
  // moves them back to the relayed message. This is necessary because the
  // message may contain fds which need to be attached to the outer message so
  // that they can be transferred to the broker.
  ScopedPlatformHandleVectorPtr handles = message->TakeHandles();
  size_t num_bytes = sizeof(RelayPortsMessageData) + message->data_num_bytes();
  RelayPortsMessageData* data;
  Channel::MessagePtr relay_message = CreateMessage(
      MessageType::RELAY_PORTS_MESSAGE, num_bytes, handles->size(), &data);
  data->destination = destination;
  memcpy(data + 1, message->data(), message->data_num_bytes());
  relay_message->SetHandles(std::move(handles));
#endif  // defined(OS_WIN)

  WriteChannelMessage(std::move(relay_message));
}

void NodeChannel::PortsMessageFromRelay(const ports::NodeName& source,
                                        Channel::MessagePtr message) {
  size_t num_bytes = sizeof(PortsMessageFromRelayData) +
      message->payload_size();
  PortsMessageFromRelayData* data;
  Channel::MessagePtr relayed_message = CreateMessage(
      MessageType::PORTS_MESSAGE_FROM_RELAY, num_bytes, message->num_handles(),
      &data);
  data->source = source;
  if (message->payload_size())
    memcpy(data + 1, message->payload(), message->payload_size());
  relayed_message->SetHandles(message->TakeHandles());
  WriteChannelMessage(std::move(relayed_message));
}
#endif  // defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))

NodeChannel::NodeChannel(Delegate* delegate,
                         ConnectionParams connection_params,
                         scoped_refptr<base::TaskRunner> io_task_runner,
                         const ProcessErrorCallback& process_error_callback)
    : delegate_(delegate),
      io_task_runner_(io_task_runner),
      process_error_callback_(process_error_callback)
#if !defined(OS_NACL_SFI)
      ,
      channel_(
          Channel::Create(this, std::move(connection_params), io_task_runner_))
#endif
{
}

NodeChannel::~NodeChannel() {
  ShutDown();
}

void NodeChannel::OnChannelMessage(const void* payload,
                                   size_t payload_size,
                                   ScopedPlatformHandleVectorPtr handles) {
  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());

  RequestContext request_context(RequestContext::Source::SYSTEM);

  // Ensure this NodeChannel stays alive through the extent of this method. The
  // delegate may have the only other reference to this object and it may choose
  // to drop it here in response to, e.g., a malformed message.
  scoped_refptr<NodeChannel> keepalive = this;

#if defined(OS_WIN)
  // If we receive handles from a known process, rewrite them to our own
  // process. This can occur when a privileged node receives handles directly
  // from a privileged descendant.
  {
    base::AutoLock lock(remote_process_handle_lock_);
    if (handles && remote_process_handle_ != base::kNullProcessHandle) {
      // Note that we explicitly mark the handles as being owned by the sending
      // process before rewriting them, in order to accommodate RewriteHandles'
      // internal sanity checks.
      for (auto& handle : *handles)
        handle.owning_process = remote_process_handle_;
      if (!Channel::Message::RewriteHandles(remote_process_handle_,
                                            base::GetCurrentProcessHandle(),
                                            handles.get())) {
        DLOG(ERROR) << "Received one or more invalid handles.";
      }
    } else if (handles) {
      // Handles received by an unknown process must already be owned by us.
      for (auto& handle : *handles)
        handle.owning_process = base::GetCurrentProcessHandle();
    }
  }
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  // If we're not the root, receive any mach ports from the message. If we're
  // the root, the only message containing mach ports should be a
  // RELAY_PORTS_MESSAGE.
  {
    MachPortRelay* relay = delegate_->GetMachPortRelay();
    if (handles && !relay) {
      if (!MachPortRelay::ReceivePorts(handles.get())) {
        LOG(ERROR) << "Error receiving mach ports.";
      }
    }
  }
#endif  // defined(OS_WIN)


  if (payload_size <= sizeof(Header)) {
    delegate_->OnChannelError(remote_node_name_, this);
    return;
  }

  const Header* header = static_cast<const Header*>(payload);
  switch (header->type) {
    case MessageType::ACCEPT_CHILD: {
      const AcceptChildData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        delegate_->OnAcceptChild(remote_node_name_, data->parent_name,
                                 data->token);
        return;
      }
      break;
    }

    case MessageType::ACCEPT_PARENT: {
      const AcceptParentData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        delegate_->OnAcceptParent(remote_node_name_, data->token,
                                  data->child_name);
        return;
      }
      break;
    }

    case MessageType::ADD_BROKER_CLIENT: {
      const AddBrokerClientData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        ScopedPlatformHandle process_handle;
#if defined(OS_WIN)
        if (!handles || handles->size() != 1) {
          DLOG(ERROR) << "Dropping invalid AddBrokerClient message.";
          break;
        }
        process_handle = ScopedPlatformHandle(handles->at(0));
        handles->clear();
        delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
                                     process_handle.release().handle);
#else
        if (handles && handles->size() != 0) {
          DLOG(ERROR) << "Dropping invalid AddBrokerClient message.";
          break;
        }
        delegate_->OnAddBrokerClient(remote_node_name_, data->client_name,
                                     data->process_handle);
#endif
        return;
      }
      break;
    }

    case MessageType::BROKER_CLIENT_ADDED: {
      const BrokerClientAddedData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        ScopedPlatformHandle broker_channel;
        if (!handles || handles->size() != 1) {
          DLOG(ERROR) << "Dropping invalid BrokerClientAdded message.";
          break;
        }
        broker_channel = ScopedPlatformHandle(handles->at(0));
        handles->clear();
        delegate_->OnBrokerClientAdded(remote_node_name_, data->client_name,
                                       std::move(broker_channel));
        return;
      }
      break;
    }

    case MessageType::ACCEPT_BROKER_CLIENT: {
      const AcceptBrokerClientData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        ScopedPlatformHandle broker_channel;
        if (handles && handles->size() > 1) {
          DLOG(ERROR) << "Dropping invalid AcceptBrokerClient message.";
          break;
        }
        if (handles && handles->size() == 1) {
          broker_channel = ScopedPlatformHandle(handles->at(0));
          handles->clear();
        }
        delegate_->OnAcceptBrokerClient(remote_node_name_, data->broker_name,
                                        std::move(broker_channel));
        return;
      }
      break;
    }

    case MessageType::PORTS_MESSAGE: {
      size_t num_handles = handles ? handles->size() : 0;
      Channel::MessagePtr message(
          new Channel::Message(payload_size, num_handles));
      message->SetHandles(std::move(handles));
      memcpy(message->mutable_payload(), payload, payload_size);
      delegate_->OnPortsMessage(remote_node_name_, std::move(message));
      return;
    }

    case MessageType::REQUEST_PORT_MERGE: {
      const RequestPortMergeData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        // Don't accept an empty token.
        size_t token_size = payload_size - sizeof(*data) - sizeof(Header);
        if (token_size == 0)
          break;
        std::string token(reinterpret_cast<const char*>(data + 1), token_size);
        delegate_->OnRequestPortMerge(remote_node_name_,
                                      data->connector_port_name, token);
        return;
      }
      break;
    }

    case MessageType::REQUEST_INTRODUCTION: {
      const IntroductionData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        delegate_->OnRequestIntroduction(remote_node_name_, data->name);
        return;
      }
      break;
    }

    case MessageType::INTRODUCE: {
      const IntroductionData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        if (handles && handles->size() > 1) {
          DLOG(ERROR) << "Dropping invalid introduction message.";
          break;
        }
        ScopedPlatformHandle channel_handle;
        if (handles && handles->size() == 1) {
          channel_handle = ScopedPlatformHandle(handles->at(0));
          handles->clear();
        }
        delegate_->OnIntroduce(remote_node_name_, data->name,
                               std::move(channel_handle));
        return;
      }
      break;
    }

#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
    case MessageType::RELAY_PORTS_MESSAGE: {
      base::ProcessHandle from_process;
      {
        base::AutoLock lock(remote_process_handle_lock_);
        from_process = remote_process_handle_;
      }
      const RelayPortsMessageData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        // Don't try to relay an empty message.
        if (payload_size <= sizeof(Header) + sizeof(RelayPortsMessageData))
          break;

        const void* message_start = data + 1;
        Channel::MessagePtr message = Channel::Message::Deserialize(
            message_start, payload_size - sizeof(Header) - sizeof(*data));
        if (!message) {
          DLOG(ERROR) << "Dropping invalid relay message.";
          break;
        }
  #if defined(OS_MACOSX) && !defined(OS_IOS)
        message->SetHandles(std::move(handles));
        MachPortRelay* relay = delegate_->GetMachPortRelay();
        if (!relay) {
          LOG(ERROR) << "Receiving mach ports without a port relay from "
                     << remote_node_name_ << ". Dropping message.";
          break;
        }
        {
          base::AutoLock lock(pending_mach_messages_lock_);
          if (relay->port_provider()->TaskForPid(from_process) ==
              MACH_PORT_NULL) {
            pending_relay_messages_.push(
                std::make_pair(data->destination, std::move(message)));
            break;
          }
        }
  #endif
        delegate_->OnRelayPortsMessage(remote_node_name_, from_process,
                                       data->destination, std::move(message));
        return;
      }
      break;
    }
#endif

    case MessageType::BROADCAST: {
      if (payload_size <= sizeof(Header))
        break;
      const void* data = static_cast<const void*>(
          reinterpret_cast<const Header*>(payload) + 1);
      Channel::MessagePtr message =
          Channel::Message::Deserialize(data, payload_size - sizeof(Header));
      if (!message || message->has_handles()) {
        DLOG(ERROR) << "Dropping invalid broadcast message.";
        break;
      }
      delegate_->OnBroadcast(remote_node_name_, std::move(message));
      return;
    }

#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
    case MessageType::PORTS_MESSAGE_FROM_RELAY:
      const PortsMessageFromRelayData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        size_t num_bytes = payload_size - sizeof(*data);
        if (num_bytes < sizeof(Header))
          break;
        num_bytes -= sizeof(Header);

        size_t num_handles = handles ? handles->size() : 0;
        Channel::MessagePtr message(
            new Channel::Message(num_bytes, num_handles));
        message->SetHandles(std::move(handles));
        if (num_bytes)
          memcpy(message->mutable_payload(), data + 1, num_bytes);
        delegate_->OnPortsMessageFromRelay(
            remote_node_name_, data->source, std::move(message));
        return;
      }
      break;

#endif  // defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))

    case MessageType::ACCEPT_PEER: {
      const AcceptPeerData* data;
      if (GetMessagePayload(payload, payload_size, &data)) {
        delegate_->OnAcceptPeer(remote_node_name_, data->token, data->peer_name,
                                data->port_name);
        return;
      }
      break;
    }

    default:
      break;
  }

  DLOG(ERROR) << "Received invalid message. Closing channel.";
  delegate_->OnChannelError(remote_node_name_, this);
}

void NodeChannel::OnChannelError() {
  DCHECK(io_task_runner_->RunsTasksOnCurrentThread());

  RequestContext request_context(RequestContext::Source::SYSTEM);

  ShutDown();
  // |OnChannelError()| may cause |this| to be destroyed, but still need access
  // to the name name after that destruction. So may a copy of
  // |remote_node_name_| so it can be used if |this| becomes destroyed.
  ports::NodeName node_name = remote_node_name_;
  delegate_->OnChannelError(node_name, this);
}

#if defined(OS_MACOSX) && !defined(OS_IOS)
void NodeChannel::OnProcessReady(base::ProcessHandle process) {
  io_task_runner_->PostTask(FROM_HERE, base::Bind(
      &NodeChannel::ProcessPendingMessagesWithMachPorts, this));
}

void NodeChannel::ProcessPendingMessagesWithMachPorts() {
  MachPortRelay* relay = delegate_->GetMachPortRelay();
  DCHECK(relay);

  base::ProcessHandle remote_process_handle;
  {
    base::AutoLock lock(remote_process_handle_lock_);
    remote_process_handle = remote_process_handle_;
  }
  PendingMessageQueue pending_writes;
  PendingRelayMessageQueue pending_relays;
  {
    base::AutoLock lock(pending_mach_messages_lock_);
    pending_writes.swap(pending_write_messages_);
    pending_relays.swap(pending_relay_messages_);
  }

  while (!pending_writes.empty()) {
    Channel::MessagePtr message = std::move(pending_writes.front());
    pending_writes.pop();
    if (!relay->SendPortsToProcess(message.get(), remote_process_handle)) {
      LOG(ERROR) << "Error on sending mach ports. Remote process is likely "
                 << "gone. Dropping message.";
      return;
    }

    base::AutoLock lock(channel_lock_);
    if (!channel_) {
      DLOG(ERROR) << "Dropping message on closed channel.";
      break;
    } else {
      channel_->Write(std::move(message));
    }
  }

  // Ensure this NodeChannel stays alive while flushing relay messages.
  scoped_refptr<NodeChannel> keepalive = this;

  while (!pending_relays.empty()) {
    ports::NodeName destination = pending_relays.front().first;
    Channel::MessagePtr message = std::move(pending_relays.front().second);
    pending_relays.pop();
    delegate_->OnRelayPortsMessage(remote_node_name_, remote_process_handle,
                                   destination, std::move(message));
  }
}
#endif

void NodeChannel::WriteChannelMessage(Channel::MessagePtr message) {
#if defined(OS_WIN)
  // Map handles to the destination process. Note: only messages from a
  // privileged node should contain handles on Windows. If an unprivileged
  // node needs to send handles, it should do so via RelayPortsMessage which
  // stashes the handles in the message in such a way that they go undetected
  // here (they'll be unpacked and duplicated by a privileged parent.)

  if (message->has_handles()) {
    base::ProcessHandle remote_process_handle;
    {
      base::AutoLock lock(remote_process_handle_lock_);
      remote_process_handle = remote_process_handle_;
    }

    // Rewrite outgoing handles if we have a handle to the destination process.
    if (remote_process_handle != base::kNullProcessHandle) {
      ScopedPlatformHandleVectorPtr handles = message->TakeHandles();
      if (!Channel::Message::RewriteHandles(base::GetCurrentProcessHandle(),
                                            remote_process_handle,
                                            handles.get())) {
        DLOG(ERROR) << "Failed to duplicate one or more outgoing handles.";
      }
      message->SetHandles(std::move(handles));
    }
  }
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  // On OSX, we need to transfer mach ports to the destination process before
  // transferring the message itself.
  if (message->has_mach_ports()) {
    MachPortRelay* relay = delegate_->GetMachPortRelay();
    if (relay) {
      base::ProcessHandle remote_process_handle;
      {
        base::AutoLock lock(remote_process_handle_lock_);
        // Expect that the receiving node is a child.
        DCHECK(remote_process_handle_ != base::kNullProcessHandle);
        remote_process_handle = remote_process_handle_;
      }
      {
        base::AutoLock lock(pending_mach_messages_lock_);
        if (relay->port_provider()->TaskForPid(remote_process_handle) ==
            MACH_PORT_NULL) {
          // It is also possible for TaskForPid() to return MACH_PORT_NULL when
          // the process has started, then died. In that case, the queued
          // message will never be processed. But that's fine since we're about
          // to die anyway.
          pending_write_messages_.push(std::move(message));
          return;
        }
      }

      if (!relay->SendPortsToProcess(message.get(), remote_process_handle)) {
        LOG(ERROR) << "Error on sending mach ports. Remote process is likely "
                   << "gone. Dropping message.";
        return;
      }
    }
  }
#endif

  base::AutoLock lock(channel_lock_);
  if (!channel_)
    DLOG(ERROR) << "Dropping message on closed channel.";
  else
    channel_->Write(std::move(message));
}

}  // namespace edk
}  // namespace mojo
