-
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
crypto/tls: allow access to net.Conn underneath tls.Conn #29257
Comments
/cc @bradfitz |
/cc @ianlancetaylor |
I have marked this as a proposal for it to get the proposal treatment. |
What do you actually want to do with the file descriptor? |
Timed out in state WaitingForInfo. Closing. (I am just a bot, though. Please speak up if this is a mistake or you have the requested information.) |
It is useful to get the underlying connections file descriptor so that it can be passed into a syscall for epoll. This removes the needed to start a go routine for every websocket connection. In my concurrent-websocket module I need to do just that so multiple websocket connections can be multiplexed through a pool of goroutines. I am currently working around this issue by using reflect and unsafe, which is really bad! L26 below shows how I am getting the connection, and you can see on L45 how I pass that connection to https://github.com/blakerouse/concurrent-websocket/blob/master/channel.go#L26 |
This is also an issue when using TLS with the new http.Server{
ConnContext: func(ctx context.Context, c net.Conn) context.Context {
// c is a tls.Conn, with apparently no way to access the actual connection
return
},
} |
Gopherbot, this is is still an issue. |
This comment has been minimized.
This comment has been minimized.
Same issue here +1 |
This comment has been minimized.
This comment has been minimized.
Friends, rather than saying “I need this”, I’m sure the maintainers would find it vastly more useful to say why you need this. Be as specific and concrete as possible. Try to answer the question if this feature were added these are the specific ways it would enable me to do X which I currently cannot do. Be specific about the X, not just X the feature, but how you would change your code to use X. Thank you |
hey, I need this because I am building a static file server and wanted to restart it gracefully without interruption |
@lordspace have you investigated https://godoc.org/crypto/tls#Server? |
@davecheney thanks for the link. I think I've seen it but it's still not clear to me how to get the descriptor so I can pass it to the program again when it restarts. |
To use tls.Server you would already hold the net.Conn for the listening socket. |
Looking at the other rationales put forward for getting the underlying fd from the tls.Conn,
Can you say more about this use case?
Can you say more about this use case? It's unclear to me whether half-closing a fd out from under TLS is well defined. Perhaps it is?
I asked above: "What are the memory constraints you have where a goroutine with minimal stack is too much overhead? It seems like we'd be talking about something like 2-4 kB per connection." It sounds like we need more information about use cases before we can figure out what the right API is. |
@rsc I rest my case. If needed I will re-open it in the future when I have some real numbers. To me it seemed as legit as any other optimization issue raised here. I appreciate all the work on making go faster, smaller and better. I thought a tiny change here could help safe memory and fulfill other people's use cases. If it's considered to impactful or not worth it then it's fine by me. Thanks for your time. |
Ping @FMLS and @LeGEC if you have anything to add in response to the questions in #29257 (comment). |
Not retitling (yet), but worth pointing out that not every tls.Conn has a file descriptor, so really this would be about allowing a tls.Conn to return the underlying net.Conn. |
Our use case : We wrote a proxy, which connects to our server, and allows us to multiplex individual connections (
We wrote a simple (simplish ?) protocol where each packet of data gets sent over
Our proxy is generic, and doesn't understand the protocol that transits over the connection ; when connections to the Service require TLS, our proxy is completely "blind" regarding the state of the TLS connection. Our "out of band" messages are important for bookkeeping : that's what allows us to control that connections and resources are actually released at some point (on the Server side as well as on the Proxy side). Connection to this issue :
A sketch of implementation I had in mind was : in some use cases, call something like After further thoughts, and reading the other comments in this thread, I realize calling but to fulfill our need to send "out of band" messages to our proxy, we have to keep together in a struct both the "clear" connection and the tls connection, in places where accessing the underlying one extra point : this is not a show stopper, since we can implement what we want, in our case it would be more of a nice to have. |
In November, @FMLS wrote:
Does anyone know what public cloud APIs work in terms of file descriptors (which would potentially justify accepting this proposal)? Thanks. |
I just came across this and wanted to share my experience. Forgive me for reiterating on something which has already been discussed, but I want to go back to the websockets and fd use case. My use case was similar to OP. I wanted to revamp the websocket architecture for Mattermost using a single epoll instance and get rid of all the reader goroutines. I actually don't require full access to net.Conn, just being able to get the fd so that I can stick it into the epoll instance should be good enough for me.
Personally, it is a matter of API consistency to me. TCPConn, UDPConn, IPConn all of them have the
Fair point. In that case, I would expect it to return a nil.
The argument is similar to the fact that while goroutines are cheap, they are not free. Having 100,000 connections (which is not that implausible) costs 400MB, which starts to matter in a multi-tenant Cloud environment. But more importantly, it feels a bit weird to me that we can have epoll instances for HTTP servers, but not HTTPS servers (without resorting to hacks). If the argument is that goroutines are cheap, and we should let the runtime do epoll, it should apply to EDIT: Just realized another use-case that I have. I want to call SetNoDelay on a TLS websocket connection. That's also not possible in the current state of things. |
SetNoDelay and maybe SetKeepAlive seem like the strongest arguments so far. Does anyone object to adding
? /cc @FiloSottile |
Based on the discussion above, this proposal seems like a likely accept. |
No change in consensus, so accepted. 🎉 |
@rsc Thank you for fixing this, when will this issue be resolved? |
Change https://golang.org/cl/325250 mentions this issue: |
Currently it is not possible to access FD in tls.Conn
in tls.Conn the underlying net.Conn is not accessible except in ClientHelloInfo
Senario:
in net/http we can't access the FD for https connections but we can access it for http connections
in a WebSocket connection after Hijack, when the connection is http we can use netpoll but when its https we can't
the only workaround right now is using a https to http proxy but it's not efficient as exposing the net.Conn on tls.Conn
/cc @FiloSottile
The text was updated successfully, but these errors were encountered: