Browse Source

peer updates over proxy using a custome message

Abhishek Kondur 2 years ago
parent
commit
6feb9916cc

+ 4 - 4
nm-proxy/manager/manager.go

@@ -255,8 +255,8 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
 			// check if peer is not connected to proxy
 			devPeer, err := wg.GetPeer(m.Payload.InterfaceName, currentPeer.Key.String())
 			if err == nil {
-				log.Printf("---------> COMAPRING ENDPOINT: DEV: %s, Proxy: %s", devPeer.Endpoint.String(), currentPeer.LocalConn.LocalAddr().String())
-				if devPeer.Endpoint.String() != currentPeer.LocalConn.LocalAddr().String() {
+				log.Printf("---------> COMAPRING ENDPOINT: DEV: %s, Proxy: %s", devPeer.Endpoint.String(), currentPeer.LocalConnAddr.String())
+				if devPeer.Endpoint.String() != currentPeer.LocalConnAddr.String() {
 					log.Println("---------> endpoint is not set to proxy: ", currentPeer.Key)
 					currentPeer.StopConn()
 					delete(wgProxyConf.PeerMap, currentPeer.Key.String())
@@ -280,7 +280,7 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
 				continue
 			}
 			if !reflect.DeepEqual(m.Payload.Peers[i], *currentPeer.PeerConf) {
-				if currentPeer.RemoteConn.IP.String() != m.Payload.Peers[i].Endpoint.IP.String() {
+				if currentPeer.RemoteConnAddr.IP.String() != m.Payload.Peers[i].Endpoint.IP.String() {
 					log.Println("----------> Resetting proxy for Peer: ", currentPeer.Key, m.Payload.InterfaceName)
 					currentPeer.StopConn()
 					delete(wgProxyConf.PeerMap, currentPeer.Key.String())
@@ -289,7 +289,7 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
 
 					log.Println("----->##### Updating Peer on Interface: ", m.Payload.InterfaceName, currentPeer.Key)
 					updatePeerConf := m.Payload.Peers[i]
-					localUdpAddr, err := net.ResolveUDPAddr("udp", currentPeer.LocalConn.LocalAddr().String())
+					localUdpAddr, err := net.ResolveUDPAddr("udp", currentPeer.LocalConnAddr.String())
 					if err == nil {
 						updatePeerConf.Endpoint = localUdpAddr
 					}

+ 13 - 0
nm-proxy/metrics/metrics.go

@@ -19,6 +19,19 @@ type Metric struct {
 	TrafficRecieved     uint64
 }
 
+type MetricsPayload struct {
+	MetricType MetricsUpdateType
+	Value      interface{}
+}
+
+type MetricsUpdateType uint32
+
+const (
+	LatencyUpdate         MetricsUpdateType = 1
+	TrafficSentUpdate     MetricsUpdateType = 2
+	TrafficRecievedUpdate MetricsUpdateType = 3
+)
+
 var MetricsMapLock = &sync.Mutex{}
 
 var MetricsMap = make(map[string]Metric)

+ 6 - 3
nm-proxy/models/peer.go

@@ -22,9 +22,12 @@ type ConnConfig struct {
 	RelayedEndpoint     *net.UDPAddr
 	IsAttachedExtClient bool
 	PeerConf            *wgtypes.PeerConfig
-	StopConn            context.CancelFunc
-	RemoteConn          *net.UDPAddr
-	LocalConn           net.Conn
+	StopConn            func()
+	ResetConn           func()
+	PeerListenPort      uint32
+	RemoteConnAddr      *net.UDPAddr
+	LocalConnAddr       *net.UDPAddr
+	RecieverChan        chan []byte
 }
 
 type RemotePeer struct {

+ 15 - 0
nm-proxy/packet/packet.go

@@ -76,6 +76,21 @@ func CreateProxyUpdatePacket(msg *ProxyUpdateMessage) ([]byte, error) {
 
 }
 
+func ConsumeProxyUpdateMsg(buf []byte) (*ProxyUpdateMessage, error) {
+	var msg ProxyUpdateMessage
+	reader := bytes.NewReader(buf[:])
+	err := binary.Read(reader, binary.LittleEndian, &msg)
+	if err != nil {
+		log.Println("Failed to decode proxy update message")
+		return nil, err
+	}
+
+	if msg.Type != MessageProxyUpdateType {
+		return nil, errors.New("not proxy update message")
+	}
+	return &msg, nil
+}
+
 func CreateMetricPacket(id uint32, sender, reciever wgtypes.Key) ([]byte, error) {
 	msg := MetricMessage{
 		Type:      MessageMetricsType,

+ 2 - 0
nm-proxy/packet/packet_helper.go

@@ -46,5 +46,7 @@ type ProxyMessage struct {
 type ProxyUpdateMessage struct {
 	Type       MessageType
 	Action     ProxyActionType
+	Sender     wgtypes.Key
+	Reciever   wgtypes.Key
 	ListenPort uint32
 }

+ 25 - 24
nm-proxy/peer/peer.go

@@ -2,11 +2,12 @@ package peer
 
 import (
 	"errors"
-	"fmt"
 	"log"
 	"net"
+	"time"
 
 	"github.com/gravitl/netmaker/nm-proxy/common"
+	"github.com/gravitl/netmaker/nm-proxy/metrics"
 	"github.com/gravitl/netmaker/nm-proxy/models"
 	"github.com/gravitl/netmaker/nm-proxy/proxy"
 	"github.com/gravitl/netmaker/nm-proxy/wg"
@@ -15,14 +16,19 @@ import (
 
 func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr string,
 	isRelayed, isExtClient, isAttachedExtClient bool, relayTo *net.UDPAddr) error {
-
+	if peer.PersistentKeepaliveInterval == nil {
+		d := time.Second * 25
+		peer.PersistentKeepaliveInterval = &d
+	}
 	c := proxy.Config{
-		Port:        peer.Endpoint.Port,
-		LocalKey:    wgInterface.Device.PublicKey,
-		RemoteKey:   peer.PublicKey,
-		WgInterface: wgInterface,
-		IsExtClient: isExtClient,
-		PeerConf:    peer,
+		LocalKey:            wgInterface.Device.PublicKey,
+		RemoteKey:           peer.PublicKey,
+		WgInterface:         wgInterface,
+		IsExtClient:         isExtClient,
+		PeerConf:            peer,
+		PersistentKeepalive: peer.PersistentKeepaliveInterval,
+		RecieverChan:        make(chan []byte, 100),
+		MetricsCh:           make(chan metrics.MetricsPayload, 30),
 	}
 	p := proxy.NewProxy(c)
 	peerPort := models.NmProxyPort
@@ -30,30 +36,22 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri
 		peerPort = peer.Endpoint.Port
 
 	}
-	peerEndpoint := peer.Endpoint.IP.String()
+	peerEndpoint := peer.Endpoint.IP
 	if isRelayed {
 		//go server.NmProxyServer.KeepAlive(peer.Endpoint.IP.String(), common.NmProxyPort)
 		if relayTo == nil {
 			return errors.New("relay endpoint is nil")
 		}
-		peerEndpoint = relayTo.IP.String()
-	}
-
-	remoteConn, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", peerEndpoint, peerPort))
-	if err != nil {
-		return err
+		peerEndpoint = relayTo.IP
 	}
-	log.Printf("----> Established Remote Conn with RPeer: %s, ----> RAddr: %s", peer.PublicKey, remoteConn.String())
+	p.Config.PeerIp = peerEndpoint
+	p.Config.PeerPort = uint32(peerPort)
 
-	// if !(isExtClient && isAttachedExtClient) {
 	log.Printf("Starting proxy for Peer: %s\n", peer.PublicKey.String())
-	err = p.Start(remoteConn)
+	lAddr, rAddr, err := p.Start()
 	if err != nil {
 		return err
 	}
-	// } else {
-	// 	log.Println("Not Starting Proxy for Attached ExtClient...")
-	// }
 
 	connConf := models.ConnConfig{
 		Key:                 peer.PublicKey,
@@ -61,9 +59,12 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri
 		RelayedEndpoint:     relayTo,
 		IsAttachedExtClient: isAttachedExtClient,
 		PeerConf:            peer,
-		StopConn:            p.Cancel,
-		RemoteConn:          remoteConn,
-		LocalConn:           p.LocalConn,
+		StopConn:            p.Close,
+		ResetConn:           p.Reset,
+		RemoteConnAddr:      rAddr,
+		LocalConnAddr:       lAddr,
+		RecieverChan:        p.Config.RecieverChan,
+		PeerListenPort:      p.Config.PeerPort,
 	}
 
 	common.WgIfaceMap.PeerMap[peer.PublicKey.String()] = &connConf

+ 82 - 25
nm-proxy/proxy/proxy.go

@@ -4,9 +4,14 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"log"
 	"net"
+	"runtime"
+	"time"
 
 	"github.com/gravitl/netmaker/nm-proxy/common"
+	"github.com/gravitl/netmaker/nm-proxy/metrics"
+	"github.com/gravitl/netmaker/nm-proxy/models"
 	"github.com/gravitl/netmaker/nm-proxy/wg"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
@@ -17,14 +22,18 @@ const (
 )
 
 type Config struct {
-	Port        int
-	BodySize    int
-	Addr        string
-	RemoteKey   wgtypes.Key
-	LocalKey    wgtypes.Key
-	WgInterface *wg.WGIface
-	IsExtClient bool
-	PeerConf    *wgtypes.PeerConfig
+	BodySize            int
+	Addr                string
+	RemoteKey           wgtypes.Key
+	LocalKey            wgtypes.Key
+	WgInterface         *wg.WGIface
+	IsExtClient         bool
+	PersistentKeepalive *time.Duration
+	RecieverChan        chan []byte
+	MetricsCh           chan metrics.MetricsPayload
+	PeerConf            *wgtypes.PeerConfig
+	PeerIp              net.IP
+	PeerPort            uint32
 }
 
 // Proxy -  WireguardProxy proxies
@@ -36,27 +45,75 @@ type Proxy struct {
 	LocalConn  net.Conn
 }
 
-func GetInterfaceIpv4Addr(interfaceName string) (addr string, err error) {
-	var (
-		ief      *net.Interface
-		addrs    []net.Addr
-		ipv4Addr net.IP
-	)
-	if ief, err = net.InterfaceByName(interfaceName); err != nil { // get interface
-		return
+func (p *Proxy) Start() (*net.UDPAddr, *net.UDPAddr, error) {
+
+	var err error
+	remoteConn, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", p.Config.PeerIp.String(), p.Config.PeerPort))
+	if err != nil {
+		return nil, nil, err
 	}
-	if addrs, err = ief.Addrs(); err != nil { // get addresses
-		return
+	p.RemoteConn = remoteConn
+	log.Printf("----> Established Remote Conn with RPeer: %s, ----> RAddr: %s", p.Config.RemoteKey.String(), remoteConn.String())
+	//log.Printf("----> WGIFACE: %+v\n", p.Config.WgInterface)
+	addr, err := GetFreeIp(models.DefaultCIDR, p.Config.WgInterface.Port)
+	if err != nil {
+		log.Println("Failed to get freeIp: ", err)
+		return nil, nil, err
 	}
-	for _, addr := range addrs { // get ipv4 address
-		if ipv4Addr = addr.(*net.IPNet).IP.To4(); ipv4Addr != nil {
-			break
-		}
+	wgListenAddr, err := GetInterfaceListenAddr(p.Config.WgInterface.Port)
+	if err != nil {
+		log.Println("failed to get wg listen addr: ", err)
+		return nil, nil, err
+	}
+	if runtime.GOOS == "darwin" {
+		wgListenAddr.IP = net.ParseIP(addr)
+	}
+	//log.Println("--------->#### Wg Listen Addr: ", wgListenAddr.String())
+	p.LocalConn, err = net.DialUDP("udp", &net.UDPAddr{
+		IP:   net.ParseIP(addr),
+		Port: models.NmProxyPort,
+	}, wgListenAddr)
+	if err != nil {
+		log.Printf("failed dialing to local Wireguard port,Err: %v\n", err)
+		return nil, nil, err
+	}
+
+	log.Printf("Dialing to local Wireguard port %s --> %s\n", p.LocalConn.LocalAddr().String(), p.LocalConn.RemoteAddr().String())
+	err = p.updateEndpoint()
+	if err != nil {
+		log.Printf("error while updating Wireguard peer endpoint [%s] %v\n", p.Config.RemoteKey, err)
+		return nil, nil, err
+	}
+	localAddr, err := net.ResolveUDPAddr("udp", p.LocalConn.LocalAddr().String())
+	if err != nil {
+		log.Println("failed to resolve local addr: ", err)
+		return nil, nil, err
 	}
-	if ipv4Addr == nil {
-		return "", errors.New(fmt.Sprintf("interface %s don't have an ipv4 address\n", interfaceName))
+	go p.ProxyPeer()
+
+	return localAddr, p.RemoteConn, nil
+}
+
+func (p *Proxy) Close() {
+	log.Println("------> Closing Proxy for ", p.Config.RemoteKey.String())
+	p.Cancel()
+	p.LocalConn.Close()
+	if runtime.GOOS == "darwin" {
+		host, _, err := net.SplitHostPort(p.LocalConn.LocalAddr().String())
+		if err != nil {
+			log.Println("Failed to split host: ", p.LocalConn.LocalAddr().String(), err)
+			return
+		}
+
+		if host != "127.0.0.1" {
+			_, err = common.RunCmd(fmt.Sprintf("ifconfig lo0 -alias %s 255.255.255.255", host), true)
+			if err != nil {
+				log.Println("Failed to add alias: ", err)
+			}
+		}
+
 	}
-	return ipv4Addr.String(), nil
+	close(p.Config.RecieverChan)
 }
 
 func GetInterfaceListenAddr(port int) (*net.UDPAddr, error) {

+ 85 - 69
nm-proxy/proxy/wireguard.go → nm-proxy/proxy/proxy_helper.go

@@ -8,6 +8,7 @@ import (
 	"net"
 	"runtime"
 	"strings"
+	"sync"
 	"time"
 
 	"github.com/c-robinson/iplib"
@@ -17,6 +18,7 @@ import (
 	"github.com/gravitl/netmaker/nm-proxy/models"
 	"github.com/gravitl/netmaker/nm-proxy/packet"
 	"github.com/gravitl/netmaker/nm-proxy/server"
+	"github.com/gravitl/netmaker/nm-proxy/stun"
 	"github.com/gravitl/netmaker/nm-proxy/wg"
 )
 
@@ -26,38 +28,35 @@ func NewProxy(config Config) *Proxy {
 	return p
 }
 
-// proxyToRemote proxies everything from Wireguard to the RemoteKey peer
-func (p *Proxy) ProxyToRemote() {
-	ticker := time.NewTicker(time.Minute)
-	buf := make([]byte, 65000)
-	go func() {
-		<-p.Ctx.Done()
-		log.Println("Closing connection for: ", p.LocalConn.LocalAddr().String())
-		ticker.Stop()
-		buf = nil
-		p.LocalConn.Close()
-	}()
+func (p *Proxy) proxyToLocal(wg *sync.WaitGroup, ticker *time.Ticker) {
+
+	defer wg.Done()
 
 	for {
 		select {
 		case <-p.Ctx.Done():
-			log.Printf("----------> stopped proxying to remote peer %s due to closed connection\n", p.Config.RemoteKey)
-			if runtime.GOOS == "darwin" {
-				host, _, err := net.SplitHostPort(p.LocalConn.LocalAddr().String())
-				if err != nil {
-					log.Println("Failed to split host: ", p.LocalConn.LocalAddr().String(), err)
-					return
-				}
-
-				if host != "127.0.0.1" {
-					_, err = common.RunCmd(fmt.Sprintf("ifconfig lo0 -alias %s 255.255.255.255", host), true)
-					if err != nil {
-						log.Println("Failed to add alias: ", err)
-					}
-				}
-
+			return
+		case buffer := <-p.Config.RecieverChan:
+			ticker.Reset(*p.Config.PersistentKeepalive + time.Second*5)
+			log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s  \n",
+				p.LocalConn.RemoteAddr(), p.LocalConn.LocalAddr())
+			_, err := p.LocalConn.Write(buffer[:])
+			if err != nil {
+				log.Println("Failed to proxy to Wg local interface: ", err)
 			}
+		}
+	}
 
+}
+
+func (p *Proxy) proxyToRemote(wg *sync.WaitGroup) {
+	ticker := time.NewTicker(time.Minute)
+	defer ticker.Stop()
+	buf := make([]byte, 65000)
+	defer wg.Done()
+	for {
+		select {
+		case <-p.Ctx.Done():
 			return
 		case <-ticker.C:
 			metrics.MetricsMapLock.Lock()
@@ -102,7 +101,7 @@ func (p *Proxy) ProxyToRemote() {
 					p.LocalConn.LocalAddr(), server.NmProxyServer.Server.LocalAddr().String(), p.RemoteConn.String(), srcPeerKeyHash, dstPeerKeyHash)
 			} else {
 				log.Printf("Peer: %s not found in config\n", p.Config.RemoteKey)
-				p.Cancel()
+				p.Close()
 				return
 			}
 
@@ -113,6 +112,65 @@ func (p *Proxy) ProxyToRemote() {
 
 		}
 	}
+
+}
+
+func (p *Proxy) Reset() {
+	p.Close()
+	p.pullLatestConfig()
+	p.Start()
+
+}
+
+func (p *Proxy) pullLatestConfig() {
+	if peer, ok := common.WgIfaceMap.PeerMap[p.Config.RemoteKey.String()]; ok {
+		p.Config.PeerPort = peer.PeerListenPort
+	}
+}
+
+func (p *Proxy) peerUpdates(wg *sync.WaitGroup, ticker *time.Ticker) {
+	defer wg.Done()
+	for {
+		select {
+		case <-p.Ctx.Done():
+			return
+		case <-ticker.C:
+			// send listen port packet
+			m := &packet.ProxyUpdateMessage{
+				Type:       packet.MessageProxyType,
+				Action:     packet.UpdateListenPort,
+				Sender:     p.Config.LocalKey,
+				Reciever:   p.Config.RemoteKey,
+				ListenPort: uint32(stun.Host.PrivPort),
+			}
+			pkt, err := packet.CreateProxyUpdatePacket(m)
+			if err == nil {
+				log.Printf("-----------> ##### $$$$$ SENDING Proxy Update PACKET TO: %s\n", p.RemoteConn.String())
+				_, err = server.NmProxyServer.Server.WriteToUDP(pkt, p.RemoteConn)
+				if err != nil {
+					log.Println("Failed to send to metric pkt: ", err)
+				}
+
+			}
+		}
+	}
+}
+
+// ProxyPeer proxies everything from Wireguard to the RemoteKey peer and vice-versa
+func (p *Proxy) ProxyPeer() {
+	ticker := time.NewTicker(*p.Config.PersistentKeepalive)
+	defer ticker.Stop()
+	wg := &sync.WaitGroup{}
+	wg.Add(1)
+	go p.proxyToLocal(wg, ticker)
+	wg.Add(1)
+	go p.proxyToRemote(wg)
+	// if common.BehindNAT {
+	wg.Add(1)
+	go p.peerUpdates(wg, ticker)
+	// }
+	wg.Wait()
+
 }
 func test(n int, buffer []byte) {
 	data := buffer[:n]
@@ -137,47 +195,6 @@ func (p *Proxy) updateEndpoint() error {
 	return nil
 }
 
-func (p *Proxy) Start(remoteConn *net.UDPAddr) error {
-	p.RemoteConn = remoteConn
-
-	var err error
-
-	//log.Printf("----> WGIFACE: %+v\n", p.Config.WgInterface)
-	addr, err := GetFreeIp(models.DefaultCIDR, p.Config.WgInterface.Port)
-	if err != nil {
-		log.Println("Failed to get freeIp: ", err)
-		return err
-	}
-	wgListenAddr, err := GetInterfaceListenAddr(p.Config.WgInterface.Port)
-	if err != nil {
-		log.Println("failed to get wg listen addr: ", err)
-		return err
-	}
-	if runtime.GOOS == "darwin" {
-		wgListenAddr.IP = net.ParseIP(addr)
-	}
-	//log.Println("--------->#### Wg Listen Addr: ", wgListenAddr.String())
-	p.LocalConn, err = net.DialUDP("udp", &net.UDPAddr{
-		IP:   net.ParseIP(addr),
-		Port: models.NmProxyPort,
-	}, wgListenAddr)
-	if err != nil {
-		log.Printf("failed dialing to local Wireguard port,Err: %v\n", err)
-		return err
-	}
-
-	log.Printf("Dialing to local Wireguard port %s --> %s\n", p.LocalConn.LocalAddr().String(), p.LocalConn.RemoteAddr().String())
-	err = p.updateEndpoint()
-	if err != nil {
-		log.Printf("error while updating Wireguard peer endpoint [%s] %v\n", p.Config.RemoteKey, err)
-		return err
-	}
-
-	go p.ProxyToRemote()
-
-	return nil
-}
-
 func GetFreeIp(cidrAddr string, dstPort int) (string, error) {
 	//ensure AddressRange is valid
 	if dstPort == 0 {
@@ -189,7 +206,6 @@ func GetFreeIp(cidrAddr string, dstPort int) (string, error) {
 	}
 	net4 := iplib.Net4FromStr(cidrAddr)
 	newAddrs := net4.FirstAddress()
-	log.Println("COUNT: ", net4.Count())
 	for {
 		if runtime.GOOS == "darwin" {
 			_, err := common.RunCmd(fmt.Sprintf("ifconfig lo0 alias %s 255.255.255.255", newAddrs.String()), true)

+ 39 - 21
nm-proxy/server/server.go

@@ -3,7 +3,6 @@ package server
 import (
 	"context"
 	"encoding/binary"
-	"fmt"
 	"log"
 	"net"
 	"time"
@@ -65,14 +64,14 @@ func (p *ProxyServer) Listen(ctx context.Context) {
 			}
 			//go func(buffer []byte, source *net.UDPAddr, n int) {
 			origBufferLen := n
-			fromProxy := true
+			proxyTransportMsg := true
 			var srcPeerKeyHash, dstPeerKeyHash string
 			n, srcPeerKeyHash, dstPeerKeyHash, err = packet.ExtractInfo(buffer, n)
 			if err != nil {
-				log.Println("proxy message not found: ", err)
-				fromProxy = false
+				log.Println("proxy transport message not found: ", err)
+				proxyTransportMsg = false
 			}
-			if fromProxy {
+			if proxyTransportMsg {
 				proxyIncomingPacket(buffer[:], source, n, srcPeerKeyHash, dstPeerKeyHash)
 				continue
 
@@ -86,14 +85,15 @@ func (p *ProxyServer) Listen(ctx context.Context) {
 						metric.ConnectionStatus = true
 						metrics.MetricsMap[peerInfo.PeerKey] = metric
 						metrics.MetricsMapLock.Unlock()
-						log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s   [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
-							peerI.LocalConn.RemoteAddr(), peerI.LocalConn.LocalAddr(),
-							fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String())
-						_, err = peerI.LocalConn.Write(buffer[:n])
-						if err != nil {
-							log.Println("Failed to proxy to Wg local interface: ", err)
-							//continue
-						}
+						peerI.RecieverChan <- buffer[:n]
+						// log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s   [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
+						// 	peerI.LocalConn.RemoteAddr(), peerI.LocalConn.LocalAddr(),
+						// 	fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String())
+						// _, err = peerI.LocalConn.Write(buffer[:n])
+						// if err != nil {
+						// 	log.Println("Failed to proxy to Wg local interface: ", err)
+						// 	//continue
+						// }
 						continue
 
 					}
@@ -133,6 +133,23 @@ func (p *ProxyServer) Listen(ctx context.Context) {
 						metrics.MetricsMapLock.Unlock()
 					}
 				}
+			case packet.MessageProxyUpdateType:
+				msg, err := packet.ConsumeProxyUpdateMsg(buffer[:origBufferLen])
+				if err == nil {
+					switch msg.Action {
+					case packet.UpdateListenPort:
+						if peer, ok := common.WgIfaceMap.PeerMap[msg.Sender.String()]; ok {
+							if peer.PeerListenPort != msg.ListenPort {
+								// update peer conn
+								peer.PeerListenPort = msg.ListenPort
+								common.WgIfaceMap.PeerMap[msg.Sender.String()] = peer
+								log.Println("--------> Resetting Proxy Conn For Peer ", msg.Sender.String())
+								peer.ResetConn()
+							}
+
+						}
+					}
+				}
 			// consume handshake message for ext clients
 			case packet.MessageInitiationType:
 
@@ -191,14 +208,15 @@ func proxyIncomingPacket(buffer []byte, source *net.UDPAddr, n int, srcPeerKeyHa
 			metric.ConnectionStatus = true
 			metrics.MetricsMap[peerInfo.PeerKey] = metric
 			metrics.MetricsMapLock.Unlock()
-			log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s   [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
-				peerI.LocalConn.RemoteAddr(), peerI.LocalConn.LocalAddr(),
-				fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String())
-			_, err = peerI.LocalConn.Write(buffer[:n])
-			if err != nil {
-				log.Println("Failed to proxy to Wg local interface: ", err)
-				//continue
-			}
+			peerI.RecieverChan <- buffer[:n]
+			// log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s   [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
+			// 	peerI.LocalConn.RemoteAddr(), peerI.LocalConn.LocalAddr(),
+			// 	fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String())
+			// _, err = peerI.LocalConn.Write(buffer[:n])
+			// if err != nil {
+			// 	log.Println("Failed to proxy to Wg local interface: ", err)
+			// 	//continue
+			// }
 			return
 		}