mirror of
https://github.com/daeuniverse/dae.git
synced 2024-12-23 01:04: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
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/daeuniverse/dae/cmd/internal"
|
"github.com/daeuniverse/dae/cmd/internal"
|
||||||
"github.com/daeuniverse/dae/common"
|
"github.com/daeuniverse/dae/common"
|
||||||
@ -14,6 +15,7 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@ -238,11 +240,21 @@ func newControlPlane(log *logrus.Logger, bpf interface{}, dnsCache map[string]*c
|
|||||||
// Resolve subscriptions to nodes.
|
// Resolve subscriptions to nodes.
|
||||||
resolvingfailed := false
|
resolvingfailed := false
|
||||||
if !conf.Global.DisableWaitingNetwork && len(conf.Subscription) > 0 {
|
if !conf.Global.DisableWaitingNetwork && len(conf.Subscription) > 0 {
|
||||||
|
epo := 5 * time.Second
|
||||||
|
client := http.Client{
|
||||||
|
Timeout: epo,
|
||||||
|
}
|
||||||
log.Infoln("Waiting for network...")
|
log.Infoln("Waiting for network...")
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
resp, err := http.Get(CheckNetworkLinks[i%len(CheckNetworkLinks)])
|
resp, err := client.Get(CheckNetworkLinks[i%len(CheckNetworkLinks)])
|
||||||
if err != nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
@ -250,7 +262,7 @@ func newControlPlane(log *logrus.Logger, bpf interface{}, dnsCache map[string]*c
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
log.Infof("Bad status: %v (%v)", resp.Status, resp.StatusCode)
|
log.Infof("Bad status: %v (%v)", resp.Status, resp.StatusCode)
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(epo)
|
||||||
}
|
}
|
||||||
log.Infoln("Network online.")
|
log.Infoln("Network online.")
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,7 @@ var (
|
|||||||
CgSocketCookieFeatureVersion = internal.Version{5, 7, 0}
|
CgSocketCookieFeatureVersion = internal.Version{5, 7, 0}
|
||||||
SkAssignFeatureVersion = internal.Version{5, 7, 0}
|
SkAssignFeatureVersion = internal.Version{5, 7, 0}
|
||||||
ChecksumFeatureVersion = internal.Version{5, 8, 0}
|
ChecksumFeatureVersion = internal.Version{5, 8, 0}
|
||||||
|
ProgTypeSkLookupFeatureVersion = internal.Version{5, 9, 0}
|
||||||
UserspaceBatchUpdateLpmTrieFeatureVersion = internal.Version{5, 13, 0}
|
UserspaceBatchUpdateLpmTrieFeatureVersion = internal.Version{5, 13, 0}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,10 +37,13 @@ func TryUpdateSystemDns() (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryUpdateSystemDns1s will update system DNS if 1 second has elapsed since the last TryUpdateSystemDns1s call.
|
// TryUpdateSystemDnsElapse will update system DNS if duration has elapsed since the last TryUpdateSystemDns1s call.
|
||||||
func TryUpdateSystemDns1s() (err error) {
|
func TryUpdateSystemDnsElapse(k time.Duration) (err error) {
|
||||||
systemDnsMu.Lock()
|
systemDnsMu.Lock()
|
||||||
defer systemDnsMu.Unlock()
|
defer systemDnsMu.Unlock()
|
||||||
|
return tryUpdateSystemDnsElapse(k)
|
||||||
|
}
|
||||||
|
func tryUpdateSystemDnsElapse(k time.Duration) (err error) {
|
||||||
if time.Now().Before(systemDnsNextUpdateAfter) {
|
if time.Now().Before(systemDnsNextUpdateAfter) {
|
||||||
return fmt.Errorf("update too quickly")
|
return fmt.Errorf("update too quickly")
|
||||||
}
|
}
|
||||||
@ -48,7 +51,7 @@ func TryUpdateSystemDns1s() (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
systemDnsNextUpdateAfter = time.Now().Add(time.Second)
|
systemDnsNextUpdateAfter = time.Now().Add(k)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +73,8 @@ func SystemDns() (dns netip.AddrPort, err error) {
|
|||||||
return netip.AddrPort{}, err
|
return netip.AddrPort{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// To avoid environment changing.
|
||||||
|
_ = tryUpdateSystemDnsElapse(5 * time.Second)
|
||||||
return systemDns, nil
|
return systemDns, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ func NewUpstream(ctx context.Context, upstream *url.URL) (up *Upstream, err erro
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = netutils.TryUpdateSystemDns1s()
|
_ = netutils.TryUpdateSystemDnsElapse(time.Second)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ func ParseTcpCheckOption(ctx context.Context, rawURL string) (opt *TcpCheckOptio
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = netutils.TryUpdateSystemDns1s()
|
_ = netutils.TryUpdateSystemDnsElapse(time.Second)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ func ParseCheckDnsOption(ctx context.Context, dnsHostPort string) (opt *CheckDns
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = netutils.TryUpdateSystemDns1s()
|
_ = netutils.TryUpdateSystemDnsElapse(time.Second)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -62,6 +62,9 @@ type ControlPlane struct {
|
|||||||
|
|
||||||
muRealDomainSet sync.Mutex
|
muRealDomainSet sync.Mutex
|
||||||
realDomainSet *bloom.BloomFilter
|
realDomainSet *bloom.BloomFilter
|
||||||
|
|
||||||
|
wanInterface []string
|
||||||
|
lanInterface []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewControlPlane(
|
func NewControlPlane(
|
||||||
@ -83,20 +86,20 @@ func NewControlPlane(
|
|||||||
}
|
}
|
||||||
/// Check linux kernel requirements.
|
/// Check linux kernel requirements.
|
||||||
// Check version from high to low to reduce the number of user upgrading kernel.
|
// 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",
|
return nil, fmt.Errorf("your kernel version %v does not support checksum related features; expect >=%v; upgrade your kernel and try again",
|
||||||
kernelVersion.String(),
|
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",
|
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(),
|
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",
|
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(),
|
kernelVersion.String(),
|
||||||
consts.SkAssignFeatureVersion.String())
|
requirement.String())
|
||||||
}
|
}
|
||||||
if kernelVersion.Less(consts.BasicFeatureVersion) {
|
if kernelVersion.Less(consts.BasicFeatureVersion) {
|
||||||
return nil, fmt.Errorf("your kernel version %v does not satisfy basic requirement; expect >=%v",
|
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{}),
|
ready: make(chan struct{}),
|
||||||
muRealDomainSet: sync.Mutex{},
|
muRealDomainSet: sync.Mutex{},
|
||||||
realDomainSet: bloom.NewWithEstimates(2048, 0.001),
|
realDomainSet: bloom.NewWithEstimates(2048, 0.001),
|
||||||
|
lanInterface: global.LanInterface,
|
||||||
|
wanInterface: global.WanInterface,
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -790,20 +795,21 @@ func (c *ControlPlane) chooseBestDnsDialer(
|
|||||||
if bestDialer == nil {
|
if bestDialer == nil {
|
||||||
return nil, fmt.Errorf("no proper dialer for DNS upstream: %v", dnsUpstream.String())
|
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) {
|
if c.log.IsLevelEnabled(logrus.TraceLevel) {
|
||||||
c.log.WithFields(logrus.Fields{
|
c.log.WithFields(logrus.Fields{
|
||||||
"ipversions": ipversions,
|
"ipversions": ipversions,
|
||||||
"l4protos": l4protos,
|
"l4protos": l4protos,
|
||||||
"upstream": dnsUpstream.String(),
|
"upstream": dnsUpstream.String(),
|
||||||
"choose": string(l4proto) + "+" + string(ipversion),
|
"choose": string(l4proto) + "+" + string(ipversion),
|
||||||
|
"use": bestTarget.String(),
|
||||||
}).Traceln("Choose DNS path")
|
}).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{
|
return &dialArgument{
|
||||||
l4proto: l4proto,
|
l4proto: l4proto,
|
||||||
ipversion: ipversion,
|
ipversion: ipversion,
|
||||||
|
@ -409,7 +409,7 @@ func (c *controlPlaneCore) setupSkPidMonitor() error {
|
|||||||
Program: prog.Prog,
|
Program: prog.Prog,
|
||||||
})
|
})
|
||||||
if err != nil {
|
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 {
|
c.deferFuncs = append(c.deferFuncs, func() error {
|
||||||
if err := attached.Close(); err != nil {
|
if err := attached.Close(); err != nil {
|
||||||
|
@ -20,11 +20,6 @@
|
|||||||
// #define __PRINT_SETUP_PROCESS_CONNNECTION
|
// #define __PRINT_SETUP_PROCESS_CONNNECTION
|
||||||
// #define __REMOVE_BPF_PRINTK
|
// #define __REMOVE_BPF_PRINTK
|
||||||
|
|
||||||
#ifdef __REMOVE_BPF_PRINTK
|
|
||||||
#undef bpf_printk
|
|
||||||
#define bpf_printk(...) (void)0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// #define likely(x) x
|
// #define likely(x) x
|
||||||
// #define unlikely(x) x
|
// #define unlikely(x) x
|
||||||
#define likely(x) __builtin_expect((x), 1)
|
#define likely(x) __builtin_expect((x), 1)
|
||||||
@ -41,7 +36,6 @@
|
|||||||
|
|
||||||
#define NOWHERE_IFINDEX 0
|
#define NOWHERE_IFINDEX 0
|
||||||
#define LOOPBACK_IFINDEX 1
|
#define LOOPBACK_IFINDEX 1
|
||||||
#define LOOPBACK_ADDR 0x7f000001
|
|
||||||
|
|
||||||
#define MAX_PARAM_LEN 16
|
#define MAX_PARAM_LEN 16
|
||||||
#define MAX_INTERFACE_NUM 128
|
#define MAX_INTERFACE_NUM 128
|
||||||
@ -1398,16 +1392,16 @@ new_connection:
|
|||||||
// TCP.
|
// TCP.
|
||||||
sk = bpf_map_lookup_elem(&listen_socket_map, &zero_key);
|
sk = bpf_map_lookup_elem(&listen_socket_map, &zero_key);
|
||||||
if (!sk || sk->state != BPF_TCP_LISTEN) {
|
if (!sk || sk->state != BPF_TCP_LISTEN) {
|
||||||
bpf_printk("shot tcp tproxy not listen: %d", ret);
|
bpf_printk("accpet tcp tproxy not listen");
|
||||||
goto sk_shot;
|
goto sk_accept;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// UDP.
|
// UDP.
|
||||||
|
|
||||||
sk = bpf_map_lookup_elem(&listen_socket_map, &one_key);
|
sk = bpf_map_lookup_elem(&listen_socket_map, &one_key);
|
||||||
if (!sk) {
|
if (!sk) {
|
||||||
bpf_printk("shot udp tproxy not listen: %d", ret);
|
bpf_printk("accpet udp tproxy not listen");
|
||||||
goto sk_shot;
|
goto sk_accept;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1427,11 +1421,10 @@ assign:
|
|||||||
}
|
}
|
||||||
return TC_ACT_OK;
|
return TC_ACT_OK;
|
||||||
|
|
||||||
sk_shot:
|
sk_accept:
|
||||||
if (sk) {
|
if (sk) {
|
||||||
bpf_sk_release(sk);
|
bpf_sk_release(sk);
|
||||||
}
|
}
|
||||||
return TC_ACT_SHOT;
|
|
||||||
|
|
||||||
direct:
|
direct:
|
||||||
return TC_ACT_OK;
|
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);
|
// bpf_printk("b start_end: %lu %lu", arg_start + last_slash, arg_start + j);
|
||||||
|
|
||||||
// Update map.
|
// Update map.
|
||||||
if (unlikely(ret = bpf_map_update_elem(&cookie_pid_map, &cookie, &val,
|
if (unlikely(
|
||||||
BPF_NOEXIST))) {
|
ret = bpf_map_update_elem(&cookie_pid_map, &cookie, &val, BPF_ANY))) {
|
||||||
// bpf_printk("setup_mapping_from_sk: failed update map: %d", ret);
|
// bpf_printk("setup_mapping_from_sk: failed update map: %d", ret);
|
||||||
return 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) {
|
static int __always_inline update_map_elem_by_cookie(const __u64 cookie) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((ret = _update_map_elem_by_cookie(cookie))) {
|
if ((ret = _update_map_elem_by_cookie(cookie))) {
|
||||||
// Fallback to only write pid to avoid loop due to packets sent by dae.
|
// Fallback to only write pid to avoid loop due to packets sent by dae.
|
||||||
struct pid_pname val = {0};
|
struct pid_pname val = {0};
|
||||||
@ -2146,7 +2140,7 @@ static int __always_inline update_map_elem_by_cookie(const __u64 cookie) {
|
|||||||
} else {
|
} else {
|
||||||
bpf_printk("failed [retrieve pname]: %u", val.pid);
|
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 ret;
|
||||||
}
|
}
|
||||||
return 0;
|
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
|
## 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.
|
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
|
## External DNS on another machine in LAN
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user