mirror of
https://github.com/gravitl/netmaker.git
synced 2025-11-10 00:30:37 +08:00
refactor proxy code
This commit is contained in:
parent
6feb9916cc
commit
1d4b915f2d
11 changed files with 289 additions and 256 deletions
|
|
@ -18,7 +18,7 @@ var BehindNAT bool
|
||||||
|
|
||||||
var WgIfaceMap = models.WgIfaceConf{
|
var WgIfaceMap = models.WgIfaceConf{
|
||||||
Iface: nil,
|
Iface: nil,
|
||||||
PeerMap: make(map[string]*models.ConnConfig),
|
PeerMap: make(map[string]*models.Conn),
|
||||||
}
|
}
|
||||||
|
|
||||||
var PeerKeyHashMap = make(map[string]models.RemotePeer)
|
var PeerKeyHashMap = make(map[string]models.RemotePeer)
|
||||||
|
|
|
||||||
22
nm-proxy/common/functions.go
Normal file
22
nm-proxy/common/functions.go
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gravitl/netmaker/nm-proxy/models"
|
||||||
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPeer(peerKey wgtypes.Key) (*models.Conn, bool) {
|
||||||
|
var peerInfo *models.Conn
|
||||||
|
var found bool
|
||||||
|
peerInfo, found = WgIfaceMap.PeerMap[peerKey.String()]
|
||||||
|
peerInfo.Mutex.RLock()
|
||||||
|
defer peerInfo.Mutex.RUnlock()
|
||||||
|
return peerInfo, found
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdatePeer(peer *models.Conn) {
|
||||||
|
peer.Mutex.Lock()
|
||||||
|
defer peer.Mutex.Unlock()
|
||||||
|
WgIfaceMap.PeerMap[peer.Key.String()] = peer
|
||||||
|
}
|
||||||
|
|
@ -141,9 +141,12 @@ func (m *ManagerAction) RelayPeers() {
|
||||||
func cleanUpInterface() {
|
func cleanUpInterface() {
|
||||||
log.Println("########------------> CLEANING UP: ", common.WgIfaceMap.Iface.Name)
|
log.Println("########------------> CLEANING UP: ", common.WgIfaceMap.Iface.Name)
|
||||||
for _, peerI := range common.WgIfaceMap.PeerMap {
|
for _, peerI := range common.WgIfaceMap.PeerMap {
|
||||||
|
peerI.Mutex.Lock()
|
||||||
peerI.StopConn()
|
peerI.StopConn()
|
||||||
|
peerI.Mutex.Unlock()
|
||||||
|
delete(common.WgIfaceMap.PeerMap, peerI.Key.String())
|
||||||
}
|
}
|
||||||
common.WgIfaceMap.PeerMap = make(map[string]*models.ConnConfig)
|
common.WgIfaceMap.PeerMap = make(map[string]*models.Conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
|
func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
|
||||||
|
|
@ -209,6 +212,7 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
|
||||||
for _, currPeerI := range wgProxyConf.Iface.Peers {
|
for _, currPeerI := range wgProxyConf.Iface.Peers {
|
||||||
if _, ok := m.Payload.PeerMap[currPeerI.PublicKey.String()]; !ok {
|
if _, ok := m.Payload.PeerMap[currPeerI.PublicKey.String()]; !ok {
|
||||||
if val, ok := wgProxyConf.PeerMap[currPeerI.PublicKey.String()]; ok {
|
if val, ok := wgProxyConf.PeerMap[currPeerI.PublicKey.String()]; ok {
|
||||||
|
val.Mutex.Lock()
|
||||||
if val.IsAttachedExtClient {
|
if val.IsAttachedExtClient {
|
||||||
log.Println("------> Deleting ExtClient Watch Thread: ", currPeerI.PublicKey.String())
|
log.Println("------> Deleting ExtClient Watch Thread: ", currPeerI.PublicKey.String())
|
||||||
if val, ok := common.ExtClientsWaitTh[currPeerI.PublicKey.String()]; ok {
|
if val, ok := common.ExtClientsWaitTh[currPeerI.PublicKey.String()]; ok {
|
||||||
|
|
@ -216,9 +220,11 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
|
||||||
delete(common.ExtClientsWaitTh, currPeerI.PublicKey.String())
|
delete(common.ExtClientsWaitTh, currPeerI.PublicKey.String())
|
||||||
}
|
}
|
||||||
log.Println("-----> Deleting Ext Client from Src Ip Map: ", currPeerI.PublicKey.String())
|
log.Println("-----> Deleting Ext Client from Src Ip Map: ", currPeerI.PublicKey.String())
|
||||||
delete(common.ExtSourceIpMap, val.PeerConf.Endpoint.String())
|
delete(common.ExtSourceIpMap, val.Config.PeerConf.Endpoint.String())
|
||||||
}
|
}
|
||||||
val.StopConn()
|
val.StopConn()
|
||||||
|
val.Mutex.Unlock()
|
||||||
|
delete(wgProxyConf.PeerMap, currPeerI.PublicKey.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete peer from interface
|
// delete peer from interface
|
||||||
|
|
@ -226,14 +232,15 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
|
||||||
if err := wgIface.RemovePeer(currPeerI.PublicKey.String()); err != nil {
|
if err := wgIface.RemovePeer(currPeerI.PublicKey.String()); err != nil {
|
||||||
log.Println("failed to remove peer: ", currPeerI.PublicKey.String(), err)
|
log.Println("failed to remove peer: ", currPeerI.PublicKey.String(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(common.PeerKeyHashMap, fmt.Sprintf("%x", md5.Sum([]byte(currPeerI.PublicKey.String()))))
|
delete(common.PeerKeyHashMap, fmt.Sprintf("%x", md5.Sum([]byte(currPeerI.PublicKey.String()))))
|
||||||
delete(wgProxyConf.PeerMap, currPeerI.PublicKey.String())
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := len(m.Payload.Peers) - 1; i >= 0; i-- {
|
for i := len(m.Payload.Peers) - 1; i >= 0; i-- {
|
||||||
|
|
||||||
if currentPeer, ok := wgProxyConf.PeerMap[m.Payload.Peers[i].PublicKey.String()]; ok {
|
if currentPeer, ok := wgProxyConf.PeerMap[m.Payload.Peers[i].PublicKey.String()]; ok {
|
||||||
|
currentPeer.Mutex.Lock()
|
||||||
if currentPeer.IsAttachedExtClient {
|
if currentPeer.IsAttachedExtClient {
|
||||||
m.Payload.Peers = append(m.Payload.Peers[:i], m.Payload.Peers[i+1:]...)
|
m.Payload.Peers = append(m.Payload.Peers[:i], m.Payload.Peers[i+1:]...)
|
||||||
continue
|
continue
|
||||||
|
|
@ -255,8 +262,8 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
|
||||||
// check if peer is not connected to proxy
|
// check if peer is not connected to proxy
|
||||||
devPeer, err := wg.GetPeer(m.Payload.InterfaceName, currentPeer.Key.String())
|
devPeer, err := wg.GetPeer(m.Payload.InterfaceName, currentPeer.Key.String())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Printf("---------> COMAPRING ENDPOINT: DEV: %s, Proxy: %s", devPeer.Endpoint.String(), currentPeer.LocalConnAddr.String())
|
log.Printf("---------> COMAPRING ENDPOINT: DEV: %s, Proxy: %s", devPeer.Endpoint.String(), currentPeer.Config.LocalConnAddr.String())
|
||||||
if devPeer.Endpoint.String() != currentPeer.LocalConnAddr.String() {
|
if devPeer.Endpoint.String() != currentPeer.Config.LocalConnAddr.String() {
|
||||||
log.Println("---------> endpoint is not set to proxy: ", currentPeer.Key)
|
log.Println("---------> endpoint is not set to proxy: ", currentPeer.Key)
|
||||||
currentPeer.StopConn()
|
currentPeer.StopConn()
|
||||||
delete(wgProxyConf.PeerMap, currentPeer.Key.String())
|
delete(wgProxyConf.PeerMap, currentPeer.Key.String())
|
||||||
|
|
@ -279,24 +286,25 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
|
||||||
delete(wgProxyConf.PeerMap, currentPeer.Key.String())
|
delete(wgProxyConf.PeerMap, currentPeer.Key.String())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(m.Payload.Peers[i], *currentPeer.PeerConf) {
|
if !reflect.DeepEqual(m.Payload.Peers[i], *currentPeer.Config.PeerConf) {
|
||||||
if currentPeer.RemoteConnAddr.IP.String() != m.Payload.Peers[i].Endpoint.IP.String() {
|
if currentPeer.Config.RemoteConnAddr.IP.String() != m.Payload.Peers[i].Endpoint.IP.String() {
|
||||||
log.Println("----------> Resetting proxy for Peer: ", currentPeer.Key, m.Payload.InterfaceName)
|
log.Println("----------> Resetting proxy for Peer: ", currentPeer.Key, m.Payload.InterfaceName)
|
||||||
currentPeer.StopConn()
|
currentPeer.StopConn()
|
||||||
|
currentPeer.Mutex.Unlock()
|
||||||
delete(wgProxyConf.PeerMap, currentPeer.Key.String())
|
delete(wgProxyConf.PeerMap, currentPeer.Key.String())
|
||||||
|
continue
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
log.Println("----->##### Updating Peer on Interface: ", m.Payload.InterfaceName, currentPeer.Key)
|
log.Println("----->##### Updating Peer on Interface: ", m.Payload.InterfaceName, currentPeer.Key)
|
||||||
updatePeerConf := m.Payload.Peers[i]
|
updatePeerConf := m.Payload.Peers[i]
|
||||||
localUdpAddr, err := net.ResolveUDPAddr("udp", currentPeer.LocalConnAddr.String())
|
localUdpAddr, err := net.ResolveUDPAddr("udp", currentPeer.Config.LocalConnAddr.String())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
updatePeerConf.Endpoint = localUdpAddr
|
updatePeerConf.Endpoint = localUdpAddr
|
||||||
}
|
}
|
||||||
if err := wgIface.Update(updatePeerConf, true); err != nil {
|
if err := wgIface.Update(updatePeerConf, true); err != nil {
|
||||||
log.Println("failed to update peer: ", currentPeer.Key, err)
|
log.Println("failed to update peer: ", currentPeer.Key, err)
|
||||||
}
|
}
|
||||||
currentPeer.PeerConf = &m.Payload.Peers[i]
|
currentPeer.Config.PeerConf = &m.Payload.Peers[i]
|
||||||
wgProxyConf.PeerMap[currentPeer.Key.String()] = currentPeer
|
wgProxyConf.PeerMap[currentPeer.Key.String()] = currentPeer
|
||||||
// delete the peer from the list
|
// delete the peer from the list
|
||||||
log.Println("-----------> deleting peer from list: ", m.Payload.Peers[i].PublicKey)
|
log.Println("-----------> deleting peer from list: ", m.Payload.Peers[i].PublicKey)
|
||||||
|
|
@ -309,6 +317,7 @@ func (m *ManagerAction) processPayload() (*wg.WGIface, error) {
|
||||||
log.Println("-----------> No updates observed so deleting peer: ", m.Payload.Peers[i].PublicKey)
|
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:]...)
|
m.Payload.Peers = append(m.Payload.Peers[:i], m.Payload.Peers[i+1:]...)
|
||||||
}
|
}
|
||||||
|
currentPeer.Mutex.Unlock()
|
||||||
|
|
||||||
} else if !m.Payload.PeerMap[m.Payload.Peers[i].PublicKey.String()].Proxy && !m.Payload.PeerMap[m.Payload.Peers[i].PublicKey.String()].IsAttachedExtClient {
|
} else if !m.Payload.PeerMap[m.Payload.Peers[i].PublicKey.String()].Proxy && !m.Payload.PeerMap[m.Payload.Peers[i].PublicKey.String()].IsAttachedExtClient {
|
||||||
log.Println("-----------> skipping peer, proxy is off: ", m.Payload.Peers[i].PublicKey)
|
log.Println("-----------> skipping peer, proxy is off: ", m.Payload.Peers[i].PublicKey)
|
||||||
|
|
@ -373,13 +382,6 @@ func (m *ManagerAction) AddInterfaceToProxy() error {
|
||||||
defer func() {
|
defer func() {
|
||||||
if addExtClient {
|
if addExtClient {
|
||||||
log.Println("GOT ENDPOINT for Extclient adding peer...")
|
log.Println("GOT ENDPOINT for Extclient adding peer...")
|
||||||
common.PeerKeyHashMap[fmt.Sprintf("%x", md5.Sum([]byte(peer.PublicKey.String())))] = models.RemotePeer{
|
|
||||||
Interface: wgInterface.Name,
|
|
||||||
PeerKey: peer.PublicKey.String(),
|
|
||||||
IsExtClient: peerConf.IsExtClient,
|
|
||||||
IsAttachedExtClient: peerConf.IsAttachedExtClient,
|
|
||||||
Endpoint: peer.Endpoint,
|
|
||||||
}
|
|
||||||
|
|
||||||
common.ExtSourceIpMap[peer.Endpoint.String()] = models.RemotePeer{
|
common.ExtSourceIpMap[peer.Endpoint.String()] = models.RemotePeer{
|
||||||
Interface: wgInterface.Name,
|
Interface: wgInterface.Name,
|
||||||
|
|
@ -413,18 +415,10 @@ func (m *ManagerAction) AddInterfaceToProxy() error {
|
||||||
}(wgInterface, &peerI, isRelayed, relayedTo, peerConf, m.Payload.WgAddr)
|
}(wgInterface, &peerI, isRelayed, relayedTo, peerConf, m.Payload.WgAddr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
common.PeerKeyHashMap[fmt.Sprintf("%x", md5.Sum([]byte(peerI.PublicKey.String())))] = models.RemotePeer{
|
|
||||||
Interface: m.Payload.InterfaceName,
|
|
||||||
PeerKey: peerI.PublicKey.String(),
|
|
||||||
IsExtClient: peerConf.IsExtClient,
|
|
||||||
Endpoint: peerI.Endpoint,
|
|
||||||
IsAttachedExtClient: peerConf.IsAttachedExtClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
peerpkg.AddNewPeer(wgInterface, &peerI, peerConf.Address, isRelayed,
|
peerpkg.AddNewPeer(wgInterface, &peerI, peerConf.Address, isRelayed,
|
||||||
peerConf.IsExtClient, peerConf.IsAttachedExtClient, relayedTo)
|
peerConf.IsExtClient, peerConf.IsAttachedExtClient, relayedTo)
|
||||||
|
|
||||||
}
|
}
|
||||||
log.Printf("------> PEERHASHMAP: %+v\n", common.PeerKeyHashMap)
|
|
||||||
log.Printf("-------> WgIFaceMap: %+v\n", common.WgIfaceMap)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ const (
|
||||||
TrafficRecievedUpdate MetricsUpdateType = 3
|
TrafficRecievedUpdate MetricsUpdateType = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
var MetricsMapLock = &sync.Mutex{}
|
var MetricsMapLock = &sync.RWMutex{}
|
||||||
|
|
||||||
var MetricsMap = make(map[string]Metric)
|
var MetricsMap = make(map[string]Metric)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@ package models
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gravitl/netmaker/nm-proxy/wg"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -12,8 +15,21 @@ const (
|
||||||
DefaultCIDR = "127.0.0.1/8"
|
DefaultCIDR = "127.0.0.1/8"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConnConfig is a peer Connection configuration
|
type ProxyConfig struct {
|
||||||
type ConnConfig struct {
|
RemoteKey wgtypes.Key
|
||||||
|
LocalKey wgtypes.Key
|
||||||
|
WgInterface *wg.WGIface
|
||||||
|
IsExtClient bool
|
||||||
|
PersistentKeepalive *time.Duration
|
||||||
|
RecieverChan chan []byte
|
||||||
|
PeerConf *wgtypes.PeerConfig
|
||||||
|
PeerEndpoint *net.UDPAddr
|
||||||
|
RemoteConnAddr *net.UDPAddr
|
||||||
|
LocalConnAddr *net.UDPAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conn is a peer Connection configuration
|
||||||
|
type Conn struct {
|
||||||
|
|
||||||
// Key is a public key of a remote peer
|
// Key is a public key of a remote peer
|
||||||
Key wgtypes.Key
|
Key wgtypes.Key
|
||||||
|
|
@ -21,13 +37,11 @@ type ConnConfig struct {
|
||||||
IsRelayed bool
|
IsRelayed bool
|
||||||
RelayedEndpoint *net.UDPAddr
|
RelayedEndpoint *net.UDPAddr
|
||||||
IsAttachedExtClient bool
|
IsAttachedExtClient bool
|
||||||
PeerConf *wgtypes.PeerConfig
|
Config ProxyConfig
|
||||||
StopConn func()
|
StopConn func()
|
||||||
ResetConn func()
|
ResetConn func()
|
||||||
PeerListenPort uint32
|
LocalConn net.Conn
|
||||||
RemoteConnAddr *net.UDPAddr
|
Mutex *sync.RWMutex
|
||||||
LocalConnAddr *net.UDPAddr
|
|
||||||
RecieverChan chan []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type RemotePeer struct {
|
type RemotePeer struct {
|
||||||
|
|
@ -36,6 +50,7 @@ type RemotePeer struct {
|
||||||
Endpoint *net.UDPAddr
|
Endpoint *net.UDPAddr
|
||||||
IsExtClient bool
|
IsExtClient bool
|
||||||
IsAttachedExtClient bool
|
IsAttachedExtClient bool
|
||||||
|
LocalConn net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExtClientPeer struct {
|
type ExtClientPeer struct {
|
||||||
|
|
@ -46,5 +61,5 @@ type ExtClientPeer struct {
|
||||||
type WgIfaceConf struct {
|
type WgIfaceConf struct {
|
||||||
Iface *wgtypes.Device
|
Iface *wgtypes.Device
|
||||||
IfaceKeyHash string
|
IfaceKeyHash string
|
||||||
PeerMap map[string]*ConnConfig
|
PeerMap map[string]*Conn
|
||||||
}
|
}
|
||||||
|
|
@ -12,6 +12,13 @@ import (
|
||||||
"github.com/gravitl/netmaker/nm-proxy/stun"
|
"github.com/gravitl/netmaker/nm-proxy/stun"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
|
1. Mutex locks for maps
|
||||||
|
2. CRUD funcs on Maps
|
||||||
|
3. Comments
|
||||||
|
*/
|
||||||
|
|
||||||
func Start(ctx context.Context, mgmChan chan *manager.ManagerAction, apiServerAddr string) {
|
func Start(ctx context.Context, mgmChan chan *manager.ManagerAction, apiServerAddr string) {
|
||||||
log.Println("Starting Proxy...")
|
log.Println("Starting Proxy...")
|
||||||
common.IsHostNetwork = (os.Getenv("HOST_NETWORK") == "" || os.Getenv("HOST_NETWORK") == "on")
|
common.IsHostNetwork = (os.Getenv("HOST_NETWORK") == "" || os.Getenv("HOST_NETWORK") == "on")
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,8 @@ func ProcessPacketBeforeSending(buf []byte, n int, srckey, dstKey string) ([]byt
|
||||||
|
|
||||||
func ExtractInfo(buffer []byte, n int) (int, string, string, error) {
|
func ExtractInfo(buffer []byte, n int) (int, string, string, error) {
|
||||||
data := buffer[:n]
|
data := buffer[:n]
|
||||||
if len(data) < 36 {
|
if len(data) < MessageProxySize {
|
||||||
return 0, "", "", errors.New("proxy message not found")
|
return n, "", "", errors.New("proxy message not found")
|
||||||
}
|
}
|
||||||
var msg ProxyMessage
|
var msg ProxyMessage
|
||||||
var err error
|
var err error
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
package peer
|
package peer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/nm-proxy/common"
|
"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/models"
|
||||||
"github.com/gravitl/netmaker/nm-proxy/proxy"
|
"github.com/gravitl/netmaker/nm-proxy/proxy"
|
||||||
"github.com/gravitl/netmaker/nm-proxy/wg"
|
"github.com/gravitl/netmaker/nm-proxy/wg"
|
||||||
|
|
@ -20,15 +22,14 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri
|
||||||
d := time.Second * 25
|
d := time.Second * 25
|
||||||
peer.PersistentKeepaliveInterval = &d
|
peer.PersistentKeepaliveInterval = &d
|
||||||
}
|
}
|
||||||
c := proxy.Config{
|
c := models.ProxyConfig{
|
||||||
LocalKey: wgInterface.Device.PublicKey,
|
LocalKey: wgInterface.Device.PublicKey,
|
||||||
RemoteKey: peer.PublicKey,
|
RemoteKey: peer.PublicKey,
|
||||||
WgInterface: wgInterface,
|
WgInterface: wgInterface,
|
||||||
IsExtClient: isExtClient,
|
IsExtClient: isExtClient,
|
||||||
PeerConf: peer,
|
PeerConf: peer,
|
||||||
PersistentKeepalive: peer.PersistentKeepaliveInterval,
|
PersistentKeepalive: peer.PersistentKeepaliveInterval,
|
||||||
RecieverChan: make(chan []byte, 100),
|
RecieverChan: make(chan []byte, 1000),
|
||||||
MetricsCh: make(chan metrics.MetricsPayload, 30),
|
|
||||||
}
|
}
|
||||||
p := proxy.NewProxy(c)
|
p := proxy.NewProxy(c)
|
||||||
peerPort := models.NmProxyPort
|
peerPort := models.NmProxyPort
|
||||||
|
|
@ -36,38 +37,47 @@ func AddNewPeer(wgInterface *wg.WGIface, peer *wgtypes.PeerConfig, peerAddr stri
|
||||||
peerPort = peer.Endpoint.Port
|
peerPort = peer.Endpoint.Port
|
||||||
|
|
||||||
}
|
}
|
||||||
peerEndpoint := peer.Endpoint.IP
|
peerEndpointIP := peer.Endpoint.IP
|
||||||
if isRelayed {
|
if isRelayed {
|
||||||
//go server.NmProxyServer.KeepAlive(peer.Endpoint.IP.String(), common.NmProxyPort)
|
//go server.NmProxyServer.KeepAlive(peer.Endpoint.IP.String(), common.NmProxyPort)
|
||||||
if relayTo == nil {
|
if relayTo == nil {
|
||||||
return errors.New("relay endpoint is nil")
|
return errors.New("relay endpoint is nil")
|
||||||
}
|
}
|
||||||
peerEndpoint = relayTo.IP
|
peerEndpointIP = relayTo.IP
|
||||||
}
|
}
|
||||||
p.Config.PeerIp = peerEndpoint
|
peerEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", peerEndpointIP, peerPort))
|
||||||
p.Config.PeerPort = uint32(peerPort)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.Config.PeerEndpoint = peerEndpoint
|
||||||
|
|
||||||
log.Printf("Starting proxy for Peer: %s\n", peer.PublicKey.String())
|
log.Printf("Starting proxy for Peer: %s\n", peer.PublicKey.String())
|
||||||
lAddr, rAddr, err := p.Start()
|
err = p.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
connConf := models.ConnConfig{
|
connConf := models.Conn{
|
||||||
|
Mutex: &sync.RWMutex{},
|
||||||
Key: peer.PublicKey,
|
Key: peer.PublicKey,
|
||||||
IsRelayed: isRelayed,
|
IsRelayed: isRelayed,
|
||||||
RelayedEndpoint: relayTo,
|
RelayedEndpoint: relayTo,
|
||||||
IsAttachedExtClient: isAttachedExtClient,
|
IsAttachedExtClient: isAttachedExtClient,
|
||||||
PeerConf: peer,
|
Config: p.Config,
|
||||||
StopConn: p.Close,
|
StopConn: p.Close,
|
||||||
ResetConn: p.Reset,
|
ResetConn: p.Reset,
|
||||||
RemoteConnAddr: rAddr,
|
LocalConn: p.LocalConn,
|
||||||
LocalConnAddr: lAddr,
|
|
||||||
RecieverChan: p.Config.RecieverChan,
|
|
||||||
PeerListenPort: p.Config.PeerPort,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
common.WgIfaceMap.PeerMap[peer.PublicKey.String()] = &connConf
|
common.WgIfaceMap.PeerMap[peer.PublicKey.String()] = &connConf
|
||||||
|
|
||||||
|
common.PeerKeyHashMap[fmt.Sprintf("%x", md5.Sum([]byte(peer.PublicKey.String())))] = models.RemotePeer{
|
||||||
|
Interface: wgInterface.Name,
|
||||||
|
PeerKey: peer.PublicKey.String(),
|
||||||
|
IsExtClient: isExtClient,
|
||||||
|
Endpoint: peerEndpoint,
|
||||||
|
IsAttachedExtClient: isAttachedExtClient,
|
||||||
|
LocalConn: p.LocalConn,
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,91 +7,63 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/nm-proxy/common"
|
"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/models"
|
||||||
"github.com/gravitl/netmaker/nm-proxy/wg"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
defaultBodySize = 10000
|
|
||||||
defaultPort = 51722
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
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
|
// Proxy - WireguardProxy proxies
|
||||||
type Proxy struct {
|
type Proxy struct {
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
Cancel context.CancelFunc
|
Cancel context.CancelFunc
|
||||||
Config Config
|
Config models.ProxyConfig
|
||||||
RemoteConn *net.UDPAddr
|
RemoteConn *net.UDPAddr
|
||||||
LocalConn net.Conn
|
LocalConn net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) Start() (*net.UDPAddr, *net.UDPAddr, error) {
|
func (p *Proxy) Start() error {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
remoteConn, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", p.Config.PeerIp.String(), p.Config.PeerPort))
|
p.RemoteConn = p.Config.PeerEndpoint
|
||||||
if err != nil {
|
log.Printf("----> Established Remote Conn with RPeer: %s, ----> RAddr: %s", p.Config.RemoteKey.String(), p.RemoteConn.String())
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
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)
|
addr, err := GetFreeIp(models.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)
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
wgListenAddr, err := GetInterfaceListenAddr(p.Config.WgInterface.Port)
|
wgListenAddr, err := GetInterfaceListenAddr(p.Config.WgInterface.Port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("failed to get wg listen addr: ", err)
|
log.Println("failed to get wg listen addr: ", err)
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
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())
|
|
||||||
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: models.NmProxyPort,
|
Port: models.NmProxyPort,
|
||||||
}, wgListenAddr)
|
}, wgListenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("failed dialing to local Wireguard port,Err: %v\n", err)
|
log.Printf("failed dialing to local Wireguard port,Err: %v\n", err)
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Dialing to local Wireguard port %s --> %s\n", p.LocalConn.LocalAddr().String(), p.LocalConn.RemoteAddr().String())
|
log.Printf("Dialing to local Wireguard port %s --> %s\n", p.LocalConn.LocalAddr().String(), p.LocalConn.RemoteAddr().String())
|
||||||
err = p.updateEndpoint()
|
err = p.updateEndpoint()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error while updating Wireguard peer endpoint [%s] %v\n", p.Config.RemoteKey, err)
|
log.Printf("error while updating Wireguard peer endpoint [%s] %v\n", p.Config.RemoteKey, err)
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
localAddr, err := net.ResolveUDPAddr("udp", p.LocalConn.LocalAddr().String())
|
localAddr, err := net.ResolveUDPAddr("udp", p.LocalConn.LocalAddr().String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("failed to resolve local addr: ", err)
|
log.Println("failed to resolve local addr: ", err)
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
p.Config.LocalConnAddr = localAddr
|
||||||
|
p.Config.RemoteConnAddr = p.RemoteConn
|
||||||
go p.ProxyPeer()
|
go p.ProxyPeer()
|
||||||
|
|
||||||
return localAddr, p.RemoteConn, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) Close() {
|
func (p *Proxy) Close() {
|
||||||
|
|
|
||||||
|
|
@ -22,33 +22,12 @@ import (
|
||||||
"github.com/gravitl/netmaker/nm-proxy/wg"
|
"github.com/gravitl/netmaker/nm-proxy/wg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewProxy(config Config) *Proxy {
|
func NewProxy(config models.ProxyConfig) *Proxy {
|
||||||
p := &Proxy{Config: config}
|
p := &Proxy{Config: config}
|
||||||
p.Ctx, p.Cancel = context.WithCancel(context.Background())
|
p.Ctx, p.Cancel = context.WithCancel(context.Background())
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) proxyToLocal(wg *sync.WaitGroup, ticker *time.Ticker) {
|
|
||||||
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-p.Ctx.Done():
|
|
||||||
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) {
|
func (p *Proxy) proxyToRemote(wg *sync.WaitGroup) {
|
||||||
ticker := time.NewTicker(time.Minute)
|
ticker := time.NewTicker(time.Minute)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
@ -58,21 +37,6 @@ func (p *Proxy) proxyToRemote(wg *sync.WaitGroup) {
|
||||||
select {
|
select {
|
||||||
case <-p.Ctx.Done():
|
case <-p.Ctx.Done():
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
|
||||||
metrics.MetricsMapLock.Lock()
|
|
||||||
metric := metrics.MetricsMap[p.Config.RemoteKey.String()]
|
|
||||||
metric.ConnectionStatus = false
|
|
||||||
metrics.MetricsMap[p.Config.RemoteKey.String()] = metric
|
|
||||||
metrics.MetricsMapLock.Unlock()
|
|
||||||
pkt, err := packet.CreateMetricPacket(uuid.New().ID(), p.Config.LocalKey, p.Config.RemoteKey)
|
|
||||||
if err == nil {
|
|
||||||
log.Printf("-----------> ##### $$$$$ SENDING METRIC 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
n, err := p.LocalConn.Read(buf)
|
n, err := p.LocalConn.Read(buf)
|
||||||
|
|
@ -81,30 +45,30 @@ func (p *Proxy) proxyToRemote(wg *sync.WaitGroup) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := common.WgIfaceMap.PeerMap[p.Config.RemoteKey.String()]; ok {
|
// if _, found := common.GetPeer(p.Config.RemoteKey); !found {
|
||||||
|
// log.Printf("Peer: %s not found in config\n", p.Config.RemoteKey)
|
||||||
|
// p.Close()
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
go func(n int, peerKey string) {
|
||||||
metrics.MetricsMapLock.Lock()
|
metrics.MetricsMapLock.Lock()
|
||||||
metric := metrics.MetricsMap[p.Config.RemoteKey.String()]
|
metric := metrics.MetricsMap[peerKey]
|
||||||
metric.TrafficSent += uint64(n)
|
metric.TrafficSent += uint64(n)
|
||||||
metrics.MetricsMap[p.Config.RemoteKey.String()] = metric
|
metrics.MetricsMap[peerKey] = metric
|
||||||
metrics.MetricsMapLock.Unlock()
|
metrics.MetricsMapLock.Unlock()
|
||||||
|
}(n, p.Config.RemoteKey.String())
|
||||||
|
|
||||||
var srcPeerKeyHash, dstPeerKeyHash string
|
//var srcPeerKeyHash, dstPeerKeyHash string
|
||||||
if !p.Config.IsExtClient {
|
if !p.Config.IsExtClient {
|
||||||
buf, n, srcPeerKeyHash, dstPeerKeyHash = packet.ProcessPacketBeforeSending(buf, n, common.WgIfaceMap.Iface.PublicKey.String(), p.Config.RemoteKey.String())
|
buf, n, _, _ = packet.ProcessPacketBeforeSending(buf, n, p.Config.WgInterface.Device.PublicKey.String(), p.Config.RemoteKey.String())
|
||||||
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)
|
|
||||||
} else {
|
|
||||||
log.Printf("Peer: %s not found in config\n", p.Config.RemoteKey)
|
|
||||||
p.Close()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
_, err = server.NmProxyServer.Server.WriteToUDP(buf[:n], p.RemoteConn)
|
_, err = server.NmProxyServer.Server.WriteToUDP(buf[:n], p.RemoteConn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Failed to send to remote: ", err)
|
log.Println("Failed to send to remote: ", err)
|
||||||
|
|
@ -117,14 +81,52 @@ func (p *Proxy) proxyToRemote(wg *sync.WaitGroup) {
|
||||||
|
|
||||||
func (p *Proxy) Reset() {
|
func (p *Proxy) Reset() {
|
||||||
p.Close()
|
p.Close()
|
||||||
p.pullLatestConfig()
|
if err := p.pullLatestConfig(); err != nil {
|
||||||
|
log.Println("couldn't perform reset: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
p.Start()
|
p.Start()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) pullLatestConfig() {
|
func (p *Proxy) pullLatestConfig() error {
|
||||||
if peer, ok := common.WgIfaceMap.PeerMap[p.Config.RemoteKey.String()]; ok {
|
peer, found := common.GetPeer(p.Config.RemoteKey)
|
||||||
p.Config.PeerPort = peer.PeerListenPort
|
if found {
|
||||||
|
p.Config.PeerEndpoint.Port = peer.Config.PeerEndpoint.Port
|
||||||
|
} else {
|
||||||
|
return errors.New("peer not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Proxy) startMetricsThread(wg *sync.WaitGroup, rTicker *time.Ticker) {
|
||||||
|
ticker := time.NewTicker(time.Minute)
|
||||||
|
defer ticker.Stop()
|
||||||
|
defer wg.Done()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-p.Ctx.Done():
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
metrics.MetricsMapLock.Lock()
|
||||||
|
metric := metrics.MetricsMap[p.Config.RemoteKey.String()]
|
||||||
|
if metric.ConnectionStatus {
|
||||||
|
rTicker.Reset(*p.Config.PersistentKeepalive)
|
||||||
|
}
|
||||||
|
metric.ConnectionStatus = false
|
||||||
|
metrics.MetricsMap[p.Config.RemoteKey.String()] = metric
|
||||||
|
metrics.MetricsMapLock.Unlock()
|
||||||
|
pkt, err := packet.CreateMetricPacket(uuid.New().ID(), p.Config.LocalKey, p.Config.RemoteKey)
|
||||||
|
if err == nil {
|
||||||
|
log.Printf("-----------> ##### $$$$$ SENDING METRIC 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,11 +164,11 @@ func (p *Proxy) ProxyPeer() {
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go p.proxyToLocal(wg, ticker)
|
|
||||||
wg.Add(1)
|
|
||||||
go p.proxyToRemote(wg)
|
go p.proxyToRemote(wg)
|
||||||
// if common.BehindNAT {
|
// if common.BehindNAT {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
go p.startMetricsThread(wg, ticker)
|
||||||
|
wg.Add(1)
|
||||||
go p.peerUpdates(wg, ticker)
|
go p.peerUpdates(wg, ticker)
|
||||||
// }
|
// }
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package server
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -34,36 +35,38 @@ type ProxyServer struct {
|
||||||
Server *net.UDPConn
|
Server *net.UDPConn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ProxyServer) Close() {
|
||||||
|
log.Println("--------->### Shutting down Proxy.....")
|
||||||
|
// clean up proxy connections
|
||||||
|
for _, peerI := range common.WgIfaceMap.PeerMap {
|
||||||
|
peerI.Mutex.Lock()
|
||||||
|
peerI.StopConn()
|
||||||
|
peerI.Mutex.Unlock()
|
||||||
|
}
|
||||||
|
// close server connection
|
||||||
|
NmProxyServer.Server.Close()
|
||||||
|
}
|
||||||
|
|
||||||
// Proxy.Listen - begins listening for packets
|
// Proxy.Listen - begins listening for packets
|
||||||
func (p *ProxyServer) Listen(ctx context.Context) {
|
func (p *ProxyServer) Listen(ctx context.Context) {
|
||||||
|
|
||||||
// Buffer with indicated body size
|
// Buffer with indicated body size
|
||||||
buffer := make([]byte, 65032)
|
buffer := make([]byte, 65036)
|
||||||
for {
|
for {
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
log.Println("--------->### Shutting down Proxy.....")
|
p.Close()
|
||||||
// clean up proxy connections
|
|
||||||
|
|
||||||
log.Println("########------------> CLEANING UP Interface ")
|
|
||||||
for _, peerI := range common.WgIfaceMap.PeerMap {
|
|
||||||
peerI.StopConn()
|
|
||||||
}
|
|
||||||
|
|
||||||
// close server connection
|
|
||||||
NmProxyServer.Server.Close()
|
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
// Read Packet
|
// Read Packet
|
||||||
|
|
||||||
n, source, err := p.Server.ReadFromUDP(buffer)
|
n, source, err := p.Server.ReadFromUDP(buffer)
|
||||||
if err != nil { // in future log errors?
|
if err != nil || source == nil { // in future log errors?
|
||||||
log.Println("RECV ERROR: ", err)
|
log.Println("RECV ERROR: ", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//go func(buffer []byte, source *net.UDPAddr, n int) {
|
//go func(buffer []byte, source *net.UDPAddr, n int) {
|
||||||
origBufferLen := n
|
|
||||||
proxyTransportMsg := true
|
proxyTransportMsg := true
|
||||||
var srcPeerKeyHash, dstPeerKeyHash string
|
var srcPeerKeyHash, dstPeerKeyHash string
|
||||||
n, srcPeerKeyHash, dstPeerKeyHash, err = packet.ExtractInfo(buffer, n)
|
n, srcPeerKeyHash, dstPeerKeyHash, err = packet.ExtractInfo(buffer, n)
|
||||||
|
|
@ -74,96 +77,103 @@ func (p *ProxyServer) Listen(ctx context.Context) {
|
||||||
if proxyTransportMsg {
|
if proxyTransportMsg {
|
||||||
proxyIncomingPacket(buffer[:], source, n, srcPeerKeyHash, dstPeerKeyHash)
|
proxyIncomingPacket(buffer[:], source, n, srcPeerKeyHash, dstPeerKeyHash)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// unknown peer to proxy -> check if extclient and handle it
|
// unknown peer to proxy -> check if extclient and handle it
|
||||||
if peerInfo, ok := common.ExtSourceIpMap[source.String()]; ok {
|
if handleExtClients(buffer[:], n, source) {
|
||||||
if peerI, ok := common.WgIfaceMap.PeerMap[peerInfo.PeerKey]; ok {
|
continue
|
||||||
metrics.MetricsMapLock.Lock()
|
|
||||||
metric := metrics.MetricsMap[peerInfo.PeerKey]
|
|
||||||
metric.TrafficRecieved += uint64(n)
|
|
||||||
metric.ConnectionStatus = true
|
|
||||||
metrics.MetricsMap[peerInfo.PeerKey] = metric
|
|
||||||
metrics.MetricsMapLock.Unlock()
|
|
||||||
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
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
handleMsgs(buffer, n, source)
|
||||||
|
|
||||||
msgType := binary.LittleEndian.Uint32(buffer[:4])
|
}
|
||||||
switch packet.MessageType(msgType) {
|
}
|
||||||
case packet.MessageMetricsType:
|
}
|
||||||
metricMsg, err := packet.ConsumeMetricPacket(buffer[:origBufferLen])
|
|
||||||
// calc latency
|
|
||||||
if err == nil {
|
|
||||||
log.Printf("------->$$$$$ Recieved Metric Pkt: %+v, FROM:%s\n", metricMsg, source.String())
|
|
||||||
if metricMsg.Sender == common.WgIfaceMap.Iface.PublicKey {
|
|
||||||
latency := time.Now().UnixMilli() - metricMsg.TimeStamp
|
|
||||||
log.Println("----------------> LAtency$$$$$$: ", latency)
|
|
||||||
metrics.MetricsMapLock.Lock()
|
|
||||||
metric := metrics.MetricsMap[metricMsg.Reciever.String()]
|
|
||||||
metric.LastRecordedLatency = uint64(latency)
|
|
||||||
metric.ConnectionStatus = true
|
|
||||||
metric.TrafficRecieved += uint64(origBufferLen)
|
|
||||||
metrics.MetricsMap[metricMsg.Reciever.String()] = metric
|
|
||||||
metrics.MetricsMapLock.Unlock()
|
|
||||||
} else if metricMsg.Reciever == common.WgIfaceMap.Iface.PublicKey {
|
|
||||||
// proxy it back to the sender
|
|
||||||
log.Println("------------> $$$ SENDING back the metric pkt to the source: ", source.String())
|
|
||||||
_, err = NmProxyServer.Server.WriteToUDP(buffer[:origBufferLen], source)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Failed to send metric packet to remote: ", err)
|
|
||||||
}
|
|
||||||
metrics.MetricsMapLock.Lock()
|
|
||||||
metric := metrics.MetricsMap[metricMsg.Sender.String()]
|
|
||||||
metric.ConnectionStatus = true
|
|
||||||
metric.TrafficRecieved += uint64(origBufferLen)
|
|
||||||
metrics.MetricsMap[metricMsg.Sender.String()] = metric
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
func handleMsgs(buffer []byte, n int, source *net.UDPAddr) {
|
||||||
}
|
|
||||||
}
|
|
||||||
// consume handshake message for ext clients
|
|
||||||
case packet.MessageInitiationType:
|
|
||||||
|
|
||||||
err := packet.ConsumeHandshakeInitiationMsg(false, buffer[:origBufferLen], source,
|
msgType := binary.LittleEndian.Uint32(buffer[:4])
|
||||||
packet.NoisePublicKey(common.WgIfaceMap.Iface.PublicKey), packet.NoisePrivateKey(common.WgIfaceMap.Iface.PrivateKey))
|
switch packet.MessageType(msgType) {
|
||||||
|
case packet.MessageMetricsType:
|
||||||
|
metricMsg, err := packet.ConsumeMetricPacket(buffer[:n])
|
||||||
|
// calc latency
|
||||||
|
if err == nil {
|
||||||
|
log.Printf("------->$$$$$ Recieved Metric Pkt: %+v, FROM:%s\n", metricMsg, source.String())
|
||||||
|
if metricMsg.Sender == common.WgIfaceMap.Iface.PublicKey {
|
||||||
|
latency := time.Now().UnixMilli() - metricMsg.TimeStamp
|
||||||
|
log.Println("----------------> LAtency$$$$$$: ", latency)
|
||||||
|
metrics.MetricsMapLock.Lock()
|
||||||
|
metric := metrics.MetricsMap[metricMsg.Reciever.String()]
|
||||||
|
metric.LastRecordedLatency = uint64(latency)
|
||||||
|
metric.ConnectionStatus = true
|
||||||
|
metric.TrafficRecieved += uint64(n)
|
||||||
|
metrics.MetricsMap[metricMsg.Reciever.String()] = metric
|
||||||
|
metrics.MetricsMapLock.Unlock()
|
||||||
|
} else if metricMsg.Reciever == common.WgIfaceMap.Iface.PublicKey {
|
||||||
|
// proxy it back to the sender
|
||||||
|
log.Println("------------> $$$ SENDING back the metric pkt to the source: ", source.String())
|
||||||
|
_, err = NmProxyServer.Server.WriteToUDP(buffer[:n], source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("---------> @@@ failed to decode HS: ", err)
|
log.Println("Failed to send metric packet to remote: ", err)
|
||||||
}
|
}
|
||||||
|
metrics.MetricsMapLock.Lock()
|
||||||
|
metric := metrics.MetricsMap[metricMsg.Sender.String()]
|
||||||
|
metric.ConnectionStatus = true
|
||||||
|
metric.TrafficRecieved += uint64(n)
|
||||||
|
metrics.MetricsMap[metricMsg.Sender.String()] = metric
|
||||||
|
metrics.MetricsMapLock.Unlock()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
case packet.MessageProxyUpdateType:
|
||||||
|
msg, err := packet.ConsumeProxyUpdateMsg(buffer[:n])
|
||||||
|
if err == nil {
|
||||||
|
switch msg.Action {
|
||||||
|
case packet.UpdateListenPort:
|
||||||
|
if peer, ok := common.WgIfaceMap.PeerMap[msg.Sender.String()]; ok {
|
||||||
|
peer.Mutex.Lock()
|
||||||
|
if peer.Config.PeerEndpoint.Port != int(msg.ListenPort) {
|
||||||
|
// update peer conn
|
||||||
|
peer.Config.PeerEndpoint.Port = int(msg.ListenPort)
|
||||||
|
common.WgIfaceMap.PeerMap[msg.Sender.String()] = peer
|
||||||
|
log.Println("--------> Resetting Proxy Conn For Peer ", msg.Sender.String())
|
||||||
|
peer.Mutex.Unlock()
|
||||||
|
peer.ResetConn()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
peer.Mutex.Unlock()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// consume handshake message for ext clients
|
||||||
|
case packet.MessageInitiationType:
|
||||||
|
|
||||||
|
err := packet.ConsumeHandshakeInitiationMsg(false, buffer[:n], source,
|
||||||
|
packet.NoisePublicKey(common.WgIfaceMap.Iface.PublicKey), packet.NoisePrivateKey(common.WgIfaceMap.Iface.PrivateKey))
|
||||||
|
if err != nil {
|
||||||
|
log.Println("---------> @@@ failed to decode HS: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleExtClients(buffer []byte, n int, source *net.UDPAddr) bool {
|
||||||
|
isExtClient := false
|
||||||
|
if peerInfo, ok := common.ExtSourceIpMap[source.String()]; ok {
|
||||||
|
if peerI, ok := common.WgIfaceMap.PeerMap[peerInfo.PeerKey]; ok {
|
||||||
|
peerI.Mutex.RLock()
|
||||||
|
peerI.Config.RecieverChan <- buffer[:n]
|
||||||
|
metrics.MetricsMapLock.Lock()
|
||||||
|
metric := metrics.MetricsMap[peerInfo.PeerKey]
|
||||||
|
metric.TrafficRecieved += uint64(n)
|
||||||
|
metric.ConnectionStatus = true
|
||||||
|
metrics.MetricsMap[peerInfo.PeerKey] = metric
|
||||||
|
metrics.MetricsMapLock.Unlock()
|
||||||
|
peerI.Mutex.RUnlock()
|
||||||
|
isExtClient = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return isExtClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func proxyIncomingPacket(buffer []byte, source *net.UDPAddr, n int, srcPeerKeyHash, dstPeerKeyHash string) {
|
func proxyIncomingPacket(buffer []byte, source *net.UDPAddr, n int, srcPeerKeyHash, dstPeerKeyHash string) {
|
||||||
|
|
@ -201,24 +211,25 @@ func proxyIncomingPacket(buffer []byte, source *net.UDPAddr, n int, srcPeerKeyHa
|
||||||
}
|
}
|
||||||
|
|
||||||
if peerInfo, ok := common.PeerKeyHashMap[srcPeerKeyHash]; ok {
|
if peerInfo, ok := common.PeerKeyHashMap[srcPeerKeyHash]; ok {
|
||||||
if peerI, ok := common.WgIfaceMap.PeerMap[peerInfo.PeerKey]; ok {
|
|
||||||
|
log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
|
||||||
|
peerInfo.LocalConn.RemoteAddr(), peerInfo.LocalConn.LocalAddr(),
|
||||||
|
fmt.Sprintf("%s:%d", source.IP.String(), source.Port), srcPeerKeyHash, dstPeerKeyHash, source.IP.String())
|
||||||
|
_, err = peerInfo.LocalConn.Write(buffer[:n])
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to proxy to Wg local interface: ", err)
|
||||||
|
//continue
|
||||||
|
}
|
||||||
|
|
||||||
|
go func(n int, peerKey string) {
|
||||||
metrics.MetricsMapLock.Lock()
|
metrics.MetricsMapLock.Lock()
|
||||||
metric := metrics.MetricsMap[peerInfo.PeerKey]
|
metric := metrics.MetricsMap[peerKey]
|
||||||
metric.TrafficRecieved += uint64(n)
|
metric.TrafficRecieved += uint64(n)
|
||||||
metric.ConnectionStatus = true
|
metric.ConnectionStatus = true
|
||||||
metrics.MetricsMap[peerInfo.PeerKey] = metric
|
metrics.MetricsMap[peerKey] = metric
|
||||||
metrics.MetricsMapLock.Unlock()
|
metrics.MetricsMapLock.Unlock()
|
||||||
peerI.RecieverChan <- buffer[:n]
|
}(n, peerInfo.PeerKey)
|
||||||
// log.Printf("PROXING TO LOCAL!!!---> %s <<<< %s <<<<<<<< %s [[ RECV PKT [SRCKEYHASH: %s], [DSTKEYHASH: %s], SourceIP: [%s] ]]\n",
|
return
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue