// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // no-include-guard-because-multiply-included // This file defines the internal messages which can be sent on a NodeLink // between two ipcz nodes. IPCZ_MSG_BEGIN_INTERFACE // Initial greeting sent by a broker node when a ConnectNode() is issued without // the IPCZ_CONNECT_NODE_TO_BROKER flag, implying that the receiving node is a // non-broker. IPCZ_MSG_BEGIN(ConnectFromBrokerToNonBroker, IPCZ_MSG_ID(0)) IPCZ_MSG_BEGIN_VERSION(0) // The name of the broker node. IPCZ_MSG_PARAM(NodeName, … } // Initial greeting sent by a non-broker node when ConnectNode() is invoked with // IPCZ_CONNECT_NODE_TO_BROKER. The sending non-broker node expects to receive a // corresponding ConnectFromBrokerToNonBroker IPCZ_MSG_BEGIN(ConnectFromNonBrokerToBroker, IPCZ_MSG_ID(1)) IPCZ_MSG_BEGIN_VERSION(0) // The highest protocol version known and desired by the sender. IPCZ_MSG_PARAM(uint32_t, … } // Sent from a non-broker to its broker when calling ConnectNode() with // IPCZ_CONNECT_NODE_SHARE_BROKER. In this case the transport given to // ConnectNode() is passed along to the broker via this message, and the broker // assumes the other end of that transport belongs to a new non-broker node who // wishes to join the network. // // The broker performs an initial handshake with the referred node -- it waits // for a ConnectToReferredBroker message on the new transport and then sends a // ConnectToReferredNonBroker over the same transport, as well as a // NonBrokerReferralAccepted message back to the original referrer who sent this // request. // // If this request is invalid or the broker otherwise fails to establish a link // to the referred node, the broker instead responds to the referrer with a // NonBrokerReferralRejected message. IPCZ_MSG_BEGIN(ReferNonBroker, IPCZ_MSG_ID(2)) IPCZ_MSG_BEGIN_VERSION(0) // A unique (for the transmitting NodeLink) identifier for this referral, // used to associate a corresponding NonBrokerReferralAccepted/Rejected // response from the broker. IPCZ_MSG_PARAM(uint64_t, … } // Sent from a non-broker to its tentative broker when calling ConnectNode() // with IPCZ_CONNECT_NODE_INHERIT_BROKER. The other end of the transport given // to that ConnectNode() call must itself be given to ConnectNode() by some // other non-broker calling with IPCZ_CONNECT_NODE_SHARE_BROKER. That other node // will pass the transport to the broker using a ReferNonBroker message. // // Once ConnectToReferredBroker is received by the broker on the new transport, // the broker sends back a ConnectToReferredNonBroker to the sender of this // message, as well as a NonBrokerReferralAccepted message to the original // referrer. IPCZ_MSG_BEGIN(ConnectToReferredBroker, IPCZ_MSG_ID(3)) IPCZ_MSG_BEGIN_VERSION(0) // The highest protocol version known and desired by the sender. IPCZ_MSG_PARAM(uint32_t, … } // Sent from a broker to a referred non-broker node over a transport that was // provided to the broker by some other non-broker via a ReferNonBroker message. // // This is sent to the referred node if and only if the referral has been // accepted by the broker, and only the broker has received a // ConnectToReferredBroker message over the same transport that sends this // message. IPCZ_MSG_BEGIN(ConnectToReferredNonBroker, IPCZ_MSG_ID(4)) IPCZ_MSG_BEGIN_VERSION(0) // The newly assigned name of the node receiving this message. IPCZ_MSG_PARAM(NodeName, … } // Sent from a broker to a non-broker who previously referred another node via // ReferNonBroker. This message indicates that the referral was accepted, and it // provides objects and details necessary for the recipient (i.e. the referrer) // to establish a direct NodeLink to the referred node. IPCZ_MSG_BEGIN(NonBrokerReferralAccepted, IPCZ_MSG_ID(5)) IPCZ_MSG_BEGIN_VERSION(0) // A unique identifier for the referral in question, as provided by the // original ReferNonBroker message sent by the receipient of this message. IPCZ_MSG_PARAM(uint64_t, … } // Sent from a broker to a non-broker who previously referred another node via // ReferNonBroker. This message indicates that the referral was rejected. No // link to the referred node has been established by the broker, and none will // be provided to the referrer. This can occur for example if the referred node // disconnects from the broker before establishing a handshake. IPCZ_MSG_BEGIN(NonBrokerReferralRejected, IPCZ_MSG_ID(6)) IPCZ_MSG_BEGIN_VERSION(0) // A unique identifier for the referral in question, as provided by the // original ReferNonBroker message sent by the receipient of this message. IPCZ_MSG_PARAM(uint64_t, … } // Sent from one broker to another to establish an initial link between two // distinct node networks. Once two brokers are connected their networks are // effectively merged and nodes in either network can become interconnected by // ipcz. IPCZ_MSG_BEGIN(ConnectFromBrokerToBroker, IPCZ_MSG_ID(7)) IPCZ_MSG_BEGIN_VERSION(0) // The name of the sending node. IPCZ_MSG_PARAM(NodeName, … } // Sent to a broker to ask for an introduction to one of the non-broker nodes in // its own network. This may be sent either from a non-broker in the same // network, or a broker from another network. // // The non-broker to be introduced to the sender is identified by `name`. If the // broker is willing and able to comply with this request, it will send an // AcceptIntroduction message (see below) to both the sender of this message and // the node identified by `name`. // // If the broker does not know the node named `name`, it will send only a // RejectIntroduction message back to the sender to indicate failure. IPCZ_MSG_BEGIN(RequestIntroduction, IPCZ_MSG_ID(10)) IPCZ_MSG_BEGIN_VERSION(0) IPCZ_MSG_PARAM(NodeName, … } // Introduces one node to another. Sent only by broker nodes and must only be // accepted from broker nodes. IPCZ_MSG_BEGIN(AcceptIntroduction, IPCZ_MSG_ID(11)) IPCZ_MSG_BEGIN_VERSION(0) // The name of the node being introduced to the recipient of this message. IPCZ_MSG_PARAM(NodeName, … } // Sent to a node in response to RequestIntroduction if the broker receiving // that message did not recognize or otherwise could not introduce the requested // node. IPCZ_MSG_BEGIN(RejectIntroduction, IPCZ_MSG_ID(12)) IPCZ_MSG_BEGIN_VERSION(0) // The name of the node whose introduction cannot be fulfilled. IPCZ_MSG_PARAM(NodeName, … } // Sent from a broker to another broker to request that the receiving broker // introduce a named node in its own network to a named node in the sender's // network. IPCZ_MSG_BEGIN(RequestIndirectIntroduction, IPCZ_MSG_ID(13)) IPCZ_MSG_BEGIN_VERSION(0) // The name of the node to be introduced on the sender's own network. IPCZ_MSG_PARAM(NodeName, … } // Shares a new buffer to support allocation of blocks of `block_size` bytes. // The sender must initialize an appropriate BlockAllocator within the buffer's // memory before sending this message. IPCZ_MSG_BEGIN(AddBlockBuffer, IPCZ_MSG_ID(14)) IPCZ_MSG_BEGIN_VERSION(0) // The ID of the new buffer as allocated by the NodeLinkMemory on the // NodeLink transmitting this message. IPCZ_MSG_PARAM(BufferId, … } // Conveys the contents of a parcel. IPCZ_MSG_BEGIN(AcceptParcel, IPCZ_MSG_ID(20)) IPCZ_MSG_BEGIN_VERSION(0) // The SublinkId linking the source and destination Routers along the // transmitting NodeLink. IPCZ_MSG_PARAM(SublinkId, … } // Conveys partial parcel contents, namely just its attached driver objects. // When a parcel with driver objects cannot be transmitted directly to its // destination, this message is split off and relayed through the broker while // the rest of the parcel contents are sent directly, without the objects // attached. The receiving node can reconstitute the full parcel once both // messages are received. IPCZ_MSG_BEGIN(AcceptParcelDriverObjects, IPCZ_MSG_ID(21)) IPCZ_MSG_BEGIN_VERSION(0) // The SublinkId linking the source and destination Routers along the // transmitting NodeLink. IPCZ_MSG_PARAM(SublinkId, … } // Notifies a node that the route has been closed on one side. This message // always pertains to the side of the route opposite of the router receiving it, // guaranteed by the fact that the closed side of the route only transmits this // message outward once its terminal router is adjacent to the central link. IPCZ_MSG_BEGIN(RouteClosed, IPCZ_MSG_ID(22)) IPCZ_MSG_BEGIN_VERSION(0) // In the context of the receiving NodeLink, this identifies the specific // Router to receive this message. IPCZ_MSG_PARAM(SublinkId, … } // Notifies a specific router that its route from the direction of this link has // been unexpectedly disconnected (e.g. due to a node crashing). This is // essentially the same as route closure but without respect for complete parcel // sequence delivery. IPCZ_MSG_BEGIN(RouteDisconnected, IPCZ_MSG_ID(23)) IPCZ_MSG_BEGIN_VERSION(0) IPCZ_MSG_PARAM(SublinkId, … } // Informs a router that its outward peer can be bypassed. Given routers X and Y // on the central link, and a router Z as Y's inward peer: // // X ==== (central) ==== Y ======== Z // // Once Y successfully locks the central link, Y may send this message to Z // with sufficient information for Z to establish a direct link to X. Z // accomplishes this via an AcceptBypassLink message to X's node. // // Note that this message is only used when X and Y belong to different nodes. // If X and Y belong to the same node, then Y sends Z a BypassPeerWithLink // message instead. IPCZ_MSG_BEGIN(BypassPeer, IPCZ_MSG_ID(30)) IPCZ_MSG_BEGIN_VERSION(0) // Identifies the router to receive this message. IPCZ_MSG_PARAM(SublinkId, … } // Provides a router with a new outward link to replace its existing outward // link to some other node. Given routers X and Y on the central link, and a // router Z as Y's inward peer: // // X ==== (central) ==== Y ======== Z // // Z sends this message to X's node to establish a new direct link to X. Both // X's and Z's existing links to Y are left intact in a decaying state: // // - - - Y - - - // / \ // X === (central) === Z // // The recipient of this message must send a StopProxying message to Y, as well // as a ProxyWillStop message to Z, in order for those decaying links to be // phased out. // // Z must send this message to X only after receiving a BypassPeer request from // Y. That request signifies that X's node has been adequately prepared by Y to // authenticate this request from Z. IPCZ_MSG_BEGIN(AcceptBypassLink, IPCZ_MSG_ID(31)) IPCZ_MSG_BEGIN_VERSION(0) // Identifies the node of the targeted router's own outward peer, as well as // the sublink their nodes use to route between those routers. In the above // scenario these fields identify the link between X and Y to be replaced, // and as a consequence they uniquely identify X itself to the recipient. IPCZ_MSG_PARAM(NodeName, … } // Informs a router about how many more parcels it can expect to receive from // its inward and outward peers before it can stop proxying between them and // cease to exist. Given routers X, Y, and Z in a configuration resulting from // a BypassPeer from Y to Z, followed by an AcceptBypassLink from Z to X: // // - - - Y - - - // / \ // X === (central) === Z // // This message is sent from X to Y to provide the final length of the sequence // of parcels routed through Y in either direction, now that X and Z have // established a direct connection. IPCZ_MSG_BEGIN(StopProxying, IPCZ_MSG_ID(32)) IPCZ_MSG_BEGIN_VERSION(0) // Identifies the router to receive this message. IPCZ_MSG_PARAM(SublinkId, … } // Informs a router about how many more parcels it can expect to receive from // its outward peer. Given routers X, Y, and Z in a configuration resulting from // a BypassPeer from Y to Z, followed by an AcceptBypassLink from Z to X: // // - - - Y - - - // / \ // X === (central) === Z // // This message is sent from X to Z to provide the final length of the sequence // of parcels routed from X to Y (and therefore from Y to Z), now that X and Z // have established a direct connection. IPCZ_MSG_BEGIN(ProxyWillStop, IPCZ_MSG_ID(33)) IPCZ_MSG_BEGIN_VERSION(0) // Identifies the router to receive this message. IPCZ_MSG_PARAM(SublinkId, … } // Informs a router that its outward peer can be bypassed, and provides a new // link with which to execute that bypass. Given the following arrangement where // X, Y, and Z are routers; AND X and Y live on the same node as each other: // // X ==== (central) ==== Y ======== Z // // Y sends this to Z to establish a new link (over the same NodeLink) directly // between Z and X. Both X's and Z's existing links to Y are left intact in a // decaying state: // // - - - Y - - - // / \ // X === (central) === Z // // Note that unlike with BypassPeer/AcceptBypassLink, there is no need to // authenticate this request, as it's only swapping one sublink out for another // along the same NodeLink. IPCZ_MSG_BEGIN(BypassPeerWithLink, IPCZ_MSG_ID(34)) IPCZ_MSG_BEGIN_VERSION(0) // Identifies the router to receive this message. IPCZ_MSG_PARAM(SublinkId, … } // Provides a router with the final length of the sequence of outbound parcels // that will be routed to it via its decaying inward link. Given the following // arrangement where X, Y, and Z are routers; X and Y live on the same node // as each other: and Y has already sent a BypassPeerWithLink message to Z: // // - - - Y - - - // / \ // X === (central) === Z // // This message is sent from Z back to Y, informing Y of the last parcel it can // expect to receive from Z, now that X and Z are connected directly. IPCZ_MSG_BEGIN(StopProxyingToLocalPeer, IPCZ_MSG_ID(35)) IPCZ_MSG_BEGIN_VERSION(0) // Identifies the router to receive this message. IPCZ_MSG_PARAM(SublinkId, … } // Hints to the target router that it should flush its state. Generally sent to // catalyze route reduction or elicit some other state change which was blocked // on some other work being done first by the sender of this message. IPCZ_MSG_BEGIN(FlushRouter, IPCZ_MSG_ID(36)) IPCZ_MSG_BEGIN_VERSION(0) IPCZ_MSG_PARAM(SublinkId, … } // Requests allocation of a shared memory region of a given size. If the // recipient can comply, they will send back a corresponding ProvideMemory // message with a serialized memory region. This message is only sent to a // node's allocation delegate (usually the broker), which is established by // providing the IPCZ_CONNECT_NODE_TO_ALLOCATION_DELEGATE flag to ConnectNode(). IPCZ_MSG_BEGIN(RequestMemory, IPCZ_MSG_ID(64)) IPCZ_MSG_BEGIN_VERSION(0) IPCZ_MSG_PARAM(uint32_t, … } // Provides a new shared buffer to the receiver, owned exclusively by the // receiver. The receiver is free to duplicate this buffer and share it with // other nodes. IPCZ_MSG_BEGIN(ProvideMemory, IPCZ_MSG_ID(65)) IPCZ_MSG_BEGIN_VERSION(0) IPCZ_MSG_PARAM(uint32_t, … } // Sends a message payload to the broker to be relayed to another node. Used to // relay messages which carry driver objects through the broker when they cannot // be transmitted directly between their source and destination nodes. IPCZ_MSG_BEGIN(RelayMessage, IPCZ_MSG_ID(66)) IPCZ_MSG_BEGIN_VERSION(0) // The node to which this message's contents should ultimately be relayed. IPCZ_MSG_PARAM(NodeName, … } // Relays a message payload from an intermediate broker to its destination. This // is the continuation of RelayMessage above. Must only be accepted on a broker. IPCZ_MSG_BEGIN(AcceptRelayedMessage, IPCZ_MSG_ID(67)) IPCZ_MSG_BEGIN_VERSION(0) // The node which originally requested that the broker relay this message. IPCZ_MSG_PARAM(NodeName, … } IPCZ_MSG_END_INTERFACE