added comments, optimized memory

This commit is contained in:
0xdcarns
2021-12-10 15:01:10 -05:00
parent 85e8c0abb6
commit e45a485bce
17 changed files with 136 additions and 152 deletions

View File

@@ -5,7 +5,7 @@ RUN apk add build-base
WORKDIR /app WORKDIR /app
COPY . . COPY . .
ENV GO111MODULE=auto ENV GO111MODULE=auto
RUN GOOS=linux CGO_ENABLED=1 go build -tags debug -ldflags="-s -X 'main.version=$version'" -o netmaker main.go RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -X 'main.version=$version'" -o netmaker main.go
FROM alpine:3.13.6 FROM alpine:3.13.6
# add a c lib # add a c lib
RUN apk add gcompat iptables RUN apk add gcompat iptables

View File

@@ -89,6 +89,7 @@ func getCurrentDB() map[string]interface{} {
} }
} }
// InitializeDatabase - initializes database
func InitializeDatabase() error { func InitializeDatabase() error {
logger.Log(0, "connecting to", servercfg.GetDB()) logger.Log(0, "connecting to", servercfg.GetDB())
tperiod := time.Now().Add(10 * time.Second) tperiod := time.Now().Add(10 * time.Second)

View File

@@ -49,6 +49,7 @@ func pgCreateTable(tableName string) error {
if err != nil { if err != nil {
return err return err
} }
defer statement.Close()
_, err = statement.Exec() _, err = statement.Exec()
if err != nil { if err != nil {
return err return err
@@ -63,6 +64,7 @@ func pgInsert(key string, value string, tableName string) error {
if err != nil { if err != nil {
return err return err
} }
defer statement.Close()
_, err = statement.Exec(key, value, value) _, err = statement.Exec(key, value, value)
if err != nil { if err != nil {
return err return err
@@ -91,6 +93,7 @@ func pgDeleteRecord(tableName string, key string) error {
if err != nil { if err != nil {
return err return err
} }
defer statement.Close()
if _, err = statement.Exec(key); err != nil { if _, err = statement.Exec(key); err != nil {
return err return err
} }
@@ -103,6 +106,7 @@ func pgDeleteAllRecords(tableName string) error {
if err != nil { if err != nil {
return err return err
} }
defer statement.Close()
if _, err = statement.Exec(); err != nil { if _, err = statement.Exec(); err != nil {
return err return err
} }

View File

@@ -12,7 +12,7 @@ import (
// == sqlite == // == sqlite ==
const dbFilename = "netmaker.db" const dbFilename = "netmaker.db"
// SqliteDB is the db object fro sqlite database connections // SqliteDB is the db object for sqlite database connections
var SqliteDB *sql.DB var SqliteDB *sql.DB
// SQLITE_FUNCTIONS - contains a map of the functions for sqlite // SQLITE_FUNCTIONS - contains a map of the functions for sqlite
@@ -50,6 +50,7 @@ func sqliteCreateTable(tableName string) error {
if err != nil { if err != nil {
return err return err
} }
defer statement.Close()
_, err = statement.Exec() _, err = statement.Exec()
if err != nil { if err != nil {
return err return err
@@ -64,6 +65,7 @@ func sqliteInsert(key string, value string, tableName string) error {
if err != nil { if err != nil {
return err return err
} }
defer statement.Close()
_, err = statement.Exec(key, value) _, err = statement.Exec(key, value)
if err != nil { if err != nil {
return err return err
@@ -90,6 +92,7 @@ func sqliteDeleteRecord(tableName string, key string) error {
if err != nil { if err != nil {
return err return err
} }
defer statement.Close()
if _, err = statement.Exec(); err != nil { if _, err = statement.Exec(); err != nil {
return err return err
} }
@@ -102,6 +105,7 @@ func sqliteDeleteAllRecords(tableName string) error {
if err != nil { if err != nil {
return err return err
} }
defer statement.Close()
if _, err = statement.Exec(); err != nil { if _, err = statement.Exec(); err != nil {
return err return err
} }

View File

@@ -685,10 +685,14 @@ func isInterfacePresent(iface string, address string) (string, bool) {
for _, addr := range currAddrs { for _, addr := range currAddrs {
if strings.Contains(addr.String(), address) && currIface.Name != iface { 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 return currIface.Name, false
} }
} }
currAddrs = nil
} }
interfaces = nil
logger.Log(2, "failed to find iface", iface) logger.Log(2, "failed to find iface", iface)
return "", true return "", true
} }

View File

@@ -86,9 +86,9 @@ func UncordonNode(network, macaddress string) (models.Node, error) {
} }
// GetPeers - gets the peers of a given node // GetPeers - gets the peers of a given node
func GetPeers(node models.Node) ([]models.Node, error) { func GetPeers(node *models.Node) ([]models.Node, error) {
if node.IsServer == "yes" && IsLeader(&node) { if IsLeader(node) {
SetNetworkServerPeers(&node) SetNetworkServerPeers(node)
} }
excludeIsRelayed := node.IsRelay != "yes" excludeIsRelayed := node.IsRelay != "yes"
var relayedNode string var relayedNode string
@@ -137,11 +137,13 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
return fmt.Errorf("failed to update node " + newNode.MacAddress + ", cannot change macaddress.") return fmt.Errorf("failed to update node " + newNode.MacAddress + ", cannot change macaddress.")
} }
// IsNodeIDUnique - checks if node id is unique
func IsNodeIDUnique(node *models.Node) (bool, error) { func IsNodeIDUnique(node *models.Node) (bool, error) {
_, err := database.FetchRecord(database.NODES_TABLE_NAME, node.ID) _, err := database.FetchRecord(database.NODES_TABLE_NAME, node.ID)
return database.IsEmptyRecord(err), err return database.IsEmptyRecord(err), err
} }
// ValidateNode - validates node values
func ValidateNode(node *models.Node, isUpdate bool) error { func ValidateNode(node *models.Node, isUpdate bool) error {
v := validator.New() v := validator.New()
_ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool { _ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
@@ -212,7 +214,7 @@ func CheckIsServer(node *models.Node) bool {
// GetNetworkByNode - gets the network model from a node // GetNetworkByNode - gets the network model from a node
func GetNetworkByNode(node *models.Node) (models.Network, error) { func GetNetworkByNode(node *models.Node) (models.Network, error) {
var network models.Network var network = models.Network{}
networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, node.Network) networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, node.Network)
if err != nil { if err != nil {
return network, err return network, err

View File

@@ -21,6 +21,8 @@ import (
// KUBERNETES_LISTEN_PORT - starting port for Kubernetes in order to use NodePort range // KUBERNETES_LISTEN_PORT - starting port for Kubernetes in order to use NodePort range
const KUBERNETES_LISTEN_PORT = 31821 const KUBERNETES_LISTEN_PORT = 31821
// KUBERNETES_SERVER_MTU - ideal mtu for kubernetes deployments right now
const KUBERNETES_SERVER_MTU = 1024 const KUBERNETES_SERVER_MTU = 1024
// ServerJoin - responsible for joining a server to a network // ServerJoin - responsible for joining a server to a network
@@ -111,13 +113,13 @@ func ServerJoin(network string, serverID string, privateKey string) error {
return err return err
} }
peers, hasGateway, gateways, err := GetServerPeers(node.MacAddress, network, node.IsDualStack == "yes", node.IsIngressGateway == "yes") peers, hasGateway, gateways, err := GetServerPeers(node)
if err != nil && !ncutils.IsEmptyRecord(err) { if err != nil && !ncutils.IsEmptyRecord(err) {
logger.Log(1, "failed to retrieve peers") logger.Log(1, "failed to retrieve peers")
return err return err
} }
err = initWireguard(node, privateKey, peers, hasGateway, gateways) err = initWireguard(node, privateKey, peers[:], hasGateway, gateways[:])
if err != nil { if err != nil {
return err return err
} }
@@ -127,46 +129,43 @@ func ServerJoin(network string, serverID string, privateKey string) error {
// ServerCheckin - runs pulls and pushes for server // ServerCheckin - runs pulls and pushes for server
func ServerCheckin(mac string, network string) error { func ServerCheckin(mac string, network string) error {
var serverNode models.Node var serverNode *models.Node
var newNode *models.Node var currentNode, err = GetNode(mac, network)
var err error
serverNode, err = GetNode(mac, network)
if err != nil { if err != nil {
return err return err
} }
serverNode = &currentNode
newNode, err = ServerPull(&serverNode, false) err = ServerPull(serverNode, false)
if isDeleteError(err) { if isDeleteError(err) {
return ServerLeave(mac, network) return ServerLeave(mac, network)
} else if err != nil { } else if err != nil {
return err return err
} }
actionCompleted := checkNodeActions(newNode, network, &serverNode) actionCompleted := checkNodeActions(serverNode)
if actionCompleted == models.NODE_DELETE { if actionCompleted == models.NODE_DELETE {
return errors.New("node has been removed") return errors.New("node has been removed")
} }
return ServerPush(newNode) return ServerPush(serverNode)
} }
// ServerPull - pulls current config/peers for server // ServerPull - pulls current config/peers for server
func ServerPull(serverNode *models.Node, onErr bool) (*models.Node, error) { func ServerPull(serverNode *models.Node, onErr bool) error {
var err error var err error
if serverNode.IPForwarding == "yes" { if serverNode.IPForwarding == "yes" {
if err = setIPForwardingLinux(); err != nil { if err = setIPForwardingLinux(); err != nil {
return serverNode, err return err
} }
} }
serverNode.OS = runtime.GOOS serverNode.OS = runtime.GOOS
if serverNode.PullChanges == "yes" || onErr { if serverNode.PullChanges == "yes" || onErr {
// check for interface change // check for interface change
var isIfacePresent bool
var oldIfaceName string
// checks if address is in use by another interface // checks if address is in use by another interface
oldIfaceName, isIfacePresent = isInterfacePresent(serverNode.Interface, serverNode.Address) var oldIfaceName, isIfacePresent = isInterfacePresent(serverNode.Interface, serverNode.Address)
if !isIfacePresent { if !isIfacePresent {
if err = deleteInterface(oldIfaceName, serverNode.PostDown); err != nil { if err = deleteInterface(oldIfaceName, serverNode.PostDown); err != nil {
logger.Log(1, "could not delete old interface", oldIfaceName) logger.Log(1, "could not delete old interface", oldIfaceName)
@@ -174,24 +173,24 @@ func ServerPull(serverNode *models.Node, onErr bool) (*models.Node, error) {
logger.Log(1, "removed old interface", oldIfaceName) logger.Log(1, "removed old interface", oldIfaceName)
} }
serverNode.PullChanges = "no" serverNode.PullChanges = "no"
if err = setWGConfig(serverNode, serverNode.Network, false); err != nil { if err = setWGConfig(serverNode, false); err != nil {
return serverNode, err return err
} }
// handle server side update // handle server side update
if err = UpdateNode(serverNode, serverNode); err != nil { if err = UpdateNode(serverNode, serverNode); err != nil {
return serverNode, err return err
} }
} else { } else {
if err = setWGConfig(serverNode, serverNode.Network, true); err != nil { if err = setWGConfig(serverNode, true); err != nil {
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {
return ServerPull(serverNode, true) return ServerPull(serverNode, true)
} else { } else {
return serverNode, err return err
} }
} }
} }
return serverNode, nil return nil
} }
// ServerPush - pushes config changes for server checkins/join // ServerPush - pushes config changes for server checkins/join
@@ -204,9 +203,7 @@ func ServerPush(serverNode *models.Node) error {
// ServerLeave - removes a server node // ServerLeave - removes a server node
func ServerLeave(mac string, network string) error { func ServerLeave(mac string, network string) error {
var serverNode models.Node var serverNode, err = GetNode(mac, network)
var err error
serverNode, err = GetNode(mac, network)
if err != nil { if err != nil {
return err return err
} }
@@ -220,28 +217,25 @@ func ServerLeave(mac string, network string) error {
*/ */
// GetServerPeers - gets peers of server // GetServerPeers - gets peers of server
func GetServerPeers(macaddress string, network string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) { func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []string, error) {
hasGateway := false hasGateway := false
var err error
var gateways []string var gateways []string
var peers []wgtypes.PeerConfig var peers []wgtypes.PeerConfig
var nodecfg models.Node
var nodes []models.Node // fill above fields from server or client var nodes []models.Node // fill above fields from server or client
nodecfg, err = GetNode(macaddress, network) var nodecfg, err = GetNode(serverNode.MacAddress, serverNode.Network)
if err != nil { if err != nil {
return nil, hasGateway, gateways, err return nil, hasGateway, gateways, err
} }
nodes, err = GetPeers(nodecfg) nodes, err = GetPeers(&nodecfg)
if err != nil { if err != nil {
return nil, hasGateway, gateways, err return nil, hasGateway, gateways, err
} }
keepalive := nodecfg.PersistentKeepalive keepalive := nodecfg.PersistentKeepalive
keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s") keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s")
keepaliveserver, err := time.ParseDuration(strconv.FormatInt(int64(5), 10) + "s")
if err != nil { if err != nil {
logger.Log(1, "Issue with format of keepalive value, Please view server config:", err.Error()) logger.Log(1, "Issue with format of keepalive duration value, Please view server config:", err.Error())
return nil, hasGateway, gateways, err return nil, hasGateway, gateways, err
} }
@@ -268,8 +262,9 @@ func GetServerPeers(macaddress string, network string, dualstack bool, isIngress
IP: net.ParseIP(node.Address), IP: net.ParseIP(node.Address),
Mask: net.CIDRMask(32, 32), Mask: net.CIDRMask(32, 32),
} }
var allowedips []net.IPNet var allowedips = []net.IPNet{
allowedips = append(allowedips, peeraddr) peeraddr,
}
// handle manually set peers // handle manually set peers
for _, allowedIp := range node.AllowedIPs { for _, allowedIp := range node.AllowedIPs {
if _, ipnet, err := net.ParseCIDR(allowedIp); err == nil { if _, ipnet, err := net.ParseCIDR(allowedIp); err == nil {
@@ -288,7 +283,7 @@ func GetServerPeers(macaddress string, network string, dualstack bool, isIngress
// handle egress gateway peers // handle egress gateway peers
if node.IsEgressGateway == "yes" { if node.IsEgressGateway == "yes" {
hasGateway = true hasGateway = true
ranges := node.EgressGatewayRanges ranges := node.EgressGatewayRanges[:]
for _, iprange := range ranges { // go through each cidr for egress gateway for _, iprange := range ranges { // go through each cidr for egress gateway
_, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr _, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr
if err != nil { if err != nil {
@@ -311,73 +306,47 @@ func GetServerPeers(macaddress string, network string, dualstack bool, isIngress
allowedips = append(allowedips, *ipnet) allowedips = append(allowedips, *ipnet)
} }
} }
ranges = nil
} }
if node.Address6 != "" && dualstack { if node.Address6 != "" && serverNode.IsDualStack == "yes" {
var addr6 = net.IPNet{ var addr6 = net.IPNet{
IP: net.ParseIP(node.Address6), IP: net.ParseIP(node.Address6),
Mask: net.CIDRMask(128, 128), Mask: net.CIDRMask(128, 128),
} }
allowedips = append(allowedips, addr6) allowedips = append(allowedips, addr6)
} }
if nodecfg.IsServer == "yes" && !(node.IsServer == "yes") { peer = wgtypes.PeerConfig{
peer = wgtypes.PeerConfig{ PublicKey: pubkey,
PublicKey: pubkey, PersistentKeepaliveInterval: &(keepalivedur),
PersistentKeepaliveInterval: &keepaliveserver, ReplaceAllowedIPs: true,
ReplaceAllowedIPs: true, AllowedIPs: allowedips,
AllowedIPs: allowedips,
}
} else if keepalive != 0 {
peer = wgtypes.PeerConfig{
PublicKey: pubkey,
PersistentKeepaliveInterval: &keepalivedur,
Endpoint: &net.UDPAddr{
IP: net.ParseIP(node.Endpoint),
Port: int(node.ListenPort),
},
ReplaceAllowedIPs: true,
AllowedIPs: allowedips,
}
} else {
peer = wgtypes.PeerConfig{
PublicKey: pubkey,
Endpoint: &net.UDPAddr{
IP: net.ParseIP(node.Endpoint),
Port: int(node.ListenPort),
},
ReplaceAllowedIPs: true,
AllowedIPs: allowedips,
}
} }
peers = append(peers, peer) peers = append(peers, peer)
} }
if isIngressGateway { if serverNode.IsIngressGateway == "yes" {
extPeers, err := GetServerExtPeers(macaddress, network, dualstack) extPeers, err := GetServerExtPeers(serverNode)
if err == nil { if err == nil {
peers = append(peers, extPeers...) peers = append(peers, extPeers...)
} else { } else {
logger.Log(1, "ERROR RETRIEVING EXTERNAL PEERS ON SERVER:", err.Error()) logger.Log(1, "ERROR RETRIEVING EXTERNAL PEERS ON SERVER:", err.Error())
} }
extPeers = nil
} }
return peers[:], hasGateway, gateways[:], err return peers, hasGateway, gateways, err
} }
// GetServerExtPeers - gets the extpeers for a client // GetServerExtPeers - gets the extpeers for a client
func GetServerExtPeers(macaddress string, network string, dualstack bool) ([]wgtypes.PeerConfig, error) { func GetServerExtPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, error) {
var peers []wgtypes.PeerConfig var peers []wgtypes.PeerConfig
var nodecfg models.Node
var extPeers []models.Node var extPeers []models.Node
var err error var err error
// fill above fields from either client or server
nodecfg, err = GetNode(macaddress, network)
if err != nil {
return nil, err
}
var tempPeers []models.ExtPeersResponse var tempPeers []models.ExtPeersResponse
tempPeers, err = GetExtPeersList(nodecfg.MacAddress, nodecfg.Network)
tempPeers, err = GetExtPeersList(serverNode.MacAddress, serverNode.Network)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for i := 0; i < len(tempPeers); i++ { for i := 0; i < len(tempPeers); i++ {
extPeers = append(extPeers, models.Node{ extPeers = append(extPeers, models.Node{
Address: tempPeers[i].Address, Address: tempPeers[i].Address,
@@ -395,7 +364,7 @@ func GetServerExtPeers(macaddress string, network string, dualstack bool) ([]wgt
return peers, err return peers, err
} }
if nodecfg.PublicKey == extPeer.PublicKey { if serverNode.PublicKey == extPeer.PublicKey {
continue continue
} }
@@ -404,10 +373,11 @@ func GetServerExtPeers(macaddress string, network string, dualstack bool) ([]wgt
IP: net.ParseIP(extPeer.Address), IP: net.ParseIP(extPeer.Address),
Mask: net.CIDRMask(32, 32), Mask: net.CIDRMask(32, 32),
} }
var allowedips []net.IPNet var allowedips = []net.IPNet{
allowedips = append(allowedips, peeraddr) peeraddr,
}
if extPeer.Address6 != "" && dualstack { if extPeer.Address6 != "" && serverNode.IsDualStack == "yes" {
var addr6 = net.IPNet{ var addr6 = net.IPNet{
IP: net.ParseIP(extPeer.Address6), IP: net.ParseIP(extPeer.Address6),
Mask: net.CIDRMask(128, 128), Mask: net.CIDRMask(128, 128),
@@ -420,8 +390,11 @@ func GetServerExtPeers(macaddress string, network string, dualstack bool) ([]wgt
AllowedIPs: allowedips, AllowedIPs: allowedips,
} }
peers = append(peers, peer) peers = append(peers, peer)
allowedips = nil
} }
return peers[:], err tempPeers = nil
extPeers = nil
return peers, err
} }
// == Private == // == Private ==
@@ -430,8 +403,8 @@ func isDeleteError(err error) bool {
return err != nil && strings.Contains(err.Error(), models.NODE_DELETE) return err != nil && strings.Contains(err.Error(), models.NODE_DELETE)
} }
func checkNodeActions(node *models.Node, networkName string, localNode *models.Node) string { func checkNodeActions(node *models.Node) string {
if (node.Action == models.NODE_UPDATE_KEY || localNode.Action == models.NODE_UPDATE_KEY) && if (node.Action == models.NODE_UPDATE_KEY) &&
node.IsStatic != "yes" { node.IsStatic != "yes" {
err := setWGKeyConfig(node) err := setWGKeyConfig(node)
if err != nil { if err != nil {
@@ -439,8 +412,8 @@ func checkNodeActions(node *models.Node, networkName string, localNode *models.N
return "" return ""
} }
} }
if node.Action == models.NODE_DELETE || localNode.Action == models.NODE_DELETE { if node.Action == models.NODE_DELETE {
err := ServerLeave(node.MacAddress, networkName) err := ServerLeave(node.MacAddress, node.Network)
if err != nil { if err != nil {
logger.Log(1, "error deleting locally:", err.Error()) logger.Log(1, "error deleting locally:", err.Error())
} }

View File

@@ -12,12 +12,11 @@ type serverData struct {
// StorePrivKey - stores server client WireGuard privatekey if needed // StorePrivKey - stores server client WireGuard privatekey if needed
func StorePrivKey(serverID string, privateKey string) error { func StorePrivKey(serverID string, privateKey string) error {
var newData *serverData var newData = serverData{}
newData = &serverData{}
var err error var err error
var data []byte var data []byte
newData.PrivateKey = privateKey newData.PrivateKey = privateKey
data, err = json.Marshal(newData) data, err = json.Marshal(&newData)
if err != nil { if err != nil {
return err return err
} }
@@ -28,8 +27,7 @@ func StorePrivKey(serverID string, privateKey string) error {
func FetchPrivKey(serverID string) (string, error) { func FetchPrivKey(serverID string) (string, error) {
var dbData string var dbData string
var err error var err error
var fetchedData serverData var fetchedData = serverData{}
fetchedData = serverData{}
dbData, err = database.FetchRecord(database.SERVERCONF_TABLE_NAME, serverID) dbData, err = database.FetchRecord(database.SERVERCONF_TABLE_NAME, serverID)
if err != nil { if err != nil {
return "", err return "", err

View File

@@ -70,7 +70,7 @@ func DeleteNode(node *models.Node, exterminate bool) error {
return err return err
} }
if servercfg.IsDNSMode() { if servercfg.IsDNSMode() {
err = SetDNS() SetDNS()
} }
return removeLocalServer(node) return removeLocalServer(node)
} }
@@ -171,7 +171,7 @@ func GetNode(macaddress string, network string) (models.Node, error) {
data, err := database.FetchRecord(database.NODES_TABLE_NAME, key) data, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
if err != nil { if err != nil {
if data == "" { if data == "" {
data, err = database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key) data, _ = database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key)
err = json.Unmarshal([]byte(data), &node) err = json.Unmarshal([]byte(data), &node)
} }
return node, err return node, err
@@ -200,9 +200,9 @@ func GetNodePeers(networkName string, excludeRelayed bool) ([]models.Node, error
logger.Log(2, errN.Error()) logger.Log(2, errN.Error())
} }
for _, value := range collection { for _, value := range collection {
var node models.Node var node *models.Node
var peer models.Node var peer models.Node
err := json.Unmarshal([]byte(value), &node) err := json.Unmarshal([]byte(value), node)
if err != nil { if err != nil {
logger.Log(2, err.Error()) logger.Log(2, err.Error())
continue continue
@@ -244,32 +244,31 @@ func GetNodePeers(networkName string, excludeRelayed bool) ([]models.Node, error
// GetPeersList - gets the peers of a given network // GetPeersList - gets the peers of a given network
func GetPeersList(networkName string, excludeRelayed bool, relayedNodeAddr string) ([]models.Node, error) { func GetPeersList(networkName string, excludeRelayed bool, relayedNodeAddr string) ([]models.Node, error) {
var peers []models.Node var peers []models.Node
var relayNode models.Node
var err error var err error
if relayedNodeAddr == "" { if relayedNodeAddr == "" {
peers, err = GetNodePeers(networkName, excludeRelayed) peers, err = GetNodePeers(networkName, excludeRelayed)
} else { } else {
var relayNode models.Node
relayNode, err = GetNodeRelay(networkName, relayedNodeAddr) relayNode, err = GetNodeRelay(networkName, relayedNodeAddr)
if relayNode.Address != "" { if relayNode.Address != "" {
relayNode = setPeerInfo(relayNode) var peerNode = setPeerInfo(&relayNode) // WHAT DO
network, err := GetNetwork(networkName) network, err := GetNetwork(networkName)
if err == nil { if err == nil {
relayNode.AllowedIPs = append(relayNode.AllowedIPs, network.AddressRange) peerNode.AllowedIPs = append(peerNode.AllowedIPs, network.AddressRange)
} else { } else {
relayNode.AllowedIPs = append(relayNode.AllowedIPs, relayNode.RelayAddrs...) peerNode.AllowedIPs = append(peerNode.AllowedIPs, peerNode.RelayAddrs...)
} }
nodepeers, err := GetNodePeers(networkName, false) nodepeers, err := GetNodePeers(networkName, false)
if err == nil && relayNode.UDPHolePunch == "yes" { if err == nil && peerNode.UDPHolePunch == "yes" {
for _, nodepeer := range nodepeers { for _, nodepeer := range nodepeers {
if nodepeer.Address == relayNode.Address { if nodepeer.Address == peerNode.Address {
relayNode.Endpoint = nodepeer.Endpoint peerNode.Endpoint = nodepeer.Endpoint
relayNode.ListenPort = nodepeer.ListenPort peerNode.ListenPort = nodepeer.ListenPort
} }
} }
} }
peers = append(peers, relayNode) peers = append(peers, peerNode)
} }
} }
return peers, err return peers, err
@@ -277,7 +276,7 @@ func GetPeersList(networkName string, excludeRelayed bool, relayedNodeAddr strin
// RandomString - returns a random string in a charset // RandomString - returns a random string in a charset
func RandomString(length int) string { func RandomString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var seededRand *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano())) var seededRand *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
@@ -290,7 +289,8 @@ func RandomString(length int) string {
// == Private Methods == // == Private Methods ==
func setPeerInfo(node models.Node) models.Node { // WHAT DO
func setPeerInfo(node *models.Node) models.Node {
var peer models.Node var peer models.Node
peer.RelayAddrs = node.RelayAddrs peer.RelayAddrs = node.RelayAddrs
peer.IsRelay = node.IsRelay peer.IsRelay = node.IsRelay

View File

@@ -25,6 +25,7 @@ func GetSystemPeers(node *models.Node) (map[string]string, error) {
if err != nil { if err != nil {
return peers, err return peers, err
} }
defer client.Close()
device, err := client.Device(node.Interface) device, err := client.Device(node.Interface)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -45,7 +46,7 @@ func RemoveConf(iface string, printlog bool) error {
return err return err
} }
// Private Functions // == Private Functions ==
func initWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error { func initWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
@@ -210,6 +211,7 @@ func setServerPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) e
logger.Log(0, "failed to start wgctrl") logger.Log(0, "failed to start wgctrl")
return err return err
} }
defer client.Close()
device, err := client.Device(iface) device, err := client.Device(iface)
if err != nil { if err != nil {
@@ -280,10 +282,10 @@ func setServerPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) e
return nil return nil
} }
func setWGConfig(node *models.Node, network string, peerupdate bool) error { func setWGConfig(node *models.Node, peerupdate bool) error {
node.SetID() node.SetID()
peers, hasGateway, gateways, err := GetServerPeers(node.MacAddress, node.Network, node.IsDualStack == "yes", node.IsIngressGateway == "yes") peers, hasGateway, gateways, err := GetServerPeers(node)
if err != nil { if err != nil {
return err return err
} }
@@ -292,11 +294,10 @@ func setWGConfig(node *models.Node, network string, peerupdate bool) error {
return err return err
} }
if peerupdate { if peerupdate {
var iface string = node.Interface err = setServerPeers(node.Interface, node.PersistentKeepalive, peers[:])
err = setServerPeers(iface, node.PersistentKeepalive, peers)
logger.Log(2, "updated peers on server", node.Name) logger.Log(2, "updated peers on server", node.Name)
} else { } else {
err = initWireguard(node, privkey, peers, hasGateway, gateways) err = initWireguard(node, privkey, peers[:], hasGateway, gateways[:])
logger.Log(3, "finished setting wg config on server", node.Name) logger.Log(3, "finished setting wg config on server", node.Name)
} }
return err return err
@@ -311,7 +312,6 @@ func setWGKeyConfig(node *models.Node) error {
} }
privkeystring := privatekey.String() privkeystring := privatekey.String()
publickey := privatekey.PublicKey() publickey := privatekey.PublicKey()
node.PublicKey = publickey.String() node.PublicKey = publickey.String()
err = StorePrivKey(node.ID, privkeystring) err = StorePrivKey(node.ID, privkeystring)
@@ -322,7 +322,7 @@ func setWGKeyConfig(node *models.Node) error {
node.Action = models.NODE_NOOP node.Action = models.NODE_NOOP
} }
return setWGConfig(node, node.Network, false) return setWGConfig(node, false)
} }
func removeLocalServer(node *models.Node) error { func removeLocalServer(node *models.Node) error {

14
main.go
View File

@@ -1,6 +1,3 @@
//TODO: Harden. Add failover for every method and agent calls
//TODO: Figure out why mongodb keeps failing (log rotation?)
package main package main
import ( import (
@@ -117,11 +114,10 @@ func startControllers() {
if servercfg.IsClientMode() == "on" { if servercfg.IsClientMode() == "on" {
var checkintime = time.Duration(servercfg.GetServerCheckinInterval()) * time.Second var checkintime = time.Duration(servercfg.GetServerCheckinInterval()) * time.Second
for { // best effort currently for { // best effort currently
var netSyncGroup sync.WaitGroup var serverGroup sync.WaitGroup
netSyncGroup.Add(1) serverGroup.Add(1)
go runClient(&netSyncGroup) go runClient(&serverGroup)
netSyncGroup.Wait() serverGroup.Wait()
logger.Log(0, "ran a checkin")
time.Sleep(checkintime) time.Sleep(checkintime)
} }
} }
@@ -169,7 +165,7 @@ func runGRPC(wg *sync.WaitGroup) {
// Right way to stop the server using a SHUTDOWN HOOK // Right way to stop the server using a SHUTDOWN HOOK
// Create a channel to receive OS signals // Create a channel to receive OS signals
c := make(chan os.Signal) c := make(chan os.Signal, 1)
// Relay os.Interrupt to our channel (os.Interrupt = CTRL+C) // Relay os.Interrupt to our channel (os.Interrupt = CTRL+C)
// Ignore other incoming signals // Ignore other incoming signals

View File

@@ -33,6 +33,7 @@ func ListPorts() error {
if err != nil { if err != nil {
return err return err
} }
defer wgclient.Close()
devices, err := wgclient.Devices() devices, err := wgclient.Devices()
if err != nil { if err != nil {
return err return err

View File

@@ -261,6 +261,7 @@ func GetFreePort(rangestart int32) (int32, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
defer wgclient.Close()
devices, err := wgclient.Devices() devices, err := wgclient.Devices()
if err != nil { if err != nil {
return 0, err return 0, err

View File

@@ -1,17 +1,17 @@
package ncutils package ncutils
import ( import (
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"net"
"strconv" "strconv"
"strings" "strings"
"net"
"time" "time"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
func GetPeers(iface string) ([]wgtypes.Peer, error) { func GetPeers(iface string) ([]wgtypes.Peer, error) {
var peers []wgtypes.Peer var peers []wgtypes.Peer
output, err := RunCmd("wg show "+iface+" dump",true) output, err := RunCmd("wg show "+iface+" dump", true)
if err != nil { if err != nil {
return peers, err return peers, err
} }
@@ -22,7 +22,7 @@ func GetPeers(iface string) ([]wgtypes.Peer, error) {
var allowedIPs []net.IPNet var allowedIPs []net.IPNet
fields := strings.Fields(line) fields := strings.Fields(line)
if len(fields) < 4 { if len(fields) < 4 {
Log("error parsing peer: "+line) Log("error parsing peer: " + line)
continue continue
} }
pubkeystring := fields[0] pubkeystring := fields[0]
@@ -36,13 +36,13 @@ func GetPeers(iface string) ([]wgtypes.Peer, error) {
pubkey, err := wgtypes.ParseKey(pubkeystring) pubkey, err := wgtypes.ParseKey(pubkeystring)
if err != nil { if err != nil {
Log("error parsing peer key "+pubkeystring) Log("error parsing peer key " + pubkeystring)
continue continue
} }
ipstrings := strings.Split(allowedipstring, ",") ipstrings := strings.Split(allowedipstring, ",")
for _, ipstring := range ipstrings { for _, ipstring := range ipstrings {
var netip net.IP var netip net.IP
if netip = net.ParseIP(strings.Split(ipstring,"/")[0]); netip != nil { if netip = net.ParseIP(strings.Split(ipstring, "/")[0]); netip != nil {
allowedIPs = append( allowedIPs = append(
allowedIPs, allowedIPs,
net.IPNet{ net.IPNet{
@@ -53,40 +53,39 @@ func GetPeers(iface string) ([]wgtypes.Peer, error) {
} }
} }
if len(allowedIPs) == 0 { if len(allowedIPs) == 0 {
Log("error parsing peer "+pubkeystring+", no allowedips found") Log("error parsing peer " + pubkeystring + ", no allowedips found")
continue continue
} }
var endpointarr []string var endpointarr []string
var endpointip net.IP var endpointip net.IP
if endpointarr = strings.Split(endpointstring,":"); len(endpointarr) != 2 { if endpointarr = strings.Split(endpointstring, ":"); len(endpointarr) != 2 {
Log("error parsing peer "+pubkeystring+", could not parse endpoint: "+endpointstring) Log("error parsing peer " + pubkeystring + ", could not parse endpoint: " + endpointstring)
continue continue
} }
if endpointip = net.ParseIP(endpointarr[0]); endpointip == nil { if endpointip = net.ParseIP(endpointarr[0]); endpointip == nil {
Log("error parsing peer "+pubkeystring+", could not parse endpoint: "+endpointarr[0]) Log("error parsing peer " + pubkeystring + ", could not parse endpoint: " + endpointarr[0])
continue continue
} }
var port int var port int
if port, err = strconv.Atoi(endpointarr[1]); err != nil { if port, err = strconv.Atoi(endpointarr[1]); err != nil {
Log("error parsing peer "+pubkeystring+", could not parse port: "+err.Error()) Log("error parsing peer " + pubkeystring + ", could not parse port: " + err.Error())
continue continue
} }
var endpoint = net.UDPAddr { var endpoint = net.UDPAddr{
IP: endpointip, IP: endpointip,
Port: port, Port: port,
} }
var dur time.Duration var dur time.Duration
if pkeepalivestring != "" { if pkeepalivestring != "" {
if dur, err = time.ParseDuration(pkeepalivestring+"s"); err != nil { if dur, err = time.ParseDuration(pkeepalivestring + "s"); err != nil {
Log("error parsing peer "+pubkeystring+", could not parse keepalive: "+err.Error()) Log("error parsing peer " + pubkeystring + ", could not parse keepalive: " + err.Error())
} }
} }
peers = append(peers, wgtypes.Peer{ peers = append(peers, wgtypes.Peer{
PublicKey: pubkey, PublicKey: pubkey,
Endpoint: &endpoint, Endpoint: &endpoint,
AllowedIPs: allowedIPs, AllowedIPs: allowedIPs,
PersistentKeepaliveInterval: dur, PersistentKeepaliveInterval: dur,
}) })
} }

View File

@@ -36,6 +36,7 @@ func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
ncutils.PrintLog("failed to start wgctrl", 0) ncutils.PrintLog("failed to start wgctrl", 0)
return err return err
} }
defer client.Close()
device, err := client.Device(iface) device, err := client.Device(iface)
if err != nil { if err != nil {
ncutils.PrintLog("failed to parse interface", 0) ncutils.PrintLog("failed to parse interface", 0)
@@ -114,7 +115,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
if err != nil { if err != nil {
return err return err
} }
defer wgclient.Close()
modcfg, err := config.ReadConfig(node.Network) modcfg, err := config.ReadConfig(node.Network)
if err != nil { if err != nil {
return err return err
@@ -125,7 +126,6 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
if err != nil { if err != nil {
log.Fatalf("failed to open client: %v", err) log.Fatalf("failed to open client: %v", err)
} }
defer wgclient.Close()
var ifacename string var ifacename string
if nodecfg.Interface != "" { if nodecfg.Interface != "" {

View File

@@ -108,7 +108,7 @@ func GetAPIConnString() string {
// GetVersion - version of netmaker // GetVersion - version of netmaker
func GetVersion() string { func GetVersion() string {
version := "0.9.1" version := "0.9.2"
if config.Config.Server.Version != "" { if config.Config.Server.Version != "" {
version = config.Config.Server.Version version = config.Config.Server.Version
} }

View File

@@ -77,9 +77,10 @@ func HandleContainedClient() error {
logger.Log(3, "completed peers check of network", serverNet.NetID) logger.Log(3, "completed peers check of network", serverNet.NetID)
} }
} }
err := SyncNetworks(servernets[:]) syncErr := SyncNetworks(servernets[:])
if err != nil { if syncErr != nil {
logger.Log(1, "error syncing networks:", err.Error()) logger.Log(1, "error syncing networks:", syncErr.Error())
syncErr = nil
} }
// logger.Log("completed a checkin call", 3) // logger.Log("completed a checkin call", 3)
} }