[GH-ISSUE #41] Gracefully handle websocket Close messages #37

Closed
opened 2026-03-02 23:01:56 +03:00 by kerem · 3 comments
Owner

Originally created by @jeromegn on GitHub (Mar 29, 2021).
Original GitHub issue: https://github.com/agrinman/tunnelto/issues/41

Maybe I missed it, but I don't think tunnelto gracefully handles websocket close messages and/or reconnects.

Testing this locally with a proxy (Fly.io) in-between tunnelto clients and servers: if the proxy goes away, the tunnel client appears to reconnect, but not without an error and then every request to the tunnel endpoint (<sub>.tunnelto.dev) will fail. Your users will have to manually start/stop their tunnel.

The client shows the following:

 ERROR tunnelto > Malformed protocol control packet: "invalid control byte in DataPacket"

and then trying to make a request:

$ curl something.tunnelto.dev
Error: Tunnel Not Found

I'm assuming this happens because a new subdomain is generated for the tunnel, but it's not printed.

Fly's proxy sends a "Restart" close message, to both the client and server, when we deploy. Normal websocket operations dictates clients and servers should try reconnecting when that happens. With tunstenite, that's a matter of handling the Message::Close(Option<CloseFrame>) appropriately depending on the close reason.

I would suggest the same hostname should be kept around on reconnect. The client should have rights to use the same hostname it was previously using for a reconnect sequence.

Restarting of our proxy is a normal part of operation. It does offer zero-downtime, but not for websocket connections (or other very long lives connections). It does the next best thing by gracefully closing the connections, expecting the clients to reconnect (on the freshly deployed version of our proxy).

Originally created by @jeromegn on GitHub (Mar 29, 2021). Original GitHub issue: https://github.com/agrinman/tunnelto/issues/41 Maybe I missed it, but I don't think tunnelto gracefully handles websocket close messages and/or reconnects. Testing this locally with a proxy (Fly.io) in-between tunnelto clients and servers: if the proxy goes away, the tunnel client appears to reconnect, but not without an error and then every request to the tunnel endpoint (`<sub>.tunnelto.dev`) will fail. Your users will have to manually start/stop their tunnel. The client shows the following: ``` ERROR tunnelto > Malformed protocol control packet: "invalid control byte in DataPacket" ``` and then trying to make a request: ```bash $ curl something.tunnelto.dev Error: Tunnel Not Found ``` I'm assuming this happens because a new subdomain is generated for the tunnel, but it's not printed. Fly's proxy sends a "Restart" close message, to both the client and server, when we deploy. Normal websocket operations dictates clients and servers should try reconnecting when that happens. With `tunstenite`, that's a matter of handling the `Message::Close(Option<CloseFrame>)` appropriately depending on the close reason. I would suggest the same hostname should be kept around on reconnect. The client should have rights to use the same hostname it was previously using for a reconnect sequence. Restarting of our proxy is a normal part of operation. It does offer zero-downtime, but not for websocket connections (or other very long lives connections). It does the next best thing by gracefully closing the connections, expecting the clients to reconnect (on the freshly deployed version of our proxy).
kerem 2026-03-02 23:01:56 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@agrinman commented on GitHub (Apr 3, 2021):

Ah thanks so much for this explanation @jeromegn! This is definitely why the tunnel occasionally breaks and needs restarting. I don't believe I am handling the close message correctly. I will address this shortly -- thanks again!

<!-- gh-comment-id:812890061 --> @agrinman commented on GitHub (Apr 3, 2021): Ah thanks so much for this explanation @jeromegn! This is definitely why the tunnel occasionally breaks and needs restarting. I don't believe I am handling the close message correctly. I will address this shortly -- thanks again!
Author
Owner

@agrinman commented on GitHub (Apr 3, 2021):

Ah so this issue occurs when you are using an anonymous tunnel only (if you're authenticated + specify a subdomain it will persist the tunnel of course)

<!-- gh-comment-id:812903722 --> @agrinman commented on GitHub (Apr 3, 2021): Ah so this issue occurs when you are using an anonymous tunnel only (if you're authenticated + specify a subdomain it will persist the tunnel of course)
Author
Owner

@agrinman commented on GitHub (Apr 18, 2021):

This should be fixed now 0.1.14!

<!-- gh-comment-id:821922195 --> @agrinman commented on GitHub (Apr 18, 2021): This should be fixed now 0.1.14!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tunnelto#37
No description provided.