mirror of
https://github.com/urbit/shrub.git
synced 2024-12-18 15:55:00 +03:00
ames: move packet en/decoding into lull
By moving this behavior for packets with ames-style headers into lull, other vanes that want to do protocols in similar style (like the upcoming %fine vane) can reuse the logic here. Note that we parameterize the main en- and decoding functions, so that we may pass in the "is ames" flag and protocol versions as appropriate to the context.
This commit is contained in:
parent
3cb3421657
commit
dd4eb87f42
@ -434,6 +434,9 @@
|
||||
:: $blob: raw atom to or from unix, representing a packet
|
||||
::
|
||||
+$ blob @uxblob
|
||||
:: $protocol-version: 3-bit protocol version
|
||||
::
|
||||
+$ protocol-version ?(%0 %1 %2 %3 %4 %5 %6 %7)
|
||||
:: $error: tagged diagnostic trace
|
||||
::
|
||||
+$ error [tag=@tas =tang]
|
||||
@ -702,7 +705,171 @@
|
||||
num-received=fragment-num
|
||||
fragments=(map fragment-num fragment)
|
||||
==
|
||||
:: |packets: ames-style packet en- and decoding
|
||||
::
|
||||
:: $dyad: pair of sender and receiver ships
|
||||
::
|
||||
+$ dyad [sndr=ship rcvr=ship]
|
||||
:: $rank: which kind of ship address, by length
|
||||
::
|
||||
:: 0b0: galaxy or star -- 2 bytes
|
||||
:: 0b1: planet -- 4 bytes
|
||||
:: 0b10: moon -- 8 bytes
|
||||
:: 0b11: comet -- 16 bytes
|
||||
::
|
||||
+$ rank ?(%0b0 %0b1 %0b10 %0b11)
|
||||
:: $packet: noun representation of an ames datagram packet
|
||||
::
|
||||
:: Roundtrips losslessly through atom encoding and decoding.
|
||||
::
|
||||
:: .origin is ~ unless the packet is being forwarded. If present,
|
||||
:: it's an atom that encodes a route to another ship, such as an IPv4
|
||||
:: address. Routes are opaque to Arvo and only have meaning in the
|
||||
:: interpreter. This enforces that Ames is transport-agnostic.
|
||||
::
|
||||
+$ packet
|
||||
$: dyad
|
||||
sndr-tick=@ubC
|
||||
rcvr-tick=@ubC
|
||||
origin=(unit @uxaddress)
|
||||
content=@uxcontent
|
||||
==
|
||||
:: +encode-packet: serialize a packet into a bytestream
|
||||
::
|
||||
++ encode-packet
|
||||
|= [ames=? =protocol-version]
|
||||
|= packet
|
||||
^- blob
|
||||
::
|
||||
=/ sndr-meta (encode-ship-metadata sndr)
|
||||
=/ rcvr-meta (encode-ship-metadata rcvr)
|
||||
::
|
||||
=/ body=@
|
||||
;: mix
|
||||
sndr-tick
|
||||
(lsh 2 rcvr-tick)
|
||||
(lsh 3 sndr)
|
||||
(lsh [3 +(size.sndr-meta)] rcvr)
|
||||
(lsh [3 +((add size.sndr-meta size.rcvr-meta))] content)
|
||||
==
|
||||
=/ checksum (end [0 20] (mug body))
|
||||
=? body ?=(^ origin) (mix u.origin (lsh [3 6] body))
|
||||
::
|
||||
=/ header=@
|
||||
%+ can 0
|
||||
:~ [3 reserved=0]
|
||||
[1 is-ames=&]
|
||||
[3 protocol-version]
|
||||
[2 rank.sndr-meta]
|
||||
[2 rank.rcvr-meta]
|
||||
[20 checksum]
|
||||
[1 relayed=.?(origin)]
|
||||
==
|
||||
(mix header (lsh 5 body))
|
||||
:: +decode-packet: deserialize packet from bytestream or crash
|
||||
::
|
||||
++ decode-packet
|
||||
|= [ames=? =protocol-version]
|
||||
|= =blob
|
||||
^- packet
|
||||
~| %decode-packet-fail
|
||||
:: first 32 (2^5) bits are header; the rest is body
|
||||
::
|
||||
=/ header (end 5 blob)
|
||||
=/ body (rsh 5 blob)
|
||||
:: read header; first three bits are reserved
|
||||
::
|
||||
=/ is-ames (cut 0 [3 1] header)
|
||||
?. =(ames is-ames)
|
||||
~| ?:(ames %ames-not-ames %fine-not-fine) !!
|
||||
::
|
||||
=/ version (cut 0 [4 3] header)
|
||||
?. =(protocol-version version)
|
||||
~| ames-protocol-version+version !!
|
||||
::
|
||||
=/ sndr-size (decode-ship-size (cut 0 [7 2] header))
|
||||
=/ rcvr-size (decode-ship-size (cut 0 [9 2] header))
|
||||
=/ checksum (cut 0 [11 20] header)
|
||||
=/ relayed (cut 0 [31 1] header)
|
||||
:: origin, if present, is 6 octets long, at the end of the body
|
||||
::
|
||||
=^ origin=(unit @) body
|
||||
?: =(| relayed)
|
||||
[~ body]
|
||||
=/ len (sub (met 3 body) 6)
|
||||
[`(end [3 6] body) (rsh [3 6] body)]
|
||||
:: .checksum does not apply to the origin
|
||||
::
|
||||
?. =(checksum (end [0 20] (mug body)))
|
||||
~| %ames-checksum !!
|
||||
:: read fixed-length sndr and rcvr life data from body
|
||||
::
|
||||
:: These represent the last four bits of the sender and receiver
|
||||
:: life fields, to be used for quick dropping of honest packets to
|
||||
:: or from the wrong life.
|
||||
::
|
||||
=/ sndr-tick (cut 0 [0 4] body)
|
||||
=/ rcvr-tick (cut 0 [4 4] body)
|
||||
:: read variable-length .sndr and .rcvr addresses
|
||||
::
|
||||
=/ off 1
|
||||
=^ sndr off [(cut 3 [off sndr-size] body) (add off sndr-size)]
|
||||
?. (is-valid-rank sndr sndr-size)
|
||||
~| ames-sender-impostor+[sndr sndr-size] !!
|
||||
::
|
||||
=^ rcvr off [(cut 3 [off rcvr-size] body) (add off rcvr-size)]
|
||||
?. (is-valid-rank rcvr rcvr-size)
|
||||
~| ames-receiver-impostor+[rcvr rcvr-size] !!
|
||||
:: read variable-length .content from the rest of .body
|
||||
::
|
||||
=/ content (cut 3 [off (sub (met 3 body) off)] body)
|
||||
[[sndr rcvr] sndr-tick rcvr-tick origin content]
|
||||
:: +decode-ship-size: decode a 2-bit ship type specifier into a byte width
|
||||
::
|
||||
:: Type 0: galaxy or star -- 2 bytes
|
||||
:: Type 1: planet -- 4 bytes
|
||||
:: Type 2: moon -- 8 bytes
|
||||
:: Type 3: comet -- 16 bytes
|
||||
::
|
||||
++ decode-ship-size
|
||||
|= rank=@ubC
|
||||
^- @
|
||||
::
|
||||
?+ rank !!
|
||||
%0b0 2
|
||||
%0b1 4
|
||||
%0b10 8
|
||||
%0b11 16
|
||||
==
|
||||
:: +encode-ship-metadata: produce size (in bytes) and address rank for .ship
|
||||
::
|
||||
:: 0: galaxy or star
|
||||
:: 1: planet
|
||||
:: 2: moon
|
||||
:: 3: comet
|
||||
::
|
||||
++ encode-ship-metadata
|
||||
|= =ship
|
||||
^- [size=@ =rank]
|
||||
::
|
||||
=/ size=@ (met 3 ship)
|
||||
::
|
||||
?: (lte size 2) [2 %0b0]
|
||||
?: (lte size 4) [4 %0b1]
|
||||
?: (lte size 8) [8 %0b10]
|
||||
[16 %0b11]
|
||||
:: +is-valid-rank: does .ship match its stated .size?
|
||||
::
|
||||
++ is-valid-rank
|
||||
|= [=ship size=@ubC]
|
||||
^- ?
|
||||
.= size
|
||||
=/ wid (met 3 ship)
|
||||
?: (lte wid 1) 2
|
||||
?: =(2 wid) 2
|
||||
?: (lte wid 4) 4
|
||||
?: (lte wid 8) 8
|
||||
?> (lte wid 16) 16
|
||||
-- ::ames
|
||||
:: ::::
|
||||
:::: ++behn :: (1b) timekeeping
|
||||
|
@ -88,8 +88,8 @@
|
||||
:: protocol-version: current version of the ames wire protocol
|
||||
::
|
||||
!:
|
||||
=/ protocol-version=?(%0 %1 %2 %3 %4 %5 %6 %7) %0
|
||||
=, ames
|
||||
=/ =protocol-version %0
|
||||
=* point point:jael
|
||||
=* public-keys-result public-keys-result:jael
|
||||
:: veb: verbosity flags
|
||||
@ -248,110 +248,9 @@
|
||||
=. private-key (rsh 8 (rsh 3 private-key))
|
||||
::
|
||||
`@`(shar:ed:crypto public-key private-key)
|
||||
:: +encode-packet: serialize a packet into a bytestream
|
||||
::
|
||||
++ encode-packet
|
||||
~/ %encode-packet
|
||||
|= packet
|
||||
^- blob
|
||||
::
|
||||
=/ sndr-meta (encode-ship-metadata sndr)
|
||||
=/ rcvr-meta (encode-ship-metadata rcvr)
|
||||
::
|
||||
=/ body=@
|
||||
;: mix
|
||||
sndr-tick
|
||||
(lsh 2 rcvr-tick)
|
||||
(lsh 3 sndr)
|
||||
(lsh [3 +(size.sndr-meta)] rcvr)
|
||||
(lsh [3 +((add size.sndr-meta size.rcvr-meta))] content)
|
||||
==
|
||||
=/ checksum (end [0 20] (mug body))
|
||||
=? body ?=(^ origin) (mix u.origin (lsh [3 6] body))
|
||||
::
|
||||
=/ header=@
|
||||
%+ can 0
|
||||
:~ [3 reserved=0]
|
||||
[1 is-ames=&]
|
||||
[3 protocol-version]
|
||||
[2 rank.sndr-meta]
|
||||
[2 rank.rcvr-meta]
|
||||
[20 checksum]
|
||||
[1 relayed=.?(origin)]
|
||||
==
|
||||
(mix header (lsh 5 body))
|
||||
:: +decode-packet: deserialize packet from bytestream or crash
|
||||
::
|
||||
++ decode-packet
|
||||
~/ %decode-packet
|
||||
|= =blob
|
||||
^- packet
|
||||
~| %decode-packet-fail
|
||||
:: first 32 (2^5) bits are header; the rest is body
|
||||
::
|
||||
=/ header (end 5 blob)
|
||||
=/ body (rsh 5 blob)
|
||||
:: read header; first three bits are reserved
|
||||
::
|
||||
=/ is-ames (cut 0 [3 1] header)
|
||||
?. =(& is-ames)
|
||||
~| %ames-not-ames !!
|
||||
::
|
||||
=/ version (cut 0 [4 3] header)
|
||||
?. =(protocol-version version)
|
||||
~| ames-protocol-version+version !!
|
||||
::
|
||||
=/ sndr-size (decode-ship-size (cut 0 [7 2] header))
|
||||
=/ rcvr-size (decode-ship-size (cut 0 [9 2] header))
|
||||
=/ checksum (cut 0 [11 20] header)
|
||||
=/ relayed (cut 0 [31 1] header)
|
||||
:: origin, if present, is 6 octets long, at the end of the body
|
||||
::
|
||||
=^ origin=(unit @) body
|
||||
?: =(| relayed)
|
||||
[~ body]
|
||||
=/ len (sub (met 3 body) 6)
|
||||
[`(end [3 6] body) (rsh [3 6] body)]
|
||||
:: .checksum does not apply to the origin
|
||||
::
|
||||
?. =(checksum (end [0 20] (mug body)))
|
||||
~| %ames-checksum !!
|
||||
:: read fixed-length sndr and rcvr life data from body
|
||||
::
|
||||
:: These represent the last four bits of the sender and receiver
|
||||
:: life fields, to be used for quick dropping of honest packets to
|
||||
:: or from the wrong life.
|
||||
::
|
||||
=/ sndr-tick (cut 0 [0 4] body)
|
||||
=/ rcvr-tick (cut 0 [4 4] body)
|
||||
:: read variable-length .sndr and .rcvr addresses
|
||||
::
|
||||
=/ off 1
|
||||
=^ sndr off [(cut 3 [off sndr-size] body) (add off sndr-size)]
|
||||
?. (is-valid-rank sndr sndr-size)
|
||||
~| ames-sender-impostor+[sndr sndr-size] !!
|
||||
::
|
||||
=^ rcvr off [(cut 3 [off rcvr-size] body) (add off rcvr-size)]
|
||||
?. (is-valid-rank rcvr rcvr-size)
|
||||
~| ames-receiver-impostor+[rcvr rcvr-size] !!
|
||||
:: read variable-length .content from the rest of .body
|
||||
::
|
||||
=/ content (cut 3 [off (sub (met 3 body) off)] body)
|
||||
[[sndr rcvr] sndr-tick rcvr-tick origin content]
|
||||
:: +is-valid-rank: does .ship match its stated .size?
|
||||
::
|
||||
++ is-valid-rank
|
||||
~/ %is-valid-rank
|
||||
|= [=ship size=@ubC]
|
||||
^- ?
|
||||
.= size
|
||||
?- (clan:title ship)
|
||||
%czar 2
|
||||
%king 2
|
||||
%duke 4
|
||||
%earl 8
|
||||
%pawn 16
|
||||
==
|
||||
++ encode-packet (^encode-packet & protocol-version)
|
||||
++ decode-packet (^decode-packet & protocol-version)
|
||||
:: +encode-open-packet: convert $open-packet attestation to $packet
|
||||
::
|
||||
++ encode-open-packet
|
||||
@ -437,54 +336,10 @@
|
||||
=/ vec ~[sndr.packet rcvr.packet sndr-life rcvr-life]
|
||||
;; shut-packet %- cue %- need
|
||||
(~(de sivc:aes:crypto (shaz symmetric-key) vec) siv len cyf)
|
||||
:: +decode-ship-size: decode a 2-bit ship type specifier into a byte width
|
||||
::
|
||||
:: Type 0: galaxy or star -- 2 bytes
|
||||
:: Type 1: planet -- 4 bytes
|
||||
:: Type 2: moon -- 8 bytes
|
||||
:: Type 3: comet -- 16 bytes
|
||||
::
|
||||
++ decode-ship-size
|
||||
~/ %decode-ship-size
|
||||
|= rank=@ubC
|
||||
^- @
|
||||
::
|
||||
?+ rank !!
|
||||
%0b0 2
|
||||
%0b1 4
|
||||
%0b10 8
|
||||
%0b11 16
|
||||
==
|
||||
:: +encode-ship-metadata: produce size (in bytes) and address rank for .ship
|
||||
::
|
||||
:: 0: galaxy or star
|
||||
:: 1: planet
|
||||
:: 2: moon
|
||||
:: 3: comet
|
||||
::
|
||||
++ encode-ship-metadata
|
||||
~/ %encode-ship-metadata
|
||||
|= =ship
|
||||
^- [size=@ =rank]
|
||||
::
|
||||
=/ size=@ (met 3 ship)
|
||||
::
|
||||
?: (lte size 2) [2 %0b0]
|
||||
?: (lte size 4) [4 %0b1]
|
||||
?: (lte size 8) [8 %0b10]
|
||||
[16 %0b11]
|
||||
+| %atomics
|
||||
::
|
||||
+$ private-key @uwprivatekey
|
||||
+$ signature @uwsignature
|
||||
:: $rank: which kind of ship address, by length
|
||||
::
|
||||
:: 0b0: galaxy or star -- 2 bytes
|
||||
:: 0b1: planet -- 4 bytes
|
||||
:: 0b10: moon -- 8 bytes
|
||||
:: 0b11: comet -- 16 bytes
|
||||
::
|
||||
+$ rank ?(%0b0 %0b1 %0b10 %0b11)
|
||||
::
|
||||
+| %kinetics
|
||||
:: $channel: combined sender and receiver identifying data
|
||||
@ -505,25 +360,6 @@
|
||||
=her=public-key
|
||||
her-sponsor=ship
|
||||
== ==
|
||||
:: $dyad: pair of sender and receiver ships
|
||||
::
|
||||
+$ dyad [sndr=ship rcvr=ship]
|
||||
:: $packet: noun representation of an ames datagram packet
|
||||
::
|
||||
:: Roundtrips losslessly through atom encoding and decoding.
|
||||
::
|
||||
:: .origin is ~ unless the packet is being forwarded. If present,
|
||||
:: it's an atom that encodes a route to another ship, such as an IPv4
|
||||
:: address. Routes are opaque to Arvo and only have meaning in the
|
||||
:: interpreter. This enforces that Ames is transport-agnostic.
|
||||
::
|
||||
+$ packet
|
||||
$: dyad
|
||||
sndr-tick=@ubC
|
||||
rcvr-tick=@ubC
|
||||
origin=(unit @uxaddress)
|
||||
content=@uxcontent
|
||||
==
|
||||
:: $open-packet: unencrypted packet payload, for comet self-attestation
|
||||
::
|
||||
:: This data structure gets signed and jammed to form the .contents
|
||||
@ -1081,7 +917,7 @@
|
||||
--
|
||||
:: |per-event: inner event-handling core
|
||||
::
|
||||
~% %per-event ..decode-packet ~
|
||||
~% %per-event ..trace ~
|
||||
|%
|
||||
++ per-event
|
||||
=| moves=(list move)
|
||||
|
Loading…
Reference in New Issue
Block a user