2018-11-21 13:47:46 +08:00
|
|
|
package executor
|
|
|
|
|
|
|
|
import (
|
2019-12-01 13:22:47 +08:00
|
|
|
"fmt"
|
2023-09-01 03:11:35 +08:00
|
|
|
"net"
|
2022-04-12 20:20:04 +08:00
|
|
|
"net/netip"
|
2019-12-01 13:22:47 +08:00
|
|
|
"os"
|
2021-12-04 17:41:13 +08:00
|
|
|
"runtime"
|
2023-09-01 03:11:35 +08:00
|
|
|
"strconv"
|
2023-04-01 11:53:39 +08:00
|
|
|
"strings"
|
2020-06-18 18:11:02 +08:00
|
|
|
"sync"
|
2023-09-01 03:11:35 +08:00
|
|
|
"time"
|
2019-12-01 13:22:47 +08:00
|
|
|
|
2023-09-23 17:59:59 +08:00
|
|
|
"github.com/Dreamacro/clash/ntp"
|
|
|
|
|
2021-06-10 14:05:56 +08:00
|
|
|
"github.com/Dreamacro/clash/adapter"
|
2022-12-04 14:37:52 +08:00
|
|
|
"github.com/Dreamacro/clash/adapter/inbound"
|
2021-06-10 14:05:56 +08:00
|
|
|
"github.com/Dreamacro/clash/adapter/outboundgroup"
|
2019-06-27 17:04:25 +08:00
|
|
|
"github.com/Dreamacro/clash/component/auth"
|
2023-09-22 14:45:34 +08:00
|
|
|
"github.com/Dreamacro/clash/component/ca"
|
2020-02-15 21:42:46 +08:00
|
|
|
"github.com/Dreamacro/clash/component/dialer"
|
2022-02-05 00:51:06 +08:00
|
|
|
G "github.com/Dreamacro/clash/component/geodata"
|
2021-09-06 23:07:34 +08:00
|
|
|
"github.com/Dreamacro/clash/component/iface"
|
2021-02-18 23:41:50 +08:00
|
|
|
"github.com/Dreamacro/clash/component/profile"
|
|
|
|
"github.com/Dreamacro/clash/component/profile/cachefile"
|
2020-02-15 21:42:46 +08:00
|
|
|
"github.com/Dreamacro/clash/component/resolver"
|
2022-04-09 22:30:36 +08:00
|
|
|
SNI "github.com/Dreamacro/clash/component/sniffer"
|
2020-05-28 12:13:05 +08:00
|
|
|
"github.com/Dreamacro/clash/component/trie"
|
2018-11-21 13:47:46 +08:00
|
|
|
"github.com/Dreamacro/clash/config"
|
|
|
|
C "github.com/Dreamacro/clash/constant"
|
2021-07-04 20:32:59 +08:00
|
|
|
"github.com/Dreamacro/clash/constant/provider"
|
2018-12-05 21:13:29 +08:00
|
|
|
"github.com/Dreamacro/clash/dns"
|
2022-11-18 22:57:33 +08:00
|
|
|
"github.com/Dreamacro/clash/listener"
|
2021-06-13 17:23:10 +08:00
|
|
|
authStore "github.com/Dreamacro/clash/listener/auth"
|
2022-12-04 14:37:52 +08:00
|
|
|
LC "github.com/Dreamacro/clash/listener/config"
|
2022-11-16 10:43:16 +08:00
|
|
|
"github.com/Dreamacro/clash/listener/inner"
|
2021-07-01 22:49:29 +08:00
|
|
|
"github.com/Dreamacro/clash/listener/tproxy"
|
2018-11-21 13:47:46 +08:00
|
|
|
"github.com/Dreamacro/clash/log"
|
2020-02-15 21:42:46 +08:00
|
|
|
"github.com/Dreamacro/clash/tunnel"
|
2018-11-21 13:47:46 +08:00
|
|
|
)
|
|
|
|
|
2021-10-10 23:44:09 +08:00
|
|
|
var mux sync.Mutex
|
2020-06-18 18:11:02 +08:00
|
|
|
|
2019-12-01 13:22:47 +08:00
|
|
|
func readConfig(path string) ([]byte, error) {
|
|
|
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-10-09 20:35:06 +08:00
|
|
|
data, err := os.ReadFile(path)
|
2019-12-01 13:22:47 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(data) == 0 {
|
2020-08-25 22:19:59 +08:00
|
|
|
return nil, fmt.Errorf("configuration file %s is empty", path)
|
2019-12-01 13:22:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return data, err
|
|
|
|
}
|
|
|
|
|
2018-11-21 13:47:46 +08:00
|
|
|
// Parse config with default config path
|
|
|
|
func Parse() (*config.Config, error) {
|
|
|
|
return ParseWithPath(C.Path.Config())
|
|
|
|
}
|
|
|
|
|
|
|
|
// ParseWithPath parse config with custom config path
|
|
|
|
func ParseWithPath(path string) (*config.Config, error) {
|
2019-12-01 13:22:47 +08:00
|
|
|
buf, err := readConfig(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-12-25 15:12:11 +08:00
|
|
|
return ParseWithBytes(buf)
|
2019-12-01 13:22:47 +08:00
|
|
|
}
|
|
|
|
|
2019-12-25 15:12:11 +08:00
|
|
|
// ParseWithBytes config with buffer
|
2019-12-01 13:22:47 +08:00
|
|
|
func ParseWithBytes(buf []byte) (*config.Config, error) {
|
2019-12-25 15:12:11 +08:00
|
|
|
return config.Parse(buf)
|
2018-11-21 13:47:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// ApplyConfig dispatch configure to all parts
|
2018-11-30 17:42:40 +08:00
|
|
|
func ApplyConfig(cfg *config.Config, force bool) {
|
2020-06-18 18:11:02 +08:00
|
|
|
mux.Lock()
|
|
|
|
defer mux.Unlock()
|
2023-03-14 22:37:07 +08:00
|
|
|
|
|
|
|
tunnel.OnSuspend()
|
|
|
|
|
2023-09-22 14:45:34 +08:00
|
|
|
ca.ResetCertificate()
|
2023-03-14 22:37:07 +08:00
|
|
|
for _, c := range cfg.TLS.CustomTrustCert {
|
2023-09-22 14:45:34 +08:00
|
|
|
if err := ca.AddCertificate(c); err != nil {
|
2023-03-14 22:37:07 +08:00
|
|
|
log.Warnln("%s\nadd error: %s", c, err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-27 17:04:25 +08:00
|
|
|
updateUsers(cfg.Users)
|
2022-01-18 21:09:36 +08:00
|
|
|
updateProxies(cfg.Proxies, cfg.Providers)
|
2022-12-04 13:37:14 +08:00
|
|
|
updateRules(cfg.Rules, cfg.SubRules, cfg.RuleProviders)
|
2022-04-16 08:29:38 +08:00
|
|
|
updateSniffer(cfg.Sniffer)
|
2022-05-05 21:14:46 +08:00
|
|
|
updateHosts(cfg.Hosts)
|
2023-02-22 22:32:04 +08:00
|
|
|
updateGeneral(cfg.General)
|
2023-09-01 03:11:35 +08:00
|
|
|
updateNTP(cfg.NTP)
|
2023-04-01 11:53:39 +08:00
|
|
|
updateDNS(cfg.DNS, cfg.RuleProviders, cfg.General.IPv6)
|
2023-02-22 22:32:04 +08:00
|
|
|
updateListeners(cfg.General, cfg.Listeners, force)
|
2022-03-22 05:38:42 +08:00
|
|
|
updateIPTables(cfg)
|
2022-11-04 08:52:30 +08:00
|
|
|
updateTun(cfg.General)
|
2021-07-10 17:01:40 +08:00
|
|
|
updateExperimental(cfg)
|
2022-11-18 22:57:33 +08:00
|
|
|
updateTunnels(cfg.Tunnels)
|
2022-01-21 22:38:02 +08:00
|
|
|
|
2023-03-14 22:37:07 +08:00
|
|
|
tunnel.OnInnerLoading()
|
|
|
|
|
|
|
|
initInnerTcp()
|
|
|
|
loadProxyProvider(cfg.Providers)
|
|
|
|
updateProfile(cfg)
|
|
|
|
loadRuleProvider(cfg.RuleProviders)
|
2023-04-01 11:53:39 +08:00
|
|
|
runtime.GC()
|
2023-03-14 22:37:07 +08:00
|
|
|
tunnel.OnRunning()
|
|
|
|
|
2022-03-05 18:04:04 +08:00
|
|
|
log.SetLevel(cfg.General.LogLevel)
|
2018-11-21 13:47:46 +08:00
|
|
|
}
|
|
|
|
|
2022-05-08 07:58:26 +08:00
|
|
|
func initInnerTcp() {
|
2023-09-28 18:59:31 +08:00
|
|
|
inner.New(tunnel.Tunnel)
|
2022-05-08 00:04:16 +08:00
|
|
|
}
|
|
|
|
|
2018-11-21 13:47:46 +08:00
|
|
|
func GetGeneral() *config.General {
|
2022-11-18 22:57:33 +08:00
|
|
|
ports := listener.GetPorts()
|
2022-03-20 02:39:48 +08:00
|
|
|
var authenticator []string
|
2019-06-27 20:45:12 +08:00
|
|
|
if auth := authStore.Authenticator(); auth != nil {
|
|
|
|
authenticator = auth.Users()
|
|
|
|
}
|
|
|
|
|
|
|
|
general := &config.General{
|
2020-06-18 18:11:02 +08:00
|
|
|
Inbound: config.Inbound{
|
2022-11-11 20:56:08 +08:00
|
|
|
Port: ports.Port,
|
|
|
|
SocksPort: ports.SocksPort,
|
|
|
|
RedirPort: ports.RedirPort,
|
|
|
|
TProxyPort: ports.TProxyPort,
|
|
|
|
MixedPort: ports.MixedPort,
|
2023-09-02 01:14:26 +08:00
|
|
|
Tun: listener.GetTunConf(),
|
2022-12-06 10:13:05 +08:00
|
|
|
TuicServer: listener.GetTuicConf(),
|
2022-11-11 20:56:08 +08:00
|
|
|
ShadowSocksConfig: ports.ShadowSocksConfig,
|
|
|
|
VmessConfig: ports.VmessConfig,
|
|
|
|
Authentication: authenticator,
|
2023-10-10 19:43:26 +08:00
|
|
|
SkipAuthPrefixes: inbound.SkipAuthPrefixes(),
|
2022-11-28 20:04:56 +08:00
|
|
|
AllowLan: listener.AllowLan(),
|
|
|
|
BindAddress: listener.BindAddress(),
|
2020-06-18 18:11:02 +08:00
|
|
|
},
|
2023-09-23 17:59:59 +08:00
|
|
|
Controller: config.Controller{},
|
2022-02-05 00:51:06 +08:00
|
|
|
Mode: tunnel.Mode(),
|
|
|
|
LogLevel: log.Level(),
|
|
|
|
IPv6: !resolver.DisableIPv6,
|
|
|
|
GeodataLoader: G.LoaderName(),
|
2022-05-24 12:43:26 +08:00
|
|
|
Interface: dialer.DefaultInterface.Load(),
|
|
|
|
Sniffing: tunnel.IsSniffing(),
|
2023-03-06 23:23:05 +08:00
|
|
|
TCPConcurrent: dialer.GetTcpConcurrent(),
|
2018-11-21 13:47:46 +08:00
|
|
|
}
|
2019-06-27 20:45:12 +08:00
|
|
|
|
|
|
|
return general
|
2018-11-21 13:47:46 +08:00
|
|
|
}
|
|
|
|
|
2023-02-22 22:32:04 +08:00
|
|
|
func updateListeners(general *config.General, listeners map[string]C.InboundListener, force bool) {
|
2023-09-28 18:59:31 +08:00
|
|
|
listener.PatchInboundListeners(listeners, tunnel.Tunnel, true)
|
2023-02-22 22:32:04 +08:00
|
|
|
if !force {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
allowLan := general.AllowLan
|
|
|
|
listener.SetAllowLan(allowLan)
|
2023-10-10 19:43:26 +08:00
|
|
|
inbound.SetSkipAuthPrefixes(general.SkipAuthPrefixes)
|
2023-02-22 22:32:04 +08:00
|
|
|
|
|
|
|
bindAddress := general.BindAddress
|
|
|
|
listener.SetBindAddress(bindAddress)
|
2023-09-28 18:59:31 +08:00
|
|
|
listener.ReCreateHTTP(general.Port, tunnel.Tunnel)
|
|
|
|
listener.ReCreateSocks(general.SocksPort, tunnel.Tunnel)
|
|
|
|
listener.ReCreateRedir(general.RedirPort, tunnel.Tunnel)
|
2023-10-23 16:50:43 +08:00
|
|
|
// listener.ReCreateAutoRedir(general.EBpf.AutoRedir, tunnel.Tunnel)
|
2023-09-28 18:59:31 +08:00
|
|
|
listener.ReCreateTProxy(general.TProxyPort, tunnel.Tunnel)
|
|
|
|
listener.ReCreateMixed(general.MixedPort, tunnel.Tunnel)
|
|
|
|
listener.ReCreateShadowSocks(general.ShadowSocksConfig, tunnel.Tunnel)
|
|
|
|
listener.ReCreateVmess(general.VmessConfig, tunnel.Tunnel)
|
|
|
|
listener.ReCreateTuic(general.TuicServer, tunnel.Tunnel)
|
2022-12-04 13:37:14 +08:00
|
|
|
}
|
|
|
|
|
2022-06-14 22:50:57 +08:00
|
|
|
func updateExperimental(c *config.Config) {
|
2023-09-08 22:58:59 +08:00
|
|
|
if c.Experimental.QUICGoDisableGSO {
|
2023-10-01 09:10:11 +08:00
|
|
|
_ = os.Setenv("QUIC_GO_DISABLE_GSO", strconv.FormatBool(true))
|
|
|
|
}
|
|
|
|
if c.Experimental.QUICGoDisableECN {
|
|
|
|
_ = os.Setenv("QUIC_GO_DISABLE_ECN", strconv.FormatBool(true))
|
2023-09-08 22:58:59 +08:00
|
|
|
}
|
2022-06-14 22:50:57 +08:00
|
|
|
}
|
2019-04-24 12:02:52 +08:00
|
|
|
|
2023-09-01 03:11:35 +08:00
|
|
|
func updateNTP(c *config.NTP) {
|
|
|
|
if c.Enable {
|
2023-09-25 09:11:20 +08:00
|
|
|
ntp.ReCreateNTPService(
|
|
|
|
net.JoinHostPort(c.Server, strconv.Itoa(c.Port)),
|
|
|
|
time.Duration(c.Interval),
|
|
|
|
c.DialerProxy,
|
|
|
|
c.WriteToSystem,
|
|
|
|
)
|
2023-09-01 03:11:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-01 11:53:39 +08:00
|
|
|
func updateDNS(c *config.DNS, ruleProvider map[string]provider.RuleProvider, generalIPv6 bool) {
|
2022-05-01 09:38:43 +08:00
|
|
|
if !c.Enable {
|
|
|
|
resolver.DefaultResolver = nil
|
|
|
|
resolver.DefaultHostMapper = nil
|
2022-05-02 14:21:37 +08:00
|
|
|
resolver.DefaultLocalServer = nil
|
2022-05-01 09:38:43 +08:00
|
|
|
dns.ReCreateServer("", nil, nil)
|
|
|
|
return
|
|
|
|
}
|
2023-04-01 11:53:39 +08:00
|
|
|
policy := make(map[string][]dns.NameServer)
|
|
|
|
domainSetPolicies := make(map[provider.RuleProvider][]dns.NameServer)
|
|
|
|
for key, nameservers := range c.NameServerPolicy {
|
|
|
|
temp := strings.Split(key, ":")
|
|
|
|
if len(temp) == 2 {
|
|
|
|
prefix := temp[0]
|
|
|
|
key := temp[1]
|
|
|
|
switch strings.ToLower(prefix) {
|
|
|
|
case "rule-set":
|
|
|
|
if p, ok := ruleProvider[key]; ok {
|
|
|
|
domainSetPolicies[p] = nameservers
|
|
|
|
}
|
|
|
|
case "geosite":
|
|
|
|
// TODO:
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
policy[key] = nameservers
|
|
|
|
}
|
|
|
|
}
|
2020-09-17 10:48:42 +08:00
|
|
|
cfg := dns.Config{
|
2018-12-05 21:13:29 +08:00
|
|
|
Main: c.NameServer,
|
|
|
|
Fallback: c.Fallback,
|
2023-01-21 22:31:07 +08:00
|
|
|
IPv6: c.IPv6 && generalIPv6,
|
2023-03-10 23:38:16 +08:00
|
|
|
IPv6Timeout: c.IPv6Timeout,
|
2018-12-05 21:13:29 +08:00
|
|
|
EnhancedMode: c.EnhancedMode,
|
2019-05-03 00:05:14 +08:00
|
|
|
Pool: c.FakeIPRange,
|
2020-08-11 10:28:17 +08:00
|
|
|
Hosts: c.Hosts,
|
2019-09-15 13:36:45 +08:00
|
|
|
FallbackFilter: dns.FallbackFilter{
|
2021-08-25 15:15:13 +08:00
|
|
|
GeoIP: c.FallbackFilter.GeoIP,
|
|
|
|
GeoIPCode: c.FallbackFilter.GeoIPCode,
|
|
|
|
IPCIDR: c.FallbackFilter.IPCIDR,
|
|
|
|
Domain: c.FallbackFilter.Domain,
|
2021-11-17 16:03:47 +08:00
|
|
|
GeoSite: c.FallbackFilter.GeoSite,
|
2019-09-15 13:36:45 +08:00
|
|
|
},
|
2023-04-01 11:53:39 +08:00
|
|
|
Default: c.DefaultNameserver,
|
|
|
|
Policy: c.NameServerPolicy,
|
|
|
|
ProxyServer: c.ProxyServerNameserver,
|
|
|
|
DomainSetPolicy: domainSetPolicies,
|
2020-09-17 10:48:42 +08:00
|
|
|
}
|
2020-08-31 00:32:18 +08:00
|
|
|
|
2020-09-17 10:48:42 +08:00
|
|
|
r := dns.NewResolver(cfg)
|
2022-03-28 00:44:13 +08:00
|
|
|
pr := dns.NewProxyServerHostResolver(r)
|
2020-09-17 10:48:42 +08:00
|
|
|
m := dns.NewEnhancer(cfg)
|
|
|
|
|
|
|
|
// reuse cache of old host mapper
|
|
|
|
if old := resolver.DefaultHostMapper; old != nil {
|
|
|
|
m.PatchFrom(old.(*dns.ResolverEnhancer))
|
2020-08-31 00:32:18 +08:00
|
|
|
}
|
|
|
|
|
2020-02-15 21:42:46 +08:00
|
|
|
resolver.DefaultResolver = r
|
2020-09-17 10:48:42 +08:00
|
|
|
resolver.DefaultHostMapper = m
|
2022-05-02 14:21:37 +08:00
|
|
|
resolver.DefaultLocalServer = dns.NewLocalServer(r, m)
|
2020-09-17 10:48:42 +08:00
|
|
|
|
2023-04-11 14:10:57 +08:00
|
|
|
if pr.Invalid() {
|
2022-03-28 00:44:13 +08:00
|
|
|
resolver.ProxyServerHostResolver = pr
|
|
|
|
}
|
|
|
|
|
2022-05-01 09:38:43 +08:00
|
|
|
dns.ReCreateServer(c.Listen, r, m)
|
2018-12-05 21:13:29 +08:00
|
|
|
}
|
|
|
|
|
2023-03-12 15:00:59 +08:00
|
|
|
func updateHosts(tree *trie.DomainTrie[resolver.HostValue]) {
|
|
|
|
resolver.DefaultHosts = resolver.NewHosts(tree)
|
2019-09-11 17:00:55 +08:00
|
|
|
}
|
|
|
|
|
2019-12-08 12:17:24 +08:00
|
|
|
func updateProxies(proxies map[string]C.Proxy, providers map[string]provider.ProxyProvider) {
|
|
|
|
tunnel.UpdateProxies(proxies, providers)
|
2018-11-21 13:47:46 +08:00
|
|
|
}
|
|
|
|
|
2022-12-04 13:37:14 +08:00
|
|
|
func updateRules(rules []C.Rule, subRules map[string][]C.Rule, ruleProviders map[string]provider.RuleProvider) {
|
|
|
|
tunnel.UpdateRules(rules, subRules, ruleProviders)
|
2018-11-21 13:47:46 +08:00
|
|
|
}
|
|
|
|
|
2022-04-28 08:55:45 +08:00
|
|
|
func loadProvider(pv provider.Provider) {
|
|
|
|
if pv.VehicleType() == provider.Compatible {
|
|
|
|
log.Infoln("Start initial compatible provider %s", pv.Name())
|
|
|
|
} else {
|
|
|
|
log.Infoln("Start initial provider %s", (pv).Name())
|
|
|
|
}
|
2022-01-18 21:09:36 +08:00
|
|
|
|
2022-05-08 00:04:16 +08:00
|
|
|
if err := pv.Initial(); err != nil {
|
2022-04-28 08:55:45 +08:00
|
|
|
switch pv.Type() {
|
|
|
|
case provider.Proxy:
|
|
|
|
{
|
2023-01-23 11:14:45 +08:00
|
|
|
log.Errorln("initial proxy provider %s error: %v", (pv).Name(), err)
|
2022-04-28 08:55:45 +08:00
|
|
|
}
|
|
|
|
case provider.Rule:
|
|
|
|
{
|
2023-01-23 11:14:45 +08:00
|
|
|
log.Errorln("initial rule provider %s error: %v", (pv).Name(), err)
|
2022-01-18 21:09:36 +08:00
|
|
|
}
|
2022-04-28 08:55:45 +08:00
|
|
|
|
2022-01-18 21:09:36 +08:00
|
|
|
}
|
|
|
|
}
|
2022-04-28 08:55:45 +08:00
|
|
|
}
|
2022-01-18 21:09:36 +08:00
|
|
|
|
2022-04-28 08:55:45 +08:00
|
|
|
func loadRuleProvider(ruleProviders map[string]provider.RuleProvider) {
|
2022-05-02 16:47:48 +08:00
|
|
|
wg := sync.WaitGroup{}
|
2022-05-08 22:52:46 +08:00
|
|
|
ch := make(chan struct{}, concurrentCount)
|
2022-04-28 08:55:45 +08:00
|
|
|
for _, ruleProvider := range ruleProviders {
|
2022-05-02 16:47:48 +08:00
|
|
|
ruleProvider := ruleProvider
|
|
|
|
wg.Add(1)
|
2022-05-08 22:52:46 +08:00
|
|
|
ch <- struct{}{}
|
2022-05-02 16:47:48 +08:00
|
|
|
go func() {
|
2022-05-08 22:52:46 +08:00
|
|
|
defer func() { <-ch; wg.Done() }()
|
2022-05-02 16:47:48 +08:00
|
|
|
loadProvider(ruleProvider)
|
2022-05-08 22:52:46 +08:00
|
|
|
|
2022-05-02 16:47:48 +08:00
|
|
|
}()
|
2022-01-18 21:09:36 +08:00
|
|
|
}
|
2022-05-02 16:47:48 +08:00
|
|
|
|
|
|
|
wg.Wait()
|
2022-04-28 08:55:45 +08:00
|
|
|
}
|
2022-01-18 21:09:36 +08:00
|
|
|
|
2022-05-02 16:47:48 +08:00
|
|
|
func loadProxyProvider(proxyProviders map[string]provider.ProxyProvider) {
|
2022-05-08 22:52:46 +08:00
|
|
|
// limit concurrent size
|
2022-05-02 16:47:48 +08:00
|
|
|
wg := sync.WaitGroup{}
|
2022-05-08 22:52:46 +08:00
|
|
|
ch := make(chan struct{}, concurrentCount)
|
2022-05-02 16:47:48 +08:00
|
|
|
for _, proxyProvider := range proxyProviders {
|
|
|
|
proxyProvider := proxyProvider
|
|
|
|
wg.Add(1)
|
2022-05-08 22:52:46 +08:00
|
|
|
ch <- struct{}{}
|
2022-05-02 16:47:48 +08:00
|
|
|
go func() {
|
2022-05-08 22:52:46 +08:00
|
|
|
defer func() { <-ch; wg.Done() }()
|
2022-05-02 16:47:48 +08:00
|
|
|
loadProvider(proxyProvider)
|
|
|
|
}()
|
2022-01-18 21:09:36 +08:00
|
|
|
}
|
2022-05-02 16:47:48 +08:00
|
|
|
|
|
|
|
wg.Wait()
|
2022-01-18 21:09:36 +08:00
|
|
|
}
|
|
|
|
|
2022-11-04 08:52:30 +08:00
|
|
|
func updateTun(general *config.General) {
|
|
|
|
if general == nil {
|
2022-11-03 18:56:03 +08:00
|
|
|
return
|
|
|
|
}
|
2023-09-28 18:59:31 +08:00
|
|
|
listener.ReCreateTun(general.Tun, tunnel.Tunnel)
|
2022-11-28 20:04:56 +08:00
|
|
|
listener.ReCreateRedirToTun(general.Tun.RedirectToTun)
|
2022-03-09 05:08:35 +08:00
|
|
|
}
|
|
|
|
|
2022-04-12 20:20:04 +08:00
|
|
|
func updateSniffer(sniffer *config.Sniffer) {
|
|
|
|
if sniffer.Enable {
|
2022-10-14 08:42:28 +08:00
|
|
|
dispatcher, err := SNI.NewSnifferDispatcher(
|
2023-01-23 13:16:25 +08:00
|
|
|
sniffer.Sniffers, sniffer.ForceDomain, sniffer.SkipDomain,
|
2022-10-14 08:42:28 +08:00
|
|
|
sniffer.ForceDnsMapping, sniffer.ParsePureIp,
|
|
|
|
)
|
2022-04-12 20:20:04 +08:00
|
|
|
if err != nil {
|
|
|
|
log.Warnln("initial sniffer failed, err:%v", err)
|
|
|
|
}
|
2022-04-16 08:21:31 +08:00
|
|
|
|
|
|
|
tunnel.UpdateSniffer(dispatcher)
|
2022-04-12 20:20:04 +08:00
|
|
|
log.Infoln("Sniffer is loaded and working")
|
2022-04-16 08:21:31 +08:00
|
|
|
} else {
|
|
|
|
dispatcher, err := SNI.NewCloseSnifferDispatcher()
|
|
|
|
if err != nil {
|
|
|
|
log.Warnln("initial sniffer failed, err:%v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tunnel.UpdateSniffer(dispatcher)
|
|
|
|
log.Infoln("Sniffer is closed")
|
2022-04-12 20:20:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-06 10:13:05 +08:00
|
|
|
func updateTunnels(tunnels []LC.Tunnel) {
|
2023-09-28 18:59:31 +08:00
|
|
|
listener.PatchTunnel(tunnels, tunnel.Tunnel)
|
2022-11-18 22:57:33 +08:00
|
|
|
}
|
|
|
|
|
2023-02-22 22:32:04 +08:00
|
|
|
func updateGeneral(general *config.General) {
|
2020-02-15 21:42:46 +08:00
|
|
|
tunnel.SetMode(general.Mode)
|
2023-01-20 16:29:08 +08:00
|
|
|
tunnel.SetFindProcessMode(general.FindProcessMode)
|
2023-03-06 23:23:05 +08:00
|
|
|
resolver.DisableIPv6 = !general.IPv6
|
2022-03-20 02:39:48 +08:00
|
|
|
|
2022-04-27 21:37:20 +08:00
|
|
|
if general.TCPConcurrent {
|
2023-03-06 23:23:05 +08:00
|
|
|
dialer.SetTcpConcurrent(general.TCPConcurrent)
|
2022-04-23 00:27:22 +08:00
|
|
|
log.Infoln("Use tcp concurrent")
|
|
|
|
}
|
2022-01-05 11:24:00 +08:00
|
|
|
|
2023-02-24 14:19:50 +08:00
|
|
|
inbound.SetTfo(general.InboundTfo)
|
2023-08-09 17:09:03 +08:00
|
|
|
inbound.SetMPTCP(general.InboundMPTCP)
|
2023-02-24 14:19:50 +08:00
|
|
|
|
2022-04-23 00:27:22 +08:00
|
|
|
adapter.UnifiedDelay.Store(general.UnifiedDelay)
|
2020-06-27 14:19:31 +08:00
|
|
|
|
2023-03-14 22:37:07 +08:00
|
|
|
dialer.DefaultInterface.Store(general.Interface)
|
2022-03-20 02:39:48 +08:00
|
|
|
dialer.DefaultRoutingMark.Store(int32(general.RoutingMark))
|
|
|
|
if general.RoutingMark > 0 {
|
|
|
|
log.Infoln("Use routing mark: %#x", general.RoutingMark)
|
2022-03-03 05:02:17 +08:00
|
|
|
}
|
2021-11-17 16:03:47 +08:00
|
|
|
|
2021-09-06 23:07:34 +08:00
|
|
|
iface.FlushCache()
|
2022-03-15 02:20:19 +08:00
|
|
|
geodataLoader := general.GeodataLoader
|
|
|
|
G.SetLoader(geodataLoader)
|
2018-11-21 13:47:46 +08:00
|
|
|
}
|
2019-06-27 17:04:25 +08:00
|
|
|
|
|
|
|
func updateUsers(users []auth.AuthUser) {
|
|
|
|
authenticator := auth.NewAuthenticator(users)
|
|
|
|
authStore.SetAuthenticator(authenticator)
|
|
|
|
if authenticator != nil {
|
|
|
|
log.Infoln("Authentication of local server updated")
|
|
|
|
}
|
|
|
|
}
|
2021-02-18 23:41:50 +08:00
|
|
|
|
|
|
|
func updateProfile(cfg *config.Config) {
|
|
|
|
profileCfg := cfg.Profile
|
|
|
|
|
|
|
|
profile.StoreSelected.Store(profileCfg.StoreSelected)
|
|
|
|
if profileCfg.StoreSelected {
|
|
|
|
patchSelectGroup(cfg.Proxies)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func patchSelectGroup(proxies map[string]C.Proxy) {
|
|
|
|
mapping := cachefile.Cache().SelectedMap()
|
|
|
|
if mapping == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, proxy := range proxies {
|
2021-06-10 14:05:56 +08:00
|
|
|
outbound, ok := proxy.(*adapter.Proxy)
|
2021-02-18 23:41:50 +08:00
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2022-05-23 00:40:27 +08:00
|
|
|
selector, ok := outbound.ProxyAdapter.(outboundgroup.SelectAble)
|
2021-02-18 23:41:50 +08:00
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
selected, exist := mapping[name]
|
|
|
|
if !exist {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2023-04-24 08:07:17 +08:00
|
|
|
selector.ForceSet(selected)
|
2021-02-18 23:41:50 +08:00
|
|
|
}
|
|
|
|
}
|
2021-11-17 16:03:47 +08:00
|
|
|
|
2022-03-22 05:38:42 +08:00
|
|
|
func updateIPTables(cfg *config.Config) {
|
|
|
|
tproxy.CleanupTProxyIPTables()
|
2022-03-09 05:08:35 +08:00
|
|
|
|
2022-03-22 05:38:42 +08:00
|
|
|
iptables := cfg.IPTables
|
|
|
|
if runtime.GOOS != "linux" || !iptables.Enable {
|
2022-03-09 05:08:35 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var err error
|
|
|
|
defer func() {
|
|
|
|
if err != nil {
|
2022-03-22 05:38:42 +08:00
|
|
|
log.Errorln("[IPTABLES] setting iptables failed: %s", err.Error())
|
2022-03-09 05:08:35 +08:00
|
|
|
os.Exit(2)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2022-11-04 08:52:30 +08:00
|
|
|
if cfg.General.Tun.Enable {
|
2022-03-23 20:37:46 +08:00
|
|
|
err = fmt.Errorf("when tun is enabled, iptables cannot be set automatically")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-03-22 05:38:42 +08:00
|
|
|
var (
|
|
|
|
inboundInterface = "lo"
|
2022-03-23 11:04:43 +08:00
|
|
|
bypass = iptables.Bypass
|
2022-03-22 05:38:42 +08:00
|
|
|
tProxyPort = cfg.General.TProxyPort
|
|
|
|
dnsCfg = cfg.DNS
|
|
|
|
)
|
|
|
|
|
|
|
|
if tProxyPort == 0 {
|
|
|
|
err = fmt.Errorf("tproxy-port must be greater than zero")
|
2022-03-09 05:08:35 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-03-22 05:38:42 +08:00
|
|
|
if !dnsCfg.Enable {
|
|
|
|
err = fmt.Errorf("DNS server must be enable")
|
2021-12-04 17:41:13 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-04-24 02:07:57 +08:00
|
|
|
dnsPort, err := netip.ParseAddrPort(dnsCfg.Listen)
|
2021-12-04 17:41:13 +08:00
|
|
|
if err != nil {
|
2022-03-23 00:46:37 +08:00
|
|
|
err = fmt.Errorf("DNS server must be correct")
|
2021-07-01 22:49:29 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-03-22 05:38:42 +08:00
|
|
|
if iptables.InboundInterface != "" {
|
|
|
|
inboundInterface = iptables.InboundInterface
|
2021-12-04 17:41:13 +08:00
|
|
|
}
|
|
|
|
|
2022-03-05 18:04:04 +08:00
|
|
|
if dialer.DefaultRoutingMark.Load() == 0 {
|
|
|
|
dialer.DefaultRoutingMark.Store(2158)
|
2021-12-04 17:41:13 +08:00
|
|
|
}
|
2022-03-05 18:04:04 +08:00
|
|
|
|
2022-04-24 02:07:57 +08:00
|
|
|
err = tproxy.SetTProxyIPTables(inboundInterface, bypass, uint16(tProxyPort), dnsPort.Port())
|
2022-03-22 05:38:42 +08:00
|
|
|
if err != nil {
|
|
|
|
return
|
2022-03-19 01:11:27 +08:00
|
|
|
}
|
2022-03-22 05:38:42 +08:00
|
|
|
|
|
|
|
log.Infoln("[IPTABLES] Setting iptables completed")
|
2021-12-04 17:41:13 +08:00
|
|
|
}
|
2021-11-17 16:03:47 +08:00
|
|
|
|
2022-03-28 03:25:55 +08:00
|
|
|
func Shutdown() {
|
2023-09-02 14:10:26 +08:00
|
|
|
listener.Cleanup()
|
2022-03-22 05:38:42 +08:00
|
|
|
tproxy.CleanupTProxyIPTables()
|
2022-04-13 16:47:47 +08:00
|
|
|
resolver.StoreFakePoolState()
|
2022-03-28 03:25:55 +08:00
|
|
|
|
|
|
|
log.Warnln("Clash shutting down")
|
2021-11-17 16:03:47 +08:00
|
|
|
}
|