Skip to content

Commit

Permalink
SplitHTTP server: Fix panic during concurrent Close and Push (#3593)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mmmray authored Jul 26, 2024
1 parent edae38c commit 2becdd6
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions transport/internet/splithttp/upload_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package splithttp
import (
"container/heap"
"io"
"sync"

"github.com/xtls/xray-core/common/errors"
)
Expand All @@ -16,11 +17,12 @@ type Packet struct {
}

type uploadQueue struct {
pushedPackets chan Packet
heap uploadHeap
nextSeq uint64
closed bool
maxPackets int
pushedPackets chan Packet
writeCloseMutex sync.Mutex
heap uploadHeap
nextSeq uint64
closed bool
maxPackets int
}

func NewUploadQueue(maxPackets int) *uploadQueue {
Expand All @@ -34,6 +36,9 @@ func NewUploadQueue(maxPackets int) *uploadQueue {
}

func (h *uploadQueue) Push(p Packet) error {
h.writeCloseMutex.Lock()
defer h.writeCloseMutex.Unlock()

if h.closed {
return errors.New("splithttp packet queue closed")
}
Expand All @@ -43,6 +48,9 @@ func (h *uploadQueue) Push(p Packet) error {
}

func (h *uploadQueue) Close() error {
h.writeCloseMutex.Lock()
defer h.writeCloseMutex.Unlock()

h.closed = true
close(h.pushedPackets)
return nil
Expand Down

0 comments on commit 2becdd6

Please sign in to comment.