mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-25 09:33:24 +01:00
feat: improve signal server reconnect logic
This commit is contained in:
parent
08554a0494
commit
41c0de2f27
@ -5,9 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pion/ice/v2"
|
"github.com/pion/ice/v2"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/wiretrustee/wiretrustee/iface"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
"net"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -55,7 +53,7 @@ type Connection struct {
|
|||||||
// agent is an actual ice.Agent that is used to negotiate and maintain a connection to a remote peer
|
// agent is an actual ice.Agent that is used to negotiate and maintain a connection to a remote peer
|
||||||
agent *ice.Agent
|
agent *ice.Agent
|
||||||
|
|
||||||
wgConn net.Conn
|
wgProxy *WgProxy
|
||||||
|
|
||||||
connected *Cond
|
connected *Cond
|
||||||
closeCond *Cond
|
closeCond *Cond
|
||||||
@ -78,6 +76,7 @@ func NewConnection(config ConnConfig,
|
|||||||
closeCond: NewCond(),
|
closeCond: NewCond(),
|
||||||
connected: NewCond(),
|
connected: NewCond(),
|
||||||
agent: nil,
|
agent: nil,
|
||||||
|
wgProxy: NewWgProxy(config.WgIface, config.RemoteWgKey.String(), config.WgAllowedIPs, config.WgListenAddr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,14 +130,10 @@ func (conn *Connection) Open(timeout time.Duration) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wgConn, err := conn.createWireguardProxy()
|
err = conn.wgProxy.Start(remoteConn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
conn.wgConn = *wgConn
|
|
||||||
|
|
||||||
go conn.proxyToRemotePeer(*wgConn, remoteConn)
|
|
||||||
go conn.proxyToLocalWireguard(*wgConn, remoteConn)
|
|
||||||
|
|
||||||
log.Infof("opened connection to peer %s", conn.Config.RemoteWgKey.String())
|
log.Infof("opened connection to peer %s", conn.Config.RemoteWgKey.String())
|
||||||
case <-time.After(timeout):
|
case <-time.After(timeout):
|
||||||
@ -170,7 +165,7 @@ func (conn *Connection) Close() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c := conn.wgConn; c != nil {
|
if c := conn.wgProxy; c != nil {
|
||||||
e := c.Close()
|
e := c.Close()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
log.Warnf("error while closingWireguard proxy connection of peer connection %s", conn.Config.RemoteWgKey.String())
|
log.Warnf("error while closingWireguard proxy connection of peer connection %s", conn.Config.RemoteWgKey.String())
|
||||||
@ -301,72 +296,3 @@ func (conn *Connection) listenOnConnectionStateChanges() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// createWireguardProxy opens connection to a local Wireguard instance (proxy) and sets Wireguard's peer endpoint to point
|
|
||||||
// to a local address of a proxy
|
|
||||||
func (conn *Connection) createWireguardProxy() (*net.Conn, error) {
|
|
||||||
wgConn, err := net.Dial("udp", conn.Config.WgListenAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed dialing to local Wireguard port %s", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// add local proxy connection as a Wireguard peer
|
|
||||||
err = iface.UpdatePeer(conn.Config.WgIface, conn.Config.RemoteWgKey.String(), conn.Config.WgAllowedIPs, DefaultWgKeepAlive,
|
|
||||||
wgConn.LocalAddr().String())
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("error while configuring Wireguard peer [%s] %s", conn.Config.RemoteWgKey.String(), err.Error())
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &wgConn, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// proxyToRemotePeer proxies everything from Wireguard to the remote peer
|
|
||||||
// blocks
|
|
||||||
func (conn *Connection) proxyToRemotePeer(wgConn net.Conn, remoteConn *ice.Conn) {
|
|
||||||
|
|
||||||
buf := make([]byte, 1500)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-conn.closeCond.C:
|
|
||||||
log.Infof("stopped proxying from remote peer %s due to closed connection", conn.Config.RemoteWgKey.String())
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
n, err := wgConn.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
//log.Warnln("failed reading from peer: ", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err = remoteConn.Write(buf[:n])
|
|
||||||
if err != nil {
|
|
||||||
//log.Warnln("failed writing to remote peer: ", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// proxyToLocalWireguard proxies everything from the remote peer to local Wireguard
|
|
||||||
// blocks
|
|
||||||
func (conn *Connection) proxyToLocalWireguard(wgConn net.Conn, remoteConn *ice.Conn) {
|
|
||||||
|
|
||||||
buf := make([]byte, 1500)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-conn.closeCond.C:
|
|
||||||
log.Infof("stopped proxying from remote peer %s due to closed connection", conn.Config.RemoteWgKey.String())
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
n, err := remoteConn.Read(buf)
|
|
||||||
if err != nil {
|
|
||||||
//log.Errorf("failed reading from remote connection %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err = wgConn.Write(buf[:n])
|
|
||||||
if err != nil {
|
|
||||||
//log.Errorf("failed writing to local Wireguard instance %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
111
connection/wgproxy.go
Normal file
111
connection/wgproxy.go
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package connection
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pion/ice/v2"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/wiretrustee/wiretrustee/iface"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WgProxy struct {
|
||||||
|
iface string
|
||||||
|
remoteKey string
|
||||||
|
allowedIps string
|
||||||
|
wgAddr string
|
||||||
|
close chan struct{}
|
||||||
|
wgConn net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
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{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *WgProxy) Close() error {
|
||||||
|
|
||||||
|
close(p.close)
|
||||||
|
if c := p.wgConn; c != nil {
|
||||||
|
err := p.wgConn.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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.Infof("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
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = remoteConn.Write(buf[:n])
|
||||||
|
if err != nil {
|
||||||
|
//log.Warnln("failed writing to remote peer: ", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.Infof("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)
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = p.wgConn.Write(buf[:n])
|
||||||
|
if err != nil {
|
||||||
|
//log.Errorf("failed writing to local Wireguard instance %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user