mirror of
https://github.com/fosrl/newt.git
synced 2026-02-08 05:56:40 +00:00
Bring in netstack locally
This commit is contained in:
@@ -5,9 +5,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fosrl/newt/logger"
|
"github.com/fosrl/newt/logger"
|
||||||
|
"github.com/fosrl/newt/netstack2"
|
||||||
"github.com/fosrl/newt/proxy"
|
"github.com/fosrl/newt/proxy"
|
||||||
"github.com/fosrl/newt/websocket"
|
"github.com/fosrl/newt/websocket"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
|
||||||
|
|
||||||
"github.com/fosrl/newt/wgnetstack"
|
"github.com/fosrl/newt/wgnetstack"
|
||||||
"github.com/fosrl/newt/wgtester"
|
"github.com/fosrl/newt/wgtester"
|
||||||
@@ -37,7 +37,7 @@ func setupClients(client *websocket.Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setupClientsNetstack(client *websocket.Client, host string) {
|
func setupClientsNetstack(client *websocket.Client, host string) {
|
||||||
logger.Info("Setting up clients with netstack...")
|
logger.Info("Setting up clients with netstack2...")
|
||||||
// Create WireGuard service
|
// Create WireGuard service
|
||||||
wgService, err = wgnetstack.NewWireGuardService(interfaceName, mtuInt, generateAndSaveKeyTo, host, id, client, "9.9.9.9")
|
wgService, err = wgnetstack.NewWireGuardService(interfaceName, mtuInt, generateAndSaveKeyTo, host, id, client, "9.9.9.9")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -45,7 +45,7 @@ func setupClientsNetstack(client *websocket.Client, host string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// // Set up callback to restart wgtester with netstack when WireGuard is ready
|
// // Set up callback to restart wgtester with netstack when WireGuard is ready
|
||||||
wgService.SetOnNetstackReady(func(tnet *netstack.Net) {
|
wgService.SetOnNetstackReady(func(tnet *netstack2.Net) {
|
||||||
|
|
||||||
wgTesterServer = wgtester.NewServerWithNetstack("0.0.0.0", wgService.Port, id, tnet) // TODO: maybe make this the same ip of the wg server?
|
wgTesterServer = wgtester.NewServerWithNetstack("0.0.0.0", wgService.Port, id, tnet) // TODO: maybe make this the same ip of the wg server?
|
||||||
err := wgTesterServer.Start()
|
err := wgTesterServer.Start()
|
||||||
@@ -66,7 +66,7 @@ func setupClientsNetstack(client *websocket.Client, host string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDownstreamTNetstack(tnet *netstack.Net) {
|
func setDownstreamTNetstack(tnet *netstack2.Net) {
|
||||||
if wgService != nil {
|
if wgService != nil {
|
||||||
wgService.SetOthertnet(tnet)
|
wgService.SetOthertnet(tnet)
|
||||||
}
|
}
|
||||||
|
|||||||
6
main.go
6
main.go
@@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/fosrl/newt/docker"
|
"github.com/fosrl/newt/docker"
|
||||||
"github.com/fosrl/newt/healthcheck"
|
"github.com/fosrl/newt/healthcheck"
|
||||||
"github.com/fosrl/newt/logger"
|
"github.com/fosrl/newt/logger"
|
||||||
|
"github.com/fosrl/newt/netstack2"
|
||||||
"github.com/fosrl/newt/proxy"
|
"github.com/fosrl/newt/proxy"
|
||||||
"github.com/fosrl/newt/updates"
|
"github.com/fosrl/newt/updates"
|
||||||
"github.com/fosrl/newt/websocket"
|
"github.com/fosrl/newt/websocket"
|
||||||
@@ -30,7 +31,6 @@ import (
|
|||||||
"golang.zx2c4.com/wireguard/conn"
|
"golang.zx2c4.com/wireguard/conn"
|
||||||
"golang.zx2c4.com/wireguard/device"
|
"golang.zx2c4.com/wireguard/device"
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -531,7 +531,7 @@ func main() {
|
|||||||
|
|
||||||
// Create TUN device and network stack
|
// Create TUN device and network stack
|
||||||
var tun tun.Device
|
var tun tun.Device
|
||||||
var tnet *netstack.Net
|
var tnet *netstack2.Net
|
||||||
var dev *device.Device
|
var dev *device.Device
|
||||||
var pm *proxy.ProxyManager
|
var pm *proxy.ProxyManager
|
||||||
var connected bool
|
var connected bool
|
||||||
@@ -637,7 +637,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug(fmtReceivedMsg, msg)
|
logger.Debug(fmtReceivedMsg, msg)
|
||||||
tun, tnet, err = netstack.CreateNetTUN(
|
tun, tnet, err = netstack2.CreateNetTUN(
|
||||||
[]netip.Addr{netip.MustParseAddr(wgData.TunnelIP)},
|
[]netip.Addr{netip.MustParseAddr(wgData.TunnelIP)},
|
||||||
[]netip.Addr{netip.MustParseAddr(dns)},
|
[]netip.Addr{netip.MustParseAddr(dns)},
|
||||||
mtuInt)
|
mtuInt)
|
||||||
|
|||||||
1057
netstack2/tun.go
Normal file
1057
netstack2/tun.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,9 +15,9 @@ import (
|
|||||||
"github.com/fosrl/newt/internal/state"
|
"github.com/fosrl/newt/internal/state"
|
||||||
"github.com/fosrl/newt/internal/telemetry"
|
"github.com/fosrl/newt/internal/telemetry"
|
||||||
"github.com/fosrl/newt/logger"
|
"github.com/fosrl/newt/logger"
|
||||||
|
"github.com/fosrl/newt/netstack2"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/metric"
|
"go.opentelemetry.io/otel/metric"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
|
||||||
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ type Target struct {
|
|||||||
|
|
||||||
// ProxyManager handles the creation and management of proxy connections
|
// ProxyManager handles the creation and management of proxy connections
|
||||||
type ProxyManager struct {
|
type ProxyManager struct {
|
||||||
tnet *netstack.Net
|
tnet *netstack2.Net
|
||||||
tcpTargets map[string]map[int]string // map[listenIP]map[port]targetAddress
|
tcpTargets map[string]map[int]string // map[listenIP]map[port]targetAddress
|
||||||
udpTargets map[string]map[int]string
|
udpTargets map[string]map[int]string
|
||||||
listeners []*gonet.TCPListener
|
listeners []*gonet.TCPListener
|
||||||
@@ -125,7 +125,7 @@ func classifyProxyError(err error) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewProxyManager creates a new proxy manager instance
|
// NewProxyManager creates a new proxy manager instance
|
||||||
func NewProxyManager(tnet *netstack.Net) *ProxyManager {
|
func NewProxyManager(tnet *netstack2.Net) *ProxyManager {
|
||||||
return &ProxyManager{
|
return &ProxyManager{
|
||||||
tnet: tnet,
|
tnet: tnet,
|
||||||
tcpTargets: make(map[string]map[int]string),
|
tcpTargets: make(map[string]map[int]string),
|
||||||
@@ -214,7 +214,7 @@ func NewProxyManagerWithoutTNet() *ProxyManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function to add tnet to existing ProxyManager
|
// Function to add tnet to existing ProxyManager
|
||||||
func (pm *ProxyManager) SetTNet(tnet *netstack.Net) {
|
func (pm *ProxyManager) SetTNet(tnet *netstack2.Net) {
|
||||||
pm.mutex.Lock()
|
pm.mutex.Lock()
|
||||||
defer pm.mutex.Unlock()
|
defer pm.mutex.Unlock()
|
||||||
pm.tnet = tnet
|
pm.tnet = tnet
|
||||||
|
|||||||
10
util.go
10
util.go
@@ -17,12 +17,12 @@ import (
|
|||||||
|
|
||||||
"github.com/fosrl/newt/internal/telemetry"
|
"github.com/fosrl/newt/internal/telemetry"
|
||||||
"github.com/fosrl/newt/logger"
|
"github.com/fosrl/newt/logger"
|
||||||
|
"github.com/fosrl/newt/netstack2"
|
||||||
"github.com/fosrl/newt/proxy"
|
"github.com/fosrl/newt/proxy"
|
||||||
"github.com/fosrl/newt/websocket"
|
"github.com/fosrl/newt/websocket"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
"golang.zx2c4.com/wireguard/device"
|
"golang.zx2c4.com/wireguard/device"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ func fixKey(key string) string {
|
|||||||
return hex.EncodeToString(decoded)
|
return hex.EncodeToString(decoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ping(tnet *netstack.Net, dst string, timeout time.Duration) (time.Duration, error) {
|
func ping(tnet *netstack2.Net, dst string, timeout time.Duration) (time.Duration, error) {
|
||||||
logger.Debug("Pinging %s", dst)
|
logger.Debug("Pinging %s", dst)
|
||||||
socket, err := tnet.Dial("ping4", dst)
|
socket, err := tnet.Dial("ping4", dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -108,7 +108,7 @@ func ping(tnet *netstack.Net, dst string, timeout time.Duration) (time.Duration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reliablePing performs multiple ping attempts with adaptive timeout
|
// reliablePing performs multiple ping attempts with adaptive timeout
|
||||||
func reliablePing(tnet *netstack.Net, dst string, baseTimeout time.Duration, maxAttempts int) (time.Duration, error) {
|
func reliablePing(tnet *netstack2.Net, dst string, baseTimeout time.Duration, maxAttempts int) (time.Duration, error) {
|
||||||
var lastErr error
|
var lastErr error
|
||||||
var totalLatency time.Duration
|
var totalLatency time.Duration
|
||||||
successCount := 0
|
successCount := 0
|
||||||
@@ -152,7 +152,7 @@ func reliablePing(tnet *netstack.Net, dst string, baseTimeout time.Duration, max
|
|||||||
return totalLatency / time.Duration(successCount), nil
|
return totalLatency / time.Duration(successCount), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func pingWithRetry(tnet *netstack.Net, dst string, timeout time.Duration) (stopChan chan struct{}, err error) {
|
func pingWithRetry(tnet *netstack2.Net, dst string, timeout time.Duration) (stopChan chan struct{}, err error) {
|
||||||
|
|
||||||
if healthFile != "" {
|
if healthFile != "" {
|
||||||
err = os.Remove(healthFile)
|
err = os.Remove(healthFile)
|
||||||
@@ -236,7 +236,7 @@ func pingWithRetry(tnet *netstack.Net, dst string, timeout time.Duration) (stopC
|
|||||||
return stopChan, fmt.Errorf("initial ping attempts failed, continuing in background")
|
return stopChan, fmt.Errorf("initial ping attempts failed, continuing in background")
|
||||||
}
|
}
|
||||||
|
|
||||||
func startPingCheck(tnet *netstack.Net, serverIP string, client *websocket.Client, tunnelID string) chan struct{} {
|
func startPingCheck(tnet *netstack2.Net, serverIP string, client *websocket.Client, tunnelID string) chan struct{} {
|
||||||
maxInterval := 6 * time.Second
|
maxInterval := 6 * time.Second
|
||||||
currentInterval := pingInterval
|
currentInterval := pingInterval
|
||||||
consecutiveFailures := 0
|
consecutiveFailures := 0
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fosrl/newt/logger"
|
"github.com/fosrl/newt/logger"
|
||||||
|
"github.com/fosrl/newt/netstack2"
|
||||||
"github.com/fosrl/newt/network"
|
"github.com/fosrl/newt/network"
|
||||||
"github.com/fosrl/newt/proxy"
|
"github.com/fosrl/newt/proxy"
|
||||||
"github.com/fosrl/newt/websocket"
|
"github.com/fosrl/newt/websocket"
|
||||||
@@ -25,7 +26,6 @@ import (
|
|||||||
"golang.zx2c4.com/wireguard/conn"
|
"golang.zx2c4.com/wireguard/conn"
|
||||||
"golang.zx2c4.com/wireguard/device"
|
"golang.zx2c4.com/wireguard/device"
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
|
||||||
"github.com/fosrl/newt/internal/telemetry"
|
"github.com/fosrl/newt/internal/telemetry"
|
||||||
@@ -83,14 +83,14 @@ type WireGuardService struct {
|
|||||||
stopGetConfig func()
|
stopGetConfig func()
|
||||||
// Netstack fields
|
// Netstack fields
|
||||||
tun tun.Device
|
tun tun.Device
|
||||||
tnet *netstack.Net
|
tnet *netstack2.Net
|
||||||
device *device.Device
|
device *device.Device
|
||||||
dns []netip.Addr
|
dns []netip.Addr
|
||||||
// Callback for when netstack is ready
|
// Callback for when netstack is ready
|
||||||
onNetstackReady func(*netstack.Net)
|
onNetstackReady func(*netstack2.Net)
|
||||||
// Callback for when netstack is closed
|
// Callback for when netstack is closed
|
||||||
onNetstackClose func()
|
onNetstackClose func()
|
||||||
othertnet *netstack.Net
|
othertnet *netstack2.Net
|
||||||
// Proxy manager for tunnel
|
// Proxy manager for tunnel
|
||||||
proxyManager *proxy.ProxyManager
|
proxyManager *proxy.ProxyManager
|
||||||
TunnelIP string
|
TunnelIP string
|
||||||
@@ -247,7 +247,9 @@ func NewWireGuardService(interfaceName string, mtu int, generateAndSaveKeyTo str
|
|||||||
|
|
||||||
// ReportRTT allows reporting native RTTs to telemetry, rate-limited externally.
|
// ReportRTT allows reporting native RTTs to telemetry, rate-limited externally.
|
||||||
func (s *WireGuardService) ReportRTT(seconds float64) {
|
func (s *WireGuardService) ReportRTT(seconds float64) {
|
||||||
if s.serverPubKey == "" { return }
|
if s.serverPubKey == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
telemetry.ObserveTunnelLatency(context.Background(), s.serverPubKey, "wireguard", seconds)
|
telemetry.ObserveTunnelLatency(context.Background(), s.serverPubKey, "wireguard", seconds)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +260,7 @@ func (s *WireGuardService) addTcpTarget(msg websocket.WSMessage) {
|
|||||||
if s.TunnelIP == "" || s.proxyManager == nil {
|
if s.TunnelIP == "" || s.proxyManager == nil {
|
||||||
logger.Info("No tunnel IP or proxy manager available")
|
logger.Info("No tunnel IP or proxy manager available")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
targetData, err := parseTargetData(msg.Data)
|
targetData, err := parseTargetData(msg.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -331,7 +333,7 @@ func (s *WireGuardService) removeTcpTarget(msg websocket.WSMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WireGuardService) SetOthertnet(tnet *netstack.Net) {
|
func (s *WireGuardService) SetOthertnet(tnet *netstack2.Net) {
|
||||||
s.othertnet = tnet
|
s.othertnet = tnet
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +384,7 @@ func (s *WireGuardService) SetToken(token string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetNetstackNet returns the netstack network interface for use by other components
|
// GetNetstackNet returns the netstack network interface for use by other components
|
||||||
func (s *WireGuardService) GetNetstackNet() *netstack.Net {
|
func (s *WireGuardService) GetNetstackNet() *netstack2.Net {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
return s.tnet
|
return s.tnet
|
||||||
@@ -401,7 +403,7 @@ func (s *WireGuardService) GetPublicKey() wgtypes.Key {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetOnNetstackReady sets a callback function to be called when the netstack interface is ready
|
// SetOnNetstackReady sets a callback function to be called when the netstack interface is ready
|
||||||
func (s *WireGuardService) SetOnNetstackReady(callback func(*netstack.Net)) {
|
func (s *WireGuardService) SetOnNetstackReady(callback func(*netstack2.Net)) {
|
||||||
s.onNetstackReady = callback
|
s.onNetstackReady = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +495,7 @@ func (s *WireGuardService) ensureWireguardInterface(wgconfig WgConfig) error {
|
|||||||
|
|
||||||
// Create TUN device and network stack using netstack
|
// Create TUN device and network stack using netstack
|
||||||
var err error
|
var err error
|
||||||
s.tun, s.tnet, err = netstack.CreateNetTUN(
|
s.tun, s.tnet, err = netstack2.CreateNetTUN(
|
||||||
[]netip.Addr{tunnelIP},
|
[]netip.Addr{tunnelIP},
|
||||||
s.dns,
|
s.dns,
|
||||||
s.mtu)
|
s.mtu)
|
||||||
@@ -1202,7 +1204,7 @@ func (s *WireGuardService) ReplaceNetstack() error {
|
|||||||
s.proxyManager.Stop()
|
s.proxyManager.Stop()
|
||||||
|
|
||||||
// Create new TUN device and netstack with new DNS
|
// Create new TUN device and netstack with new DNS
|
||||||
newTun, newTnet, err := netstack.CreateNetTUN(
|
newTun, newTnet, err := netstack2.CreateNetTUN(
|
||||||
[]netip.Addr{tunnelIP},
|
[]netip.Addr{tunnelIP},
|
||||||
s.dns,
|
s.dns,
|
||||||
s.mtu)
|
s.mtu)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fosrl/newt/logger"
|
"github.com/fosrl/newt/logger"
|
||||||
"golang.zx2c4.com/wireguard/tun/netstack"
|
"github.com/fosrl/newt/netstack2"
|
||||||
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ type Server struct {
|
|||||||
newtID string
|
newtID string
|
||||||
outputPrefix string
|
outputPrefix string
|
||||||
useNetstack bool
|
useNetstack bool
|
||||||
tnet interface{} // Will be *netstack.Net when using netstack
|
tnet interface{} // Will be *netstack2.Net when using netstack
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a new connection test server using UDP
|
// NewServer creates a new connection test server using UDP
|
||||||
@@ -56,7 +56,7 @@ func NewServer(serverAddr string, serverPort uint16, newtID string) *Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewServerWithNetstack creates a new connection test server using WireGuard netstack
|
// NewServerWithNetstack creates a new connection test server using WireGuard netstack
|
||||||
func NewServerWithNetstack(serverAddr string, serverPort uint16, newtID string, tnet *netstack.Net) *Server {
|
func NewServerWithNetstack(serverAddr string, serverPort uint16, newtID string, tnet *netstack2.Net) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
serverAddr: serverAddr,
|
serverAddr: serverAddr,
|
||||||
serverPort: serverPort + 1, // use the next port for the server
|
serverPort: serverPort + 1, // use the next port for the server
|
||||||
@@ -82,7 +82,7 @@ func (s *Server) Start() error {
|
|||||||
|
|
||||||
if s.useNetstack && s.tnet != nil {
|
if s.useNetstack && s.tnet != nil {
|
||||||
// Use WireGuard netstack
|
// Use WireGuard netstack
|
||||||
tnet := s.tnet.(*netstack.Net)
|
tnet := s.tnet.(*netstack2.Net)
|
||||||
udpAddr := &net.UDPAddr{Port: int(s.serverPort)}
|
udpAddr := &net.UDPAddr{Port: int(s.serverPort)}
|
||||||
netstackConn, err := tnet.ListenUDP(udpAddr)
|
netstackConn, err := tnet.ListenUDP(udpAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -130,7 +130,7 @@ func (s *Server) Stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RestartWithNetstack stops the current server and restarts it with netstack
|
// RestartWithNetstack stops the current server and restarts it with netstack
|
||||||
func (s *Server) RestartWithNetstack(tnet *netstack.Net) error {
|
func (s *Server) RestartWithNetstack(tnet *netstack2.Net) error {
|
||||||
s.Stop()
|
s.Stop()
|
||||||
|
|
||||||
// Update configuration to use netstack
|
// Update configuration to use netstack
|
||||||
|
|||||||
Reference in New Issue
Block a user