Our networking protocol.

Ames is the name of both our network and the vane that communicates over it. When Unix receives a packet over the correct UDP port, it pipes it straight into Ames for handling. Also, all packets sent over the Ames network are sent by the Ames vane. Apps and vanes may use Ames to directly send messages to other ships. In general, apps use Gall and Clay to communicate with other ships rather than using Ames directly, but this isn't a requirement. Of course, Gall and Clay use Ames behind the scenes to communicate across the network. Jael is the only other vane to utilize Ames.

Ames includes several significant components. Although the actual crypto algorithms are defined in zuse, they're used extensively in Ames for encrypting and decrypting packets. Congestion control and routing is handled entirely in Ames. Finally, the actual Ames protocol itself, including how to route incoming packets to the correct vane or app, is defined in Ames.

Technical Overview

Ames extends Arvo's %pass/%give move semantics across the network.

Ames receives packets as Arvo events and emits packets as Arvo effects. The runtime is responsible for transferring the bytes in an Ames packet across a physical network to another ship.

The runtime tells Ames which physical address a packet came from, represented as an opaque atom. Ames can emit a packet effect to one of those opaque atoms or to the Urbit address of a galaxy (root node), which the runtime is responsible for translating to a physical address. One runtime implementation sends UDP packets using IPv4 addresses for ships and DNS lookups for galaxies, but other implementations may overlay over other kinds of networks.

A local vane can pass Ames a %plea request message. Ames transmits the message over the wire to the peer ship's Ames, which passes the message to the destination vane.

Once the peer has processed the %plea message, it sends a message-acknowledgment packet over the wire back to the local Ames. This "ack" can either be positive to indicate the request was processed, or negative to indicate the request failed, in which case it's called a "nack". (Don't confuse Ames nacks with TCP nacks, which are a different concept).

When the local Ames receives either a positive message-ack or a combination of a nack and "naxplanation" (explained in more detail below), it gives an %done move to the local vane that had requested the original %plea message be sent.

A local vane can give Ames zero or more %boon response messages in response to a %plea, on the same duct that Ames used to pass the %plea to the vane. Ames transmits a %boon over the wire to the peer's Ames, which gives it to the destination vane on the same duct the vane had used to pass the original %plea to Ames.

%boon messages are acked automatically by the receiver Ames. They cannot be nacked, and Ames only uses the ack internally, without notifying the client vane that gave Ames the %boon.

If the Arvo event that completed receipt of a %boon message crashes, Ames instead sends the client vane a %lost message indicating the %boon was missed.

%plea messages can be nacked, in which case the peer will send both a message-nack packet and a naxplanation message, which is sent in a way that does not interfere with normal operation. The naxplanation is sent as a full Ames message, instead of just a packet, because the contained error information can be arbitrarily large. A naxplanation can only give rise to a positive ack -- never ack an ack, and never nack a naxplanation.

Ames guarantees a total ordering of messages within a "flow", identified in other vanes by a duct and over the wire by a "bone": an opaque number. Each flow has a FIFO (first-in-first-out) queue of %plea requests from the requesting ship to the responding ship and a FIFO queue of %boon's in the other direction.

Message order across flows is not specified and may vary based on network conditions.

Ames guarantees that a message will only be delivered once to the destination vane.

Ames encrypts every message using symmetric-key encryption by performing an elliptic curve Diffie-Hellman using our private key and the public key of the peer. For ships in the Jael PKI (public-key infrastructure), Ames looks up the peer's public key from Jael. Comets (128-bit ephemeral addresses) are not cryptographic assets and must self-attest over Ames by sending a single self-signed packet containing their public key.

When a peer suffers a continuity breach, Ames removes all messaging state related to it. Ames does not guarantee that all messages will be fully delivered to the now-stale peer. From Ames's perspective, the newly restarted peer is a new ship. Ames's guarantees are not maintained across a breach.

A vane can pass Ames a %heed $task to request Ames track a peer's responsiveness. If our %boon's to it start backing up locally, Ames will give a %clog back to the requesting vane containing the unresponsive peer's urbit address. This interaction does not use ducts as unique keys. Stop tracking a peer by sending Ames a %jilt $task.

Debug output can be adjusted using %sift and %spew $task's.