chromium/mojo/core/channel.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "mojo/core/channel.h"

#include <stddef.h>
#include <string.h>

#include <cstdint>
#include <limits>
#include <utility>

#include "base/check_op.h"
#include "base/functional/overloaded.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_math.h"
#include "base/process/current_process.h"
#include "base/process/process_handle.h"
#include "base/ranges/algorithm.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/trace_event/typed_macros.h"
#include "build/build_config.h"
#include "mojo/core/configuration.h"
#include "mojo/core/embedder/features.h"

#if BUILDFLAG(MOJO_USE_APPLE_CHANNEL)
#include "base/apple/mach_logging.h"
#elif BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#endif

#if BUILDFLAG(IS_ANDROID)
#include "mojo/core/channel_binder.h"
#endif

namespace mojo::core {

namespace {

std::atomic_bool g_use_trivial_messages{};

// TODO(crbug.com/40824727): Consider asking the memory allocator for a suitable
// size.
constexpr int kGrowthFactor =;

static_assert;

static_assert;

static_assert;

static_assert;
static_assert;

const size_t kReadBufferSize =;
const size_t kMaxUnusedReadBufferCapacity =;

// TODO(rockot): Increase this if/when Channel implementations support more.
// Linux: The platform imposes a limit of 253 handles per sendmsg().
// Fuchsia: The zx_channel_write() API supports up to 64 handles.
const size_t kMaxAttachedHandles =;

static_assert;
Channel::AlignedBuffer MakeAlignedBuffer(size_t size) {}

struct TrivialMessage;

// The type of message always used by a Channel which backs an ipcz transport.
// Most of the inherited Message interface is unused since it's only called by
// the original Mojo Core implementation.
struct IpczMessage : public Channel::Message {};

// A complex message can be large or contain file handles.
struct ComplexMessage : public Channel::Message {};

struct TrivialMessage : public Channel::Message {};

static_assert;

}  // namespace

// static
Channel::MessagePtr Channel::Message::CreateMessage(size_t payload_size,
                                                    size_t max_handles) {}

// static
Channel::MessagePtr Channel::Message::CreateMessage(size_t payload_size,
                                                    size_t max_handles,
                                                    MessageType message_type) {}

// static
Channel::MessagePtr Channel::Message::CreateMessage(size_t capacity,
                                                    size_t payload_size,
                                                    size_t max_handles) {}

// static
Channel::MessagePtr Channel::Message::CreateMessage(size_t capacity,
                                                    size_t payload_size,
                                                    size_t max_handles,
                                                    MessageType message_type) {}

// static
Channel::MessagePtr Channel::Message::CreateIpczMessage(
    base::span<const uint8_t> data,
    std::vector<PlatformHandle> handles) {}

// static
void Channel::set_use_trivial_messages(bool use_trivial_messages) {}

// static
Channel::MessagePtr Channel::Message::CreateRawForFuzzing(
    base::span<const unsigned char> data) {}

// static
Channel::MessagePtr Channel::Message::Deserialize(
    const void* data,
    size_t data_num_bytes,
    HandlePolicy handle_policy,
    base::ProcessHandle from_process) {}

// static
void Channel::Message::ExtendPayload(MessagePtr& message,
                                     size_t new_payload_size) {}

const void* Channel::Message::extra_header() const {}

void* Channel::Message::mutable_extra_header() {}

size_t Channel::Message::extra_header_size() const {}

void* Channel::Message::mutable_payload() {}

const void* Channel::Message::payload() const {}

size_t Channel::Message::payload_size() const {}

size_t Channel::Message::num_handles() const {}

bool Channel::Message::has_handles() const {}

bool Channel::Message::is_legacy_message() const {}

Channel::Message::LegacyHeader* Channel::Message::legacy_header() const {}

Channel::Message::Header* Channel::Message::header() const {}

ComplexMessage::ComplexMessage(size_t capacity,
                               size_t payload_size,
                               size_t max_handles,
                               MessageType message_type)
    :{}

size_t ComplexMessage::capacity() const {}

bool ComplexMessage::ExtendPayload(size_t new_payload_size) {}

void ComplexMessage::SetHandles(std::vector<PlatformHandle> new_handles) {}

void ComplexMessage::SetHandles(
    std::vector<PlatformHandleInTransit> new_handles) {}

std::vector<PlatformHandleInTransit> ComplexMessage::TakeHandles() {}

size_t ComplexMessage::NumHandlesForTransit() const {}

// static
Channel::MessagePtr TrivialMessage::TryConstruct(size_t payload_size,
                                                 MessageType message_type) {}

size_t TrivialMessage::capacity() const {}

bool TrivialMessage::ExtendPayload(size_t new_payload_size) {}

void TrivialMessage::SetHandles(std::vector<PlatformHandle> new_handles) {}

void TrivialMessage::SetHandles(
    std::vector<PlatformHandleInTransit> new_handles) {}

std::vector<PlatformHandleInTransit> TrivialMessage::TakeHandles() {}

size_t TrivialMessage::NumHandlesForTransit() const {}

// Helper class for managing a Channel's read buffer allocations. This maintains
// a single contiguous buffer with the layout:
//
//   [discarded bytes][occupied bytes][unoccupied bytes]
//
// The Reserve() method ensures that a certain capacity of unoccupied bytes are
// available. It does not claim that capacity and only allocates new capacity
// when strictly necessary.
//
// Claim() marks unoccupied bytes as occupied.
//
// Discard() marks occupied bytes as discarded, signifying that their contents
// can be forgotten or overwritten.
//
// Realign() moves occupied bytes to the front of the buffer so that those
// occupied bytes are properly aligned.
//
// The most common Channel behavior in practice should result in very few
// allocations and copies, as memory is claimed and discarded shortly after
// being reserved, and future reservations will immediately reuse discarded
// memory.
class Channel::ReadBuffer {};

bool Channel::Delegate::IsIpczTransport() const {}

void Channel::Delegate::OnChannelDestroyed() {}

Channel::Channel(Delegate* delegate,
                 HandlePolicy handle_policy,
                 DispatchBufferPolicy buffer_policy)
    :{}

Channel::~Channel() {}

// static
scoped_refptr<Channel> Channel::CreateForIpczDriver(
    Delegate* delegate,
    PlatformChannelEndpoint endpoint,
    scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {}

void Channel::ShutDown() {}

char* Channel::GetReadBuffer(size_t* buffer_capacity) {}

bool Channel::OnReadComplete(size_t bytes_read, size_t* next_read_size_hint) {}

Channel::DispatchResult Channel::TryDispatchMessage(
    base::span<const char> buffer,
    size_t* size_hint) {}

Channel::DispatchResult Channel::TryDispatchMessage(
    base::span<const char> buffer,
    std::optional<std::vector<PlatformHandle>> received_handles,
    size_t* size_hint) {}

void Channel::OnError(Error error) {}

bool Channel::OnControlMessage(Message::MessageType message_type,
                               const void* payload,
                               size_t payload_size,
                               std::vector<PlatformHandle> handles) {}

// static
void Channel::LogHistogramForIPCMetrics(MessageType type) {}

// Currently only Non-nacl CrOs, Linux, and Android support upgrades.
#if BUILDFLAG(IS_NACL) || (!(BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || \
                             BUILDFLAG(IS_ANDROID)))
// static
MOJO_SYSTEM_IMPL_EXPORT bool Channel::SupportsChannelUpgrade() {
  return false;
}

MOJO_SYSTEM_IMPL_EXPORT void Channel::OfferChannelUpgrade() {
  NOTREACHED();
}
#endif

bool Channel::ShouldRecordSubsampledHistograms() {}

}  // namespace mojo::core