mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
Fix start lifecycle
This commit is contained in:
@@ -96,6 +96,15 @@ type appleTransport struct {
|
||||
closed bool
|
||||
}
|
||||
|
||||
func validateAppleTransport(ctx context.Context, options option.HTTPClientOptions) error {
|
||||
sessionConfig, err := newAppleSessionConfig(ctx, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sessionConfig.close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func newAppleTransport(ctx context.Context, logger logger.ContextLogger, rawDialer N.Dialer, options option.HTTPClientOptions) (innerTransport, error) {
|
||||
sessionConfig, err := newAppleSessionConfig(ctx, options)
|
||||
if err != nil {
|
||||
@@ -111,6 +120,10 @@ func newAppleTransport(ctx context.Context, logger logger.ContextLogger, rawDial
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = bridge.Start()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shared := &appleTransportShared{
|
||||
logger: logger,
|
||||
bridge: bridge,
|
||||
|
||||
@@ -11,6 +11,10 @@ import (
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
func validateAppleTransport(ctx context.Context, options option.HTTPClientOptions) error {
|
||||
return E.New("Apple HTTP engine is not available on non-Apple platforms")
|
||||
}
|
||||
|
||||
func newAppleTransport(ctx context.Context, logger logger.ContextLogger, rawDialer N.Dialer, options option.HTTPClientOptions) (innerTransport, error) {
|
||||
return nil, E.New("Apple HTTP engine is not available on non-Apple platforms")
|
||||
}
|
||||
|
||||
@@ -35,11 +35,11 @@ func NewTransport(ctx context.Context, logger logger.ContextLogger, tag string,
|
||||
var cheapRebuild bool
|
||||
switch options.Engine {
|
||||
case C.TLSEngineApple:
|
||||
inner, transportErr := newAppleTransport(ctx, logger, rawDialer, options)
|
||||
if transportErr != nil {
|
||||
return nil, transportErr
|
||||
err = validateAppleTransport(ctx, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
managedTransport := &ManagedTransport{
|
||||
return &ManagedTransport{
|
||||
dialer: rawDialer,
|
||||
headers: headers,
|
||||
host: host,
|
||||
@@ -47,9 +47,7 @@ func NewTransport(ctx context.Context, logger logger.ContextLogger, tag string,
|
||||
factory: func() (innerTransport, error) {
|
||||
return newAppleTransport(ctx, logger, rawDialer, options)
|
||||
},
|
||||
}
|
||||
managedTransport.epoch.Store(&transportEpoch{transport: inner})
|
||||
return managedTransport, nil
|
||||
}, nil
|
||||
case "", C.TLSEngineGo:
|
||||
cheapRebuild = true
|
||||
default:
|
||||
|
||||
@@ -34,23 +34,26 @@ type Bridge struct {
|
||||
func New(ctx context.Context, logger logger.ContextLogger, tag string, dialer N.Dialer) (*Bridge, error) {
|
||||
username := randomHex(16)
|
||||
password := randomHex(16)
|
||||
tcpListener, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1)})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bridge := &Bridge{
|
||||
return &Bridge{
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
tag: tag,
|
||||
dialer: dialer,
|
||||
connection: service.FromContext[adapter.ConnectionManager](ctx),
|
||||
tcpListener: tcpListener,
|
||||
username: username,
|
||||
password: password,
|
||||
authenticator: auth.NewAuthenticator([]auth.User{{Username: username, Password: password}}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *Bridge) Start() error {
|
||||
tcpListener, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go bridge.acceptLoop()
|
||||
return bridge, nil
|
||||
b.tcpListener = tcpListener
|
||||
go b.acceptLoop()
|
||||
return nil
|
||||
}
|
||||
|
||||
func randomHex(size int) string {
|
||||
@@ -72,7 +75,7 @@ func (b *Bridge) Password() string {
|
||||
}
|
||||
|
||||
func (b *Bridge) Close() error {
|
||||
return common.Close(b.tcpListener)
|
||||
return common.Close(common.PtrOrNil(b.tcpListener))
|
||||
}
|
||||
|
||||
func (b *Bridge) acceptLoop() {
|
||||
|
||||
+44
-21
@@ -26,21 +26,45 @@ import (
|
||||
)
|
||||
|
||||
type acmeWrapper struct {
|
||||
ctx context.Context
|
||||
cfg *certmagic.Config
|
||||
cache *certmagic.Cache
|
||||
domain []string
|
||||
ctx context.Context
|
||||
cfg *certmagic.Config
|
||||
cache *certmagic.Cache
|
||||
zapLogger *zap.Logger
|
||||
dataDirectory string
|
||||
domain []string
|
||||
}
|
||||
|
||||
func (w *acmeWrapper) Start() error {
|
||||
if w.dataDirectory != "" {
|
||||
err := filemanager.MkdirAll(w.ctx, w.dataDirectory, 0o700)
|
||||
if err != nil {
|
||||
return E.Cause(err, "create ACME data directory")
|
||||
}
|
||||
}
|
||||
config := w.cfg
|
||||
cache := certmagic.NewCache(certmagic.CacheOptions{
|
||||
GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) {
|
||||
return config, nil
|
||||
},
|
||||
Logger: w.zapLogger,
|
||||
})
|
||||
config = certmagic.New(cache, *config)
|
||||
w.cfg = config
|
||||
w.cache = cache
|
||||
return w.cfg.ManageSync(w.ctx, w.domain)
|
||||
}
|
||||
|
||||
func (w *acmeWrapper) Close() error {
|
||||
w.cache.Stop()
|
||||
if w.cache != nil {
|
||||
w.cache.Stop()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *acmeWrapper) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
return w.cfg.GetCertificate(hello)
|
||||
}
|
||||
|
||||
func startACME(ctx context.Context, logger logger.Logger, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
|
||||
var acmeServer string
|
||||
switch options.Provider {
|
||||
@@ -54,13 +78,12 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
|
||||
}
|
||||
acmeServer = options.Provider
|
||||
}
|
||||
var storage certmagic.Storage
|
||||
var (
|
||||
storage certmagic.Storage
|
||||
dataDirectory string
|
||||
)
|
||||
if options.DataDirectory != "" {
|
||||
dataDirectory := filemanager.BasePath(ctx, os.ExpandEnv(options.DataDirectory))
|
||||
err := filemanager.MkdirAll(ctx, dataDirectory, 0o700)
|
||||
if err != nil {
|
||||
return nil, nil, E.Cause(err, "create ACME data directory")
|
||||
}
|
||||
dataDirectory = filemanager.BasePath(ctx, os.ExpandEnv(options.DataDirectory))
|
||||
storage = &certmagic.FileStorage{
|
||||
Path: dataDirectory,
|
||||
}
|
||||
@@ -126,23 +149,23 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
|
||||
acmeConfig.ExternalAccount = (*acme.EAB)(options.ExternalAccount)
|
||||
}
|
||||
config.Issuers = []certmagic.Issuer{certmagic.NewACMEIssuer(config, acmeConfig)}
|
||||
cache := certmagic.NewCache(certmagic.CacheOptions{
|
||||
GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) {
|
||||
return config, nil
|
||||
},
|
||||
Logger: zapLogger,
|
||||
})
|
||||
config = certmagic.New(cache, *config)
|
||||
wrapper := &acmeWrapper{
|
||||
ctx: ctx,
|
||||
cfg: config,
|
||||
zapLogger: zapLogger,
|
||||
dataDirectory: dataDirectory,
|
||||
domain: options.Domain,
|
||||
}
|
||||
var tlsConfig *tls.Config
|
||||
if acmeConfig.DisableTLSALPNChallenge || acmeConfig.DNS01Solver != nil {
|
||||
tlsConfig = &tls.Config{
|
||||
GetCertificate: config.GetCertificate,
|
||||
GetCertificate: wrapper.GetCertificate,
|
||||
}
|
||||
} else {
|
||||
tlsConfig = &tls.Config{
|
||||
GetCertificate: config.GetCertificate,
|
||||
GetCertificate: wrapper.GetCertificate,
|
||||
NextProtos: []string{C.ACMETLS1Protocol},
|
||||
}
|
||||
}
|
||||
return tlsConfig, &acmeWrapper{ctx: ctx, cfg: config, cache: cache, domain: options.Domain}, nil
|
||||
return tlsConfig, wrapper, nil
|
||||
}
|
||||
|
||||
@@ -50,13 +50,10 @@ type Manager struct {
|
||||
}
|
||||
|
||||
func NewManager(outbound adapter.OutboundManager) *Manager {
|
||||
manager := &Manager{
|
||||
return &Manager{
|
||||
outbound: outbound,
|
||||
eventSubscriber: observable.NewSubscriber[ConnectionEvent](256),
|
||||
}
|
||||
manager.eventObserver = observable.NewObserver(manager.eventSubscriber, 64)
|
||||
manager.cleaner = cleanup.Add(manager.Clear)
|
||||
return manager
|
||||
}
|
||||
|
||||
func (m *Manager) Name() string {
|
||||
@@ -64,12 +61,21 @@ func (m *Manager) Name() string {
|
||||
}
|
||||
|
||||
func (m *Manager) Start(stage adapter.StartStage) error {
|
||||
if stage == adapter.StartStateInitialize {
|
||||
m.eventObserver = observable.NewObserver(m.eventSubscriber, 64)
|
||||
m.cleaner = cleanup.Add(m.Clear)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Close() error {
|
||||
m.cleaner.Close()
|
||||
return m.eventObserver.Close()
|
||||
if m.cleaner != nil {
|
||||
m.cleaner.Close()
|
||||
}
|
||||
if m.eventObserver != nil {
|
||||
return m.eventObserver.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) SubscribeEvents() (observable.Subscription[ConnectionEvent], <-chan struct{}, error) {
|
||||
|
||||
Reference in New Issue
Block a user