mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-29 14:45:07 +03:00
work-in-progress on buffering overhaul
This commit is contained in:
parent
dc128121e5
commit
052de98f12
5 changed files with 202 additions and 111 deletions
|
@ -4,9 +4,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// TODO take max size from config
|
||||
const MAX_PACKET_QUEUE_SIZE = 4 * 1048576 // 4 MB
|
||||
|
||||
type pqStreamID string
|
||||
|
||||
type pqPacketInfo struct {
|
||||
|
@ -25,46 +22,50 @@ type packetQueue struct {
|
|||
size uint64
|
||||
}
|
||||
|
||||
func (q *packetQueue) cleanup() {
|
||||
for q.size > MAX_PACKET_QUEUE_SIZE {
|
||||
// TODO? drop from a random stream
|
||||
// odds proportional to size? bandwidth?
|
||||
// always using the worst is exploitable -> flood 1 packet per random stream
|
||||
// find the stream that's using the most bandwidth
|
||||
now := time.Now()
|
||||
var worst pqStreamID
|
||||
for id := range q.streams {
|
||||
// drop will remove a packet from the queue, returning it to the pool
|
||||
// returns true if a packet was removed, false otherwise
|
||||
func (q *packetQueue) drop() bool {
|
||||
if q.size == 0 {
|
||||
return false
|
||||
}
|
||||
// TODO? drop from a random stream
|
||||
// odds proportional to size? bandwidth?
|
||||
// always using the worst is exploitable -> flood 1 packet per random stream
|
||||
// find the stream that's using the most bandwidth
|
||||
now := time.Now()
|
||||
var worst pqStreamID
|
||||
for id := range q.streams {
|
||||
worst = id
|
||||
break // get a random ID to start
|
||||
}
|
||||
worstStream := q.streams[worst]
|
||||
worstSize := float64(worstStream.size)
|
||||
worstAge := now.Sub(worstStream.infos[0].time).Seconds()
|
||||
for id, stream := range q.streams {
|
||||
thisSize := float64(stream.size)
|
||||
thisAge := now.Sub(stream.infos[0].time).Seconds()
|
||||
// cross multiply to avoid division by zero issues
|
||||
if worstSize*thisAge < thisSize*worstAge {
|
||||
// worstSize/worstAge < thisSize/thisAge -> this uses more bandwidth
|
||||
worst = id
|
||||
break // get a random ID to start
|
||||
}
|
||||
worstStream := q.streams[worst]
|
||||
worstSize := float64(worstStream.size)
|
||||
worstAge := now.Sub(worstStream.infos[0].time).Seconds()
|
||||
for id, stream := range q.streams {
|
||||
thisSize := float64(stream.size)
|
||||
thisAge := now.Sub(stream.infos[0].time).Seconds()
|
||||
// cross multiply to avoid division by zero issues
|
||||
if worstSize*thisAge < thisSize*worstAge {
|
||||
// worstSize/worstAge < thisSize/thisAge -> this uses more bandwidth
|
||||
worst = id
|
||||
worstStream = stream
|
||||
worstSize = thisSize
|
||||
worstAge = thisAge
|
||||
}
|
||||
}
|
||||
// Drop the oldest packet from the worst stream
|
||||
packet := worstStream.infos[0].packet
|
||||
worstStream.infos = worstStream.infos[1:]
|
||||
worstStream.size -= uint64(len(packet))
|
||||
q.size -= uint64(len(packet))
|
||||
pool_putBytes(packet)
|
||||
// save the modified stream to queues
|
||||
if len(worstStream.infos) > 0 {
|
||||
q.streams[worst] = worstStream
|
||||
} else {
|
||||
delete(q.streams, worst)
|
||||
worstStream = stream
|
||||
worstSize = thisSize
|
||||
worstAge = thisAge
|
||||
}
|
||||
}
|
||||
// Drop the oldest packet from the worst stream
|
||||
packet := worstStream.infos[0].packet
|
||||
worstStream.infos = worstStream.infos[1:]
|
||||
worstStream.size -= uint64(len(packet))
|
||||
q.size -= uint64(len(packet))
|
||||
pool_putBytes(packet)
|
||||
// save the modified stream to queues
|
||||
if len(worstStream.infos) > 0 {
|
||||
q.streams[worst] = worstStream
|
||||
} else {
|
||||
delete(q.streams, worst)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (q *packetQueue) push(packet []byte) {
|
||||
|
@ -80,7 +81,6 @@ func (q *packetQueue) push(packet []byte) {
|
|||
// save update to queues
|
||||
q.streams[id] = stream
|
||||
q.size += uint64(len(packet))
|
||||
q.cleanup()
|
||||
}
|
||||
|
||||
func (q *packetQueue) pop() ([]byte, bool) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue