@@ -10,10 +10,13 @@ import (
1010)
1111
1212const (
13+ // Default SACK delay per RFC 9260 (protocol parameter 'SACK.Delay').
1314 ackInterval time.Duration = 200 * time .Millisecond
15+ // Implementations MUST NOT allow SACK.Delay > 500ms (RFC 9260).
16+ ackMaxDelay time.Duration = 500 * time .Millisecond
1417)
1518
16- // ackTimerObserver is the inteface to an ack timer observer.
19+ // ackTimerObserver is the interface to an ack timer observer.
1720type ackTimerObserver interface {
1821 onAckTimeout ()
1922}
@@ -26,18 +29,27 @@ const (
2629 ackTimerClosed
2730)
2831
29- // ackTimer provides the retnransmission timer conforms with RFC 4960 Sec 6.3.1 .
32+ // ackTimer provides the SACK.Delay according to RFC 9260 section 6.2 .
3033type ackTimer struct {
3134 timer * time.Timer
3235 observer ackTimerObserver
33- mutex sync.Mutex
34- state ackTimerState
35- pending uint8
36+
37+ mutex sync.Mutex
38+ state ackTimerState
39+ pending uint8
40+
41+ // Configurable SACK delay clamped to (0, ackMaxDelay].
42+ interval time.Duration
3643}
3744
3845// newAckTimer creates a new acknowledgement timer used to enable delayed ack.
46+ // Default delay is 200ms (SACK.Delay). The maximum allowed by spec is 500ms.
3947func newAckTimer (observer ackTimerObserver ) * ackTimer {
40- t := & ackTimer {observer : observer }
48+ t := & ackTimer {
49+ observer : observer ,
50+ interval : ackInterval ,
51+ }
52+
4153 t .timer = time .AfterFunc (math .MaxInt64 , t .timeout )
4254 t .timer .Stop ()
4355
@@ -53,7 +65,7 @@ func (t *ackTimer) timeout() {
5365 t .mutex .Unlock ()
5466}
5567
56- // start starts the timer.
68+ // start starts the timer if not already running. Returns true if it started .
5769func (t * ackTimer ) start () bool {
5870 t .mutex .Lock ()
5971 defer t .mutex .Unlock ()
@@ -65,20 +77,30 @@ func (t *ackTimer) start() bool {
6577
6678 t .state = ackTimerStarted
6779 t .pending ++
68- t .timer .Reset (ackInterval )
80+
81+ // Clamp interval (0, ackMaxDelay].
82+ delay := t .interval
83+ if delay <= 0 {
84+ delay = ackInterval
85+ } else if delay > ackMaxDelay {
86+ delay = ackMaxDelay
87+ }
88+
89+ t .timer .Reset (delay )
6990
7091 return true
7192}
7293
73- // stops the timer. this is similar to stop() but subsequent start() call
74- // will fail (the timer is no longer usable).
94+ // stop stops the timer if running and keeps it reusable.
7595func (t * ackTimer ) stop () {
7696 t .mutex .Lock ()
7797 defer t .mutex .Unlock ()
7898
7999 if t .state == ackTimerStarted {
80100 if t .timer .Stop () {
81- t .pending --
101+ if t .pending > 0 {
102+ t .pending --
103+ }
82104 }
83105 t .state = ackTimerStopped
84106 }
@@ -91,7 +113,9 @@ func (t *ackTimer) close() {
91113 defer t .mutex .Unlock ()
92114
93115 if t .state == ackTimerStarted && t .timer .Stop () {
94- t .pending --
116+ if t .pending > 0 {
117+ t .pending --
118+ }
95119 }
96120 t .state = ackTimerClosed
97121}
0 commit comments