ack_timer.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package sctp
  4. import (
  5. "math"
  6. "sync"
  7. "time"
  8. )
  9. const (
  10. ackInterval time.Duration = 200 * time.Millisecond
  11. )
  12. // ackTimerObserver is the inteface to an ack timer observer.
  13. type ackTimerObserver interface {
  14. onAckTimeout()
  15. }
  16. type ackTimerState int
  17. const (
  18. ackTimerStopped ackTimerState = iota
  19. ackTimerStarted
  20. ackTimerClosed
  21. )
  22. // ackTimer provides the retnransmission timer conforms with RFC 4960 Sec 6.3.1
  23. type ackTimer struct {
  24. observer ackTimerObserver
  25. mutex sync.RWMutex
  26. state ackTimerState
  27. timer *time.Timer
  28. }
  29. // newAckTimer creates a new acknowledgement timer used to enable delayed ack.
  30. func newAckTimer(observer ackTimerObserver) *ackTimer {
  31. t := &ackTimer{observer: observer}
  32. t.timer = time.AfterFunc(math.MaxInt64, t.timeout)
  33. t.timer.Stop()
  34. return t
  35. }
  36. func (t *ackTimer) timeout() {
  37. t.mutex.Lock()
  38. if t.state == ackTimerStarted {
  39. t.state = ackTimerStopped
  40. defer t.observer.onAckTimeout()
  41. }
  42. t.mutex.Unlock()
  43. }
  44. // start starts the timer.
  45. func (t *ackTimer) start() bool {
  46. t.mutex.Lock()
  47. defer t.mutex.Unlock()
  48. // this timer is already closed or already running
  49. if t.state != ackTimerStopped {
  50. return false
  51. }
  52. t.state = ackTimerStarted
  53. t.timer.Reset(ackInterval)
  54. return true
  55. }
  56. // stops the timer. this is similar to stop() but subsequent start() call
  57. // will fail (the timer is no longer usable)
  58. func (t *ackTimer) stop() {
  59. t.mutex.Lock()
  60. defer t.mutex.Unlock()
  61. if t.state == ackTimerStarted {
  62. t.timer.Stop()
  63. t.state = ackTimerStopped
  64. }
  65. }
  66. // closes the timer. this is similar to stop() but subsequent start() call
  67. // will fail (the timer is no longer usable)
  68. func (t *ackTimer) close() {
  69. t.mutex.Lock()
  70. defer t.mutex.Unlock()
  71. if t.state == ackTimerStarted {
  72. t.timer.Stop()
  73. }
  74. t.state = ackTimerClosed
  75. }
  76. // isRunning tests if the timer is running.
  77. // Debug purpose only
  78. func (t *ackTimer) isRunning() bool {
  79. t.mutex.RLock()
  80. defer t.mutex.RUnlock()
  81. return t.state == ackTimerStarted
  82. }