mirror of
https://github.com/qdm12/gluetun.git
synced 2026-07-22 10:26:26 +02:00
wire up everything with gluetun
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
package socks5
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Loop struct {
|
||||
settings Settings
|
||||
|
||||
mutex sync.Mutex
|
||||
runCancel context.CancelFunc
|
||||
runDone <-chan error
|
||||
}
|
||||
|
||||
func NewLoop(settings Settings) *Loop {
|
||||
return &Loop{
|
||||
settings: settings,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Loop) String() string {
|
||||
return "SOCKS5 server loop"
|
||||
}
|
||||
|
||||
func (l *Loop) Start(_ context.Context) (runError <-chan error, err error) {
|
||||
l.mutex.Lock()
|
||||
defer l.mutex.Unlock()
|
||||
|
||||
var runCtx context.Context
|
||||
runCtx, l.runCancel = context.WithCancel(context.Background())
|
||||
|
||||
runDone := make(chan error)
|
||||
l.runDone = runDone
|
||||
runErrorCh := make(chan error)
|
||||
|
||||
go run(runCtx, runDone, l.settings)
|
||||
|
||||
return runErrorCh, nil
|
||||
}
|
||||
|
||||
func run(ctx context.Context, done chan<- error, settings Settings) {
|
||||
defer close(done)
|
||||
logger := settings.Logger
|
||||
|
||||
for ctx.Err() == nil {
|
||||
server := newServer(settings)
|
||||
errorCh, err := server.Start(ctx)
|
||||
if err != nil {
|
||||
logger.Warnf("failed starting SOCKS5 server: %s", err)
|
||||
waitBeforeRetry(ctx)
|
||||
continue
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
done <- server.Stop()
|
||||
return
|
||||
case err := <-errorCh:
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
logger.Warnf("SOCKS5 server crashed: %s", err)
|
||||
waitBeforeRetry(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Loop) Stop() (err error) {
|
||||
l.mutex.Lock()
|
||||
defer l.mutex.Unlock()
|
||||
|
||||
l.runCancel()
|
||||
return <-l.runDone
|
||||
}
|
||||
|
||||
func waitBeforeRetry(ctx context.Context) {
|
||||
const retryDelay = 10 * time.Second
|
||||
timer := time.NewTimer(retryDelay)
|
||||
select {
|
||||
case <-timer.C:
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ type Server struct {
|
||||
stopping atomic.Bool
|
||||
}
|
||||
|
||||
func New(settings Settings) *Server {
|
||||
func newServer(settings Settings) *Server {
|
||||
return &Server{
|
||||
username: settings.Username,
|
||||
password: settings.Password,
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestServerProxy(t *testing.T) {
|
||||
backendConnCh <- conn
|
||||
}()
|
||||
|
||||
server := New(Settings{
|
||||
server := newServer(Settings{
|
||||
Username: testCase.username,
|
||||
Password: testCase.password,
|
||||
Address: "127.0.0.1:0",
|
||||
@@ -215,7 +215,7 @@ func TestNew(t *testing.T) {
|
||||
for name, testCase := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := New(testCase.settings)
|
||||
result := newServer(testCase.settings)
|
||||
assert.Equal(t, testCase.expected.username, result.username)
|
||||
assert.Equal(t, testCase.expected.password, result.password)
|
||||
assert.Equal(t, testCase.expected.address, result.address)
|
||||
@@ -231,7 +231,7 @@ func TestStartStop(t *testing.T) {
|
||||
logger.EXPECT().Infof(gomock.Any(), gomock.Any()).Times(0)
|
||||
logger.EXPECT().Warnf(gomock.Any(), gomock.Any()).Times(0)
|
||||
|
||||
server := New(Settings{
|
||||
server := newServer(Settings{
|
||||
Address: "127.0.0.1:0",
|
||||
Logger: logger,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user