refine ack list flushing

pull/215/head
v2ray 9 years ago
parent 5680c69146
commit d63330d15e
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169

@ -81,7 +81,7 @@ func NewKCP(conv uint16, mtu uint32, sendingWindowSize uint32, receivingWindowSi
kcp.rcv_buf = NewReceivingWindow(receivingWindowSize) kcp.rcv_buf = NewReceivingWindow(receivingWindowSize)
kcp.snd_queue = NewSendingQueue(sendingQueueSize) kcp.snd_queue = NewSendingQueue(sendingQueueSize)
kcp.rcv_queue = NewReceivingQueue() kcp.rcv_queue = NewReceivingQueue()
kcp.acklist = new(ACKList) kcp.acklist = NewACKList(kcp)
kcp.cwnd = kcp.snd_wnd kcp.cwnd = kcp.snd_wnd
return kcp return kcp
} }
@ -250,9 +250,7 @@ func (kcp *KCP) HandleReceivingNext(receivingNext uint32) {
} }
func (kcp *KCP) HandleSendingNext(sendingNext uint32) { func (kcp *KCP) HandleSendingNext(sendingNext uint32) {
if kcp.acklist.Clear(sendingNext) { kcp.acklist.Clear(sendingNext)
kcp.receivingUpdated = true
}
} }
func (kcp *KCP) parse_data(newseg *DataSegment) { func (kcp *KCP) parse_data(newseg *DataSegment) {
@ -367,16 +365,9 @@ func (kcp *KCP) flush() {
lost := false lost := false
// flush acknowledges // flush acknowledges
//if kcp.receivingUpdated { if kcp.acklist.Flush() {
ackSeg := kcp.acklist.AsSegment()
if ackSeg != nil {
ackSeg.Conv = kcp.conv
ackSeg.ReceivingWindow = uint32(kcp.rcv_nxt + kcp.rcv_wnd)
ackSeg.ReceivingNext = kcp.rcv_nxt
kcp.output.Write(ackSeg)
kcp.receivingUpdated = false kcp.receivingUpdated = false
} }
//}
// calculate window size // calculate window size
cwnd := kcp.snd_una + kcp.snd_wnd cwnd := kcp.snd_una + kcp.snd_wnd

@ -149,22 +149,35 @@ func (this *ReceivingQueue) Close() {
} }
type ACKList struct { type ACKList struct {
kcp *KCP
timestamps []uint32 timestamps []uint32
numbers []uint32 numbers []uint32
nextFlush []uint32
}
func NewACKList(kcp *KCP) *ACKList {
return &ACKList{
kcp: kcp,
timestamps: make([]uint32, 0, 32),
numbers: make([]uint32, 0, 32),
nextFlush: make([]uint32, 0, 32),
}
} }
func (this *ACKList) Add(number uint32, timestamp uint32) { func (this *ACKList) Add(number uint32, timestamp uint32) {
this.timestamps = append(this.timestamps, timestamp) this.timestamps = append(this.timestamps, timestamp)
this.numbers = append(this.numbers, number) this.numbers = append(this.numbers, number)
this.nextFlush = append(this.nextFlush, 0)
} }
func (this *ACKList) Clear(una uint32) bool { func (this *ACKList) Clear(una uint32) {
count := 0 count := 0
for i := 0; i < len(this.numbers); i++ { for i := 0; i < len(this.numbers); i++ {
if this.numbers[i] >= una { if this.numbers[i] >= una {
if i != count { if i != count {
this.numbers[count] = this.numbers[i] this.numbers[count] = this.numbers[i]
this.timestamps[count] = this.timestamps[i] this.timestamps[count] = this.timestamps[i]
this.nextFlush[count] = this.nextFlush[i]
} }
count++ count++
} }
@ -172,26 +185,34 @@ func (this *ACKList) Clear(una uint32) bool {
if count < len(this.numbers) { if count < len(this.numbers) {
this.numbers = this.numbers[:count] this.numbers = this.numbers[:count]
this.timestamps = this.timestamps[:count] this.timestamps = this.timestamps[:count]
return true this.nextFlush = this.nextFlush[:count]
} }
return false
} }
func (this *ACKList) AsSegment() *ACKSegment { func (this *ACKList) Flush() bool {
count := len(this.numbers) seg := &ACKSegment{
if count == 0 { Conv: this.kcp.conv,
return nil ReceivingNext: this.kcp.rcv_nxt,
ReceivingWindow: this.kcp.rcv_nxt + this.kcp.rcv_wnd,
} }
if this.kcp.state == StateReadyToClose {
if count > 128 { seg.Opt = SegmentOptionClose
count = 128
} }
seg := &ACKSegment{ current := this.kcp.current
Count: byte(count), for i := 0; i < len(this.numbers); i++ {
NumberList: this.numbers[:count], if this.nextFlush[i] <= current {
TimestampList: this.timestamps[:count], seg.Count++
seg.NumberList = append(seg.NumberList, this.numbers[i])
seg.TimestampList = append(seg.TimestampList, this.timestamps[i])
this.nextFlush[i] = current + 50
if seg.Count == 128 {
break
}
}
} }
//this.numbers = nil if seg.Count > 0 {
//this.timestamps = nil this.kcp.output.Write(seg)
return seg return true
}
return false
} }

Loading…
Cancel
Save