WireGuard outbound: Fix multi-peer's readQueue issue (#5554)

Fixes https://github.com/XTLS/Xray-core/issues/4507

---------

Co-authored-by: RPRX <63339210+RPRX@users.noreply.github.com>
This commit is contained in:
Copilot
2026-03-23 08:08:28 +00:00
committed by GitHub
parent 982c95d89a
commit d8a8629a14
+24 -18
View File
@@ -89,13 +89,14 @@ func (bind *netBind) Open(uport uint16) ([]conn.ReceiveFunc, uint16, error) {
} }
}() }()
r := &netReadInfo{ r, ok := <-bind.readQueue
buff: bufs[0], if !ok {
return 0, errors.New("channel closed")
} }
r.waiter.Add(1)
bind.readQueue <- r copy(bufs[0], r.buff[:r.bytes])
r.waiter.Wait() // wait read goroutine done, or we will miss the result
sizes[0], eps[0] = r.bytes, r.endpoint sizes[0], eps[0] = r.bytes, r.endpoint
r.waiter.Done()
return 1, r.err return 1, r.err
} }
workers := bind.workers workers := bind.workers
@@ -133,24 +134,29 @@ func (bind *netBindClient) connectTo(endpoint *netEndpoint) error {
} }
endpoint.conn = c endpoint.conn = c
go func(readQueue <-chan *netReadInfo, endpoint *netEndpoint) { go func(readQueue chan<- *netReadInfo, endpoint *netEndpoint) {
defer func() {
_ = recover() // handle send on closed channel
}()
for { for {
v, ok := <-readQueue buff := make([]byte, 1700)
if !ok { i, err := c.Read(buff)
return
}
i, err := c.Read(v.buff)
if i > 3 { if i > 3 {
v.buff[1] = 0 buff[1] = 0
v.buff[2] = 0 buff[2] = 0
v.buff[3] = 0 buff[3] = 0
} }
v.bytes = i r := &netReadInfo{
v.endpoint = endpoint buff: buff,
v.err = err bytes: i,
v.waiter.Done() endpoint: endpoint,
err: err,
}
r.waiter.Add(1)
readQueue <- r
r.waiter.Wait()
if err != nil { if err != nil {
endpoint.conn = nil endpoint.conn = nil
return return