diff --git a/v2/config/chain.go b/v2/config/chain.go index 3a6e7aeb2..4cbfce827 100644 --- a/v2/config/chain.go +++ b/v2/config/chain.go @@ -129,7 +129,9 @@ func chainWarpEndpoint(tag, chainStatus string, warp ChainWarpOptions, detour st Detour: detour, // register the WARP account along the same path }, Noise: chainWarpNoise(warp), - MTU: 1280, + // its packets travel inside the main proxy, which adds its own header: 1280 lost every + // packet above ~1200 bytes behind a shadowsocks server, 1000 passed + MTU: 1280, } options.Detour = detour if warp.CleanIP != "" { diff --git a/v2/hcore/custom.go b/v2/hcore/custom.go index 81e0a5263..9b8012fbf 100644 --- a/v2/hcore/custom.go +++ b/v2/hcore/custom.go @@ -15,7 +15,7 @@ func StopAndAlert(msgType MessageType, message string) { SetCoreStatus(CoreStates_STOPPED, msgType, message) if ss := static.StartedService; ss != nil { - ss.CloseService() + closeService(ss) static.StartedService = nil } } diff --git a/v2/hcore/independent_instance.go b/v2/hcore/independent_instance.go index 4e38d067b..d512092fc 100644 --- a/v2/hcore/independent_instance.go +++ b/v2/hcore/independent_instance.go @@ -73,7 +73,7 @@ func RunInstance(ctx context.Context, hiddifySettings *config.HiddifyOptions, si // dialer, err := s.libbox.GetInstance().Router().Dialer(context.Background()) func (s *HiddifyInstance) Close() error { - return s.StartedService.CloseService() + return closeService(s.StartedService) } func (s *HiddifyInstance) GetContent(url string) (string, error) { diff --git a/v2/hcore/service.go b/v2/hcore/service.go index 83e5e6526..d70f70881 100644 --- a/v2/hcore/service.go +++ b/v2/hcore/service.go @@ -44,9 +44,11 @@ func NewService(ctx context.Context, options option.Options) (*daemon.StartedSer content, err := json.MarshalContext(ctx, options) if err != nil { + closeService(instance) return nil, err } if err := instance.StartOrReloadService(ctx, string(content), nil); err != nil { + closeService(instance) return nil, err } @@ -59,6 +61,14 @@ func NewService(ctx context.Context, options option.Options) (*daemon.StartedSer return instance, nil } +// closeService stops ss and ends its observer goroutines. CloseService alone +// stops only the box and leaves five goroutines running for every service built. +func closeService(ss *daemon.StartedService) error { + err := ss.CloseService() + ss.Close() + return err +} + func (h *HiddifyInstance) UrlTestHistory() *urltest.HistoryStorage { ins := h.Instance() diff --git a/v2/hcore/start.go b/v2/hcore/start.go index 1f5998a9a..b79b2d3e9 100644 --- a/v2/hcore/start.go +++ b/v2/hcore/start.go @@ -204,7 +204,7 @@ func startServiceLocked(ctx context.Context, in *StartRequest) (coreResponse *Co } if err := contextErr(ctx); err != nil { // cancelled while the service was starting: stop it again - if closeErr := instance.CloseService(); closeErr != nil { + if closeErr := closeService(instance); closeErr != nil { Log(LogLevel_ERROR, LogType_CORE, "closing cancelled service: ", closeErr.Error()) } return cancelledStart(err) diff --git a/v2/hcore/stop.go b/v2/hcore/stop.go index 51bd1802e..9df8c24e4 100644 --- a/v2/hcore/stop.go +++ b/v2/hcore/stop.go @@ -32,7 +32,7 @@ func Stop() (coreResponse *CoreInfoResponse, err error) { return SetCoreStatus(CoreStates_STOPPED, MessageType_ALREADY_STOPPED, ""), nil } - if err := ss.CloseService(); err != nil { + if err := closeService(ss); err != nil { static.StartedService = nil dumpGoroutinesToFile(fmt.Sprint(sWorkingPath, "/data/goroutine-stop.log")) return errorWrapper(MessageType_UNEXPECTED_ERROR, err) diff --git a/v2/hcore/tunnelservice/tunnel_service.go b/v2/hcore/tunnelservice/tunnel_service.go index 94cf97152..a30c8e696 100644 --- a/v2/hcore/tunnelservice/tunnel_service.go +++ b/v2/hcore/tunnelservice/tunnel_service.go @@ -111,6 +111,8 @@ func (s *TunnelService) Stop(ctx context.Context, _ *hcommon.Empty) (*TunnelResp }, nil } err := s.box.CloseService() + // CloseService leaves the box's observer goroutines running; Close ends them. + s.box.Close() if err != nil { return &TunnelResponse{ Message: err.Error(), @@ -131,6 +133,7 @@ func (s *TunnelService) Status(ctx context.Context, _ *hcommon.Empty) (*TunnelRe func (s *TunnelService) Exit(ctx context.Context, _ *hcommon.Empty) (*TunnelResponse, error) { if s.box != nil { s.box.CloseService() + s.box.Close() } go func() { <-time.After(time.Second * 1)