Open securez opened 2 years ago
Tableflip is not meant to preserve what established connections, only listeners (TCP) or unconnected sockets (UDP). The reason is that it's rarely useful to have an established connection without some associated state to go with it and that sharing a connection like this requires additional care. In your example you only ever write to conn
, but in most scenarios you also want to read from it. How can you do that if another process might still be reading from the same socket concurrently? How do you figure out at what point in a protocol a socket is in?
If you really want to share established connections you will have to build your own mechanism to do so. You can use AddConn to build this mechanism by using a unix domain socket or similar and passing state + fds via SCM_RIGHTS.
Regarding the lib: this is not a bug. The best it could do is refuse to accept connected sockets in AddConn, to avoid this mistake in the first place.
I have a scenario where I want to perform hitless reloads but I have too many connections that are long lived (such as WebSocket). tableflip helps with the listener and I can write the code to pass connection FDs via unix sockets with SCM_RIGHTS but I need to actually pass existing connections too.
The one part that's actually tricky is serializing the net.Conn
struct so that I can pass it via RPCs on unix socket or shared memory space then deserialize to reconstruct the struct and pass it to net.Conn request handlers. My only choice is to write my own H1/H2 lib isn't it ? One that I can pass a fd and config struct to say it was an existing connection and some data like keepalive headers (h1), stream states (h2), flow controls (h2), etc.
After deep review of this great library, I come with a problem on inherited connections, let's me explain with a example.
I figure that in golang, to access the file descriptor of a net.Conn or viceversa a fd dup is in place, and has it's explanation, This library has 2 scenarios:
The problems seems to be fds.go:300 replace f.used[key] = file by file.Close(), but PacketConn seems to have the same problem. For large number of connections, the duplication of unused file descriptors, can be a problem too.
The sample code, that listen on 8080, and writes to the socket every second, and closes it after 30s. If the connection is fresh the connection is closed and client receives TCP close, but if inherited the connection will hang.