mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-17 02:47:51 +01:00
UDT: Fix critical bugs: congestion window size was not set on senders side; sentAck was not set in case ACK threshold wasn't reached, which caused resendACKTimer to fail to send
This commit is contained in:
@@ -29,6 +29,7 @@ func DefaultConfig() *Config {
|
||||
ListenReplayWindow: 5 * time.Minute,
|
||||
LingerTime: 10 * time.Second,
|
||||
MaxFlowWinSize: 64,
|
||||
MaxBandwidth: 0,
|
||||
MaxPacketSize: 65535,
|
||||
SynTime: 10000 * time.Microsecond,
|
||||
CongestionForSocket: func(sock *udtSocket) CongestionControl {
|
||||
|
||||
@@ -29,7 +29,7 @@ func (ncc NativeCongestionControl) Init(parms CongestionControlParms, synTime ti
|
||||
ncc.lastRCTime = time.Now()
|
||||
parms.SetACKPeriod(ncc.rcInterval)
|
||||
|
||||
// TODO: Once packet loss is reported, the ACK interval should fall back to 1, and increased if a stable connection is detected.
|
||||
// This value should be adjusted at runtime according to congestion.
|
||||
parms.SetACKInterval(4)
|
||||
|
||||
ncc.slowStart = true
|
||||
@@ -83,6 +83,7 @@ func (ncc NativeCongestionControl) OnACK(parms CongestionControlParms, ack packe
|
||||
} else {
|
||||
// Set the congestion window size (CWND) to: CWND = A * (RTT + SYN) + 16.
|
||||
cWndSize = uint((float64(recvRate)/float64(time.Second))*float64(rtt+ncc.rcInterval) + 16)
|
||||
parms.SetCongestionWindowSize(cWndSize)
|
||||
}
|
||||
if ncc.loss {
|
||||
ncc.loss = false
|
||||
|
||||
@@ -88,6 +88,7 @@ func (s *udtSocketRecv) goReceiveEvent() {
|
||||
case <-s.resendACKTimer: // handles both resending ACKs and NAKs
|
||||
if s.recvAck2.IsLess(s.sentAck) {
|
||||
s.sendACK(s.sentAck)
|
||||
s.unackPktCount = 0
|
||||
}
|
||||
if first, valid := s.recvLossList.FirstSequence(); valid {
|
||||
s.sendNAK(first, 1)
|
||||
@@ -467,12 +468,6 @@ func (s *udtSocketRecv) ingestError(p *packet.ErrPacket) {
|
||||
func (s *udtSocketRecv) ackEvent() {
|
||||
s.unackPktCount++
|
||||
|
||||
// Check if the threshold to send is reached, if used. Note that sendACK is called revery SynTime.
|
||||
ackInterval := uint(s.ackInterval.get())
|
||||
if (ackInterval > 0) && (ackInterval > s.unackPktCount) {
|
||||
return
|
||||
}
|
||||
|
||||
// The ack number is excluding.
|
||||
ack := s.lastSequence.Add(1)
|
||||
|
||||
@@ -481,6 +476,13 @@ func (s *udtSocketRecv) ackEvent() {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the threshold to send is reached, if used. Note that sendACK is called revery SynTime.
|
||||
ackInterval := uint(s.ackInterval.get())
|
||||
if (ackInterval > 0) && (ackInterval > s.unackPktCount) {
|
||||
s.sentAck = ack // This is needed for resendACKTimer to pick it up in case no ackInterval count of packets are immediately sent.
|
||||
return
|
||||
}
|
||||
|
||||
s.sendACK(ack)
|
||||
s.unackPktCount = 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user