feat: support to give fixed ip for tcp_check_url and udp_check_dns

This commit is contained in:
mzz2017
2023-04-29 01:08:46 +08:00
parent 7948ba044c
commit 9493b9a0aa
4 changed files with 60 additions and 17 deletions

View File

@ -321,6 +321,13 @@ func FuzzyDecode(to interface{}, val string) bool {
default: default:
return false return false
} }
case reflect.Slice:
switch v.Interface().(type) {
case []string:
v.Set(reflect.ValueOf(strings.Split(val, ",")))
default:
return false
}
default: default:
return false return false
} }

View File

@ -99,12 +99,28 @@ func (d *Dialer) MustGetAlive(typ *NetworkType) bool {
return d.mustGetCollection(typ).Alive return d.mustGetCollection(typ).Alive
} }
func parseIp46FromList(ip []string) *netutils.Ip46 {
ip46 := new(netutils.Ip46)
for _, ip := range ip {
addr, err := netip.ParseAddr(ip)
if err != nil {
continue
}
if addr.Is4() || addr.Is4In6() {
ip46.Ip4 = addr
} else if addr.Is6() {
ip46.Ip6 = addr
}
}
return ip46
}
type TcpCheckOption struct { type TcpCheckOption struct {
Url *netutils.URL Url *netutils.URL
*netutils.Ip46 *netutils.Ip46
} }
func ParseTcpCheckOption(ctx context.Context, rawURL string) (opt *TcpCheckOption, err error) { func ParseTcpCheckOption(ctx context.Context, rawURL []string) (opt *TcpCheckOption, err error) {
systemDns, err := netutils.SystemDns() systemDns, err := netutils.SystemDns()
if err != nil { if err != nil {
return nil, err return nil, err
@ -115,14 +131,22 @@ func ParseTcpCheckOption(ctx context.Context, rawURL string) (opt *TcpCheckOptio
} }
}() }()
u, err := url.Parse(rawURL) if len(rawURL) == 0 {
return nil, fmt.Errorf("ParseTcpCheckOption: bad format: empty")
}
u, err := url.Parse(rawURL[0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, u.Hostname(), false, false) var ip46 *netutils.Ip46
if len(rawURL) > 1 {
ip46 = parseIp46FromList(rawURL[1:])
} else {
ip46, err = netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, u.Hostname(), false, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
return &TcpCheckOption{ return &TcpCheckOption{
Url: &netutils.URL{URL: u}, Url: &netutils.URL{URL: u},
Ip46: ip46, Ip46: ip46,
@ -135,7 +159,7 @@ type CheckDnsOption struct {
*netutils.Ip46 *netutils.Ip46
} }
func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDnsOption, err error) { func ParseCheckDnsOption(ctx context.Context, dnsHostPort []string) (opt *CheckDnsOption, err error) {
systemDns, err := netutils.SystemDns() systemDns, err := netutils.SystemDns()
if err != nil { if err != nil {
return nil, err return nil, err
@ -146,7 +170,11 @@ func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDns
} }
}() }()
host, _port, err := net.SplitHostPort(dnsHostPort) if len(dnsHostPort) == 0 {
return nil, fmt.Errorf("ParseCheckDnsOption: bad format: empty")
}
host, _port, err := net.SplitHostPort(dnsHostPort[0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -154,10 +182,15 @@ func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDns
if err != nil { if err != nil {
return nil, fmt.Errorf("bad port: %v", err) return nil, fmt.Errorf("bad port: %v", err)
} }
ip46, err := netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, host, false, false) var ip46 *netutils.Ip46
if len(dnsHostPort) > 1 {
ip46 = parseIp46FromList(dnsHostPort[1:])
} else {
ip46, err = netutils.ResolveIp46(ctx, direct.SymmetricDirect, systemDns, host, false, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
return &CheckDnsOption{ return &CheckDnsOption{
DnsHost: host, DnsHost: host,
DnsPort: uint16(port), DnsPort: uint16(port),
@ -169,7 +202,7 @@ type TcpCheckOptionRaw struct {
opt *TcpCheckOption opt *TcpCheckOption
mu sync.Mutex mu sync.Mutex
Log *logrus.Logger Log *logrus.Logger
Raw string Raw []string
} }
func (c *TcpCheckOptionRaw) Option() (opt *TcpCheckOption, err error) { func (c *TcpCheckOptionRaw) Option() (opt *TcpCheckOption, err error) {
@ -191,7 +224,7 @@ func (c *TcpCheckOptionRaw) Option() (opt *TcpCheckOption, err error) {
type CheckDnsOptionRaw struct { type CheckDnsOptionRaw struct {
opt *CheckDnsOption opt *CheckDnsOption
mu sync.Mutex mu sync.Mutex
Raw string Raw []string
} }
func (c *CheckDnsOptionRaw) Option() (opt *CheckDnsOption, err error) { func (c *CheckDnsOptionRaw) Option() (opt *CheckDnsOption, err error) {

View File

@ -18,8 +18,8 @@ type Global struct {
LogLevel string `mapstructure:"log_level" default:"info"` LogLevel string `mapstructure:"log_level" default:"info"`
// We use DirectTcpCheckUrl to check (tcp)*(ipv4/ipv6) connectivity for direct. // We use DirectTcpCheckUrl to check (tcp)*(ipv4/ipv6) connectivity for direct.
//DirectTcpCheckUrl string `mapstructure:"direct_tcp_check_url" default:"http://www.qualcomm.cn/generate_204"` //DirectTcpCheckUrl string `mapstructure:"direct_tcp_check_url" default:"http://www.qualcomm.cn/generate_204"`
TcpCheckUrl string `mapstructure:"tcp_check_url" default:"http://keep-alv.google.com/generate_204"` TcpCheckUrl []string `mapstructure:"tcp_check_url" default:"http://cp.cloudflare.com,1.1.1.1,2606:4700:4700::1111"`
UdpCheckDns string `mapstructure:"udp_check_dns" default:"dns.google.com:53"` UdpCheckDns []string `mapstructure:"udp_check_dns" default:"dns.google.com:53,8.8.8.8,2001:4860:4860::8888"`
CheckInterval time.Duration `mapstructure:"check_interval" default:"30s"` CheckInterval time.Duration `mapstructure:"check_interval" default:"30s"`
CheckTolerance time.Duration `mapstructure:"check_tolerance" default:"0"` CheckTolerance time.Duration `mapstructure:"check_tolerance" default:"0"`
LanInterface []string `mapstructure:"lan_interface"` LanInterface []string `mapstructure:"lan_interface"`

View File

@ -8,14 +8,17 @@ global {
# Node connectivity check. # Node connectivity check.
# Host of URL should have both IPv4 and IPv6 if you have double stack in local. # Host of URL should have both IPv4 and IPv6 if you have double stack in local.
# First is URL, others are IP addresses if given.
# Considering traffic consumption, it is recommended to choose a site with anycast IP and less response. # Considering traffic consumption, it is recommended to choose a site with anycast IP and less response.
#tcp_check_url: 'http://keep-alv.google.com/generate_204' #tcp_check_url: 'http://cp.cloudflare.com'
tcp_check_url: 'http://gstatic.com/generate_204' tcp_check_url: 'http://cp.cloudflare.com,1.1.1.1,2606:4700:4700::1111'
# This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check # This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check
# TCP DNS connectivity of nodes. # TCP DNS connectivity of nodes.
# First is URL, others are IP addresses if given.
# This DNS should have both IPv4 and IPv6 if you have double stack in local. # This DNS should have both IPv4 and IPv6 if you have double stack in local.
udp_check_dns: 'dns.google.com:53' #udp_check_dns: 'dns.google.com:53'
udp_check_dns: 'dns.google.com:53,8.8.8.8,2001:4860:4860::8888'
check_interval: 30s check_interval: 30s