Release 3.8.0.2: app.zip updates, lock hygiene, secret-safe getState.
This commit is contained in:
+39
-20
@@ -79,54 +79,65 @@ func (m *Manager) Connect(ctx context.Context, profileName string) error {
|
||||
m.waitEngineStopped()
|
||||
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if m.engine != nil && m.engine.Running() {
|
||||
m.mu.Unlock()
|
||||
return fmt.Errorf("already connected; disconnect first")
|
||||
}
|
||||
if m.engine != nil {
|
||||
// Defunct reference (stop finished or engine died) — drop before start.
|
||||
m.engine = nil
|
||||
m.profile = nil
|
||||
}
|
||||
|
||||
if profileName != "" {
|
||||
m.cfg.Active = profileName
|
||||
}
|
||||
profile, err := m.cfg.ActiveProfile()
|
||||
if err != nil {
|
||||
m.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
profileCopy := *profile
|
||||
binDir := m.binDir
|
||||
wantSysProxy := m.cfg.SystemProxy
|
||||
cfgPath := m.cfgPath
|
||||
sys := m.sys
|
||||
stderr := m.stderr
|
||||
m.mu.Unlock()
|
||||
|
||||
engine, err := m.newEngine(profile.Protocol)
|
||||
engine, err := m.newEngine(profileCopy.Protocol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := engine.Start(ctx, *profile, m.binDir); err != nil {
|
||||
if err := engine.Start(ctx, profileCopy, binDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.cfg.SystemProxy {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if m.engine != nil && m.engine.Running() {
|
||||
_ = engine.Stop()
|
||||
return fmt.Errorf("already connected; disconnect first")
|
||||
}
|
||||
|
||||
if wantSysProxy {
|
||||
httpProxy, ok := engine.LocalHTTPProxy()
|
||||
if !ok {
|
||||
_ = engine.Stop()
|
||||
return fmt.Errorf("system_proxy requires an http:// listen address in the profile")
|
||||
}
|
||||
if err := m.sys.Enable(httpProxy); err != nil {
|
||||
if err := sys.Enable(httpProxy); err != nil {
|
||||
if errors.Is(err, sysproxy.ErrUnsupported) {
|
||||
fmt.Fprintf(m.stderr, "system proxy unsupported on this OS; local SOCKS/HTTP still up\n")
|
||||
fmt.Fprintf(stderr, "system proxy unsupported on this OS; local SOCKS/HTTP still up\n")
|
||||
} else {
|
||||
_ = engine.Stop()
|
||||
return fmt.Errorf("enable system proxy: %w", err)
|
||||
}
|
||||
} else {
|
||||
sysproxy.WriteSentinel(m.cfgPath, httpProxy)
|
||||
sysproxy.WriteSentinel(cfgPath, httpProxy)
|
||||
}
|
||||
}
|
||||
|
||||
m.engine = engine
|
||||
m.profile = profile
|
||||
m.profile = &profileCopy
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -552,25 +563,33 @@ func (m *Manager) newEngine(p config.Protocol) (Engine, error) {
|
||||
|
||||
// EnsureCore downloads the binary required by the active (or given) protocol.
|
||||
func (m *Manager) EnsureCore(proto config.Protocol) (string, error) {
|
||||
m.mu.Lock()
|
||||
binDir := m.binDir
|
||||
if proto == "" {
|
||||
if p, err := m.cfg.ActiveProfile(); err == nil {
|
||||
proto = p.Protocol
|
||||
}
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
switch proto {
|
||||
case config.ProtocolHysteria2:
|
||||
return hysteria2.EnsureBinary(m.binDir)
|
||||
return hysteria2.EnsureBinary(binDir)
|
||||
case config.ProtocolAWG:
|
||||
return awg.EnsureBinary(m.binDir)
|
||||
return awg.EnsureBinary(binDir)
|
||||
case config.ProtocolVLESS, config.ProtocolVMess, config.ProtocolTrojan:
|
||||
return xray.EnsureBinary(m.binDir)
|
||||
return xray.EnsureBinary(binDir)
|
||||
default:
|
||||
return naive.EnsureBinary(m.binDir)
|
||||
return naive.EnsureBinary(binDir)
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureAllCores installs naive + hysteria2 + xray cores (AWG is embedded).
|
||||
func (m *Manager) EnsureAllCores() (map[string]string, error) {
|
||||
m.mu.Lock()
|
||||
binDir := m.binDir
|
||||
m.mu.Unlock()
|
||||
|
||||
type item struct {
|
||||
key string
|
||||
path string
|
||||
@@ -580,10 +599,10 @@ func (m *Manager) EnsureAllCores() (map[string]string, error) {
|
||||
key string
|
||||
fn func() (string, error)
|
||||
}{
|
||||
{"naive", func() (string, error) { return naive.EnsureBinary(m.binDir) }},
|
||||
{"hysteria2", func() (string, error) { return hysteria2.EnsureBinary(m.binDir) }},
|
||||
{"awg", func() (string, error) { return awg.EnsureBinary(m.binDir) }},
|
||||
{"xray", func() (string, error) { return xray.EnsureBinary(m.binDir) }},
|
||||
{"naive", func() (string, error) { return naive.EnsureBinary(binDir) }},
|
||||
{"hysteria2", func() (string, error) { return hysteria2.EnsureBinary(binDir) }},
|
||||
{"awg", func() (string, error) { return awg.EnsureBinary(binDir) }},
|
||||
{"xray", func() (string, error) { return xray.EnsureBinary(binDir) }},
|
||||
}
|
||||
ch := make(chan item, len(jobs))
|
||||
for _, j := range jobs {
|
||||
|
||||
Reference in New Issue
Block a user