Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter idea: Simple routing with every packet having the connection id appended #8

Closed
markmandel opened this issue Jan 28, 2020 · 6 comments · Fixed by #135
Closed
Assignees
Labels
kind/design Proposal discussing new features / fixes and how they should be implemented kind/feature New feature or request

Comments

@markmandel
Copy link
Contributor

This design is not meant to necessarily be used for production workloads, but is a simple design for testing and POC work and also giving us a simple filter to get started with implementation wise that covers both a sender and receiver.

UDP Structure

The connection_id is on every packet, at the end, so as to not change data positioning.

[ game data ][ connection_id ]

Sender implementation

The Sender will append the connection_id to the end of every packet it receives, and forward that to the receiver proxies.

Configuration options:

  • connection_id: the connection_id to attach to the packet.

Receiver implementation

Configuration options:

  • length: the connection_id length at the end of the packet.
  • strip: whether to remove the connection_id before passing the packet on. Defaults to true.

Logic

The Receiver will introspect the packet for the connection_id, and query the endpoints to see which ones contain that connection_id. The packet is then routed to only the endpoints that retain that connection_id

@markmandel markmandel added kind/feature New feature or request kind/design Proposal discussing new features / fixes and how they should be implemented labels Jan 28, 2020
@markmandel markmandel self-assigned this Aug 1, 2020
@markmandel
Copy link
Contributor Author

Started work on this 👍

markmandel added a commit that referenced this issue Aug 3, 2020
Connections id's should be Vec[u8] instead of strings, as the connection
authentication tokens could easily be arbitrary data rather than
strings.

This PR implements this in the config, as well as changes the yaml
storage to be a base64 encoding of the byte array.

Implementation is done through a new type `ByteArray` which implements a
custom de/serialiser for serde to create this functionality.

Deliberately didn't use serde's de/serialize_with attributes as I
couldn't find clean way to implement this in a way that would work for
both the Vec<u8> in the Client config as well as a Vec<Vec<u8>> in the
Server configuration.

Work on #8
markmandel added a commit that referenced this issue Aug 5, 2020
Connections id's should be Vec[u8] instead of strings, as the connection
authentication tokens could easily be arbitrary data rather than
strings.

This PR implements this in the config, as well as changes the yaml
storage to be a base64 encoding of the byte array.

Implementation is done through a new type `ByteArray` which implements a
custom de/serialiser for serde to create this functionality.

Deliberately didn't use serde's de/serialize_with attributes as I
couldn't find clean way to implement this in a way that would work for
both the Vec<u8> in the Client config as well as a Vec<Vec<u8>> in the
Server configuration.

Work on #8
markmandel added a commit that referenced this issue Aug 10, 2020
* Convert connection_id's to base64 byte arraus

Connections id's should be Vec[u8] instead of strings, as the connection
authentication tokens could easily be arbitrary data rather than
strings.

This PR implements this in the config, as well as changes the yaml
storage to be a base64 encoding of the byte array.

Implementation is done through a new type `ByteArray` which implements a
custom de/serialiser for serde to create this functionality.

Deliberately didn't use serde's de/serialize_with attributes as I
couldn't find clean way to implement this in a way that would work for
both the Vec<u8> in the Client config as well as a Vec<Vec<u8>> in the
Server configuration.

Work on #8

* Implement From

* Introduce base64-serde and refactor to ConnectionId

* ConnectionId::new() -> "".into()
markmandel added a commit that referenced this issue Sep 6, 2020
Filter that appends the connection_id to each packet on the client side,
and uses it to compare against endpoint stored connection_ids to route
traffic to the appropriate game server on the server side.

Work on #8

Integration tests and Metrics are next.
markmandel added a commit that referenced this issue Sep 10, 2020
Filter that appends the connection_id to each packet on the client side,
and uses it to compare against endpoint stored connection_ids to route
traffic to the appropriate game server on the server side.

Work on #8

