Merge branch 'lf/content-dist-rc-testnet' into yu/content-dist-fallback

This commit is contained in:
yosoyubik 2022-06-06 11:09:50 +02:00
commit 297a2de9bc
10 changed files with 576 additions and 386 deletions

3
bin/ropsten-ivory.pill Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:666fb799fb714579e17a919cc81e8e28c178e9dbb6af7bc01cd9593aad7adf37
size 2336718

3
bin/ropsten-solid.pill Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:74f8043eec22ecea43294fb4c41bd0006aa5c382ca41e4e84476692f44edf6cd
size 6826461

View File

@ -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]
::

View File

@ -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: {<sndr.packet>} -> {<rcvr.packet>}")
:: set .origin.packet if it doesn't already have one, re-encode, and send
%- %^ trace for.veb sndr.shot
|.("forward: {<sndr.shot>} -> {<rcvr.shot>}")
:: 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

View File

@ -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 {<pour.leak>}: creating" ~)
:: %- (slog leaf+"ford: cache {<pour.leak>}: 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 {<leak>}" ~)
:: %- (slog leaf+"ford: lose missing leak {<leak>}" ~)
fad
?: (lth 1 refs.u.got)
=/ tape "ford: cache {<pour.leak>}: decrementing from {<refs.u.got>}"
%- (slog leaf+tape ~)
:: =/ tape "ford: cache {<pour.leak>}: decrementing from {<refs.u.got>}"
:: %- (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 {<leak>}" ~) ~)
%- (slog leaf+"ford: cache {<pour.leak>}: freeing" ~)
~ :: ((slog leaf+"ford: lose zero leak {<leak>}" ~) ~)
:: %- (slog leaf+"ford: cache {<pour.leak>}: 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
::

View File

@ -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

View File

@ -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]~)

View File

@ -78,7 +78,7 @@
:: # constants
::
:: contract addresses
++ contracts mainnet-contracts
++ contracts ropsten-contracts
++ mainnet-contracts
|%
:: azimuth: data contract

View File

@ -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]) ) )
{