Browse Source

route inbound packets to relayed node

Abhishek Kondur 2 years ago
parent
commit
ce5e7bee4a
5 changed files with 62 additions and 26 deletions
  1. 12 4
      logic/peers.go
  2. 35 17
      nm-proxy/manager/manager.go
  3. 1 2
      nm-proxy/peer/peer.go
  4. 2 2
      nm-proxy/proxy/wireguard.go
  5. 12 1
      nm-proxy/server/server.go

+ 12 - 4
logic/peers.go

@@ -45,15 +45,23 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ManagerPayload
 				logger.Log(1, "failed to relayed nodes: ", node.Name, err.Error())
 				logger.Log(1, "failed to relayed nodes: ", node.Name, err.Error())
 				proxyPayload.IsRelay = false
 				proxyPayload.IsRelay = false
 			} else {
 			} else {
-				relayPeersMap := make(map[string][]wgtypes.PeerConfig)
+				relayPeersMap := make(map[string]manager.RelayedConf)
 				for _, relayedNode := range relayedNodes {
 				for _, relayedNode := range relayedNodes {
 					payload, err := GetPeersForProxy(&relayedNode, true)
 					payload, err := GetPeersForProxy(&relayedNode, true)
 					if err == nil {
 					if err == nil {
-						relayPeersMap[relayedNode.PublicKey] = payload.Peers
+						relayedEndpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayedNode.Endpoint, relayedNode.LocalListenPort))
+						if udpErr == nil {
+							relayPeersMap[relayedNode.PublicKey] = manager.RelayedConf{
+								RelayedPeerEndpoint: relayedEndpoint,
+								RelayedPeerPubKey:   relayedNode.PublicKey,
+								Peers:               payload.Peers,
+							}
+						}
+
 					}
 					}
 				}
 				}
 				proxyPayload.IsRelay = true
 				proxyPayload.IsRelay = true
-				proxyPayload.RelayedPeers = relayPeersMap
+				proxyPayload.RelayedPeerConf = relayPeersMap
 			}
 			}
 		}
 		}
 	}
 	}
@@ -89,7 +97,7 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ManagerPayload
 		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", peer.Endpoint, peer.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,

+ 35 - 17
nm-proxy/manager/manager.go

