Use net.Dial to test if bind address is available

This commit is contained in:
iBug 2023-01-11 12:35:49 +08:00
parent cb0201de6e
commit 4879fff292
1 changed files with 15 additions and 17 deletions

View File

@ -352,14 +352,8 @@ func prepareTunnelConfig(
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if ok, err := isIPHostLocal(edgeBindAddr); !ok { if err := testIPBindable(edgeBindAddr); err != nil {
if err != nil { return nil, nil, fmt.Errorf("invalid edge-bind-address %s: %v", edgeBindAddr, err)
// There could be unforeseen reasons that net.InterfaceAddrs() may fail
// Better not to be fatal here, or it could be annoying for users
log.Warn().Msgf("Cannot determine if edge-bind-address is available: %v", err)
} else {
return nil, nil, fmt.Errorf("edge-bind-address is not local to this host: %s", edgeBindAddr)
}
} }
edgeIPVersion, err = adjustIPVersionByBindAddress(edgeIPVersion, edgeBindAddr) edgeIPVersion, err = adjustIPVersionByBindAddress(edgeIPVersion, edgeBindAddr)
if err != nil { if err != nil {
@ -494,17 +488,21 @@ func parseConfigBindAddress(ipstr string) (net.IP, error) {
return ip, nil return ip, nil
} }
func isIPHostLocal(ip net.IP) (bool, error) { func testIPBindable(ip net.IP) error {
addrs, err := net.InterfaceAddrs() var network, address string
if ip.To4() != nil {
network, address = "udp4", "127.0.0.1:4"
} else {
network, address = "udp6", "[::1]:4"
}
dialer := net.Dialer{LocalAddr: &net.UDPAddr{IP: ip}}
conn, err := dialer.Dial(network, address)
if err != nil { if err != nil {
return false, err return err
} }
for _, addr := range addrs { conn.Close()
if ip.Equal(addr.(*net.IPNet).IP) { return nil
return true, nil
}
}
return false, nil
} }
func adjustIPVersionByBindAddress(ipVersion allregions.ConfigIPVersion, ip net.IP) (allregions.ConfigIPVersion, error) { func adjustIPVersionByBindAddress(ipVersion allregions.ConfigIPVersion, ip net.IP) (allregions.ConfigIPVersion, error) {