-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
lib/connections: Try TCP punchthrough #5753
Conversation
7a3d4da
to
e7f9794
Compare
e7f9794
to
461a70b
Compare
Ready for review maybe? Given 1.2.0 is out, and quic has not broken the world, let's try to do it again. |
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.
Looks good generally, mostly nitpicks below.
Is my understanding of the mechanism correct: We now dial and listen on the same port. We announce an unspecified address to the discovery server, which then uses the port of the announcement. We expect this to be the same port that the NAT assigned to where we are listening/dialing on. The remote then uses that port for dialing, and thus we manage to dial and listen on the same port.
I've addressed the review comments and unmarked some comments as done as it's not for me to judge when it's done. |
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 am totally fine with you dismissing my utterly nit-picky and/or opinionated comments - it's still nice when you let me mark them done just for convenience when reading your answers ;)
I like the sneak attack, but I think there's a problem with how it's done currently. The other two comments are even worse nitpickery than before, ignore at will.
Otherwise this is lgtm from my side. I didn't look up the low-level stuff (syscall), I am sure you got that right.
Editing on the mobile on a train, yay. Time for @calmh? |
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.
Looks reasonable, I'm going to see if I can do some testing...
if localAddrInterface != nil { | ||
if addr, ok := localAddrInterface.(*net.TCPAddr); !ok { | ||
return nil, errUnexpectedInterfaceType | ||
} else { |
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.
if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (from golint
)
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.
You are fucking stupid.
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.
Hey, it's right although you may not agree with the style choice
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 struggle to understand where the suggested style choice would be better.
The old go version check (go1.10.7) fails due to |
So the announce part seems to work for me.
And log the announcement addresses before and after the "fixup"
I suspect the problem you've seen is because nginx/caddy fronting the server does not forward the port in X-Forwarded-Port. |
How do we take this forward? |
Some kind of reasonable testing I guess. Have you run this and seen it work? If so I'll take it for another spin and we can debug any issues. Last time I had the feeling it was all theoretical and hence I wasn't sure whether to debug my network or just assume that things didn't work as intended... |
Well the only thing I tested is that the source address connecting to discovery is port 22000, and that discovery correctly substitutes port 0 with that port (on a local discovery server). I have not tested actual punch through capabilities as I don't have two devices behind different domestic routers. |
I think the best way forward with this would be to cherry-pick and deploy the discovery changes and adding support for X-Forwarded-Port. This should have no effect. Then run with this PR for a week to verify it doesn't break anything existing in your setup, and then just merge it on good will and see if anything comes from the RC? |
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.
Your plan from a week ago (sorry for the delay) sound good. If it works at all should be well discernable from the transport usage reporting and if it doesn't, reverting is easy (as longs as we don't redesign dialing in the meantime).
if remote != nil { | ||
if host == "" || ip.IsUnspecified() { |
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.
Could be remote != nil && (host == "" || ip.IsUnspecified())
removing the need for an additional indentation.
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.
There is a block after the nested if which would have to repeat remote != nil
then.
Soo, approve and lets go? 👯 |
Only @calmh can deploy, so the ball is in his court now, isn't it? |
I actually did deploy the discovery servers from this a while back (still running), but I can do so again. I'm generally not super excited about merging code that the person who wrote it hasn't been able to test at all for whether it actually does what it's supposed to, but if there's confidence that it doesn't sabotage existing connection setup and a plan for actual post-merge testing and reporting back, sure. |
So looking at this it seems we want |
* main: (37 commits) various: Master is now main lib/model: Fix minor flakiness in TestModTimeWindow cmd/ursrv: Attempt to fix js failure to load (syncthing#6747) lib/osutil: Use filepath.Join in tests (syncthing#6740) cmd/strelaysrv: Fix JSON unmarshalling when joining a relay pool (fixes syncthing#6733) (syncthing#6729) gui, man, authors: Update docs, translations, and contributors build(deps): bump github.com/lucas-clemente/quic-go (syncthing#6722) lib/db: Remove unused keyer methods (syncthing#6723) gui: Fix auto dismissing auth notification (ref syncthing#6536) lib/scanner: Save one stat call per file (syncthing#6715) gui: Ignore permissions isn't just about FAT (syncthing#6713) lib/connections, lib/nat: Correctly dis-/enable nat (fixes syncthing#6552) (syncthing#6719) gui: Fix string and update translations (ref syncthing#6536) (syncthing#6716) lib/protocol: Avoid panic in DeviceIDFromBytes (syncthing#6714) build: Fix rebuild of strelaypoolsrv assets cmd/strelaysrv: Add note about relay operators cmd/stcrashreceiver: Pick up extra build tags and send to Sentry (syncthing#6710) lib/build: Add some env vars as synthetic build tags (syncthing#6709) build(deps): bump github.com/lucas-clemente/quic-go (syncthing#6695) gui, man, authors: Update docs, translations, and contributors ...
Well some cursory testing at home seems to indicate it doesn't in fact fuck anything up beyond repair, so that's good 👍 |
You are right, I should probably change it to X-Client-Port or something. I'll also try to come with with something that atleast tries to show it working. |
I would try it with one end tethered behind mobile, assuming the other is behind a "regular" router. But this still requires full cone (I think? or maybe just deterministic port mappings) so might not work in that setup even if everything is great on our side. |
Anyway it's deployed server side, though we can redeploy with a different header name later |
* main: (30 commits) lib/connections: Try TCP punchthrough (fixes syncthing#4259) (syncthing#5753) build(deps): bump github.com/lucas-clemente/quic-go (syncthing#6742) various: Master is now main lib/model: Fix minor flakiness in TestModTimeWindow cmd/ursrv: Attempt to fix js failure to load (syncthing#6747) lib/osutil: Use filepath.Join in tests (syncthing#6740) cmd/strelaysrv: Fix JSON unmarshalling when joining a relay pool (fixes syncthing#6733) (syncthing#6729) gui, man, authors: Update docs, translations, and contributors build(deps): bump github.com/lucas-clemente/quic-go (syncthing#6722) lib/db: Remove unused keyer methods (syncthing#6723) gui: Fix auto dismissing auth notification (ref syncthing#6536) lib/scanner: Save one stat call per file (syncthing#6715) gui: Ignore permissions isn't just about FAT (syncthing#6713) lib/connections, lib/nat: Correctly dis-/enable nat (fixes syncthing#6552) (syncthing#6719) gui: Fix string and update translations (ref syncthing#6536) (syncthing#6716) lib/protocol: Avoid panic in DeviceIDFromBytes (syncthing#6714) build: Fix rebuild of strelaypoolsrv assets cmd/strelaysrv: Add note about relay operators cmd/stcrashreceiver: Pick up extra build tags and send to Sentry (syncthing#6710) lib/build: Add some env vars as synthetic build tags (syncthing#6709) ...
This is hopefully a PR with only the relevant changes, if I haven't failed to git.