Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@leowini
Copy link

@leowini leowini commented May 29, 2022

@belisarius222
Submitting for feedback:

  • replaced origin field with the next field
  • added two bits to the packet header for scry notifications packet type
  • added the relay-state data structure to the ames-state
  • changed send-blob to send-packet
  • +on-hear-packet:
    1. Add the ship to the sponsees map if the packet is from a sponsee and not forwarded.
    2. Add the lane to the pending map.
    3. Update the pending map next lane if the packet has a next field.
  • +send-packet
    1. If we are the sponsor of rcvr.packet, send to the lane from the sponsees map.
    2. If we are not the sponsor, try to get the lane from the pending map.
    3. If we don't know rcvr.packet, send to its sponsoring galaxy.
    4. Write the next field if forwarding
      TODOs
  • Update the ames-state to remove routes completely
  • Update the scry paths since previous routing system is deprecated - need guidance on specifics
  • testing
  • handle upgrading

leowini added 2 commits May 28, 2022 08:00
+on-hear-packet updates the pending and sponsees maps.
+send-packet gets the lane(s) to send the packet to from the
relay-state and writes the next field if forwarding.
Behn is used to delete lanes from the pending and sponsees maps after
30s without activity.
%+ can 0
:~ [3 reserved=0]
:~ [1 reserved=0]
[2 packet-type=0]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need at a bit to represent "is this a request?", i.e. not a response. The is-ames bit should also be consolidated into the 2-bit packet-type field to save space, and of course this function should return these new values -- my inclination would be to add the fields to the $packet type.

This is a note as much to myself as to you:

Something to keep in mind with this sort of change to the packet format is that we should ensure packets at this version are discriminable from older packets. In this case it's good enough just to look at the protocol version, but I was hoping each protocol could develop its own version to enable per-protocol updates later. We could probably still do that, though, by looking at both the protocol version bits and the packet-type bits.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would the request/response bit be used for? My current implementation is request/response agnostic. I'm setting the next lane on every forwarded packet. Is this a bad idea?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's legitimate, though maybe not useful, for a relay to set the .next field unconditionally. The relay needs to know where to forward the packet, though, which is why I think we need the request/response bit.

In Ames's current asymmetric routing, the relay doesn't care whether a packet is a request or response, so it forwards the packet to some of the destination ship's sponsors list either way. Symmetric routing needs to route responses differently from requests, though.

In symmetric routing, only the requesting ship needs to send a packet to potentially multiple sponsors. All other ships just send to a single lane. A ship in the responder's sponsors list relays a request down to the next ship down the sponsorship chain, which might be the responder ship itself. A ship sends or relays a response on whatever lane it heard the request packet come from, which is either its immediate sponsor's lane or the requester's lane.

You could almost look this up from PKI information, since if a packet's sender is our transitive sponsee and the receiver is not, it's a response, and if the receiver is our transitive sponsee and the sender is not, it's a request. However, if both sender and receiver ships are our transitive sponsees, then we don't know whether it's a request or response, so it's not clear how to maintain the symmetry of the routing.

If we use a request/response bit in the packet instead, there's no ambiguity, and figuring out the destination ship is more straightforward. If it's a request, find the next sponsor in the sponsors list for that ship. If it's a response, send it back on the lane it came from.

