github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/tcp/stream-timing-keep_alive.go (about) 1 /* For license and copyright information please see the LEGAL file in the code repository */ 2 3 package tcp 4 5 import ( 6 "github.com/GeniusesGroup/libgo/protocol" 7 "github.com/GeniusesGroup/libgo/time/monotonic" 8 ) 9 10 type keepAlive struct { 11 enable bool 12 idle protocol.Duration 13 interval protocol.Duration 14 lastUse monotonic.Time 15 nextCheck monotonic.Time 16 retryCount int 17 } 18 19 func (ka *keepAlive) Init(now monotonic.Time) (next protocol.Duration) { 20 ka.enable = true 21 ka.idle = KeepAlive_Idle 22 ka.interval = KeepAlive_Interval 23 now.Add(KeepAlive_Interval) 24 ka.nextCheck = now 25 return KeepAlive_Interval 26 } 27 func (ka *keepAlive) Reinit() { 28 ka.enable = false 29 ka.interval = 0 30 ka.nextCheck = 0 31 ka.retryCount = 0 32 } 33 func (ka *keepAlive) Deinit() {} 34 35 // Don't block the caller 36 func (ka *keepAlive) CheckInterval(st *Stream, now monotonic.Time) (next protocol.Duration) { 37 if !ka.enable { 38 return -1 39 } 40 41 // TODO::: check stream state 42 43 // check last use of stream and compare with our state 44 if ka.lastUse != st.lastUse { 45 ka.lastUse = st.lastUse 46 now.Add(ka.idle) 47 ka.nextCheck = now 48 ka.retryCount = 0 49 next = ka.idle 50 return 51 } 52 53 next = ka.next(now) 54 if next > 0 { 55 return 56 } 57 if next < 0 { 58 // calculate timer delta because timer start after nextCheck. 59 if ka.retryCount == 0 { 60 next = ka.idle + next // + because we have negative next 61 } else { 62 next = ka.interval + next // + because we have negative next 63 } 64 } 65 ka.nextCheck.Add(next) 66 67 // if (tp->packets_out || !tcp_write_queue_empty(sk)) 68 69 if ka.retryCount <= KeepAlive_Probes { 70 // TODO::: send ack segment (keepalive message) 71 ka.retryCount++ 72 } else { 73 // TODO::: kill the stream 74 // return 75 } 76 return 77 } 78 79 // d can be negative that show ka.CheckInterval called with some delay 80 func (ka *keepAlive) next(now monotonic.Time) (d protocol.Duration) { 81 d = ka.nextCheck.Until(now) 82 return 83 }