config.go 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622
  1. package config
  2. import (
  3. "container/list"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "net/netip"
  8. "net/url"
  9. "os"
  10. "path"
  11. "regexp"
  12. "strings"
  13. "time"
  14. "github.com/metacubex/mihomo/adapter"
  15. "github.com/metacubex/mihomo/adapter/outbound"
  16. "github.com/metacubex/mihomo/adapter/outboundgroup"
  17. "github.com/metacubex/mihomo/adapter/provider"
  18. N "github.com/metacubex/mihomo/common/net"
  19. "github.com/metacubex/mihomo/common/utils"
  20. "github.com/metacubex/mihomo/component/auth"
  21. "github.com/metacubex/mihomo/component/fakeip"
  22. "github.com/metacubex/mihomo/component/geodata"
  23. "github.com/metacubex/mihomo/component/geodata/router"
  24. P "github.com/metacubex/mihomo/component/process"
  25. "github.com/metacubex/mihomo/component/resolver"
  26. SNIFF "github.com/metacubex/mihomo/component/sniffer"
  27. tlsC "github.com/metacubex/mihomo/component/tls"
  28. "github.com/metacubex/mihomo/component/trie"
  29. "github.com/metacubex/mihomo/component/updater"
  30. C "github.com/metacubex/mihomo/constant"
  31. providerTypes "github.com/metacubex/mihomo/constant/provider"
  32. snifferTypes "github.com/metacubex/mihomo/constant/sniffer"
  33. "github.com/metacubex/mihomo/dns"
  34. L "github.com/metacubex/mihomo/listener"
  35. LC "github.com/metacubex/mihomo/listener/config"
  36. "github.com/metacubex/mihomo/log"
  37. R "github.com/metacubex/mihomo/rules"
  38. RP "github.com/metacubex/mihomo/rules/provider"
  39. T "github.com/metacubex/mihomo/tunnel"
  40. orderedmap "github.com/wk8/go-ordered-map/v2"
  41. "golang.org/x/exp/slices"
  42. "gopkg.in/yaml.v3"
  43. )
  44. // General config
  45. type General struct {
  46. Inbound
  47. Controller
  48. Mode T.TunnelMode `json:"mode"`
  49. UnifiedDelay bool
  50. LogLevel log.LogLevel `json:"log-level"`
  51. IPv6 bool `json:"ipv6"`
  52. Interface string `json:"interface-name"`
  53. RoutingMark int `json:"-"`
  54. GeoXUrl GeoXUrl `json:"geox-url"`
  55. GeoAutoUpdate bool `json:"geo-auto-update"`
  56. GeoUpdateInterval int `json:"geo-update-interval"`
  57. GeodataMode bool `json:"geodata-mode"`
  58. GeodataLoader string `json:"geodata-loader"`
  59. GeositeMatcher string `json:"geosite-matcher"`
  60. TCPConcurrent bool `json:"tcp-concurrent"`
  61. FindProcessMode P.FindProcessMode `json:"find-process-mode"`
  62. Sniffing bool `json:"sniffing"`
  63. EBpf EBpf `json:"-"`
  64. GlobalClientFingerprint string `json:"global-client-fingerprint"`
  65. GlobalUA string `json:"global-ua"`
  66. }
  67. // Inbound config
  68. type Inbound struct {
  69. Port int `json:"port"`
  70. SocksPort int `json:"socks-port"`
  71. RedirPort int `json:"redir-port"`
  72. TProxyPort int `json:"tproxy-port"`
  73. MixedPort int `json:"mixed-port"`
  74. Tun LC.Tun `json:"tun"`
  75. TuicServer LC.TuicServer `json:"tuic-server"`
  76. ShadowSocksConfig string `json:"ss-config"`
  77. VmessConfig string `json:"vmess-config"`
  78. Authentication []string `json:"authentication"`
  79. SkipAuthPrefixes []netip.Prefix `json:"skip-auth-prefixes"`
  80. LanAllowedIPs []netip.Prefix `json:"lan-allowed-ips"`
  81. LanDisAllowedIPs []netip.Prefix `json:"lan-disallowed-ips"`
  82. AllowLan bool `json:"allow-lan"`
  83. BindAddress string `json:"bind-address"`
  84. InboundTfo bool `json:"inbound-tfo"`
  85. InboundMPTCP bool `json:"inbound-mptcp"`
  86. }
  87. // Controller config
  88. type Controller struct {
  89. ExternalController string `json:"-"`
  90. ExternalControllerTLS string `json:"-"`
  91. ExternalControllerUnix string `json:"-"`
  92. ExternalUI string `json:"-"`
  93. ExternalDohServer string `json:"-"`
  94. Secret string `json:"-"`
  95. }
  96. // NTP config
  97. type NTP struct {
  98. Enable bool `yaml:"enable"`
  99. Server string `yaml:"server"`
  100. Port int `yaml:"port"`
  101. Interval int `yaml:"interval"`
  102. DialerProxy string `yaml:"dialer-proxy"`
  103. WriteToSystem bool `yaml:"write-to-system"`
  104. }
  105. // DNS config
  106. type DNS struct {
  107. Enable bool `yaml:"enable"`
  108. PreferH3 bool `yaml:"prefer-h3"`
  109. IPv6 bool `yaml:"ipv6"`
  110. IPv6Timeout uint `yaml:"ipv6-timeout"`
  111. UseSystemHosts bool `yaml:"use-system-hosts"`
  112. NameServer []dns.NameServer `yaml:"nameserver"`
  113. Fallback []dns.NameServer `yaml:"fallback"`
  114. FallbackFilter FallbackFilter `yaml:"fallback-filter"`
  115. Listen string `yaml:"listen"`
  116. EnhancedMode C.DNSMode `yaml:"enhanced-mode"`
  117. DefaultNameserver []dns.NameServer `yaml:"default-nameserver"`
  118. CacheAlgorithm string `yaml:"cache-algorithm"`
  119. FakeIPRange *fakeip.Pool
  120. Hosts *trie.DomainTrie[resolver.HostValue]
  121. NameServerPolicy *orderedmap.OrderedMap[string, []dns.NameServer]
  122. ProxyServerNameserver []dns.NameServer
  123. }
  124. // FallbackFilter config
  125. type FallbackFilter struct {
  126. GeoIP bool `yaml:"geoip"`
  127. GeoIPCode string `yaml:"geoip-code"`
  128. IPCIDR []netip.Prefix `yaml:"ipcidr"`
  129. Domain []string `yaml:"domain"`
  130. GeoSite []router.DomainMatcher `yaml:"geosite"`
  131. }
  132. // Profile config
  133. type Profile struct {
  134. StoreSelected bool `yaml:"store-selected"`
  135. StoreFakeIP bool `yaml:"store-fake-ip"`
  136. }
  137. type TLS struct {
  138. Certificate string `yaml:"certificate"`
  139. PrivateKey string `yaml:"private-key"`
  140. CustomTrustCert []string `yaml:"custom-certifactes"`
  141. }
  142. // IPTables config
  143. type IPTables struct {
  144. Enable bool `yaml:"enable" json:"enable"`
  145. InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"`
  146. Bypass []string `yaml:"bypass" json:"bypass"`
  147. DnsRedirect bool `yaml:"dns-redirect" json:"dns-redirect"`
  148. }
  149. type Sniffer struct {
  150. Enable bool
  151. Sniffers map[snifferTypes.Type]SNIFF.SnifferConfig
  152. ForceDomain *trie.DomainSet
  153. SkipDomain *trie.DomainSet
  154. ForceDnsMapping bool
  155. ParsePureIp bool
  156. }
  157. // Experimental config
  158. type Experimental struct {
  159. Fingerprints []string `yaml:"fingerprints"`
  160. QUICGoDisableGSO bool `yaml:"quic-go-disable-gso"`
  161. QUICGoDisableECN bool `yaml:"quic-go-disable-ecn"`
  162. IP4PEnable bool `yaml:"dialer-ip4p-convert"`
  163. }
  164. // Config is mihomo config manager
  165. type Config struct {
  166. General *General
  167. IPTables *IPTables
  168. NTP *NTP
  169. DNS *DNS
  170. Experimental *Experimental
  171. Hosts *trie.DomainTrie[resolver.HostValue]
  172. Profile *Profile
  173. Rules []C.Rule
  174. SubRules map[string][]C.Rule
  175. Users []auth.AuthUser
  176. Proxies map[string]C.Proxy
  177. Listeners map[string]C.InboundListener
  178. Providers map[string]providerTypes.ProxyProvider
  179. RuleProviders map[string]providerTypes.RuleProvider
  180. Tunnels []LC.Tunnel
  181. Sniffer *Sniffer
  182. TLS *TLS
  183. }
  184. type RawNTP struct {
  185. Enable bool `yaml:"enable"`
  186. Server string `yaml:"server"`
  187. ServerPort int `yaml:"server-port"`
  188. Interval int `yaml:"interval"`
  189. DialerProxy string `yaml:"dialer-proxy"`
  190. WriteToSystem bool `yaml:"write-to-system"`
  191. }
  192. type RawDNS struct {
  193. Enable bool `yaml:"enable" json:"enable"`
  194. PreferH3 bool `yaml:"prefer-h3" json:"prefer-h3"`
  195. IPv6 bool `yaml:"ipv6" json:"ipv6"`
  196. IPv6Timeout uint `yaml:"ipv6-timeout" json:"ipv6-timeout"`
  197. UseHosts bool `yaml:"use-hosts" json:"use-hosts"`
  198. UseSystemHosts bool `yaml:"use-system-hosts" json:"use-system-hosts"`
  199. RespectRules bool `yaml:"respect-rules" json:"respect-rules"`
  200. NameServer []string `yaml:"nameserver" json:"nameserver"`
  201. Fallback []string `yaml:"fallback" json:"fallback"`
  202. FallbackFilter RawFallbackFilter `yaml:"fallback-filter" json:"fallback-filter"`
  203. Listen string `yaml:"listen" json:"listen"`
  204. EnhancedMode C.DNSMode `yaml:"enhanced-mode" json:"enhanced-mode"`
  205. FakeIPRange string `yaml:"fake-ip-range" json:"fake-ip-range"`
  206. FakeIPFilter []string `yaml:"fake-ip-filter" json:"fake-ip-filter"`
  207. DefaultNameserver []string `yaml:"default-nameserver" json:"default-nameserver"`
  208. CacheAlgorithm string `yaml:"cache-algorithm" json:"cache-algorithm"`
  209. NameServerPolicy *orderedmap.OrderedMap[string, any] `yaml:"nameserver-policy" json:"nameserver-policy"`
  210. ProxyServerNameserver []string `yaml:"proxy-server-nameserver" json:"proxy-server-nameserver"`
  211. }
  212. type RawFallbackFilter struct {
  213. GeoIP bool `yaml:"geoip" json:"geoip"`
  214. GeoIPCode string `yaml:"geoip-code" json:"geoip-code"`
  215. IPCIDR []string `yaml:"ipcidr" json:"ipcidr"`
  216. Domain []string `yaml:"domain" json:"domain"`
  217. GeoSite []string `yaml:"geosite" json:"geosite"`
  218. }
  219. type RawTun struct {
  220. Enable bool `yaml:"enable" json:"enable"`
  221. Device string `yaml:"device" json:"device"`
  222. Stack C.TUNStack `yaml:"stack" json:"stack"`
  223. DNSHijack []string `yaml:"dns-hijack" json:"dns-hijack"`
  224. AutoRoute bool `yaml:"auto-route" json:"auto-route"`
  225. AutoDetectInterface bool `yaml:"auto-detect-interface"`
  226. MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
  227. GSO bool `yaml:"gso" json:"gso,omitempty"`
  228. GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
  229. //Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4_address,omitempty"`
  230. Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6_address,omitempty"`
  231. IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
  232. IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
  233. AutoRedirect bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
  234. AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
  235. AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
  236. StrictRoute bool `yaml:"strict-route" json:"strict_route,omitempty"`
  237. RouteAddress []netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
  238. RouteAddressSet []string `yaml:"route-address-set" json:"route_address_set,omitempty"`
  239. RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
  240. RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
  241. IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
  242. ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
  243. IncludeUID []uint32 `yaml:"include-uid" json:"include_uid,omitempty"`
  244. IncludeUIDRange []string `yaml:"include-uid-range" json:"include_uid_range,omitempty"`
  245. ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude_uid,omitempty"`
  246. ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude_uid_range,omitempty"`
  247. IncludeAndroidUser []int `yaml:"include-android-user" json:"include_android_user,omitempty"`
  248. IncludePackage []string `yaml:"include-package" json:"include_package,omitempty"`
  249. ExcludePackage []string `yaml:"exclude-package" json:"exclude_package,omitempty"`
  250. EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint_independent_nat,omitempty"`
  251. UDPTimeout int64 `yaml:"udp-timeout" json:"udp_timeout,omitempty"`
  252. FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
  253. Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4_route_address,omitempty"`
  254. Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6_route_address,omitempty"`
  255. Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4_route_exclude_address,omitempty"`
  256. Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6_route_exclude_address,omitempty"`
  257. }
  258. type RawTuicServer struct {
  259. Enable bool `yaml:"enable" json:"enable"`
  260. Listen string `yaml:"listen" json:"listen"`
  261. Token []string `yaml:"token" json:"token"`
  262. Users map[string]string `yaml:"users" json:"users,omitempty"`
  263. Certificate string `yaml:"certificate" json:"certificate"`
  264. PrivateKey string `yaml:"private-key" json:"private-key"`
  265. CongestionController string `yaml:"congestion-controller" json:"congestion-controller,omitempty"`
  266. MaxIdleTime int `yaml:"max-idle-time" json:"max-idle-time,omitempty"`
  267. AuthenticationTimeout int `yaml:"authentication-timeout" json:"authentication-timeout,omitempty"`
  268. ALPN []string `yaml:"alpn" json:"alpn,omitempty"`
  269. MaxUdpRelayPacketSize int `yaml:"max-udp-relay-packet-size" json:"max-udp-relay-packet-size,omitempty"`
  270. CWND int `yaml:"cwnd" json:"cwnd,omitempty"`
  271. }
  272. type RawConfig struct {
  273. Port int `yaml:"port" json:"port"`
  274. SocksPort int `yaml:"socks-port" json:"socks-port"`
  275. RedirPort int `yaml:"redir-port" json:"redir-port"`
  276. TProxyPort int `yaml:"tproxy-port" json:"tproxy-port"`
  277. MixedPort int `yaml:"mixed-port" json:"mixed-port"`
  278. ShadowSocksConfig string `yaml:"ss-config"`
  279. VmessConfig string `yaml:"vmess-config"`
  280. InboundTfo bool `yaml:"inbound-tfo"`
  281. InboundMPTCP bool `yaml:"inbound-mptcp"`
  282. Authentication []string `yaml:"authentication" json:"authentication"`
  283. SkipAuthPrefixes []netip.Prefix `yaml:"skip-auth-prefixes"`
  284. LanAllowedIPs []netip.Prefix `yaml:"lan-allowed-ips"`
  285. LanDisAllowedIPs []netip.Prefix `yaml:"lan-disallowed-ips"`
  286. AllowLan bool `yaml:"allow-lan" json:"allow-lan"`
  287. BindAddress string `yaml:"bind-address" json:"bind-address"`
  288. Mode T.TunnelMode `yaml:"mode" json:"mode"`
  289. UnifiedDelay bool `yaml:"unified-delay" json:"unified-delay"`
  290. LogLevel log.LogLevel `yaml:"log-level" json:"log-level"`
  291. IPv6 bool `yaml:"ipv6" json:"ipv6"`
  292. ExternalController string `yaml:"external-controller" json:"external-controller"`
  293. ExternalControllerUnix string `yaml:"external-controller-unix"`
  294. ExternalControllerTLS string `yaml:"external-controller-tls"`
  295. ExternalUI string `yaml:"external-ui"`
  296. ExternalUIURL string `yaml:"external-ui-url" json:"external-ui-url"`
  297. ExternalUIName string `yaml:"external-ui-name" json:"external-ui-name"`
  298. ExternalDohServer string `yaml:"external-doh-server"`
  299. Secret string `yaml:"secret"`
  300. Interface string `yaml:"interface-name"`
  301. RoutingMark int `yaml:"routing-mark"`
  302. Tunnels []LC.Tunnel `yaml:"tunnels"`
  303. GeoAutoUpdate bool `yaml:"geo-auto-update" json:"geo-auto-update"`
  304. GeoUpdateInterval int `yaml:"geo-update-interval" json:"geo-update-interval"`
  305. GeodataMode bool `yaml:"geodata-mode" json:"geodata-mode"`
  306. GeodataLoader string `yaml:"geodata-loader" json:"geodata-loader"`
  307. GeositeMatcher string `yaml:"geosite-matcher" json:"geosite-matcher"`
  308. TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
  309. FindProcessMode P.FindProcessMode `yaml:"find-process-mode" json:"find-process-mode"`
  310. GlobalClientFingerprint string `yaml:"global-client-fingerprint"`
  311. GlobalUA string `yaml:"global-ua" json:"global-ua"`
  312. KeepAliveInterval int `yaml:"keep-alive-interval" json:"keep-alive-interval"`
  313. Sniffer RawSniffer `yaml:"sniffer" json:"sniffer"`
  314. ProxyProvider map[string]map[string]any `yaml:"proxy-providers"`
  315. RuleProvider map[string]map[string]any `yaml:"rule-providers"`
  316. Hosts map[string]any `yaml:"hosts" json:"hosts"`
  317. NTP RawNTP `yaml:"ntp" json:"ntp"`
  318. DNS RawDNS `yaml:"dns" json:"dns"`
  319. Tun RawTun `yaml:"tun"`
  320. TuicServer RawTuicServer `yaml:"tuic-server"`
  321. EBpf EBpf `yaml:"ebpf"`
  322. IPTables IPTables `yaml:"iptables"`
  323. Experimental Experimental `yaml:"experimental"`
  324. Profile Profile `yaml:"profile"`
  325. GeoXUrl GeoXUrl `yaml:"geox-url" json:"geox-url"`
  326. Proxy []map[string]any `yaml:"proxies"`
  327. ProxyGroup []map[string]any `yaml:"proxy-groups"`
  328. Rule []string `yaml:"rules"`
  329. SubRules map[string][]string `yaml:"sub-rules"`
  330. RawTLS TLS `yaml:"tls"`
  331. Listeners []map[string]any `yaml:"listeners"`
  332. }
  333. type GeoXUrl struct {
  334. GeoIp string `yaml:"geoip" json:"geoip"`
  335. Mmdb string `yaml:"mmdb" json:"mmdb"`
  336. ASN string `yaml:"asn" json:"asn"`
  337. GeoSite string `yaml:"geosite" json:"geosite"`
  338. }
  339. type RawSniffer struct {
  340. Enable bool `yaml:"enable" json:"enable"`
  341. OverrideDest bool `yaml:"override-destination" json:"override-destination"`
  342. Sniffing []string `yaml:"sniffing" json:"sniffing"`
  343. ForceDomain []string `yaml:"force-domain" json:"force-domain"`
  344. SkipDomain []string `yaml:"skip-domain" json:"skip-domain"`
  345. Ports []string `yaml:"port-whitelist" json:"port-whitelist"`
  346. ForceDnsMapping bool `yaml:"force-dns-mapping" json:"force-dns-mapping"`
  347. ParsePureIp bool `yaml:"parse-pure-ip" json:"parse-pure-ip"`
  348. Sniff map[string]RawSniffingConfig `yaml:"sniff" json:"sniff"`
  349. }
  350. type RawSniffingConfig struct {
  351. Ports []string `yaml:"ports" json:"ports"`
  352. OverrideDest *bool `yaml:"override-destination" json:"override-destination"`
  353. }
  354. // EBpf config
  355. type EBpf struct {
  356. RedirectToTun []string `yaml:"redirect-to-tun" json:"redirect-to-tun"`
  357. AutoRedir []string `yaml:"auto-redir" json:"auto-redir"`
  358. }
  359. var (
  360. GroupsList = list.New()
  361. ProxiesList = list.New()
  362. ParsingProxiesCallback func(groupsList *list.List, proxiesList *list.List)
  363. )
  364. // Parse config
  365. func Parse(buf []byte) (*Config, error) {
  366. rawCfg, err := UnmarshalRawConfig(buf)
  367. if err != nil {
  368. return nil, err
  369. }
  370. return ParseRawConfig(rawCfg)
  371. }
  372. func DefaultRawConfig() *RawConfig {
  373. return &RawConfig{
  374. AllowLan: false,
  375. BindAddress: "*",
  376. LanAllowedIPs: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0"), netip.MustParsePrefix("::/0")},
  377. IPv6: true,
  378. Mode: T.Rule,
  379. GeoAutoUpdate: false,
  380. GeoUpdateInterval: 24,
  381. GeodataMode: C.GeodataMode,
  382. GeodataLoader: "memconservative",
  383. UnifiedDelay: false,
  384. Authentication: []string{},
  385. LogLevel: log.INFO,
  386. Hosts: map[string]any{},
  387. Rule: []string{},
  388. Proxy: []map[string]any{},
  389. ProxyGroup: []map[string]any{},
  390. TCPConcurrent: false,
  391. FindProcessMode: P.FindProcessStrict,
  392. GlobalUA: "clash.meta/" + C.Version,
  393. Tun: RawTun{
  394. Enable: false,
  395. Device: "",
  396. Stack: C.TunGvisor,
  397. DNSHijack: []string{"0.0.0.0:53"}, // default hijack all dns query
  398. AutoRoute: true,
  399. AutoDetectInterface: true,
  400. Inet6Address: []netip.Prefix{netip.MustParsePrefix("fdfe:dcba:9876::1/126")},
  401. },
  402. TuicServer: RawTuicServer{
  403. Enable: false,
  404. Token: nil,
  405. Users: nil,
  406. Certificate: "",
  407. PrivateKey: "",
  408. Listen: "",
  409. CongestionController: "",
  410. MaxIdleTime: 15000,
  411. AuthenticationTimeout: 1000,
  412. ALPN: []string{"h3"},
  413. MaxUdpRelayPacketSize: 1500,
  414. },
  415. EBpf: EBpf{
  416. RedirectToTun: []string{},
  417. AutoRedir: []string{},
  418. },
  419. IPTables: IPTables{
  420. Enable: false,
  421. InboundInterface: "lo",
  422. Bypass: []string{},
  423. DnsRedirect: true,
  424. },
  425. NTP: RawNTP{
  426. Enable: false,
  427. WriteToSystem: false,
  428. Server: "time.apple.com",
  429. ServerPort: 123,
  430. Interval: 30,
  431. },
  432. DNS: RawDNS{
  433. Enable: false,
  434. IPv6: false,
  435. UseHosts: true,
  436. UseSystemHosts: true,
  437. IPv6Timeout: 100,
  438. EnhancedMode: C.DNSMapping,
  439. FakeIPRange: "198.18.0.1/16",
  440. FallbackFilter: RawFallbackFilter{
  441. GeoIP: true,
  442. GeoIPCode: "CN",
  443. IPCIDR: []string{},
  444. GeoSite: []string{},
  445. },
  446. DefaultNameserver: []string{
  447. "114.114.114.114",
  448. "223.5.5.5",
  449. "8.8.8.8",
  450. "1.0.0.1",
  451. },
  452. NameServer: []string{
  453. "https://doh.pub/dns-query",
  454. "tls://223.5.5.5:853",
  455. },
  456. FakeIPFilter: []string{
  457. "dns.msftnsci.com",
  458. "www.msftnsci.com",
  459. "www.msftconnecttest.com",
  460. },
  461. },
  462. Experimental: Experimental{
  463. // https://github.com/quic-go/quic-go/issues/4178
  464. // Quic-go currently cannot automatically fall back on platforms that do not support ecn, so this feature is turned off by default.
  465. QUICGoDisableECN: true,
  466. },
  467. Sniffer: RawSniffer{
  468. Enable: false,
  469. Sniff: map[string]RawSniffingConfig{},
  470. ForceDomain: []string{},
  471. SkipDomain: []string{},
  472. Ports: []string{},
  473. ForceDnsMapping: true,
  474. ParsePureIp: true,
  475. OverrideDest: true,
  476. },
  477. Profile: Profile{
  478. StoreSelected: true,
  479. },
  480. GeoXUrl: GeoXUrl{
  481. Mmdb: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb",
  482. ASN: "https://github.com/xishang0128/geoip/releases/download/latest/GeoLite2-ASN.mmdb",
  483. GeoIp: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat",
  484. GeoSite: "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat",
  485. },
  486. ExternalUIURL: "https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip",
  487. }
  488. }
  489. func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
  490. // config with default value
  491. rawCfg := DefaultRawConfig()
  492. if err := yaml.Unmarshal(buf, rawCfg); err != nil {
  493. return nil, err
  494. }
  495. return rawCfg, nil
  496. }
  497. func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
  498. config := &Config{}
  499. log.Infoln("Start initial configuration in progress") //Segment finished in xxm
  500. startTime := time.Now()
  501. config.Experimental = &rawCfg.Experimental
  502. config.Profile = &rawCfg.Profile
  503. config.IPTables = &rawCfg.IPTables
  504. config.TLS = &rawCfg.RawTLS
  505. general, err := parseGeneral(rawCfg)
  506. if err != nil {
  507. return nil, err
  508. }
  509. config.General = general
  510. if len(config.General.GlobalClientFingerprint) != 0 {
  511. log.Debugln("GlobalClientFingerprint: %s", config.General.GlobalClientFingerprint)
  512. tlsC.SetGlobalUtlsClient(config.General.GlobalClientFingerprint)
  513. }
  514. proxies, providers, err := parseProxies(rawCfg)
  515. if err != nil {
  516. return nil, err
  517. }
  518. config.Proxies = proxies
  519. config.Providers = providers
  520. listener, err := parseListeners(rawCfg)
  521. if err != nil {
  522. return nil, err
  523. }
  524. config.Listeners = listener
  525. log.Infoln("Geodata Loader mode: %s", geodata.LoaderName())
  526. log.Infoln("Geosite Matcher implementation: %s", geodata.SiteMatcherName())
  527. ruleProviders, err := parseRuleProviders(rawCfg)
  528. if err != nil {
  529. return nil, err
  530. }
  531. config.RuleProviders = ruleProviders
  532. subRules, err := parseSubRules(rawCfg, proxies, ruleProviders)
  533. if err != nil {
  534. return nil, err
  535. }
  536. config.SubRules = subRules
  537. rules, err := parseRules(rawCfg.Rule, proxies, ruleProviders, subRules, "rules")
  538. if err != nil {
  539. return nil, err
  540. }
  541. config.Rules = rules
  542. hosts, err := parseHosts(rawCfg)
  543. if err != nil {
  544. return nil, err
  545. }
  546. config.Hosts = hosts
  547. ntpCfg := paresNTP(rawCfg)
  548. config.NTP = ntpCfg
  549. dnsCfg, err := parseDNS(rawCfg, hosts, rules, ruleProviders)
  550. if err != nil {
  551. return nil, err
  552. }
  553. config.DNS = dnsCfg
  554. err = parseTun(rawCfg.Tun, config.General)
  555. err = parseTuicServer(rawCfg.TuicServer, config.General)
  556. if err != nil {
  557. return nil, err
  558. }
  559. config.Users = parseAuthentication(rawCfg.Authentication)
  560. config.Tunnels = rawCfg.Tunnels
  561. // verify tunnels
  562. for _, t := range config.Tunnels {
  563. if len(t.Proxy) > 0 {
  564. if _, ok := config.Proxies[t.Proxy]; !ok {
  565. return nil, fmt.Errorf("tunnel proxy %s not found", t.Proxy)
  566. }
  567. }
  568. }
  569. config.Sniffer, err = parseSniffer(rawCfg.Sniffer)
  570. if err != nil {
  571. return nil, err
  572. }
  573. elapsedTime := time.Since(startTime) / time.Millisecond // duration in ms
  574. log.Infoln("Initial configuration complete, total time: %dms", elapsedTime) //Segment finished in xxm
  575. return config, nil
  576. }
  577. func parseGeneral(cfg *RawConfig) (*General, error) {
  578. geodata.SetGeodataMode(cfg.GeodataMode)
  579. geodata.SetGeoAutoUpdate(cfg.GeoAutoUpdate)
  580. geodata.SetGeoUpdateInterval(cfg.GeoUpdateInterval)
  581. geodata.SetLoader(cfg.GeodataLoader)
  582. geodata.SetSiteMatcher(cfg.GeositeMatcher)
  583. C.GeoAutoUpdate = cfg.GeoAutoUpdate
  584. C.GeoUpdateInterval = cfg.GeoUpdateInterval
  585. C.GeoIpUrl = cfg.GeoXUrl.GeoIp
  586. C.GeoSiteUrl = cfg.GeoXUrl.GeoSite
  587. C.MmdbUrl = cfg.GeoXUrl.Mmdb
  588. C.ASNUrl = cfg.GeoXUrl.ASN
  589. C.GeodataMode = cfg.GeodataMode
  590. C.UA = cfg.GlobalUA
  591. if cfg.KeepAliveInterval != 0 {
  592. N.KeepAliveInterval = time.Duration(cfg.KeepAliveInterval) * time.Second
  593. }
  594. updater.ExternalUIPath = cfg.ExternalUI
  595. // checkout externalUI exist
  596. if updater.ExternalUIPath != "" {
  597. updater.ExternalUIPath = C.Path.Resolve(updater.ExternalUIPath)
  598. if _, err := os.Stat(updater.ExternalUIPath); os.IsNotExist(err) {
  599. defaultUIpath := path.Join(C.Path.HomeDir(), "ui")
  600. log.Warnln("external-ui: %s does not exist, creating folder in %s", updater.ExternalUIPath, defaultUIpath)
  601. if err := os.MkdirAll(defaultUIpath, os.ModePerm); err != nil {
  602. return nil, err
  603. }
  604. updater.ExternalUIPath = defaultUIpath
  605. cfg.ExternalUI = defaultUIpath
  606. }
  607. }
  608. // checkout UIpath/name exist
  609. if cfg.ExternalUIName != "" {
  610. updater.ExternalUIName = cfg.ExternalUIName
  611. } else {
  612. updater.ExternalUIFolder = updater.ExternalUIPath
  613. }
  614. if cfg.ExternalUIURL != "" {
  615. updater.ExternalUIURL = cfg.ExternalUIURL
  616. }
  617. return &General{
  618. Inbound: Inbound{
  619. Port: cfg.Port,
  620. SocksPort: cfg.SocksPort,
  621. RedirPort: cfg.RedirPort,
  622. TProxyPort: cfg.TProxyPort,
  623. MixedPort: cfg.MixedPort,
  624. ShadowSocksConfig: cfg.ShadowSocksConfig,
  625. VmessConfig: cfg.VmessConfig,
  626. AllowLan: cfg.AllowLan,
  627. SkipAuthPrefixes: cfg.SkipAuthPrefixes,
  628. LanAllowedIPs: cfg.LanAllowedIPs,
  629. LanDisAllowedIPs: cfg.LanDisAllowedIPs,
  630. BindAddress: cfg.BindAddress,
  631. InboundTfo: cfg.InboundTfo,
  632. InboundMPTCP: cfg.InboundMPTCP,
  633. },
  634. Controller: Controller{
  635. ExternalController: cfg.ExternalController,
  636. ExternalUI: cfg.ExternalUI,
  637. Secret: cfg.Secret,
  638. ExternalControllerUnix: cfg.ExternalControllerUnix,
  639. ExternalControllerTLS: cfg.ExternalControllerTLS,
  640. ExternalDohServer: cfg.ExternalDohServer,
  641. },
  642. UnifiedDelay: cfg.UnifiedDelay,
  643. Mode: cfg.Mode,
  644. LogLevel: cfg.LogLevel,
  645. IPv6: cfg.IPv6,
  646. Interface: cfg.Interface,
  647. RoutingMark: cfg.RoutingMark,
  648. GeoXUrl: cfg.GeoXUrl,
  649. GeoAutoUpdate: cfg.GeoAutoUpdate,
  650. GeoUpdateInterval: cfg.GeoUpdateInterval,
  651. GeodataMode: cfg.GeodataMode,
  652. GeodataLoader: cfg.GeodataLoader,
  653. TCPConcurrent: cfg.TCPConcurrent,
  654. FindProcessMode: cfg.FindProcessMode,
  655. EBpf: cfg.EBpf,
  656. GlobalClientFingerprint: cfg.GlobalClientFingerprint,
  657. GlobalUA: cfg.GlobalUA,
  658. }, nil
  659. }
  660. func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[string]providerTypes.ProxyProvider, err error) {
  661. proxies = make(map[string]C.Proxy)
  662. providersMap = make(map[string]providerTypes.ProxyProvider)
  663. proxiesConfig := cfg.Proxy
  664. groupsConfig := cfg.ProxyGroup
  665. providersConfig := cfg.ProxyProvider
  666. var (
  667. proxyList []string
  668. AllProxies []string
  669. hasGlobal bool
  670. )
  671. proxiesList := list.New()
  672. groupsList := list.New()
  673. proxies["DIRECT"] = adapter.NewProxy(outbound.NewDirect())
  674. proxies["REJECT"] = adapter.NewProxy(outbound.NewReject())
  675. proxies["REJECT-DROP"] = adapter.NewProxy(outbound.NewRejectDrop())
  676. proxies["COMPATIBLE"] = adapter.NewProxy(outbound.NewCompatible())
  677. proxies["PASS"] = adapter.NewProxy(outbound.NewPass())
  678. proxyList = append(proxyList, "DIRECT", "REJECT")
  679. // parse proxy
  680. for idx, mapping := range proxiesConfig {
  681. proxy, err := adapter.ParseProxy(mapping)
  682. if err != nil {
  683. return nil, nil, fmt.Errorf("proxy %d: %w", idx, err)
  684. }
  685. if _, exist := proxies[proxy.Name()]; exist {
  686. return nil, nil, fmt.Errorf("proxy %s is the duplicate name", proxy.Name())
  687. }
  688. proxies[proxy.Name()] = proxy
  689. proxyList = append(proxyList, proxy.Name())
  690. AllProxies = append(AllProxies, proxy.Name())
  691. proxiesList.PushBack(mapping)
  692. }
  693. // keep the original order of ProxyGroups in config file
  694. for idx, mapping := range groupsConfig {
  695. groupName, existName := mapping["name"].(string)
  696. if !existName {
  697. return nil, nil, fmt.Errorf("proxy group %d: missing name", idx)
  698. }
  699. if groupName == "GLOBAL" {
  700. hasGlobal = true
  701. }
  702. proxyList = append(proxyList, groupName)
  703. groupsList.PushBack(mapping)
  704. }
  705. // check if any loop exists and sort the ProxyGroups
  706. if err := proxyGroupsDagSort(groupsConfig); err != nil {
  707. return nil, nil, err
  708. }
  709. var AllProviders []string
  710. // parse and initial providers
  711. for name, mapping := range providersConfig {
  712. if name == provider.ReservedName {
  713. return nil, nil, fmt.Errorf("can not defined a provider called `%s`", provider.ReservedName)
  714. }
  715. pd, err := provider.ParseProxyProvider(name, mapping)
  716. if err != nil {
  717. return nil, nil, fmt.Errorf("parse proxy provider %s error: %w", name, err)
  718. }
  719. providersMap[name] = pd
  720. AllProviders = append(AllProviders, name)
  721. }
  722. slices.Sort(AllProxies)
  723. slices.Sort(AllProviders)
  724. // parse proxy group
  725. for idx, mapping := range groupsConfig {
  726. group, err := outboundgroup.ParseProxyGroup(mapping, proxies, providersMap, AllProxies, AllProviders)
  727. if err != nil {
  728. return nil, nil, fmt.Errorf("proxy group[%d]: %w", idx, err)
  729. }
  730. groupName := group.Name()
  731. if _, exist := proxies[groupName]; exist {
  732. return nil, nil, fmt.Errorf("proxy group %s: the duplicate name", groupName)
  733. }
  734. proxies[groupName] = adapter.NewProxy(group)
  735. }
  736. var ps []C.Proxy
  737. for _, v := range proxyList {
  738. if proxies[v].Type() == C.Pass {
  739. continue
  740. }
  741. ps = append(ps, proxies[v])
  742. }
  743. hc := provider.NewHealthCheck(ps, "", 5000, 0, true, nil)
  744. pd, _ := provider.NewCompatibleProvider(provider.ReservedName, ps, hc)
  745. providersMap[provider.ReservedName] = pd
  746. if !hasGlobal {
  747. global := outboundgroup.NewSelector(
  748. &outboundgroup.GroupCommonOption{
  749. Name: "GLOBAL",
  750. },
  751. []providerTypes.ProxyProvider{pd},
  752. )
  753. proxies["GLOBAL"] = adapter.NewProxy(global)
  754. }
  755. ProxiesList = proxiesList
  756. GroupsList = groupsList
  757. if ParsingProxiesCallback != nil {
  758. // refresh tray menu
  759. go ParsingProxiesCallback(GroupsList, ProxiesList)
  760. }
  761. return proxies, providersMap, nil
  762. }
  763. func parseListeners(cfg *RawConfig) (listeners map[string]C.InboundListener, err error) {
  764. listeners = make(map[string]C.InboundListener)
  765. for index, mapping := range cfg.Listeners {
  766. listener, err := L.ParseListener(mapping)
  767. if err != nil {
  768. return nil, fmt.Errorf("proxy %d: %w", index, err)
  769. }
  770. if _, exist := mapping[listener.Name()]; exist {
  771. return nil, fmt.Errorf("listener %s is the duplicate name", listener.Name())
  772. }
  773. listeners[listener.Name()] = listener
  774. }
  775. return
  776. }
  777. func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]providerTypes.RuleProvider, err error) {
  778. RP.SetTunnel(T.Tunnel)
  779. ruleProviders = map[string]providerTypes.RuleProvider{}
  780. // parse rule provider
  781. for name, mapping := range cfg.RuleProvider {
  782. rp, err := RP.ParseRuleProvider(name, mapping, R.ParseRule)
  783. if err != nil {
  784. return nil, err
  785. }
  786. ruleProviders[name] = rp
  787. }
  788. return
  789. }
  790. func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy, ruleProviders map[string]providerTypes.RuleProvider) (subRules map[string][]C.Rule, err error) {
  791. subRules = map[string][]C.Rule{}
  792. for name := range cfg.SubRules {
  793. subRules[name] = make([]C.Rule, 0)
  794. }
  795. for name, rawRules := range cfg.SubRules {
  796. if len(name) == 0 {
  797. return nil, fmt.Errorf("sub-rule name is empty")
  798. }
  799. var rules []C.Rule
  800. rules, err = parseRules(rawRules, proxies, ruleProviders, subRules, fmt.Sprintf("sub-rules[%s]", name))
  801. if err != nil {
  802. return nil, err
  803. }
  804. subRules[name] = rules
  805. }
  806. if err = verifySubRule(subRules); err != nil {
  807. return nil, err
  808. }
  809. return
  810. }
  811. func verifySubRule(subRules map[string][]C.Rule) error {
  812. for name := range subRules {
  813. err := verifySubRuleCircularReferences(name, subRules, []string{})
  814. if err != nil {
  815. return err
  816. }
  817. }
  818. return nil
  819. }
  820. func verifySubRuleCircularReferences(n string, subRules map[string][]C.Rule, arr []string) error {
  821. isInArray := func(v string, array []string) bool {
  822. for _, c := range array {
  823. if v == c {
  824. return true
  825. }
  826. }
  827. return false
  828. }
  829. arr = append(arr, n)
  830. for i, rule := range subRules[n] {
  831. if rule.RuleType() == C.SubRules {
  832. if _, ok := subRules[rule.Adapter()]; !ok {
  833. return fmt.Errorf("sub-rule[%d:%s] error: [%s] not found", i, n, rule.Adapter())
  834. }
  835. if isInArray(rule.Adapter(), arr) {
  836. arr = append(arr, rule.Adapter())
  837. return fmt.Errorf("sub-rule error: circular references [%s]", strings.Join(arr, "->"))
  838. }
  839. if err := verifySubRuleCircularReferences(rule.Adapter(), subRules, arr); err != nil {
  840. return err
  841. }
  842. }
  843. }
  844. return nil
  845. }
  846. func parseRules(rulesConfig []string, proxies map[string]C.Proxy, ruleProviders map[string]providerTypes.RuleProvider, subRules map[string][]C.Rule, format string) ([]C.Rule, error) {
  847. var rules []C.Rule
  848. // parse rules
  849. for idx, line := range rulesConfig {
  850. rule := trimArr(strings.Split(line, ","))
  851. var (
  852. payload string
  853. target string
  854. params []string
  855. ruleName = strings.ToUpper(rule[0])
  856. )
  857. l := len(rule)
  858. if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" || ruleName == "DOMAIN-REGEX" || ruleName == "PROCESS-NAME-REGEX" || ruleName == "PROCESS-PATH-REGEX" {
  859. target = rule[l-1]
  860. payload = strings.Join(rule[1:l-1], ",")
  861. } else {
  862. if l < 2 {
  863. return nil, fmt.Errorf("%s[%d] [%s] error: format invalid", format, idx, line)
  864. }
  865. if l < 4 {
  866. rule = append(rule, make([]string, 4-l)...)
  867. }
  868. if ruleName == "MATCH" {
  869. l = 2
  870. }
  871. if l >= 3 {
  872. l = 3
  873. payload = rule[1]
  874. }
  875. target = rule[l-1]
  876. params = rule[l:]
  877. }
  878. if _, ok := proxies[target]; !ok {
  879. if ruleName != "SUB-RULE" {
  880. return nil, fmt.Errorf("%s[%d] [%s] error: proxy [%s] not found", format, idx, line, target)
  881. } else if _, ok = subRules[target]; !ok {
  882. return nil, fmt.Errorf("%s[%d] [%s] error: sub-rule [%s] not found", format, idx, line, target)
  883. }
  884. }
  885. params = trimArr(params)
  886. parsed, parseErr := R.ParseRule(ruleName, payload, target, params, subRules)
  887. if parseErr != nil {
  888. return nil, fmt.Errorf("%s[%d] [%s] error: %s", format, idx, line, parseErr.Error())
  889. }
  890. for _, name := range parsed.ProviderNames() {
  891. if _, ok := ruleProviders[name]; !ok {
  892. return nil, fmt.Errorf("%s[%d] [%s] error: rule set [%s] not found", format, idx, line, name)
  893. }
  894. }
  895. rules = append(rules, parsed)
  896. }
  897. return rules, nil
  898. }
  899. func parseHosts(cfg *RawConfig) (*trie.DomainTrie[resolver.HostValue], error) {
  900. tree := trie.New[resolver.HostValue]()
  901. // add default hosts
  902. hostValue, _ := resolver.NewHostValueByIPs(
  903. []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 1})})
  904. if err := tree.Insert("localhost", hostValue); err != nil {
  905. log.Errorln("insert localhost to host error: %s", err.Error())
  906. }
  907. if len(cfg.Hosts) != 0 {
  908. for domain, anyValue := range cfg.Hosts {
  909. if str, ok := anyValue.(string); ok && str == "lan" {
  910. if addrs, err := net.InterfaceAddrs(); err != nil {
  911. log.Errorln("insert lan to host error: %s", err)
  912. } else {
  913. ips := make([]netip.Addr, 0)
  914. for _, addr := range addrs {
  915. if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && !ipnet.IP.IsLinkLocalUnicast() {
  916. if ip, err := netip.ParseAddr(ipnet.IP.String()); err == nil {
  917. ips = append(ips, ip)
  918. }
  919. }
  920. }
  921. anyValue = ips
  922. }
  923. }
  924. value, err := resolver.NewHostValue(anyValue)
  925. if err != nil {
  926. return nil, fmt.Errorf("%s is not a valid value", anyValue)
  927. }
  928. if value.IsDomain {
  929. node := tree.Search(value.Domain)
  930. for node != nil && node.Data().IsDomain {
  931. if node.Data().Domain == domain {
  932. return nil, fmt.Errorf("%s, there is a cycle in domain name mapping", domain)
  933. }
  934. node = tree.Search(node.Data().Domain)
  935. }
  936. }
  937. _ = tree.Insert(domain, value)
  938. }
  939. }
  940. tree.Optimize()
  941. return tree, nil
  942. }
  943. func hostWithDefaultPort(host string, defPort string) (string, error) {
  944. hostname, port, err := net.SplitHostPort(host)
  945. if err != nil {
  946. if !strings.Contains(err.Error(), "missing port in address") {
  947. return "", err
  948. }
  949. host = host + ":" + defPort
  950. if hostname, port, err = net.SplitHostPort(host); err != nil {
  951. return "", err
  952. }
  953. }
  954. return net.JoinHostPort(hostname, port), nil
  955. }
  956. func parseNameServer(servers []string, respectRules bool, preferH3 bool) ([]dns.NameServer, error) {
  957. var nameservers []dns.NameServer
  958. for idx, server := range servers {
  959. if strings.HasPrefix(server, "dhcp://") {
  960. nameservers = append(
  961. nameservers,
  962. dns.NameServer{
  963. Net: "dhcp",
  964. Addr: server[len("dhcp://"):],
  965. },
  966. )
  967. continue
  968. }
  969. server = parsePureDNSServer(server)
  970. u, err := url.Parse(server)
  971. if err != nil {
  972. return nil, fmt.Errorf("DNS NameServer[%d] format error: %s", idx, err.Error())
  973. }
  974. proxyName := u.Fragment
  975. var addr, dnsNetType string
  976. params := map[string]string{}
  977. switch u.Scheme {
  978. case "udp":
  979. addr, err = hostWithDefaultPort(u.Host, "53")
  980. dnsNetType = "" // UDP
  981. case "tcp":
  982. addr, err = hostWithDefaultPort(u.Host, "53")
  983. dnsNetType = "tcp" // TCP
  984. case "tls":
  985. addr, err = hostWithDefaultPort(u.Host, "853")
  986. dnsNetType = "tcp-tls" // DNS over TLS
  987. case "http", "https":
  988. addr, err = hostWithDefaultPort(u.Host, "443")
  989. dnsNetType = "https" // DNS over HTTPS
  990. if u.Scheme == "http" {
  991. addr, err = hostWithDefaultPort(u.Host, "80")
  992. }
  993. if err == nil {
  994. proxyName = ""
  995. clearURL := url.URL{Scheme: u.Scheme, Host: addr, Path: u.Path, User: u.User}
  996. addr = clearURL.String()
  997. if len(u.Fragment) != 0 {
  998. for _, s := range strings.Split(u.Fragment, "&") {
  999. arr := strings.Split(s, "=")
  1000. if len(arr) == 0 {
  1001. continue
  1002. } else if len(arr) == 1 {
  1003. proxyName = arr[0]
  1004. } else if len(arr) == 2 {
  1005. params[arr[0]] = arr[1]
  1006. } else {
  1007. params[arr[0]] = strings.Join(arr[1:], "=")
  1008. }
  1009. }
  1010. }
  1011. }
  1012. case "quic":
  1013. addr, err = hostWithDefaultPort(u.Host, "853")
  1014. dnsNetType = "quic" // DNS over QUIC
  1015. case "system":
  1016. dnsNetType = "system" // System DNS
  1017. case "rcode":
  1018. dnsNetType = "rcode"
  1019. addr = u.Host
  1020. switch addr {
  1021. case "success",
  1022. "format_error",
  1023. "server_failure",
  1024. "name_error",
  1025. "not_implemented",
  1026. "refused":
  1027. default:
  1028. err = fmt.Errorf("unsupported RCode type: %s", addr)
  1029. }
  1030. default:
  1031. return nil, fmt.Errorf("DNS NameServer[%d] unsupport scheme: %s", idx, u.Scheme)
  1032. }
  1033. if err != nil {
  1034. return nil, fmt.Errorf("DNS NameServer[%d] format error: %s", idx, err.Error())
  1035. }
  1036. if respectRules && len(proxyName) == 0 {
  1037. proxyName = dns.RespectRules
  1038. }
  1039. nameservers = append(
  1040. nameservers,
  1041. dns.NameServer{
  1042. Net: dnsNetType,
  1043. Addr: addr,
  1044. ProxyName: proxyName,
  1045. Params: params,
  1046. PreferH3: preferH3,
  1047. },
  1048. )
  1049. }
  1050. return nameservers, nil
  1051. }
  1052. func init() {
  1053. dns.ParseNameServer = func(servers []string) ([]dns.NameServer, error) { // using by wireguard
  1054. return parseNameServer(servers, false, false)
  1055. }
  1056. }
  1057. func parsePureDNSServer(server string) string {
  1058. addPre := func(server string) string {
  1059. return "udp://" + server
  1060. }
  1061. if server == "system" {
  1062. return "system://"
  1063. }
  1064. if ip, err := netip.ParseAddr(server); err != nil {
  1065. if strings.Contains(server, "://") {
  1066. return server
  1067. }
  1068. return addPre(server)
  1069. } else {
  1070. if ip.Is4() {
  1071. return addPre(server)
  1072. } else {
  1073. return addPre("[" + server + "]")
  1074. }
  1075. }
  1076. }
  1077. func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], ruleProviders map[string]providerTypes.RuleProvider, respectRules bool, preferH3 bool) (*orderedmap.OrderedMap[string, []dns.NameServer], error) {
  1078. policy := orderedmap.New[string, []dns.NameServer]()
  1079. updatedPolicy := orderedmap.New[string, any]()
  1080. re := regexp.MustCompile(`[a-zA-Z0-9\-]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?`)
  1081. for pair := nsPolicy.Oldest(); pair != nil; pair = pair.Next() {
  1082. k, v := pair.Key, pair.Value
  1083. if strings.Contains(strings.ToLower(k), ",") {
  1084. if strings.Contains(k, "geosite:") {
  1085. subkeys := strings.Split(k, ":")
  1086. subkeys = subkeys[1:]
  1087. subkeys = strings.Split(subkeys[0], ",")
  1088. for _, subkey := range subkeys {
  1089. newKey := "geosite:" + subkey
  1090. updatedPolicy.Store(newKey, v)
  1091. }
  1092. } else if strings.Contains(strings.ToLower(k), "rule-set:") {
  1093. subkeys := strings.Split(k, ":")
  1094. subkeys = subkeys[1:]
  1095. subkeys = strings.Split(subkeys[0], ",")
  1096. for _, subkey := range subkeys {
  1097. newKey := "rule-set:" + subkey
  1098. updatedPolicy.Store(newKey, v)
  1099. }
  1100. } else if re.MatchString(k) {
  1101. subkeys := strings.Split(k, ",")
  1102. for _, subkey := range subkeys {
  1103. updatedPolicy.Store(subkey, v)
  1104. }
  1105. }
  1106. } else {
  1107. if strings.Contains(strings.ToLower(k), "geosite:") {
  1108. updatedPolicy.Store("geosite:"+k[8:], v)
  1109. } else if strings.Contains(strings.ToLower(k), "rule-set:") {
  1110. updatedPolicy.Store("rule-set:"+k[9:], v)
  1111. }
  1112. updatedPolicy.Store(k, v)
  1113. }
  1114. }
  1115. for pair := updatedPolicy.Oldest(); pair != nil; pair = pair.Next() {
  1116. domain, server := pair.Key, pair.Value
  1117. servers, err := utils.ToStringSlice(server)
  1118. if err != nil {
  1119. return nil, err
  1120. }
  1121. nameservers, err := parseNameServer(servers, respectRules, preferH3)
  1122. if err != nil {
  1123. return nil, err
  1124. }
  1125. if _, valid := trie.ValidAndSplitDomain(domain); !valid {
  1126. return nil, fmt.Errorf("DNS ResoverRule invalid domain: %s", domain)
  1127. }
  1128. if strings.HasPrefix(domain, "rule-set:") {
  1129. domainSetName := domain[9:]
  1130. if provider, ok := ruleProviders[domainSetName]; !ok {
  1131. return nil, fmt.Errorf("not found rule-set: %s", domainSetName)
  1132. } else {
  1133. switch provider.Behavior() {
  1134. case providerTypes.IPCIDR:
  1135. return nil, fmt.Errorf("rule provider type error, except domain,actual %s", provider.Behavior())
  1136. case providerTypes.Classical:
  1137. log.Warnln("%s provider is %s, only matching it contain domain rule", provider.Name(), provider.Behavior())
  1138. }
  1139. }
  1140. }
  1141. policy.Store(domain, nameservers)
  1142. }
  1143. return policy, nil
  1144. }
  1145. func parseFallbackIPCIDR(ips []string) ([]netip.Prefix, error) {
  1146. var ipNets []netip.Prefix
  1147. for idx, ip := range ips {
  1148. ipnet, err := netip.ParsePrefix(ip)
  1149. if err != nil {
  1150. return nil, fmt.Errorf("DNS FallbackIP[%d] format error: %s", idx, err.Error())
  1151. }
  1152. ipNets = append(ipNets, ipnet)
  1153. }
  1154. return ipNets, nil
  1155. }
  1156. func parseFallbackGeoSite(countries []string, rules []C.Rule) ([]router.DomainMatcher, error) {
  1157. var sites []router.DomainMatcher
  1158. if len(countries) > 0 {
  1159. if err := geodata.InitGeoSite(); err != nil {
  1160. return nil, fmt.Errorf("can't initial GeoSite: %s", err)
  1161. }
  1162. log.Warnln("replace fallback-filter.geosite with nameserver-policy, it will be removed in the future")
  1163. }
  1164. for _, country := range countries {
  1165. found := false
  1166. for _, rule := range rules {
  1167. if rule.RuleType() == C.GEOSITE {
  1168. if strings.EqualFold(country, rule.Payload()) {
  1169. found = true
  1170. sites = append(sites, rule.(C.RuleGeoSite).GetDomainMatcher())
  1171. log.Infoln("Start initial GeoSite dns fallback filter from rule `%s`", country)
  1172. }
  1173. }
  1174. }
  1175. if !found {
  1176. matcher, recordsCount, err := geodata.LoadGeoSiteMatcher(country)
  1177. if err != nil {
  1178. return nil, err
  1179. }
  1180. sites = append(sites, matcher)
  1181. log.Infoln("Start initial GeoSite dns fallback filter `%s`, records: %d", country, recordsCount)
  1182. }
  1183. }
  1184. return sites, nil
  1185. }
  1186. func paresNTP(rawCfg *RawConfig) *NTP {
  1187. cfg := rawCfg.NTP
  1188. ntpCfg := &NTP{
  1189. Enable: cfg.Enable,
  1190. Server: cfg.Server,
  1191. Port: cfg.ServerPort,
  1192. Interval: cfg.Interval,
  1193. DialerProxy: cfg.DialerProxy,
  1194. WriteToSystem: cfg.WriteToSystem,
  1195. }
  1196. return ntpCfg
  1197. }
  1198. func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[resolver.HostValue], rules []C.Rule, ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) {
  1199. cfg := rawCfg.DNS
  1200. if cfg.Enable && len(cfg.NameServer) == 0 {
  1201. return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
  1202. }
  1203. if cfg.RespectRules && len(cfg.ProxyServerNameserver) == 0 {
  1204. return nil, fmt.Errorf("if “respect-rules” is turned on, “proxy-server-nameserver” cannot be empty")
  1205. }
  1206. dnsCfg := &DNS{
  1207. Enable: cfg.Enable,
  1208. Listen: cfg.Listen,
  1209. PreferH3: cfg.PreferH3,
  1210. IPv6Timeout: cfg.IPv6Timeout,
  1211. IPv6: cfg.IPv6,
  1212. UseSystemHosts: cfg.UseSystemHosts,
  1213. EnhancedMode: cfg.EnhancedMode,
  1214. FallbackFilter: FallbackFilter{
  1215. IPCIDR: []netip.Prefix{},
  1216. GeoSite: []router.DomainMatcher{},
  1217. },
  1218. }
  1219. var err error
  1220. if dnsCfg.NameServer, err = parseNameServer(cfg.NameServer, cfg.RespectRules, cfg.PreferH3); err != nil {
  1221. return nil, err
  1222. }
  1223. if dnsCfg.Fallback, err = parseNameServer(cfg.Fallback, cfg.RespectRules, cfg.PreferH3); err != nil {
  1224. return nil, err
  1225. }
  1226. if dnsCfg.NameServerPolicy, err = parseNameServerPolicy(cfg.NameServerPolicy, ruleProviders, cfg.RespectRules, cfg.PreferH3); err != nil {
  1227. return nil, err
  1228. }
  1229. if dnsCfg.ProxyServerNameserver, err = parseNameServer(cfg.ProxyServerNameserver, false, cfg.PreferH3); err != nil {
  1230. return nil, err
  1231. }
  1232. if len(cfg.DefaultNameserver) == 0 {
  1233. return nil, errors.New("default nameserver should have at least one nameserver")
  1234. }
  1235. if dnsCfg.DefaultNameserver, err = parseNameServer(cfg.DefaultNameserver, false, cfg.PreferH3); err != nil {
  1236. return nil, err
  1237. }
  1238. // check default nameserver is pure ip addr
  1239. for _, ns := range dnsCfg.DefaultNameserver {
  1240. if ns.Net == "system" {
  1241. continue
  1242. }
  1243. host, _, err := net.SplitHostPort(ns.Addr)
  1244. if err != nil || net.ParseIP(host) == nil {
  1245. u, err := url.Parse(ns.Addr)
  1246. if err == nil && net.ParseIP(u.Host) == nil {
  1247. if ip, _, err := net.SplitHostPort(u.Host); err != nil || net.ParseIP(ip) == nil {
  1248. return nil, errors.New("default nameserver should be pure IP")
  1249. }
  1250. }
  1251. }
  1252. }
  1253. fakeIPRange, err := netip.ParsePrefix(cfg.FakeIPRange)
  1254. T.SetFakeIPRange(fakeIPRange)
  1255. if cfg.EnhancedMode == C.DNSFakeIP {
  1256. if err != nil {
  1257. return nil, err
  1258. }
  1259. var host *trie.DomainTrie[struct{}]
  1260. // fake ip skip host filter
  1261. if len(cfg.FakeIPFilter) != 0 {
  1262. host = trie.New[struct{}]()
  1263. for _, domain := range cfg.FakeIPFilter {
  1264. _ = host.Insert(domain, struct{}{})
  1265. }
  1266. host.Optimize()
  1267. }
  1268. if len(dnsCfg.Fallback) != 0 {
  1269. if host == nil {
  1270. host = trie.New[struct{}]()
  1271. }
  1272. for _, fb := range dnsCfg.Fallback {
  1273. if net.ParseIP(fb.Addr) != nil {
  1274. continue
  1275. }
  1276. _ = host.Insert(fb.Addr, struct{}{})
  1277. }
  1278. host.Optimize()
  1279. }
  1280. pool, err := fakeip.New(fakeip.Options{
  1281. IPNet: fakeIPRange,
  1282. Size: 1000,
  1283. Host: host,
  1284. Persistence: rawCfg.Profile.StoreFakeIP,
  1285. })
  1286. if err != nil {
  1287. return nil, err
  1288. }
  1289. dnsCfg.FakeIPRange = pool
  1290. }
  1291. if len(cfg.Fallback) != 0 {
  1292. dnsCfg.FallbackFilter.GeoIP = cfg.FallbackFilter.GeoIP
  1293. dnsCfg.FallbackFilter.GeoIPCode = cfg.FallbackFilter.GeoIPCode
  1294. if fallbackip, err := parseFallbackIPCIDR(cfg.FallbackFilter.IPCIDR); err == nil {
  1295. dnsCfg.FallbackFilter.IPCIDR = fallbackip
  1296. }
  1297. dnsCfg.FallbackFilter.Domain = cfg.FallbackFilter.Domain
  1298. fallbackGeoSite, err := parseFallbackGeoSite(cfg.FallbackFilter.GeoSite, rules)
  1299. if err != nil {
  1300. return nil, fmt.Errorf("load GeoSite dns fallback filter error, %w", err)
  1301. }
  1302. dnsCfg.FallbackFilter.GeoSite = fallbackGeoSite
  1303. }
  1304. if cfg.UseHosts {
  1305. dnsCfg.Hosts = hosts
  1306. }
  1307. if cfg.CacheAlgorithm == "" || cfg.CacheAlgorithm == "lru" {
  1308. dnsCfg.CacheAlgorithm = "lru"
  1309. } else {
  1310. dnsCfg.CacheAlgorithm = "arc"
  1311. }
  1312. return dnsCfg, nil
  1313. }
  1314. func parseAuthentication(rawRecords []string) []auth.AuthUser {
  1315. var users []auth.AuthUser
  1316. for _, line := range rawRecords {
  1317. if user, pass, found := strings.Cut(line, ":"); found {
  1318. users = append(users, auth.AuthUser{User: user, Pass: pass})
  1319. }
  1320. }
  1321. return users
  1322. }
  1323. func parseTun(rawTun RawTun, general *General) error {
  1324. tunAddressPrefix := T.FakeIPRange()
  1325. if !tunAddressPrefix.IsValid() {
  1326. tunAddressPrefix = netip.MustParsePrefix("198.18.0.1/16")
  1327. }
  1328. tunAddressPrefix = netip.PrefixFrom(tunAddressPrefix.Addr(), 30)
  1329. if !general.IPv6 || !verifyIP6() {
  1330. rawTun.Inet6Address = nil
  1331. }
  1332. general.Tun = LC.Tun{
  1333. Enable: rawTun.Enable,
  1334. Device: rawTun.Device,
  1335. Stack: rawTun.Stack,
  1336. DNSHijack: rawTun.DNSHijack,
  1337. AutoRoute: rawTun.AutoRoute,
  1338. AutoDetectInterface: rawTun.AutoDetectInterface,
  1339. MTU: rawTun.MTU,
  1340. GSO: rawTun.GSO,
  1341. GSOMaxSize: rawTun.GSOMaxSize,
  1342. Inet4Address: []netip.Prefix{tunAddressPrefix},
  1343. Inet6Address: rawTun.Inet6Address,
  1344. IPRoute2TableIndex: rawTun.IPRoute2TableIndex,
  1345. IPRoute2RuleIndex: rawTun.IPRoute2RuleIndex,
  1346. AutoRedirect: rawTun.AutoRedirect,
  1347. AutoRedirectInputMark: rawTun.AutoRedirectInputMark,
  1348. AutoRedirectOutputMark: rawTun.AutoRedirectOutputMark,
  1349. StrictRoute: rawTun.StrictRoute,
  1350. RouteAddress: rawTun.RouteAddress,
  1351. RouteAddressSet: rawTun.RouteAddressSet,
  1352. RouteExcludeAddress: rawTun.RouteExcludeAddress,
  1353. RouteExcludeAddressSet: rawTun.RouteExcludeAddressSet,
  1354. IncludeInterface: rawTun.IncludeInterface,
  1355. ExcludeInterface: rawTun.ExcludeInterface,
  1356. IncludeUID: rawTun.IncludeUID,
  1357. IncludeUIDRange: rawTun.IncludeUIDRange,
  1358. ExcludeUID: rawTun.ExcludeUID,
  1359. ExcludeUIDRange: rawTun.ExcludeUIDRange,
  1360. IncludeAndroidUser: rawTun.IncludeAndroidUser,
  1361. IncludePackage: rawTun.IncludePackage,
  1362. ExcludePackage: rawTun.ExcludePackage,
  1363. EndpointIndependentNat: rawTun.EndpointIndependentNat,
  1364. UDPTimeout: rawTun.UDPTimeout,
  1365. FileDescriptor: rawTun.FileDescriptor,
  1366. Inet4RouteAddress: rawTun.Inet4RouteAddress,
  1367. Inet6RouteAddress: rawTun.Inet6RouteAddress,
  1368. Inet4RouteExcludeAddress: rawTun.Inet4RouteExcludeAddress,
  1369. Inet6RouteExcludeAddress: rawTun.Inet6RouteExcludeAddress,
  1370. }
  1371. return nil
  1372. }
  1373. func parseTuicServer(rawTuic RawTuicServer, general *General) error {
  1374. general.TuicServer = LC.TuicServer{
  1375. Enable: rawTuic.Enable,
  1376. Listen: rawTuic.Listen,
  1377. Token: rawTuic.Token,
  1378. Users: rawTuic.Users,
  1379. Certificate: rawTuic.Certificate,
  1380. PrivateKey: rawTuic.PrivateKey,
  1381. CongestionController: rawTuic.CongestionController,
  1382. MaxIdleTime: rawTuic.MaxIdleTime,
  1383. AuthenticationTimeout: rawTuic.AuthenticationTimeout,
  1384. ALPN: rawTuic.ALPN,
  1385. MaxUdpRelayPacketSize: rawTuic.MaxUdpRelayPacketSize,
  1386. CWND: rawTuic.CWND,
  1387. }
  1388. return nil
  1389. }
  1390. func parseSniffer(snifferRaw RawSniffer) (*Sniffer, error) {
  1391. sniffer := &Sniffer{
  1392. Enable: snifferRaw.Enable,
  1393. ForceDnsMapping: snifferRaw.ForceDnsMapping,
  1394. ParsePureIp: snifferRaw.ParsePureIp,
  1395. }
  1396. loadSniffer := make(map[snifferTypes.Type]SNIFF.SnifferConfig)
  1397. if len(snifferRaw.Sniff) != 0 {
  1398. for sniffType, sniffConfig := range snifferRaw.Sniff {
  1399. find := false
  1400. ports, err := utils.NewUnsignedRangesFromList[uint16](sniffConfig.Ports)
  1401. if err != nil {
  1402. return nil, err
  1403. }
  1404. overrideDest := snifferRaw.OverrideDest
  1405. if sniffConfig.OverrideDest != nil {
  1406. overrideDest = *sniffConfig.OverrideDest
  1407. }
  1408. for _, snifferType := range snifferTypes.List {
  1409. if snifferType.String() == strings.ToUpper(sniffType) {
  1410. find = true
  1411. loadSniffer[snifferType] = SNIFF.SnifferConfig{
  1412. Ports: ports,
  1413. OverrideDest: overrideDest,
  1414. }
  1415. }
  1416. }
  1417. if !find {
  1418. return nil, fmt.Errorf("not find the sniffer[%s]", sniffType)
  1419. }
  1420. }
  1421. } else {
  1422. if sniffer.Enable && len(snifferRaw.Sniffing) != 0 {
  1423. // Deprecated: Use Sniff instead
  1424. log.Warnln("Deprecated: Use Sniff instead")
  1425. }
  1426. globalPorts, err := utils.NewUnsignedRangesFromList[uint16](snifferRaw.Ports)
  1427. if err != nil {
  1428. return nil, err
  1429. }
  1430. for _, snifferName := range snifferRaw.Sniffing {
  1431. find := false
  1432. for _, snifferType := range snifferTypes.List {
  1433. if snifferType.String() == strings.ToUpper(snifferName) {
  1434. find = true
  1435. loadSniffer[snifferType] = SNIFF.SnifferConfig{
  1436. Ports: globalPorts,
  1437. OverrideDest: snifferRaw.OverrideDest,
  1438. }
  1439. }
  1440. }
  1441. if !find {
  1442. return nil, fmt.Errorf("not find the sniffer[%s]", snifferName)
  1443. }
  1444. }
  1445. }
  1446. sniffer.Sniffers = loadSniffer
  1447. forceDomainTrie := trie.New[struct{}]()
  1448. for _, domain := range snifferRaw.ForceDomain {
  1449. err := forceDomainTrie.Insert(domain, struct{}{})
  1450. if err != nil {
  1451. return nil, fmt.Errorf("error domian[%s] in force-domain, error:%v", domain, err)
  1452. }
  1453. }
  1454. sniffer.ForceDomain = forceDomainTrie.NewDomainSet()
  1455. skipDomainTrie := trie.New[struct{}]()
  1456. for _, domain := range snifferRaw.SkipDomain {
  1457. err := skipDomainTrie.Insert(domain, struct{}{})
  1458. if err != nil {
  1459. return nil, fmt.Errorf("error domian[%s] in force-domain, error:%v", domain, err)
  1460. }
  1461. }
  1462. sniffer.SkipDomain = skipDomainTrie.NewDomainSet()
  1463. return sniffer, nil
  1464. }