Integration tests and Metrics are next.
@markmandel
Copy link
Contributor Author

markmandel commented Sep 14, 2020

Coming off context in #98 (comment)

I feel like there are a few separate parts to tackle that I want to outline:

  1. Agreement: Yes, we will split this functionality up into separate filters.
  2. We will need a way to pass data between filters (which I think we can do with the new context object -- I'm working on this now)
  3. An AppendToken (or similarly named) filter that appends a byte packet to the end of a UDP packet (maybe even more generic a name if we ever want it to append or prepend?)
  4. Some kind of TokenCapture filter (can't come up with a better name), that finds the connection_id and puts it in the shared filter data storage, under a configurable key
  5. An EndpointTokenRouter (or similar name) that looks under a configurable key for that token, and matches it against an Endpoint for filtering.

A couple of thoughts/questions on this:

  1. This would mean we could get rid of the connection_id on the Client side
  2. We could likely also get rid of the connection_id on the Server Endpoint side as well - I'm wondering if xDS has some kind of arbitrary data store (like metadata, or similar) we could potentially store auth tokens against (and we could also make the key configurable from the router)

Figuring this will also make xDS config easier as well. WDYT?

@iffyio
Copy link
Collaborator

iffyio commented Sep 15, 2020

I'm wondering if points 4 and 5 could be merged together? Since the TokenCapture filter implementation will be trivial and mostly be used together with the EndpointTokenRouter - since the router filter will likely be used in a lot of cases it would be nice if its easier to configure, avoiding configs of two filters (and figuring out what key the capture filter places the token in order to configure the router filter)

From the looks of it, it seems the XDS api has both endpoint metadata support and Config for filters if we need that as well - we should be able to use them for e.g tokens

@markmandel
Copy link
Contributor Author

So my thought with splitting 4 + 5 - was that if you had a different strategy to capture the token (maybe something unique to your game), you could still use the Router once the data was stored in the Context object, without having to write it yourself (even though the logic is pretty straight forward).

It's sounding like we'll be able to drop connection_id though -- we could store tokens either on endpoint metdata or within the config of the filter itself.

Question - I was looking at this Endpoint proto -- which doesn't seem to have metadata? Is that the same Endpoint we use in xDS? (I need to dig into that PR soon!)

@iffyio
Copy link
Collaborator

iffyio commented Sep 15, 2020

So my thought with splitting 4 + 5 - was that if you had a different strategy to capture the token (maybe something unique to your game), you could still use the Router once the data was stored in the Context object, without having to write it yourself (even though the logic is pretty straight forward)

Ah yeah that makes sense, it would be harder to do if we had that part inside the router, splitting them sounds good!

Question - I was looking at this Endpoint proto -- which doesn't seem to have metadata? Is that the same Endpoint we use in xDS? (I need to dig into that PR soon!)

Yes its pretty much the same, the one you linked (contains the actual address for the endpoing) is nested within the one I linked (which includes other metadata for that endpoint) - most of the api objects are quite large and nested like that 😬

markmandel added a commit that referenced this issue Sep 17, 2020
Add a `values` of with a `HashMap` of `Any` to the filter context
objects and results, and update the FilterChain to pass that Map between
each invocation of a Filter in the chain.

Work on #8
markmandel added a commit that referenced this issue Sep 17, 2020
Add a `values` of with a `HashMap` of `Any` to the filter context
objects and results, and update the FilterChain to pass that Map between
each invocation of a Filter in the chain.

Work on #8
markmandel added a commit that referenced this issue Sep 17, 2020
Add a `values` of with a `HashMap` of `Any` to the filter context
objects and results, and update the FilterChain to pass that Map between
each invocation of a Filter in the chain.

Work on #8
markmandel added a commit that referenced this issue Sep 17, 2020
* Be able to pass data between Filters

Add a `values` of with a `HashMap` of `Any` to the filter context
objects and results, and update the FilterChain to pass that Map between
each invocation of a Filter in the chain.

Work on #8
markmandel added a commit that referenced this issue Sep 19, 2020
The `ConcatBytes` filter's job is to add a byte packet to either the
beginning or end of each UDP packet that passes through. This is
commonly used to provide an auth token to each packet, so they can be
routed appropriately.

This also includes implementing `Filter` on `Box` to make reusable test
assertion functions easier to write.

Next step will be to remove `connection_id` from the Client config.

Work on #8
markmandel added a commit that referenced this issue Sep 21, 2020
The `ConcatBytes` filter's job is to add a byte packet to either the
beginning or end of each UDP packet that passes through. This is
commonly used to provide an auth token to each packet, so they can be
routed appropriately.

This also includes implementing `Filter` on `Box` to make reusable test
assertion functions easier to write.

Next step will be to remove `connection_id` from the Client config.

Work on #8
markmandel added a commit that referenced this issue Oct 13, 2020
The `ConcatBytes` filter's job is to add a byte packet to either the
beginning or end of each UDP packet that passes through. This is
commonly used to provide an auth token to each packet, so they can be
routed appropriately.

This also includes implementing `Filter` on `Box` to make reusable test
assertion functions easier to write.

Next step will be to remove `connection_id` from the Client config.

Work on #8
markmandel added a commit that referenced this issue Oct 14, 2020
* Concat Byte Filter

The `ConcatBytes` filter's job is to add a byte packet to either the
beginning or end of each UDP packet that passes through. This is
commonly used to provide an auth token to each packet, so they can be
routed appropriately.

Next step will be to remove `connection_id` from the Client config.

Work on #8
markmandel added a commit that referenced this issue Oct 22, 2020
Since the inclusion of the connection id token is being processed as a
filter, we no longer have a need for connection_id in the client
configuration.

Work on #8
markmandel added a commit that referenced this issue Oct 23, 2020
Since the inclusion of the connection id token is being processed as a
filter, we no longer have a need for connection_id in the client
configuration.

Work on #8
@markmandel
Copy link
Contributor Author

Working on the router at the moment, just need to wrap up some docs, and it'll be good to submit as a PR.

I couldn't work out a good name for it - settled on "ConnectionIdRouter" just because we have this concept (currently) of a connection id on an Endpoint.

Anyone got any better ideas?

Some random thoughts as they come to me now, as we've been taking through concepts:

  • EndpointAuthRouter
  • EndpointAuthentication (Don't mind this either on review)
  • EndpointRouter (feels to generic to me though)
  • EndpointMetadataRouter (actually I don't mind this now xDS is coming through Proxy config file format #130)

I was trying to have something about a "token" or something in the name, but maybe that's not neccessary?

markmandel added a commit that referenced this issue Nov 14, 2020
Implementation of the filter that will route
packets to Endpoints that have a matching
connection_id to the auth token found in the
dynamic metadata.

Closes #8
markmandel added a commit that referenced this issue Nov 18, 2020
Implementation of the filter that will route
packets to Endpoints that have a matching
connection_id to the auth token found in the
dynamic metadata.

Closes #8
markmandel added a commit that referenced this issue Nov 19, 2020
Implementation of the filter that will route
packets to Endpoints that have a matching
connection_id to the auth token found in the
dynamic metadata.

Closes #8
markmandel added a commit that referenced this issue Nov 24, 2020
Implementation of the filter that will route
packets to Endpoints that have a matching
connection_id to the auth token found in the
dynamic metadata.

Closes #8
markmandel added a commit that referenced this issue Nov 25, 2020
Implementation of the filter that will route
packets to Endpoints that have a matching
connection_id to the auth token found in the
dynamic metadata.

Closes #8
markmandel added a commit that referenced this issue Nov 25, 2020
* TokenRouter filter

Implementation of the filter that will route
packets to Endpoints that have a matching
connection_id to the auth token found in the
dynamic metadata.

Closes #8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/design Proposal discussing new features / fixes and how they should be implemented kind/feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants