diff --git a/controllers/node_grpc.go b/controllers/node_grpc.go index e30f0142..f14439e0 100644 --- a/controllers/node_grpc.go +++ b/controllers/node_grpc.go @@ -182,14 +182,15 @@ func getServerAddrs(node *models.Node) { } } - var serverAddrs = make([]models.ServerAddr, 1) + var serverAddrs = make([]models.ServerAddr, 0) for _, node := range serverNodes { - - serverAddrs = append(serverAddrs, models.ServerAddr{ - IsLeader: logic.IsLeader(&node), - Address: node.Address, - }) + if node.Address != "" { + serverAddrs = append(serverAddrs, models.ServerAddr{ + IsLeader: logic.IsLeader(&node), + Address: node.Address, + }) + } } networkSettings, _ := logic.GetParentNetwork(node.Network) diff --git a/logic/networks.go b/logic/networks.go index 2936299e..8bf5c2ea 100644 --- a/logic/networks.go +++ b/logic/networks.go @@ -752,7 +752,7 @@ func isInterfacePresent(iface string, address string) (string, bool) { } for _, addr := range currAddrs { if strings.Contains(addr.String(), address) && currIface.Name != iface { - logger.Log(2, "found iface", addr.String(), currIface.Name) + // logger.Log(2, "found iface", addr.String(), currIface.Name) interfaces = nil currAddrs = nil return currIface.Name, false @@ -761,6 +761,6 @@ func isInterfacePresent(iface string, address string) (string, bool) { currAddrs = nil } interfaces = nil - logger.Log(2, "failed to find iface", iface) + // logger.Log(2, "failed to find iface", iface) return "", true } diff --git a/netclient/auth/auth.go b/netclient/auth/auth.go index 35793831..89ce035b 100644 --- a/netclient/auth/auth.go +++ b/netclient/auth/auth.go @@ -21,13 +21,13 @@ import ( // SetJWT func will used to create the JWT while signing in and signing out func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, error) { home := ncutils.GetNetclientPathSpecific() - tokentext, err := os.ReadFile(home + "nettoken-" + network) + tokentext, err := ncutils.GetFileWithRetry(home+"nettoken-"+network, 1) if err != nil { err = AutoLogin(client, network) if err != nil { return nil, status.Errorf(codes.Unauthenticated, fmt.Sprintf("Something went wrong with Auto Login: %v", err)) } - tokentext, err = os.ReadFile(home + "nettoken-" + network) + tokentext, err = ncutils.GetFileWithRetry(home+"nettoken-"+network, 1) if err != nil { return nil, status.Errorf(codes.Unauthenticated, fmt.Sprintf("Something went wrong: %v", err)) } @@ -88,7 +88,7 @@ func StoreSecret(key string, network string) error { // RetrieveSecret - fetches secret locally func RetrieveSecret(network string) (string, error) { - dat, err := os.ReadFile(ncutils.GetNetclientPathSpecific() + "secret-" + network) + dat, err := ncutils.GetFileWithRetry(ncutils.GetNetclientPathSpecific()+"secret-"+network, 3) return string(dat), err } @@ -103,7 +103,7 @@ func StoreTrafficKey(key *[32]byte, network string) error { // RetrieveTrafficKey - reads traffic file locally func RetrieveTrafficKey(network string) (*[32]byte, error) { - data, err := os.ReadFile(ncutils.GetNetclientPathSpecific() + "traffic-" + network) + data, err := ncutils.GetFileWithRetry(ncutils.GetNetclientPathSpecific()+"traffic-"+network, 2) if err != nil { return nil, err } diff --git a/netclient/config/config.go b/netclient/config/config.go index 4c409660..1943c0f6 100644 --- a/netclient/config/config.go +++ b/netclient/config/config.go @@ -68,7 +68,7 @@ func Write(config *ClientConfig, network string) error { if err != nil { return err } - return err + return f.Sync() } // ClientConfig.ReadConfig - used to read config from client disk into memory @@ -109,7 +109,6 @@ func ModConfig(node *models.Node) error { return errors.New("no network provided") } var modconfig ClientConfig - var err error if FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network) { useconfig, err := ReadConfig(network) if err != nil { @@ -120,8 +119,7 @@ func ModConfig(node *models.Node) error { modconfig.Node = (*node) modconfig.NetworkSettings = node.NetworkSettings - err = Write(&modconfig, network) - return err + return Write(&modconfig, network) } // ModConfig - overwrites the node inside client config on disk diff --git a/netclient/functions/daemon.go b/netclient/functions/daemon.go index 93702b76..2a59c0dc 100644 --- a/netclient/functions/daemon.go +++ b/netclient/functions/daemon.go @@ -299,10 +299,9 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) { return } if newNode.DNSOn == "yes" { - ncutils.Log("setting up DNS") - for _, server := range cfg.Node.NetworkSettings.DefaultServerAddrs { + for _, server := range newNode.NetworkSettings.DefaultServerAddrs { if server.IsLeader { - go setDNS(cfg.Node.Interface, cfg.Network, server.Address) + go local.SetDNSWithRetry(newNode.Interface, newNode.Network, server.Address) break } } @@ -581,19 +580,6 @@ func decryptMsg(cfg *config.ClientConfig, msg []byte) ([]byte, error) { return ncutils.BoxDecrypt(msg, serverPubKey, diskKey) } -func setDNS(iface, network, address string) { - var reachable bool - for counter := 0; !reachable && counter < 5; counter++ { - reachable = local.IsDNSReachable(address) - time.Sleep(time.Second << 1) - } - if !reachable { - ncutils.Log("not setting dns, server unreachable: " + address) - } else if err := local.UpdateDNS(iface, network, address); err != nil { - ncutils.Log("error applying dns" + err.Error()) - } -} - func pingServer(cfg *config.ClientConfig) error { node := getServerAddress(cfg) pinger, err := ping.NewPinger(node) diff --git a/netclient/functions/join.go b/netclient/functions/join.go index 0cf07728..2224f3f3 100644 --- a/netclient/functions/join.go +++ b/netclient/functions/join.go @@ -68,13 +68,12 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error { cfg.Node.TrafficKeys.Server = nil // == end handle keys == - if cfg.Node.LocalRange != "" && cfg.Node.LocalAddress == "" { - log.Println("local vpn, getting local address from range: " + cfg.Node.LocalRange) - cfg.Node.LocalAddress = getLocalIP(cfg.Node) - } else if cfg.Node.LocalAddress == "" { + if cfg.Node.LocalAddress == "" { intIP, err := getPrivateAddr() if err == nil { cfg.Node.LocalAddress = intIP + } else { + ncutils.PrintLog("error retrieving private address: "+err.Error(), 1) } } @@ -237,6 +236,14 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error { if err != nil { return err } + if node.DNSOn == "yes" { + for _, server := range node.NetworkSettings.DefaultServerAddrs { + if server.IsLeader { + go local.SetDNSWithRetry(node.Interface, node.Network, server.Address) + break + } + } + } if cfg.Daemon != "off" { err = daemon.InstallDaemon(cfg) } diff --git a/netclient/local/dns.go b/netclient/local/dns.go index 4dc10359..2b33fbfe 100644 --- a/netclient/local/dns.go +++ b/netclient/local/dns.go @@ -16,6 +16,19 @@ import ( const DNS_UNREACHABLE_ERROR = "nameserver unreachable" +func SetDNSWithRetry(iface, network, address string) { + var reachable bool + for counter := 0; !reachable && counter < 5; counter++ { + reachable = IsDNSReachable(address) + time.Sleep(time.Second << 1) + } + if !reachable { + ncutils.Log("not setting dns, server unreachable: " + address) + } else if err := UpdateDNS(iface, network, address); err != nil { + ncutils.Log("error applying dns" + err.Error()) + } +} + // SetDNS - sets the DNS of a local machine func SetDNS(nameserver string) error { bytes, err := os.ReadFile("/etc/resolv.conf") diff --git a/netclient/local/routes_linux.go b/netclient/local/routes_linux.go index 7989d85b..b147accc 100644 --- a/netclient/local/routes_linux.go +++ b/netclient/local/routes_linux.go @@ -5,19 +5,25 @@ import ( "fmt" "net" + "strings" "github.com/gravitl/netmaker/netclient/ncutils" ) func setRoute(iface string, addr *net.IPNet, address string) error { - var err error - _, err = ncutils.RunCmd(fmt.Sprintf("ip route add %s dev %s", addr.String(), iface), false) + out, err := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false) + if err != nil || !strings.Contains(out, iface) { + _, err = ncutils.RunCmd(fmt.Sprintf("ip route add %s dev %s", addr.String(), iface), true) + } return err } func deleteRoute(iface string, addr *net.IPNet, address string) error { var err error - _, err = ncutils.RunCmd(fmt.Sprintf("ip route del %s dev %s", addr.String(), iface), false) + out, _ := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false) + if strings.Contains(out, iface) { + _, err = ncutils.RunCmd(fmt.Sprintf("ip route del %s dev %s", addr.String(), iface), false) + } return err } diff --git a/netclient/local/routes_other.go b/netclient/local/routes_other.go new file mode 100644 index 00000000..34d2fb11 --- /dev/null +++ b/netclient/local/routes_other.go @@ -0,0 +1,38 @@ +//go:build !linux +// +build !linux + +package local + +import ( + //"github.com/davecgh/go-spew/spew" + + "fmt" + "net" + + "github.com/gravitl/netmaker/netclient/ncutils" +) + +//"github.com/davecgh/go-spew/spew" + +/* + +These functions are not used. These should only be called by Linux (see routes_linux.go). These routes return nothing if called. + +*/ + +func setRoute(iface string, addr *net.IPNet) error { + out, err := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false) + if err != nil || !strings.Contains(out, iface) { + _, err = ncutils.RunCmd(fmt.Sprintf("ip route add %s dev %s", addr.String(), iface), true) + } + return err +} + +func deleteRoute(iface string, addr *net.IPNet) error { + var err error + out, _ := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false) + if strings.Contains(out, iface) { + _, err = ncutils.RunCmd(fmt.Sprintf("ip route del %s dev %s", addr.String(), iface), true) + } + return err +} diff --git a/netclient/ncutils/netclientutils.go b/netclient/ncutils/netclientutils.go index 25d3d07d..cd44e221 100644 --- a/netclient/ncutils/netclientutils.go +++ b/netclient/ncutils/netclientutils.go @@ -320,6 +320,22 @@ func GetNetclientPath() string { } } +// GetFileWithRetry - retry getting file X number of times before failing +func GetFileWithRetry(path string, retryCount int) ([]byte, error) { + var data []byte + var err error + for count := 0; count < retryCount; count++ { + data, err = os.ReadFile(path) + if err == nil { + return data, err + } else { + PrintLog("failed to retrieve file "+path+", retrying...", 1) + time.Sleep(time.Second >> 2) + } + } + return data, err +} + // GetNetclientPathSpecific - gets specific netclient config path func GetNetclientPathSpecific() string { if IsWindows() { @@ -411,6 +427,7 @@ func Copy(src, dst string) error { return err } err = os.Chmod(dst, 0755) + return err } diff --git a/netclient/wireguard/unix.go b/netclient/wireguard/unix.go index 7b4a5e95..92217ef4 100644 --- a/netclient/wireguard/unix.go +++ b/netclient/wireguard/unix.go @@ -126,6 +126,6 @@ func StorePrivKey(key string, network string) error { // RetrievePrivKey - reads wg priv key from local disk func RetrievePrivKey(network string) (string, error) { - dat, err := os.ReadFile(ncutils.GetNetclientPathSpecific() + "wgkey-" + network) + dat, err := ncutils.GetFileWithRetry(ncutils.GetNetclientPathSpecific()+"wgkey-"+network, 2) return string(dat), err }