mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
77 lines
1.6 KiB
Go
77 lines
1.6 KiB
Go
package quic
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/lucas-clemente/quic-go/internal/protocol"
|
|
)
|
|
|
|
type zeroRTTQueueEntry struct {
|
|
timer *time.Timer
|
|
packets []*receivedPacket
|
|
}
|
|
|
|
type zeroRTTQueue struct {
|
|
mutex sync.Mutex
|
|
queue map[string]*zeroRTTQueueEntry
|
|
queueDuration time.Duration // so we can set it in tests
|
|
}
|
|
|
|
func newZeroRTTQueue() *zeroRTTQueue {
|
|
return &zeroRTTQueue{
|
|
queue: make(map[string]*zeroRTTQueueEntry),
|
|
queueDuration: protocol.Max0RTTQueueingDuration,
|
|
}
|
|
}
|
|
|
|
func (h *zeroRTTQueue) Enqueue(connID protocol.ConnectionID, p *receivedPacket) {
|
|
h.mutex.Lock()
|
|
defer h.mutex.Unlock()
|
|
|
|
cid := string(connID)
|
|
if _, ok := h.queue[cid]; !ok {
|
|
if len(h.queue) >= protocol.Max0RTTQueues {
|
|
return
|
|
}
|
|
h.queue[cid] = &zeroRTTQueueEntry{timer: time.AfterFunc(h.queueDuration, func() {
|
|
h.deleteQueue(connID)
|
|
})}
|
|
}
|
|
entry := h.queue[cid]
|
|
if len(entry.packets) >= protocol.Max0RTTQueueLen {
|
|
return
|
|
}
|
|
entry.packets = append(entry.packets, p)
|
|
}
|
|
|
|
func (h *zeroRTTQueue) Dequeue(connID protocol.ConnectionID) *receivedPacket {
|
|
h.mutex.Lock()
|
|
defer h.mutex.Unlock()
|
|
|
|
entry, ok := h.queue[string(connID)]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
p := entry.packets[0]
|
|
entry.packets = entry.packets[1:]
|
|
if len(entry.packets) == 0 {
|
|
entry.timer.Stop()
|
|
delete(h.queue, string(connID))
|
|
}
|
|
return p
|
|
}
|
|
|
|
func (h *zeroRTTQueue) deleteQueue(connID protocol.ConnectionID) {
|
|
h.mutex.Lock()
|
|
defer h.mutex.Unlock()
|
|
|
|
entry, ok := h.queue[string(connID)]
|
|
if !ok {
|
|
return
|
|
}
|
|
for _, p := range entry.packets {
|
|
p.buffer.Release()
|
|
}
|
|
delete(h.queue, string(connID))
|
|
}
|