From dd4eb87f4224769e5c85ee61f00a54430f2bfcf2 Mon Sep 17 00:00:00 2001 From: fang Date: Thu, 20 Jan 2022 01:59:43 +0100 Subject: [PATCH] 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. --- pkg/arvo/sys/lull.hoon | 167 ++++++++++++++++++++++++++++++++++ pkg/arvo/sys/vane/ames.hoon | 172 +----------------------------------- 2 files changed, 171 insertions(+), 168 deletions(-) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 379f6f14ba..f0de981af9 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -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 diff --git a/pkg/arvo/sys/vane/ames.hoon b/pkg/arvo/sys/vane/ames.hoon index 41742600b3..baf1b813e9 100644 --- a/pkg/arvo/sys/vane/ames.hoon +++ b/pkg/arvo/sys/vane/ames.hoon @@ -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)