udp: handle closed forwarding channel (#5470)

This commit is contained in:
fatedier
2026-08-09 15:31:11 +08:00
committed by GitHub
parent d1928f9689
commit 5b68148f11
2 changed files with 41 additions and 3 deletions
+4
View File
@@ -63,10 +63,14 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UDPPacket, sendCh
// NewUDPPacket copies buf[:n], so the read buffer can be reused // NewUDPPacket copies buf[:n], so the read buffer can be reused
udpMsg := NewUDPPacket(buf[:n], nil, remoteAddr) udpMsg := NewUDPPacket(buf[:n], nil, remoteAddr)
if err = errors.PanicToError(func() {
select { select {
case sendCh <- udpMsg: case sendCh <- udpMsg:
default: default:
} }
}); err != nil {
return
}
} }
} }
+34
View File
@@ -1,9 +1,13 @@
package udp package udp
import ( import (
"net"
"testing" "testing"
"time"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/fatedier/frp/pkg/msg"
) )
func TestUdpPacket(t *testing.T) { func TestUdpPacket(t *testing.T) {
@@ -16,3 +20,33 @@ func TestUdpPacket(t *testing.T) {
require.NoError(err) require.NoError(err)
require.EqualValues(buf, newBuf) require.EqualValues(buf, newBuf)
} }
func TestForwardUserConnReturnsWhenSendChannelIsClosed(t *testing.T) {
listener, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)})
require.NoError(t, err)
t.Cleanup(func() { _ = listener.Close() })
readCh := make(chan *msg.UDPPacket)
sendCh := make(chan *msg.UDPPacket)
close(sendCh)
t.Cleanup(func() { close(readCh) })
done := make(chan struct{})
go func() {
ForwardUserConn(listener, readCh, sendCh, 1500)
close(done)
}()
sender, err := net.DialUDP("udp4", nil, listener.LocalAddr().(*net.UDPAddr))
require.NoError(t, err)
t.Cleanup(func() { _ = sender.Close() })
_, err = sender.Write([]byte("trigger"))
require.NoError(t, err)
select {
case <-done:
case <-time.After(time.Second):
t.Fatal("ForwardUserConn did not return after sending to a closed channel")
}
}