mirror of
				https://github.com/gravitl/netmaker.git
				synced 2025-10-31 12:16:29 +08:00 
			
		
		
		
	fix for issue #621
This commit is contained in:
		| @@ -12,6 +12,7 @@ import ( | ||||
| 	"github.com/gravitl/netmaker/logger" | ||||
| 	"github.com/gravitl/netmaker/models" | ||||
| 	"github.com/gravitl/netmaker/netclient/ncutils" | ||||
| 	"github.com/gravitl/netmaker/netclient/wireguard" | ||||
| 	"golang.zx2c4.com/wireguard/wgctrl" | ||||
| 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||||
| ) | ||||
| @@ -84,17 +85,22 @@ func initWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig | ||||
| 	} | ||||
|  | ||||
| 	if !ncutils.IsKernel() { | ||||
| 		var newConf string | ||||
| 		newConf, _ = ncutils.CreateWireGuardConf(node, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), peers) | ||||
| 		confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf" | ||||
| 		logger.Log(1, "writing wg conf file to:", confPath) | ||||
| 		err = os.WriteFile(confPath, []byte(newConf), 0644) | ||||
| 		if err != nil { | ||||
| 			logger.Log(1, "error writing wg conf file to", confPath, ":", err.Error()) | ||||
| 		//var newConf string | ||||
| 		//newConf, _ = ncutils.CreateWireGuardConf(node, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), peers) | ||||
| 		//confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf" | ||||
| 		//logger.Log(1, "writing wg conf file to:", confPath) | ||||
| 		//err = os.WriteFile(confPath, []byte(newConf), 0644) | ||||
| 		//if err != nil { | ||||
| 		//logger.Log(1, "error writing wg conf file to", confPath, ":", err.Error()) | ||||
| 		//return err | ||||
| 		//} | ||||
| 		if err := wireguard.WriteWgConfig(node, key.String(), peers); err != nil { | ||||
| 			logger.Log(1, "error writing wg conf file: ", err.Error()) | ||||
| 			return err | ||||
| 		} | ||||
| 		// spin up userspace + apply the conf file | ||||
| 		var deviceiface = ifacename | ||||
| 		confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf" | ||||
| 		d, _ := wgclient.Device(deviceiface) | ||||
| 		for d != nil && d.Name == deviceiface { | ||||
| 			_ = RemoveConf(ifacename, false) // remove interface first | ||||
|   | ||||
| @@ -164,7 +164,7 @@ func GetMacAddr() ([]string, error) { | ||||
| func parsePeers(keepalive int32, peers []wgtypes.PeerConfig) (string, error) { | ||||
| 	peersString := "" | ||||
| 	if keepalive <= 0 { | ||||
| 		keepalive = 20 | ||||
| 		keepalive = 0 | ||||
| 	} | ||||
|  | ||||
| 	for _, peer := range peers { | ||||
|   | ||||
| @@ -1,14 +1,9 @@ | ||||
| package ncutils | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os/exec" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/gravitl/netmaker/models" | ||||
| 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||||
| ) | ||||
|  | ||||
| // RunCmd - runs a local command | ||||
| @@ -35,31 +30,31 @@ func GetEmbedded() error { | ||||
| } | ||||
|  | ||||
| // CreateWireGuardConf - creates a WireGuard conf string | ||||
| func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, peers []wgtypes.PeerConfig) (string, error) { | ||||
| 	peersString, err := parsePeers(node.PersistentKeepalive, peers) | ||||
| 	var listenPortString string | ||||
| 	if node.MTU <= 0 { | ||||
| 		node.MTU = 1280 | ||||
| 	} | ||||
| 	if listenPort != "" { | ||||
| 		listenPortString += "ListenPort = " + listenPort | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	config := fmt.Sprintf(`[Interface] | ||||
| Address = %s | ||||
| PrivateKey = %s | ||||
| MTU = %s | ||||
| %s | ||||
|  | ||||
| %s | ||||
|  | ||||
| `, | ||||
| 		node.Address+"/32", | ||||
| 		privatekey, | ||||
| 		strconv.Itoa(int(node.MTU)), | ||||
| 		listenPortString, | ||||
| 		peersString) | ||||
| 	return config, nil | ||||
| } | ||||
| //func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, peers []wgtypes.PeerConfig) (string, error) { | ||||
| //	peersString, err := parsePeers(node.PersistentKeepalive, peers) | ||||
| //	var listenPortString string | ||||
| //	if node.MTU <= 0 { | ||||
| //		node.MTU = 1280 | ||||
| //	} | ||||
| //	if listenPort != "" { | ||||
| //		listenPortString += "ListenPort = " + listenPort | ||||
| //	} | ||||
| //	if err != nil { | ||||
| //		return "", err | ||||
| //	} | ||||
| //	config := fmt.Sprintf(`[Interface] | ||||
| //Address = %s | ||||
| //PrivateKey = %s | ||||
| //MTU = %s | ||||
| //%s | ||||
| // | ||||
| //%s | ||||
| // | ||||
| //`, | ||||
| //		node.Address+"/32", | ||||
| //		privatekey, | ||||
| //		strconv.Itoa(int(node.MTU)), | ||||
| //		listenPortString, | ||||
| //		peersString) | ||||
| //	return config, nil | ||||
| //} | ||||
|   | ||||
| @@ -2,16 +2,11 @@ package ncutils | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os/exec" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/gravitl/netmaker/models" | ||||
| 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||||
| ) | ||||
|  | ||||
| // RunCmdFormatted - run a command formatted for freebsd | ||||
| @@ -44,31 +39,31 @@ func RunCmd(command string, printerr bool) (string, error) { | ||||
| } | ||||
|  | ||||
| // CreateWireGuardConf - creates a WireGuard conf string | ||||
| func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, peers []wgtypes.PeerConfig) (string, error) { | ||||
| 	peersString, err := parsePeers(node.PersistentKeepalive, peers) | ||||
| 	var listenPortString string | ||||
| 	if node.MTU <= 0 { | ||||
| 		node.MTU = 1280 | ||||
| 	} | ||||
| 	if listenPort != "" { | ||||
| 		listenPortString += "ListenPort = " + listenPort | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	config := fmt.Sprintf(`[Interface] | ||||
| Address = %s | ||||
| PrivateKey = %s | ||||
| MTU = %s | ||||
| %s | ||||
|  | ||||
| %s | ||||
|  | ||||
| `, | ||||
| 		node.Address+"/32", | ||||
| 		privatekey, | ||||
| 		strconv.Itoa(int(node.MTU)), | ||||
| 		listenPortString, | ||||
| 		peersString) | ||||
| 	return config, nil | ||||
| } | ||||
| //func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, peers []wgtypes.PeerConfig) (string, error) { | ||||
| //	peersString, err := parsePeers(node.PersistentKeepalive, peers) | ||||
| //	var listenPortString string | ||||
| //	if node.MTU <= 0 { | ||||
| //		node.MTU = 1280 | ||||
| //	} | ||||
| //	if listenPort != "" { | ||||
| //		listenPortString += "ListenPort = " + listenPort | ||||
| //	} | ||||
| //	if err != nil { | ||||
| //		return "", err | ||||
| //	} | ||||
| //	config := fmt.Sprintf(`[Interface] | ||||
| //Address = %s | ||||
| //PrivateKey = %s | ||||
| //MTU = %s | ||||
| //%s | ||||
| // | ||||
| //%s | ||||
| // | ||||
| //`, | ||||
| //		node.Address+"/32", | ||||
| //		privatekey, | ||||
| //		strconv.Itoa(int(node.MTU)), | ||||
| //		listenPortString, | ||||
| //		peersString) | ||||
| //	return config, nil | ||||
| //} | ||||
|   | ||||
| @@ -3,11 +3,7 @@ package ncutils | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os/exec" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/gravitl/netmaker/models" | ||||
| 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||||
| ) | ||||
|  | ||||
| // RunCmd - runs a local command | ||||
| @@ -34,43 +30,43 @@ func GetEmbedded() error { | ||||
| } | ||||
|  | ||||
| // CreateWireGuardConf - creates a user space WireGuard conf | ||||
| func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, peers []wgtypes.PeerConfig) (string, error) { | ||||
| 	peersString, err := parsePeers(node.PersistentKeepalive, peers) | ||||
| 	var listenPortString, postDownString, postUpString string | ||||
| 	if node.MTU <= 0 { | ||||
| 		node.MTU = 1280 | ||||
| 	} | ||||
| 	if node.PostDown != "" { | ||||
| 		postDownString = fmt.Sprintf("PostDown = %s", node.PostDown) | ||||
| 	} | ||||
| 	if node.PostUp != "" { | ||||
| 		postUpString = fmt.Sprintf("PostUp = %s", node.PostUp) | ||||
| 	} | ||||
|  | ||||
| 	if listenPort != "" { | ||||
| 		listenPortString = fmt.Sprintf("ListenPort = %s", listenPort) | ||||
| 	} | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	config := fmt.Sprintf(`[Interface] | ||||
| Address = %s | ||||
| PrivateKey = %s | ||||
| MTU = %s | ||||
| %s | ||||
| %s | ||||
| %s | ||||
|  | ||||
| %s | ||||
|  | ||||
| `, | ||||
| 		node.Address+"/32", | ||||
| 		privatekey, | ||||
| 		strconv.Itoa(int(node.MTU)), | ||||
| 		postDownString, | ||||
| 		postUpString, | ||||
| 		listenPortString, | ||||
| 		peersString) | ||||
| 	return config, nil | ||||
| } | ||||
| //func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, peers []wgtypes.PeerConfig) (string, error) { | ||||
| //	peersString, err := parsePeers(node.PersistentKeepalive, peers) | ||||
| //	var listenPortString, postDownString, postUpString string | ||||
| //	if node.MTU <= 0 { | ||||
| //		node.MTU = 1280 | ||||
| //	} | ||||
| //	if node.PostDown != "" { | ||||
| //		postDownString = fmt.Sprintf("PostDown = %s", node.PostDown) | ||||
| //	} | ||||
| //	if node.PostUp != "" { | ||||
| //		postUpString = fmt.Sprintf("PostUp = %s", node.PostUp) | ||||
| //	} | ||||
| // | ||||
| //	if listenPort != "" { | ||||
| //		listenPortString = fmt.Sprintf("ListenPort = %s", listenPort) | ||||
| //	} | ||||
| // | ||||
| //	if err != nil { | ||||
| //		return "", err | ||||
| //	} | ||||
| //	config := fmt.Sprintf(`[Interface] | ||||
| //Address = %s | ||||
| //PrivateKey = %s | ||||
| //MTU = %s | ||||
| //%s | ||||
| //%s | ||||
| //%s | ||||
| // | ||||
| //%s | ||||
| // | ||||
| //`, | ||||
| //		node.Address+"/32", | ||||
| //		privatekey, | ||||
| //		strconv.Itoa(int(node.MTU)), | ||||
| //		postDownString, | ||||
| //		postUpString, | ||||
| //		listenPortString, | ||||
| //		peersString) | ||||
| //	return config, nil | ||||
| //} | ||||
|   | ||||
| @@ -6,12 +6,8 @@ import ( | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/gravitl/netmaker/models" | ||||
| 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||||
| ) | ||||
|  | ||||
| //go:embed windowsdaemon/winsw.exe | ||||
| @@ -49,35 +45,35 @@ func RunCmdFormatted(command string, printerr bool) (string, error) { | ||||
| } | ||||
|  | ||||
| // CreateWireGuardConf - creates a WireGuard conf string | ||||
| func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, peers []wgtypes.PeerConfig) (string, error) { | ||||
| 	peersString, err := parsePeers(node.PersistentKeepalive, peers) | ||||
| 	var listenPortString string | ||||
| 	if node.MTU <= 0 { | ||||
| 		node.MTU = 1280 | ||||
| 	} | ||||
| 	if listenPort != "" { | ||||
| 		listenPortString += "ListenPort = " + listenPort | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	config := fmt.Sprintf(`[Interface] | ||||
| Address = %s | ||||
| PrivateKey = %s | ||||
| MTU = %s | ||||
| %s | ||||
|  | ||||
| %s | ||||
|  | ||||
| `, | ||||
| 		node.Address+"/32", | ||||
| 		privatekey, | ||||
| 		strconv.Itoa(int(node.MTU)), | ||||
| 		listenPortString, | ||||
| 		peersString) | ||||
| 	return config, nil | ||||
| } | ||||
|  | ||||
| //func CreateWireGuardConf(node *models.Node, privatekey string, listenPort string, peers []wgtypes.PeerConfig) (string, error) { | ||||
| //	peersString, err := parsePeers(node.PersistentKeepalive, peers) | ||||
| //	var listenPortString string | ||||
| //	if node.MTU <= 0 { | ||||
| //		node.MTU = 1280 | ||||
| //	} | ||||
| //	if listenPort != "" { | ||||
| //		listenPortString += "ListenPort = " + listenPort | ||||
| //	} | ||||
| //	if err != nil { | ||||
| //		return "", err | ||||
| //	} | ||||
| //	config := fmt.Sprintf(`[Interface] | ||||
| //Address = %s | ||||
| //PrivateKey = %s | ||||
| //MTU = %s | ||||
| //%s | ||||
| // | ||||
| //%s | ||||
| // | ||||
| //`, | ||||
| //		node.Address+"/32", | ||||
| //		privatekey, | ||||
| //		strconv.Itoa(int(node.MTU)), | ||||
| //		listenPortString, | ||||
| //		peersString) | ||||
| //	return config, nil | ||||
| //} | ||||
| // | ||||
| // GetEmbedded - Gets the Windows daemon creator | ||||
| func GetEmbedded() error { | ||||
| 	data, err := winswContent.ReadFile("windowsdaemon/winsw.exe") | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package wireguard | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"runtime" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| @@ -144,28 +143,36 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig | ||||
| 	if node.Address == "" { | ||||
| 		log.Fatal("no address to configure") | ||||
| 	} | ||||
| 	var newConf string | ||||
| 	if node.UDPHolePunch != "yes" { | ||||
| 		newConf, _ = ncutils.CreateWireGuardConf(node, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), peers) | ||||
| 	} else { | ||||
| 		newConf, _ = ncutils.CreateWireGuardConf(node, key.String(), "", peers) | ||||
| 		node.ListenPort = 0 | ||||
| 	} | ||||
| 	confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf" | ||||
| 	ncutils.PrintLog("writing wg conf file to: "+confPath, 1) | ||||
| 	err = os.WriteFile(confPath, []byte(newConf), 0644) | ||||
| 	if err != nil { | ||||
| 		ncutils.PrintLog("error writing wg conf file to "+confPath+": "+err.Error(), 1) | ||||
| 	if err := WriteWgConfig(&modcfg.Node, key.String(), peers); err != nil { | ||||
| 		ncutils.PrintLog("error writing wg conf file: "+err.Error(), 1) | ||||
| 		return err | ||||
| 	} | ||||
| 	if ncutils.IsWindows() { | ||||
| 		wgConfPath := ncutils.GetWGPathSpecific() + ifacename + ".conf" | ||||
| 		err = os.WriteFile(wgConfPath, []byte(newConf), 0644) | ||||
| 		if err != nil { | ||||
| 			ncutils.PrintLog("error writing wg conf file to "+wgConfPath+": "+err.Error(), 1) | ||||
| 			return err | ||||
| 		} | ||||
| 		confPath = wgConfPath | ||||
| 	} | ||||
|  | ||||
| 	//var newConf string | ||||
| 	//if node.UDPHolePunch != "yes" { | ||||
| 	//	newConf, _ = ncutils.CreateWireGuardConf(node, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), peers) | ||||
| 	//} else { | ||||
| 	//	newConf, _ = ncutils.CreateWireGuardConf(node, key.String(), "", peers) | ||||
| 	//} | ||||
| 	//confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf" | ||||
| 	//ncutils.PrintLog("writing wg conf file to: "+confPath, 1) | ||||
| 	//err = os.WriteFile(confPath, []byte(newConf), 0644) | ||||
| 	//if err != nil { | ||||
| 	//	ncutils.PrintLog("error writing wg conf file to "+confPath+": "+err.Error(), 1) | ||||
| 	//	return err | ||||
| 	//} | ||||
| 	//if ncutils.IsWindows() { | ||||
| 	confPath := ncutils.GetWGPathSpecific() + ifacename + ".conf" | ||||
| 	//	err = os.WriteFile(wgConfPath, []byte(newConf), 0644) | ||||
| 	//	if err != nil { | ||||
| 	//		ncutils.PrintLog("error writing wg conf file to "+wgConfPath+": "+err.Error(), 1) | ||||
| 	//		return err | ||||
| 	//	} | ||||
| 	//	confPath = wgConfPath | ||||
| 	//} | ||||
| 	// spin up userspace / windows interface + apply the conf file | ||||
| 	var deviceiface string | ||||
| 	if ncutils.IsMac() { | ||||
| @@ -297,28 +304,32 @@ func ApplyConf(node models.Node, ifacename string, confPath string) error { | ||||
| } | ||||
|  | ||||
| // WriteWgConfig - creates a wireguard config file | ||||
| func WriteWgConfig(cfg config.ClientConfig, privateKey string, peers []wgtypes.Peer) error { | ||||
| //func WriteWgConfig(cfg *config.ClientConfig, privateKey string, peers []wgtypes.PeerConfig) error { | ||||
| func WriteWgConfig(node *models.Node, privateKey string, peers []wgtypes.PeerConfig) error { | ||||
| 	options := ini.LoadOptions{ | ||||
| 		AllowNonUniqueSections: true, | ||||
| 		AllowShadows:           true, | ||||
| 	} | ||||
| 	wireguard := ini.Empty(options) | ||||
| 	wireguard.Section(section_interface).Key("PrivateKey").SetValue(privateKey) | ||||
| 	wireguard.Section(section_interface).Key("ListenPort").SetValue(strconv.Itoa(int(cfg.Node.ListenPort))) | ||||
| 	if cfg.Node.Address != "" { | ||||
| 		wireguard.Section(section_interface).Key("Address").SetValue(cfg.Node.Address) | ||||
| 	if node.ListenPort > 0 { | ||||
| 		wireguard.Section(section_interface).Key("ListenPort").SetValue(strconv.Itoa(int(node.ListenPort))) | ||||
| 	} | ||||
| 	if cfg.Node.Address6 != "" { | ||||
| 		wireguard.Section(section_interface).Key("Address").SetValue(cfg.Node.Address6) | ||||
| 	if node.Address != "" { | ||||
| 		wireguard.Section(section_interface).Key("Address").SetValue(node.Address) | ||||
| 	} | ||||
| 	if cfg.Node.DNSOn == "yes" { | ||||
| 		wireguard.Section(section_interface).Key("DNS").SetValue(cfg.Server.CoreDNSAddr) | ||||
| 	if node.Address6 != "" { | ||||
| 		wireguard.Section(section_interface).Key("Address").SetValue(node.Address6) | ||||
| 	} | ||||
| 	if cfg.Node.PostUp != "" { | ||||
| 		wireguard.Section(section_interface).Key("PostUp").SetValue(cfg.Node.PostUp) | ||||
| 	// need to figure out DNS | ||||
| 	//if node.DNSOn == "yes" { | ||||
| 	//	wireguard.Section(section_interface).Key("DNS").SetValue(cfg.Server.CoreDNSAddr) | ||||
| 	//} | ||||
| 	if node.PostUp != "" { | ||||
| 		wireguard.Section(section_interface).Key("PostUp").SetValue(node.PostUp) | ||||
| 	} | ||||
| 	if cfg.Node.PostDown != "" { | ||||
| 		wireguard.Section(section_interface).Key("PostDown").SetValue(cfg.Node.PostDown) | ||||
| 	if node.PostDown != "" { | ||||
| 		wireguard.Section(section_interface).Key("PostDown").SetValue(node.PostDown) | ||||
| 	} | ||||
| 	for i, peer := range peers { | ||||
| 		wireguard.SectionWithIndex(section_peers, i).Key("PublicKey").SetValue(peer.PublicKey.String()) | ||||
| @@ -339,8 +350,11 @@ func WriteWgConfig(cfg config.ClientConfig, privateKey string, peers []wgtypes.P | ||||
| 		if peer.Endpoint != nil { | ||||
| 			wireguard.SectionWithIndex(section_peers, i).Key("Endpoint").SetValue(peer.Endpoint.String()) | ||||
| 		} | ||||
| 		if peer.PersistentKeepaliveInterval != nil && peer.PersistentKeepaliveInterval.Seconds() > 0 { | ||||
| 			wireguard.SectionWithIndex(section_peers, i).Key("PersistentKeepalive").SetValue(strconv.FormatInt((int64)(peer.PersistentKeepaliveInterval.Seconds()), 10)) | ||||
| 		} | ||||
| 	if err := wireguard.SaveTo(ncutils.GetNetclientPathSpecific() + cfg.Node.Interface + ".conf"); err != nil { | ||||
| 	} | ||||
| 	if err := wireguard.SaveTo(ncutils.GetNetclientPathSpecific() + node.Interface + ".conf"); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| @@ -379,7 +393,7 @@ func UpdateWgPeers(wgInterface string, peers []wgtypes.PeerConfig) error { | ||||
| 		if peer.Endpoint != nil { | ||||
| 			wireguard.SectionWithIndex(section_peers, i).Key("Endpoint").SetValue(peer.Endpoint.String()) | ||||
| 		} | ||||
| 		if peer.PersistentKeepaliveInterval != nil && peer.PersistentKeepaliveInterval.Seconds() != 0 { | ||||
| 		if peer.PersistentKeepaliveInterval != nil && peer.PersistentKeepaliveInterval.Seconds() > 0 { | ||||
| 			wireguard.SectionWithIndex(section_peers, i).Key("PersistentKeepalive").SetValue(strconv.FormatInt((int64)(peer.PersistentKeepaliveInterval.Seconds()), 10)) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Matthew R Kasun
					Matthew R Kasun