Go: proposal: crypto/tls: allow access to file descriptor for tls.Conn

Created on 14 Dec 2018  ·  23Comments  ·  Source: golang/go

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

FeatureRequest NeedsInvestigation Proposal Proposal-Crypto

Most helpful comment

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 netpoll.HandleReadOnce. It still uses the tls.Conn for reading and writing, but needs to pass the underlying connection for epoll to work.

https://github.com/blakerouse/concurrent-websocket/blob/master/channel.go#L26

All 23 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 netpoll.HandleReadOnce. It still uses the tls.Conn for reading and writing, but needs to pass the underlying connection for epoll to work.

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 callback, in my case I want to get syscall.TCPInfo for each connection.

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.

I also need to access FD

Same issue here +1
The file descriptor is needed when working with epoll WebSocket

+1 same same

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.

@davecheney I believe this is about handling websockets with epoll and working with file descriptors and it tracks back to a comment in this method: https://github.com/blakerouse/concurrent-websocket/blob/master/channel.go#L29
@lordspace probably wants to do something similar to this: https://gravitational.com/blog/golang-ssh-bastion-graceful-restarts/

yes, @jtorvald I know the ticket is for something else but I will use the descriptor for something else. The article doesn't cover HTTPS

I would need this to retrieve the TCPInfo struct from net.Conn

@jtorvald yep. you're absolutely right. I've spend about 15 hours on looking for a workaround and I had to resort to using nginx as a reverse proxy for my http server.

I need to access Fd too, In public cloud environment, we need this fd to parse VPC infomation

Without access to the file description it may be hard to achieve this for TLS/SSL .
https://github.com/fvbock/endless
https://tomaz.lovrec.dev/posts/graceful-server-restart/

I have some code where I would like to call (*TCPConn).CloseWrite() from a TLS connection, which I currently create using tls.Dial("tcp", ... ).

I know my use case is not a blocker : I can create a net.TCPConn (or net.UnixConn for that matter), upgrade it using tls.Client(...), and keep the two objects alive together,
I would just say that it feels awkward to be locked away from the underlying connection.

Was this page helpful?
0 / 5 - 0 ratings