Skip to content

Commit e6bd888

Browse files
authored
fix: streamline UDP session cleanup and slot management in commonUDPLoop and commonUDPOnce
1 parent 0d44f66 commit e6bd888

File tree

1 file changed

+23
-21
lines changed

1 file changed

+23
-21
lines changed

internal/common.go

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,10 @@ func (c *Common) commonUDPLoop() {
840840

841841
go func(remoteConn net.Conn, clientAddr *net.UDPAddr, sessionKey, id string) {
842842
defer func() {
843+
// 清理UDP会话和释放槽位
844+
c.targetUDPSession.Delete(sessionKey)
845+
c.releaseSlot(true)
846+
843847
// 池连接关闭或复用
844848
if !c.poolReuse && remoteConn != nil {
845849
remoteConn.Close()
@@ -849,10 +853,6 @@ func (c *Common) commonUDPLoop() {
849853
remoteConn.SetReadDeadline(time.Time{})
850854
c.tunnelPool.Put(id, remoteConn)
851855
c.logger.Debug("Tunnel connection: put %v -> pool active %v", id, c.tunnelPool.Active())
852-
853-
// 清理UDP会话
854-
c.targetUDPSession.Delete(sessionKey)
855-
c.releaseSlot(true)
856856
}()
857857

858858
buffer := c.getUDPBuffer()
@@ -1118,42 +1118,44 @@ func (c *Common) commonUDPOnce(signalURL *url.URL) {
11181118

11191119
var targetConn net.Conn
11201120
sessionKey := signalURL.Host
1121+
isNewSession := false
11211122

11221123
// 获取或创建目标UDP会话
11231124
if session, ok := c.targetUDPSession.Load(sessionKey); ok {
11241125
targetConn = session.(net.Conn)
11251126
c.logger.Debug("Using UDP session: %v <-> %v", targetConn.LocalAddr(), targetConn.RemoteAddr())
11261127
} else {
11271128
// 创建新的会话
1129+
isNewSession = true
1130+
1131+
// 尝试获取UDP连接槽位
1132+
if !c.tryAcquireSlot(true) {
1133+
c.logger.Error("commonUDPOnce: UDP slot limit reached: %v/%v", c.udpSlot, c.slotLimit)
1134+
return
1135+
}
1136+
11281137
newSession, err := net.DialTimeout("udp", c.targetUDPAddr.String(), udpDialTimeout)
11291138
if err != nil {
11301139
c.logger.Error("commonUDPOnce: dialTimeout failed: %v", err)
1140+
c.releaseSlot(true)
11311141
return
11321142
}
11331143
targetConn = &conn.StatConn{Conn: newSession, RX: &c.udpRX, TX: &c.udpTX, Rate: c.rateLimiter}
11341144
c.targetUDPSession.Store(sessionKey, targetConn)
11351145
c.logger.Debug("Target connection: %v <-> %v", targetConn.LocalAddr(), targetConn.RemoteAddr())
11361146
}
11371147

1138-
// 尝试获取UDP连接槽位
1139-
if !c.tryAcquireSlot(true) {
1140-
c.logger.Error("commonUDPOnce: UDP slot limit reached: %v/%v", c.udpSlot, c.slotLimit)
1141-
c.targetUDPSession.Delete(sessionKey)
1142-
if targetConn != nil {
1143-
targetConn.Close()
1144-
}
1145-
return
1148+
if isNewSession {
1149+
defer func() {
1150+
// 清理UDP会话和释放槽位
1151+
c.targetUDPSession.Delete(sessionKey)
1152+
if targetConn != nil {
1153+
targetConn.Close()
1154+
}
1155+
c.releaseSlot(true)
1156+
}()
11461157
}
11471158

1148-
defer func() {
1149-
// 清理UDP会话
1150-
c.targetUDPSession.Delete(sessionKey)
1151-
if targetConn != nil {
1152-
targetConn.Close()
1153-
}
1154-
c.releaseSlot(true)
1155-
}()
1156-
11571159
c.logger.Debug("Starting transfer: %v <-> %v", remoteConn.LocalAddr(), targetConn.LocalAddr())
11581160

11591161
done := make(chan struct{}, 2)

0 commit comments

Comments
 (0)