Shadowsocks and Tinyproxy Start and Stop

This commit is contained in:
Quentin McGaw
2020-07-15 23:53:40 +00:00
parent 83cf59b93e
commit a0312ec916
2 changed files with 129 additions and 40 deletions

View File

@@ -14,6 +14,8 @@ import (
type Looper interface { type Looper interface {
Run(ctx context.Context, wg *sync.WaitGroup) Run(ctx context.Context, wg *sync.WaitGroup)
Restart() Restart()
Start()
Stop()
} }
type looper struct { type looper struct {
@@ -26,6 +28,8 @@ type looper struct {
uid int uid int
gid int gid int
restart chan struct{} restart chan struct{}
start chan struct{}
stop chan struct{}
} }
func (l *looper) logAndWait(ctx context.Context, err error) { func (l *looper) logAndWait(ctx context.Context, err error) {
@@ -48,23 +52,51 @@ func NewLooper(conf Configurator, firewallConf firewall.Configurator, settings s
uid: uid, uid: uid,
gid: gid, gid: gid,
restart: make(chan struct{}), restart: make(chan struct{}),
start: make(chan struct{}),
stop: make(chan struct{}),
} }
} }
func (l *looper) Restart() { l.restart <- struct{}{} } func (l *looper) Restart() { l.restart <- struct{}{} }
func (l *looper) Start() { l.start <- struct{}{} }
func (l *looper) Stop() { l.stop <- struct{}{} }
func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) { func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
wg.Add(1) wg.Add(1)
defer wg.Done() defer wg.Done()
select { waitForStart := true
case <-l.restart: for waitForStart {
case <-ctx.Done(): select {
return case <-l.stop:
l.logger.Info("not started yet")
case <-l.start:
waitForStart = false
case <-l.restart:
waitForStart = false
case <-ctx.Done():
return
}
} }
defer l.logger.Warn("loop exited") defer l.logger.Warn("loop exited")
l.settings.Enabled = true
var previousPort uint16 var previousPort uint16
for ctx.Err() == nil { for ctx.Err() == nil {
for !l.settings.Enabled {
// wait for a signal to re-enable
select {
case <-l.stop:
l.logger.Info("already disabled")
case <-l.restart:
l.settings.Enabled = true
case <-l.start:
l.settings.Enabled = true
case <-ctx.Done():
return
}
}
nameserver := l.dnsSettings.PlaintextAddress.String() nameserver := l.dnsSettings.PlaintextAddress.String()
if l.dnsSettings.Enabled { if l.dnsSettings.Enabled {
nameserver = "127.0.0.1" nameserver = "127.0.0.1"
@@ -107,22 +139,37 @@ func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
err := waitFn() // blocking err := waitFn() // blocking
waitError <- err waitError <- err
}() }()
select {
case <-ctx.Done(): stayHere := true
l.logger.Warn("context canceled: exiting loop") for stayHere {
shadowsocksCancel() select {
<-waitError case <-ctx.Done():
close(waitError) l.logger.Warn("context canceled: exiting loop")
return shadowsocksCancel()
case <-l.restart: // triggered restart <-waitError
l.logger.Info("restarting") close(waitError)
shadowsocksCancel() return
<-waitError case <-l.restart: // triggered restart
close(waitError) l.logger.Info("restarting")
case err := <-waitError: // unexpected error shadowsocksCancel()
shadowsocksCancel() <-waitError
close(waitError) close(waitError)
l.logAndWait(ctx, err) stayHere = false
case <-l.start:
l.logger.Info("already started")
case <-l.stop:
l.logger.Info("stopping")
shadowsocksCancel()
<-waitError
close(waitError)
l.settings.Enabled = false
stayHere = false
case err := <-waitError: // unexpected error
shadowsocksCancel()
close(waitError)
l.logAndWait(ctx, err)
}
} }
shadowsocksCancel() // repetition for linter only
} }
} }

View File

@@ -25,6 +25,8 @@ type looper struct {
uid int uid int
gid int gid int
restart chan struct{} restart chan struct{}
start chan struct{}
stop chan struct{}
} }
func (l *looper) logAndWait(ctx context.Context, err error) { func (l *looper) logAndWait(ctx context.Context, err error) {
@@ -46,23 +48,49 @@ func NewLooper(conf Configurator, firewallConf firewall.Configurator, settings s
uid: uid, uid: uid,
gid: gid, gid: gid,
restart: make(chan struct{}), restart: make(chan struct{}),
start: make(chan struct{}),
stop: make(chan struct{}),
} }
} }
func (l *looper) Restart() { l.restart <- struct{}{} } func (l *looper) Restart() { l.restart <- struct{}{} }
func (l *looper) Start() { l.start <- struct{}{} }
func (l *looper) Stop() { l.stop <- struct{}{} }
func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) { func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
wg.Add(1) wg.Add(1)
defer wg.Done() defer wg.Done()
select { waitForStart := true
case <-l.restart: for waitForStart {
case <-ctx.Done(): select {
return case <-l.stop:
l.logger.Info("not started yet")
case <-l.start:
waitForStart = false
case <-l.restart:
waitForStart = false
case <-ctx.Done():
return
}
} }
defer l.logger.Warn("loop exited") defer l.logger.Warn("loop exited")
var previousPort uint16 var previousPort uint16
for ctx.Err() == nil { for ctx.Err() == nil {
for !l.settings.Enabled {
// wait for a signal to re-enable
select {
case <-l.stop:
l.logger.Info("already disabled")
case <-l.restart:
l.settings.Enabled = true
case <-l.start:
l.settings.Enabled = true
case <-ctx.Done():
return
}
}
err := l.conf.MakeConf( err := l.conf.MakeConf(
l.settings.LogLevel, l.settings.LogLevel,
l.settings.Port, l.settings.Port,
@@ -100,22 +128,36 @@ func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) {
err := waitFn() // blocking err := waitFn() // blocking
waitError <- err waitError <- err
}() }()
select { stayHere := true
case <-ctx.Done(): for stayHere {
l.logger.Warn("context canceled: exiting loop") select {
tinyproxyCancel() case <-ctx.Done():
<-waitError l.logger.Warn("context canceled: exiting loop")
close(waitError) tinyproxyCancel()
return <-waitError
case <-l.restart: // triggered restart close(waitError)
l.logger.Info("restarting") return
tinyproxyCancel() case <-l.restart: // triggered restart
<-waitError l.logger.Info("restarting")
close(waitError) tinyproxyCancel()
case err := <-waitError: // unexpected error <-waitError
tinyproxyCancel() close(waitError)
close(waitError) stayHere = false
l.logAndWait(ctx, err) case <-l.start:
l.logger.Info("already started")
case <-l.stop:
l.logger.Info("stopping")
tinyproxyCancel()
<-waitError
close(waitError)
l.settings.Enabled = false
stayHere = false
case err := <-waitError: // unexpected error
tinyproxyCancel()
close(waitError)
l.logAndWait(ctx, err)
}
} }
tinyproxyCancel() // repetition for linter only
} }
} }