|
@@ -8,6 +8,7 @@ import (
|
|
"net"
|
|
"net"
|
|
"runtime"
|
|
"runtime"
|
|
"strings"
|
|
"strings"
|
|
|
|
+ "sync"
|
|
"time"
|
|
"time"
|
|
|
|
|
|
"github.com/c-robinson/iplib"
|
|
"github.com/c-robinson/iplib"
|
|
@@ -17,6 +18,7 @@ import (
|
|
"github.com/gravitl/netmaker/nm-proxy/models"
|
|
"github.com/gravitl/netmaker/nm-proxy/models"
|
|
"github.com/gravitl/netmaker/nm-proxy/packet"
|
|
"github.com/gravitl/netmaker/nm-proxy/packet"
|
|
"github.com/gravitl/netmaker/nm-proxy/server"
|
|
"github.com/gravitl/netmaker/nm-proxy/server"
|
|
|
|
+ "github.com/gravitl/netmaker/nm-proxy/stun"
|
|
"github.com/gravitl/netmaker/nm-proxy/wg"
|
|
"github.com/gravitl/netmaker/nm-proxy/wg"
|
|
)
|
|
)
|
|
|
|
|
|
@@ -26,38 +28,35 @@ func NewProxy(config Config) *Proxy {
|
|
return p
|
|
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 {
|
|
for {
|
|
select {
|
|
select {
|
|
case <-p.Ctx.Done():
|
|
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
|
|
return
|
|
case <-ticker.C:
|
|
case <-ticker.C:
|
|
metrics.MetricsMapLock.Lock()
|
|
metrics.MetricsMapLock.Lock()
|
|
@@ -102,7 +101,7 @@ func (p *Proxy) ProxyToRemote() {
|
|
p.LocalConn.LocalAddr(), server.NmProxyServer.Server.LocalAddr().String(), p.RemoteConn.String(), srcPeerKeyHash, dstPeerKeyHash)
|
|
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.Close()
|
|
return
|
|
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) {
|
|
func test(n int, buffer []byte) {
|
|
data := buffer[:n]
|
|
data := buffer[:n]
|
|
@@ -137,47 +195,6 @@ func (p *Proxy) updateEndpoint() error {
|
|
return nil
|
|
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) {
|
|
func GetFreeIp(cidrAddr string, dstPort int) (string, error) {
|
|
//ensure AddressRange is valid
|
|
//ensure AddressRange is valid
|
|
if dstPort == 0 {
|
|
if dstPort == 0 {
|
|
@@ -189,7 +206,6 @@ func GetFreeIp(cidrAddr string, dstPort int) (string, error) {
|
|
}
|
|
}
|
|
net4 := iplib.Net4FromStr(cidrAddr)
|
|
net4 := iplib.Net4FromStr(cidrAddr)
|
|
newAddrs := net4.FirstAddress()
|
|
newAddrs := net4.FirstAddress()
|
|
- log.Println("COUNT: ", net4.Count())
|
|
|
|
for {
|
|
for {
|
|
if runtime.GOOS == "darwin" {
|
|
if runtime.GOOS == "darwin" {
|
|
_, err := common.RunCmd(fmt.Sprintf("ifconfig lo0 alias %s 255.255.255.255", newAddrs.String()), true)
|
|
_, err := common.RunCmd(fmt.Sprintf("ifconfig lo0 alias %s 255.255.255.255", newAddrs.String()), true)
|