mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 22:33:06 +03:00
ames: fix lane discovery during some lane changes
We used to not accept new indirect lanes if we already have a direct lane. This means that if Bob, with a publicly-accessible lane, changes lanes (eg by restarting the process and getting a new port or changing ip addresses), tries to talk to Alice, who is behind a NAT, then Bob will try directly but fail (because Alice is behind a NAT), so he will route the message through her galaxy. This is good -- the message gets to Alice. However, Alice had a direct route to Bob's old lane, so she will try to ack on that lane, which fails. She will not time out this lane because she doesn't know that Bob isn't getting the acks (acks don't have their own acks). The solution is that if Alice receives an indirect lane for Bob when she already has a direct lane, she shouldn't ignore it. If the lane is the same as what she has, she shouldn't change anything (in particular, she shouldn't mark it as indirect). But if it's a new lane, she should discard her old direct lane and use the new indirect lane.
This commit is contained in:
parent
c96705e755
commit
1d0409c4c4
@ -1121,17 +1121,32 @@
|
||||
?> =(rcvr-life.shut-packet our-life.channel)
|
||||
:: non-galaxy: update route with heard lane or forwarded lane
|
||||
::
|
||||
=? route.peer-state
|
||||
?: =(%czar (clan:title her.channel))
|
||||
%.n
|
||||
=/ is-old-direct=? ?=([~ %& *] route.peer-state)
|
||||
=/ is-new-direct=? ?=(~ origin.packet)
|
||||
:: old direct takes precedence over new indirect
|
||||
::
|
||||
|(is-new-direct !is-old-direct)
|
||||
=? route.peer-state !=(%czar (clan:title her.channel))
|
||||
:: if new packet is direct, use that. otherwise, if the new new
|
||||
:: and old lanes are indirect, use the new one. if the new lane
|
||||
:: is indirect but the old lane is direct, then if the lanes are
|
||||
:: identical, don't mark it indirect; if they're not identical,
|
||||
:: use the new lane and mark it indirect.
|
||||
::
|
||||
?~ origin.packet
|
||||
:: if you mark lane as indirect because you got an indirect
|
||||
:: packet even though you already had a direct identical lane,
|
||||
:: then delayed forwarded packets will come later and reset to
|
||||
:: indirect, so you're unlikely to get a stable direct route
|
||||
:: (unless the forwarder goes offline for a while).
|
||||
::
|
||||
:: conversely, if you don't accept indirect routes with different
|
||||
:: lanes, then if your lane is stale and they're trying to talk
|
||||
:: to you, your acks will go to the stale lane, and you'll never
|
||||
:: time it out unless you reach out to them. this manifests as
|
||||
:: needing to |hi or dotpost to get a response when the other
|
||||
:: ship has changed lanes.
|
||||
::
|
||||
?: ?=(~ origin.packet)
|
||||
`[direct=%.y lane]
|
||||
?: ?=([~ %& *] route.peer-state)
|
||||
?: =(lane.u.route.peer-state u.origin.packet)
|
||||
route.peer-state
|
||||
`[direct=%.n u.origin.packet]
|
||||
`[direct=%.n u.origin.packet]
|
||||
:: perform peer-specific handling of packet
|
||||
::
|
||||
|
Loading…
Reference in New Issue
Block a user