#include "ipcz/router.h"
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <optional>
#include <utility>
#include "ipcz/ipcz.h"
#include "ipcz/local_router_link.h"
#include "ipcz/node_link.h"
#include "ipcz/parcel_wrapper.h"
#include "ipcz/remote_router_link.h"
#include "ipcz/sequence_number.h"
#include "ipcz/trap_event_dispatcher.h"
#include "third_party/abseil-cpp/absl/base/macros.h"
#include "third_party/abseil-cpp/absl/container/inlined_vector.h"
#include "third_party/abseil-cpp/absl/synchronization/mutex.h"
#include "util/log.h"
#include "util/multi_mutex_lock.h"
#include "util/safe_math.h"
namespace ipcz {
namespace {
struct ParcelToFlush { … };
ParcelsToFlush;
void CollectParcelsToFlush(ParcelQueue& queue,
const RouteEdge& edge,
ParcelsToFlush& parcels) { … }
bool ValidateAndAcquireObjectsForTransitFrom(
Router& sender,
absl::Span<const IpczHandle> handles,
std::vector<Ref<APIObject>>& objects) { … }
}
Router::Router() = default;
Router::~Router() { … }
Router::Pair Router::CreatePair() { … }
IpczResult Router::Close() { … }
bool Router::CanSendFrom(Router& sender) { … }
bool Router::IsPeerClosed() { … }
bool Router::IsRouteDead() { … }
bool Router::IsOnCentralRemoteLink() { … }
void Router::QueryStatus(IpczPortalStatus& status) { … }
bool Router::HasLocalPeer(Router& router) { … }
std::unique_ptr<Parcel> Router::AllocateOutboundParcel(size_t num_bytes,
bool allow_partial) { … }
IpczResult Router::SendOutboundParcel(std::unique_ptr<Parcel> parcel) { … }
void Router::CloseRoute() { … }
void Router::SetOutwardLink(Ref<RouterLink> link) { … }
bool Router::AcceptInboundParcel(std::unique_ptr<Parcel> parcel) { … }
bool Router::AcceptOutboundParcel(std::unique_ptr<Parcel> parcel) { … }
bool Router::AcceptRouteClosureFrom(LinkType link_type,
SequenceNumber sequence_length) { … }
bool Router::AcceptRouteDisconnectedFrom(LinkType link_type) { … }
IpczResult Router::Put(absl::Span<const uint8_t> data,
absl::Span<const IpczHandle> handles) { … }
IpczResult Router::BeginPut(IpczBeginPutFlags flags,
volatile void** data,
size_t* num_bytes,
IpczTransaction* transaction) { … }
IpczResult Router::EndPut(IpczTransaction transaction,
size_t num_bytes_produced,
absl::Span<const IpczHandle> handles,
IpczEndPutFlags flags) { … }
IpczResult Router::Get(IpczGetFlags flags,
void* data,
size_t* num_bytes,
IpczHandle* handles,
size_t* num_handles,
IpczHandle* parcel) { … }
IpczResult Router::BeginGet(IpczBeginGetFlags flags,
const volatile void** data,
size_t* num_bytes,
IpczHandle* handles,
size_t* num_handles,
IpczTransaction* transaction) { … }
IpczResult Router::EndGet(IpczTransaction transaction,
IpczEndGetFlags flags,
IpczHandle* parcel_handle) { … }
IpczResult Router::Trap(const IpczTrapConditions& conditions,
IpczTrapEventHandler handler,
uint64_t context,
IpczTrapConditionFlags* satisfied_condition_flags,
IpczPortalStatus* status) { … }
IpczResult Router::MergeRoute(const Ref<Router>& other) { … }
Ref<Router> Router::Deserialize(const RouterDescriptor& descriptor,
NodeLink& from_node_link) { … }
void Router::SerializeNewRouter(NodeLink& to_node_link,
RouterDescriptor& descriptor) { … }
bool Router::SerializeNewRouterWithLocalPeer(NodeLink& to_node_link,
RouterDescriptor& descriptor,
Ref<Router> local_peer) { … }
void Router::SerializeNewRouterAndConfigureProxy(
NodeLink& to_node_link,
RouterDescriptor& descriptor,
bool initiate_proxy_bypass) { … }
void Router::BeginProxyingToNewRouter(NodeLink& to_node_link,
const RouterDescriptor& descriptor) { … }
bool Router::BypassPeer(RemoteRouterLink& requestor,
const NodeName& bypass_target_node,
SublinkId bypass_target_sublink) { … }
bool Router::AcceptBypassLink(
NodeLink& new_node_link,
SublinkId new_sublink,
FragmentRef<RouterLinkState> new_link_state,
SequenceNumber inbound_sequence_length_from_bypassed_link) { … }
bool Router::StopProxying(SequenceNumber inbound_sequence_length,
SequenceNumber outbound_sequence_length) { … }
bool Router::NotifyProxyWillStop(SequenceNumber inbound_sequence_length) { … }
bool Router::StopProxyingToLocalPeer(SequenceNumber outbound_sequence_length) { … }
void Router::NotifyLinkDisconnected(RemoteRouterLink& link) { … }
void Router::Flush(FlushBehavior behavior) { … }
bool Router::MaybeStartSelfBypass() { … }
bool Router::StartSelfBypassToLocalPeer(
Router& local_outward_peer,
RemoteRouterLink& inward_link,
FragmentRef<RouterLinkState> new_link_state) { … }
void Router::MaybeStartBridgeBypass() { … }
void Router::StartBridgeBypassFromLocalPeer(
FragmentRef<RouterLinkState> link_state) { … }
bool Router::BypassPeerWithNewRemoteLink(
RemoteRouterLink& requestor,
NodeLink& node_link,
SublinkId bypass_target_sublink,
FragmentRef<RouterLinkState> new_link_state) { … }
bool Router::BypassPeerWithNewLocalLink(RemoteRouterLink& requestor,
SublinkId bypass_target_sublink) { … }
std::unique_ptr<Parcel> Router::TakeNextInboundParcel(
TrapEventDispatcher& dispatcher) { … }
}