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 # "[aaaa::a8aa:ff:fe09:57d8]": bind a single IPv6 address
# bind-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) # rule / global / direct (default is rule)
mode: rule mode: rule
@ -133,7 +135,7 @@ experimental:
# dns: # dns:
# enable: true # set true to enable dns (default is false) # 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 # listen: 0.0.0.0:53
# # default-nameserver: # resolve dns nameserver host, should fill pure IP # # default-nameserver: # resolve dns nameserver host, should fill pure IP
# # - 114.114.114.114 # # - 114.114.114.114

View file

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

View file

@ -25,18 +25,29 @@ import (
// General config // General config
type General struct { type General struct {
Port int `json:"port"` Inbound
SocksPort int `json:"socks-port"` Controller
RedirPort int `json:"redir-port"` Mode T.TunnelMode `json:"mode"`
MixedPort int `json:"mixed-port"` LogLevel log.LogLevel `json:"log-level"`
Authentication []string `json:"authentication"` IPv6 bool `json:"ipv6"`
AllowLan bool `json:"allow-lan"` }
BindAddress string `json:"bind-address"`
Mode T.TunnelMode `json:"mode"` // Inbound
LogLevel log.LogLevel `json:"log-level"` type Inbound struct {
ExternalController string `json:"-"` Port int `json:"port"`
ExternalUI string `json:"-"` SocksPort int `json:"socks-port"`
Secret string `json:"-"` RedirPort int `json:"redir-port"`
MixedPort int `json:"mixed-port"`
Authentication []string `json:"authentication"`
AllowLan bool `json:"allow-lan"`
BindAddress string `json:"bind-address"`
}
// Controller
type Controller struct {
ExternalController string `json:"-"`
ExternalUI string `json:"-"`
Secret string `json:"-"`
} }
// DNS config // DNS config
@ -104,6 +115,7 @@ type RawConfig struct {
BindAddress string `yaml:"bind-address"` BindAddress string `yaml:"bind-address"`
Mode T.TunnelMode `yaml:"mode"` Mode T.TunnelMode `yaml:"mode"`
LogLevel log.LogLevel `yaml:"log-level"` LogLevel log.LogLevel `yaml:"log-level"`
IPv6 bool `yaml:"ipv6"`
ExternalController string `yaml:"external-controller"` ExternalController string `yaml:"external-controller"`
ExternalUI string `yaml:"external-ui"` ExternalUI string `yaml:"external-ui"`
Secret string `yaml:"secret"` Secret string `yaml:"secret"`
@ -216,18 +228,9 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
} }
func parseGeneral(cfg *RawConfig) (*General, 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 externalUI := cfg.ExternalUI
secret := cfg.Secret
mode := cfg.Mode
logLevel := cfg.LogLevel
// checkout externalUI exist
if externalUI != "" { if externalUI != "" {
externalUI = C.Path.Resolve(externalUI) externalUI = C.Path.Resolve(externalUI)
@ -236,20 +239,24 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
} }
} }
general := &General{ return &General{
Port: port, Inbound: Inbound{
SocksPort: socksPort, Port: cfg.Port,
RedirPort: redirPort, SocksPort: cfg.SocksPort,
MixedPort: mixedPort, RedirPort: cfg.RedirPort,
AllowLan: allowLan, MixedPort: cfg.MixedPort,
BindAddress: bindAddress, AllowLan: cfg.AllowLan,
Mode: mode, BindAddress: cfg.BindAddress,
LogLevel: logLevel, },
ExternalController: externalController, Controller: Controller{
ExternalUI: externalUI, ExternalController: cfg.ExternalController,
Secret: secret, ExternalUI: cfg.ExternalUI,
} Secret: cfg.Secret,
return general, nil },
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) { 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 { func withResolver(resolver *Resolver) handler {
return func(w D.ResponseWriter, r *D.Msg) { 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) msg, err := resolver.Exchange(r)
if err != nil { if err != nil {
q := r.Question[0]
log.Debugln("[DNS Server] Exchange %s failed: %v", q.String(), err) log.Debugln("[DNS Server] Exchange %s failed: %v", q.String(), err)
D.HandleFailed(w, r) D.HandleFailed(w, r)
return return

View file

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

View file

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