@@ -115,21 +115,22 @@ ducts as unique keys. Stop tracking a peer by sending Ames a
116Debug output can be adjusted using `%sift` and `%spew` `$task`'s.
116Debug output can be adjusted using `%sift` and `%spew` `$task`'s.
118−## Packet structure
118+## Packets
120Ames datagram packets are handled as nouns internally by Arvo but as serial data
120Ames datagram packets are handled as nouns internally by Arvo but as serial data
121−by Unix. Here we document their serial structure.
121+by Unix. In this section we describe how packets are formed, serialized, and relayed.
122−For further information, see `+encode-packet` and `+decode-packet` in `ames.hoon`.
122+
124There is a 32-bit header followed by a variable width body.
125There is a 32-bit header followed by a variable width body.
126−### Header
127+#### Header
128The 32-bit header is given by the following data, presented in order:
129The 32-bit header is given by the following data, presented in order:
130 - 3 bits: Ames `protocol-version`,
131 - 3 bits: Ames `protocol-version`,
131 - 20 bits: a checksum as a truncated insecure hash of the body, done with
132 - 20 bits: a checksum as a truncated insecure hash of the body, done with
132− `+mug`,
133+ [`+mug`](@/docs/reference/library/2e.md#mug),
133 - 2 bits: the bit width of the sender address encoded as a 2-bit enum,
134 - 2 bits: the bit width of the sender address encoded as a 2-bit enum,
134 - 2 bits: the bit width of the receiver address encoded as a 2-bit enum,
135 - 2 bits: the bit width of the receiver address encoded as a 2-bit enum,
135 - 1 bit: whether the packet is encrypted or not,
136 - 1 bit: whether the packet is encrypted or not,
@@ -137,7 +138,7 @@ The 32-bit header is given by the following data, presented in order:
138 Every packet sent between ships is encrypted except for self-signed attestation packets from 128-bit comets.
139 Every packet sent between ships is encrypted except for self-signed attestation packets from 128-bit comets.
140−### Body
141+#### Body
142The body is of variable length and consists of three parts in this order:
143The body is of variable length and consists of three parts in this order:
@@ -148,7 +149,7 @@ The body is of variable length and consists of three parts in this order:
148 `origin` is the IP and port of the original sender if the packet was proxied
149 `origin` is the IP and port of the original sender if the packet was proxied
149 through a relay and null otherwise. `content` is a noun that is either an encrypted ack or an
150 through a relay and null otherwise. `content` is a noun that is either an encrypted ack or an
150 encrypted message fragment, unless it is a comet attestation packet in which
151 encrypted message fragment, unless it is a comet attestation packet in which
151− case it is unencrypted.
152+ case it is unencrypted. `content` is always 1kB in size or less.
153 The sender and receiver live outside of the jammed data section to simplify
154 The sender and receiver live outside of the jammed data section to simplify
154 packet filtering for the interpreter.
155 packet filtering for the interpreter.
@@ -165,15 +166,15 @@ which number they are. Finally it encrypts each individual packet and enqueues
165them to be sent along their stated flow.
166them to be sent along their stated flow.
167Network packets aren't always received in order, so this numbering is important
168Network packets aren't always received in order, so this numbering is important
168−for reconstruction, and also pakcets may get lost. So Ames does transmission
169+for reconstruction, and also packets may get lost. So Ames does transmission
169control (the TC in TCP) to solve this problem. It makes sure that all packets
170control (the TC in TCP) to solve this problem. It makes sure that all packets
170−eventually get through, and when the other side gets them is can put them in the
171+eventually get through, and when the other side gets them it can put them in the
171correct order. If Ames doesn't get an ack on a packet then it will resend it
172correct order. If Ames doesn't get an ack on a packet then it will resend it
172until it does. The timing on resending packets is called congestion control and
173until it does. The timing on resending packets is called congestion control and
173works in the same fashion as TCP, namely exponential backoff.
174works in the same fashion as TCP, namely exponential backoff.
175Once all packets are received, the receiving Ames decrypts them, deserializes
176Once all packets are received, the receiving Ames decrypts them, deserializes
176−them, and puts them back together.
177+them, and puts them back together to form a message.
@@ -204,10 +205,6 @@ receipt of those packets are considered to be what makes up a given message.
204Thus a message-level ack must be received before the next message on the flow
205Thus a message-level ack must be received before the next message on the flow
205can begin.
206can begin.
208−+$ ack-meat (each fragment-num [ok=? lag=@dr])
211#### Ack packets
208#### Ack packets
213The contents of a given ack packet are deterministic. The `content` (i.e. the
210The contents of a given ack packet are deterministic. The `content` (i.e. the
@@ -233,6 +230,68 @@ A message ack is an extended fragment ack that is obtained by encrypting the
234[our-life her-life bone message-num fragment-num ok=? lag=@dr]
231[our-life her-life bone message-num fragment-num ok=? lag=@dr]
233+`ok` is a flag that is set to `%.y` for a message ack and `%.n` for a message
234+nack. We defer discussion of nacks. In the future, `lag` will be used to
235+describe the time it took to process a message, but for now it is always zero.
239+Here we describes how the Ames network relays packets. We ignore all details
240+about UDP, which occurs at a lower layer than Ames.
242+When a ship first contacts another ship, it may only know its `@p`, but an IP
243+address and port are necessary for peer-to-peer communication to occur.
244+Thus the initial correspondence between two ships, or additional correspondence
245+following a change in IP or port of one of the parties, will need to be relayed
246+by an intermediary that knows the IP and port of the receiving ship.
248+For now packet relaying is handled entirely by galaxies. Every galaxy is
249+responsible for knowing the IP and port of every planet underneath it. In the
250+future, galaxies will only need to know the star sponsoring a planet, and stars
251+will be responsible for the final step of the relay.
253+The following diagram summarizes the packet creation and forwarding process.
255+<div style="text-align:center">
256+<img src="https://media.urbit.org/docs/arvo/datagram-long.png">
259+We elaborate on the above diagram.
261+A typical relay will look something like this: `~bacbel-tagfeb` wishes to
262+contact `~worwel-sipnum` but does not know the IP address and port at which
263+`~worwel-sipnum` resides. Both planets live under `~zod`, which knows both of
264+their IP and port numbers by virtue of being the galaxy that both live under.
266+So `~bacbel-tagfeb` sends a packet addressed to `~worwel-sipnum` to `~zod`.
268+The packet has the following format:
269+ - The standard Ames header described in [header](#header), where the checksum
270+ is the `+mug` of the body, and the sender and receiver ship types are `01`,
271+ denoting that the sender and receiver are planets. The remainder of the
273+ - The body of this packet will be the `@p` of the
274+sender `~bacbel-tagfeb`, followed by the `@p` of the receiver `~worwel-sipnum`,
275+followed by the payload.
276+ - The payload of this packet will be the `+jam` of `[origin content]`. `origin`
277+for this initial packet will be `~`, which implies that the packet is
278+originating from the sender. `content` is the `+jam` of the message, encrypted
279+using a Diffie-Hellman symmetric key obtained with the private key of
280+`~bacbel-tagfeb` and the public key of `~worwel-sipnum`.
282+`~zod` receives the packet and reads the body. It sees that it is not the
283+intended recipient of the packet, and so gets ready to forward it to
284+`~worwel-sipnum`. First, it [`+cue`s](@/docs/reference/library/2p.md#cue)
285+(deserializes) the payload and changes the `origin` to the IP and port of
286+`~bacbel-tagfeb`. Then it `+jam`s `[origin content]` to form a new payload, and
287+`+mug`s that payload to get a new checksum. It replaces the old payload and
288+checksum with the new, and then sends the packet along to `~worwel-sipnum`.
290+Once `~worwel-sipnum` processes the packet, it will know the IP and port of
291+`~bacbel-tagfeb` since `~zod` included it when it forwarded the packet and so
292+will send an ack packet directly to `~bacbel-tagfeb`. Communication between the
293+two ships will now be direct until one of them changes their IP address, port, or networking keys.
237## A typical successful Ames exchange
296## A typical successful Ames exchange