Change: ipv6 logic

This commit is contained in:
gVisor bot 2020-06-18 18:11:02 +08:00
parent 84ab3c5708
commit 216116e128
6 changed files with 104 additions and 53 deletions

View file

@ -95,6 +95,8 @@ allow-lan: false
# "[aaaa::a8aa:ff:fe09:57d8]": bind a single IPv6 address
# bind-address: "*"
# ipv6: false # when ipv6 is false, each clash dial with ipv6, but it's not affect the response of the dns server, default is false
# rule / global / direct (default is rule)
mode: rule
@ -133,7 +135,7 @@ experimental:
# dns:
# enable: true # set true to enable dns (default is false)
# ipv6: false # default is false
# ipv6: false # it only affect the dns server response, default is false
# listen: 0.0.0.0:53
# # default-nameserver: # resolve dns nameserver host, should fill pure IP
# # - 114.114.114.114

View file

@ -12,6 +12,10 @@ var (
// DefaultResolver aim to resolve ip
DefaultResolver Resolver
// DisableIPv6 means don't resolve ipv6 host
// default value is true
DisableIPv6 = true
// DefaultHosts aim to resolve hosts
DefaultHosts = trie.New()
)
@ -19,6 +23,7 @@ var (
var (
ErrIPNotFound = errors.New("couldn't find ip")
ErrIPVersion = errors.New("ip version error")
ErrIPv6Disabled = errors.New("ipv6 disabled")
)
type Resolver interface {
@ -63,6 +68,10 @@ func ResolveIPv4(host string) (net.IP, error) {
// ResolveIPv6 with a host, return ipv6
func ResolveIPv6(host string) (net.IP, error) {
if DisableIPv6 {
return nil, ErrIPv6Disabled
}
if node := DefaultHosts.Search(host); node != nil {
if ip := node.Data.(net.IP).To16(); ip != nil {
return ip, nil
@ -102,7 +111,12 @@ func ResolveIP(host string) (net.IP, error) {
}
if DefaultResolver != nil {
if DisableIPv6 {
return DefaultResolver.ResolveIPv4(host)
}
return DefaultResolver.ResolveIP(host)
} else if DisableIPv6 {
return ResolveIPv4(host)
}
ip := net.ParseIP(host)

View file

@ -25,6 +25,15 @@ import (
// General config
type General struct {
Inbound
Controller
Mode T.TunnelMode `json:"mode"`
LogLevel log.LogLevel `json:"log-level"`
IPv6 bool `json:"ipv6"`
}
// Inbound
type Inbound struct {
Port int `json:"port"`
SocksPort int `json:"socks-port"`
RedirPort int `json:"redir-port"`
@ -32,8 +41,10 @@ type General struct {
Authentication []string `json:"authentication"`
AllowLan bool `json:"allow-lan"`
BindAddress string `json:"bind-address"`
Mode T.TunnelMode `json:"mode"`
LogLevel log.LogLevel `json:"log-level"`
}
// Controller
type Controller struct {
ExternalController string `json:"-"`
ExternalUI string `json:"-"`
Secret string `json:"-"`
@ -104,6 +115,7 @@ type RawConfig struct {
BindAddress string `yaml:"bind-address"`
Mode T.TunnelMode `yaml:"mode"`
LogLevel log.LogLevel `yaml:"log-level"`
IPv6 bool `yaml:"ipv6"`
ExternalController string `yaml:"external-controller"`
ExternalUI string `yaml:"external-ui"`
Secret string `yaml:"secret"`
@ -216,18 +228,9 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
}
func parseGeneral(cfg *RawConfig) (*General, error) {
port := cfg.Port
socksPort := cfg.SocksPort
redirPort := cfg.RedirPort
mixedPort := cfg.MixedPort
allowLan := cfg.AllowLan
bindAddress := cfg.BindAddress
externalController := cfg.ExternalController
externalUI := cfg.ExternalUI
secret := cfg.Secret
mode := cfg.Mode
logLevel := cfg.LogLevel
// checkout externalUI exist
if externalUI != "" {
externalUI = C.Path.Resolve(externalUI)
@ -236,20 +239,24 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
}
}
general := &General{
Port: port,
SocksPort: socksPort,
RedirPort: redirPort,
MixedPort: mixedPort,
AllowLan: allowLan,
BindAddress: bindAddress,
Mode: mode,
LogLevel: logLevel,
ExternalController: externalController,
ExternalUI: externalUI,
Secret: secret,
}
return general, nil
return &General{
Inbound: Inbound{
Port: cfg.Port,
SocksPort: cfg.SocksPort,
RedirPort: cfg.RedirPort,
MixedPort: cfg.MixedPort,
AllowLan: cfg.AllowLan,
BindAddress: cfg.BindAddress,
},
Controller: Controller{
ExternalController: cfg.ExternalController,
ExternalUI: cfg.ExternalUI,
Secret: cfg.Secret,
},
Mode: cfg.Mode,
LogLevel: cfg.LogLevel,
IPv6: cfg.IPv6,
}, nil
}
func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[string]provider.ProxyProvider, err error) {

View file

@ -58,9 +58,23 @@ func withFakeIP(fakePool *fakeip.Pool) middleware {
func withResolver(resolver *Resolver) handler {
return func(w D.ResponseWriter, r *D.Msg) {
q := r.Question[0]
// return a empty AAAA msg when ipv6 disabled
if !resolver.ipv6 && q.Qtype == D.TypeAAAA {
msg := &D.Msg{}
msg.Answer = []D.RR{}
msg.SetRcode(r, D.RcodeSuccess)
msg.Authoritative = true
msg.RecursionAvailable = true
w.WriteMsg(msg)
return
}
msg, err := resolver.Exchange(r)
if err != nil {
q := r.Question[0]
log.Debugln("[DNS Server] Exchange %s failed: %v", q.String(), err)
D.HandleFailed(w, r)
return

View file

@ -43,6 +43,7 @@ func ReCreateServer(addr string, resolver *Resolver) error {
if server.Server != nil {
server.Shutdown()
server = &Server{}
address = ""
}

View file

@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"sync"
"github.com/Dreamacro/clash/adapters/provider"
"github.com/Dreamacro/clash/component/auth"
@ -20,6 +21,10 @@ import (
"github.com/Dreamacro/clash/tunnel"
)
var (
mux sync.Mutex
)
// forward compatibility before 1.0
func readRawConfig(path string) ([]byte, error) {
data, err := ioutil.ReadFile(path)
@ -77,10 +82,11 @@ func ParseWithBytes(buf []byte) (*config.Config, error) {
// ApplyConfig dispatch configure to all parts
func ApplyConfig(cfg *config.Config, force bool) {
mux.Lock()
defer mux.Unlock()
updateUsers(cfg.Users)
if force {
updateGeneral(cfg.General)
}
updateGeneral(cfg.General, force)
updateProxies(cfg.Proxies, cfg.Providers)
updateRules(cfg.Rules)
updateDNS(cfg.DNS)
@ -96,6 +102,7 @@ func GetGeneral() *config.General {
}
general := &config.General{
Inbound: config.Inbound{
Port: ports.Port,
SocksPort: ports.SocksPort,
RedirPort: ports.RedirPort,
@ -103,6 +110,7 @@ func GetGeneral() *config.General {
Authentication: authenticator,
AllowLan: P.AllowLan(),
BindAddress: P.BindAddress(),
},
Mode: tunnel.Mode(),
LogLevel: log.Level(),
}
@ -166,9 +174,14 @@ func updateRules(rules []C.Rule) {
tunnel.UpdateRules(rules)
}
func updateGeneral(general *config.General) {
func updateGeneral(general *config.General, force bool) {
log.SetLevel(general.LogLevel)
tunnel.SetMode(general.Mode)
resolver.DisableIPv6 = !general.IPv6
if !force {
return
}
allowLan := general.AllowLan
P.SetAllowLan(allowLan)