Chore: merge branch 'with-tun' into plus-pro

This commit is contained in:
yaling888
2022-04-10 05:57:06 +08:00
66 changed files with 2807 additions and 334 deletions

View File

@@ -27,6 +27,7 @@ import (
"github.com/Dreamacro/clash/dns"
"github.com/Dreamacro/clash/listener/tun/ipstack/commons"
"github.com/Dreamacro/clash/log"
rewrites "github.com/Dreamacro/clash/rewrite"
R "github.com/Dreamacro/clash/rule"
T "github.com/Dreamacro/clash/tunnel"
@@ -51,6 +52,7 @@ type Inbound struct {
RedirPort int `json:"redir-port"`
TProxyPort int `json:"tproxy-port"`
MixedPort int `json:"mixed-port"`
MitmPort int `json:"mitm-port"`
Authentication []string `json:"authentication"`
AllowLan bool `json:"allow-lan"`
BindAddress string `json:"bind-address"`
@@ -74,7 +76,7 @@ type DNS struct {
EnhancedMode C.DNSMode `yaml:"enhanced-mode"`
DefaultNameserver []dns.NameServer `yaml:"default-nameserver"`
FakeIPRange *fakeip.Pool
Hosts *trie.DomainTrie
Hosts *trie.DomainTrie[netip.Addr]
NameServerPolicy map[string]dns.NameServer
ProxyServerNameserver []dns.NameServer
}
@@ -115,6 +117,12 @@ type IPTables struct {
InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"`
}
// Mitm config
type Mitm struct {
Hosts *trie.DomainTrie[bool] `yaml:"hosts" json:"hosts"`
Rules C.RewriteRule `yaml:"rules" json:"rules"`
}
// Experimental config
type Experimental struct{}
@@ -123,9 +131,10 @@ type Config struct {
General *General
Tun *Tun
IPTables *IPTables
Mitm *Mitm
DNS *DNS
Experimental *Experimental
Hosts *trie.DomainTrie
Hosts *trie.DomainTrie[netip.Addr]
Profile *Profile
Rules []C.Rule
RuleProviders map[string]C.Rule
@@ -166,12 +175,18 @@ type RawTun struct {
AutoRoute bool `yaml:"auto-route" json:"auto-route"`
}
type RawMitm struct {
Hosts []string `yaml:"hosts" json:"hosts"`
Rules []string `yaml:"rules" json:"rules"`
}
type RawConfig struct {
Port int `yaml:"port"`
SocksPort int `yaml:"socks-port"`
RedirPort int `yaml:"redir-port"`
TProxyPort int `yaml:"tproxy-port"`
MixedPort int `yaml:"mixed-port"`
MitmPort int `yaml:"mitm-port"`
Authentication []string `yaml:"authentication"`
AllowLan bool `yaml:"allow-lan"`
BindAddress string `yaml:"bind-address"`
@@ -189,6 +204,7 @@ type RawConfig struct {
DNS RawDNS `yaml:"dns"`
Tun RawTun `yaml:"tun"`
IPTables IPTables `yaml:"iptables"`
MITM RawMitm `yaml:"mitm"`
Experimental Experimental `yaml:"experimental"`
Profile Profile `yaml:"profile"`
Proxy []map[string]any `yaml:"proxies"`
@@ -250,6 +266,10 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
"tls://223.5.5.5:853",
},
},
MITM: RawMitm{
Hosts: []string{},
Rules: []string{},
},
Profile: Profile{
StoreSelected: true,
},
@@ -314,6 +334,12 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
}
config.DNS = dnsCfg
mitm, err := parseMitm(rawCfg.MITM)
if err != nil {
return nil, err
}
config.Mitm = mitm
config.Users = parseAuthentication(rawCfg.Authentication)
return config, nil
@@ -338,6 +364,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
RedirPort: cfg.RedirPort,
TProxyPort: cfg.TProxyPort,
MixedPort: cfg.MixedPort,
MitmPort: cfg.MitmPort,
AllowLan: cfg.AllowLan,
BindAddress: cfg.BindAddress,
},
@@ -546,24 +573,29 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, map[strin
return rules, ruleProviders, nil
}
func parseHosts(cfg *RawConfig) (*trie.DomainTrie, error) {
tree := trie.New()
func parseHosts(cfg *RawConfig) (*trie.DomainTrie[netip.Addr], error) {
tree := trie.New[netip.Addr]()
// add default hosts
if err := tree.Insert("localhost", net.IP{127, 0, 0, 1}); err != nil {
if err := tree.Insert("localhost", netip.AddrFrom4([4]byte{127, 0, 0, 1})); err != nil {
log.Errorln("insert localhost to host error: %s", err.Error())
}
if len(cfg.Hosts) != 0 {
for domain, ipStr := range cfg.Hosts {
ip := net.ParseIP(ipStr)
if ip == nil {
ip, err := netip.ParseAddr(ipStr)
if err != nil {
return nil, fmt.Errorf("%s is not a valid IP", ipStr)
}
_ = tree.Insert(domain, ip)
}
}
// add mitm.clash hosts
if err := tree.Insert("mitm.clash", netip.AddrFrom4([4]byte{8, 8, 9, 9})); err != nil {
log.Errorln("insert mitm.clash to host error: %s", err.Error())
}
return tree, nil
}
@@ -697,7 +729,7 @@ func parseFallbackGeoSite(countries []string, rules []C.Rule) ([]*router.DomainM
return sites, nil
}
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS, error) {
func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[netip.Addr], rules []C.Rule) (*DNS, error) {
cfg := rawCfg.DNS
if cfg.Enable && len(cfg.NameServer) == 0 {
return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty")
@@ -750,10 +782,10 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS,
return nil, err
}
var host *trie.DomainTrie
var host *trie.DomainTrie[bool]
// fake ip skip host filter
if len(cfg.FakeIPFilter) != 0 {
host = trie.New()
host = trie.New[bool]()
for _, domain := range cfg.FakeIPFilter {
_ = host.Insert(domain, true)
}
@@ -761,7 +793,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS,
if len(dnsCfg.Fallback) != 0 {
if host == nil {
host = trie.New()
host = trie.New[bool]()
}
for _, fb := range dnsCfg.Fallback {
if net.ParseIP(fb.Addr) != nil {
@@ -930,3 +962,38 @@ func cleanPyKeywords(code string) string {
}
return code
}
func parseMitm(rawMitm RawMitm) (*Mitm, error) {
var (
req []C.Rewrite
res []C.Rewrite
)
for _, line := range rawMitm.Rules {
rule, err := rewrites.ParseRewrite(line)
if err != nil {
return nil, fmt.Errorf("parse rewrite rule failure: %w", err)
}
if rule.RuleType() == C.MitmResponseHeader || rule.RuleType() == C.MitmResponseBody {
res = append(res, rule)
} else {
req = append(req, rule)
}
}
hosts := trie.New[bool]()
if len(rawMitm.Hosts) != 0 {
for _, domain := range rawMitm.Hosts {
_ = hosts.Insert(domain, true)
}
}
_ = hosts.Insert("mitm.clash", true)
return &Mitm{
Hosts: hosts,
Rules: rewrites.NewRewriteRules(req, res),
}, nil
}

View File

@@ -50,23 +50,6 @@ func initMMDB() error {
return nil
}
//func downloadGeoIP(path string) (err error) {
// resp, err := http.Get("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geoip.dat")
// if err != nil {
// return
// }
// defer resp.Body.Close()
//
// f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0644)
// if err != nil {
// return err
// }
// defer f.Close()
// _, err = io.Copy(f, resp.Body)
//
// return err
//}
func downloadGeoSite(path string) (err error) {
resp, err := http.Get("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat")
if err != nil {
@@ -84,19 +67,6 @@ func downloadGeoSite(path string) (err error) {
return err
}
//
//func initGeoIP() error {
// if _, err := os.Stat(C.Path.GeoIP()); os.IsNotExist(err) {
// log.Infoln("Can't find GeoIP.dat, start download")
// if err := downloadGeoIP(C.Path.GeoIP()); err != nil {
// return fmt.Errorf("can't download GeoIP.dat: %s", err.Error())
// }
// log.Infoln("Download GeoIP.dat finish")
// }
//
// return nil
//}
func initGeoSite() error {
if _, err := os.Stat(C.Path.GeoSite()); os.IsNotExist(err) {
log.Infoln("Can't find GeoSite.dat, start download")
@@ -129,11 +99,6 @@ func Init(dir string) error {
f.Close()
}
//// initial GeoIP
//if err := initGeoIP(); err != nil {
// return fmt.Errorf("can't initial GeoIP: %w", err)
//}
// initial mmdb
if err := initMMDB(); err != nil {
return fmt.Errorf("can't initial MMDB: %w", err)