mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-22 20:24:40 +07:00
fix: should update system DNS every 5 seconds
This commit is contained in:
parent
648710a40e
commit
85343ac141
18
cmd/run.go
18
cmd/run.go
@ -1,6 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/daeuniverse/dae/cmd/internal"
|
||||
"github.com/daeuniverse/dae/common"
|
||||
@ -14,6 +15,7 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
@ -238,11 +240,21 @@ func newControlPlane(log *logrus.Logger, bpf interface{}, dnsCache map[string]*c
|
||||
// Resolve subscriptions to nodes.
|
||||
resolvingfailed := false
|
||||
if !conf.Global.DisableWaitingNetwork && len(conf.Subscription) > 0 {
|
||||
epo := 5 * time.Second
|
||||
client := http.Client{
|
||||
Timeout: epo,
|
||||
}
|
||||
log.Infoln("Waiting for network...")
|
||||
for i := 0; ; i++ {
|
||||
resp, err := http.Get(CheckNetworkLinks[i%len(CheckNetworkLinks)])
|
||||
resp, err := client.Get(CheckNetworkLinks[i%len(CheckNetworkLinks)])
|
||||
if err != nil {
|
||||
time.Sleep(5 * time.Second)
|
||||
log.Debugln("CheckNetwork:", err)
|
||||
var neterr net.Error
|
||||
if errors.As(err, &neterr) && neterr.Timeout() {
|
||||
// Do not sleep.
|
||||
continue
|
||||
}
|
||||
time.Sleep(epo)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
@ -250,7 +262,7 @@ func newControlPlane(log *logrus.Logger, bpf interface{}, dnsCache map[string]*c
|
||||
break
|
||||
}
|
||||
log.Infof("Bad status: %v (%v)", resp.Status, resp.StatusCode)
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(epo)
|
||||
}
|
||||
log.Infoln("Network online.")
|
||||
}
|
||||
|
@ -139,6 +139,7 @@ var (
|
||||
CgSocketCookieFeatureVersion = internal.Version{5, 7, 0}
|
||||
SkAssignFeatureVersion = internal.Version{5, 7, 0}
|
||||
ChecksumFeatureVersion = internal.Version{5, 8, 0}
|
||||
ProgTypeSkLookupFeatureVersion = internal.Version{5, 9, 0}
|
||||
UserspaceBatchUpdateLpmTrieFeatureVersion = internal.Version{5, 13, 0}
|
||||
)
|
||||
|
||||
|
@ -37,10 +37,13 @@ func TryUpdateSystemDns() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
// TryUpdateSystemDns1s will update system DNS if 1 second has elapsed since the last TryUpdateSystemDns1s call.
|
||||
func TryUpdateSystemDns1s() (err error) {
|
||||
// TryUpdateSystemDnsElapse will update system DNS if duration has elapsed since the last TryUpdateSystemDns1s call.
|
||||
func TryUpdateSystemDnsElapse(k time.Duration) (err error) {
|
||||
systemDnsMu.Lock()
|
||||
defer systemDnsMu.Unlock()
|
||||
return tryUpdateSystemDnsElapse(k)
|
||||
}
|
||||
func tryUpdateSystemDnsElapse(k time.Duration) (err error) {
|
||||
if time.Now().Before(systemDnsNextUpdateAfter) {
|
||||
return fmt.Errorf("update too quickly")
|
||||
}
|
||||
@ -48,7 +51,7 @@ func TryUpdateSystemDns1s() (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
systemDnsNextUpdateAfter = time.Now().Add(time.Second)
|
||||
systemDnsNextUpdateAfter = time.Now().Add(k)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -70,6 +73,8 @@ func SystemDns() (dns netip.AddrPort, err error) {
|
||||
return netip.AddrPort{}, err
|
||||
}
|
||||
}
|
||||
// To avoid environment changing.
|
||||
_ = tryUpdateSystemDnsElapse(5 * time.Second)
|
||||
return systemDns, nil
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ func NewUpstream(ctx context.Context, upstream *url.URL) (up *Upstream, err erro
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = netutils.TryUpdateSystemDns1s()
|
||||
_ = netutils.TryUpdateSystemDnsElapse(time.Second)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -110,7 +110,7 @@ func ParseTcpCheckOption(ctx context.Context, rawURL string) (opt *TcpCheckOptio
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = netutils.TryUpdateSystemDns1s()
|
||||
_ = netutils.TryUpdateSystemDnsElapse(time.Second)
|
||||
}
|
||||
}()
|
||||
|
||||
@ -141,7 +141,7 @@ func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDns
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = netutils.TryUpdateSystemDns1s()
|
||||
_ = netutils.TryUpdateSystemDnsElapse(time.Second)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -62,6 +62,9 @@ type ControlPlane struct {
|
||||
|
||||
muRealDomainSet sync.Mutex
|
||||
realDomainSet *bloom.BloomFilter
|
||||
|
||||
wanInterface []string
|
||||
lanInterface []string
|
||||
}
|
||||
|
||||
func NewControlPlane(
|
||||
@ -83,20 +86,20 @@ func NewControlPlane(
|
||||
}
|
||||
/// Check linux kernel requirements.
|
||||
// Check version from high to low to reduce the number of user upgrading kernel.
|
||||
if kernelVersion.Less(consts.ChecksumFeatureVersion) {
|
||||
if requirement := consts.ChecksumFeatureVersion; kernelVersion.Less(requirement) {
|
||||
return nil, fmt.Errorf("your kernel version %v does not support checksum related features; expect >=%v; upgrade your kernel and try again",
|
||||
kernelVersion.String(),
|
||||
consts.ChecksumFeatureVersion.String())
|
||||
requirement.String())
|
||||
}
|
||||
if len(global.WanInterface) > 0 && kernelVersion.Less(consts.CgSocketCookieFeatureVersion) {
|
||||
if requirement := consts.CgSocketCookieFeatureVersion; len(global.WanInterface) > 0 && kernelVersion.Less(requirement) {
|
||||
return nil, fmt.Errorf("your kernel version %v does not support bind to WAN; expect >=%v; remove wan_interface in config file and try again",
|
||||
kernelVersion.String(),
|
||||
consts.CgSocketCookieFeatureVersion.String())
|
||||
requirement.String())
|
||||
}
|
||||
if len(global.LanInterface) > 0 && kernelVersion.Less(consts.SkAssignFeatureVersion) {
|
||||
if requirement := consts.SkAssignFeatureVersion; len(global.LanInterface) > 0 && kernelVersion.Less(requirement) {
|
||||
return nil, fmt.Errorf("your kernel version %v does not support bind to LAN; expect >=%v; remove lan_interface in config file and try again",
|
||||
kernelVersion.String(),
|
||||
consts.SkAssignFeatureVersion.String())
|
||||
requirement.String())
|
||||
}
|
||||
if kernelVersion.Less(consts.BasicFeatureVersion) {
|
||||
return nil, fmt.Errorf("your kernel version %v does not satisfy basic requirement; expect >=%v",
|
||||
@ -339,6 +342,8 @@ func NewControlPlane(
|
||||
ready: make(chan struct{}),
|
||||
muRealDomainSet: sync.Mutex{},
|
||||
realDomainSet: bloom.NewWithEstimates(2048, 0.001),
|
||||
lanInterface: global.LanInterface,
|
||||
wanInterface: global.WanInterface,
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@ -790,20 +795,21 @@ func (c *ControlPlane) chooseBestDnsDialer(
|
||||
if bestDialer == nil {
|
||||
return nil, fmt.Errorf("no proper dialer for DNS upstream: %v", dnsUpstream.String())
|
||||
}
|
||||
switch ipversion {
|
||||
case consts.IpVersionStr_4:
|
||||
bestTarget = netip.AddrPortFrom(dnsUpstream.Ip4, dnsUpstream.Port)
|
||||
case consts.IpVersionStr_6:
|
||||
bestTarget = netip.AddrPortFrom(dnsUpstream.Ip6, dnsUpstream.Port)
|
||||
}
|
||||
if c.log.IsLevelEnabled(logrus.TraceLevel) {
|
||||
c.log.WithFields(logrus.Fields{
|
||||
"ipversions": ipversions,
|
||||
"l4protos": l4protos,
|
||||
"upstream": dnsUpstream.String(),
|
||||
"choose": string(l4proto) + "+" + string(ipversion),
|
||||
"use": bestTarget.String(),
|
||||
}).Traceln("Choose DNS path")
|
||||
}
|
||||
switch ipversion {
|
||||
case consts.IpVersionStr_4:
|
||||
bestTarget = netip.AddrPortFrom(dnsUpstream.Ip4, dnsUpstream.Port)
|
||||
case consts.IpVersionStr_6:
|
||||
bestTarget = netip.AddrPortFrom(dnsUpstream.Ip6, dnsUpstream.Port)
|
||||
}
|
||||
return &dialArgument{
|
||||
l4proto: l4proto,
|
||||
ipversion: ipversion,
|
||||
|
@ -409,7 +409,7 @@ func (c *controlPlaneCore) setupSkPidMonitor() error {
|
||||
Program: prog.Prog,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("AttachTracing: %v: %w", prog.Prog.String(), err)
|
||||
return fmt.Errorf("AttachCgroup: %v: %w", prog.Prog.String(), err)
|
||||
}
|
||||
c.deferFuncs = append(c.deferFuncs, func() error {
|
||||
if err := attached.Close(); err != nil {
|
||||
|
@ -20,11 +20,6 @@
|
||||
// #define __PRINT_SETUP_PROCESS_CONNNECTION
|
||||
// #define __REMOVE_BPF_PRINTK
|
||||
|
||||
#ifdef __REMOVE_BPF_PRINTK
|
||||
#undef bpf_printk
|
||||
#define bpf_printk(...) (void)0
|
||||
#endif
|
||||
|
||||
// #define likely(x) x
|
||||
// #define unlikely(x) x
|
||||
#define likely(x) __builtin_expect((x), 1)
|
||||
@ -41,7 +36,6 @@
|
||||
|
||||
#define NOWHERE_IFINDEX 0
|
||||
#define LOOPBACK_IFINDEX 1
|
||||
#define LOOPBACK_ADDR 0x7f000001
|
||||
|
||||
#define MAX_PARAM_LEN 16
|
||||
#define MAX_INTERFACE_NUM 128
|
||||
@ -1398,16 +1392,16 @@ new_connection:
|
||||
// TCP.
|
||||
sk = bpf_map_lookup_elem(&listen_socket_map, &zero_key);
|
||||
if (!sk || sk->state != BPF_TCP_LISTEN) {
|
||||
bpf_printk("shot tcp tproxy not listen: %d", ret);
|
||||
goto sk_shot;
|
||||
bpf_printk("accpet tcp tproxy not listen");
|
||||
goto sk_accept;
|
||||
}
|
||||
} else {
|
||||
// UDP.
|
||||
|
||||
sk = bpf_map_lookup_elem(&listen_socket_map, &one_key);
|
||||
if (!sk) {
|
||||
bpf_printk("shot udp tproxy not listen: %d", ret);
|
||||
goto sk_shot;
|
||||
bpf_printk("accpet udp tproxy not listen");
|
||||
goto sk_accept;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1427,11 +1421,10 @@ assign:
|
||||
}
|
||||
return TC_ACT_OK;
|
||||
|
||||
sk_shot:
|
||||
sk_accept:
|
||||
if (sk) {
|
||||
bpf_sk_release(sk);
|
||||
}
|
||||
return TC_ACT_SHOT;
|
||||
|
||||
direct:
|
||||
return TC_ACT_OK;
|
||||
@ -2118,8 +2111,8 @@ static int __always_inline _update_map_elem_by_cookie(const __u64 cookie) {
|
||||
// bpf_printk("b start_end: %lu %lu", arg_start + last_slash, arg_start + j);
|
||||
|
||||
// Update map.
|
||||
if (unlikely(ret = bpf_map_update_elem(&cookie_pid_map, &cookie, &val,
|
||||
BPF_NOEXIST))) {
|
||||
if (unlikely(
|
||||
ret = bpf_map_update_elem(&cookie_pid_map, &cookie, &val, BPF_ANY))) {
|
||||
// bpf_printk("setup_mapping_from_sk: failed update map: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
@ -2133,6 +2126,7 @@ static int __always_inline _update_map_elem_by_cookie(const __u64 cookie) {
|
||||
|
||||
static int __always_inline update_map_elem_by_cookie(const __u64 cookie) {
|
||||
int ret;
|
||||
|
||||
if ((ret = _update_map_elem_by_cookie(cookie))) {
|
||||
// Fallback to only write pid to avoid loop due to packets sent by dae.
|
||||
struct pid_pname val = {0};
|
||||
@ -2146,7 +2140,7 @@ static int __always_inline update_map_elem_by_cookie(const __u64 cookie) {
|
||||
} else {
|
||||
bpf_printk("failed [retrieve pname]: %u", val.pid);
|
||||
}
|
||||
bpf_map_update_elem(&cookie_pid_map, &cookie, &val, BPF_NOEXIST);
|
||||
bpf_map_update_elem(&cookie_pid_map, &cookie, &val, BPF_ANY);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
@ -7,7 +7,7 @@ If you use a external DNS like AdguardHome, you could refer to the following gui
|
||||
|
||||
## External DNS on localhost
|
||||
|
||||
If you set up a external DNS on localhost, you may want to let the DNS queries to dns.google.com proxied. For example, if you have following configuration in AdguardHome:
|
||||
If you set up an external DNS on localhost, you may want to let the DNS queries to dns.google.com proxied. For example, if you have the following configuration in AdguardHome:
|
||||
|
||||
```
|
||||
Listen on: the same machine with dae, port 53.
|
||||
@ -43,11 +43,13 @@ You should configure dae as follows:
|
||||
}
|
||||
```
|
||||
|
||||
4. If you bind to LAN, make sure your DHCP server will distribute dae as the DNS server (DNS request should be forwarded by dae for domain based traffic split).
|
||||
4. If you bind to WAN, make sure your `/etc/resolv.conf` does NOT use your local external DNS directly. For example, you can set it as `nameserver 119.29.29.29`, and then DNS traffic will be hijacked by dae when the packets are sent through NIC. Most of the time, `/etc/resolv.conf` will be modified back by your DNS service like dnsmasq after rebooting, which is hard to deal with. We recommended you to uninstall them or give `sudo chattr +i /etc/resolv.conf` if you encounter such situation.
|
||||
|
||||
5. If there is still a DNS issue and there are no warn/error logs, you have to change your listening port of external DNS (here is AdGuardHome) from 53 to non-53 port. See [#31](https://github.com/daeuniverse/dae/issues/31#issuecomment-1467358364).
|
||||
5. If you bind to LAN, make sure your DHCP server will distribute dae as the DNS server (DNS request should be forwarded by dae for domain based traffic split).
|
||||
|
||||
6. If you use PVE, refer to [#37](https://github.com/daeuniverse/dae/discussions/37).
|
||||
6. If there is still a DNS issue and there are no warn/error logs, you have to change your listening port of external DNS (here is AdGuardHome) from 53 to non-53 port. See [#31](https://github.com/daeuniverse/dae/issues/31#issuecomment-1467358364).
|
||||
|
||||
7. If you use PVE, refer to [#37](https://github.com/daeuniverse/dae/discussions/37).
|
||||
|
||||
## External DNS on another machine in LAN
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user