Skip to content

Commit 3af0da8

Browse files
committed
flush cached UDP packets after auth stage timeout
Experimental attempt to address QUIC connections that remain stuck in the auth stage. May help resume communication, but not guaranteed to fix the issue.
1 parent a45f0b2 commit 3af0da8

1 file changed

Lines changed: 32 additions & 14 deletions

File tree

tsshd/proxy_server.go

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,43 @@ func (c *clientState) setAuthedAddr(addr *net.UDPAddr) {
146146

147147
if addr != nil && conn != nil {
148148
conn.addAuthedMap(c)
149+
150+
// Based on logs, we observed an issue when using QUIC:
151+
// multiple "authed" events occur, but no subsequent client packets
152+
// are received, causing the connection to remain stuck in the auth stage.
153+
// As a workaround, attempt to flush cached UDP packets here to see if it
154+
// helps QUIC resume normal communication.
155+
go func() {
156+
time.Sleep(time.Second)
157+
if c.authedAddr.Load() == addr {
158+
hasCache := c.sendPacketCache(conn)
159+
if enableDebugLogging && !hasCache {
160+
debug("auth stage timeout but no cached packets to flush")
161+
}
162+
}
163+
}()
149164
}
150165

151166
if oldAddr != nil && conn != nil {
152167
conn.delAuthedMap(oldAddr)
153168
}
154169
}
155170

171+
func (c *clientState) sendPacketCache(conn frontendConnection) bool {
172+
flushSize, flushCount := c.pktCache.sendCache(func(b []byte) error {
173+
conn.writeTo(b, c)
174+
return nil
175+
})
176+
177+
hasCache := flushSize > 0 || flushCount > 0
178+
179+
if enableDebugLogging && hasCache {
180+
debug("send packet cache count [%d] size [%d]", flushCount, flushSize)
181+
}
182+
183+
return hasCache
184+
}
185+
156186
func newClientState(clientID uint64) *clientState {
157187
client := &clientState{proxyAddr: proxyClientAddr{clientID}}
158188
client.clientCond = sync.NewCond(&client.clientMutex)
@@ -753,13 +783,7 @@ func (p *serverProxy) onNewClientConn(client *clientState) {
753783
// from being delivered after reconnection.
754784
server.enablePendingInputDiscard()
755785

756-
flushSize, flushCount := client.pktCache.sendCache(func(b []byte) error {
757-
p.frontendConn.writeTo(b, client)
758-
return nil
759-
})
760-
if enableDebugLogging && (flushSize > 0 || flushCount > 0) {
761-
debug("send packet cache count [%d] size [%d]", flushCount, flushSize)
762-
}
786+
client.sendPacketCache(p.frontendConn)
763787
}
764788
}
765789

@@ -793,13 +817,7 @@ func (p *serverProxy) ReadFrom(buf []byte) (int, net.Addr, error) {
793817
server.clientChecker.updateNow()
794818
if client.sendCacheFlag.Load() {
795819
client.sendCacheFlag.Store(false)
796-
flushSize, flushCount := client.pktCache.sendCache(func(b []byte) error {
797-
p.frontendConn.writeTo(b, client)
798-
return nil
799-
})
800-
if enableDebugLogging && (flushSize > 0 || flushCount > 0) {
801-
debug("send packet cache count [%d] size [%d]", flushCount, flushSize)
802-
}
820+
client.sendPacketCache(p.frontendConn)
803821
}
804822
}
805823

0 commit comments

Comments
 (0)