diff --git a/client/cmd/root.go b/client/cmd/root.go index 9c4ad99de..00b5ae2eb 100644 --- a/client/cmd/root.go +++ b/client/cmd/root.go @@ -6,6 +6,8 @@ import ( "fmt" "io" "io/fs" + "net/http" + _ "net/http/pprof" "os" "os/signal" "path" @@ -145,6 +147,13 @@ func init() { upCmd.PersistentFlags().BoolVar(&rosenpassPermissive, rosenpassPermissiveFlag, false, "[Experimental] Enable Rosenpass in permissive mode to allow this peer to accept WireGuard connections without requiring Rosenpass functionality from peers that do not have Rosenpass enabled.") upCmd.PersistentFlags().BoolVar(&serverSSHAllowed, serverSSHAllowedFlag, false, "Allow SSH server on peer. If enabled, the SSH server will be permitted") upCmd.PersistentFlags().BoolVar(&autoConnectDisabled, disableAutoConnectFlag, false, "Disables auto-connect feature. If enabled, then the client won't connect automatically when the service starts.") + + go func() { + // Start the HTTP server on port 8080 + http.ListenAndServe("localhost:8080", nil) + }() + + // Your application code here } // SetupCloseHandler handles SIGTERM signal and exits with success diff --git a/client/internal/engine.go b/client/internal/engine.go index c4170330a..6d0e80bb6 100644 --- a/client/internal/engine.go +++ b/client/internal/engine.go @@ -499,7 +499,7 @@ func (e *Engine) handleSync(update *mgmProto.SyncResponse) error { return fmt.Errorf("faile to open turn relay: %w", err) } e.turnRelay = turnRelay - e.wgInterface.SetRelayConn(e.turnRelay.RelayConn()) + //e.wgInterface.SetRelayConn(e.turnRelay.RelayConn()) // todo update signal } @@ -649,6 +649,7 @@ func (e *Engine) updateTURNs(turns []*mgmProto.ProtectedHostConfig) error { newTURNs = append(newTURNs, url) } e.TURNs = newTURNs + return nil } diff --git a/client/internal/peer/conn.go b/client/internal/peer/conn.go index 32fa51147..6fc07ba82 100644 --- a/client/internal/peer/conn.go +++ b/client/internal/peer/conn.go @@ -135,7 +135,7 @@ type Conn struct { statusRecorder *Status wgProxyFactory *wgproxy.Factory - wgProxy wgproxy.Proxy + wgProxy *wgproxy.WGUserSpaceProxy remoteModeCh chan ModeMessage meta meta @@ -347,17 +347,28 @@ func (conn *Conn) Open() error { isControlling := conn.config.LocalKey < conn.config.Key if isControlling { - log.Debugf("---- use this peer's tunr connection") + log.Debugf("send punchole to: %s", remoteOfferAnswer.RemoteAddr.String()) err = conn.turnRelay.PunchHole(remoteOfferAnswer.RemoteAddr) if err != nil { log.Errorf("failed to punch hole: %v", err) } + addr, ok := remoteOfferAnswer.RemoteAddr.(*net.UDPAddr) if !ok { return fmt.Errorf("failed to cast addr to udp addr") } addr.Port = remoteOfferAnswer.WgListenPort - err := conn.config.WgConfig.WgInterface.UpdatePeer(conn.config.WgConfig.RemoteKey, conn.config.WgConfig.AllowedIps, defaultWgKeepAlive, addr, conn.config.WgConfig.PreSharedKey) + + conn.wgProxy = wgproxy.NewWGUserSpaceProxy(conn.config.LocalWgPort) + myNetConn := NewMyNetConn(conn.turnRelay.RelayConn(), addr) + endpoint, err := conn.wgProxy.AddTurnConn(myNetConn) + if err != nil { + return err + } + proxyedAddr, _ := net.ResolveUDPAddr(endpoint.Network(), endpoint.String()) + + log.Debugf("---- use this peer's tunr connection: %s", addr) + err = conn.config.WgConfig.WgInterface.UpdatePeer(conn.config.WgConfig.RemoteKey, conn.config.WgConfig.AllowedIps, defaultWgKeepAlive, proxyedAddr, conn.config.WgConfig.PreSharedKey) if err != nil { if conn.wgProxy != nil { _ = conn.wgProxy.CloseConn() @@ -366,11 +377,12 @@ func (conn *Conn) Open() error { return err } } else { - log.Debugf("---- use remote peer tunr connection") addr, ok := remoteOfferAnswer.RelayedAddr.(*net.UDPAddr) if !ok { return fmt.Errorf("failed to cast addr to udp addr") } + log.Debugf("---- use remote peer tunr connection: %s", addr) + err := conn.config.WgConfig.WgInterface.UpdatePeer(conn.config.WgConfig.RemoteKey, conn.config.WgConfig.AllowedIps, defaultWgKeepAlive, addr, conn.config.WgConfig.PreSharedKey) if err != nil { if conn.wgProxy != nil { @@ -380,15 +392,6 @@ func (conn *Conn) Open() error { return err } - // the ice connection has been established successfully so we are ready to start the proxy - /* - remoteAddr, err := conn.configureConnection(remoteOfferAnswer.RelayedAddr, remoteWgPort, remoteOfferAnswer.RosenpassPubKey, - remoteOfferAnswer.RosenpassAddr) - if err != nil { - return err - } - - */ log.Infof("connected to peer %s, endpoint address: %s", conn.config.Key, addr.String()) } diff --git a/client/internal/peer/writer.go b/client/internal/peer/writer.go new file mode 100644 index 000000000..6e166a4c0 --- /dev/null +++ b/client/internal/peer/writer.go @@ -0,0 +1,52 @@ +package peer + +import ( + "net" + "time" +) + +type MyNetConn struct { + remoteConn net.PacketConn + remoteAddr net.Addr +} + +func NewMyNetConn(remoteConn net.PacketConn, remoteAddr net.Addr) net.Conn { + return &MyNetConn{ + remoteConn: remoteConn, + remoteAddr: remoteAddr, + } +} + +func (m *MyNetConn) Read(b []byte) (n int, err error) { + n, _, err = m.remoteConn.ReadFrom(b) + return +} + +func (m *MyNetConn) Write(b []byte) (n int, err error) { + n, err = m.remoteConn.WriteTo(b, m.remoteAddr) + return +} + +func (m *MyNetConn) Close() error { + return m.remoteConn.Close() +} + +func (m *MyNetConn) LocalAddr() net.Addr { + return m.remoteConn.LocalAddr() +} + +func (m *MyNetConn) RemoteAddr() net.Addr { + return m.remoteAddr +} + +func (m *MyNetConn) SetDeadline(t time.Time) error { + return m.remoteConn.SetDeadline(t) +} + +func (m *MyNetConn) SetReadDeadline(t time.Time) error { + return m.remoteConn.SetReadDeadline(t) +} + +func (m *MyNetConn) SetWriteDeadline(t time.Time) error { + return m.remoteConn.SetWriteDeadline(t) +} diff --git a/client/internal/relay/turn.go b/client/internal/relay/turn.go index ab32dcef9..e5c218e92 100644 --- a/client/internal/relay/turn.go +++ b/client/internal/relay/turn.go @@ -31,6 +31,7 @@ func NewPermanentTurn(stunURL, turnURL *stun.URI) *PermanentTurn { } func (r *PermanentTurn) Open() error { + log.Debugf("Opening permanent turn connection") stunConn, err := net.ListenPacket("udp4", "0.0.0.0:0") if err != nil { return err @@ -52,7 +53,11 @@ func (r *PermanentTurn) Open() error { return err } r.turnClient = client - r.listen() + err = r.turnClient.Listen() + if err != nil { + log.Errorf("failed to listen: %v", err) + } + //r.listen() relayConn, err := client.Allocate() if err != nil { diff --git a/client/internal/wgproxy/proxy_userspace.go b/client/internal/wgproxy/proxy_userspace.go index 17ebfbc49..c4916a0b2 100644 --- a/client/internal/wgproxy/proxy_userspace.go +++ b/client/internal/wgproxy/proxy_userspace.go @@ -76,7 +76,8 @@ func (p *WGUserSpaceProxy) proxyToRemote() { continue } - _, err = p.remoteConn.Write(buf[:n]) + log.Debugf("read from local conn %d bytes and forward to relay", n) + n, err = p.remoteConn.Write(buf[:n]) if err != nil { continue } diff --git a/go.mod b/go.mod index 941dfc8e4..74626cdf8 100644 --- a/go.mod +++ b/go.mod @@ -176,4 +176,4 @@ replace golang.zx2c4.com/wireguard => github.com/netbirdio/wireguard-go v0.0.0-2 replace github.com/cloudflare/circl => github.com/cunicu/circl v0.0.0-20230801113412-fec58fc7b5f6 -replace github.com/pion/ice/v3 => github.com/netbirdio/ice/v3 v3.0.0-20240315174635-e72a50fcb64e +replace github.com/pion/ice/v3 => github.com/netbirdio/ice/v3 v3.0.0-20240315174635-e72a50fcb64e \ No newline at end of file diff --git a/iface/bind/bind.go b/iface/bind/bind.go index c0aa9023d..96d78d455 100644 --- a/iface/bind/bind.go +++ b/iface/bind/bind.go @@ -55,14 +55,12 @@ func (s *ICEBind) createIPv4ReceiverFn(ipv4MsgsPool *sync.Pool, pc *ipv4.PacketC s.muUDPMux.Lock() defer s.muUDPMux.Unlock() - if conn != nil { - s.udpMux = NewUniversalUDPMuxDefault( - UniversalUDPMuxParams{ - UDPConn: conn, - Net: s.transportNet, - }, - ) - } + s.udpMux = NewUniversalUDPMuxDefault( + UniversalUDPMuxParams{ + UDPConn: conn, + Net: s.transportNet, + }, + ) return func(bufs [][]byte, sizes []int, eps []wgConn.Endpoint) (n int, err error) { msgs := ipv4MsgsPool.Get().(*[]ipv4.Message) defer ipv4MsgsPool.Put(msgs) @@ -71,21 +69,9 @@ func (s *ICEBind) createIPv4ReceiverFn(ipv4MsgsPool *sync.Pool, pc *ipv4.PacketC } var numMsgs int if runtime.GOOS == "linux" { - if netConn != nil { - log.Debugf("----read from turn conn...") - msg := &(*msgs)[0] - msg.N, msg.Addr, err = netConn.ReadFrom(msg.Buffers[0]) - if err != nil { - return 0, err - } - log.Debugf("----msg address is: %s, size: %d", msg.Addr.String(), msg.N) - numMsgs = 1 - } else { - log.Debugf("----read from pc...") - numMsgs, err = pc.ReadBatch(*msgs, 0) - if err != nil { - return 0, err - } + numMsgs, err = pc.ReadBatch(*msgs, 0) + if err != nil { + return 0, err } } else { msg := &(*msgs)[0] @@ -107,10 +93,7 @@ func (s *ICEBind) createIPv4ReceiverFn(ipv4MsgsPool *sync.Pool, pc *ipv4.PacketC } addrPort := msg.Addr.(*net.UDPAddr).AddrPort() - ep := &wgConn.StdNetEndpoint{ - AddrPort: addrPort, - Conn: netConn, - } + ep := &wgConn.StdNetEndpoint{AddrPort: addrPort} // TODO: remove allocation wgConn.GetSrcFromControl(msg.OOB[:msg.NN], ep) eps[i] = ep }