ames: move various types and gates into lull

So that userspace may also en- and decode (scry) packets.
This commit is contained in:
fang 2022-04-20 00:09:00 +02:00
parent 8731ac191d
commit 12ca0f45e5
No known key found for this signature in database
GPG Key ID: EB035760C1BBA972
2 changed files with 195 additions and 196 deletions

View File

@ -1153,6 +1153,9 @@
++ com |~(a=pass ^?(..nu)) :: from pass
-- ::nu ::
-- ::acru ::
:: +protocol-version: current version of the ames wire protocol
::
++ protocol-version `?(%0 %1 %2 %3 %4 %5 %6 %7)`%0
:: $address: opaque atomic transport address to or from unix
::
+$ address @uxaddress
@ -1194,6 +1197,25 @@
+$ song (list purr) :: full response
::
:: +| %kinetics
:: $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
==
:: $ack: positive ack, nack packet, or nack trace
::
+$ ack
@ -1287,6 +1309,14 @@
siz=@ud
byts
==
+$ peep :: request data
$: =path
num=@ud
==
+$ twit :: signed request
$: signature=@
peep
==
:: $qos: quality of service; how is our connection to a peer doing?
::
:: .last-contact: last time we heard from peer, or if %unborn, when
@ -1465,6 +1495,170 @@
num-received=fragment-num
fragments=(map fragment-num fragment)
==
:: $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)
::
:: +| %coding
:: +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
==
:: +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
:: +decode-packet: deserialize packet from bytestream or crash
::
++ decode-packet
|= =blob
^- [ames=? =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)
::
=/ version (cut 0 [4 3] header)
?. =(protocol-version version)
~& [%ames-protocol-version 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
~| %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-imposter 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-imposter 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-request
|= =hoot
^- twit
:- sig=(cut 3 [0 64] hoot)
-:(decode-request-info (rsh 3^64 hoot))
::
++ decode-request-info
|= =hoot
^- [=peep =purr]
=+ num=(cut 3 [0 4] hoot)
=+ len=(cut 3 [4 2] hoot)
=+ pat=(cut 3 [6 len] hoot)
:- [(stab pat) num]
:: if there is data remaining, it's the response
(rsh [3 (add 6 len)] hoot)
:: +encode-packet: serialize a packet into a bytestream
::
++ encode-packet
|= [ames=? 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=ames]
[3 protocol-version]
[2 rank.sndr-meta]
[2 rank.rcvr-meta]
[20 checksum]
[1 relayed=.?(origin)]
==
(mix header (lsh 5 body))
::
:: +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]
-- ::ames
:: ::::
:::: ++behn :: (1b) timekeeping

View File

@ -90,10 +90,7 @@
:: - sending packets: +on-plea -> +make-peer-core (make a function kind of like +on-memo) -> call +on-pump-send kind of like how +run-message-pump does
:: (assuming as event, scry just stateless)
::
:: protocol-version: current version of the ames wire protocol
::
!:
=/ protocol-version=?(%0 %1 %2 %3 %4 %5 %6 %7) %0
=, ames
=* point point:jael
=* public-keys-result public-keys-result:jael
@ -253,53 +250,6 @@
=. 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
|= [ames=? 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=ames]
[3 protocol-version]
[2 rank.sndr-meta]
[2 rank.rcvr-meta]
[20 checksum]
[1 relayed=.?(origin)]
==
(mix header (lsh 5 body))
::
++ decode-request
|= =hoot
^- twit
:- sig=(cut 3 [0 64] hoot)
-:(decode-request-info (rsh 3^64 hoot))
::
++ decode-request-info
|= =hoot
^- [=peep =purr]
=+ num=(cut 3 [0 4] hoot)
=+ len=(cut 3 [4 2] hoot)
=+ pat=(cut 3 [6 len] hoot)
:- [(stab pat) num]
:: if there is data remaining, it's the response
(rsh [3 (add 6 len)] hoot)
::
++ decode-response-packet
|= =purr
@ -326,74 +276,6 @@
?~ dat ~
~| [%fine %response-not-cask]
;;((cask) (cue dat))
:: +decode-packet: deserialize packet from bytestream or crash
::
++ decode-packet
|= =blob
^- [ames=? =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)
::
=/ 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
|= [=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
:: +welt: like +weld but first argument is reversed
:: TODO: move to hoon.hoon
++ welt
@ -486,52 +368,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
|= 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]
+| %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)
+$ byuts [wid=@ud dat=@ux]
::
+| %kinetics
@ -553,25 +393,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
@ -687,22 +508,6 @@
--
--
::
+$ twit :: signed request
$: signature=@
peep
==
::
+$ peep :: request data
$: =path
num=@ud
==
::
+$ rawr :: response packet ::TODO meow
$: sig=@
siz=@ud
byts
==
::
+$ roar :: response message
$: sig=@
dat=$@(~ (cask))
@ -1286,7 +1091,7 @@
--
:: |per-event: inner event-handling core
::
~% %per-event ..decode-packet ~
~% %per-event ..trace ~
|%
++ per-event
=| moves=(list move)