github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/internal/ackhandler/received_packet_history.go (about) 1 package ackhandler 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/danielpfeifer02/quic-go-prio-packs/internal/protocol" 8 list "github.com/danielpfeifer02/quic-go-prio-packs/internal/utils/linkedlist" 9 "github.com/danielpfeifer02/quic-go-prio-packs/internal/wire" 10 "github.com/danielpfeifer02/quic-go-prio-packs/packet_setting" 11 ) 12 13 // interval is an interval from one PacketNumber to the other 14 type interval struct { 15 Start protocol.PacketNumber 16 End protocol.PacketNumber 17 } 18 19 var intervalElementPool sync.Pool 20 21 func init() { 22 intervalElementPool = *list.NewPool[interval]() 23 } 24 25 // The receivedPacketHistory stores if a packet number has already been received. 26 // It generates ACK ranges which can be used to assemble an ACK frame. 27 // It does not store packet contents. 28 type receivedPacketHistory struct { 29 ranges *list.List[interval] 30 31 deletedBelow protocol.PacketNumber 32 } 33 34 func newReceivedPacketHistory() *receivedPacketHistory { 35 return &receivedPacketHistory{ 36 ranges: list.NewWithPool[interval](&intervalElementPool), 37 } 38 } 39 40 // ReceivedPacket registers a packet with PacketNumber p and updates the ranges 41 func (h *receivedPacketHistory) ReceivedPacket(p protocol.PacketNumber) bool /* is a new packet (and not a duplicate / delayed packet) */ { 42 // ignore delayed packets, if we already deleted the range 43 if p < h.deletedBelow { 44 45 // PACKET_NUMBER_TAG 46 if packet_setting.PRINT_PACKET_RECEIVING_INFO { 47 fmt.Println("ReceivedPacket: Ignoring delayed packet with pn", p, "because it is below deletedBelow", h.deletedBelow) 48 } 49 50 return false 51 } 52 53 // PACKET_NUMBER_TAG 54 if packet_setting.PRINT_PACKET_RECEIVING_INFO { 55 fmt.Println("ReceivedPacket: Received packet with pn", p) 56 } 57 58 isNew := h.addToRanges(p) 59 h.maybeDeleteOldRanges() 60 return isNew 61 } 62 63 func (h *receivedPacketHistory) addToRanges(p protocol.PacketNumber) bool /* is a new packet (and not a duplicate / delayed packet) */ { 64 if h.ranges.Len() == 0 { 65 h.ranges.PushBack(interval{Start: p, End: p}) 66 return true 67 } 68 69 for el := h.ranges.Back(); el != nil; el = el.Prev() { 70 // p already included in an existing range. Nothing to do here 71 if p >= el.Value.Start && p <= el.Value.End { 72 return false 73 } 74 75 if el.Value.End == p-1 { // extend a range at the end 76 el.Value.End = p 77 return true 78 } 79 if el.Value.Start == p+1 { // extend a range at the beginning 80 el.Value.Start = p 81 82 prev := el.Prev() 83 if prev != nil && prev.Value.End+1 == el.Value.Start { // merge two ranges 84 prev.Value.End = el.Value.End 85 h.ranges.Remove(el) 86 } 87 return true 88 } 89 90 // create a new range at the end 91 if p > el.Value.End { 92 h.ranges.InsertAfter(interval{Start: p, End: p}, el) 93 return true 94 } 95 } 96 97 // create a new range at the beginning 98 h.ranges.InsertBefore(interval{Start: p, End: p}, h.ranges.Front()) 99 return true 100 } 101 102 // Delete old ranges, if we're tracking more than 500 of them. 103 // This is a DoS defense against a peer that sends us too many gaps. 104 func (h *receivedPacketHistory) maybeDeleteOldRanges() { 105 for h.ranges.Len() > protocol.MaxNumAckRanges { 106 h.ranges.Remove(h.ranges.Front()) 107 } 108 } 109 110 // DeleteBelow deletes all entries below (but not including) p 111 func (h *receivedPacketHistory) DeleteBelow(p protocol.PacketNumber) { 112 if p < h.deletedBelow { 113 return 114 } 115 h.deletedBelow = p 116 117 nextEl := h.ranges.Front() 118 for el := h.ranges.Front(); nextEl != nil; el = nextEl { 119 nextEl = el.Next() 120 121 if el.Value.End < p { // delete a whole range 122 h.ranges.Remove(el) 123 } else if p > el.Value.Start && p <= el.Value.End { 124 el.Value.Start = p 125 return 126 } else { // no ranges affected. Nothing to do 127 return 128 } 129 } 130 } 131 132 // AppendAckRanges appends to a slice of all AckRanges that can be used in an AckFrame 133 func (h *receivedPacketHistory) AppendAckRanges(ackRanges []wire.AckRange) []wire.AckRange { 134 if h.ranges.Len() > 0 { 135 for el := h.ranges.Back(); el != nil; el = el.Prev() { 136 ackRanges = append(ackRanges, wire.AckRange{Smallest: el.Value.Start, Largest: el.Value.End}) 137 } 138 } 139 return ackRanges 140 } 141 142 func (h *receivedPacketHistory) GetHighestAckRange() wire.AckRange { 143 ackRange := wire.AckRange{} 144 if h.ranges.Len() > 0 { 145 r := h.ranges.Back().Value 146 ackRange.Smallest = r.Start 147 ackRange.Largest = r.End 148 } 149 return ackRange 150 } 151 152 func (h *receivedPacketHistory) IsPotentiallyDuplicate(p protocol.PacketNumber) bool { 153 if p < h.deletedBelow { 154 return true 155 } 156 for el := h.ranges.Back(); el != nil; el = el.Prev() { 157 if p > el.Value.End { 158 return false 159 } 160 if p <= el.Value.End && p >= el.Value.Start { 161 return true 162 } 163 } 164 return false 165 }