-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
net: make some way to set socket options other than using File{Listener,Conn,PacketConn} #9661
Comments
Update: disregard this comment, the example i took it from was using select incorrectly. Related: |
Some of these cases can be addressed through the golang.org/x/net package. I haven't looked into this one. |
@ianlancetaylor AFAICT, golang.org/x/net does not handle setting |
reuseport is a hack. It is necessary for us to do certain kinds of tcp nat traversal. Ideally, reuseport would be available in go: golang/go#9661 But until that issue is fixed, we're stuck with this. In some cases, reuseport is strictly a detriment: nodes are not NATed. This commit introduces an ENV var IPFS_REUSEPORT that can be set to false to avoid using reuseport entirely: IPFS_REUSEPORT=false ipfs daemon This approach addresses our current need. It could become a config var if necessary. If reuseport continues to give problems, we should look into improving it.
I'm curious if anybody's given thought to the approach suggested above. I wouldn't mind submitting a patch to fix this. It would make our life easier. |
This does seem to come up a lot but we'd need to find a VERY clean way to do it. |
Not having SO_REUSEPORT is sometimes problematic. https://stackoverflow.com/questions/4465104/socket-still-listening-after-application-crash |
A random thought. There's a way to set platform, feature-specific socket options before booking like the following:
and having a clean, platform and feature-agnostic way sounds pretty nice, though the reality is a bit bitter. For example, SO_REUSEPORT option makes a bit different behavior on IP control block inside the kernel between DragonFly BSD, Linux, and BSD variants, Windows. Perhaps it might annoy package net users to when they read and write data during in-service software update, networking facility on-line insertion and removal. |
In general, if you don't pass an established, read/write ready socket descriptor to File{Listener,Conn,PacketConn} or Socket{Conn,PacketConn}, you need to understand the entire behavior of event IO mechanism, epoll, kqueue or Windows IOCP, which is used in runtime-integrated network poller. |
@mikioh thanks, yep.
Since the runtime-integrated network poller came up, i think it should be exposed in some way for users to build pkgs/libs with it. Making the stdlib net package privileged in a way no other network package could ever be:
This is a separate issue altogether-- if you agree with the above claims, I can file another issue and expand on the problem. |
Please take a look at https://groups.google.com/d/msg/golang-dev/4GOiSBCX568/brrg9aCbqngJ, speak up for the ongoing development process and follow the procedure If you have some proposals. I have no concrete opinions on both issues at the moment. |
reuseport is a hack. It is necessary for us to do certain kinds of tcp nat traversal. Ideally, reuseport would be available in go: golang/go#9661 But until that issue is fixed, we're stuck with this. In some cases, reuseport is strictly a detriment: nodes are not NATed. This commit introduces an ENV var IPFS_REUSEPORT that can be set to false to avoid using reuseport entirely: IPFS_REUSEPORT=false ipfs daemon This approach addresses our current need. It could become a config var if necessary. If reuseport continues to give problems, we should look into improving it.
Another case where this is a problem is when one wants to set IP_TOS (for DSCP) on a socket before accepting any connection. The more verbose solution proposed above by @mikioh is fraught with peril, as there are many minutiae that needs to be attended and that vary greatly across platforms (how to set the FD non-blocking, close-on-exec, how to find a decent default backlog value to pass to I also went down a similar path as @jbenet and ended up replicating a simplified version of a bunch of code from the +1 to the proposal of using function options to allow the user to set tunables. |
I ended up using reflection to get a hold of the FD after calling https://github.com/aristanetworks/goarista/blob/master/dscp/listen_unix.go |
@tsuna does that work cross-arch? dont recall atm, but I think this is still not a solution for SO_REUSEPORT as it has to be set before, else a listen will fail. |
This works for the UNIX implementation of Exact sequence of events that happen when using my kludge to set the TOS to
|
Shamelessly pinging this issue on behalf of @AudriusButkevicius. I think this one's been waiting for a lgtm and/or review. This is quite a useful feature because it helps a lot in implementing efficient NAT hole punching. |
I am sure everyone is busy and all, but to leave a CL hanging for over a month, without any indication on what it is waiting for is not ok. Drop a quick note letting us know that it will be reviewed in the future or that it's not the right implementation, or whatever. Any response is better than no response. So far my attempt to contribute to Go has been a very disappointing experience. I am surprised people have the patience to wait in silence for whatever it is we are waiting for in order to contribute. |
Hi @AudriusButkevicius, it’s normal for a cl that touches core library to go through a extra thorough review process and it might take months. Judging by your cl, it still has 13 unresolved comments. Until they are all resolved, your cl won’t pop up to the front of the reviewers attention list. That’s probably the reason why it’s not getting any updates. |
I've resolved them now, but I was expecting that a new patch set would dismiss them. |
You also need to rebase it on top the master, as there are merge confilcts. |
Change https://golang.org/cl/114827 mentions this issue: |
@AudriusButkevicius I just take another look at your CL, and I don't think you should resolve those comments as you didn't actually address to them. All the review comments are mandatory unless you have a concrete reason against it. Please revisit those comments, and push a new patchset, then reply with PTAL ("please take another look") in Gerrit. |
Even if the comments are no longee relevant and the code is gone? |
For that case, it's OK to mark it as done. But there are many needs to be addressed, just some random picks: |
Sorry, I am completely lost. The first one was addressed in patch 7, the other two which were left on patch 3 were addresses in patch 5. Are you saying they have to marked as done by the person who made the original comment? |
Oops, apparently, I was mistakenly thought the link was pointing to the latest patchset and didn't see the later fixes. I'm totally sorry about this, please ignore my comments and just wait for the reviewer to start another round of review. Looking forward to seeing your CL merged. |
There are two comments that are not addressed but that is because they need some discussion. Do I need to ack them after replying or just reply and wait? |
You should mark them as resolved, as you have already answered the questions. If the reviewer is not satisfied, they will reopen the comment. Otherwise, they will consider it's still your turn (I think Gerrit still has the issue of not being able to detect "whose the next turn"). |
The CL (https://golang.org/cl/72810) introduces a new type I can't say that I'm crazy about the name Any other suggestions? |
Another issue: the new |
I guess I prefer ListenConfig over Announcer. I don't have any objections in regards to adding context usage for the Listen method, yet I've asked a question on the CL as to how the API should look like.
where the latter matches Perhaps we can have both, just like the dialer,
|
We only have both for My vote would be to call the method |
Change https://golang.org/cl/115175 mentions this issue: |
Updates #9661 Change-Id: I237e7502cb9faad6dece1e25b1a503739c54d826 Reviewed-on: https://go-review.googlesource.com/115175 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Thanks everyone! |
woooohoooo! |
I regret having to bring up anything related to sockets. I hate them as much as the next gopher.
There are some cases[1] where setting socket options (like
SO_REUSEPORT
) is just unavoidable. In most cases, we can pull out theconn.File()
and set them. But those few annoying cases where the option must be set on the socket before listening or dialing are impossible to handle with today's net package. (please tell me i'm wrong!)"Setting the socket up yourself" is not a good option. Getting sockets right is not trivial-- there are bound to be dozens of tricky corner cases across platforms. I gave it a shot, but I keep finding problems in various OSes. It would be much more user friendly to stick to the
net
interface which already had to do all this hard work.Now, I would even go as far as to copy the
net
package wholesale just to add this feature, but AFAIK the existence of theruntime·
functions makes this also impossible (such anetcopy
wont compile). Without them, we're left up to whittling downnetcopy
(and exchanging the runtime polling forselect/epoll/ugliness
) , most likely introducing more bugs.A nice way to solve this -- I think -- is to make listeners and dialers have "tuners", as implemented in https://github.com/benburkert/net.tune/ [3]. This approach is based on rob's self-referential functions, and manages to contain the ugly, exposing a nice interface.[4] But I imagine there are many other approaches that are even nicer and idiomatic.
I know-- the stdlib is trying to contain the ugly as much as possible and prevent it from spreading. But in this type of case, the current state of affairs brings it out more for some of us.
[1] One example: being able to dial out from the same TCP port you're listening on is a requirement for some kinds of NAT traversal.
[2] There's issues in this very tracker showing years of tuning the use of sockets.
[3] Specifically: https://github.com/benburkert/net.tune/blob/master/dial.go#L59-L63
[4] It could be done with new functions -- or if the goal is to keep the interface thin, a variadic argument to the existing functions should be backwards compatible.
The text was updated successfully, but these errors were encountered: