分片机制开始实现 大致是使用了一个map管理+小根堆自动排序实现的

This commit is contained in:
impact-eintr
2022-11-28 11:31:46 +08:00
parent 553a16f655
commit cd0d9492a0
6 changed files with 87 additions and 19 deletions

View File

@@ -22,16 +22,18 @@ const HighFragThreshold = 4 << 20 // 4MB
// net.ipv4.ipfrag_low_thresh for more information.
const LowFragThreshold = 3 << 20 // 3MB
// Fragmentation 分片处理器对象
type Fragmentation struct {
mu sync.Mutex
highLimit int
lowLimit int
reassemblers map[uint32]*reassembler
reassemblers map[uint32]*reassembler // IP报文hash:重组器
rList reassemblerList
size int
timeout time.Duration
}
// NewFragmentation 新建一个分片处理器
func NewFragmentation(highMemoryLimit, lowMemoryLimit int, reassemblingTimeout time.Duration) *Fragmentation {
if lowMemoryLimit >= highMemoryLimit {
lowMemoryLimit = highMemoryLimit
@@ -49,20 +51,41 @@ func NewFragmentation(highMemoryLimit, lowMemoryLimit int, reassemblingTimeout t
}
}
// Process 处理ip报文分片
func (f *Fragmentation) Process(id uint32, first, last uint16, more bool, vv buffer.VectorisedView) (buffer.VectorisedView, bool) {
log.Println("分片机制工作中", id, first, last, vv.First())
f.mu.Lock()
r, ok := f.reassemblers[id]
if ok && r.tooOld(f.timeout) {
if ok && r.tooOld(f.timeout) { // 检测一个分片是否存在超过了30s
// This is very likely to be an id-collision or someone performing a slow-rate attack.
//f.release(r)
f.release(r)
ok = false
}
if !ok {
if !ok { // 首次注册该报文的分片
r = newReassembler(id)
f.reassemblers[id] = r
f.rList.PushFront(r)
}
f.mu.Unlock()
//res, done, consumed := r.process(first, last, more, vv)
log.Printf("[%d]的分片 [%d,%d) 合并中\n", id, first, last)
r.process(first, last, more, vv)
return buffer.VectorisedView{}, false
}
func (f *Fragmentation) release(r *reassembler) {
// Before releasing a fragment we need to check if r is already marked as done.
// Otherwise, we would delete it twice.
if r.checkDoneOrMark() {
return
}
delete(f.reassemblers, r.id)
f.rList.Remove(r)
f.size -= r.size
if f.size < 0 {
log.Printf("memory counter < 0 (%d), this is an accounting bug that requires investigation", f.size)
f.size = 0
}
}