fix(dialer): prevent hang on HTTP+ICMP by enabling QUIC keepalive by default

The ICMP dialer required explicit keepalive:true to send QUIC PING frames,
while the regular QUIC dialer enabled keepalive by default (10s period).
Without PING frames, quic-go's 30s idle timeout silently killed connections,
causing HTTP+ICMP tunnels to hang after periods of inactivity.

Fixes go-gost/gost#352

Also in this commit:
- Release session mutex before calling GetConn() in both ICMP and QUIC
  dialers, so a dead session doesn't block all Dial() calls while
  OpenStreamSync blocks
- Add 30s timeout context to OpenStreamSync to prevent indefinite blocking
  if the QUIC session dies between liveness check and stream open
- Guard session cache deletion with pointer identity check to avoid
  evicting a newly created session during a race
This commit is contained in:
ginuerzh
2026-06-21 10:09:34 +08:00
parent 37bc81576c
commit 9fab332772
5 changed files with 36 additions and 10 deletions
+4 -1
View File
@@ -3,6 +3,7 @@ package quic
import (
"context"
"net"
"time"
"github.com/quic-go/quic-go"
)
@@ -12,7 +13,9 @@ type quicSession struct {
}
func (session *quicSession) GetConn() (*quicConn, error) {
stream, err := session.session.OpenStreamSync(context.Background())
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
stream, err := session.session.OpenStreamSync(ctx)
if err != nil {
return nil, err
}