diff --git a/linux.go b/linux.go new file mode 100644 index 0000000..076e2f1 --- /dev/null +++ b/linux.go @@ -0,0 +1,80 @@ +//go:build linux + +package main + +import ( + "fmt" + "strings" + + "github.com/fosrl/newt/logger" + "github.com/fosrl/newt/proxy" + "github.com/fosrl/newt/websocket" + "github.com/fosrl/newt/wg" + "github.com/fosrl/newt/wgtester" +) + +var wgService *wg.WireGuardService +var wgTesterServer *wgtester.Server + +func setupClients(client *websocket.Client) { + var host = endpoint + if strings.HasPrefix(host, "http://") { + host = strings.TrimPrefix(host, "http://") + } else if strings.HasPrefix(host, "https://") { + host = strings.TrimPrefix(host, "https://") + } + + host = strings.TrimSuffix(host, "/") + + // Create WireGuard service + wgService, err = wg.NewWireGuardService(interfaceName, mtuInt, generateAndSaveKeyTo, host, id, client) + if err != nil { + logger.Fatal("Failed to create WireGuard service: %v", err) + } + defer wgService.Close(rm) + + wgTesterServer = wgtester.NewServer("0.0.0.0", wgService.Port, id) // TODO: maybe make this the same ip of the wg server? + err := wgTesterServer.Start() + if err != nil { + logger.Error("Failed to start WireGuard tester server: %v", err) + } else { + // Make sure to stop the server on exit + defer wgTesterServer.Stop() + } + + client.OnTokenUpdate(func(token string) { + wgService.SetToken(token) + }) +} + +func closeClients() { + if wgService != nil { + wgService.Close(rm) + wgService = nil + } + + if wgTesterServer != nil { + wgTesterServer.Stop() + wgTesterServer = nil + } +} + +func clientsHandleNewtConnection(publicKey string) { + if wgService != nil { + wgService.SetServerPubKey(publicKey) + } else { + logger.Error("WireGuard service is not initialized, cannot set server public key") + } +} + +func clientsOnConnect() { + if wgService != nil { + wgService.LoadRemoteConfig() + } +} + +func clientsAddProxyTarget(pm *proxy.ProxyManager, tunnelIp string) { + // add a udp proxy for localost and the wgService port + // TODO: make sure this port is not used in a target + pm.AddTarget("udp", tunnelIp, int(wgService.Port), fmt.Sprintf("127.0.0.1:%d", wgService.Port)) +} diff --git a/main.go b/main.go index 0a4fdf3..9b517c7 100644 --- a/main.go +++ b/main.go @@ -19,8 +19,6 @@ import ( "github.com/fosrl/newt/proxy" "github.com/fosrl/newt/updates" "github.com/fosrl/newt/websocket" - "github.com/fosrl/newt/wg" - "github.com/fosrl/newt/wgtester" "golang.zx2c4.com/wireguard/conn" "golang.zx2c4.com/wireguard/device" @@ -255,14 +253,12 @@ func main() { } // Create TUN device and network stack - var wgService *wg.WireGuardService var tun tun.Device var tnet *netstack.Net var dev *device.Device var pm *proxy.ProxyManager var connected bool var wgData WgData - var wgTesterServer *wgtester.Server if acceptClients { // make sure we are running on linux @@ -271,30 +267,7 @@ func main() { os.Exit(1) } - var host = endpoint - if strings.HasPrefix(host, "http://") { - host = strings.TrimPrefix(host, "http://") - } else if strings.HasPrefix(host, "https://") { - host = strings.TrimPrefix(host, "https://") - } - - host = strings.TrimSuffix(host, "/") - - // Create WireGuard service - wgService, err = wg.NewWireGuardService(interfaceName, mtuInt, generateAndSaveKeyTo, host, id, client) - if err != nil { - logger.Fatal("Failed to create WireGuard service: %v", err) - } - defer wgService.Close(rm) - - wgTesterServer = wgtester.NewServer("0.0.0.0", wgService.Port, id) // TODO: maybe make this the same ip of the wg server? - err := wgTesterServer.Start() - if err != nil { - logger.Error("Failed to start WireGuard tester server: %v", err) - } else { - // Make sure to stop the server on exit - defer wgTesterServer.Stop() - } + setupClients(client) } var pingWithRetryStopChan chan struct{} @@ -349,9 +322,7 @@ func main() { return } - if wgService != nil { - wgService.SetServerPubKey(wgData.PublicKey) - } + clientsHandleNewtConnection(wgData.PublicKey) logger.Info("Received: %+v", msg) tun, tnet, err = netstack.CreateNetTUN( @@ -423,12 +394,7 @@ persistent_keepalive_interval=5`, fixKey(privateKey.String()), fixKey(wgData.Pub updateTargets(pm, "add", wgData.TunnelIP, "udp", TargetData{Targets: wgData.Targets.UDP}) } - // first make sure the wpgService has a port - if wgService != nil { - // add a udp proxy for localost and the wgService port - // TODO: make sure this port is not used in a target - pm.AddTarget("udp", wgData.TunnelIP, int(wgService.Port), fmt.Sprintf("127.0.0.1:%d", wgService.Port)) - } + clientsAddProxyTarget(pm, wgData.TunnelIP) err = pm.Start() if err != nil { @@ -734,9 +700,7 @@ persistent_keepalive_interval=5`, fixKey(privateKey.String()), fixKey(wgData.Pub // request from the server the list of nodes to ping at newt/ping/request stopFunc = client.SendMessageInterval("newt/ping/request", map[string]interface{}{}, 3*time.Second) - if wgService != nil { - wgService.LoadRemoteConfig() - } + clientsOnConnect() } // Send registration message to the server for backward compatibility @@ -755,12 +719,6 @@ persistent_keepalive_interval=5`, fixKey(privateKey.String()), fixKey(wgData.Pub return nil }) - client.OnTokenUpdate(func(token string) { - if wgService != nil { - wgService.SetToken(token) - } - }) - // Connect to the WebSocket server if err := client.Connect(); err != nil { logger.Fatal("Failed to connect to server: %v", err) @@ -774,13 +732,7 @@ persistent_keepalive_interval=5`, fixKey(privateKey.String()), fixKey(wgData.Pub dev.Close() - if wgService != nil { - wgService.Close(rm) - } - - if wgTesterServer != nil { - wgTesterServer.Stop() - } + closeClients() if pm != nil { pm.Stop() diff --git a/stub.go b/stub.go new file mode 100644 index 0000000..e2360ff --- /dev/null +++ b/stub.go @@ -0,0 +1,32 @@ +//go:build !linux + +package main + +import ( + "github.com/fosrl/newt/proxy" + "github.com/fosrl/newt/websocket" +) + +func setupClients(client *websocket.Client) { + return // This function is not implemented for non-Linux systems. +} + +func closeClients() { + // This function is not implemented for non-Linux systems. + return +} + +func clientsHandleNewtConnection(publicKey string) { + // This function is not implemented for non-Linux systems. + return +} + +func clientsOnConnect() { + // This function is not implemented for non-Linux systems. + return +} + +func clientsAddProxyTarget(pm *proxy.ProxyManager, tunnelIp string) { + // This function is not implemented for non-Linux systems. + return +} diff --git a/wg/wg.go b/wg/wg.go index cc86d57..1c378ea 100644 --- a/wg/wg.go +++ b/wg/wg.go @@ -1,3 +1,5 @@ +//go:build linux + package wg import (