Description
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 the conn.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 the runtime·
functions makes this also impossible (such a netcopy
wont compile). Without them, we're left up to whittling down netcopy
(and exchanging the runtime polling for select/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.
Activity
[-]net: make some way to setting sockopts[/-][+]net: make some way to set sockopts[/+]jbenet commentedon Jan 22, 2015
Update: disregard this comment, the example i took it from was using select incorrectly.
Related:
I think I found a "bug" in-- not sure what's expected. See: https://gist.github.com/jbenet/5c191d698fe9ec58c49d -- the outcome changes if I wait before or after thenet.FileConn(f)
semanticsnet.FileConn(f)
call. this is similar to #3838. (( Maybe I'm just waiting incorrectly? I usesyscall.Select
becauseruntime_*
is not avail. )) The same fix as #3838 is not easy, asraddr
is not directly available.ianlancetaylor commentedon Jan 22, 2015
Some of these cases can be addressed through the golang.org/x/net package. I haven't looked into this one.
jbenet commentedon Jan 22, 2015
@ianlancetaylor AFAICT, golang.org/x/net does not handle setting
SO_REUSEPORT
or any other options before a dial or a listen. Would love to find out i'm entirely wrong :)[-]net: make some way to set sockopts[/-][+]net: make some way to set socket options[/+]Dial
? benburkert/net.tune#2reuseport: env var to turn it off
jbenet commentedon Apr 8, 2015
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.
rsc commentedon Apr 10, 2015
This does seem to come up a lot but we'd need to find a VERY clean way to do it.
@rsc
coolaj86 commentedon Jun 20, 2015
Not having SO_REUSEPORT is sometimes problematic. https://stackoverflow.com/questions/4465104/socket-still-listening-after-application-crash
[-]net: make some way to set socket options[/-][+]net: make some way to set socket options other than using File{Listener,Conn,PacketConn} and Socket{Conn,PacketConn}[/+]90 remaining items