Files
sing-box-extended/transport/call/tunnel/config_ack.go

70 lines
1.4 KiB
Go

package tunnel
import (
"fmt"
"sync"
"time"
"github.com/sagernet/sing/common/logger"
)
const configResendPeriod = 3 * time.Second
type ConfigAckTracker struct {
mu sync.Mutex
acked chan struct{}
cancel chan struct{}
confirmed bool
}
func (t *ConfigAckTracker) Acknowledged() bool {
t.mu.Lock()
defer t.mu.Unlock()
return t.confirmed
}
func (t *ConfigAckTracker) Arm() (acked, cancel chan struct{}) {
t.mu.Lock()
defer t.mu.Unlock()
if t.cancel != nil {
close(t.cancel)
}
t.acked = make(chan struct{})
t.cancel = make(chan struct{})
return t.acked, t.cancel
}
func (t *ConfigAckTracker) Mark() {
t.mu.Lock()
defer t.mu.Unlock()
t.confirmed = true
if t.acked == nil {
return
}
select {
case <-t.acked:
default:
close(t.acked)
}
}
func SendVP8ConfigUntilAcked(acked, cancel <-chan struct{}, stopCh <-chan struct{}, tun DataTunnel, fps, batch, trackCount int, logger logger.ContextLogger, logPrefix string) {
tun.SendData(EncodeVP8Config(fps, batch, trackCount))
ticker := time.NewTicker(configResendPeriod)
defer ticker.Stop()
for {
select {
case <-acked:
return
case <-cancel:
return
case <-stopCh:
return
case <-ticker.C:
logger.Debug(fmt.Sprintf("%s: resending vp8 config fps=%d batch=%d trackCount=%d, no ack yet",
logPrefix, fps, batch, trackCount))
tun.SendData(EncodeVP8Config(fps, batch, trackCount))
}
}
}