feat: support to auto detect WAN interface

This commit is contained in:
mzz2017 2023-03-24 13:30:02 +08:00
parent a3bf4e1ebd
commit a04a6be76b
5 changed files with 53 additions and 4 deletions

View File

@ -13,7 +13,9 @@ import (
"encoding/hex"
"fmt"
internal "github.com/daeuniverse/dae/pkg/ebpf_internal"
"github.com/vishvananda/netlink"
"golang.org/x/net/dns/dnsmessage"
"golang.org/x/sys/unix"
"net/netip"
"net/url"
"path/filepath"
@ -68,6 +70,9 @@ func Ipv6Uint32ArrayToByteSlice(_ip [4]uint32) (ip []byte) {
}
func Deduplicate(list []string) []string {
if list == nil {
return nil
}
res := make([]string, 0, len(list))
m := make(map[string]struct{})
for _, v := range list {
@ -415,3 +420,32 @@ func Ntohs(i uint16) uint16 {
bytes := *(*[2]byte)(unsafe.Pointer(&i))
return binary.BigEndian.Uint16(bytes[:])
}
func GetDefaultIfnames() (defaultIfs []string, err error) {
linkList, err := netlink.LinkList()
if err != nil {
return nil, err
}
nextLink:
for _, link := range linkList {
if link.Attrs().Flags&unix.RTF_UP != unix.RTF_UP {
// Interface is down.
continue
}
for _, family := range []int{unix.AF_INET, unix.AF_INET6} {
rs, err := netlink.RouteList(link, family)
if err != nil {
return nil, err
}
for _, route := range rs {
if route.Dst != nil {
continue
}
// Have no dst, it is a default route.
defaultIfs = append(defaultIfs, link.Attrs().Name)
continue nextLink
}
}
}
return Deduplicate(defaultIfs), nil
}

View File

@ -42,7 +42,7 @@ var GlobalDesc = Desc{
"check_interval": "Interval of connectivity check for TCP and UDP",
"check_tolerance": "Group will switch node only when new_latency <= old_latency - tolerance.",
"lan_interface": "The LAN interface to bind. Use it if you only want to proxy LAN instead of localhost.",
"wan_interface": "The WAN interface to bind. Use it if you want to proxy localhost.",
"wan_interface": "The WAN interface to bind. Use it if you want to proxy localhost. Use \"auto\" to auto detect.",
"allow_insecure": "Allow insecure TLS certificates. It is not recommended to turn it on unless you have to.",
"dial_mode": `Optional values of dial_mode are:
1. "ip". Dial proxy using the IP from DNS directly. This allows your ipv4, ipv6 to choose the optimal path respectively, and makes the IP version requested by the application meet expectations. For example, if you use curl -4 ip.sb, you will request IPv4 via proxy and get a IPv4 echo. And curl -6 ip.sb will request IPv6. This may solve some wierd full-cone problem if your are be your node support that.

View File

@ -186,6 +186,7 @@ func NewControlPlane(
if err = core.setupRoutingPolicy(); err != nil {
return nil, err
}
global.LanInterface = common.Deduplicate(global.LanInterface)
for _, ifname := range global.LanInterface {
if err = core.bindLan(ifname); err != nil {
return nil, fmt.Errorf("bindLan: %v: %w", ifname, err)
@ -193,6 +194,20 @@ func NewControlPlane(
}
}
// Bind to WAN
// preprocess "auto".
ifs := make([]string, 0, len(global.WanInterface)+2)
for _, ifname := range global.WanInterface {
if ifname == "auto" {
defaultIfs, err := common.GetDefaultIfnames()
if err != nil {
return nil, fmt.Errorf("failed to convert 'auto': %w", err)
}
ifs = append(ifs, defaultIfs...)
} else {
ifs = append(ifs, ifname)
}
}
global.WanInterface = common.Deduplicate(ifs)
if len(global.WanInterface) > 0 {
if err = core.setupSkPidMonitor(); err != nil {
return nil, err

View File

@ -133,7 +133,7 @@ However, this config leaves dae no-load state. If you want dae to be in working
global {
# Bind to LAN and/or WAN as you want. Replace the interface name to your own.
#lan_interface: docker0
wan_interface: wlp5s0
wan_interface: auto # Use "auto" to auto detect WAN interface.
log_level: info
allow_insecure: false

View File

@ -26,8 +26,8 @@ global {
#lan_interface: docker0
# The WAN interface to bind. Use it if you want to proxy localhost.
# Multiple interfaces split by ",".
wan_interface: wlp5s0
# Multiple interfaces split by ",". Use "auto" to auto detect.
wan_interface: auto
# Allow insecure TLS certificates. It is not recommended to turn it on unless you have to.
allow_insecure: false