Skip to content

Fix: Automatic session reconnection for closed pipe errors#7

Open
AliRezaBeigy wants to merge 8 commits intoMygod:pluginfrom
AliRezaBeigy:plugin
Open

Fix: Automatic session reconnection for closed pipe errors#7
AliRezaBeigy wants to merge 8 commits intoMygod:pluginfrom
AliRezaBeigy:plugin

Conversation

@AliRezaBeigy
Copy link
Copy Markdown

Problem

After extended usage, dnstt-client would fail with the error:

opening stream: io: read/write on closed pipe

This occurred when the smux session (or underlying KCP/Noise connection) became closed due to:

  • Network interruptions
  • Idle timeout (2 minutes, defined as idleTimeout constant in main.go:66 and used as KeepAliveTimeout in smux config at line 214)
  • Connection failures
  • Long periods without activity

The original implementation created a single smux session at startup and never attempted to recreate it when it became invalid. Once the session closed, all subsequent stream opening attempts would fail permanently.

Solution

Implemented automatic session reconnection with the following improvements:

  1. Session Manager: Created a sessionManager struct that encapsulates the KCP connection, Noise channel, and smux session lifecycle
  2. Automatic Detection: Enhanced error detection to identify closed pipe errors and other connection failure indicators
  3. Automatic Reconnection: When a closed session is detected, the system automatically:
    • Closes the old session cleanly
    • Creates a new KCP connection
    • Establishes a new Noise handshake
    • Creates a new smux session
    • Retries the stream opening operation
  4. Thread Safety: Added proper locking to prevent race conditions during session recreation
  5. Concurrent Safety: Multiple goroutines attempting to recreate a session simultaneously are handled gracefully with double-check locking

Changes

Modified Files

  • dnstt-client/main.go

Key Changes

  1. New sessionManager type (lines 123-137):

    • Manages KCP connection, Noise channel, and smux session
    • Thread-safe with sync.RWMutex
    • Tracks connection state and conversation ID
  2. Session lifecycle methods:

    • newSessionManager(): Creates a new session manager
    • createSession(): Creates/recreates the full connection chain (KCP → Noise → smux)
    • closeSession() / closeSessionLocked(): Cleanly closes all resources
    • getSession(): Thread-safe session retrieval with lazy initialization
    • openStream(): Opens a stream with automatic reconnection on failure
  3. Enhanced error detection (lines 286-290):

    • Detects io.ErrClosedPipe
    • Detects "closed pipe" and "broken pipe" string errors
    • Detects "use of closed network connection" errors
    • Handles io.EOF as a potential connection closure indicator
  4. Refactored handle() function:

    • Now accepts sessionManager instead of raw *smux.Session
    • Uses openStream() which handles reconnection automatically
  5. Refactored run() function:

    • Creates and manages sessionManager instance
    • Initializes session on startup
    • Properly cleans up on exit

@AliRezaBeigy
Copy link
Copy Markdown
Author

^ @Mygod

@Mygod
Copy link
Copy Markdown
Owner

Mygod commented Jan 16, 2026

Any interest in this? ;)

https://github.com/Mygod/slipstream-rust

@AliRezaBeigy
Copy link
Copy Markdown
Author

@Mygod Thank you for the suggestion!
Actually your project has helped a huge number of people in Iran access the internet.
I'm even working on it from inside Iran without proper internet
Because of that, I really can't search for and test lots of different solutions, your project (with the help of github.com/bugfloyd/dnstt-deploy) is basically the only fast & reliable one that works here right now.
I'll switch to slipstream as soon as I get the chance.
Thanks again for everything! ❤️

@Mygod
Copy link
Copy Markdown
Owner

Mygod commented Jan 17, 2026

Okay I've decided that I hate kcp so I'll just leave this PR as is and redirect you to slipstream. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants