-
Notifications
You must be signed in to change notification settings - Fork 21
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
Add TCP port information to NetAddr #12
Open
bgola
wants to merge
3
commits into
supercollider:main
Choose a base branch
from
bgola:master
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
- Title: Add TCP port information to NetAddr | ||
- Date proposed: 2020-07-20 | ||
- RFC PR: https://github.com/supercollider/rfcs/pull/0012 | ||
|
||
# Summary | ||
|
||
Currently it is not possible to directly access an open TCP socket from sclang. This RFC proposes a way to access the metadata of the socket created when calling NetAddr.connect method so the user can listen to messages coming back from that socket. | ||
|
||
# Motivation | ||
|
||
One of the differences between TCP and UDP is that in UDP the connecton is usually not kept alive. The sender of a message simply sends the UDP package and does not bother if the package arrives, is actually sent, or even if the host exists. In TCP a connection between both points must be made before any packages are sent, and this connection is kept open until one of the ends closes it. This usually means that the sender opens a random port locally to receive incoming data from the other end of the TCP connection. One of the advantages of TCP is that a host behind a NAT or a complex network routing can open a connection to a public IP on the internet and, because the connection is two-way, the host receiving the connection can send messages back through the opened channel without the need to know the route or how to solve NAT routing and so on. This is not possible with UDP, when both ends need to know the IP of each other to exchange messages. | ||
|
||
While it is possible to open TCP connections from sclang using `NetAddr.connect` currently it is not possible to get any information about the opened socket, making it difficult to listen back to messages sent on that channel. For example in the [OSCRouterClient Quark](https://github.com/aiberlin/HyperDisCo/blob/master/Classes/OSCRouterClient.sc#L95) it needs to call `this.addOSCRecvFunc` with a generic function that will listen to any incoming message on any port, and add some information on the application protocol layer (in this case the randomId assigned when the first call to the other end of the connection is made) so we can check back and assign the correct TCP port to that socket. | ||
|
||
The proposal in this RFC is to expose the metadata of the socket, especially the port it listens to, so we can do things like `n = NetAddr(addr, port); OSCFunc({}, n.tcpRecvPort);` and directly listen to messages received in that that opened socket. | ||
|
||
# Specification | ||
|
||
Adds the instance attribute `tcpRecvPort` to `NetAddr`, an integer representing the locally opened port for a TCP connection. It is `nil` by default and is only set after `.connect` or `.tryConnectTCP` is called. | ||
|
||
# Drawbacks | ||
|
||
|
||
# Unresolved Questions | ||
|
||
Are there other information to be added to `NetAddr` that might be useful in the context of TCP sockets? |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When receiving a UDP message, we also receive the sender address:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the problem is if both peers are not in the same network or if the IP of the sender is not directly accessible. example:
I'm behind a router with internet IP 194.42.123.98, my computer local IP is 192.168.8.42 and I send a UDP package to a public IP / host (for example if there is a server listening on scsynth.org port 57120).
The package arrives there with my router IP (194.42.123.98) the software running on scsynth.org tries to send me an UDP message back using that IP, but my router has no idea about where it should send this package to inside the network unless I configure Port Forward in the router (telling it that any packages arriving on 57120 should be sent to 192.168.8.42).
With TCP the connection is kept on and the route between scsynth.org and my computer inside the network is still reachable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest not making assumptions about peoples NAT situation. As an aside, in normally working NAT replies should be correctly delivered because of the routing table. It's making initial connections to computers behind NAT that usually requires configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but a UDP reply (as in the scenario I described) is basically making an initial connection to a computer behind NAT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, normally when an internal address and port sends to an external one, replies are expected and routed accordingly. Otherwise no external to internal messages would be possible.
We did a remote recording for NIME this week with a shared server and Utopia Registrar that worked exactly like this. Port forwarding was only needed on the NAT at the server end as all clients sent out a /notify message. It's possible something else is going on in your situation (like a very short translation timeout), and I know there are some exotic forms of NAT, but normally the translation table just takes care of this.
TCP on its own of course will not solve the NAT problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are correct @muellmusik that the translation will occur and I didn't know that sendMsg will open that port locally. So I tried now and it works:
OSCdef(\x, { |msg, time, addr| addr.postln }, '/test').add
and then on my machine:
NetAddr("bgo.la", 57120).sendMsg('/test');
and on bgo.la I get:
a NetAddr(95.91.208.191, 9435)
If I send back from bgo.la to that address in port 9435 I am able to get it back on my machine. So, somehow NetAddr is opening the port to listen. I guess the issue with TCP then is that once you do NetAddr.connect it won't register OSCFunc/Def to that TCP port?