mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 20:24:03 +03:00
FILE / ScuroNeko/mtg
faketls/cloak.go
Исходный файл и его история в репозитории.
74 lines
1.2 KiB
Go
74 lines
1.2 KiB
Go
package faketls
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/9seconds/mtg/wrappers/rwc"
|
|
)
|
|
|
|
const (
|
|
cloakLastActivityTimeout = 5 * time.Second
|
|
cloakMaxTimeout = 30 * time.Second
|
|
)
|
|
|
|
func cloak(one, another io.ReadWriteCloser) {
|
|
defer func() {
|
|
one.Close()
|
|
another.Close()
|
|
}()
|
|
|
|
channelPing := make(chan struct{}, 1)
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
one = rwc.NewPing(ctx, one, channelPing)
|
|
another = rwc.NewPing(ctx, another, channelPing)
|
|
wg := &sync.WaitGroup{}
|
|
|
|
wg.Add(2)
|
|
|
|
go cloakPipe(one, another, wg)
|
|
|
|
go cloakPipe(another, one, wg)
|
|
|
|
go func() {
|
|
wg.Wait()
|
|
cancel()
|
|
}()
|
|
|
|
go func() {
|
|
lastActivityTimer := time.NewTimer(cloakLastActivityTimeout)
|
|
defer lastActivityTimer.Stop()
|
|
|
|
maxTimer := time.NewTimer(cloakMaxTimeout)
|
|
defer maxTimer.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-channelPing:
|
|
lastActivityTimer.Stop()
|
|
lastActivityTimer = time.NewTimer(cloakLastActivityTimeout)
|
|
case <-ctx.Done():
|
|
return
|
|
case <-lastActivityTimer.C:
|
|
cancel()
|
|
|
|
return
|
|
case <-maxTimer.C:
|
|
cancel()
|
|
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
<-ctx.Done()
|
|
}
|
|
|
|
func cloakPipe(one io.Writer, another io.Reader, wg *sync.WaitGroup) {
|
|
defer wg.Done()
|
|
|
|
io.Copy(one, another) // nolint: errcheck
|
|
}
|