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:
Kleissner
2022-02-19 23:37:04 +01:00
parent 7d9e38a6f5
commit a41de8a4db
3 changed files with 11 additions and 7 deletions

View File

@@ -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 {

View File

@@ -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

View File

@@ -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
}