mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-22 08:31:28 +00:00
SplitHTTP server: Fix panic during concurrent Close and Push (#3593)
When Close and Push are called concurrently, it may happen that Push attempts to write to an already-closed channel, and trigger a panic. From a user perspective, it results in logs like this: http: panic serving 172.19.0.6:50476: send on closed channel It's probably triggered when download is closed at the same time an upload packet is submitted. These panics don't crash the server and the inbound is still usable.
This commit is contained in:
parent
edae38c620
commit
2becdd6414
|
@ -6,6 +6,7 @@ package splithttp
|
||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
"io"
|
"io"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
)
|
)
|
||||||
|
@ -16,11 +17,12 @@ type Packet struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type uploadQueue struct {
|
type uploadQueue struct {
|
||||||
pushedPackets chan Packet
|
pushedPackets chan Packet
|
||||||
heap uploadHeap
|
writeCloseMutex sync.Mutex
|
||||||
nextSeq uint64
|
heap uploadHeap
|
||||||
closed bool
|
nextSeq uint64
|
||||||
maxPackets int
|
closed bool
|
||||||
|
maxPackets int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUploadQueue(maxPackets int) *uploadQueue {
|
func NewUploadQueue(maxPackets int) *uploadQueue {
|
||||||
|
@ -34,6 +36,9 @@ func NewUploadQueue(maxPackets int) *uploadQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *uploadQueue) Push(p Packet) error {
|
func (h *uploadQueue) Push(p Packet) error {
|
||||||
|
h.writeCloseMutex.Lock()
|
||||||
|
defer h.writeCloseMutex.Unlock()
|
||||||
|
|
||||||
if h.closed {
|
if h.closed {
|
||||||
return errors.New("splithttp packet queue closed")
|
return errors.New("splithttp packet queue closed")
|
||||||
}
|
}
|
||||||
|
@ -43,6 +48,9 @@ func (h *uploadQueue) Push(p Packet) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *uploadQueue) Close() error {
|
func (h *uploadQueue) Close() error {
|
||||||
|
h.writeCloseMutex.Lock()
|
||||||
|
defer h.writeCloseMutex.Unlock()
|
||||||
|
|
||||||
h.closed = true
|
h.closed = true
|
||||||
close(h.pushedPackets)
|
close(h.pushedPackets)
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in a new issue