Unfortunately, to forward requests, a relay does still need to look up PKI information for the destination ship, to find its sponsors. It's not a huge problem, but it does increase the amount that the forwarding code needs to interact with Arvo to read PKI information -- ideally a relay could have very minimal state. So a future design might improve upon that, but I don't know how just yet, and it might not be possible without tradeoffs (such as giving the requesting ship more control over the route its packet will take through the routing hierarchy, which isn't necessarily a good thing).

Copy link
Author

@leowini leowini Jun 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense to me. I can change the logic to treat requests and responses differently, but I'm not sure it's necessary.
My current relay logic works like this:

  1. If we have a lane for sndr to rcvr in the pending map, use that.
  2. If we are the direct sponsor of the rcvr, send to rcvr. (rcvr is in our sponsees map)
    --> otherwise, +try-next-sponsor up the sponsorship chain in case rcvr is our transitive sponsee
  3. If we don't have an entry for the request in the pending map AND the rcvr isn't our direct or transitive sponsee, send to the rcvr's galaxy.

Regardless of request/response, +on-hear-packet stores [[rcvr sndr]] [lane (unit next-lane)] in the pending map. I think this handles the routes correctly and maintains symmetry without needing to treat requests and responses differently.

Example:

request: ~rovnys -> ~syl -> ~sipsyl -> ~ritpub-sipsyl -> ~mister-ritpub-sipsyl

~rovnys has no record of ~mister-ritpub-sipsyl in the pending requests map and is not a sponsor, so it sends the packet to the ~syl galaxy.
As the request is routed, each relay will enter [[~mister-ritpub-sipsyl ~rovnys] [previous-lane previous-previous-lane]] in its pending map. e.g. ~sypsyl will have [[~mister-ritpub-sipsyl ~rovnys] [(~syl's lane) (~rovnys's lane)]].

response: ~rovnys <- ~syl <- ~sipsyl <- ~ritpub-sipsyl <- ~mister-ritpub-sipsyl

On the way back, the relay's all have entries in their pending map for [~mister-ritpub-sipsyl ~rovnys], so they will send the packet to both lane and the next-lane.
As the request is routed, each relay will enter [[~rovnys ~mister-ritpub-sipsyl] [previous-lane previous-previous-lane]] in its pending map. e.g. ~sypsyl will have [[~rovnys ~mister-ritpub-sipsyl] [(~ritpub-sipsyl's lane) (~mister-ritpub-sipsyl's lane)].

Then, on the next request, the relays have entries in their pending map going both ways. Each relay has an entry in the pending map for [~rovnys ~mister-ritpub-sipsyl] and an entry for [~mister-ritpub-sipsyl ~rovnys]. i.e. after the first request, only the pending map is used to route packets. The result is that all of the relays then try to tighten the route in both directions.

Copy link
Collaborator

@belisarius222 belisarius222 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a cursory initial review. Some nits, but this looks very promising.

@belisarius222
Copy link
Collaborator

belisarius222 commented Jun 3, 2022 via email

@leowini
Copy link
Author

leowini commented Jun 5, 2022

It would be possible for a small number of packets to take a tighter route on the way back if the route tightens while the packet is at the destination. However, the route will only tighten if there is a known path to the destination on the tightened route (the packet will only tighten a route to the next lane if it receives a packet from that lane). Essentially, all packets will take the tightest known route to the destination both ways. Is there an issue with breaking strict symmetry in this way?

~/ %send-blob
|= [for=? =ship =blob]
++ send-packet
|= [for=? next-lane=(unit lane) =packet]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As next-lane is a unit, is for redundant?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I think so I'll get rid of it

::
=/ =blob (encode-packet packet)
(send-blob & rcvr.packet blob)
(send-packet & `lane packet)
Copy link
Contributor

@dnmfarrell dnmfarrell Jun 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a caller of on-hear-forward which provides lane- am I be missing something?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on-hear-forward gets called in on-hear-packet, with the same sample as on-hear-packet.

 %.  +<
 ::
 ?.  =(our rcvr.packet)
    on-hear-forward

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracing this back: it seems that +call correctly passes lane when dud is a cell by extracting it from the task lane.task on line 1065. Otherwise is passes lane (line 1071) which I don't see in the sample at that point - is it passing the type $lane and not the value?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still getting the lane and blob from the task: [lane blob ~]:task. The dud looks like a stack trace in case of a crash (I think in the arvo kernel).

!=(%czar (clan:title ship))
==
=/ final-ship rcvr.packet
%- (trace rot.veb final-ship |.("send-packet: to {<ship>}"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be {<final-ship>} as ship is no longer an alias of final-ship?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I'll change that

::
+$ relay-state
$: pending=(map ship [(pair lane (unit lane)) expiry=@da])
sponsees=(map ship [lane expiry=@da])
Copy link
Contributor

@dnmfarrell dnmfarrell Jun 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't pending going to have both rcvr and sndr ships in it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that was the original design. I noticed that the relays only need to know the destination, so I'm pretty sure it's okay to drop the sender. e.g. if a relay knows the lane of ~zod, it shouldn't matter where the relayed packets are coming from. It just sends them to ~zod's lane.

@zalberico
Copy link
Contributor

This PR needs an associated issue for symmetric routing.

@zalberico
Copy link
Contributor

In discussion with @belisarius222 he's going to focus on this as part of his roadmap work and we'll create an issue then that references the important bits when we get to it. As is, we're going to close this PR for now until we're working on it.

@zalberico zalberico closed this Nov 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants