mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-23 01:14:46 +07:00
feat: allow tcp_check_url and udp_check_dns are not double stack
This commit is contained in:
parent
affb49d85b
commit
0b5263c89b
@ -7,7 +7,6 @@ package netutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"golang.org/x/net/proxy"
|
||||
"net/netip"
|
||||
@ -18,28 +17,20 @@ type Ip46 struct {
|
||||
Ip6 netip.Addr
|
||||
}
|
||||
|
||||
func ParseIp46(ctx context.Context, dialer proxy.Dialer, dns netip.AddrPort, host string, must46 bool, tcp bool) (ipv46 *Ip46, err error) {
|
||||
func ParseIp46(ctx context.Context, dialer proxy.Dialer, dns netip.AddrPort, host string, tcp bool) (ipv46 *Ip46, err error) {
|
||||
addrs4, err := ResolveNetip(ctx, dialer, dns, host, dnsmessage.TypeA, tcp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(addrs4) == 0 && must46 {
|
||||
if must46 {
|
||||
return nil, fmt.Errorf("domain \"%v\" has no ipv4 record", host)
|
||||
} else {
|
||||
addrs4 = []netip.Addr{{}}
|
||||
}
|
||||
if len(addrs4) == 0 {
|
||||
addrs4 = []netip.Addr{{}}
|
||||
}
|
||||
addrs6, err := ResolveNetip(ctx, dialer, dns, host, dnsmessage.TypeAAAA, tcp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(addrs6) == 0 {
|
||||
if must46 {
|
||||
return nil, fmt.Errorf("domain \"%v\" has no ipv6 record", host)
|
||||
} else {
|
||||
addrs6 = []netip.Addr{{}}
|
||||
}
|
||||
addrs6 = []netip.Addr{{}}
|
||||
}
|
||||
return &Ip46{
|
||||
Ip4: addrs4[0],
|
||||
|
@ -115,7 +115,7 @@ func ParseTcpCheckOption(ctx context.Context, rawURL string) (opt *TcpCheckOptio
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ip46, err := netutils.ParseIp46(ctx, SymmetricDirect, systemDns, u.Hostname(), true, false)
|
||||
ip46, err := netutils.ParseIp46(ctx, SymmetricDirect, systemDns, u.Hostname(), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -150,7 +150,7 @@ func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDns
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad port: %v", err)
|
||||
}
|
||||
ip46, err := netutils.ParseIp46(ctx, SymmetricDirect, systemDns, host, true, false)
|
||||
ip46, err := netutils.ParseIp46(ctx, SymmetricDirect, systemDns, host, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -205,7 +205,7 @@ func (c *CheckDnsOptionRaw) Option() (opt *CheckDnsOption, err error) {
|
||||
|
||||
type CheckOption struct {
|
||||
networkType *NetworkType
|
||||
CheckFunc func(ctx context.Context) (ok bool, err error)
|
||||
CheckFunc func(ctx context.Context, typ *NetworkType) (ok bool, err error)
|
||||
}
|
||||
|
||||
func (d *Dialer) ActivateCheck() {
|
||||
@ -227,11 +227,18 @@ func (d *Dialer) aliveBackground() {
|
||||
IpVersion: consts.IpVersionStr_4,
|
||||
IsDns: false,
|
||||
},
|
||||
CheckFunc: func(ctx context.Context) (ok bool, err error) {
|
||||
CheckFunc: func(ctx context.Context, typ *NetworkType) (ok bool, err error) {
|
||||
opt, err := d.TcpCheckOptionRaw.Option()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !opt.Ip4.IsValid() {
|
||||
d.Log.WithFields(logrus.Fields{
|
||||
"link": d.TcpCheckOptionRaw.Raw,
|
||||
"network": typ.String(),
|
||||
}).Debugln("Skip check due to no record.")
|
||||
return false, nil
|
||||
}
|
||||
return d.HttpCheck(ctx, opt.Url, opt.Ip4)
|
||||
},
|
||||
}
|
||||
@ -241,11 +248,18 @@ func (d *Dialer) aliveBackground() {
|
||||
IpVersion: consts.IpVersionStr_6,
|
||||
IsDns: false,
|
||||
},
|
||||
CheckFunc: func(ctx context.Context) (ok bool, err error) {
|
||||
CheckFunc: func(ctx context.Context, typ *NetworkType) (ok bool, err error) {
|
||||
opt, err := d.TcpCheckOptionRaw.Option()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !opt.Ip6.IsValid() {
|
||||
d.Log.WithFields(logrus.Fields{
|
||||
"link": d.TcpCheckOptionRaw.Raw,
|
||||
"network": typ.String(),
|
||||
}).Debugln("Skip check due to no record.")
|
||||
return false, nil
|
||||
}
|
||||
return d.HttpCheck(ctx, opt.Url, opt.Ip6)
|
||||
},
|
||||
}
|
||||
@ -255,11 +269,18 @@ func (d *Dialer) aliveBackground() {
|
||||
IpVersion: consts.IpVersionStr_4,
|
||||
IsDns: true,
|
||||
},
|
||||
CheckFunc: func(ctx context.Context) (ok bool, err error) {
|
||||
CheckFunc: func(ctx context.Context, typ *NetworkType) (ok bool, err error) {
|
||||
opt, err := d.CheckDnsOptionRaw.Option()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !opt.Ip4.IsValid() {
|
||||
d.Log.WithFields(logrus.Fields{
|
||||
"link": d.CheckDnsOptionRaw.Raw,
|
||||
"network": typ.String(),
|
||||
}).Debugln("Skip check due to no record.")
|
||||
return false, nil
|
||||
}
|
||||
return d.DnsCheck(ctx, netip.AddrPortFrom(opt.Ip4, opt.DnsPort), true)
|
||||
},
|
||||
}
|
||||
@ -269,11 +290,18 @@ func (d *Dialer) aliveBackground() {
|
||||
IpVersion: consts.IpVersionStr_6,
|
||||
IsDns: true,
|
||||
},
|
||||
CheckFunc: func(ctx context.Context) (ok bool, err error) {
|
||||
CheckFunc: func(ctx context.Context, typ *NetworkType) (ok bool, err error) {
|
||||
opt, err := d.CheckDnsOptionRaw.Option()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !opt.Ip6.IsValid() {
|
||||
d.Log.WithFields(logrus.Fields{
|
||||
"link": d.CheckDnsOptionRaw.Raw,
|
||||
"network": typ.String(),
|
||||
}).Debugln("Skip check due to no record.")
|
||||
return false, nil
|
||||
}
|
||||
return d.DnsCheck(ctx, netip.AddrPortFrom(opt.Ip6, opt.DnsPort), true)
|
||||
},
|
||||
}
|
||||
@ -283,11 +311,18 @@ func (d *Dialer) aliveBackground() {
|
||||
IpVersion: consts.IpVersionStr_4,
|
||||
IsDns: true,
|
||||
},
|
||||
CheckFunc: func(ctx context.Context) (ok bool, err error) {
|
||||
CheckFunc: func(ctx context.Context, typ *NetworkType) (ok bool, err error) {
|
||||
opt, err := d.CheckDnsOptionRaw.Option()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !opt.Ip4.IsValid() {
|
||||
d.Log.WithFields(logrus.Fields{
|
||||
"link": d.CheckDnsOptionRaw.Raw,
|
||||
"network": typ.String(),
|
||||
}).Debugln("Skip check due to no record.")
|
||||
return false, nil
|
||||
}
|
||||
return d.DnsCheck(ctx, netip.AddrPortFrom(opt.Ip4, opt.DnsPort), false)
|
||||
},
|
||||
}
|
||||
@ -297,11 +332,18 @@ func (d *Dialer) aliveBackground() {
|
||||
IpVersion: consts.IpVersionStr_6,
|
||||
IsDns: true,
|
||||
},
|
||||
CheckFunc: func(ctx context.Context) (ok bool, err error) {
|
||||
CheckFunc: func(ctx context.Context, typ *NetworkType) (ok bool, err error) {
|
||||
opt, err := d.CheckDnsOptionRaw.Option()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !opt.Ip6.IsValid() {
|
||||
d.Log.WithFields(logrus.Fields{
|
||||
"link": d.CheckDnsOptionRaw.Raw,
|
||||
"network": typ.String(),
|
||||
}).Debugln("Skip check due to no record.")
|
||||
return false, nil
|
||||
}
|
||||
return d.DnsCheck(ctx, netip.AddrPortFrom(opt.Ip6, opt.DnsPort), false)
|
||||
},
|
||||
}
|
||||
@ -401,7 +443,7 @@ func (d *Dialer) Check(timeout time.Duration,
|
||||
start := time.Now()
|
||||
// Calc latency.
|
||||
collection := d.mustGetCollection(opts.networkType)
|
||||
if ok, err = opts.CheckFunc(ctx); ok && err == nil {
|
||||
if ok, err = opts.CheckFunc(ctx, opts.networkType); ok && err == nil {
|
||||
// No error.
|
||||
latency := time.Since(start)
|
||||
latencies10 := d.mustGetCollection(opts.networkType).Latencies10
|
||||
|
@ -79,7 +79,7 @@ func ResolveDnsUpstream(ctx context.Context, dnsUpstream *url.URL) (up *DnsUpstr
|
||||
}
|
||||
}()
|
||||
|
||||
ip46, err := netutils.ParseIp46(ctx, dialer.SymmetricDirect, systemDns, hostname, false, false)
|
||||
ip46, err := netutils.ParseIp46(ctx, dialer.SymmetricDirect, systemDns, hostname, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve dns_upstream: %w", err)
|
||||
}
|
||||
|
@ -1195,7 +1195,6 @@ int tproxy_lan_egress(struct __sk_buff *skb) {
|
||||
if (*tproxy_port != tuples.src.port) {
|
||||
return TC_ACT_PIPE;
|
||||
}
|
||||
bpf_printk("SAME");
|
||||
|
||||
struct ip_port_outbound ori_src;
|
||||
if ((ret = decap_after_udp_hdr(skb, ipversion, ihl,
|
||||
@ -1969,8 +1968,12 @@ static int __always_inline update_map_elem_by_cookie(const __u64 cookie) {
|
||||
bpf_printk("zero cookie");
|
||||
return -EINVAL;
|
||||
}
|
||||
int ret;
|
||||
if (bpf_map_lookup_elem(&cookie_pid_map, &cookie)) {
|
||||
// Cookie to pid mapping already exists.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret;
|
||||
// Build value.
|
||||
struct pid_pname val;
|
||||
__builtin_memset(&val, 0, sizeof(struct pid_pname));
|
||||
|
@ -10,9 +10,9 @@ global {
|
||||
# Host of URL should have both IPv4 and IPv6 if you have double stack in local.
|
||||
tcp_check_url: 'http://cp.cloudflare.com'
|
||||
|
||||
# This DNS will be used to check UDP connectivity. 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.
|
||||
# Host of 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:53'
|
||||
|
||||
check_interval: 30s
|
||||
@ -93,7 +93,8 @@ group {
|
||||
|
||||
# See routing.md for full examples.
|
||||
routing {
|
||||
ip(geoip:private, 224.0.0.0/3, 'ff00::/8') -> direct # Put it first unless you know what you're doing.
|
||||
pname(dnsmasq, systemd-resolved) -> must_direct # Traffic of DNS in local must be direct to avoid loop when binding to WAN.
|
||||
ip(geoip:private, 224.0.0.0/3, 'ff00::/8') -> direct # Put it in front unless you know what you're doing.
|
||||
# Write your rules below.
|
||||
|
||||
# dae arms DNS rush-answer filter so we can use dns.google regardless of DNS pollution.
|
||||
|
Loading…
Reference in New Issue
Block a user