chore: better config internal structure
Some checks are pending
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run

This commit is contained in:
wwqgtxx 2024-08-24 20:49:12 +08:00
parent 53425bb9f2
commit 27bcb26ecd
10 changed files with 393 additions and 257 deletions

View File

@ -17,10 +17,18 @@ func SetTfo(open bool) {
lc.DisableTFO = !open
}
func Tfo() bool {
return !lc.DisableTFO
}
func SetMPTCP(open bool) {
setMultiPathTCP(&lc.ListenConfig, open)
}
func MPTCP() bool {
return getMultiPathTCP(&lc.ListenConfig)
}
func ListenContext(ctx context.Context, network, address string) (net.Listener, error) {
return lc.Listen(ctx, network, address)
}

View File

@ -8,3 +8,7 @@ const multipathTCPAvailable = false
func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) {
}
func getMultiPathTCP(listenConfig *net.ListenConfig) bool {
return false
}

View File

@ -9,3 +9,7 @@ const multipathTCPAvailable = true
func setMultiPathTCP(listenConfig *net.ListenConfig, open bool) {
listenConfig.SetMultipathTCP(open)
}
func getMultiPathTCP(listenConfig *net.ListenConfig) bool {
return listenConfig.MultipathTCP()
}

View File

@ -50,13 +50,12 @@ import (
// General config
type General struct {
Inbound
Controller
Mode T.TunnelMode `json:"mode"`
UnifiedDelay bool
Mode T.TunnelMode `json:"mode"`
UnifiedDelay bool `json:"unified-delay"`
LogLevel log.LogLevel `json:"log-level"`
IPv6 bool `json:"ipv6"`
Interface string `json:"interface-name"`
RoutingMark int `json:"-"`
RoutingMark int `json:"routing-mark"`
GeoXUrl GeoXUrl `json:"geox-url"`
GeoAutoUpdate bool `json:"geo-auto-update"`
GeoUpdateInterval int `json:"geo-update-interval"`
@ -91,24 +90,48 @@ type Inbound struct {
InboundMPTCP bool `json:"inbound-mptcp"`
}
// GeoXUrl config
type GeoXUrl struct {
GeoIp string `json:"geo-ip"`
Mmdb string `json:"mmdb"`
ASN string `json:"asn"`
GeoSite string `json:"geo-site"`
}
// Controller config
type Controller struct {
ExternalController string `json:"-"`
ExternalControllerTLS string `json:"-"`
ExternalControllerUnix string `json:"-"`
ExternalUI string `json:"-"`
ExternalDohServer string `json:"-"`
Secret string `json:"-"`
ExternalController string
ExternalControllerTLS string
ExternalControllerUnix string
ExternalUI string
ExternalDohServer string
Secret string
}
// Experimental config
type Experimental struct {
Fingerprints []string
QUICGoDisableGSO bool
QUICGoDisableECN bool
IP4PEnable bool
}
// IPTables config
type IPTables struct {
Enable bool
InboundInterface string
Bypass []string
DnsRedirect bool
}
// NTP config
type NTP struct {
Enable bool `yaml:"enable"`
Server string `yaml:"server"`
Port int `yaml:"port"`
Interval int `yaml:"interval"`
DialerProxy string `yaml:"dialer-proxy"`
WriteToSystem bool `yaml:"write-to-system"`
Enable bool
Server string
Port int
Interval int
DialerProxy string
WriteToSystem bool
}
// DNS config
@ -134,24 +157,11 @@ type DNS struct {
// Profile config
type Profile struct {
StoreSelected bool `yaml:"store-selected"`
StoreFakeIP bool `yaml:"store-fake-ip"`
}
type TLS struct {
Certificate string `yaml:"certificate"`
PrivateKey string `yaml:"private-key"`
CustomTrustCert []string `yaml:"custom-certifactes"`
}
// IPTables config
type IPTables struct {
Enable bool `yaml:"enable" json:"enable"`
InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"`
Bypass []string `yaml:"bypass" json:"bypass"`
DnsRedirect bool `yaml:"dns-redirect" json:"dns-redirect"`
StoreSelected bool
StoreFakeIP bool
}
// Sniffer config
type Sniffer struct {
Enable bool
Sniffers map[snifferTypes.Type]SNIFF.SnifferConfig
@ -161,21 +171,21 @@ type Sniffer struct {
ParsePureIp bool
}
// Experimental config
type Experimental struct {
Fingerprints []string `yaml:"fingerprints"`
QUICGoDisableGSO bool `yaml:"quic-go-disable-gso"`
QUICGoDisableECN bool `yaml:"quic-go-disable-ecn"`
IP4PEnable bool `yaml:"dialer-ip4p-convert"`
// TLS config
type TLS struct {
Certificate string
PrivateKey string
CustomTrustCert []string
}
// Config is mihomo config manager
type Config struct {
General *General
Controller *Controller
Experimental *Experimental
IPTables *IPTables
NTP *NTP
DNS *DNS
Experimental *Experimental
Hosts *trie.DomainTrie[resolver.HostValue]
Profile *Profile
Rules []C.Rule
@ -190,15 +200,6 @@ type Config struct {
TLS *TLS
}
type RawNTP struct {
Enable bool `yaml:"enable"`
Server string `yaml:"server"`
ServerPort int `yaml:"server-port"`
Interval int `yaml:"interval"`
DialerProxy string `yaml:"dialer-proxy"`
WriteToSystem bool `yaml:"write-to-system"`
}
type RawDNS struct {
Enable bool `yaml:"enable" json:"enable"`
PreferH3 bool `yaml:"prefer-h3" json:"prefer-h3"`
@ -233,6 +234,15 @@ type RawClashForAndroid struct {
UiSubtitlePattern string `yaml:"ui-subtitle-pattern" json:"ui-subtitle-pattern"`
}
type RawNTP struct {
Enable bool `yaml:"enable" json:"enable"`
Server string `yaml:"server" json:"server"`
Port int `yaml:"port" json:"port"`
Interval int `yaml:"interval" json:"interval"`
DialerProxy string `yaml:"dialer-proxy" json:"dialer-proxy"`
WriteToSystem bool `yaml:"write-to-system" json:"write-to-system"`
}
type RawTun struct {
Enable bool `yaml:"enable" json:"enable"`
Device string `yaml:"device" json:"device"`
@ -244,35 +254,35 @@ type RawTun struct {
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
GSO bool `yaml:"gso" json:"gso,omitempty"`
GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
//Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4_address,omitempty"`
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6_address,omitempty"`
IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
AutoRedirect bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict_route,omitempty"`
RouteAddress []netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
RouteAddressSet []string `yaml:"route-address-set" json:"route_address_set,omitempty"`
RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
//Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"`
IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"`
AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"`
AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"`
RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"`
RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"`
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include_uid,omitempty"`
IncludeUIDRange []string `yaml:"include-uid-range" json:"include_uid_range,omitempty"`
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude_uid,omitempty"`
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude_uid_range,omitempty"`
IncludeAndroidUser []int `yaml:"include-android-user" json:"include_android_user,omitempty"`
IncludePackage []string `yaml:"include-package" json:"include_package,omitempty"`
ExcludePackage []string `yaml:"exclude-package" json:"exclude_package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint_independent_nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp_timeout,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"`
IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"`
ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4_route_address,omitempty"`
Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6_route_address,omitempty"`
Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4_route_exclude_address,omitempty"`
Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6_route_exclude_address,omitempty"`
Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"`
Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4-route-exclude-address,omitempty"`
Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6-route-exclude-address,omitempty"`
}
type RawTuicServer struct {
@ -290,6 +300,55 @@ type RawTuicServer struct {
CWND int `yaml:"cwnd" json:"cwnd,omitempty"`
}
type RawIPTables struct {
Enable bool `yaml:"enable" json:"enable"`
InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"`
Bypass []string `yaml:"bypass" json:"bypass"`
DnsRedirect bool `yaml:"dns-redirect" json:"dns-redirect"`
}
type RawExperimental struct {
Fingerprints []string `yaml:"fingerprints"`
QUICGoDisableGSO bool `yaml:"quic-go-disable-gso"`
QUICGoDisableECN bool `yaml:"quic-go-disable-ecn"`
IP4PEnable bool `yaml:"dialer-ip4p-convert"`
}
type RawProfile struct {
StoreSelected bool `yaml:"store-selected" json:"store-selected"`
StoreFakeIP bool `yaml:"store-fake-ip" json:"store-fake-ip"`
}
type RawGeoXUrl struct {
GeoIp string `yaml:"geoip" json:"geoip"`
Mmdb string `yaml:"mmdb" json:"mmdb"`
ASN string `yaml:"asn" json:"asn"`
GeoSite string `yaml:"geosite" json:"geosite"`
}
type RawSniffer struct {
Enable bool `yaml:"enable" json:"enable"`
OverrideDest bool `yaml:"override-destination" json:"override-destination"`
Sniffing []string `yaml:"sniffing" json:"sniffing"`
ForceDomain []string `yaml:"force-domain" json:"force-domain"`
SkipDomain []string `yaml:"skip-domain" json:"skip-domain"`
Ports []string `yaml:"port-whitelist" json:"port-whitelist"`
ForceDnsMapping bool `yaml:"force-dns-mapping" json:"force-dns-mapping"`
ParsePureIp bool `yaml:"parse-pure-ip" json:"parse-pure-ip"`
Sniff map[string]RawSniffingConfig `yaml:"sniff" json:"sniff"`
}
type RawSniffingConfig struct {
Ports []string `yaml:"ports" json:"ports"`
OverrideDest *bool `yaml:"override-destination" json:"override-destination"`
}
type RawTLS struct {
Certificate string `yaml:"certificate" json:"certificate"`
PrivateKey string `yaml:"private-key" json:"private-key"`
CustomTrustCert []string `yaml:"custom-certifactes" json:"custom-certifactes"`
}
type RawConfig struct {
Port int `yaml:"port" json:"port"`
SocksPort int `yaml:"socks-port" json:"socks-port"`
@ -301,9 +360,9 @@ type RawConfig struct {
InboundTfo bool `yaml:"inbound-tfo" json:"inbound-tfo"`
InboundMPTCP bool `yaml:"inbound-mptcp" json:"inbound-mptcp"`
Authentication []string `yaml:"authentication" json:"authentication"`
SkipAuthPrefixes []netip.Prefix `yaml:"skip-auth-prefixes"`
LanAllowedIPs []netip.Prefix `yaml:"lan-allowed-ips"`
LanDisAllowedIPs []netip.Prefix `yaml:"lan-disallowed-ips"`
SkipAuthPrefixes []netip.Prefix `yaml:"skip-auth-prefixes" json:"skip-auth-prefixes"`
LanAllowedIPs []netip.Prefix `yaml:"lan-allowed-ips" json:"lan-allowed-ips"`
LanDisAllowedIPs []netip.Prefix `yaml:"lan-disallowed-ips" json:"lan-disallowed-ips"`
AllowLan bool `yaml:"allow-lan" json:"allow-lan"`
BindAddress string `yaml:"bind-address" json:"bind-address"`
Mode T.TunnelMode `yaml:"mode" json:"mode"`
@ -334,52 +393,28 @@ type RawConfig struct {
KeepAliveInterval int `yaml:"keep-alive-interval" json:"keep-alive-interval"`
DisableKeepAlive bool `yaml:"disable-keep-alive" json:"disable-keep-alive"`
Sniffer RawSniffer `yaml:"sniffer" json:"sniffer"`
ProxyProvider map[string]map[string]any `yaml:"proxy-providers"`
RuleProvider map[string]map[string]any `yaml:"rule-providers"`
ProxyProvider map[string]map[string]any `yaml:"proxy-providers" json:"proxy-providers"`
RuleProvider map[string]map[string]any `yaml:"rule-providers" json:"rule-providers"`
Proxy []map[string]any `yaml:"proxies" json:"proxies"`
ProxyGroup []map[string]any `yaml:"proxy-groups" json:"proxy-groups"`
Rule []string `yaml:"rules" json:"rule"`
SubRules map[string][]string `yaml:"sub-rules" json:"sub-rules"`
Listeners []map[string]any `yaml:"listeners" json:"listeners"`
Hosts map[string]any `yaml:"hosts" json:"hosts"`
NTP RawNTP `yaml:"ntp" json:"ntp"`
DNS RawDNS `yaml:"dns" json:"dns"`
Tun RawTun `yaml:"tun"`
TuicServer RawTuicServer `yaml:"tuic-server"`
IPTables IPTables `yaml:"iptables"`
Experimental Experimental `yaml:"experimental"`
Profile Profile `yaml:"profile"`
GeoXUrl GeoXUrl `yaml:"geox-url"`
Proxy []map[string]any `yaml:"proxies"`
ProxyGroup []map[string]any `yaml:"proxy-groups"`
Rule []string `yaml:"rules"`
SubRules map[string][]string `yaml:"sub-rules"`
RawTLS TLS `yaml:"tls"`
Listeners []map[string]any `yaml:"listeners"`
NTP RawNTP `yaml:"ntp" json:"ntp"`
Tun RawTun `yaml:"tun" json:"tun"`
TuicServer RawTuicServer `yaml:"tuic-server" json:"tuic-server"`
IPTables RawIPTables `yaml:"iptables" json:"iptables"`
Experimental RawExperimental `yaml:"experimental" json:"experimental"`
Profile RawProfile `yaml:"profile" json:"profile"`
GeoXUrl RawGeoXUrl `yaml:"geox-url" json:"geox-url"`
Sniffer RawSniffer `yaml:"sniffer" json:"sniffer"`
TLS RawTLS `yaml:"tls" json:"tls"`
ClashForAndroid RawClashForAndroid `yaml:"clash-for-android" json:"clash-for-android"`
}
type GeoXUrl struct {
GeoIp string `yaml:"geoip" json:"geoip"`
Mmdb string `yaml:"mmdb" json:"mmdb"`
ASN string `yaml:"asn" json:"asn"`
GeoSite string `yaml:"geosite" json:"geosite"`
}
type RawSniffer struct {
Enable bool `yaml:"enable" json:"enable"`
OverrideDest bool `yaml:"override-destination" json:"override-destination"`
Sniffing []string `yaml:"sniffing" json:"sniffing"`
ForceDomain []string `yaml:"force-domain" json:"force-domain"`
SkipDomain []string `yaml:"skip-domain" json:"skip-domain"`
Ports []string `yaml:"port-whitelist" json:"port-whitelist"`
ForceDnsMapping bool `yaml:"force-dns-mapping" json:"force-dns-mapping"`
ParsePureIp bool `yaml:"parse-pure-ip" json:"parse-pure-ip"`
Sniff map[string]RawSniffingConfig `yaml:"sniff" json:"sniff"`
}
type RawSniffingConfig struct {
Ports []string `yaml:"ports" json:"ports"`
OverrideDest *bool `yaml:"override-destination" json:"override-destination"`
}
var (
GroupsList = list.New()
ProxiesList = list.New()
@ -418,41 +453,6 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
TCPConcurrent: false,
FindProcessMode: P.FindProcessStrict,
GlobalUA: "clash.meta/" + C.Version,
Tun: RawTun{
Enable: false,
Device: "",
Stack: C.TunGvisor,
DNSHijack: []string{"0.0.0.0:53"}, // default hijack all dns query
AutoRoute: true,
AutoDetectInterface: true,
Inet6Address: []netip.Prefix{netip.MustParsePrefix("fdfe:dcba:9876::1/126")},
},
TuicServer: RawTuicServer{
Enable: false,
Token: nil,
Users: nil,
Certificate: "",
PrivateKey: "",
Listen: "",
CongestionController: "",
MaxIdleTime: 15000,
AuthenticationTimeout: 1000,
ALPN: []string{"h3"},
MaxUdpRelayPacketSize: 1500,
},
IPTables: IPTables{
Enable: false,
InboundInterface: "lo",
Bypass: []string{},
DnsRedirect: true,
},
NTP: RawNTP{
Enable: false,
WriteToSystem: false,
Server: "time.apple.com",
ServerPort: 123,
Interval: 30,
},
DNS: RawDNS{
Enable: false,
IPv6: false,
@ -483,11 +483,55 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
"www.msftconnecttest.com",
},
},
Experimental: Experimental{
NTP: RawNTP{
Enable: false,
WriteToSystem: false,
Server: "time.apple.com",
Port: 123,
Interval: 30,
},
Tun: RawTun{
Enable: false,
Device: "",
Stack: C.TunGvisor,
DNSHijack: []string{"0.0.0.0:53"}, // default hijack all dns query
AutoRoute: true,
AutoDetectInterface: true,
Inet6Address: []netip.Prefix{netip.MustParsePrefix("fdfe:dcba:9876::1/126")},
},
TuicServer: RawTuicServer{
Enable: false,
Token: nil,
Users: nil,
Certificate: "",
PrivateKey: "",
Listen: "",
CongestionController: "",
MaxIdleTime: 15000,
AuthenticationTimeout: 1000,
ALPN: []string{"h3"},
MaxUdpRelayPacketSize: 1500,
},
IPTables: RawIPTables{
Enable: false,
InboundInterface: "lo",
Bypass: []string{},
DnsRedirect: true,
},
Experimental: RawExperimental{
// https://github.com/quic-go/quic-go/issues/4178
// Quic-go currently cannot automatically fall back on platforms that do not support ecn, so this feature is turned off by default.
QUICGoDisableECN: true,
},
Profile: RawProfile{
StoreSelected: true,
},
GeoXUrl: RawGeoXUrl{
Mmdb: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb",
ASN: "https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb",
GeoIp: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat",
GeoSite: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat",
},
Sniffer: RawSniffer{
Enable: false,
Sniff: map[string]RawSniffingConfig{},
@ -498,15 +542,6 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
ParsePureIp: true,
OverrideDest: true,
},
Profile: Profile{
StoreSelected: true,
},
GeoXUrl: GeoXUrl{
Mmdb: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb",
ASN: "https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb",
GeoIp: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat",
GeoSite: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat",
},
ExternalUIURL: "https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip",
}
@ -521,10 +556,6 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
config := &Config{}
log.Infoln("Start initial configuration in progress") //Segment finished in xxm
startTime := time.Now()
config.Experimental = &rawCfg.Experimental
config.Profile = &rawCfg.Profile
config.IPTables = &rawCfg.IPTables
config.TLS = &rawCfg.RawTLS
general, err := parseGeneral(rawCfg)
if err != nil {
@ -537,6 +568,42 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
tlsC.SetGlobalUtlsClient(config.General.GlobalClientFingerprint)
}
controller, err := parseController(rawCfg)
if err != nil {
return nil, err
}
config.Controller = controller
experimental, err := parseExperimental(rawCfg)
if err != nil {
return nil, err
}
config.Experimental = experimental
iptables, err := parseIPTables(rawCfg)
if err != nil {
return nil, err
}
config.IPTables = iptables
ntpCfg, err := parseNTP(rawCfg)
if err != nil {
return nil, err
}
config.NTP = ntpCfg
profile, err := parseProfile(rawCfg)
if err != nil {
return nil, err
}
config.Profile = profile
tlsCfg, err := parseTLS(rawCfg)
if err != nil {
return nil, err
}
config.TLS = tlsCfg
proxies, providers, err := parseProxies(rawCfg)
if err != nil {
return nil, err
@ -576,9 +643,6 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
}
config.Hosts = hosts
ntpCfg := paresNTP(rawCfg)
config.NTP = ntpCfg
dnsCfg, err := parseDNS(rawCfg, hosts, rules, ruleProviders)
if err != nil {
return nil, err
@ -687,21 +751,18 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
InboundTfo: cfg.InboundTfo,
InboundMPTCP: cfg.InboundMPTCP,
},
Controller: Controller{
ExternalController: cfg.ExternalController,
ExternalUI: cfg.ExternalUI,
Secret: cfg.Secret,
ExternalControllerUnix: cfg.ExternalControllerUnix,
ExternalControllerTLS: cfg.ExternalControllerTLS,
ExternalDohServer: cfg.ExternalDohServer,
UnifiedDelay: cfg.UnifiedDelay,
Mode: cfg.Mode,
LogLevel: cfg.LogLevel,
IPv6: cfg.IPv6,
Interface: cfg.Interface,
RoutingMark: cfg.RoutingMark,
GeoXUrl: GeoXUrl{
GeoIp: cfg.GeoXUrl.GeoIp,
Mmdb: cfg.GeoXUrl.Mmdb,
ASN: cfg.GeoXUrl.ASN,
GeoSite: cfg.GeoXUrl.GeoSite,
},
UnifiedDelay: cfg.UnifiedDelay,
Mode: cfg.Mode,
LogLevel: cfg.LogLevel,
IPv6: cfg.IPv6,
Interface: cfg.Interface,
RoutingMark: cfg.RoutingMark,
GeoXUrl: cfg.GeoXUrl,
GeoAutoUpdate: cfg.GeoAutoUpdate,
GeoUpdateInterval: cfg.GeoUpdateInterval,
GeodataMode: cfg.GeodataMode,
@ -713,6 +774,61 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
}, nil
}
func parseController(cfg *RawConfig) (*Controller, error) {
return &Controller{
ExternalController: cfg.ExternalController,
ExternalUI: cfg.ExternalUI,
Secret: cfg.Secret,
ExternalControllerUnix: cfg.ExternalControllerUnix,
ExternalControllerTLS: cfg.ExternalControllerTLS,
ExternalDohServer: cfg.ExternalDohServer,
}, nil
}
func parseExperimental(cfg *RawConfig) (*Experimental, error) {
return &Experimental{
Fingerprints: cfg.Experimental.Fingerprints,
QUICGoDisableGSO: cfg.Experimental.QUICGoDisableGSO,
QUICGoDisableECN: cfg.Experimental.QUICGoDisableECN,
IP4PEnable: cfg.Experimental.IP4PEnable,
}, nil
}
func parseIPTables(cfg *RawConfig) (*IPTables, error) {
return &IPTables{
Enable: cfg.IPTables.Enable,
InboundInterface: cfg.IPTables.InboundInterface,
Bypass: cfg.IPTables.Bypass,
DnsRedirect: cfg.IPTables.DnsRedirect,
}, nil
}
func parseNTP(cfg *RawConfig) (*NTP, error) {
return &NTP{
Enable: cfg.NTP.Enable,
Server: cfg.NTP.Server,
Port: cfg.NTP.Port,
Interval: cfg.NTP.Interval,
DialerProxy: cfg.NTP.DialerProxy,
WriteToSystem: cfg.NTP.WriteToSystem,
}, nil
}
func parseProfile(cfg *RawConfig) (*Profile, error) {
return &Profile{
StoreSelected: cfg.Profile.StoreSelected,
StoreFakeIP: cfg.Profile.StoreFakeIP,
}, nil
}
func parseTLS(cfg *RawConfig) (*TLS, error) {
return &TLS{
Certificate: cfg.TLS.Certificate,
PrivateKey: cfg.TLS.PrivateKey,
CustomTrustCert: cfg.TLS.CustomTrustCert,
}, nil
}
func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[string]providerTypes.ProxyProvider, err error) {
proxies = make(map[string]C.Proxy)
providersMap = make(map[string]providerTypes.ProxyProvider)
@ -1259,19 +1375,6 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rules [
return policy, nil
}
func paresNTP(rawCfg *RawConfig) *NTP {
cfg := rawCfg.NTP
ntpCfg := &NTP{
Enable: cfg.Enable,
Server: cfg.Server,
Port: cfg.ServerPort,
Interval: cfg.Interval,
DialerProxy: cfg.DialerProxy,
WriteToSystem: cfg.WriteToSystem,
}
return ntpCfg
}
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) {
cfg := rawCfg.DNS
if cfg.Enable && len(cfg.NameServer) == 0 {

View File

@ -22,6 +22,7 @@ import (
"github.com/metacubex/mihomo/component/profile/cachefile"
"github.com/metacubex/mihomo/component/resolver"
SNI "github.com/metacubex/mihomo/component/sniffer"
tlsC "github.com/metacubex/mihomo/component/tls"
"github.com/metacubex/mihomo/component/trie"
"github.com/metacubex/mihomo/component/updater"
"github.com/metacubex/mihomo/config"
@ -90,7 +91,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
}
}
updateExperimental(cfg)
updateExperimental(cfg.Experimental)
updateUsers(cfg.Users)
updateProxies(cfg.Proxies, cfg.Providers)
updateRules(cfg.Rules, cfg.SubRules, cfg.RuleProviders)
@ -145,19 +146,31 @@ func GetGeneral() *config.General {
LanDisAllowedIPs: inbound.DisAllowedIPs(),
AllowLan: listener.AllowLan(),
BindAddress: listener.BindAddress(),
InboundTfo: inbound.Tfo(),
InboundMPTCP: inbound.MPTCP(),
},
Controller: config.Controller{},
Mode: tunnel.Mode(),
LogLevel: log.Level(),
IPv6: !resolver.DisableIPv6,
GeodataMode: G.GeodataMode(),
GeoAutoUpdate: G.GeoAutoUpdate(),
GeoUpdateInterval: G.GeoUpdateInterval(),
GeodataLoader: G.LoaderName(),
GeositeMatcher: G.SiteMatcherName(),
Interface: dialer.DefaultInterface.Load(),
Sniffing: tunnel.IsSniffing(),
TCPConcurrent: dialer.GetTcpConcurrent(),
Mode: tunnel.Mode(),
UnifiedDelay: adapter.UnifiedDelay.Load(),
LogLevel: log.Level(),
IPv6: !resolver.DisableIPv6,
Interface: dialer.DefaultInterface.Load(),
RoutingMark: int(dialer.DefaultRoutingMark.Load()),
GeoXUrl: config.GeoXUrl{
GeoIp: C.GeoIpUrl,
Mmdb: C.MmdbUrl,
ASN: C.ASNUrl,
GeoSite: C.GeoSiteUrl,
},
GeoAutoUpdate: G.GeoAutoUpdate(),
GeoUpdateInterval: G.GeoUpdateInterval(),
GeodataMode: G.GeodataMode(),
GeodataLoader: G.LoaderName(),
GeositeMatcher: G.SiteMatcherName(),
TCPConcurrent: dialer.GetTcpConcurrent(),
FindProcessMode: tunnel.FindProcessMode(),
Sniffing: tunnel.IsSniffing(),
GlobalClientFingerprint: tlsC.GetGlobalFingerprint(),
GlobalUA: C.UA,
}
return general
@ -188,14 +201,14 @@ func updateListeners(general *config.General, listeners map[string]C.InboundList
listener.ReCreateTun(general.Tun, tunnel.Tunnel)
}
func updateExperimental(c *config.Config) {
if c.Experimental.QUICGoDisableGSO {
func updateExperimental(c *config.Experimental) {
if c.QUICGoDisableGSO {
_ = os.Setenv("QUIC_GO_DISABLE_GSO", strconv.FormatBool(true))
}
if c.Experimental.QUICGoDisableECN {
if c.QUICGoDisableECN {
_ = os.Setenv("QUIC_GO_DISABLE_ECN", strconv.FormatBool(true))
}
dialer.GetIP4PEnable(c.Experimental.IP4PEnable)
dialer.GetIP4PEnable(c.IP4PEnable)
}
func updateNTP(c *config.NTP) {

View File

@ -11,25 +11,25 @@ type Option func(*config.Config)
func WithExternalUI(externalUI string) Option {
return func(cfg *config.Config) {
cfg.General.ExternalUI = externalUI
cfg.Controller.ExternalUI = externalUI
}
}
func WithExternalController(externalController string) Option {
return func(cfg *config.Config) {
cfg.General.ExternalController = externalController
cfg.Controller.ExternalController = externalController
}
}
func WithExternalControllerUnix(externalControllerUnix string) Option {
return func(cfg *config.Config) {
cfg.General.ExternalControllerUnix = externalControllerUnix
cfg.Controller.ExternalControllerUnix = externalControllerUnix
}
}
func WithSecret(secret string) Option {
return func(cfg *config.Config) {
cfg.General.Secret = secret
cfg.Controller.Secret = secret
}
}
@ -44,18 +44,18 @@ func Parse(options ...Option) error {
option(cfg)
}
if cfg.General.ExternalUI != "" {
route.SetUIPath(cfg.General.ExternalUI)
if cfg.Controller.ExternalUI != "" {
route.SetUIPath(cfg.Controller.ExternalUI)
}
if cfg.General.ExternalController != "" {
go route.Start(cfg.General.ExternalController, cfg.General.ExternalControllerTLS,
cfg.General.Secret, cfg.TLS.Certificate, cfg.TLS.PrivateKey, cfg.General.ExternalDohServer,
if cfg.Controller.ExternalController != "" {
go route.Start(cfg.Controller.ExternalController, cfg.Controller.ExternalControllerTLS,
cfg.Controller.Secret, cfg.TLS.Certificate, cfg.TLS.PrivateKey, cfg.Controller.ExternalDohServer,
cfg.General.LogLevel == log.DEBUG)
}
if cfg.General.ExternalControllerUnix != "" {
go route.StartUnix(cfg.General.ExternalControllerUnix, cfg.General.ExternalDohServer, cfg.General.LogLevel == log.DEBUG)
if cfg.Controller.ExternalControllerUnix != "" {
go route.StartUnix(cfg.Controller.ExternalControllerUnix, cfg.Controller.ExternalDohServer, cfg.General.LogLevel == log.DEBUG)
}
executor.ApplyConfig(cfg, true)

View File

@ -68,16 +68,16 @@ type tunSchema struct {
GSOMaxSize *uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
//Inet4Address *[]netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
Inet6Address *[]netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
IPRoute2TableIndex *int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
IPRoute2RuleIndex *int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
AutoRedirect *bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
AutoRedirectInputMark *uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
AutoRedirectOutputMark *uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
IPRoute2TableIndex *int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"`
IPRoute2RuleIndex *int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"`
AutoRedirect *bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
AutoRedirectInputMark *uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"`
AutoRedirectOutputMark *uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"`
StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"`
RouteAddress *[]netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
RouteAddressSet *[]string `yaml:"route-address-set" json:"route_address_set,omitempty"`
RouteExcludeAddress *[]netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
RouteExcludeAddressSet *[]string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
RouteAddress *[]netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
RouteAddressSet *[]string `yaml:"route-address-set" json:"route-address-set,omitempty"`
RouteExcludeAddress *[]netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"`
RouteExcludeAddressSet *[]string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"`
IncludeInterface *[]string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface *[]string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"`

View File

@ -34,16 +34,16 @@ type Tun struct {
GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
AutoRedirect bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2-table-index,omitempty"`
IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2-rule-index,omitempty"`
AutoRedirect bool `yaml:"auto-redirect" json:"auto-redirect,omitempty"`
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto-redirect-input-mark,omitempty"`
AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto-redirect-output-mark,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
RouteAddress []netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
RouteAddressSet []string `yaml:"route-address-set" json:"route_address_set,omitempty"`
RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
RouteAddress []netip.Prefix `yaml:"route-address" json:"route-address,omitempty"`
RouteAddressSet []string `yaml:"route-address-set" json:"route-address-set,omitempty"`
RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route-exclude-address,omitempty"`
RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route-exclude-address-set,omitempty"`
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"`

View File

@ -21,35 +21,35 @@ type TunOption struct {
MTU uint32 `inbound:"mtu,omitempty"`
GSO bool `inbound:"gso,omitempty"`
GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"`
Inet4Address []string `inbound:"inet4_address,omitempty"`
Inet6Address []string `inbound:"inet6_address,omitempty"`
Inet4Address []string `inbound:"inet4-address,omitempty"`
Inet6Address []string `inbound:"inet6-address,omitempty"`
IPRoute2TableIndex int `inbound:"iproute2-table-index"`
IPRoute2RuleIndex int `inbound:"iproute2-rule-index"`
AutoRedirect bool `inbound:"auto-redirect"`
AutoRedirectInputMark uint32 `inbound:"auto-redirect-input-mark"`
AutoRedirectOutputMark uint32 `inbound:"auto-redirect-output-mark"`
StrictRoute bool `inbound:"strict_route,omitempty"`
StrictRoute bool `inbound:"strict-route,omitempty"`
RouteAddress []string `inbound:"route-address"`
RouteAddressSet []string `inbound:"route-address-set"`
RouteExcludeAddress []string `inbound:"route-exclude-address"`
RouteExcludeAddressSet []string `inbound:"route-exclude-address-set"`
IncludeInterface []string `inbound:"include-interface,omitempty"`
ExcludeInterface []string `inbound:"exclude-interface"`
IncludeUID []uint32 `inbound:"include_uid,omitempty"`
IncludeUIDRange []string `inbound:"include_uid_range,omitempty"`
ExcludeUID []uint32 `inbound:"exclude_uid,omitempty"`
ExcludeUIDRange []string `inbound:"exclude_uid_range,omitempty"`
IncludeAndroidUser []int `inbound:"include_android_user,omitempty"`
IncludePackage []string `inbound:"include_package,omitempty"`
ExcludePackage []string `inbound:"exclude_package,omitempty"`
EndpointIndependentNat bool `inbound:"endpoint_independent_nat,omitempty"`
UDPTimeout int64 `inbound:"udp_timeout,omitempty"`
IncludeUID []uint32 `inbound:"include-uid,omitempty"`
IncludeUIDRange []string `inbound:"include-uid-range,omitempty"`
ExcludeUID []uint32 `inbound:"exclude-uid,omitempty"`
ExcludeUIDRange []string `inbound:"exclude-uid-range,omitempty"`
IncludeAndroidUser []int `inbound:"include-android-user,omitempty"`
IncludePackage []string `inbound:"include-package,omitempty"`
ExcludePackage []string `inbound:"exclude-package,omitempty"`
EndpointIndependentNat bool `inbound:"endpoint-independent-nat,omitempty"`
UDPTimeout int64 `inbound:"udp-timeout,omitempty"`
FileDescriptor int `inbound:"file-descriptor,omitempty"`
Inet4RouteAddress []string `inbound:"inet4_route_address,omitempty"`
Inet6RouteAddress []string `inbound:"inet6_route_address,omitempty"`
Inet4RouteExcludeAddress []string `inbound:"inet4_route_exclude_address,omitempty"`
Inet6RouteExcludeAddress []string `inbound:"inet6_route_exclude_address,omitempty"`
Inet4RouteAddress []string `inbound:"inet4-route-address,omitempty"`
Inet6RouteAddress []string `inbound:"inet6-route-address,omitempty"`
Inet4RouteExcludeAddress []string `inbound:"inet4-route-exclude-address,omitempty"`
Inet6RouteExcludeAddress []string `inbound:"inet6-route-exclude-address,omitempty"`
}
func (o TunOption) Equal(config C.InboundConfig) bool {

View File

@ -225,6 +225,10 @@ func SetMode(m TunnelMode) {
mode = m
}
func FindProcessMode() P.FindProcessMode {
return findProcessMode
}
// SetFindProcessMode replace SetAlwaysFindProcess
// always find process info if legacyAlways = true or mode.Always() = true, may be increase many memory
func SetFindProcessMode(mode P.FindProcessMode) {