diff --git a/bin/ropsten-ivory.pill b/bin/ropsten-ivory.pill new file mode 100644 index 000000000..5f3e6dc8d --- /dev/null +++ b/bin/ropsten-ivory.pill @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:666fb799fb714579e17a919cc81e8e28c178e9dbb6af7bc01cd9593aad7adf37 +size 2336718 diff --git a/bin/ropsten-solid.pill b/bin/ropsten-solid.pill new file mode 100644 index 000000000..b76b5e215 --- /dev/null +++ b/bin/ropsten-solid.pill @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74f8043eec22ecea43294fb4c41bd0006aa5c382ca41e4e84476692f44edf6cd +size 6826461 diff --git a/pkg/arvo/app/azimuth/version-0.azimuth-snapshot b/pkg/arvo/app/azimuth/version-0.azimuth-snapshot index a664ca92f..1d05e2943 100644 Binary files a/pkg/arvo/app/azimuth/version-0.azimuth-snapshot and b/pkg/arvo/app/azimuth/version-0.azimuth-snapshot differ diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index eb4d1b41b..059df859e 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1202,7 +1202,7 @@ :: $dyad: pair of sender and receiver ships :: +$ dyad [sndr=ship rcvr=ship] - :: $packet: noun representation of an ames datagram packet + :: $shot: noun representation of an ames datagram packet :: :: Roundtrips losslessly through atom encoding and decoding. :: @@ -1214,7 +1214,7 @@ :: req: is a request :: sam: is using the ames protocol (not fine or another protocol) :: - +$ packet + +$ shot $: dyad req=? sam=? @@ -1314,18 +1314,23 @@ meow == +$ meow :: response packet - $: sig=@ - siz=@ud - byts + $: sig=@ux :: signature + num=@ud :: number of fragments + siz=@ud :: official size of this fragment + dat=@ux :: contents == +$ peep :: request data $: =path num=@ud == - +$ twit :: signed request + +$ keen :: signed request $: signature=@ peep == + +$ roar :: response message + $: sig=@ + dat=$@(~ (cask)) + == :: $qos: quality of service; how is our connection to a peer doing? :: :: .last-contact: last time we heard from peer, or if %unborn, when @@ -1514,14 +1519,14 @@ +$ rank ?(%0b0 %0b1 %0b10 %0b11) :: :: +| %coding - :: +decode-ship-size: decode a 2-bit ship type specifier into a byte width + :: +sift-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 + ++ sift-ship-size |= rank=@ubC ^- @ :: @@ -1543,12 +1548,12 @@ ?: (lte wid 4) 4 ?: (lte wid 8) 8 ?> (lte wid 16) 16 - :: +decode-packet: deserialize packet from bytestream or crash + :: +sift-shot: deserialize packet from bytestream or crash :: - ++ decode-packet + ++ sift-shot |= =blob - ^- packet - ~| %decode-packet-fail + ^- shot + ~| %sift-shot-fail :: first 32 (2^5) bits are header; the rest is body :: =/ header (end 5 blob) @@ -1563,8 +1568,8 @@ ~& [%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)) + =/ sndr-size (sift-ship-size (cut 0 [7 2] header)) + =/ rcvr-size (sift-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 @@ -1604,29 +1609,46 @@ =/ content (cut 3 [off (sub (met 3 body) off)] body) [[sndr rcvr] req sam sndr-tick rcvr-tick origin content] :: - ++ decode-request + ++ sift-keen |= =hoot - ^- twit - :- sig=(cut 3 [0 64] hoot) - -:(decode-request-info (rsh 3^64 hoot)) + ^- keen + :- sig=(end 9 hoot) + +:(sift-peep (rsh 9 hoot)) :: - ++ decode-request-info + ++ sift-purr |= =hoot - ^- [=peep =purr] + ^- [=peep =meow] + =+ [wid peep]=(sift-peep hoot) + [peep (sift-meow (rsh [3 wid] hoot))] + :: + ++ sift-peep + |= =hoot + ^- [wid=@ =peep] =+ 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 + ~| pat=pat + [(add 6 len) [(stab pat) num]] :: - ++ encode-packet - |= packet + ++ sift-meow + |= =purr + =; =meow + ~| %fine-meow-len^meow + ?> (gte siz.meow (met 3 dat.meow)) + meow + :* sig=(cut 3 [0 64] purr) + num=(cut 3 [64 4] purr) + siz=(cut 3 [68 2] purr) + dat=(rsh 3^70 purr) + == + :: +etch-shot: serialize a packet into a bytestream + :: + ++ etch-shot + |= shot ^- blob :: - =/ sndr-meta (encode-ship-metadata sndr) - =/ rcvr-meta (encode-ship-metadata rcvr) + =/ sndr-meta (ship-meta sndr) + =/ rcvr-meta (ship-meta rcvr) :: =/ body=@ ;: mix @@ -1652,14 +1674,14 @@ == (mix header (lsh 5 body)) :: - :: +encode-ship-metadata: produce size (in bytes) and address rank for .ship + :: +ship-meta: produce size (in bytes) and address rank for .ship :: :: 0: galaxy or star :: 1: planet :: 2: moon :: 3: comet :: - ++ encode-ship-metadata + ++ ship-meta |= =ship ^- [size=@ =rank] :: diff --git a/pkg/arvo/sys/vane/ames.hoon b/pkg/arvo/sys/vane/ames.hoon index 4131f1e39..20a47721b 100644 --- a/pkg/arvo/sys/vane/ames.hoon +++ b/pkg/arvo/sys/vane/ames.hoon @@ -267,28 +267,20 @@ :: `@`(shar:ed:crypto public-key private-key) :: -++ decode-response-packet - |= =purr - =; =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) - dat=(rsh 3^70 purr) - == ++ response-size 13 :: 1kb +:: +sift-roar: assemble scry response fragments into full message :: -++ decode-response-msg +++ sift-roar |= [total=@ud hav=(list have)] ^- roar - =/ mess=@ + =/ mes=@ %+ rep response-size %+ turn (flop hav) |= =have dat.have - :- sig=(cut 3 [0 64] mess) - =+ dat=(rsh 3^64 mess) + =+ sig=(end 9 mes) + :- sig + =+ dat=(rsh 9 mes) ?~ dat ~ ~| [%fine %response-not-cask] ;;((cask) (cue dat)) @@ -301,12 +293,12 @@ |- ^+ b ?~ a b $(a t.a, b [i.a b]) -:: +encode-open-packet: convert $open-packet attestation to $packet +:: +etch-open-packet: convert $open-packet attestation to $shot :: -++ encode-open-packet - ~/ %encode-open-packet +++ etch-open-packet + ~/ %etch-open-packet |= [pac=open-packet =acru:ames] - ^- packet + ^- shot :* [sndr rcvr]:pac req=& sam=& (mod sndr-life.pac 16) @@ -314,37 +306,37 @@ origin=~ content=`@`(sign:as:acru (jam pac)) == -:: +decode-open-packet: decode comet attestation into an $open-packet +:: +sift-open-packet: decode comet attestation into an $open-packet :: -++ decode-open-packet - ~/ %decode-open-packet - |= [=packet our=ship our-life=@] +++ sift-open-packet + ~/ %sift-open-packet + |= [=shot our=ship our-life=@] ^- open-packet :: deserialize and type-check packet contents :: - =+ ;; [signature=@ signed=@] (cue content.packet) + =+ ;; [signature=@ signed=@] (cue content.shot) =+ ;; =open-packet (cue signed) :: assert .our and .her and lives match :: - ?> .= sndr.open-packet sndr.packet + ?> .= sndr.open-packet sndr.shot ?> .= rcvr.open-packet our ?> .= sndr-life.open-packet 1 ?> .= rcvr-life.open-packet our-life :: only a star can sponsor a comet :: - ?> =(%king (clan:title (^sein:title sndr.packet))) + ?> =(%king (clan:title (^sein:title sndr.shot))) =/ crub (com:nu:crub:crypto public-key.open-packet) :: comet public-key must hash to its @p address :: - ?> =(sndr.packet fig:ex:crub) + ?> =(sndr.shot fig:ex:crub) :: verify signature :: ?> (safe:as:crub signature signed) open-packet -:: +encode-shut-packet: encrypt and packetize a $shut-packet +:: +etch-shut-packet: encrypt and packetize a $shut-packet :: -++ encode-shut-packet - ~/ %encode-shut-packet +++ etch-shut-packet + ~/ %etch-shut-packet :: TODO add rift to signed messages to prevent replay attacks? :: |= $: =shut-packet @@ -354,7 +346,7 @@ sndr-life=@ rcvr-life=@ == - ^- packet + ^- shot :: =? meat.shut-packet ?& ?=(%& -.meat.shut-packet) @@ -377,21 +369,21 @@ ^= origin ~ ^= content :(mix siv (lsh 7 len) (lsh [3 18] cyf)) == -:: +decode-shut-packet: decrypt a $shut-packet from a $packet +:: +sift-shut-packet: decrypt a $shut-packet from a $shot :: -++ decode-shut-packet - ~/ %decode-shut-packet - |= [=packet =symmetric-key sndr-life=@ rcvr-life=@] +++ sift-shut-packet + ~/ %sift-shut-packet + |= [=shot =symmetric-key sndr-life=@ rcvr-life=@] ^- shut-packet - ?. =(sndr-tick.packet (mod sndr-life 16)) - ~| ames-sndr-tick+sndr-tick.packet !! - ?. =(rcvr-tick.packet (mod rcvr-life 16)) - ~| ames-rcvr-tick+rcvr-tick.packet !! - =/ siv (end 7 content.packet) - =/ len (end 4 (rsh 7 content.packet)) - =/ cyf (rsh [3 18] content.packet) - ~| ames-decrypt+[[sndr rcvr origin]:packet len siv] - =/ vec ~[sndr.packet rcvr.packet sndr-life rcvr-life] + ?. =(sndr-tick.shot (mod sndr-life 16)) + ~| ames-sndr-tick+sndr-tick.shot !! + ?. =(rcvr-tick.shot (mod rcvr-life 16)) + ~| ames-rcvr-tick+rcvr-tick.shot !! + =/ siv (end 7 content.shot) + =/ len (end 4 (rsh 7 content.shot)) + =/ cyf (rsh [3 18] content.shot) + ~| ames-decrypt+[[sndr rcvr origin]:shot len siv] + =/ vec ~[sndr.shot rcvr.shot sndr-life rcvr-life] ;; shut-packet %- cue %- need (~(de sivc:aes:crypto (shaz symmetric-key) vec) siv len cyf) +| %atomics @@ -569,18 +561,6 @@ ++ com |~(a=pass ^?(..nu)) -- -- -:: -+$ roar :: response message - $: sig=@ - dat=$@(~ (cask)) - == -:: $partial-fine: partial remote scry response -:: -+$ partial-fine - $: num-fragments=@ud - num-received=@ud - fragments=(map @ud byts) ::TODO not byts, always 1024 bytes, just @ - == :: $bug: debug printing configuration :: :: veb: verbosity toggles @@ -1118,7 +1098,7 @@ :: /ax/peers/[ship]/forward-lane (list lane) :: /ax/bones/[ship] [snd=(set bone) rcv=(set bone)] :: /ax/snd-bones/[ship]/[bone] vase - :: /ax/fine/message/[path/...] song + :: /ax/fine/hunk/[path/...] (list @ux) scry response fragments :: ?. ?=(%x ren) ~ => .(tyl `(pole knot)`tyl) @@ -1153,10 +1133,16 @@ :: :^ ~ ~ %noun !> ^- (list lane) - ?. ?& ?=([~ %known *] peer) - !=(our u.who) - == + ?: =(our u.who) ~ + ?. ?=([~ %known *] peer) + =/ sax (rof ~ %j `beam`[[our %saxo %da now] /(scot %p u.who)]) + ?. ?=([~ ~ *] sax) + ~ + =/ gal (rear ;;((list ship) q.q.u.u.sax)) + ?: =(our gal) + ~ + [%& gal]~ =; zar=(trap (list lane)) ?~ route.u.peer $:zar =* rot u.route.u.peer @@ -1220,8 +1206,8 @@ =/ fin fine:(per-event [now 0v0 rof] *duct ames-state) ?- res ~ ~ - [~ ~] ``noun+!>((encode-hunk:fin pax.tyl hunk ~)) - [~ ~ *] ``noun+!>((encode-hunk:fin pax.tyl hunk [p q.q]:u.u.res)) + [~ ~] ``noun+!>((etch-hunk:fin pax.tyl hunk ~)) + [~ ~ *] ``noun+!>((etch-hunk:fin pax.tyl hunk [p q.q]:u.u.res)) == == -- @@ -1444,29 +1430,29 @@ ++ on-hear |= [l=lane b=blob d=(unit goof)] ^+ event-core - =/ =packet (decode-packet b) - ?: sam.packet - (on-hear-packet l packet d) - ?: req.packet + =/ =shot (sift-shot b) + ?: sam.shot + (on-hear-packet l shot d) + ?: req.shot ~|([%fine %request-events-forbidden] !!) - (on-hear-response:fine l packet d) + (on-hear-response:fine l shot d) :: +on-hear-packet: handle mildly processed packet receipt :: ++ on-hear-packet ~/ %on-hear-packet - |= [=lane =packet dud=(unit goof)] + |= [=lane =shot dud=(unit goof)] ^+ event-core :: - ?: =(our sndr.packet) + ?: =(our sndr.shot) event-core :: %. +< :: - ?. =(our rcvr.packet) + ?. =(our rcvr.shot) on-hear-forward :: - ?: ?& ?=(%pawn (clan:title sndr.packet)) - !?=([~ %known *] (~(get by peers.ames-state) sndr.packet)) + ?: ?& ?=(%pawn (clan:title sndr.shot)) + !?=([~ %known *] (~(get by peers.ames-state) sndr.shot)) == on-hear-open on-hear-shut @@ -1478,42 +1464,42 @@ :: ++ on-hear-forward ~/ %on-hear-forward - |= [=lane =packet dud=(unit goof)] + |= [=lane =shot dud=(unit goof)] ^+ event-core - %- %^ trace for.veb sndr.packet - |.("forward: {} -> {}") - :: set .origin.packet if it doesn't already have one, re-encode, and send + %- %^ trace for.veb sndr.shot + |.("forward: {} -> {}") + :: set .origin.shot if it doesn't already have one, re-encode, and send :: - =? origin.packet - &(?=(~ origin.packet) !=(%czar (clan:title sndr.packet))) + =? origin.shot + &(?=(~ origin.shot) !=(%czar (clan:title sndr.shot))) ?: ?=(%& -.lane) ~ ?. (lte (met 3 p.lane) 6) ~| ames-lane-size+p.lane !! `p.lane :: - =/ =blob (encode-packet packet) - (send-blob & rcvr.packet blob) + =/ =blob (etch-shot shot) + (send-blob & rcvr.shot blob) :: +on-hear-open: handle receipt of plaintext comet self-attestation :: ++ on-hear-open ~/ %on-hear-open - |= [=lane =packet dud=(unit goof)] + |= [=lane =shot dud=(unit goof)] ^+ event-core :: assert the comet can't pretend to be a moon or other address :: - ?> ?=(%pawn (clan:title sndr.packet)) + ?> ?=(%pawn (clan:title sndr.shot)) :: if we already know .sndr, ignore duplicate attestation :: - =/ ship-state (~(get by peers.ames-state) sndr.packet) + =/ ship-state (~(get by peers.ames-state) sndr.shot) ?: ?=([~ %known *] ship-state) event-core :: - =/ =open-packet (decode-open-packet packet our life.ames-state) + =/ =open-packet (sift-open-packet shot our life.ames-state) :: add comet as an %alien if we haven't already :: =? peers.ames-state ?=(~ ship-state) - (~(put by peers.ames-state) sndr.packet %alien *alien-agenda) + (~(put by peers.ames-state) sndr.shot %alien *alien-agenda) :: upgrade comet to %known via on-publ-full :: =. event-core @@ -1522,30 +1508,30 @@ :* ^= rift 0 ^= life sndr-life.open-packet ^= keys (my [sndr-life.open-packet crypto-suite public-key.open-packet]~) - ^= sponsor `(^sein:title sndr.packet) + ^= sponsor `(^sein:title sndr.shot) == - (on-publ / [%full (my [sndr.packet point]~)]) + (on-publ / [%full (my [sndr.shot point]~)]) :: manually add the lane to the peer state :: =. peers.ames-state - =/ =peer-state (gut-peer-state sndr.packet) + =/ =peer-state (gut-peer-state sndr.shot) =. route.peer-state `[direct=%.n lane] - (~(put by peers.ames-state) sndr.packet %known peer-state) + (~(put by peers.ames-state) sndr.shot %known peer-state) :: event-core :: +on-hear-shut: handle receipt of encrypted packet :: ++ on-hear-shut ~/ %on-hear-shut - |= [=lane =packet dud=(unit goof)] + |= [=lane =shot dud=(unit goof)] ^+ event-core - =/ sndr-state (~(get by peers.ames-state) sndr.packet) + =/ sndr-state (~(get by peers.ames-state) sndr.shot) :: If we don't know them, ask Jael for their keys. On comets, this will :: also cause us to send a self-attestation to the sender. The packet :: itself is dropped; we can assume it will be resent. :: ?. ?=([~ %known *] sndr-state) - (enqueue-alien-todo sndr.packet |=(alien-agenda +<)) + (enqueue-alien-todo sndr.shot |=(alien-agenda +<)) :: decrypt packet contents using symmetric-key.channel :: :: If we know them, we have a $channel with them, which we've @@ -1553,10 +1539,10 @@ :: and their public key using elliptic curve Diffie-Hellman. :: =/ =peer-state +.u.sndr-state - =/ =channel [[our sndr.packet] now channel-state -.peer-state] + =/ =channel [[our sndr.shot] now channel-state -.peer-state] ~| %ames-crash-on-packet-from^her.channel =/ =shut-packet - (decode-shut-packet packet [symmetric-key her-life our-life]:channel) + (sift-shut-packet shot [symmetric-key her-life our-life]:channel) :: non-galaxy: update route with heard lane or forwarded lane :: =? route.peer-state !=(%czar (clan:title her.channel)) @@ -1579,13 +1565,13 @@ :: needing to |hi or dotpost to get a response when the other :: ship has changed lanes. :: - ?: ?=(~ origin.packet) + ?: ?=(~ origin.shot) `[direct=%.y lane] ?: ?=([~ %& *] route.peer-state) - ?: =(lane.u.route.peer-state |+u.origin.packet) + ?: =(lane.u.route.peer-state |+u.origin.shot) route.peer-state - `[direct=%.n |+u.origin.packet] - `[direct=%.n |+u.origin.packet] + `[direct=%.n |+u.origin.shot] + `[direct=%.n |+u.origin.shot] :: perform peer-specific handling of packet :: =/ peer-core (make-peer-core peer-state channel) @@ -2112,8 +2098,8 @@ ++ attestation-packet |= [her=ship =her=life] ^- blob - %- encode-packet - %- encode-open-packet + %- etch-shot + %- etch-open-packet :_ crypto-core.ames-state :* ^= public-key pub:ex:crypto-core.ames-state ^= sndr our @@ -2129,8 +2115,8 @@ |= her=ship ^- blob ?> ?=(%pawn (clan:title her)) - %+ encode-packet & - %- encode-shut-packet + %- etch-shot + %- etch-shut-packet :* ^= shut-packet *shut-packet ^= symmetric-key *symmetric-key ^= sndr our @@ -2401,8 +2387,8 @@ :: =. event-core %^ send-blob | her.channel - %- encode-packet - %: encode-shut-packet + %- etch-shot + %: etch-shut-packet shut-packet(bone (mix 1 bone.shut-packet)) symmetric-key.channel our her.channel @@ -2645,10 +2631,10 @@ =. peers.ames-state (~(put by peers.ames-state) ship known/peer) event-core - ++ pe-lane (get-lane ship) ++ pe-keen |= [=path =^duct] ?: (~(has by order.scry) path) + ~> %slog.0^leaf/"fine: dupe {(spud 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) @@ -2699,15 +2685,15 @@ ke-abet:(ke-unsub:(ke-abed:keen-core path) duct) :: ++ pe-hear - |= [=lane =packet] - ?> =(sndr-tick.packet (mod life.peer 16)) + |= [=lane =shot] + ?> =(sndr-tick.shot (mod life.peer 16)) :: - =/ [=peep =purr] (decode-request-info `@ux`content.packet) + =/ [=peep =meow] (sift-purr `@ux`content.shot) =/ =path (slag 3 path.peep) ?. (~(has by order.scry) path) ~&(dead-response/peep pe-core) =< ke-abet - (ke-rcv:(ke-abed:keen-core path) num.peep purr lane) + (ke-rcv:(ke-abed:keen-core path) peep meow lane) :: ++ pe-update-qos |= =new=qos @@ -2791,9 +2777,9 @@ (scot %ud life.peer) path :: - ++ ke-encode-req + ++ ke-etch-keen |= frag=@ud - (encode-request ship ke-full-path frag) + (etch-keen ship ke-full-path frag) :: ++ ke-on-ack =| marked=(list want) @@ -2819,28 +2805,25 @@ [`want %.n found ke-core] =. tries.want +(tries.want) =. last-sent.want now - =. ke-core - (ke-resend [fra hoot]:want) + =. ke-core (ke-send hoot.want) [`want %.n found ke-core] :: ++ ke-start |= =^duct - ~& start/now + ~> %slog.0^leaf/"fine: keen {(spud ke-full-path)}" =. ke-core (ke-sub duct) ?> =(num-fragments.keen 0) =/ fra=@ 1 - =/ req (ke-encode-req fra) + =/ req (ke-etch-keen fra) =/ =want [fra req now 1 0] =. wan.keen (cons:ke-deq *(pha ^want) want) =. metrics.keen (on-sent:ke-gauge 1) - =- ke-core(event-core -) - %- emit - [unix-duct.ames-state %give %send pe-lane `@ux`req] + (ke-send req) :: ++ ke-done |= [sig=@ data=$@(~ (cask))] ?> (meri:keys ship life.peer ke-full-path sig data) - ~& got-response/path + ~> %slog.0^leaf/"fine: done {(spud ke-full-path)}" =/ listeners ~(tap in listeners.keen) =/ dat=(unit (cask)) ?~(data ~ `data) @@ -2857,13 +2840,13 @@ =- ke-core(keen -) :: =/ paz=(list want) - %+ turn (gulf 1 siz.meow) + %+ turn (gulf 1 num.meow) |= fra=@ud ^- want - [fra (ke-encode-req fra) now 0 0] + [fra (ke-etch-keen fra) now 0 0] :: %_ keen - num-fragments siz.meow + num-fragments num.meow nex (tail paz) == :: +ke-continue: send packets according to normal congestion flow @@ -2880,32 +2863,23 @@ =. tries.want +(tries.want) =. wan.keen (snoc:ke-deq wan.keen want) =. metrics.keen (on-sent:ke-gauge 1) - =. ke-core (ke-emit hoot.want) + =. ke-core (ke-send hoot.want) $(inx +(inx)) :: - ++ ke-resend - |= [fra=@ud =hoot] - (ke-emit hoot) - :: ++ ke-sub |= =^duct - =. listeners.keen (~(put in listeners.keen) duct) - ke-core + ke-core(listeners.keen (~(put in listeners.keen) duct)) :: scry is autocancelled in +ke-abet if no more listeners :: ++ ke-unsub |= =^duct - =. listeners.keen (~(del in listeners.keen) duct) - ke-core + ke-core(listeners.keen (~(del in listeners.keen) duct)) :: - ++ ke-emit + ++ ke-send |= =hoot - ^+ ke-core - =- ke-core(event-core -) - %- emit - [unix-duct.ames-state %give %send pe-lane `@ux`hoot] + ke-core(event-core (send-blob for=| ship `@ux`hoot)) :: - ++ ke-decode-full + ++ ke-sift-full =, keen ~| %frag-mismatch ~| have/num-received @@ -2913,40 +2887,50 @@ ~| path/path ?> =(num-fragments num-received) ?> =((lent hav) num-received) - (decode-response-msg num-fragments hav) - :: + (sift-roar num-fragments hav) :: ++ ke-rcv - |= [fra=@ud =purr =lane:ames] + |= [[=full=^path num=@ud] =meow =lane:ames] ^+ ke-core - =/ =meow (decode-response-packet purr) =/ og ke-core =. pe-core (pe-update-qos %live last-contact=now) :: handle empty - ?: =(0 siz.meow) + ?: =(0 num.meow) ?> =(~ dat.meow) (ke-done sig.meow ~) :: update congestion, or fill details :: =? ke-core =(0 num-fragments.keen) - ?> =(fra 1) + ?> =(num 1) (ke-first-rcv meow) :: - ~| failed-signature/fra^`@ux`sig.meow - ~| life.peer - ?> (veri-fra:keys ship life.peer ke-full-path fra [dat sig]:meow) - =^ found=? ke-core - (ke-on-ack fra) + ?. ?=([@ @ @ *] full-path) + ~| fine-path-too-short+full-path + !! + ?. =(`ship (slaw %p i.full-path)) + ~| fine-path-bunk-ship+[full-path ship] + !! + ?. =(`life.peer (slaw %ud i.t.full-path)) + ~| fine-path-bunk-life+[full-path life.peer] + !! + ?. =(`rift.peer (slaw %ud i.t.t.full-path)) + ~| fine-path-bunk-rift+[full-path rift.peer] + !! + ?. %- veri-fra:keys + [ship life.peer full-path num [dat sig]:meow] + ~| fine-purr-fail-signature/num^`@ux`sig.meow + ~| life.peer + !! :: + =^ found=? ke-core (ke-on-ack num) ?. found - (ke-fast-retransmit:og fra) - =/ =have [fra meow] - =. hav.keen - `(list ^have)`[have hav.keen] - =. num-received.keen +(num-received.keen) - ?: =(num-fragments num-received):keen - (ke-done [sig dat]:ke-decode-full) - ke-continue + (ke-fast-retransmit:og num) + =: hav.keen [[num meow] hav.keen] + num-received.keen +(num-received.keen) + == + ?. =(num-fragments num-received):keen + ke-continue + (ke-done [sig dat]:ke-sift-full) :: ++ ke-fast-retransmit |= fra=@ud @@ -2961,8 +2945,7 @@ ?: (gth (next-expiry:ke-gauge:cor +>.want) now) [`want & cor] =. last-sent.want now - =. cor - (ke-emit:cor hoot.want) + =. cor (ke-send:cor hoot.want) [`want | cor] :: ++ ke-gauge @@ -3022,7 +3005,7 @@ last-sent.u.want now == =. wan.keen (cons:ke-deq wan.keen u.want) - (ke-resend [fra hoot]:u.want) + (ke-send hoot.u.want) -- -- :: @@ -3085,12 +3068,8 @@ ++ on-yawn |= [=ship =path] ^+ event-core - =/ omen - ~| [%fine %invalid-namespace-path path] - (need (de-omen path)) - =/ peer-core (pe-abed:fine-peer p.bem.omen) - ?~ peer-core - ~|(%no-ship-for-yawn !!) + =/ peer-core (pe-abed:fine-peer ship) + ?~ peer-core ~|(%no-ship-for-yawn !!) pe-abet:(pe-yawn:u.peer-core path) :: ++ on-take-wake @@ -3108,48 +3087,30 @@ pe-abet:(pe-take-wake:peer-core t.wire) :: ++ on-hear-response - |= [=lane =packet dud=(unit goof)] + |= [=lane =shot dud=(unit goof)] ^+ event-core ?^ dud ::TODO handle ~& [%fine %done-goofed mote.u.dud] %- (slog tang.u.dud) event-core + :: TODO no longer true ::NOTE we only send requests to ships we know, :: so we should only get responses from ships we know. :: below we assume sndr.packet is a known peer. - =* from sndr.packet + =* from sndr.shot =/ peer-core (need (pe-abed:fine-peer from)) - pe-abet:(pe-hear:peer-core lane packet) + pe-abet:(pe-hear:peer-core lane shot) -- |% - +$ twit :: signed request - $: signature=@ - peep - == :: - +$ peep :: request data - $: =path - num=@ud - == - :: - +$ meow :: response packet - $: sig=@ - siz=@ud - byts - == - :: - +$ roar :: response message - $: sig=@ - dat=$@(~ (cask)) - == ++ orm ((on @ud keen-state) lte) :: +gum: glue together a list of $byts into one :: :: TODO: move to hoon.hoon :: ++ gum - ~/ %gum + ::~/ %gum |= biz=(list byts) ^- byts :- (roll biz |=([[wid=@ *] acc=@] (add wid acc))) @@ -3163,7 +3124,7 @@ ?> (lte wid 384) [pat wid] :: - ++ request-body + ++ etch-peep |= [=path num=@ud] ^- byts ?> (lth num (bex 32)) @@ -3173,62 +3134,95 @@ 2^wid :: path size wid^`@`pat :: namespace path == + :: +show-meow: prepare $meow for printing :: - ++ 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 + ++ show-meow + |= =meow + :* sig=`@q`(mug sig.meow) + num=num.meow + siz=siz.meow + dat=`@q`(mug dat.meow) == :: - ++ encode-request + ++ make-meow + |= [=path mes=@ num=@ud] + ^- meow + =/ tot (met 13 mes) + =/ dat (cut 13 [(dec num) 1] mes) + =/ wid (met 3 dat) + :* sig=(sign-fra:keys path num dat) :: fragment signature + num=tot :: number of fragments + siz=?:(=(num tot) (met 3 dat) 1.024) :: fragment byte width + dat=dat :: response data fragment + == + :: + ++ etch-meow + |= =meow + ^- @uxmeow + %+ can 3 + :~ 64^sig.meow + 4^num.meow + 2^siz.meow + (met 3 dat.meow)^dat.meow + == + :: + ++ etch-keen |= [=ship =path num=@ud] ^- hoot ^- @ =/ sic (mod life.ames-state 16) =/ ric (mod (lyfe:keys ship) 16) =/ syn - =/ bod (request-body path num) + =/ bod (etch-peep path num) =/ sig 64^(sign:keys dat.bod) (can 3 sig bod ~) - (encode-packet [our ship] req=& sam=| sic ric ~ syn) + (etch-shot [our ship] req=& sam=| sic ric ~ syn) :: - ++ encode-hunk ::TODO unit tests + ++ etch-hunk |= [=path =hunk data=$@(~ (cask))] ^- (list @uxmeow) =/ mes=@ =/ sig=@ (full:keys path data) ?~ data sig - (cat 9 sig (jam data)) + (mix sig (lsh 9 (jam data))) + ::(cat 9 sig (jam data)) :: - =/ top +((min (met 13 mes) (add [lop len]:hunk))) + =/ las (met 13 mes) + =/ tip (dec (add [lop len]:hunk)) + =/ top (min las tip) =/ num lop.hunk + ?> (lte num top) =| res=(list @uxmeow) |- ^+ res - ?: =(num top) (flop res) - $(num +(num), res :_(res (frag-body path mes num))) + ?: =(num top) + =- (flop - res) + (etch-meow (make-meow path mes num)) + $(num +(num), res :_(res (etch-meow (make-meow path mes num)))) :: ++ keys |% ++ mess - |=([@p life path $@(~ (cask))] (jam +<)) + |= [=ship life=@ud =path dat=$@(~ (cask))] + (jam +<) :: ++ full |= [=path data=$@(~ (cask))] - (sign (mess our life.ames-state path data)) + =/ buf (mess our life.ames-state path data) + ::=/ nam (crip "sign-full {<(met 3 buf)>}") + ::~> %bout.[1 nam] + (sign buf) + :: + ++ frag + |= [=path fra=@ud dat=@ux] + (jam +<) :: ++ sign-fra - |= [=path fra=@ dat=@ux] - (sign (jam path fra dat)) + |= [=path fra=@ud dat=@ux] + ::~> %bout.[1 %sign-fra] + (sign (frag path fra dat)) :: ++ veri-fra - |= [who=ship lyf=life =path fra=@ dat=@ux sig=@] - (veri who lyf sig (jam path fra dat)) + |= [who=ship lyf=life =path fra=@ud dat=@ux sig=@] + (veri who lyf sig (frag path fra dat)) :: ++ sign sigh:as:crypto-core.ames-state @@ -3260,26 +3254,6 @@ |= [who=ship lyf=life pax=path sig=@ dat=$@(~ (cask))] (veri who lyf sig (mess who lyf pax dat)) -- - :: TODO: should not crash, - :: improve routing? - ++ get-lane - |= =ship - ^- lane:ames - =/ =peer-state - (got-peer-state ship) - ?^ route.peer-state - lane.u.route.peer-state - ?: ?=(%czar (rank:title ship)) - [%& ship] - !! -:: :- %& -:: ;; ship -:: =- -.q.q.- -:: %- need %- need -:: %- rof -:: %j -:: /(scot %p our)/saxo/(scot %da now)/(scot %p who) -:: == -- -- :: +make-message-pump: constructor for |message-pump @@ -3915,7 +3889,7 @@ ++ clamp-rto |= rto=@dr ^+ rto - (min ~m2 (max ^~((div ~s1 5)) rto)) + (min ~s5 (max ^~((div ~s1 5)) rto)) :: +in-slow-start: %.y iff we're in "slow-start" mode :: ++ in-slow-start diff --git a/pkg/arvo/sys/vane/clay.hoon b/pkg/arvo/sys/vane/clay.hoon index 18f29a28a..5d4d564ed 100644 --- a/pkg/arvo/sys/vane/clay.hoon +++ b/pkg/arvo/sys/vane/clay.hoon @@ -443,7 +443,7 @@ :: |% ++ scry-timeout-time ~m1 -++ scry-retry-time ~m30 +++ scry-retry-time ~s0 :: +sort-by-head: sorts alphabetically using the head of each element :: ++ sort-by-head @@ -899,7 +899,7 @@ %- soak-vase %+ gain-sprig file+path |. =. stack.nub [~ stack.nub] - ~> %slog.0^leaf/"ford: make file {(spud path)}" + :: ~> %slog.0^leaf/"ford: make file {(spud path)}" ?: (~(has in cycle.nub) file+path) ~|(cycle+file+path^cycle.nub !!) =. cycle.nub (~(put in cycle.nub) file+path) @@ -1214,7 +1214,7 @@ =? cache.nub !spilt (~(put by cache.nub) leak [+(refs.u.got) soak.u.got]) [soak.u.got nub] - %- (slog leaf+"ford: cache {}: creating" ~) + :: %- (slog leaf+"ford: cache {}: creating" ~) =^ =soak nub (next nub) =. cache.nub (~(put by cache.nub) leak [1 soak]) :: If we're creating a cache entry, add refs to our dependencies @@ -1242,16 +1242,16 @@ |= [fad=flow =leak] ^- flow ?~ got=(~(get by fad) leak) - %- (slog leaf+"ford: lose missing leak {}" ~) + :: %- (slog leaf+"ford: lose missing leak {}" ~) fad ?: (lth 1 refs.u.got) - =/ tape "ford: cache {}: decrementing from {}" - %- (slog leaf+tape ~) + :: =/ tape "ford: cache {}: decrementing from {}" + :: %- (slog leaf+tape ~) =. fad (~(put by fad) leak u.got(refs (dec refs.u.got))) fad =+ ?. =(0 refs.u.got) ~ - ((slog leaf+"ford: lose zero leak {}" ~) ~) - %- (slog leaf+"ford: cache {}: freeing" ~) + ~ :: ((slog leaf+"ford: lose zero leak {}" ~) ~) + :: %- (slog leaf+"ford: cache {}: freeing" ~) =. fad (~(del by fad) leak) =/ leaks ~(tap in deps.leak) |- ^- flow @@ -3062,9 +3062,11 @@ %. [hen her u.nux [syd ~]] send-over-ames(ref `(unit rind)`ref) :: XX TMI %- emil - =/ =wire (request-wire kind.u.busy.sat her syd u.nux) - :~ [hen %pass wire %a %yawn her path.u.busy.sat] - [hen %pass wire %b %rest time.u.busy.sat] + =* bus u.busy.sat + =/ =wire (request-wire kind.bus her syd u.nux) + ~& %cancel-request-yawn + :~ [hen %pass wire %a %yawn her path.bus] + [hen %pass wire %b %rest time.bus] == :: :: Handles a request. @@ -3104,12 +3106,12 @@ =. ..retry-with-ames =< ?>(?=(^ ref) .) ~| [%strange-retry-not-scry her syd inx busy.sat -.rave.sat] - ?> ?=([~ ^] busy.sat) + =/ bus ?>(?=([~ ^] busy.sat) u.busy.sat) =/ =wire (request-wire kind her syd inx) - =/ =path path.u.busy.sat %- emil - :~ [hen %pass wire %b %rest time.u.busy.sat] - [hen %pass wire %a %yawn her path] + ~& %retry-with-ames-yawn + :~ [hen %pass wire %b %rest time.bus] + [hen %pass wire %a %yawn her path.bus] == :: re-send over ames :: diff --git a/pkg/arvo/sys/vane/jael.hoon b/pkg/arvo/sys/vane/jael.hoon index d335f2359..e1d458a2a 100644 --- a/pkg/arvo/sys/vane/jael.hoon +++ b/pkg/arvo/sys/vane/jael.hoon @@ -304,8 +304,8 @@ :: =. +>.$ %^ poke-watch hen %azimuth - %+ fall node.tac - (need (de-purl:html 'http://eth-mainnet.urbit.org:8545')) + :: %+ fall node.tac + (need (de-purl:html 'https://ropsten.infura.io/v3/2599df54929b47099bda360958d75aaf')) =. +>.$ :: get everything from /app/azimuth because jael subscriptions :: seem to be flaky for now diff --git a/pkg/arvo/tests/sys/vane/ames.hoon b/pkg/arvo/tests/sys/vane/ames.hoon index ac8207469..146b76501 100644 --- a/pkg/arvo/tests/sys/vane/ames.hoon +++ b/pkg/arvo/tests/sys/vane/ames.hoon @@ -1,6 +1,7 @@ /+ *test /= ames /sys/vane/ames /= jael /sys/vane/jael +/* dojo %hoon /app/dojo/hoon :: construct some test fixtures :: =/ nec ^$:((ames ~nec)) @@ -183,6 +184,16 @@ %+ snag index (skim moves is-move-send) :: +++ n-frags + |= n=@ + ^- @ux + :: 6 chosen randomly to get some trailing zeros + :: + %+ rsh 10 + %+ rep 13 + %+ turn (gulf 1 n) + |=(x=@ (fil 3 1.024 (dis 0xff x))) +:: ++ scry |= [vane=_nec car=term bem=beam] =/ =roof @@ -198,7 +209,12 @@ ``noun+!>([black black]) :: %cz - ``noun+!>(`@ux`(fil 5 32 0xdead.beef)) + ?+ -.r.bem !! + %ud ``noun+!>((n-frags p.r.bem)) + == + :: + %cx + ``hoon+!>(dojo) == =/ vane-core (vane(rof roof)) (scry:vane-core ~ car bem) @@ -226,34 +242,36 @@ :: =/ =packet:ames :* [sndr=~nec rcvr=~bud] + req=& sam=& sndr-tick=0b10 rcvr-tick=0b11 origin=~ content=0xdead.beef == :: - =/ encoded (encode-packet:ames & packet) + =/ encoded (encode-packet:ames packet) =/ decoded (decode-packet:ames encoded) :: %+ expect-eq - !> [& packet] + !> packet !> decoded :: ++ test-origin-encoding ^- tang :: =/ =packet:ames :* [sndr=~nec rcvr=~bud] + req=& sam=& sndr-tick=0b10 rcvr-tick=0b11 origin=`0xbeef.cafe.beef content=0xdead.beef == :: - =/ encoded (encode-packet:ames & packet) + =/ encoded (encode-packet:ames packet) =/ decoded (decode-packet:ames encoded) :: %+ expect-eq - !> [& packet] + !> packet !> decoded :: ++ test-shut-packet-encoding ^- tang @@ -305,7 +323,7 @@ rcvr-life=3 == :: - =/ =blob:ames (encode-packet:ames & packet) + =/ =blob:ames (encode-packet:ames packet) =^ moves1 bud (call bud ~[//unix] %hear lane-foo blob) =^ moves2 bud =/ =point:ames @@ -478,55 +496,79 @@ ?. ?=(%give -.card.move) ~ ?. ?=(%send -.p.card.move) ~ `;;(@uxhoot blob.p.card.move) - =/ [is-ames=? =packet:ames] (decode-packet:ames `@ux`req) - ?> ?=(%| is-ames) + =/ =packet:ames (decode-packet:ames `@ux`req) + ?< sam.packet + ?> req.packet =/ twit (decode-request:ames `@ux`content.packet) ~& twit (expect-eq !>(1) !>(1)) :: +++ test-fine-hunk + ^- tang + %- zing + %+ turn (gulf 1 10) + |= siz=@ + =/ want=path /~bud/0/1/c/z/(scot %ud siz)/kids/sys + :: + =/ =beam [[~bud %$ da+now:bud] (welp /fine/hunk/1/16.384 want)] + =/ [=mark =vase] (need (need (scry bud %x beam))) + =+ !<(song=(list @uxmeow) vase) + %+ expect-eq + !>(siz) + !>((lent song)) +:: ++ test-fine-response ^- tang - =/ datum=@ux (fil 5 32 0xdead.beef) - =/ want=path /~bud/0/1/c/z/1/kids/sys - =. rof.bud - |=(* ``noun+!>(datum)) - =/ =beam [[~bud %$ da+now:bud] (welp /fine/message want)] + ::%- zing + ::%+ turn (gulf 1 50) + ::|= siz=@ + ::=/ want=path /~bud/0/1/c/z/(scot %ud siz)/kids/sys + =/ want=path /~bud/0/1/c/x/1/kids/app/dojo/hoon + =/ dit (jam %hoon dojo) + =/ exp (cat 9 (fil 3 64 0xff) dit) + =/ siz=@ud (met 13 exp) + ^- tang + :: + =/ =beam [[~bud %$ da+now:bud] (welp /fine/hunk/1/16.384 want)] =/ [=mark =vase] (need (need (scry bud %x beam))) - =+ !<(=song:ames vase) - =/ partial=(list have:ames) - %- head - %^ spin song 1 - |= [blob=@ux num=@ud] + =+ !<(song=(list @uxmeow) vase) + =/ paz=(list have:ames) + %+ spun song + |= [blob=@ux num=_1] ^- [have:ames _num] :_ +(num) - =/ [is-ames=? =packet:ames] (decode-packet:ames `@ux`blob) - ?> ?=(%| is-ames) - =/ [=peep:ames =purr:ames] (decode-request-info:ames `@ux`content.packet) - =/ rawr (decode-response-packet:ames `@ux`purr) - ~& rawr-sig/`@ux`sig.rawr - ~& rawr-siz/`@ux`siz.rawr - ~& rawr-wid/`@ux`wid.rawr - ~& rawr-dat/`@ux`dat.rawr - [num rawr] + =/ =meow:ames (decode-response-packet:ames blob) + [num meow] :: - =/ num-frag=@ud (lent partial) + =/ num-frag=@ud (lent paz) + ~& num-frag=num-frag =/ =roar:ames - (decode-response-msg:ames num-frag (flop partial)) + (decode-response-msg:ames num-frag (flop paz)) %+ welp =/ dat ?> ?=(^ dat.roar) ;;(@ux q.dat.roar) - (expect-eq !>(dat) !>(datum)) + (expect-eq !>(`@`dat) !>(`@`dojo)) =/ event-core ~! nec =/ foo [*@da *@ rof.nec] (per-event:(nec foo) [*@da *@ rof.nec] *duct ames-state.nec) - %- zing - %+ turn partial - |= [fra=@ud sig=@ siz=@ud byts] - %+ expect-eq !>(%.y) - !>((veri-fra:keys:fine:event-core ~bud life.ames-state.bud want fra dat sig)) + %+ welp + ^- tang + %- zing + %+ turn paz + |= [fra=@ud sig=@ siz=@ud byts] + %+ expect-eq !>(%.y) + !> + %- veri-fra:keys:fine:event-core + [~bud life.ames-state.bud want fra dat sig] + ~& %verifying-sig + %+ expect-eq + !>(&) + !> + %- meri:keys:fine:event-core + [~bud life.ames-state.bud want roar] :: ++ test-old-ames-wire ^- tang =^ moves0 bud (call bud ~[/g/hood] %spew [%odd]~) diff --git a/pkg/base-dev/lib/azimuth.hoon b/pkg/base-dev/lib/azimuth.hoon index d9c6a1b2e..b0c2c2b6c 100644 --- a/pkg/base-dev/lib/azimuth.hoon +++ b/pkg/base-dev/lib/azimuth.hoon @@ -78,7 +78,7 @@ :: # constants :: :: contract addresses - ++ contracts mainnet-contracts + ++ contracts ropsten-contracts ++ mainnet-contracts |% :: azimuth: data contract diff --git a/pkg/urbit/vere/io/ames.c b/pkg/urbit/vere/io/ames.c index 2928fb0f2..d6882385a 100644 --- a/pkg/urbit/vere/io/ames.c +++ b/pkg/urbit/vere/io/ames.c @@ -5,11 +5,16 @@ #include "vere/vere.h" #include "ur/serial.h" -#define FINE_PAGE 16384 // packets per page +#define FINE_PAGE 512 // packets per page #define FINE_FRAG 1024 // bytes per fragment packet #define FINE_PATH_MAX 384 // longest allowed scry path #define HEAD_SIZE 4 // header size in bytes +// a hack to work around the inability to delete from a hashtable +// +#define FINE_PEND 1 // scry cache sentinel value: "pending" +#define FINE_DEAD 2 // scry cache sentinel value: "dead" + /* u3_fine: fine networking */ typedef struct _u3_fine { @@ -96,11 +101,15 @@ } u3_wail; /* u3_meow: response portion of purr packet + * + * siz_s: number of bytes to stitch into a message + * act_s: number of bytes in the actual packet */ typedef struct _u3_meow { c3_y sig_y[64]; // host signature c3_w num_w; // number of fragments - c3_s siz_s; // datum size + c3_s siz_s; // datum size (official) + c3_w act_s; // datum size (actual) c3_y* dat_y; // datum (0 if null response) } u3_meow; @@ -160,17 +169,23 @@ c3_o for_o; // are we forwarding this? } u3_panc; +#define _str_o(lob_o) ( ( c3y == lob_o ) ? "yes" : "no" ) +#define _str_typ(typ_y) ( \ + ( PACT_AMES == typ_y ) ? "ames" \ + : ( PACT_WAIL == typ_y ) ? "wail" \ + : ( PACT_PURR == typ_y ) ? "purr" : "????") + static void _log_head(u3_head* hed_u) { u3l_log("-- HEADER --\n"); - u3l_log("is request: %s\n", (c3y == hed_u->req_o)? "yes" : "no"); - u3l_log("is ames: %s\n", (c3y == hed_u->sim_o)? "yes" : "no"); + u3l_log("is request: %s\n", _str_o(hed_u->req_o)); + u3l_log("is ames: %s\n", _str_o(hed_u->sim_o)); u3l_log("mug: 0x%05x\n", (hed_u->mug_l &0xfffff)); u3l_log("protocol version: %u\n", hed_u->ver_y); u3l_log("sender class: %u\n", hed_u->sac_y); u3l_log("recevr class: %u\n", hed_u->rac_y); - u3l_log("is relayed: %s\n", (c3y == hed_u->rel_o)? "yes" : "no"); + u3l_log("is relayed: %s\n", _str_o(hed_u->rel_o)); u3l_log("\n"); } @@ -195,6 +210,36 @@ _log_keen(u3_keen* req_u) u3l_log("\n"); } +static c3_c* +_show_mug_buf(c3_y* buf_y, c3_w len_w) +{ + u3_noun mug = u3r_mug_bytes(buf_y, len_w); + u3_noun cot = u3dc("scot", 'q', mug); + return u3r_string(cot); +} + +static void +_log_meow(u3_meow* mew_u) +{ + c3_c* sig_c = _show_mug_buf(mew_u->sig_y, sizeof(mew_u->sig_y)); + c3_c* dat_c = _show_mug_buf(mew_u->dat_y, mew_u->act_s); + + u3l_log(" sig=%s\n" + " num=%u\n" + " siz=%u\n" + " act=%u\n" + " dat=%s\n", + sig_c, + mew_u->num_w, + mew_u->siz_s, + mew_u->act_s, + dat_c + ); + + c3_free(sig_c); + c3_free(dat_c); +} + static void _log_bytes(c3_y* byt_y, c3_w len_w) { @@ -239,7 +284,8 @@ _ames_pact_free(u3_pact* pac_u) break; default: - u3l_log("ames_pact_free: bad packet type %d\n", pac_u->typ_y); + u3l_log("ames_pact_free: bad packet type %s\n", + _str_typ(pac_u->typ_y)); u3_pier_bail(u3_king_stub()); } @@ -253,7 +299,7 @@ _ames_pact_free(u3_pact* pac_u) static void _ames_panc_free(u3_panc* pan_u) { - if ( pan_u->for_o ) { + if ( c3y == pan_u->for_o ) { if ( 0 != pan_u->nex_u ) { pan_u->nex_u->pre_u = pan_u->pre_u; } @@ -270,6 +316,13 @@ _ames_panc_free(u3_panc* pan_u) c3_free(pan_u); } +static inline u3_ptag +_ames_pact_typ(u3_head* hed_u) +{ + return (( c3y == hed_u->sim_o ) ? PACT_AMES : + ( c3y == hed_u->req_o ) ? PACT_WAIL : PACT_PURR); +} + static inline c3_y _ames_origin_size(u3_head* hed_u) { @@ -308,7 +361,7 @@ _fine_meow_size(u3_meow* mew_u) sizeof(mew_u->sig_y) + sizeof(mew_u->num_w) + sizeof(mew_u->siz_s) + - mew_u->siz_s); + mew_u->act_s); } static c3_s @@ -319,6 +372,21 @@ _fine_purr_size(u3_purr* pur_u) return pur_s + mew_s; } +static c3_o +_ames_check_mug(u3_pact* pac_u) +{ + c3_w rog_w = HEAD_SIZE + _ames_origin_size(&pac_u->hed_u); + c3_l mug_l = u3r_mug_bytes(pac_u->hun_y + rog_w, + pac_u->len_w - rog_w); + // u3l_log("len_w: %u, rog_w: %u, bod_l 0x%05x, hed_l 0x%05x\n", + // pac_u->len_w, rog_w, + // (mug_l & 0xfffff), + // (pac_u->hed_u.mug_l & 0xfffff)); + return ( + ((mug_l & 0xfffff) == (pac_u->hed_u.mug_l & 0xfffff)) + ? c3y : c3n); +} + static inline c3_s _ames_sift_short(c3_y buf_y[2]) { @@ -539,8 +607,9 @@ _fine_sift_meow(u3_meow* mew_u, u3_noun mew) // parse data payload // - mew_u->dat_y = c3_calloc(mew_u->siz_s); - u3r_bytes(cur_w, mew_u->siz_s, mew_u->dat_y, mew); + mew_u->act_s = len_w - cur_w; + mew_u->dat_y = c3_calloc(mew_u->act_s); + u3r_bytes(cur_w, mew_u->act_s, mew_u->dat_y, mew); ret_o = c3y; } @@ -585,6 +654,14 @@ _ames_etch_head(u3_head* hed_u, c3_y buf_y[4]) _ames_etch_word(buf_y, hed_w); } +static void +_ames_etch_origin(c3_d rog_d, c3_y* buf_y) +{ + c3_y rag_y[8] = {0}; + _ames_bytes_chub(rag_y, rog_d); + memcpy(buf_y, rag_y, 6); +} + /* _ames_etch_prel(): serialize packet prelude */ static void @@ -595,9 +672,7 @@ _ames_etch_prel(u3_head* hed_u, u3_prel* pre_u, c3_y* buf_y) // if packet is relayed, write the 6-byte origin field // if ( c3y == hed_u->rel_o ) { - c3_y rag_y[8] = {0}; - _ames_bytes_chub(rag_y, pre_u->rog_d); - memcpy(buf_y + cur_w, rag_y, 6); + _ames_etch_origin(pre_u->rog_d, buf_y + cur_w); cur_w += 6; } @@ -666,7 +741,7 @@ _fine_etch_meow(u3_meow* mew_u, c3_y* buf_y) // write response fragment data // - memcpy(buf_y + cur_w, mew_u->dat_y, mew_u->siz_s); + memcpy(buf_y + cur_w, mew_u->dat_y, mew_u->act_s); } /* _fine_etch_purr(): serialise response packet @@ -716,6 +791,8 @@ _fine_etch_response(u3_pact* pac_u) pac_u->hed_u.mug_l = u3r_mug_bytes(pac_u->hun_y + rog_w, pac_u->len_w - rog_w); _ames_etch_head(&pac_u->hed_u, pac_u->hun_y); + + c3_assert( c3y == _ames_check_mug(pac_u) ); } /* _lane_scry_path(): format scry path for retrieving a lane @@ -762,7 +839,7 @@ _ames_send(u3_pact* pac_u) || !pac_u->len_w || !pac_u->rut_u.lan_u.por_s ) { - u3l_log("_ames_send null\n"); + u3l_log("ames: _ames_send null\n"); _ames_pact_free(pac_u); } else { @@ -773,6 +850,9 @@ _ames_send(u3_pact* pac_u) add_u.sin_addr.s_addr = htonl(pac_u->rut_u.lan_u.pip_w); add_u.sin_port = htons(pac_u->rut_u.lan_u.por_s); + //u3l_log("_ames_send %s %u\n", _str_typ(pac_u->typ_y), + // pac_u->rut_u.lan_u.por_s); + { uv_buf_t buf_u = uv_buf_init((c3_c*)pac_u->hun_y, pac_u->len_w); @@ -1066,14 +1146,20 @@ _ames_czar(u3_pact* pac_u) static void _fine_put_cache(u3_ames* sam_u, u3_noun pax, c3_w lop_w, u3_noun lis) { - c3_w cur_w = lop_w; - while ( lis != u3_nul ) { - u3_noun key = u3nc(u3k(pax), u3i_word(cur_w)); - u3h_put(sam_u->fin_s.sac_p, key, u3k(u3h(lis))); + if ( (FINE_PEND == lis) || (FINE_DEAD == lis) ) { + u3_noun key = u3nc(u3k(pax), u3i_word(lop_w)); + u3h_put(sam_u->fin_s.sac_p, key, lis); + } + else { + c3_w cur_w = lop_w; + while ( lis != u3_nul ) { + u3_noun key = u3nc(u3k(pax), u3i_word(cur_w)); + u3h_put(sam_u->fin_s.sac_p, key, u3k(u3h(lis))); - lis = u3t(lis); - cur_w++; - u3z(key); + lis = u3t(lis); + cur_w++; + u3z(key); + } } } @@ -1096,9 +1182,7 @@ _ames_ef_send(u3_ames* sam_u, u3_noun lan, u3_noun pac) u3r_bytes(0, pac_u->len_w, pac_u->hun_y, pac); _ames_sift_head(&pac_u->hed_u, pac_u->hun_y); - pac_u->typ_y = - ( pac_u->hed_u.sim_o == c3y ) ? PACT_AMES : - ( pac_u->hed_u.req_o == c3y ) ? PACT_WAIL : PACT_PURR; + pac_u->typ_y = _ames_pact_typ(&pac_u->hed_u); u3_noun tag, val; u3x_cell(lan, &tag, &val); @@ -1110,6 +1194,7 @@ _ames_ef_send(u3_ames* sam_u, u3_noun lan, u3_noun pac) c3_assert( c3y == u3a_is_cat(val) ); c3_assert( val < 256 ); + //u3l_log("_ames_ef_send imp %s %u\n", _str_typ(pac_u->typ_y), val); pac_u->rut_u.imp_y = val; _ames_czar(pac_u); } @@ -1117,6 +1202,9 @@ _ames_ef_send(u3_ames* sam_u, u3_noun lan, u3_noun pac) // else { u3_lane lan_u = u3_ames_decode_lane(u3k(val)); + ////u3l_log("_ames_ef_send low %s %u\n", _str_typ(pac_u->typ_y), + // lan_u.por_s); + // convert incoming localhost to outgoing localhost // lan_u.pip_w = ( 0 == lan_u.pip_w )? 0x7f000001 : lan_u.pip_w; @@ -1380,13 +1468,17 @@ _ames_try_send(u3_pact* pac_u, c3_o for_o) } // if we don't know the lane, and the lane scry queue is full, // just drop the packet + //TODO cap queue for lane lookups for scry responses, not just forwards // //TODO drop oldest item in forward queue in favor of this one. // ames.c doesn't/shouldn't know about the shape of scry events, // so can't pluck these out of the event queue like it does in // _ames_cap_queue. as such, blocked on u3_lord_peek_cancel or w/e. // - if ( (u3_none == lac) && (1000 < sam_u->sat_u.foq_d) ) { + if ( (c3y == for_o) + && (u3_none == lac) + && (1000 < sam_u->sat_u.foq_d) ) + { sam_u->sat_u.fod_d++; if ( 0 == (sam_u->sat_u.fod_d % 10000) ) { u3l_log("ames: dropped %" PRIu64 " forwards total\n", @@ -1402,13 +1494,15 @@ _ames_try_send(u3_pact* pac_u, c3_o for_o) if ( u3_none != lac ) { _ames_send_many(pac_u, lac, for_o); } - // if forwarding, store the packet details for later processing + // store the packet to be sent later when the lane scry completes // else { u3_panc* pan_u = c3_calloc(sizeof(*pan_u)); pan_u->pac_u = pac_u; pan_u->for_o = for_o; + // if forwarding, enqueue + // if ( c3y == for_o ) { if ( 0 != sam_u->pan_u ) { pan_u->nex_u = sam_u->pan_u; @@ -1418,7 +1512,7 @@ _ames_try_send(u3_pact* pac_u, c3_o for_o) sam_u->sat_u.foq_d++; } - // there's space in the scry queue; scry the lane out of ames + // scry the lane out of ames // u3_noun pax = _lane_scry_path(u3i_chubs(2, pac_u->pre_u.rec_d)); @@ -1452,7 +1546,35 @@ _ames_skip(u3_prel* pre_u) static inline c3_w _fine_lop(c3_w fra_w) { - return fra_w - (fra_w % FINE_PAGE) + 1; + return 1 + (((fra_w - 1) / FINE_PAGE) * FINE_PAGE); +} + +static u3_weak +_fine_scry_path(u3_pact* pac_u, c3_o lop_o) +{ + u3_keen* ken_u = ( + ( PACT_WAIL == pac_u->typ_y ) + ? &pac_u->wal_u.ken_u + : &pac_u->pur_u.ken_u); + + u3_noun pat; + { + u3_noun pux = u3i_string(ken_u->pat_c); + u3_noun ful = u3dc("rush", pux, u3v_wish("stap")); + if ( u3_nul == ful ) { + u3z(ful); + return u3_none; + } + pat = u3k(u3t(ful)); + u3z(ful); + } + + c3_w fra_w = ken_u->fra_w; + if ( c3y == lop_o ) { + fra_w = _fine_lop(fra_w); + } + + return u3nc(pat, u3i_word(fra_w)); } /* _fine_pack_scry_cb(): receive packets for datum out of fine @@ -1464,16 +1586,20 @@ static void _fine_pack_scry_cb(void* vod_p, u3_noun nun) u3_ames* sam_u = pac_u->sam_u; u3_keen* ken_u = &pac_u->pur_u.ken_u; + u3_noun pax = u3do("stab", u3i_string(ken_u->pat_c)); + c3_w lop_w = _fine_lop(ken_u->fra_w); + + // if not [~ ~ fragments], mark as dead + // u3_weak pas = u3r_at(7, nun); - if(pas == u3_none) { + if( pas == u3_none ) { + _fine_put_cache(sam_u, pax, lop_w, FINE_DEAD); _ames_pact_free(pac_u); u3z(nun); return; } - u3_noun pax = u3do("stab", u3i_string(ken_u->pat_c)); - c3_w lop_w = _fine_lop(ken_u->fra_w); _fine_put_cache(sam_u, pax, lop_w, pas); // find requested fragment @@ -1511,6 +1637,7 @@ static void _fine_hear_request(u3_pact* req_u, c3_w cur_w) { u3_pact* res_u; + u3_weak key; if ( c3n == _fine_sift_wail(req_u, cur_w) ) { u3l_log("_fine_hear_request bad wail\n"); @@ -1518,12 +1645,9 @@ _fine_hear_request(u3_pact* req_u, c3_w cur_w) return; } - u3_noun pux = u3i_string(req_u->wal_u.ken_u.pat_c); - u3_noun pat = u3dc("rush", pux, u3v_wish("stap")); - if ( u3_nul == pat ) { - u3l_log("fine: bad request\n"); + if ( c3n == _fine_sift_wail(req_u, cur_w) ) { + u3l_log("fine: _fine_hear_request bad wail\n"); _ames_pact_free(req_u); - u3z(pat); return; } @@ -1569,6 +1693,15 @@ _fine_hear_request(u3_pact* req_u, c3_w cur_w) res_u->pur_u.ken_u.pat_c = c3_calloc(len_s + 1); memcpy(res_u->pur_u.ken_u.pat_c, req_u->wal_u.ken_u.pat_c, len_s); } + + // make scry cache key + // + key = _fine_scry_path(req_u, c3n); + if ( u3_none == key ) { + u3l_log("fine: bad request\n"); + _ames_pact_free(req_u); + return; + } // free incoming request // _ames_pact_free(req_u); @@ -1584,35 +1717,50 @@ _fine_hear_request(u3_pact* req_u, c3_w cur_w) // look up request in scry cache // - u3_noun key = u3nc(u3k(pat), u3i_word(res_u->pur_u.ken_u.fra_w)); u3_weak cac = u3h_git(res_u->sam_u->fin_s.sac_p, key); - if ( u3_none == cac ) { - // cache miss, scry into arvo for a page of packets - // + // already pending; drop + // + if ( FINE_PEND == cac ) { + u3l_log("fine: pend %u %s\n", res_u->pur_u.ken_u.fra_w, + res_u->pur_u.ken_u.pat_c); + _ames_pact_free(res_u); + } + // cache miss or a previous scry blocked; try again + // + else if ( (u3_none == cac) || (FINE_DEAD == cac) ) { + u3l_log("fine: miss %u %s\n", res_u->pur_u.ken_u.fra_w, + res_u->pur_u.ken_u.pat_c); c3_w lop_w = _fine_lop(res_u->pur_u.ken_u.fra_w); u3_noun pax = u3nc(c3__fine, u3nq(c3__hunk, u3dc("scot", c3__ud, lop_w), u3dc("scot", c3__ud, FINE_PAGE), - u3k(u3t(pat)))); + u3k(u3h(key)))); + // mark as pending in the scry cache + // + _fine_put_cache(res_u->sam_u, u3k(u3h(key)), lop_w, FINE_PEND); + + // scry into arvo for a page of packets + // u3_pier_peek_last(res_u->sam_u->car_u.pir_u, u3_nul, c3__ax, u3_nul, pax, res_u, _fine_pack_scry_cb); - } // cache hit, fill in response meow and send // else if ( c3y == _fine_sift_meow(&res_u->pur_u.mew_u, u3k(cac)) ) { + u3l_log("fine: hit %u %s\n", res_u->pur_u.ken_u.fra_w, + res_u->pur_u.ken_u.pat_c); _fine_etch_response(res_u); _ames_try_send(res_u, c3n); } else { - u3l_log("_fine_hear_request meow bad\n"); + u3l_log("fine: _fine_hear_request meow bad\n"); + _ames_pact_free(res_u); } u3z(key); - u3z(pat); } // TODO: check protocol version @@ -1649,7 +1797,6 @@ _ames_hear_ames(u3_pact* pac_u, c3_w cur_w) } _ames_pact_free(pac_u); - return; } // otherwise, inject the packet as an event @@ -1670,17 +1817,6 @@ _ames_hear_ames(u3_pact* pac_u, c3_w cur_w) } } -static c3_o -_ames_check_mug(u3_pact* pac_u) -{ - c3_w rog_w = HEAD_SIZE + _ames_origin_size(&pac_u->hed_u); - c3_l mug_l = u3r_mug_bytes(pac_u->hun_y + rog_w, - pac_u->len_w - rog_w); - return ( - ((mug_l & 0xfffff) == (pac_u->hed_u.mug_l & 0xfffff)) - ? c3y : c3n); -} - static void _ames_try_forward(u3_pact* pac_u) { @@ -1691,7 +1827,7 @@ _ames_try_forward(u3_pact* pac_u) && ( 0 == pac_u->pre_u.sen_d[1] ) ) ) { c3_y* old_y; - c3_w old_w; + c3_w old_w, cur_w; pac_u->hed_u.rel_o = c3y; pac_u->pre_u.rog_d = u3_ames_lane_to_chub(pac_u->rut_u.lan_u); @@ -1702,8 +1838,15 @@ _ames_try_forward(u3_pact* pac_u) pac_u->len_w += 6; pac_u->hun_y = c3_calloc(pac_u->len_w); + cur_w = 0; + _ames_etch_head(&pac_u->hed_u, pac_u->hun_y); - memcpy(pac_u->hun_y + HEAD_SIZE + 6, + cur_w += HEAD_SIZE; + + _ames_etch_origin(pac_u->pre_u.rog_d, pac_u->hun_y + cur_w); + cur_w += 6; + + memcpy(pac_u->hun_y + cur_w, old_y + HEAD_SIZE, old_w - HEAD_SIZE); @@ -1758,21 +1901,22 @@ _ames_hear(u3_ames* sam_u, // parse the header // - _ames_sift_head(&pac_u->hed_u, hun_y); + _ames_sift_head(&pac_u->hed_u, pac_u->hun_y); cur_w += HEAD_SIZE; - pac_u->typ_y = ( c3y == pac_u->hed_u.sim_o ) ? PACT_AMES : - ( c3y == pac_u->hed_u.req_o ) ? PACT_WAIL : PACT_PURR; - + pac_u->typ_y = _ames_pact_typ(&pac_u->hed_u); // check contents match mug in header // if ( c3n == _ames_check_mug(pac_u) ) { - sam_u->sat_u.mut_d++; - if ( 0 == (sam_u->sat_u.mut_d % 100000) ) { - u3l_log("ames: %" PRIu64 " dropped for invalid mug\n", - sam_u->sat_u.mut_d); - } + _log_head(&pac_u->hed_u); + sam_u->sat_u.mut_d++; + // TODO: reinstate filter after debugging is over + // if ( 0 == (sam_u->sat_u.mut_d % 100000) ) { + if ( 1 ) { + u3l_log("ames: %" PRIu64 " dropped for invalid mug\n", + sam_u->sat_u.mut_d); + } _ames_pact_free(pac_u); return; } @@ -1797,7 +1941,7 @@ _ames_hear(u3_ames* sam_u, // and we are not the recipient, // we might want to forward statelessly // - if ( 0 && (c3y == sam_u->fig_u.see_o) + if ( (c3y == sam_u->fig_u.see_o) && ( (pac_u->pre_u.rec_d[0] != sam_u->pir_u->who_d[0]) || (pac_u->pre_u.rec_d[1] != sam_u->pir_u->who_d[1]) ) ) {