Browse Source

configure proxy on peer update without resetting

Abhishek Kondur 2 years ago
parent
commit
653b5f21d6

+ 5 - 1
logic/peers.go

@@ -83,7 +83,7 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ManagerPayload
 			logger.Log(1, "failed to resolve udp addr for node: ", peer.ID, peer.Endpoint, err.Error())
 			logger.Log(1, "failed to resolve udp addr for node: ", peer.ID, peer.Endpoint, err.Error())
 			continue
 			continue
 		}
 		}
-		allowedips := getNodeAllowedIPs(node, &peer)
+		allowedips := getNodeAllowedIPs(&peer, node)
 		var keepalive time.Duration
 		var keepalive time.Duration
 		if node.PersistentKeepalive != 0 {
 		if node.PersistentKeepalive != 0 {
 			// set_keepalive
 			// set_keepalive
@@ -96,12 +96,16 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ManagerPayload
 			PersistentKeepaliveInterval: &keepalive,
 			PersistentKeepaliveInterval: &keepalive,
 			ReplaceAllowedIPs:           true,
 			ReplaceAllowedIPs:           true,
 		})
 		})
+		peerConfMap[peer.PublicKey] = manager.PeerConf{
+			Address: peer.PrimaryAddress(),
+		}
 		if !onlyPeers && peer.IsRelayed == "yes" {
 		if !onlyPeers && peer.IsRelayed == "yes" {
 			relayNode := FindRelay(&peer)
 			relayNode := FindRelay(&peer)
 			if relayNode != nil {
 			if relayNode != nil {
 				relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayNode.Endpoint, relayNode.LocalListenPort))
 				relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayNode.Endpoint, relayNode.LocalListenPort))
 				if err == nil {
 				if err == nil {
 					peerConfMap[peer.PublicKey] = manager.PeerConf{
 					peerConfMap[peer.PublicKey] = manager.PeerConf{
+
 						IsRelayed: true,
 						IsRelayed: true,
 						RelayedTo: relayTo,
 						RelayedTo: relayTo,
 						Address:   peer.PrimaryAddress(),
 						Address:   peer.PrimaryAddress(),

+ 15 - 15
netclient/functions/mqhandlers.go

@@ -14,7 +14,6 @@ import (
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/netclient/config"
 	"github.com/gravitl/netmaker/netclient/config"
-	"github.com/gravitl/netmaker/netclient/local"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/netclient/wireguard"
 	"github.com/gravitl/netmaker/netclient/wireguard"
 	"github.com/gravitl/netmaker/nm-proxy/manager"
 	"github.com/gravitl/netmaker/nm-proxy/manager"
@@ -53,6 +52,7 @@ func ProxyUpdate(client mqtt.Client, msg mqtt.Message) {
 
 
 // NodeUpdate -- mqtt message handler for /update/<NodeID> topic
 // NodeUpdate -- mqtt message handler for /update/<NodeID> topic
 func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
 func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
+	return
 	var newNode models.Node
 	var newNode models.Node
 	var nodeCfg config.ClientConfig
 	var nodeCfg config.ClientConfig
 	var network = parseNetworkFromTopic(msg.Topic())
 	var network = parseNetworkFromTopic(msg.Topic())
@@ -252,22 +252,22 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
 		UpdateLocalListenPort(&cfg)
 		UpdateLocalListenPort(&cfg)
 		return
 		return
 	}
 	}
-	queryAddr := cfg.Node.PrimaryAddress()
+	// queryAddr := cfg.Node.PrimaryAddress()
 
 
 	//err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
 	//err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
-	var iface = cfg.Node.Interface
-	if ncutils.IsMac() {
-		iface, err = local.GetMacIface(queryAddr)
-		if err != nil {
-			logger.Log(0, "error retrieving mac iface: "+err.Error())
-			return
-		}
-	}
-	err = wireguard.SetPeers(iface, &cfg.Node, peerUpdate.Peers)
-	if err != nil {
-		logger.Log(0, "error syncing wg after peer update: "+err.Error())
-		return
-	}
+	// var iface = cfg.Node.Interface
+	// if ncutils.IsMac() {
+	// 	iface, err = local.GetMacIface(queryAddr)
+	// 	if err != nil {
+	// 		logger.Log(0, "error retrieving mac iface: "+err.Error())
+	// 		return
+	// 	}
+	// }
+	// err = wireguard.SetPeers(iface, &cfg.Node, peerUpdate.Peers)
+	// if err != nil {
+	// 	logger.Log(0, "error syncing wg after peer update: "+err.Error())
+	// 	return
+	// }
 	ProxyMgmChan <- &peerUpdate.ProxyUpdate
 	ProxyMgmChan <- &peerUpdate.ProxyUpdate
 	logger.Log(0, "network:", cfg.Node.Network, "received peer update for node "+cfg.Node.Name+" "+cfg.Node.Network)
 	logger.Log(0, "network:", cfg.Node.Network, "received peer update for node "+cfg.Node.Name+" "+cfg.Node.Network)
 	if cfg.Node.DNSOn == "yes" {
 	if cfg.Node.DNSOn == "yes" {

+ 13 - 9
nm-proxy/common/common.go

@@ -42,14 +42,13 @@ type ConnConfig struct {
 }
 }
 
 
 type Config struct {
 type Config struct {
-	Port         int
-	BodySize     int
-	Addr         string
-	RemoteKey    string
-	LocalKey     string
-	WgInterface  *wg.WGIface
-	AllowedIps   []net.IPNet
-	PreSharedKey *wgtypes.Key
+	Port        int
+	BodySize    int
+	Addr        string
+	RemoteKey   string
+	LocalKey    string
+	WgInterface *wg.WGIface
+	PeerConf    *wgtypes.PeerConfig
 }
 }
 
 
 // Proxy -  WireguardProxy proxies
 // Proxy -  WireguardProxy proxies
@@ -70,7 +69,12 @@ type RemotePeer struct {
 	IsAttachedExtClient bool
 	IsAttachedExtClient bool
 }
 }
 
 
-var WgIFaceMap = make(map[string]map[string]*Conn)
+type WgIfaceConf struct {
+	Iface   *wgtypes.Device
+	PeerMap map[string]*Conn
+}
+
+var WgIFaceMap = make(map[string]WgIfaceConf)
 
 
 var PeerKeyHashMap = make(map[string]RemotePeer)
 var PeerKeyHashMap = make(map[string]RemotePeer)
 
 

+ 107 - 71
nm-proxy/manager/manager.go

@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"fmt"
 	"log"
 	"log"
 	"net"
 	"net"
+	"reflect"
 	"runtime"
 	"runtime"
 	"time"
 	"time"
 
 
@@ -59,6 +60,7 @@ const (
 	AddInterface ProxyAction = "ADD_INTERFACE"
 	AddInterface ProxyAction = "ADD_INTERFACE"
 	DeletePeer   ProxyAction = "DELETE_PEER"
 	DeletePeer   ProxyAction = "DELETE_PEER"
 	UpdatePeer   ProxyAction = "UPDATE_PEER"
 	UpdatePeer   ProxyAction = "UPDATE_PEER"
+	AddPeer      ProxyAction = "ADD_PEER"
 	RelayPeers   ProxyAction = "RELAY_PEERS"
 	RelayPeers   ProxyAction = "RELAY_PEERS"
 	RelayUpdate  ProxyAction = "RELAY_UPDATE"
 	RelayUpdate  ProxyAction = "RELAY_UPDATE"
 	RelayTo      ProxyAction = "RELAY_TO"
 	RelayTo      ProxyAction = "RELAY_TO"
@@ -90,7 +92,7 @@ func StartProxyManager(manageChan chan *ManagerAction) {
 			case UpdatePeer:
 			case UpdatePeer:
 				//mI.UpdatePeerProxy()
 				//mI.UpdatePeerProxy()
 			case DeletePeer:
 			case DeletePeer:
-				mI.DeletePeers()
+
 			case RelayPeers:
 			case RelayPeers:
 				mI.RelayPeers()
 				mI.RelayPeers()
 			case RelayUpdate:
 			case RelayUpdate:
@@ -135,98 +137,132 @@ func (m *ManagerAction) RelayPeers() {
 	}
 	}
 }
 }
 
 
-func (m *ManagerAction) DeletePeers() {
-	if len(m.Payload.Peers) == 0 {
-		log.Println("No Peers to delete...")
-		return
+func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
+	var err error
+	var wgIface *wg.WGIface
+	if m.Payload.InterfaceName == "" {
+		return nil, errors.New("interface cannot be empty")
 	}
 	}
-	peersMap, ok := common.WgIFaceMap[m.Payload.InterfaceName]
-	if !ok {
-		log.Println("interface not found: ", m.Payload.InterfaceName)
-		return
+	if len(m.Payload.Peers) == 0 {
+		return nil, errors.New("no peers to add")
 	}
 	}
 
 
-	for _, peerI := range m.Payload.Peers {
-		if peerConf, ok := peersMap[peerI.PublicKey.String()]; ok {
-			peerConf.Proxy.Cancel()
-			delete(peersMap, peerI.PublicKey.String())
+	if runtime.GOOS == "darwin" {
+		m.Payload.InterfaceName, err = wg.GetRealIface(m.Payload.InterfaceName)
+		if err != nil {
+			log.Println("failed to get real iface: ", err)
 		}
 		}
 	}
 	}
-	common.WgIFaceMap[m.Payload.InterfaceName] = peersMap
-}
-
-func (m *ManagerAction) UpdatePeerProxy() {
-	if len(m.Payload.Peers) == 0 {
-		log.Println("No Peers to add...")
-		return
+	wgIface, err = wg.NewWGIFace(m.Payload.InterfaceName, "127.0.0.1/32", wg.DefaultMTU)
+	if err != nil {
+		log.Println("Failed init new interface: ", err)
+		return nil, err
 	}
 	}
-	peers, ok := common.WgIFaceMap[m.Payload.InterfaceName]
-	if !ok {
-		log.Println("interface not found: ", m.Payload.InterfaceName)
-		return
+	var wgProxyConf common.WgIfaceConf
+	var ok bool
+	if wgProxyConf, ok = common.WgIFaceMap[m.Payload.InterfaceName]; !ok {
+		return wgIface, nil
 	}
 	}
+	// sync map with wg device config
+	// check if listen port has changed
+	if wgIface.Device.ListenPort != wgProxyConf.Iface.ListenPort {
+		// reset proxy for this interface
 
 
-	for _, peerI := range m.Payload.Peers {
-		peerConf := m.Payload.PeerMap[peerI.PublicKey.String()]
-		if peerI.Endpoint == nil && !peerConf.IsExtClient {
-			log.Println("Endpoint nil for peer: ", peerI.PublicKey.String())
-			continue
-		}
-
-		if peerConf, ok := peers[peerI.PublicKey.String()]; ok {
-
-			peerConf.Config.RemoteWgPort = peerI.Endpoint.Port
-			peers[peerI.PublicKey.String()] = peerConf
-			common.WgIFaceMap[m.Payload.InterfaceName] = peers
-			log.Printf("---->####### Updated PEER: %+v\n", peerConf)
+		log.Println("########------------>  CLEANING UP: ", m.Payload.InterfaceName)
+		for _, peerI := range wgProxyConf.PeerMap {
+			peerI.Proxy.Cancel()
 		}
 		}
+		delete(common.WgIFaceMap, m.Payload.InterfaceName)
+		return wgIface, nil
 	}
 	}
+	wgProxyConf.Iface = wgIface.Device
+	for i := len(m.Payload.Peers) - 1; i >= 0; i-- {
+		if currentPeer, ok := wgProxyConf.PeerMap[m.Payload.Peers[i].PublicKey.String()]; ok {
+			// check if peer is not connected to proxy
+			devPeer, err := wg.GetPeer(m.Payload.InterfaceName, currentPeer.Config.Key)
+			if err == nil {
+				log.Printf("---------> COMAPRING ENDP{INT}: DEV: %s, Proxy: %s", devPeer.Endpoint.String(), currentPeer.Proxy.LocalConn.LocalAddr().String())
+				if devPeer.Endpoint.String() != currentPeer.Proxy.LocalConn.LocalAddr().String() {
+					log.Println("---------> endpoint is not set to proxy: ", currentPeer.Config.Key)
+					currentPeer.Proxy.Cancel()
+					delete(wgProxyConf.PeerMap, currentPeer.Config.Key)
+					continue
+				}
+			}
+			if !reflect.DeepEqual(m.Payload.Peers[i], *currentPeer.Proxy.Config.PeerConf) {
+				if currentPeer.Proxy.RemoteConn.IP.String() != m.Payload.Peers[i].Endpoint.IP.String() {
+					log.Println("----------> Resetting proxy for Peer: ", currentPeer.Config.Key, m.Payload.InterfaceName)
+					currentPeer.Proxy.Cancel()
+					delete(wgProxyConf.PeerMap, currentPeer.Config.Key)
+
+				} else {
+
+					log.Println("----->##### Updating Peer on Interface: ", m.Payload.InterfaceName, currentPeer.Config.Key)
+					updatePeerConf := m.Payload.Peers[i]
+					localUdpAddr, err := net.ResolveUDPAddr("udp", currentPeer.Proxy.LocalConn.LocalAddr().String())
+					if err == nil {
+						updatePeerConf.Endpoint = localUdpAddr
+					}
+					if err := wgIface.Update(updatePeerConf); err != nil {
+						log.Println("failed to update peer: ", currentPeer.Config.Key, err)
+					}
+					currentPeer.Proxy.Config.PeerConf = &m.Payload.Peers[i]
+					wgProxyConf.PeerMap[currentPeer.Config.Key] = currentPeer
+					// delete the peer from the list
+					log.Println("-----------> deleting peer from list: ", m.Payload.Peers[i].PublicKey)
+					m.Payload.Peers = append(m.Payload.Peers[:i], m.Payload.Peers[i+1:]...)
 
 
-}
+				}
+
+			} else {
+				// delete the peer from the list
+				log.Println("-----------> No updates observed so deleting peer: ", m.Payload.Peers[i].PublicKey)
+				m.Payload.Peers = append(m.Payload.Peers[:i], m.Payload.Peers[i+1:]...)
+			}
 
 
-func cleanUp(iface string) {
-	if peers, ok := common.WgIFaceMap[iface]; ok {
-		log.Println("########------------>  CLEANING UP: ", iface)
-		for _, peerI := range peers {
-			peerI.Proxy.Cancel()
 		}
 		}
 	}
 	}
-	delete(common.WgIFaceMap, iface)
-	delete(common.PeerAddrMap, iface)
-	if waitThs, ok := common.ExtClientsWaitTh[iface]; ok {
-		for _, cancelF := range waitThs {
-			cancelF()
+	for _, currPeerI := range wgProxyConf.PeerMap {
+		if _, ok := m.Payload.PeerMap[currPeerI.Config.Key]; !ok {
+			currPeerI.Proxy.Cancel()
+			// delete peer from interface
+			log.Println("CurrPeer Not Found, Deleting Peer from Interface: ", currPeerI.Config.Key)
+			if err := wgIface.RemovePeer(currPeerI.Config.Key); err != nil {
+				log.Println("failed to remove peer: ", currPeerI.Config.Key, err)
+			}
+			delete(wgProxyConf.PeerMap, currPeerI.Config.Key)
+
 		}
 		}
-		delete(common.ExtClientsWaitTh, iface)
 	}
 	}
+	common.WgIFaceMap[m.Payload.InterfaceName] = wgProxyConf
+
+	// if peers, ok := common.WgIFaceMap[iface]; ok {
+	// 	log.Println("########------------>  CLEANING UP: ", iface)
+	// 	for _, peerI := range peers {
+	// 		peerI.Proxy.Cancel()
+	// 	}
+	// }
+	// delete(common.WgIFaceMap, iface)
+	// delete(common.PeerAddrMap, iface)
+	// if waitThs, ok := common.ExtClientsWaitTh[iface]; ok {
+	// 	for _, cancelF := range waitThs {
+	// 		cancelF()
+	// 	}
+	// 	delete(common.ExtClientsWaitTh, iface)
+	// }
 
 
 	log.Println("CLEANED UP..........")
 	log.Println("CLEANED UP..........")
+	return wgIface, nil
 }
 }
 
 
 func (m *ManagerAction) AddInterfaceToProxy() error {
 func (m *ManagerAction) AddInterfaceToProxy() error {
 	var err error
 	var err error
-	if m.Payload.InterfaceName == "" {
-		return errors.New("interface cannot be empty")
-	}
-	if len(m.Payload.Peers) == 0 {
-		log.Println("No Peers to add...")
-		return nil
-	}
-	ifaceName := m.Payload.InterfaceName
-	log.Println("--------> IFACE: ", ifaceName)
-	if runtime.GOOS == "darwin" {
-		ifaceName, err = wg.GetRealIface(ifaceName)
-		if err != nil {
-			log.Println("failed to get real iface: ", err)
-		}
-	}
-	cleanUp(ifaceName)
 
 
-	wgInterface, err := wg.NewWGIFace(ifaceName, "127.0.0.1/32", wg.DefaultMTU)
+	wgInterface, err := m.processPayload()
 	if err != nil {
 	if err != nil {
-		log.Println("Failed init new interface: ", err)
 		return err
 		return err
 	}
 	}
+
 	log.Printf("wg: %+v\n", wgInterface)
 	log.Printf("wg: %+v\n", wgInterface)
 	wgListenAddr, err := proxy.GetInterfaceListenAddr(wgInterface.Port)
 	wgListenAddr, err := proxy.GetInterfaceListenAddr(wgInterface.Port)
 	if err != nil {
 	if err != nil {
@@ -272,7 +308,7 @@ func (m *ManagerAction) AddInterfaceToProxy() error {
 		}
 		}
 		if shouldProceed {
 		if shouldProceed {
 			common.PeerKeyHashMap[fmt.Sprintf("%x", md5.Sum([]byte(peerI.PublicKey.String())))] = common.RemotePeer{
 			common.PeerKeyHashMap[fmt.Sprintf("%x", md5.Sum([]byte(peerI.PublicKey.String())))] = common.RemotePeer{
-				Interface:           ifaceName,
+				Interface:           m.Payload.InterfaceName,
 				PeerKey:             peerI.PublicKey.String(),
 				PeerKey:             peerI.PublicKey.String(),
 				IsExtClient:         peerConf.IsExtClient,
 				IsExtClient:         peerConf.IsExtClient,
 				Endpoint:            peerI.Endpoint,
 				Endpoint:            peerI.Endpoint,
@@ -295,7 +331,7 @@ func (m *ManagerAction) AddInterfaceToProxy() error {
 			log.Println("Extclient endpoint not updated yet....skipping")
 			log.Println("Extclient endpoint not updated yet....skipping")
 			// TODO - watch the interface for ext client update
 			// TODO - watch the interface for ext client update
 			go func(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig,
 			go func(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig,
-				isRelayed, isExtClient, isAttachedExtClient bool, relayTo *net.UDPAddr, peerConf PeerConf) {
+				isRelayed bool, relayTo *net.UDPAddr, peerConf PeerConf) {
 				addExtClient := false
 				addExtClient := false
 				ctx, cancel := context.WithCancel(context.Background())
 				ctx, cancel := context.WithCancel(context.Background())
 				common.ExtClientsWaitTh[wgInterface.Name] = append(common.ExtClientsWaitTh[wgInterface.Name], cancel)
 				common.ExtClientsWaitTh[wgInterface.Name] = append(common.ExtClientsWaitTh[wgInterface.Name], cancel)
@@ -321,7 +357,7 @@ func (m *ManagerAction) AddInterfaceToProxy() error {
 						log.Println("Exiting extclient watch Thread for: ", wgInterface.Device.PublicKey.String())
 						log.Println("Exiting extclient watch Thread for: ", wgInterface.Device.PublicKey.String())
 						return
 						return
 					default:
 					default:
-						wgInterface, err := wg.NewWGIFace(ifaceName, "127.0.0.1/32", wg.DefaultMTU)
+						wgInterface, err := wg.NewWGIFace(m.Payload.InterfaceName, "127.0.0.1/32", wg.DefaultMTU)
 						if err != nil {
 						if err != nil {
 							log.Println("Failed init new interface: ", err)
 							log.Println("Failed init new interface: ", err)
 							return
 							return
@@ -338,7 +374,7 @@ func (m *ManagerAction) AddInterfaceToProxy() error {
 
 
 				}
 				}
 
 
-			}(wgInterface, &peerI, isRelayed, peerConf.IsExtClient, peerConf.IsAttachedExtClient, relayedTo, peerConf)
+			}(wgInterface, &peerI, isRelayed, relayedTo, peerConf)
 			continue
 			continue
 		}
 		}
 
 

+ 10 - 5
nm-proxy/peer/peer.go

@@ -41,7 +41,7 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri
 		LocalKey:    wgInterface.Device.PublicKey.String(),
 		LocalKey:    wgInterface.Device.PublicKey.String(),
 		RemoteKey:   peer.PublicKey.String(),
 		RemoteKey:   peer.PublicKey.String(),
 		WgInterface: wgInterface,
 		WgInterface: wgInterface,
-		AllowedIps:  peer.AllowedIPs,
+		PeerConf:    peer,
 	}
 	}
 	p := proxy.NewProxy(c)
 	p := proxy.NewProxy(c)
 	peerPort := common.NmProxyPort
 	peerPort := common.NmProxyPort
@@ -91,7 +91,7 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri
 			LocalKey:    wgInterface.Device.PublicKey.String(),
 			LocalKey:    wgInterface.Device.PublicKey.String(),
 			RemoteKey:   peer.PublicKey.String(),
 			RemoteKey:   peer.PublicKey.String(),
 			WgInterface: wgInterface,
 			WgInterface: wgInterface,
-			AllowedIps:  peer.AllowedIPs,
+			PeerConf:    peer,
 		},
 		},
 
 
 		RemoteConn: remoteConn,
 		RemoteConn: remoteConn,
@@ -105,10 +105,15 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri
 		Proxy:  peerProxy,
 		Proxy:  peerProxy,
 	}
 	}
 	if _, ok := common.WgIFaceMap[wgInterface.Name]; ok {
 	if _, ok := common.WgIFaceMap[wgInterface.Name]; ok {
-		common.WgIFaceMap[wgInterface.Name][peer.PublicKey.String()] = &peerConn
+		common.WgIFaceMap[wgInterface.Name].PeerMap[peer.PublicKey.String()] = &peerConn
 	} else {
 	} else {
-		common.WgIFaceMap[wgInterface.Name] = make(map[string]*common.Conn)
-		common.WgIFaceMap[wgInterface.Name][peer.PublicKey.String()] = &peerConn
+		ifaceConf := common.WgIfaceConf{
+			Iface:   wgInterface.Device,
+			PeerMap: make(map[string]*common.Conn),
+		}
+
+		common.WgIFaceMap[wgInterface.Name] = ifaceConf
+		common.WgIFaceMap[wgInterface.Name].PeerMap[peer.PublicKey.String()] = &peerConn
 	}
 	}
 	if _, ok := common.PeerAddrMap[wgInterface.Name]; ok {
 	if _, ok := common.PeerAddrMap[wgInterface.Name]; ok {
 		common.PeerAddrMap[wgInterface.Name][peerAddr] = &peerConn
 		common.PeerAddrMap[wgInterface.Name][peerAddr] = &peerConn

+ 7 - 8
nm-proxy/proxy/proxy.go

@@ -17,14 +17,13 @@ const (
 )
 )
 
 
 type Config struct {
 type Config struct {
-	Port         int
-	BodySize     int
-	Addr         string
-	RemoteKey    string
-	LocalKey     string
-	WgInterface  *wg.WGIface
-	AllowedIps   []net.IPNet
-	PreSharedKey *wgtypes.Key
+	Port        int
+	BodySize    int
+	Addr        string
+	RemoteKey   string
+	LocalKey    string
+	WgInterface *wg.WGIface
+	PeerConf    *wgtypes.PeerConfig
 }
 }
 
 
 // Proxy -  WireguardProxy proxies
 // Proxy -  WireguardProxy proxies

+ 12 - 22
nm-proxy/proxy/wireguard.go

@@ -25,7 +25,6 @@ func NewProxy(config Config) *Proxy {
 // proxyToRemote proxies everything from Wireguard to the RemoteKey peer
 // proxyToRemote proxies everything from Wireguard to the RemoteKey peer
 func (p *Proxy) ProxyToRemote() {
 func (p *Proxy) ProxyToRemote() {
 
 
-	peers := common.WgIFaceMap[p.Config.WgInterface.Name]
 	go func() {
 	go func() {
 		<-p.Ctx.Done()
 		<-p.Ctx.Done()
 		log.Println("Closing connection for: ", p.LocalConn.LocalAddr().String())
 		log.Println("Closing connection for: ", p.LocalConn.LocalAddr().String())
@@ -61,15 +60,15 @@ func (p *Proxy) ProxyToRemote() {
 				continue
 				continue
 			}
 			}
 			//go func(buf []byte, n int) {
 			//go func(buf []byte, n int) {
-
-			if peerI, ok := peers[p.Config.RemoteKey]; ok {
-				//var srcPeerKeyHash, dstPeerKeyHash string
-				buf, n, _, _ = packet.ProcessPacketBeforeSending(buf, n, peerI.Config.LocalKey, peerI.Config.Key)
+			ifaceConf := common.WgIFaceMap[p.Config.WgInterface.Name]
+			if peerI, ok := ifaceConf.PeerMap[p.Config.RemoteKey]; ok {
+				var srcPeerKeyHash, dstPeerKeyHash string
+				buf, n, srcPeerKeyHash, dstPeerKeyHash = packet.ProcessPacketBeforeSending(buf, n, peerI.Config.LocalKey, peerI.Config.Key)
 				if err != nil {
 				if err != nil {
 					log.Println("failed to process pkt before sending: ", err)
 					log.Println("failed to process pkt before sending: ", err)
 				}
 				}
-				// log.Printf("PROXING TO REMOTE!!!---> %s >>>>> %s >>>>> %s [[ SrcPeerHash: %s, DstPeerHash: %s ]]\n",
-				// 	p.LocalConn.LocalAddr(), server.NmProxyServer.Server.LocalAddr().String(), p.RemoteConn.String(), srcPeerKeyHash, dstPeerKeyHash)
+				log.Printf("PROXING TO REMOTE!!!---> %s >>>>> %s >>>>> %s [[ SrcPeerHash: %s, DstPeerHash: %s ]]\n",
+					p.LocalConn.LocalAddr(), server.NmProxyServer.Server.LocalAddr().String(), p.RemoteConn.String(), srcPeerKeyHash, dstPeerKeyHash)
 			} else {
 			} else {
 				log.Printf("Peer: %s not found in config\n", p.Config.RemoteKey)
 				log.Printf("Peer: %s not found in config\n", p.Config.RemoteKey)
 				p.Cancel()
 				p.Cancel()
@@ -99,9 +98,9 @@ func (p *Proxy) updateEndpoint() error {
 		return err
 		return err
 	}
 	}
 	// add local proxy connection as a Wireguard peer
 	// add local proxy connection as a Wireguard peer
-	log.Printf("---> ## Updating Peer:  %+v\n", p.Config)
-	err = p.Config.WgInterface.UpdatePeer(p.Config.RemoteKey, p.Config.AllowedIps, wg.DefaultWgKeepAlive,
-		udpAddr, p.Config.PreSharedKey)
+	log.Printf("---> ####### Updating Peer:  %+v\n", p.Config.PeerConf)
+	err = p.Config.WgInterface.UpdatePeer(p.Config.RemoteKey, p.Config.PeerConf.AllowedIPs, wg.DefaultWgKeepAlive,
+		udpAddr, p.Config.PeerConf.PresharedKey)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -113,17 +112,8 @@ func (p *Proxy) Start(remoteConn *net.UDPAddr) error {
 	p.RemoteConn = remoteConn
 	p.RemoteConn = remoteConn
 
 
 	var err error
 	var err error
-	// err = p.Config.WgInterface.GetWgIface(p.Config.WgInterface.Name)
-	// if err != nil {
-	// 	log.Println("Failed to get iface: ", p.Config.WgInterface.Name, err)
-	// 	return err
-	// }
-	// wgAddr, err := GetInterfaceIpv4Addr(p.Config.WgInterface.Name)
-	// if err != nil {
-	// 	log.Println("failed to get interface addr: ", err)
-	// 	return err
-	// }
-	log.Printf("----> WGIFACE: %+v\n", p.Config.WgInterface)
+
+	//log.Printf("----> WGIFACE: %+v\n", p.Config.WgInterface)
 	addr, err := GetFreeIp(common.DefaultCIDR, p.Config.WgInterface.Port)
 	addr, err := GetFreeIp(common.DefaultCIDR, p.Config.WgInterface.Port)
 	if err != nil {
 	if err != nil {
 		log.Println("Failed to get freeIp: ", err)
 		log.Println("Failed to get freeIp: ", err)
@@ -137,7 +127,7 @@ func (p *Proxy) Start(remoteConn *net.UDPAddr) error {
 	if runtime.GOOS == "darwin" {
 	if runtime.GOOS == "darwin" {
 		wgListenAddr.IP = net.ParseIP(addr)
 		wgListenAddr.IP = net.ParseIP(addr)
 	}
 	}
-	log.Println("--------->#### Wg Listen Addr: ", wgListenAddr.String())
+	//log.Println("--------->#### Wg Listen Addr: ", wgListenAddr.String())
 	p.LocalConn, err = net.DialUDP("udp", &net.UDPAddr{
 	p.LocalConn, err = net.DialUDP("udp", &net.UDPAddr{
 		IP:   net.ParseIP(addr),
 		IP:   net.ParseIP(addr),
 		Port: common.NmProxyPort,
 		Port: common.NmProxyPort,

+ 8 - 7
nm-proxy/server/server.go

@@ -2,6 +2,7 @@ package server
 
 
 import (
 import (
 	"context"
 	"context"
+	"fmt"
 	"log"
 	"log"
 	"net"
 	"net"
 	"time"
 	"time"
@@ -42,9 +43,9 @@ func (p *ProxyServer) Listen(ctx context.Context) {
 		case <-ctx.Done():
 		case <-ctx.Done():
 			log.Println("--------->### Shutting down Proxy.....")
 			log.Println("--------->### Shutting down Proxy.....")
 			// clean up proxy connections
 			// clean up proxy connections
-			for iface, peers := range common.WgIFaceMap {
+			for iface, ifaceConf := range common.WgIFaceMap {
 				log.Println("########------------>  CLEANING UP: ", iface)
 				log.Println("########------------>  CLEANING UP: ", iface)
-				for _, peerI := range peers {
+				for _, peerI := range ifaceConf.PeerMap {
 					peerI.Proxy.Cancel()
 					peerI.Proxy.Cancel()
 				}
 				}
 			}
 			}
@@ -114,11 +115,11 @@ func (p *ProxyServer) Listen(ctx context.Context) {
 			}
 			}
 
 
 			if peerInfo, ok := common.PeerKeyHashMap[srcPeerKeyHash]; ok {
 			if peerInfo, ok := common.PeerKeyHashMap[srcPeerKeyHash]; ok {
-				if peers, ok := common.WgIFaceMap[peerInfo.Interface]; ok {
-					if peerI, ok := peers[peerInfo.PeerKey]; ok {
-						// log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s   [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
-						// 	peerI.Proxy.LocalConn.RemoteAddr(), peerI.Proxy.LocalConn.LocalAddr(),
-						// 	fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String())
+				if ifaceConf, ok := common.WgIFaceMap[peerInfo.Interface]; ok {
+					if peerI, ok := ifaceConf.PeerMap[peerInfo.PeerKey]; ok {
+						log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s   [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
+							peerI.Proxy.LocalConn.RemoteAddr(), peerI.Proxy.LocalConn.LocalAddr(),
+							fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String())
 						_, err = peerI.Proxy.LocalConn.Write(buffer[:n])
 						_, err = peerI.Proxy.LocalConn.Write(buffer[:n])
 						if err != nil {
 						if err != nil {
 							log.Println("Failed to proxy to Wg local interface: ", err)
 							log.Println("Failed to proxy to Wg local interface: ", err)

+ 73 - 3
nm-proxy/wg/wg.go

@@ -124,9 +124,9 @@ func (w *WGIface) UpdatePeer(peerKey string, allowedIps []net.IPNet, keepAlive t
 		return err
 		return err
 	}
 	}
 	peer := wgtypes.PeerConfig{
 	peer := wgtypes.PeerConfig{
-		PublicKey: peerKeyParsed,
-		// ReplaceAllowedIPs:           true,
-		// AllowedIPs:                  allowedIps,
+		PublicKey:                   peerKeyParsed,
+		ReplaceAllowedIPs:           true,
+		AllowedIPs:                  allowedIps,
 		PersistentKeepaliveInterval: &keepAlive,
 		PersistentKeepaliveInterval: &keepAlive,
 		PresharedKey:                preSharedKey,
 		PresharedKey:                preSharedKey,
 		Endpoint:                    endpoint,
 		Endpoint:                    endpoint,
@@ -234,3 +234,73 @@ func RunCmd(command string, printerr bool) (string, error) {
 	}
 	}
 	return string(out), err
 	return string(out), err
 }
 }
+
+// RemovePeer removes a Wireguard Peer from the interface iface
+func (w *WGIface) RemovePeer(peerKey string) error {
+	w.mu.Lock()
+	defer w.mu.Unlock()
+
+	log.Printf("Removing peer %s from interface %s ", peerKey, w.Name)
+
+	peerKeyParsed, err := wgtypes.ParseKey(peerKey)
+	if err != nil {
+		return err
+	}
+
+	peer := wgtypes.PeerConfig{
+		PublicKey: peerKeyParsed,
+		Remove:    true,
+	}
+
+	config := wgtypes.Config{
+		Peers: []wgtypes.PeerConfig{peer},
+	}
+	err = w.configureDevice(config)
+	if err != nil {
+		return fmt.Errorf("received error \"%v\" while removing peer %s from interface %s", err, peerKey, w.Name)
+	}
+	return nil
+}
+
+// UpdatePeer
+func (w *WGIface) Update(peerConf wgtypes.PeerConfig) error {
+	w.mu.Lock()
+	defer w.mu.Unlock()
+	var err error
+	log.Printf("---------> NEWWWWWW Updating peer %+v from interface %s ", peerConf, w.Name)
+
+	peerConf.UpdateOnly = true
+	peerConf.ReplaceAllowedIPs = true
+	config := wgtypes.Config{
+		Peers: []wgtypes.PeerConfig{peerConf},
+	}
+	err = w.configureDevice(config)
+	if err != nil {
+		return fmt.Errorf("received error \"%v\" while Updating peer %s from interface %s", err, peerConf.PublicKey.String(), w.Name)
+	}
+	return nil
+}
+
+func GetPeer(ifaceName, peerPubKey string) (wgtypes.Peer, error) {
+	wg, err := wgctrl.New()
+	if err != nil {
+		return wgtypes.Peer{}, err
+	}
+	defer func() {
+		err = wg.Close()
+		if err != nil {
+			log.Printf("got error while closing wgctl: %v", err)
+		}
+	}()
+
+	wgDevice, err := wg.Device(ifaceName)
+	if err != nil {
+		return wgtypes.Peer{}, err
+	}
+	for _, peer := range wgDevice.Peers {
+		if peer.PublicKey.String() == peerPubKey {
+			return peer, nil
+		}
+	}
+	return wgtypes.Peer{}, fmt.Errorf("peer not found")
+}