ames: merge driver rework

This commit is contained in:
Ted Blackman 2022-05-27 14:52:30 -05:00
commit 062fbc71d7
4 changed files with 1074 additions and 996 deletions

View File

@ -1196,7 +1196,7 @@
::
+$ hoot @uxhoot :: request packet
+$ purr @uxpurr :: response packet
+$ song (list purr) :: full response
+$ hunk [lop=@ len=@] :: range specifier
::
:: +| %kinetics
:: $dyad: pair of sender and receiver ships
@ -1211,8 +1211,13 @@
:: address. Routes are opaque to Arvo and only have meaning in the
:: interpreter. This enforces that Ames is transport-agnostic.
::
:: req: is a request
:: sam: is using the ames protocol (not fine or another protocol)
::
+$ packet
$: dyad
req=?
sam=?
sndr-tick=@ubC
rcvr-tick=@ubC
origin=(unit @uxaddress)
@ -1306,9 +1311,9 @@
==
+$ have
$: fra=@ud
rawr
meow
==
+$ rawr :: response packet ::TODO meow
+$ meow :: response packet
$: sig=@
siz=@ud
byts
@ -1542,16 +1547,16 @@
::
++ decode-packet
|= =blob
^- [ames=? =packet]
^- 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
:: read header; first two bits are reserved
::
=/ is-ames (cut 0 [3 1] header)
:- =(& is-ames)
=/ req =(& (cut 0 [2 1] header))
=/ sam =(& (cut 0 [3 1] header))
::
=/ version (cut 0 [4 3] header)
?. =(protocol-version version)
@ -1597,7 +1602,7 @@
:: 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]
[[sndr rcvr] req sam sndr-tick rcvr-tick origin content]
::
++ decode-request
|= =hoot
@ -1611,13 +1616,14 @@
=+ num=(cut 3 [0 4] hoot)
=+ len=(cut 3 [4 2] hoot)
=+ pat=(cut 3 [6 len] hoot)
~| pat=pat
:- [(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]
|= packet
^- blob
::
=/ sndr-meta (encode-ship-metadata sndr)
@ -1636,8 +1642,9 @@
::
=/ header=@
%+ can 0
:~ [3 reserved=0]
[1 is-ames=ames]
:~ [2 reserved=0]
[1 req]
[1 sam]
[3 protocol-version]
[2 rank.sndr-meta]
[2 rank.rcvr-meta]

View File

@ -269,9 +269,9 @@
::
++ decode-response-packet
|= =purr
=; =rawr
~? !=(wid.rawr (met 3 dat.rawr)) [%fine %unexpected-dat-size]
rawr
=; =meow
~? !=(wid.meow (met 3 dat.meow)) [%fine %unexpected-dat-size]
meow
:* sig=(cut 3 [0 64] purr)
siz=(cut 3 [64 4] purr)
wid=(cut 3 [68 2] purr)
@ -308,6 +308,7 @@
|= [pac=open-packet =acru:ames]
^- packet
:* [sndr rcvr]:pac
req=& sam=&
(mod sndr-life.pac 16)
(mod rcvr-life.pac 16)
origin=~
@ -367,8 +368,15 @@
=/ vec ~[sndr rcvr sndr-life rcvr-life]
=/ [siv=@uxH len=@ cyf=@ux]
(~(en sivc:aes:crypto (shaz symmetric-key) vec) (jam shut-packet))
=/ content :(mix siv (lsh 7 len) (lsh [3 18] cyf))
[[sndr rcvr] (mod sndr-life 16) (mod rcvr-life 16) origin=~ content]
::
:* ^= dyad [sndr rcvr]
^= req ?=(%& -.meat.shut-packet)
^= sam &
^= sndr-tick (mod sndr-life 16)
^= sndr-tick (mod rcvr-life 16)
^= origin ~
^= content :(mix siv (lsh 7 len) (lsh [3 18] cyf))
==
:: +decode-shut-packet: decrypt a $shut-packet from a $packet
::
++ decode-shut-packet
@ -1113,6 +1121,7 @@
:: /ax/fine/message/[path/...] song
::
?. ?=(%x ren) ~
=> .(tyl `(pole knot)`tyl)
?+ tyl ~
[%protocol %version ~]
``noun+!>(protocol-version)
@ -1122,11 +1131,11 @@
!> ^- (map ship ?(%alien %known))
(~(run by peers.ames-state) head)
::
[%peers @ *]
=/ who (slaw %p i.t.tyl)
[%peers her=@ req=*]
=/ who (slaw %p her.tyl)
?~ who [~ ~]
=/ peer (~(get by peers.ames-state) u.who)
?+ t.t.tyl [~ ~]
?+ req.tyl [~ ~]
~
?~ peer
[~ ~]
@ -1164,8 +1173,8 @@
$(peer next)
==
::
[%bones @ ~]
=/ who (slaw %p i.t.tyl)
[%bones her=@ ~]
=/ who (slaw %p her.tyl)
?~ who [~ ~]
=/ per (~(get by peers.ames-state) u.who)
?. ?=([~ %known *] per) [~ ~]
@ -1174,10 +1183,10 @@
[snd=~(key by snd) rcv=~(key by rcv)]
``noun+!>(res)
::
[%snd-bones @ @ ~]
=/ who (slaw %p i.t.tyl)
[%snd-bones her=@ bon=@ ~]
=/ who (slaw %p her.tyl)
?~ who [~ ~]
=/ ost (slaw %ud i.t.t.tyl)
=/ ost (slaw %ud bon.tyl)
?~ ost [~ ~]
=/ per (~(get by peers.ames-state) u.who)
?. ?=([~ %known *] per) [~ ~]
@ -1187,14 +1196,12 @@
u.mps
``noun+!>(!>(res))
::
[%fine %message @ *]
[%fine %hunk lop=@t len=@t pax=^]
::TODO separate endpoint for the full message (instead of packet list)
:: t.t.tyl is expected to be a scry path of the shape /vc/desk/rev/etc,
:: .pax is expected to be a scry path of the shape /vc/desk/rev/etc,
:: so we need to give it the right shape
::
=* path t.t.tyl
~| path
?~ blk=(de-path-soft:balk path) ~
?~ blk=(de-path-soft:balk pax.tyl) ~
=+ nom=(en-roof:balk u.blk)
~| nom
:: we only support scrying into clay,
@ -1208,12 +1215,13 @@
=+ per=!<([r=dict:clay w=dict:clay] q.u.u.pem)
?. =([%black ~ ~] rul.r.per) ~
=+ res=(rof lyc nom)
=/ =hunk [(slav %ud lop.tyl) (slav %ud len.tyl)]
::TODO suggests we need to factor differently
=+ ven=(per-event [now 0v0 rof] *duct ames-state)
=/ fin fine:(per-event [now 0v0 rof] *duct ames-state)
?- res
~ ~
[~ ~] ``noun+!>((encode-response:fine:ven path ~))
[~ ~ *] ``noun+!>((encode-response:fine:ven path [p q.q]:u.u.res))
[~ ~] ``noun+!>((encode-hunk:fin pax.tyl hunk ~))
[~ ~ *] ``noun+!>((encode-hunk:fin pax.tyl hunk [p q.q]:u.u.res))
==
==
--
@ -1436,11 +1444,10 @@
++ on-hear
|= [l=lane b=blob d=(unit goof)]
^+ event-core
=/ [ames=? =packet]
(decode-packet b)
?: ames
=/ =packet (decode-packet b)
?: sam.packet
(on-hear-packet l packet d)
?. response==(& (cut 0 [2 1] b))
?: req.packet
~|([%fine %request-events-forbidden] !!)
(on-hear-response:fine l packet d)
:: +on-hear-packet: handle mildly processed packet receipt
@ -1485,7 +1492,7 @@
~| ames-lane-size+p.lane !!
`p.lane
::
=/ =blob (encode-packet & packet)
=/ =blob (encode-packet packet)
(send-blob & rcvr.packet blob)
:: +on-hear-open: handle receipt of plaintext comet self-attestation
::
@ -2105,7 +2112,7 @@
++ attestation-packet
|= [her=ship =her=life]
^- blob
%+ encode-packet &
%- encode-packet
%- encode-open-packet
:_ crypto-core.ames-state
:* ^= public-key pub:ex:crypto-core.ames-state
@ -2122,7 +2129,7 @@
|= her=ship
^- blob
?> ?=(%pawn (clan:title her))
%+ encode-packet &
%- encode-packet
%- encode-shut-packet
:* ^= shut-packet *shut-packet
^= symmetric-key *symmetric-key
@ -2394,7 +2401,7 @@
::
=. event-core
%^ send-blob | her.channel
%+ encode-packet &
%- encode-packet
%: encode-shut-packet
shut-packet(bone (mix 1 bone.shut-packet))
symmetric-key.channel
@ -2643,12 +2650,9 @@
|= [=path =^duct]
?: (~(has by order.scry) path)
ke-abet:(ke-sub:(ke-abed:keen-core path) duct)
=/ keen-id=@ud seq.scry
=. seq.scry +(seq.scry)
=. order.scry
(~(put by order.scry) path keen-id)
=| =keen-state
=. keens.scry (put:orm keens.scry keen-id keen-state)
=^ keen-id=@ud seq.scry [seq.scry +(seq.scry)]
=. order.scry (~(put by order.scry) path keen-id)
=. keens.scry (put:orm keens.scry keen-id *keen-state)
ke-abet:(ke-start:(ke-abed:keen-core path) duct)
::
++ pe-pine
@ -2848,18 +2852,18 @@
$(listeners t.listeners)
::
++ ke-first-rcv
|= =rawr
|= =meow
^+ ke-core
=- ke-core(keen -)
::
=/ paz=(list want)
%+ turn (gulf 1 siz.rawr)
%+ turn (gulf 1 siz.meow)
|= fra=@ud
^- want
[fra (ke-encode-req fra) now 0 0]
::
%_ keen
num-fragments siz.rawr
num-fragments siz.meow
nex (tail paz)
==
:: +ke-continue: send packets according to normal congestion flow
@ -2915,28 +2919,28 @@
++ ke-rcv
|= [fra=@ud =purr =lane:ames]
^+ ke-core
=/ =rawr (decode-response-packet purr)
=/ =meow (decode-response-packet purr)
=/ og ke-core
=. pe-core (pe-update-qos %live last-contact=now)
:: handle empty
?: =(0 siz.rawr)
?> =(~ dat.rawr)
(ke-done sig.rawr ~)
?: =(0 siz.meow)
?> =(~ dat.meow)
(ke-done sig.meow ~)
:: update congestion, or fill details
::
=? ke-core =(0 num-fragments.keen)
?> =(fra 1)
(ke-first-rcv rawr)
(ke-first-rcv meow)
::
~| failed-signature/fra^`@ux`sig.rawr
~| failed-signature/fra^`@ux`sig.meow
~| life.peer
?> (veri-fra:keys ship life.peer ke-full-path fra [dat sig]:rawr)
?> (veri-fra:keys ship life.peer ke-full-path fra [dat sig]:meow)
=^ found=? ke-core
(ke-on-ack fra)
::
?. found
(ke-fast-retransmit:og fra)
=/ =have [fra rawr]
=/ =have [fra meow]
=. hav.keen
`(list ^have)`[have hav.keen]
=. num-received.keen +(num-received.keen)
@ -3067,9 +3071,11 @@
=+ !<(=cass:clay q.u.u.cag)
(emit duct %give %boon `*`ud.cass)
==
::
++ on-keen
|= [=ship =path]
^+ event-core
=+ ~:(spit path) :: assert length
=/ peer-core (pe-abed:fine-peer ship)
?^ peer-core pe-abet:(pe-keen:u.peer-core path duct)
%+ enqueue-alien-todo ship
@ -3127,7 +3133,7 @@
num=@ud
==
::
+$ rawr :: response packet ::TODO meow
+$ meow :: response packet
$: sig=@
siz=@ud
byts
@ -3138,81 +3144,74 @@
dat=$@(~ (cask))
==
++ orm ((on @ud keen-state) lte)
:: +gum: glue together a list of $byts into one
::
:: TODO: move to hoon.hoon
::
++ gum
~/ %gum
|= biz=(list byts)
^- byts
:- (roll biz |=([[wid=@ *] acc=@] (add wid acc)))
(can 3 biz)
::
++ spit
|= =path
^- [pat=@t wid=@ud]
=+ pat=(spat path)
=+ wid=(met 3 pat)
?> (lte wid 384) ::TODO check when we handle %keen, in addition to here
?> (lte wid 384)
[pat wid]
::
++ request-body
|= [=path num=@ud]
::NOTE path is expected to be a namespace path without the ship
^- byts
?> (lth num (bex 32))
=+ (spit path)
:- :(add 4 2 wid)
%+ can 3
%- gum
:~ 4^num :: fragment number
2^wid :: path size
wid^`@`pat :: namespace path
==
::
++ frag-body
|= [=path mes=@ num=@ud]
^- @uxmeow
=/ tot (met 13 mes)
=/ fra (cut 13 [(dec num) 1] mes)
=/ wid (met 3 fra)
%+ can 3
:~ 64^(sign-fra:keys path num fra)
4^tot :: number of fragments
2^wid :: response data fragment size in bytes
wid^fra :: response data fragment
==
::
++ encode-request
|= [=ship =path num=@ud]
::NOTE path is expected to be a namespace path without the ship
^- hoot ^- @
=+ bod=(request-body path num)
=+ sig=64^(sign:keys dat.bod)
=+ syn=(can 3 sig bod ~)
%+ con 0b100 ::NOTE request bit
%^ encode-packet |
[our ship]
[(mod life.ames-state 16) (mod (lyfe:keys ship) 16) ~ syn]
=/ sic (mod life.ames-state 16)
=/ ric (mod (lyfe:keys ship) 16)
=/ syn
=/ bod (request-body path num)
=/ sig 64^(sign:keys dat.bod)
(can 3 sig bod ~)
(encode-packet [our ship] req=& sam=| sic ric ~ syn)
::
++ encode-response ::TODO unit tests
|= [=path data=$@(~ (cask))]
^- song
:: prepend request descriptions to each response packet
::
=; pacs=(list @ux)
%- head
%^ spin pacs 1
|= [pac=@ux num=@ud]
^- [purr _num]
:_ +(num)
^- @ux
::NOTE we stub out the receiver & origin details,
:: runtime should replace them as appropriate.
(encode-packet | [our ~zod] (mod life.ames-state 16) 0b0 ~ pac)
:: prepend a signature and split the data into 1024-byte fragments
::
=/ frag=(list @)
++ encode-hunk ::TODO unit tests
|= [=path =hunk data=$@(~ (cask))]
^- (list @uxmeow)
=/ mes=@
=/ sig=@ (full:keys path data)
?~ data [sig]~
%+ rip response-size ::NOTE 1024 bytes
(cat 9 sig (jam data)) ::TODO should include life
:: sign & packetize the fragments
?~ data sig
(cat 9 sig (jam data))
::
%- head
%^ spin frag 1
|= [dat=@ num=@ud]
:_ +(num)
^- @ux
=/ req=byts (request-body path num)
=/ bod=byts
=/ wid=@ud (met 3 dat)
:- :(add 4 2 wid)
%+ can 3
:~ 4^(lent frag) :: number of fragments
2^wid :: response data fragment size in bytes
wid^dat :: response data fragment
==
=/ sig=byts
64^(sign-fra:keys path num dat)
(can 3 req sig bod ~)
=/ top +((min (met 13 mes) (add [lop len]:hunk)))
=/ num lop.hunk
=| res=(list @uxmeow)
|- ^+ res
?: =(num top) (flop res)
$(num +(num), res :_(res (frag-body path mes num)))
::
++ keys
|%

View File

@ -25,7 +25,6 @@
} u3_prel;
typedef struct _u3_body {
u3_prel pre_u; // prelude
c3_s con_s; // content size
c3_y* con_y; // content
c3_l mug_l; // checksum
@ -61,52 +60,53 @@ _test_ames(void)
}
}
static void
_test_sift_etch()
{
u3_head* hed_u = c3_calloc(sizeof(*hed_u));
u3_body* bod_u = c3_calloc(sizeof(*bod_u));
//TODO: rewrite with more types: purr, wail, body,etc.
//static void
//_test_sift_etch()
//{
// u3_head* hed_u = c3_calloc(sizeof(*hed_u));
// u3_body* bod_u = c3_calloc(sizeof(*bod_u));
//
// hed_u->sim_o = c3y;
// hed_u->ver_y = 1;
// hed_u->sac_y = 4;
// hed_u->rac_y = 4;
// hed_u->rel_o = c3n;
//
// bod_u->pre_u.sen_d[0] = 0;
// bod_u->pre_u.sen_d[1] = 0;
// bod_u->pre_u.rec_d[0] = 182;
// bod_u->pre_u.rec_d[1] = 0;
//
// c3_y* str = (c3_y*)"test";
//
// bod_u->con_y = str;
// bod_u->con_s = 5;
//
// c3_y** out_y;
//
// c3_w pac_w = _ames_etch_pack(hed_u, bod_u, out_y);
//
// u3_head* nhed_u = c3_calloc(sizeof(*nhed_u));
// u3_body* nbod_u = c3_calloc(sizeof(*nbod_u));
// _ames_sift_head(nhed_u, *out_y);
// *out_y += 4;
// c3_y_ames_sift_body(nbod_u, *out_y);
//
// if( 0 != memcmp(hed_u, nhed_u, sizeof(*hed_u))) {
// fprintf(stderr, "ames: header serialisation mismatch(a)\r\n");
// exit(1);
// }
// if( 0 != memcmp(bod_u, nbod_u, sizeof(*bod_u))) {
// fprintf(stderr, "ames: body serialisation fail(a)\r\n");
// exit(1);
// } else {
// fprintf(stderr, "ames: pass (a)\r\n");
// exit(1);
// }
//
//}
hed_u->sim_o = c3y;
hed_u->ver_y = 1;
hed_u->sac_y = 4;
hed_u->rac_y = 4;
hed_u->rel_o = c3n;
bod_u->pre_u.sen_d[0] = 0;
bod_u->pre_u.sen_d[1] = 0;
bod_u->pre_u.rec_d[0] = 182;
bod_u->pre_u.rec_d[1] = 0;
c3_y* str = (c3_y*)"test";
bod_u->con_y = str;
bod_u->con_s = 5;
c3_y** out_y;
//TODO fix me!
// c3_w pac_w = _ames_etch_pack(hed_u, bod_u, out_y);
// u3_head* nhed_u = c3_calloc(sizeof(*nhed_u));
// u3_body* nbod_u = c3_calloc(sizeof(*nbod_u));
// _ames_sift_head(nhed_u, *out_y);
// *out_y += 4;
// c3_y_ames_sift_body(nbod_u, *out_y);
// if( 0 != memcmp(hed_u, nhed_u, sizeof(*hed_u))) {
// fprintf(stderr, "ames: header serialisation mismatch(a)\r\n");
// exit(1);
// }
// if( 0 != memcmp(bod_u, nbod_u, sizeof(*bod_u))) {
// fprintf(stderr, "ames: body serialisation fail(a)\r\n");
// exit(1);
// } else {
// fprintf(stderr, "ames: pass (a)\r\n");
// exit(1);
// }
}
/* main(): run all test cases.
*/
int

File diff suppressed because it is too large Load Diff