diff --git a/constant/status.go b/constant/status.go new file mode 100644 index 00000000..4a784bfa --- /dev/null +++ b/constant/status.go @@ -0,0 +1,9 @@ +package constant + +type TunnelStatus uint8 + +const ( + TunnelSuspend TunnelStatus = iota + TunnelInner + TunnelRunning +) diff --git a/hub/executor/executor.go b/hub/executor/executor.go index 21a25ecd..1b2ec572 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -75,24 +75,38 @@ func ParseWithBytes(buf []byte) (*config.Config, error) { func ApplyConfig(cfg *config.Config, force bool) { mux.Lock() defer mux.Unlock() - preUpdateExperimental(cfg) + + tunnel.OnSuspend() + + CTLS.ResetCertificate() + for _, c := range cfg.TLS.CustomTrustCert { + if err := CTLS.AddCertificate(c); err != nil { + log.Warnln("%s\nadd error: %s", c, err.Error()) + } + } + updateUsers(cfg.Users) updateProxies(cfg.Proxies, cfg.Providers) updateRules(cfg.Rules, cfg.SubRules, cfg.RuleProviders) updateSniffer(cfg.Sniffer) updateHosts(cfg.Hosts) updateGeneral(cfg.General) - initInnerTcp() updateDNS(cfg.DNS, cfg.General.IPv6) - loadProxyProvider(cfg.Providers) - updateProfile(cfg) - loadRuleProvider(cfg.RuleProviders) updateListeners(cfg.General, cfg.Listeners, force) updateIPTables(cfg) updateTun(cfg.General) updateExperimental(cfg) updateTunnels(cfg.Tunnels) + tunnel.OnInnerLoading() + + initInnerTcp() + loadProxyProvider(cfg.Providers) + updateProfile(cfg) + loadRuleProvider(cfg.RuleProviders) + + tunnel.OnRunning() + log.SetLevel(cfg.General.LogLevel) } @@ -144,10 +158,6 @@ func updateListeners(general *config.General, listeners map[string]C.InboundList return } - if general.Interface == "" && (!general.Tun.Enable || !general.Tun.AutoDetectInterface) { - dialer.DefaultInterface.Store(general.Interface) - } - allowLan := general.AllowLan listener.SetAllowLan(allowLan) @@ -168,15 +178,6 @@ func updateExperimental(c *config.Config) { runtime.GC() } -func preUpdateExperimental(c *config.Config) { - CTLS.ResetCertificate() - for _, c := range c.TLS.CustomTrustCert { - if err := CTLS.AddCertificate(c); err != nil { - log.Warnln("%s\nadd error: %s", c, err.Error()) - } - } -} - func updateDNS(c *config.DNS, generalIPv6 bool) { if !c.Enable { resolver.DefaultResolver = nil @@ -342,17 +343,8 @@ func updateGeneral(general *config.General) { inbound.SetTfo(general.InboundTfo) adapter.UnifiedDelay.Store(general.UnifiedDelay) - // Avoid reload configuration clean the value, causing traffic loops - if listener.GetTunConf().Enable && listener.GetTunConf().AutoDetectInterface { - // changed only when the name is specified - // if name is empty, setting delay until after tun loaded - if general.Interface != "" && (!general.Tun.Enable || !general.Tun.AutoDetectInterface) { - dialer.DefaultInterface.Store(general.Interface) - } - } else { - dialer.DefaultInterface.Store(general.Interface) - } + dialer.DefaultInterface.Store(general.Interface) dialer.DefaultRoutingMark.Store(int32(general.RoutingMark)) if general.RoutingMark > 0 { log.Infoln("Use routing mark: %#x", general.RoutingMark) diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index b686eae6..aad1dda7 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -26,6 +26,7 @@ import ( ) var ( + status C.TunnelStatus tcpQueue = make(chan C.ConnContext, 200) udpQueue = make(chan C.PacketAdapter, 200) natTable = nat.New() @@ -49,6 +50,18 @@ var ( fakeIPRange netip.Prefix ) +func OnSuspend() { + status = C.TunnelSuspend +} + +func OnInnerLoading() { + status = C.TunnelInner +} + +func OnRunning() { + status = C.TunnelRunning +} + func SetFakeIPRange(p netip.Prefix) { fakeIPRange = p } @@ -158,10 +171,18 @@ func SetFindProcessMode(mode P.FindProcessMode) { findProcessMode = mode } +func isHandle(t C.Type) bool { + return status == C.TunnelRunning || (status == C.TunnelInner && t == C.INNER) +} + // processUDP starts a loop to handle udp packet func processUDP() { queue := udpQueue for conn := range queue { + if !isHandle(conn.Metadata().Type) { + conn.Drop() + continue + } handleUDPConn(conn) } } @@ -177,6 +198,10 @@ func process() { queue := tcpQueue for conn := range queue { + if !isHandle(conn.Metadata().Type) { + _ = conn.Conn().Close() + continue + } go handleTCPConn(conn) } }