mirror of
https://github.com/urbit/shrub.git
synced 2024-12-23 19:05:48 +03:00
201 lines
4.6 KiB
Plaintext
201 lines
4.6 KiB
Plaintext
:: Ping our sponsorship tree regularly for routing.
|
|
::
|
|
:: To traverse NAT, we need the response to come back from someone
|
|
:: we've sent a message to. We ping our sponsor so that they know
|
|
:: where we are. However, we also need to ping our galaxy because if
|
|
:: the other ship tries to respond directly, it may be blocked by our
|
|
:: firewall or NAT. Thus, the response must come from a ship we've
|
|
:: messaged directly, and the only one we can guarantee is our galaxy.
|
|
:: Note this issue manifests itself even for bootstrapping a planet to
|
|
:: talk to its own star.
|
|
::
|
|
/+ default-agent, verb, dbug
|
|
=* point point:kale
|
|
::
|
|
|%
|
|
:: How often to ping our sponsor when we might be behind a NAT.
|
|
::
|
|
:: NAT timeouts are often pretty short for UDP entries. 5 minutes is
|
|
:: a common value. We use 25 seconds, same as Wireguard.
|
|
::
|
|
++ nat-timeout ~s25
|
|
::
|
|
+$ card card:agent:gall
|
|
::
|
|
+$ state-3
|
|
$: %3
|
|
mode=?(%formal %informal)
|
|
pokes=@ud
|
|
timer=(unit [=wire date=@da])
|
|
galaxy=@p
|
|
==
|
|
--
|
|
::
|
|
%- agent:dbug
|
|
::
|
|
=| state=state-3
|
|
=> |%
|
|
++ galaxy-for
|
|
|= [=ship =bowl:gall]
|
|
^- @p
|
|
=/ next (sein:title our.bowl now.bowl ship)
|
|
?: ?=(%czar (clan:title next))
|
|
next
|
|
$(ship next)
|
|
::
|
|
++ wait-card
|
|
|= [=wire now=@da]
|
|
^- card
|
|
[%pass wire %arvo %b %wait (add nat-timeout now)]
|
|
::
|
|
++ ping
|
|
|= [=ship force=?]
|
|
^- (quip card _state)
|
|
?: &(!force (gth pokes.state 0) =(ship galaxy.state))
|
|
[~ state]
|
|
:_ state(pokes +(pokes.state), galaxy ship)
|
|
[%pass /ping %agent [ship %ping] %poke %noun !>(~)]~
|
|
--
|
|
%+ verb |
|
|
^- agent:gall
|
|
|_ =bowl:gall
|
|
+* this .
|
|
def ~(. (default-agent this %|) bowl)
|
|
::
|
|
:: +on-init: initializing on startup
|
|
::
|
|
++ on-init
|
|
^- [(list card) _this]
|
|
=. mode.state %formal
|
|
=. pokes.state 0
|
|
=. galaxy.state (galaxy-for our.bowl bowl)
|
|
[~ this]
|
|
::
|
|
++ on-load
|
|
|= old-vase=vase
|
|
|^
|
|
=/ old !<(state-any old-vase)
|
|
=? old ?=(%0 -.old) (state-0-to-1 old)
|
|
=? old ?=(%1 -.old) (state-1-to-2 old)
|
|
=? old ?=(%2 -.old) (state-2-to-3 old)
|
|
?> ?=(%3 -.old)
|
|
=. state old
|
|
[~ this]
|
|
::
|
|
+$ ship-state
|
|
$% [%idle ~]
|
|
[%poking ~]
|
|
[%http until=@da]
|
|
[%waiting until=@da]
|
|
==
|
|
+$ state-any $%(state-0 state-1 state-2 state-3)
|
|
+$ state-0 [%0 ships=(map ship [=rift =ship-state])]
|
|
+$ state-1
|
|
$: %1
|
|
ships=(set ship)
|
|
nonce=@ud
|
|
$= plan
|
|
$~ [%nat ~]
|
|
$% [%nat ~]
|
|
[%pub ip=(unit @t)]
|
|
== ==
|
|
+$ state-2
|
|
$: %2
|
|
ships=(set ship)
|
|
nonce=@ud
|
|
$= plan
|
|
$~ [%nat ~]
|
|
$% [%nat ~]
|
|
[%pub ip=(unit @t)]
|
|
[%off ~]
|
|
[%one ~]
|
|
==
|
|
==
|
|
::
|
|
++ state-0-to-1
|
|
|= old=state-0
|
|
^- state-1
|
|
[%1 ~ 0 %nat ~]
|
|
::
|
|
++ state-1-to-2
|
|
|= old=state-1
|
|
^- state-2
|
|
old(- %2)
|
|
::
|
|
++ state-2-to-3
|
|
|= old=state-2
|
|
^- state-3
|
|
:* %3 %formal 0 ~
|
|
=/ galaxy=(list @p)
|
|
%+ skim ~(tap in ships.old)
|
|
|=(p=@p ?=(%czar (clan:title p)))
|
|
?: =(1 (lent galaxy))
|
|
-.galaxy
|
|
(head (flop (^saxo:title our.bowl)))
|
|
==
|
|
--
|
|
:: +on-poke: positively acknowledge pokes
|
|
::
|
|
++ on-poke
|
|
|= [=mark =vase]
|
|
?. =(our src):bowl :: don't crash, this is where pings are handled
|
|
`this
|
|
::
|
|
=^ cards state
|
|
?: ?=([%kick ?] q.vase)
|
|
=? mode.state =(+.q.vase %.y)
|
|
%formal
|
|
(ping (galaxy-for our.bowl bowl) %.n)
|
|
::
|
|
?: |(=(q.vase %once) =(q.vase %stop)) :: NB: ames calls this on %once
|
|
=. mode.state %informal
|
|
(ping (galaxy-for our.bowl bowl) %.y)
|
|
`state
|
|
[cards this]
|
|
::
|
|
++ on-peek
|
|
|= =path
|
|
^- (unit (unit cage))
|
|
``noun+!>(state)
|
|
:: +on-agent: handle ames ack
|
|
::
|
|
++ on-agent
|
|
|= [=wire =sign:agent:gall]
|
|
^- [(list card) _this]
|
|
?. ?=([%ping *] wire)
|
|
`this
|
|
?. ?=(%poke-ack -.sign)
|
|
`this
|
|
=. pokes.state (dec pokes.state)
|
|
?. =(pokes.state 0)
|
|
`this
|
|
?. |(?=(%formal mode.state) ?=(^ p.sign))
|
|
`this
|
|
=/ wir /wait
|
|
=. timer.state `[wir now.bowl]
|
|
[[(wait-card wir now.bowl)]~ this]
|
|
:: +on-arvo: handle timer firing
|
|
::
|
|
++ on-arvo
|
|
|= [=wire =sign-arvo]
|
|
^- [(list card) _this]
|
|
=^ cards state
|
|
?+ wire `state
|
|
[%wait *]
|
|
?. ?=(%formal mode.state) `state
|
|
?> ?=(%wake +<.sign-arvo)
|
|
?^ error.sign-arvo
|
|
%- (slog 'ping: strange wake fail!' u.error.sign-arvo)
|
|
`state
|
|
=. timer.state ~
|
|
(ping (galaxy-for our.bowl bowl) %.n)
|
|
::
|
|
==
|
|
[cards this]
|
|
::
|
|
++ on-save !>(state)
|
|
++ on-fail on-fail:def
|
|
++ on-watch on-watch:def
|
|
++ on-leave on-leave:def
|
|
--
|