@@ -17,13 +17,19 @@ import (
 type ProxyAction string
 type ProxyAction string
 
 
 type ManagerPayload struct {
 type ManagerPayload struct {
-	InterfaceName string                          `json:"interface_name"`
-	Peers         []wgtypes.PeerConfig            `json:"peers"`
-	PeerMap       map[string]PeerConf             `json:"peer_map"`
-	IsRelayed     bool                            `json:"is_relayed"`
-	RelayedTo     *net.UDPAddr                    `json:"relayed_to"`
-	IsRelay       bool                            `json:"is_relay"`
-	RelayedPeers  map[string][]wgtypes.PeerConfig `json:"relayed_peers"`
+	InterfaceName   string                 `json:"interface_name"`
+	Peers           []wgtypes.PeerConfig   `json:"peers"`
+	PeerMap         map[string]PeerConf    `json:"peer_map"`
+	IsRelayed       bool                   `json:"is_relayed"`
+	RelayedTo       *net.UDPAddr           `json:"relayed_to"`
+	IsRelay         bool                   `json:"is_relay"`
+	RelayedPeerConf map[string]RelayedConf `json:"relayed_conf"`
+}
+
+type RelayedConf struct {
+	RelayedPeerEndpoint *net.UDPAddr         `json:"relayed_peer_endpoint"`
+	RelayedPeerPubKey   string               `json:"relayed_peer_pub_key"`
+	Peers               []wgtypes.PeerConfig `json:"relayed_peers"`
 }
 }
 type PeerConf struct {
 type PeerConf struct {
 	IsRelayed bool         `json:"is_relayed"`
 	IsRelayed bool         `json:"is_relayed"`
@@ -80,21 +86,22 @@ func (m *ManagerAction) RelayUpdate() {
 
 
 func (m *ManagerAction) RelayPeers() {
 func (m *ManagerAction) RelayPeers() {
 	common.IsRelay = true
 	common.IsRelay = true
-	for relayedNodePubKey, peers := range m.Payload.RelayedPeers {
-		for _, peer := range peers {
-			if _, ok := common.RelayPeerMap[relayedNodePubKey]; !ok {
-				common.RelayPeerMap[relayedNodePubKey] = make(map[string]common.RemotePeer)
-			}
+	for relayedNodePubKey, relayedNodeConf := range m.Payload.RelayedPeerConf {
+		relayedNodePubKeyHash := fmt.Sprintf("%x", md5.Sum([]byte(relayedNodePubKey)))
+		if _, ok := common.RelayPeerMap[relayedNodePubKeyHash]; !ok {
+			common.RelayPeerMap[relayedNodePubKeyHash] = make(map[string]common.RemotePeer)
+		}
+		for _, peer := range relayedNodeConf.Peers {
 			peer.Endpoint.Port = common.NmProxyPort
 			peer.Endpoint.Port = common.NmProxyPort
-			relayedNodePubKeyHash := fmt.Sprintf("%x", md5.Sum([]byte(relayedNodePubKey)))
 			remotePeerKeyHash := fmt.Sprintf("%x", md5.Sum([]byte(peer.PublicKey.String())))
 			remotePeerKeyHash := fmt.Sprintf("%x", md5.Sum([]byte(peer.PublicKey.String())))
-			if _, ok := common.RelayPeerMap[relayedNodePubKeyHash]; !ok {
-				common.RelayPeerMap[relayedNodePubKeyHash] = make(map[string]common.RemotePeer)
-			}
 			common.RelayPeerMap[relayedNodePubKeyHash][remotePeerKeyHash] = common.RemotePeer{
 			common.RelayPeerMap[relayedNodePubKeyHash][remotePeerKeyHash] = common.RemotePeer{
 				Endpoint: peer.Endpoint,
 				Endpoint: peer.Endpoint,
 			}
 			}
 		}
 		}
+		relayedNodeConf.RelayedPeerEndpoint.Port = common.NmProxyPort
+		common.RelayPeerMap[relayedNodePubKeyHash][relayedNodePubKeyHash] = common.RemotePeer{
+			Endpoint: relayedNodeConf.RelayedPeerEndpoint,
+		}
 
 
 	}
 	}
 }
 }
@@ -192,8 +199,19 @@ func (m *ManagerAction) AddInterfaceToProxy() error {
 			Interface: ifaceName,
 			Interface: ifaceName,
 			PeerKey:   peerI.PublicKey.String(),
 			PeerKey:   peerI.PublicKey.String(),
 		}
 		}
+		var isRelayed bool
+		var relayedTo *net.UDPAddr
+		if m.Payload.IsRelayed {
+			isRelayed = true
+			relayedTo = m.Payload.RelayedTo
+		} else {
+			if val, ok := m.Payload.PeerMap[peerI.PublicKey.String()]; ok {
+				isRelayed = val.IsRelayed
+				relayedTo = val.RelayedTo
+			}
+		}
 
 
-		peerpkg.AddNewPeer(wgInterface, &peerI, m.Payload.IsRelayed, m.Payload.RelayedTo)
+		peerpkg.AddNewPeer(wgInterface, &peerI, isRelayed, relayedTo)
 	}
 	}
 	log.Printf("------> PEERHASHMAP: %+v\n", common.PeerKeyHashMap)
 	log.Printf("------> PEERHASHMAP: %+v\n", common.PeerKeyHashMap)
 	return nil
 	return nil

+ 1 - 2
nm-proxy/peer/peer.go

@@ -8,7 +8,6 @@ import (
 
 
 	"github.com/gravitl/netmaker/nm-proxy/common"
 	"github.com/gravitl/netmaker/nm-proxy/common"
 	"github.com/gravitl/netmaker/nm-proxy/proxy"
 	"github.com/gravitl/netmaker/nm-proxy/proxy"
-	"github.com/gravitl/netmaker/nm-proxy/server"
 	"github.com/gravitl/netmaker/nm-proxy/wg"
 	"github.com/gravitl/netmaker/nm-proxy/wg"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 )
@@ -47,7 +46,7 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, isRelayed boo
 
 
 	peerEndpoint := peer.Endpoint.IP.String()
 	peerEndpoint := peer.Endpoint.IP.String()
 	if isRelayed {
 	if isRelayed {
-		go server.NmProxyServer.KeepAlive(peer.Endpoint.IP.String(), common.NmProxyPort)
+		//go server.NmProxyServer.KeepAlive(peer.Endpoint.IP.String(), common.NmProxyPort)
 		peerEndpoint = relayTo.IP.String()
 		peerEndpoint = relayTo.IP.String()
 	}
 	}
 	remoteConn, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", peerEndpoint, common.NmProxyPort))
 	remoteConn, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", peerEndpoint, common.NmProxyPort))

+ 2 - 2
nm-proxy/proxy/wireguard.go

@@ -63,8 +63,8 @@ func (p *Proxy) ProxyToRemote() {
 				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 [[ DstPort: %d, SrcPeerHash: %s, DstPeerHash: %s ]]\n",
-					server.NmProxyServer.Server.LocalAddr().String(), p.RemoteConn.String(), peerI.Config.RemoteWgPort, srcPeerKeyHash, dstPeerKeyHash)
+				log.Printf("PROXING TO REMOTE!!!---> %s >>>>> %s [[ SrcPeerHash: %s, DstPeerHash: %s ]]\n",
+					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)
 				continue
 				continue

+ 12 - 1
nm-proxy/server/server.go

@@ -46,7 +46,7 @@ func (p *ProxyServer) Listen() {
 		var srcPeerKeyHash, dstPeerKeyHash string
 		var srcPeerKeyHash, dstPeerKeyHash string
 		n, srcPeerKeyHash, dstPeerKeyHash = packet.ExtractInfo(buffer, n)
 		n, srcPeerKeyHash, dstPeerKeyHash = packet.ExtractInfo(buffer, n)
 		//log.Printf("--------> RECV PKT [DSTPORT: %d], [SRCKEYHASH: %s], SourceIP: [%s] \n", localWgPort, srcPeerKeyHash, source.IP.String())
 		//log.Printf("--------> RECV PKT [DSTPORT: %d], [SRCKEYHASH: %s], SourceIP: [%s] \n", localWgPort, srcPeerKeyHash, source.IP.String())
-		if common.IsRelay && dstPeerKeyHash != "" {
+		if common.IsRelay && dstPeerKeyHash != "" && srcPeerKeyHash != "" {
 			if _, ok := common.WgIfaceKeyMap[dstPeerKeyHash]; !ok {
 			if _, ok := common.WgIfaceKeyMap[dstPeerKeyHash]; !ok {
 
 
 				log.Println("----------> Relaying######")
 				log.Println("----------> Relaying######")
@@ -60,6 +60,17 @@ func (p *ProxyServer) Listen() {
 							log.Println("Failed to send to remote: ", err)
 							log.Println("Failed to send to remote: ", err)
 						}
 						}
 					}
 					}
+				} else {
+					if remoteMap, ok := common.RelayPeerMap[dstPeerKeyHash]; ok {
+						if conf, ok := remoteMap[dstPeerKeyHash]; ok {
+							log.Printf("--------> Relaying BACK TO RELAYED NODE PKT [ SourceIP: %s ], [ SourceKeyHash: %s ], [ DstIP: %s ], [ DstHashKey: %s ] \n",
+								source.String(), srcPeerKeyHash, conf.Endpoint.String(), dstPeerKeyHash)
+							_, err = NmProxyServer.Server.WriteToUDP(buffer[:n+32], conf.Endpoint)
+							if err != nil {
+								log.Println("Failed to send to remote: ", err)
+							}
+						}
+					}
 				}
 				}
 
 
 			}
 			}