From 26be0202f0938991d0e148cc6d1c63416beb7157 Mon Sep 17 00:00:00 2001 From: mzz2017 <2017@duck.com> Date: Mon, 8 Jan 2024 14:28:37 +0000 Subject: [PATCH 1/3] fix: activate check after listening to avoid the first failure --- control/control_plane.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/control/control_plane.go b/control/control_plane.go index 06d00cb53..584d60b86 100644 --- a/control/control_plane.go +++ b/control/control_plane.go @@ -292,8 +292,6 @@ func NewControlPlane( log.Infof(`Group "%v" node list:`, group.Name) for _, d := range dialers { log.Infoln("\t" + d.Property().Name) - // We only activate check of nodes that have a group. - d.ActivateCheck() } if len(dialers) == 0 { log.Infoln("\t") @@ -555,6 +553,14 @@ func (c *ControlPlane) dnsUpstreamReadyCallback(dnsUpstream *dns.Upstream) (err return nil } +func (c *ControlPlane) ActivateCheck() { + for _, g := range c.outbounds { + for _, d := range g.Dialers { + // We only activate check of nodes that have a group. + d.ActivateCheck() + } + } +} func (c *ControlPlane) ChooseDialTarget(outbound consts.OutboundIndex, dst netip.AddrPort, domain string) (dialTarget string, shouldReroute bool, dialIp bool) { dialMode := consts.DialMode_Ip @@ -751,6 +757,7 @@ func (c *ControlPlane) Serve(readyChan chan<- bool, listener *Listener) (err err }(newBuf, newOob, src) } }() + c.ActivateCheck() <-c.ctx.Done() return nil } From 03458bf579aefd521ba0a884106795a4e7154d9d Mon Sep 17 00:00:00 2001 From: mzz2017 <2017@duck.com> Date: Mon, 8 Jan 2024 14:29:01 +0000 Subject: [PATCH 2/3] docs: update docs to avoid possible dns leaking --- docs/en/README.md | 2 +- docs/zh/README.md | 2 +- example.dae | 35 +++++++++++++++++++++-------------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/docs/en/README.md b/docs/en/README.md index 8d9941196..44cde1b36 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -195,7 +195,7 @@ group { # See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/routing.md for full examples. routing { - pname(NetworkManager, systemd-resolved, dnsmasq) -> must_direct + pname(NetworkManager) -> direct dip(224.0.0.0/3, 'ff00::/8') -> direct ### Write your rules below. diff --git a/docs/zh/README.md b/docs/zh/README.md index 59060212e..8c7eca4df 100644 --- a/docs/zh/README.md +++ b/docs/zh/README.md @@ -189,7 +189,7 @@ group { # 更多的 Routing 样例见 https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/routing.md routing { - pname(NetworkManager, systemd-resolved, dnsmasq) -> must_direct + pname(NetworkManager) -> direct dip(224.0.0.0/3, 'ff00::/8') -> direct ### 以下为自定义规则 diff --git a/example.dae b/example.dae index ab08dd121..148f4adc3 100644 --- a/example.dae +++ b/example.dae @@ -143,20 +143,30 @@ dns { # According to the request of dns query, decide to use which DNS upstream. # Match rules from top to bottom. request { + # Lookup China mainland domains using alidns, otherwise googledns. + qname(geosite:cn) -> alidns # fallback is also called default. - fallback: alidns - } - # According to the response of dns query, decide to accept or re-lookup using another DNS upstream. - # Match rules from top to bottom. - response { - # Trusted upstream. Always accept its result. - upstream(googledns) -> accept - # Possibly polluted, re-lookup using googledns. - ip(geoip:private) && !qname(geosite:cn) -> googledns - # fallback is also called default. - fallback: accept + fallback: googledns } } +# routing { +# # According to the request of dns query, decide to use which DNS upstream. +# # Match rules from top to bottom. +# request { +# # fallback is also called default. +# fallback: alidns +# } +# # According to the response of dns query, decide to accept or re-lookup using another DNS upstream. +# # Match rules from top to bottom. +# response { +# # Trusted upstream. Always accept its result. +# upstream(googledns) -> accept +# # Possibly polluted, re-lookup using googledns. +# ip(geoip:private) && !qname(geosite:cn) -> googledns +# # fallback is also called default. +# fallback: accept +# } +# } } # Node group (outbound). @@ -202,9 +212,6 @@ routing { # WAN. pname(NetworkManager) -> direct - # Bypass DNS stubs. We want to bypass their DNS requests, thus use 'must'. - pname(systemd-resolved, dnsmasq) -> must_direct - # Put it in the front to prevent broadcast, multicast and other packets that should be sent to the LAN from being # forwarded by the proxy. # "dip" means destination IP. From c2fc9d6001a1838083d69a8f7706088810aae588 Mon Sep 17 00:00:00 2001 From: mzz2017 <2017@duck.com> Date: Mon, 8 Jan 2024 15:16:21 +0000 Subject: [PATCH 3/3] chore: refine code --- component/outbound/dialer/connectivity_check.go | 4 ++-- component/outbound/dialer/dialer.go | 7 +++---- component/outbound/dialer_group_test.go | 2 +- component/outbound/filter.go | 2 +- control/control_plane.go | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/component/outbound/dialer/connectivity_check.go b/component/outbound/dialer/connectivity_check.go index 14b6f2b6b..f06212ca2 100644 --- a/component/outbound/dialer/connectivity_check.go +++ b/component/outbound/dialer/connectivity_check.go @@ -272,10 +272,10 @@ type CheckOption struct { func (d *Dialer) ActivateCheck() { d.tickerMu.Lock() defer d.tickerMu.Unlock() - if d.InstanceOption.CheckEnabled { + if d.InstanceOption.DisableCheck || d.checkActivated { return } - d.InstanceOption.CheckEnabled = true + d.checkActivated = true go d.aliveBackground() } diff --git a/component/outbound/dialer/dialer.go b/component/outbound/dialer/dialer.go index 1a8486940..64ef0699c 100644 --- a/component/outbound/dialer/dialer.go +++ b/component/outbound/dialer/dialer.go @@ -35,6 +35,8 @@ type Dialer struct { checkCh chan time.Time ctx context.Context cancel context.CancelFunc + + checkActivated bool } type GlobalOption struct { @@ -48,7 +50,7 @@ type GlobalOption struct { } type InstanceOption struct { - CheckEnabled bool + DisableCheck bool } type Property struct { @@ -78,9 +80,6 @@ func NewDialer(dialer netproxy.Dialer, option *GlobalOption, iOption InstanceOpt ctx: ctx, cancel: cancel, } - if iOption.CheckEnabled { - go d.aliveBackground() - } return d } diff --git a/component/outbound/dialer_group_test.go b/component/outbound/dialer_group_test.go index 4268cc236..65a918dfb 100644 --- a/component/outbound/dialer_group_test.go +++ b/component/outbound/dialer_group_test.go @@ -30,7 +30,7 @@ var log = logger.NewLogger("trace", false, nil) func newDirectDialer(option *dialer.GlobalOption, fullcone bool) *dialer.Dialer { _d, p := dialer.NewDirectDialer(option, true) - d := dialer.NewDialer(_d, option, dialer.InstanceOption{CheckEnabled: false}, p) + d := dialer.NewDialer(_d, option, dialer.InstanceOption{DisableCheck: false}, p) return d } diff --git a/component/outbound/filter.go b/component/outbound/filter.go index 0decc2beb..c87d91970 100644 --- a/component/outbound/filter.go +++ b/component/outbound/filter.go @@ -39,7 +39,7 @@ func NewDialerSetFromLinks(option *dialer.GlobalOption, tagToNodeList map[string } for subscriptionTag, nodes := range tagToNodeList { for _, node := range nodes { - d, err := dialer.NewFromLink(option, dialer.InstanceOption{CheckEnabled: false}, node, subscriptionTag) + d, err := dialer.NewFromLink(option, dialer.InstanceOption{DisableCheck: false}, node, subscriptionTag) if err != nil { option.Log.Infof("failed to parse node: %v", err) continue diff --git a/control/control_plane.go b/control/control_plane.go index 584d60b86..dc4cf8ad6 100644 --- a/control/control_plane.go +++ b/control/control_plane.go @@ -253,9 +253,9 @@ func NewControlPlane( } disableKernelAliveCallback := dialMode != consts.DialMode_Ip _direct, directProperty := dialer.NewDirectDialer(option, true) - direct := dialer.NewDialer(_direct, option, dialer.InstanceOption{CheckEnabled: false}, directProperty) + direct := dialer.NewDialer(_direct, option, dialer.InstanceOption{DisableCheck: true}, directProperty) _block, blockProperty := dialer.NewBlockDialer(option, func() { /*Dialer Outbound*/ }) - block := dialer.NewDialer(_block, option, dialer.InstanceOption{CheckEnabled: false}, blockProperty) + block := dialer.NewDialer(_block, option, dialer.InstanceOption{DisableCheck: true}, blockProperty) outbounds := []*outbound.DialerGroup{ outbound.NewDialerGroup(option, consts.OutboundDirect.String(), []*dialer.Dialer{direct}, []*dialer.Annotation{{}},