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

Bind Quilkin's sender socket to a given address:port #345

Open
davidkornel opened this issue Jul 21, 2021 · 5 comments
Open

Bind Quilkin's sender socket to a given address:port #345

davidkornel opened this issue Jul 21, 2021 · 5 comments
Labels
area/networking Related to networking I/O area/user-experience Pertaining to developers trying to use Quilkin, e.g. cli interface, configuration, etc good first issue Good for newcomers help wanted Extra attention is needed kind/feature New feature or request

Comments

@davidkornel
Copy link

This is a feature proposal issue
It would be nice to be able to bind Quilkin's sender socket to a given address and port pair. When Quilkin proxies the packets to an upstream host server, it chooses a random socket to use. This feature would remove the randomness and allow us to control which address and port pair to use.

Why do we need this?

  • The first reason behind this feature request is that our telco use-case uses RTPengine as a backend RTP proxy. RTPengine supports resilience using a Redis store, but due to its design, it stores the connection's port number as well. So when it comes to resilience the second RTPengine will read call the call record from the Redis store and proxy the packets to a port that was used by the first RTPengine... Port binding would solve this.
  • The second design issue is that RTPengine thinks that it's talking directly to a client and not to some proxy. In a call setup, there are initiating SDP messages that include the client's sender port. When the RTPengine gets these SDP messages it expects the media stream to come from that port number that was in the SDP control messages. There are workarounds but the best solution would be to bind the sender socket to that very port.

We are using a separate control and media plane, and dynamically (via an XDS server) create a media plane pipeline for every single RTP/RTCP stream. After the mentioned SDP messages we would know where to bind the sender socket.

Not sure if this should be a filter or not. Or in general how the configuration would look like? What do you think about this?

@XAMPPRocky XAMPPRocky added the kind/feature New feature or request label Jul 21, 2021
@XAMPPRocky
Copy link
Collaborator

XAMPPRocky commented Jul 27, 2021

Thank you for your issue! This should be relatively straightforward to add to Quilkin, we need to add a upstream_addr: or equivalvent to the proxy configuration, and then in our implementation, we change the upstream socket to be Arc<UdpSocket>, which is either a new dynamically allocated socket or the socket defined from upstream_addr: if set.

@XAMPPRocky XAMPPRocky added area/user-experience Pertaining to developers trying to use Quilkin, e.g. cli interface, configuration, etc good first issue Good for newcomers help wanted Extra attention is needed labels Jul 27, 2021
@XAMPPRocky XAMPPRocky added the area/networking Related to networking I/O label Oct 11, 2021
@hellof20
Copy link

hello, any update about this feature?

@XAMPPRocky
Copy link
Collaborator

@hellof20 Hello, no there's been no work on it yet, we're currently focused on xDS support in Quilkin, a PR is always welcome!

@markmandel
Copy link
Contributor

markmandel commented May 20, 2022

Was just digging into the PR (thanks so much btw!) and it made me realise some concerns that make me wonder if this is viable (or maybe need to take a different approach).

Quilkin is built to be non-transparent, so that may be the issue here that could be blocking for this specific use case.

In the PR as I noted in a comment if we have only a singular address/port combo as the sending port, then each Session's key is no longer unique combo of receiver and ephemeral address and port - which may have some unintended consequences.

In the current model as well, each Session can watch it's own Socket, since it's unique:

received = socket.recv_from(&mut buf) => {

But if the socket is shared in this scenario - which part of Quilkin listens for incoming packets from usptream endpoints, and how do we determine which downstream client that a packet is supposed to go to if they are sharing the port?

I'm concerned this current config solution of a singular upstream_address only works if you have one client to one one endpoint, but not if you have multiple clients and/or multiple endpoints (anything that forces multiple sessions).

If we had a address per-endpoint, that solves part of the problem (multiple endpoints), but still leaves us with the problem of how to handle multiple downstream clients creating multiple sessions all bound to the same port.

So... I'm not quite sure how we can facilitate the currently proposed design 🤔 or come up with a new design that will work to solve the outlined problems.

Do we need a mode that assumes a singular UDP client->server connection maybe? (feels a bit weird), or some kind of other control over which port a Session creates? (or maybe a way to somehow tell Quilkin to reuse some ports on disconnect or something?)

Thoughts?

@markmandel
Copy link
Contributor

I had two other potential thoughts over the weekend, but I'm not familiar with this protocol, but thought I would run them by you, see if they would work out:

  1. Configurable Session timeout

I think those might help in your circumstances, since you could set a timeout that aligns with your system, and potentially avoid/reduce the issue where the port the RTPengine is expecting is still up and working.

I also figured we'll have to do this at some point anyway 😄

  1. Sequential sender port assignment

Basically have an option to turn off ephemeral port assignment, and instead use a sequential system starting from a configured value.

This would take some logic on the Quilkin side, since if you assigned 8000, 8001 and 8002, and the Session tied to 8001 drops, then rather than assign 8003 on the next Session creation, you would go back to 8001 - but this is not impossible.

This would require some port management in the end user side, but would mean you would know the range of sending ports, based on how many client connections and endpoints you have. If you only have a single connection to a single endpoint, then you also know what your sending port is (the configured lowest value in the sequence).

Does that work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/networking Related to networking I/O area/user-experience Pertaining to developers trying to use Quilkin, e.g. cli interface, configuration, etc good first issue Good for newcomers help wanted Extra attention is needed kind/feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants