stunclient: connect() UDP socket to STUN server#67
Open
Kimapr wants to merge 1 commit intojselbie:masterfrom
Open
stunclient: connect() UDP socket to STUN server#67Kimapr wants to merge 1 commit intojselbie:masterfrom
Kimapr wants to merge 1 commit intojselbie:masterfrom
Conversation
the purpose is so that when the socket has the Linux SO_REUSEPORT option set, and another program listens on the same port as stunclient, the kernel knows to route the STUN response to stunclient rather than the other program. stunclient currently offers no option to set SO_REUSEPORT on the socket, but if it's somehow set externally this is still useful, and doesn't break anything if it isn't. since the Filtering Test involves receiving the response from a different address, unconnected socket is used for it as usual.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
I have a Bash script that uses stunclient to perform Full Cone NAT traversal for server applications that are unaware of NAT: https://git.kimapr.net/kimapr/fcnatfw
The way it works, is the script first opens as many port mappings as it can using UPnP, and then pings a STUN server repeatedly forever, using stunclient, which is bound to a specific port using
--localport. The server application is bound to the same port as stunclient, and this should result in external internet users being able to connect to the server application using the address printed by the script. To make both stunclient and the server application be able to use the same port, a shared library with a hackedsocket(2)function that sets the non-standardSO_REUSEPORToption on all internet sockets is interposed usingLD_PRELOAD(important to note that this relies on Linux specifics ofSO_REUSEPORTimplementation — other systems have very different semantics for it, and even Linux doesn't seem to document at all what should happen when the feature is used in the way I am using it. Might be possible to achieve similar results withSO_REUSEADDRbut I am not sure (doesn't help that the docs don't explain at all what it really does), andSO_REUSEPORTis still better either way as it prevents other users from binding on the port whileSO_REUSEADDRseems not to).This approach works well for TCP, and I have been able to expose a web server to the internet from my laptop through 2 levels of home router NAT + 1 CGNAT. However, with UDP, Linux can't distinguish stunclient's unconnected socket from the server application's listening socket, and sometimes it would route STUN response messages to the server application instead of stunclient, or vice versa. By connecting stunclient's UDP socket to the STUN server during a binding request this is avoided, as the kernel now knows that stunclient is the intended recipient of the STUN server's response packets, and is not interested in packets from other peers.
The change shouldn't affect normal operation. Tested on Linux 6.17.12, basic binding and behavior and filtering tests continue working as expected. Might also be useful to add an option to set
SO_REUSEPORTand such on sockets in stunclient on platforms that support this, though this is not as important to me as I have a crude and evil way to do this already.To test the problem:
fcnatfwfrom linked repository like this:fcnatfw 21010 udp(stunclient as well as a few other programs should be in PATH)fcnatwrap ncat -k -l -c 'echo meow; cat > /dev/stderr' --udp 21010at the same time as fcnatfw