mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-23 08:33:45 +01:00
bef3b3392b
* fix: graceful shutdown * fix: windows graceful shutdown
133 lines
3.1 KiB
Go
133 lines
3.1 KiB
Go
package internal
|
|
|
|
import (
|
|
ice "github.com/pion/ice/v2"
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/wiretrustee/wiretrustee/iface"
|
|
"net"
|
|
)
|
|
|
|
// WgProxy an instance of an instance of the Connection Wireguard Proxy
|
|
type WgProxy struct {
|
|
iface string
|
|
remoteKey string
|
|
allowedIps string
|
|
wgAddr string
|
|
close chan struct{}
|
|
wgConn net.Conn
|
|
}
|
|
|
|
// NewWgProxy creates a new Connection Wireguard Proxy
|
|
func NewWgProxy(iface string, remoteKey string, allowedIps string, wgAddr string) *WgProxy {
|
|
return &WgProxy{
|
|
iface: iface,
|
|
remoteKey: remoteKey,
|
|
allowedIps: allowedIps,
|
|
wgAddr: wgAddr,
|
|
close: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
// Close closes the proxy
|
|
func (p *WgProxy) Close() error {
|
|
|
|
close(p.close)
|
|
if c := p.wgConn; c != nil {
|
|
err := p.wgConn.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
err := iface.RemovePeer(p.iface, p.remoteKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// StartLocal configure the interface with a peer using a direct IP:Port endpoint to the remote host
|
|
func (p *WgProxy) StartLocal(host string) error {
|
|
err := iface.UpdatePeer(p.iface, p.remoteKey, p.allowedIps, DefaultWgKeepAlive, host)
|
|
if err != nil {
|
|
log.Errorf("error while configuring Wireguard peer [%s] %s", p.remoteKey, err.Error())
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Start starts a new proxy using the ICE connection
|
|
func (p *WgProxy) Start(remoteConn *ice.Conn) error {
|
|
|
|
wgConn, err := net.Dial("udp", p.wgAddr)
|
|
if err != nil {
|
|
log.Fatalf("failed dialing to local Wireguard port %s", err)
|
|
return err
|
|
}
|
|
p.wgConn = wgConn
|
|
// add local proxy connection as a Wireguard peer
|
|
err = iface.UpdatePeer(p.iface, p.remoteKey, p.allowedIps, DefaultWgKeepAlive,
|
|
wgConn.LocalAddr().String())
|
|
if err != nil {
|
|
log.Errorf("error while configuring Wireguard peer [%s] %s", p.remoteKey, err.Error())
|
|
return err
|
|
}
|
|
|
|
go func() { p.proxyToRemotePeer(remoteConn) }()
|
|
go func() { p.proxyToLocalWireguard(remoteConn) }()
|
|
|
|
return err
|
|
}
|
|
|
|
// proxyToRemotePeer proxies everything from Wireguard to the remote peer
|
|
// blocks
|
|
func (p *WgProxy) proxyToRemotePeer(remoteConn *ice.Conn) {
|
|
|
|
buf := make([]byte, 1500)
|
|
for {
|
|
select {
|
|
case <-p.close:
|
|
log.Debugf("stopped proxying from remote peer %s due to closed connection", p.remoteKey)
|
|
return
|
|
default:
|
|
n, err := p.wgConn.Read(buf)
|
|
if err != nil {
|
|
//log.Warnln("failed reading from peer: ", err.Error())
|
|
continue
|
|
}
|
|
|
|
_, err = remoteConn.Write(buf[:n])
|
|
if err != nil {
|
|
//log.Warnln("failed writing to remote peer: ", err.Error())
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// proxyToLocalWireguard proxies everything from the remote peer to local Wireguard
|
|
// blocks
|
|
func (p *WgProxy) proxyToLocalWireguard(remoteConn *ice.Conn) {
|
|
|
|
buf := make([]byte, 1500)
|
|
for {
|
|
select {
|
|
case <-p.close:
|
|
log.Debugf("stopped proxying from remote peer %s due to closed connection", p.remoteKey)
|
|
return
|
|
default:
|
|
n, err := remoteConn.Read(buf)
|
|
if err != nil {
|
|
//log.Errorf("failed reading from remote connection %s", err)
|
|
continue
|
|
}
|
|
|
|
_, err = p.wgConn.Write(buf[:n])
|
|
if err != nil {
|
|
//log.Errorf("failed writing to local Wireguard instance %s", err)
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|