diff --git a/.github/workflows/branchtest.yml b/.github/workflows/branchtest.yml index dbce2297..95c46ad2 100644 --- a/.github/workflows/branchtest.yml +++ b/.github/workflows/branchtest.yml @@ -9,12 +9,13 @@ jobs: skip-check: runs-on: ubuntu-latest outputs: - skip: ${{ steps.check.outputs.skip }} + skip: ${{ steps.skip.outputs.skip }} steps: - id: skip uses: fkirc/skip-duplicate-actions@v5 with: concurrent_skipping: 'always' + getbranch: runs-on: ubuntu-latest needs: skip-check @@ -38,12 +39,56 @@ jobs: echo "netmakerbranch=develop" >> $GITHUB_OUTPUT fi + getserver: + runs-on: ubuntu-latest + needs: skip-check + if: ${{ needs.skip-check.outputs.skip != 'true' }} + outputs: + netmakerserver: ${{ steps.getserver.outputs.server }} + steps: + - name: setup ssh + run: | + mkdir -p ~/.ssh/ + echo "$SSH_KEY" > ~/.ssh/id_devops + chmod 600 ~/.ssh/id_devops + cat >>~/.ssh/config <>/tmp/server + break + fi + done + echo server is $server + if [ "$server" == "" ] + then + echo server not set + exit 1 + fi + echo "netmakerserver=$server" >> $GITHUB_OUTPUT + terraform: - needs: getbranch + needs: [getbranch, getserver] uses: gravitl/devops/.github/workflows/terraform.yml@master with: netclientbranch: ${{ github.head_ref }} netmakerbranch: ${{ needs.getbranch.outputs.netmakerbranch }} + server: ${{ needs.getserver.outputs.netmakerserver }} secrets: inherit diff --git a/.github/workflows/deletedroplets.yml b/.github/workflows/deletedroplets.yml index 1f5165bb..d3b6c8b7 100644 --- a/.github/workflows/deletedroplets.yml +++ b/.github/workflows/deletedroplets.yml @@ -16,6 +16,9 @@ jobs: with: run_id: ${{ github.event.workflow_run.id}} if_no_artifact_found: warn + - name: get server name + run: | + echo "SERVER=$(cat ./server/server) >> $GITHUB_ENV" - name: get PR env: GH_TOKEN: ${{ github.token }} @@ -42,6 +45,14 @@ jobs: env: DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }} TAG: ${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }} + - name: mark server as available + uses: appleboy/ssh-action@master + with: + host: server.${{ env.SERVER }}.clustercat.com + username: root + key: ${{ secrets.TESTING_SSH_KEY }} + script: | + rm /tmp/branchtest on-failure: runs-on: ubuntu-latest @@ -52,6 +63,9 @@ jobs: with: run_id: ${{ github.event.workflow_run.id}} if_no_artifact_found: warn + - name: get server name + run: | + echo "SERVER=$(cat ./server/server) >> $GITHUB_ENV" - name: get PR env: GH_TOKEN: ${{ github.token }} @@ -65,7 +79,7 @@ jobs: webhook_token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} color: "#990000" username: "GitHub Bot" - message: " ${{ github.repository}}:${{ github.event.workflow_run.name }}:PR ${{ env.pull_request}} failed: droplets from this workflow (tag ${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}) will be deleted in 5 hours" + message: " ${{ github.repository}}:${{ github.event.workflow_run.name }}:PR ${{ env.pull_request}} failed: droplets from this workflow (tag ${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}) will be deleted in 3 hours" file: ./results/results.log - name: discord error message uses: appleboy/discord-action@master @@ -79,7 +93,7 @@ jobs: - name: delete droplets if: success() || failure() run: | - sleep 5h + sleep 3h curl -X DELETE \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ @@ -87,3 +101,13 @@ jobs: env: DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }} TAG: ${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }} + - name: mark server as available + if: success() || failure() + uses: appleboy/ssh-action@master + with: + host: server.${{ env.SERVER }}.clustercat.com + username: root + key: ${{ secrets.TESTING_SSH_KEY }} + script: | + rm /tmp/branchtest + diff --git a/cmd/root.go b/cmd/root.go index 8221e84b..9ea6347e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -10,6 +10,7 @@ import ( "github.com/gravitl/netclient/config" "github.com/gravitl/netclient/functions" + "github.com/gravitl/netclient/wireguard" "github.com/spf13/cobra" "github.com/spf13/viper" "golang.org/x/exp/slog" @@ -54,6 +55,12 @@ func initConfig() { flags.BindPFlags(rootCmd.Flags()) config.InitConfig(flags) setupLoging(flags) + nc := wireguard.NewNCIface(config.Netclient(), config.GetNodes()) + if err := nc.Create(); err != nil { + slog.Error("failed to create interface, is wireguard installed?", "error", err) + os.Exit(1) + } + nc.Close() } func setupLoging(flags *viper.Viper) { diff --git a/config/config.go b/config/config.go index f0979740..74460e17 100644 --- a/config/config.go +++ b/config/config.go @@ -31,7 +31,7 @@ const ( // MacAppDataPath - mac path MacAppDataPath = "/Applications/Netclient/" // WindowsAppDataPath - windows path - WindowsAppDataPath = "C:\\Program Files (x86)\\Netclient\\" + WindowsAppDataPath = "C:\\Program Files\\Netclient\\" // Timeout timelimit for obtaining/releasing lockfile Timeout = time.Second * 5 // ConfigLockfile lockfile to control access to config file diff --git a/functions/daemon.go b/functions/daemon.go index 3d6b3b5d..d194dbe1 100644 --- a/functions/daemon.go +++ b/functions/daemon.go @@ -123,7 +123,7 @@ func closeRoutines(closers []context.CancelFunc, wg *sync.WaitGroup) { func startGoRoutines(wg *sync.WaitGroup) context.CancelFunc { ctx, cancel := context.WithCancel(context.Background()) if _, err := config.ReadNetclientConfig(); err != nil { - slog.Error("error reading neclient config file", "error", err) + slog.Error("error reading netclient config file", "error", err) } config.UpdateNetclient(*config.Netclient()) if err := config.ReadServerConf(); err != nil { @@ -132,6 +132,21 @@ func startGoRoutines(wg *sync.WaitGroup) context.CancelFunc { config.SetServerCtx() config.HostPublicIP, config.WgPublicListenPort = holePunchWgPort() slog.Info("wireguard public listen port: ", "port", config.WgPublicListenPort) + + updateConfig := false + if config.Netclient().WgPublicListenPort == 0 { + config.Netclient().WgPublicListenPort = config.WgPublicListenPort + updateConfig = true + } + if config.Netclient().EndpointIP == nil { + config.Netclient().EndpointIP = config.HostPublicIP + updateConfig = true + } + if updateConfig { + if err := config.WriteNetclientConfig(); err != nil { + slog.Error("error writing endpoint/port netclient config file", "error", err) + } + } setNatInfo() slog.Info("configuring netmaker wireguard interface") if len(config.Servers) == 0 { @@ -211,7 +226,7 @@ func setupMQTT(server *config.Server) error { setHostSubscription(client, server.Name) checkin() }) - opts.SetOrderMatters(true) + opts.SetOrderMatters(false) opts.SetResumeSubs(true) opts.SetConnectionLostHandler(func(c mqtt.Client, e error) { slog.Warn("detected broker connection lost for", "server", server.Broker) @@ -447,14 +462,14 @@ func UpdateKeys() error { } func holePunchWgPort() (pubIP net.IP, pubPort int) { - for _, server := range config.Servers { - portToStun := config.Netclient().ListenPort - pubIP, pubPort = stun.HolePunch(server.StunList, portToStun) - if pubPort == 0 || pubIP == nil || pubIP.IsUnspecified() { - continue - } - break - } + stunServers := []models.StunServer{ + {Domain: "stun1.netmaker.io", Port: 3478}, + {Domain: "stun2.netmaker.io", Port: 3478}, + {Domain: "stun1.l.google.com", Port: 19302}, + {Domain: "stun2.l.google.com", Port: 19302}, + } + portToStun := config.Netclient().ListenPort + pubIP, pubPort = stun.HolePunch(stunServers, portToStun) return } diff --git a/functions/httpserver.go b/functions/httpserver.go index 05290a9f..939090cc 100644 --- a/functions/httpserver.go +++ b/functions/httpserver.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "net/http" + "runtime" "strings" "sync" @@ -22,19 +23,26 @@ type Network struct { Server config.Server } +const DefaultHttpServerPort = "18095" +const DefaultHttpServerAddr = "127.0.0.1" + func HttpServer(ctx context.Context, wg *sync.WaitGroup) { defer wg.Done() if config.Netclient().DisableGUIServer { return } - port, err := ncutils.GetFreeTCPPort() - if err != nil { - logger.Log(0, "failed to get free port", err.Error()) - logger.Log(0, "unable to start http server", "exiting") - logger.Log(0, "netclient-gui will not be available") - return + port := DefaultHttpServerPort + if runtime.GOOS != "windows" { + p, err := ncutils.GetFreeTCPPort() + if err != nil { + logger.Log(0, "failed to get free port", err.Error()) + logger.Log(0, "unable to start http server", "exiting") + logger.Log(0, "netclient-gui will not be available") + return + } + port = p } - config.SetGUI("127.0.0.1", port) + config.SetGUI(DefaultHttpServerAddr, port) config.WriteGUIConfig() router := SetupRouter() diff --git a/functions/mqhandlers.go b/functions/mqhandlers.go index 0eff6fa7..eaa95b48 100644 --- a/functions/mqhandlers.go +++ b/functions/mqhandlers.go @@ -125,6 +125,7 @@ func HostPeerUpdate(client mqtt.Client, msg mqtt.Message) { slog.Error("error unmarshalling peer data", "error", err) return } + turn.ResetCh <- struct{}{} if peerUpdate.ServerVersion != config.Version { slog.Warn("server/client version mismatch", "server", peerUpdate.ServerVersion, "client", config.Version) if versionLessThan(config.Version, peerUpdate.ServerVersion) && config.Netclient().Host.AutoUpdate { @@ -140,8 +141,6 @@ func HostPeerUpdate(client mqtt.Client, msg mqtt.Message) { server.Version = peerUpdate.ServerVersion config.WriteServerConfig() } - // endpoint detection always comes from the server - config.Netclient().Host.EndpointDetection = peerUpdate.Host.EndpointDetection gwDetected := config.GW4PeerDetected || config.GW6PeerDetected currentGW4 := config.GW4Addr currentGW6 := config.GW6Addr @@ -165,7 +164,7 @@ func HostPeerUpdate(client mqtt.Client, msg mqtt.Message) { gwDelta, &originalGW, ) - if config.Netclient().Host.EndpointDetection { + if peerUpdate.EndpointDetection { slog.Debug("endpoint detection enabled") go handleEndpointDetection(&peerUpdate) } else { @@ -307,7 +306,7 @@ func handleEndpointDetection(peerUpdate *models.HostPeerUpdate) { peerPubKey, peerInfo.ProxyListenPort, ); err != nil { // happens v often - slog.Error("failed to check for endpoint on peer", "peer", peerPubKey, "error", err) + slog.Debug("failed to check for endpoint on peer", "peer", peerPubKey, "error", err) } } } diff --git a/functions/mqpublish.go b/functions/mqpublish.go index 921362c7..011c3be9 100644 --- a/functions/mqpublish.go +++ b/functions/mqpublish.go @@ -291,13 +291,6 @@ func UpdateHostSettings() error { publishMsg = true } } - if !config.Netclient().ProxyEnabledSet && proxyCfg.GetCfg().ShouldUseProxy() && - !config.Netclient().ProxyEnabled && !proxyCfg.NatAutoSwitchDone() { - logger.Log(0, "Host is behind NAT, enabling proxy...") - proxyCfg.SetNatAutoSwitch() - config.Netclient().ProxyEnabled = true - publishMsg = true - } ip, err := getInterfaces() if err != nil { logger.Log(0, "failed to retrieve local interfaces during check-in", err.Error()) diff --git a/functions/register.go b/functions/register.go index bfdc191e..239b324b 100644 --- a/functions/register.go +++ b/functions/register.go @@ -72,11 +72,11 @@ func Register(token string) error { } func doubleCheck(host *config.Config, apiServer string) (shouldUpdate bool, err error) { + var shouldUpdateHost bool if len(config.CurrServer) == 0 { // should indicate a first join // do a double check of name and uuid logger.Log(1, "performing first join") - var shouldUpdateHost bool if len(host.Name) == 0 { if name, err := os.Hostname(); err == nil { host.Name = name @@ -97,11 +97,19 @@ func doubleCheck(host *config.Config, apiServer string) (shouldUpdate bool, err host.HostPass = logic.RandomString(32) shouldUpdateHost = true } - if shouldUpdateHost { - config.UpdateNetclient(*host) - config.WriteNetclientConfig() - return true, nil - } + } + + if host.EndpointIP == nil || host.WgPublicListenPort == 0 { + publicIp, publicPort := holePunchWgPort() + host.EndpointIP = publicIp + host.WgPublicListenPort = publicPort + shouldUpdateHost = true + } + + if shouldUpdateHost { + config.UpdateNetclient(*host) + config.WriteNetclientConfig() + return true, nil } return } diff --git a/go.mod b/go.mod index 5daa028c..8f5b4a67 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/google/nftables v0.1.0 github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.5.0 - github.com/gravitl/netmaker v0.20.2-0.20230607190105-1e65fa2f9ad5 + github.com/gravitl/netmaker v0.20.3-0.20230627170624-243cc7449057 github.com/gravitl/txeh v0.0.0-20230509181318-3778c58bd69f github.com/guumaster/hostctl v1.1.4 github.com/hashicorp/go-version v1.6.0 @@ -124,7 +124,7 @@ require ( golang.org/x/image v0.6.0 // indirect golang.org/x/mobile v0.0.0-20230301163155-e0f57694e12c // indirect golang.org/x/mod v0.8.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect + golang.org/x/oauth2 v0.9.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/text v0.10.0 // indirect golang.org/x/tools v0.6.0 // indirect diff --git a/go.sum b/go.sum index 95578879..0bb1b636 100644 --- a/go.sum +++ b/go.sum @@ -192,8 +192,8 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gravitl/netmaker v0.20.2-0.20230607190105-1e65fa2f9ad5 h1:fdGc8TxzqRSx7tCnuWPOffWDPbrLtdxpTRwnHD4OzbI= -github.com/gravitl/netmaker v0.20.2-0.20230607190105-1e65fa2f9ad5/go.mod h1:7ikBzRznRUag2KrQhw7etTJhOwNj3Op8wMvXCBVOI/M= +github.com/gravitl/netmaker v0.20.3-0.20230627170624-243cc7449057 h1:LgISep7GNdpA8fFM44sHZYVQOen/AZRzAOzDC7c9WR4= +github.com/gravitl/netmaker v0.20.3-0.20230627170624-243cc7449057/go.mod h1:h/8zpORPHUNX5POfb7h2M3p30qK/PLoX1XhSPqc6xJc= github.com/gravitl/txeh v0.0.0-20230509181318-3778c58bd69f h1:XzsYovKdrDvj2z2HEHoeHU67+JIEFMHQKHU6oU+1fVE= github.com/gravitl/txeh v0.0.0-20230509181318-3778c58bd69f/go.mod h1:Nqo/7iOJSVP1JRSUv+FkZ0FgBjK89gjU0D/V8nH4xy8= github.com/guumaster/hostctl v1.1.4 h1:4zb9wEurBlz/hQiXFz9feHHfunf7oj+9serAH8ohGuM= @@ -508,8 +508,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= +golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/gui/frontend/package-lock.json b/gui/frontend/package-lock.json index 42dc0f0f..eaee413c 100644 --- a/gui/frontend/package-lock.json +++ b/gui/frontend/package-lock.json @@ -2245,6 +2245,20 @@ "node": ">= 6" } }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -3351,10 +3365,16 @@ "devOptional": true }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -3536,9 +3556,9 @@ } }, "node_modules/postcss": { - "version": "8.4.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz", - "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==", + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", "dev": true, "funding": [ { @@ -3548,10 +3568,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -3788,9 +3812,9 @@ } }, "node_modules/rollup": { - "version": "2.78.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", - "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -4122,15 +4146,15 @@ } }, "node_modules/vite": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.4.tgz", - "integrity": "sha512-JoQI08aBjY9lycL7jcEq4p9o1xUjq5aRvdH4KWaXtkSx7e7RpAh9D3IjzDWRD4Fg44LS3oDAIOG/Kq1L+82psA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.7.tgz", + "integrity": "sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==", "dev": true, "dependencies": { - "esbuild": "^0.15.6", - "postcss": "^8.4.16", + "esbuild": "^0.15.9", + "postcss": "^8.4.18", "resolve": "^1.22.1", - "rollup": "~2.78.0" + "rollup": "^2.79.1" }, "bin": { "vite": "bin/vite.js" @@ -4142,12 +4166,17 @@ "fsevents": "~2.3.2" }, "peerDependencies": { + "@types/node": ">= 14", "less": "*", "sass": "*", "stylus": "*", + "sugarss": "*", "terser": "^5.4.0" }, "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, "less": { "optional": true }, @@ -4157,6 +4186,9 @@ "stylus": { "optional": true }, + "sugarss": { + "optional": true + }, "terser": { "optional": true } @@ -5980,6 +6012,13 @@ "mime-types": "^2.1.12" } }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -6785,9 +6824,9 @@ "devOptional": true }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true }, "node-releases": { @@ -6916,12 +6955,12 @@ "dev": true }, "postcss": { - "version": "8.4.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz", - "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==", + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", "dev": true, "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -7100,9 +7139,9 @@ "devOptional": true }, "rollup": { - "version": "2.78.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.78.1.tgz", - "integrity": "sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -7341,16 +7380,16 @@ } }, "vite": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-3.1.4.tgz", - "integrity": "sha512-JoQI08aBjY9lycL7jcEq4p9o1xUjq5aRvdH4KWaXtkSx7e7RpAh9D3IjzDWRD4Fg44LS3oDAIOG/Kq1L+82psA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.7.tgz", + "integrity": "sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==", "dev": true, "requires": { - "esbuild": "^0.15.6", + "esbuild": "^0.15.9", "fsevents": "~2.3.2", - "postcss": "^8.4.16", + "postcss": "^8.4.18", "resolve": "^1.22.1", - "rollup": "~2.78.0" + "rollup": "^2.79.1" } }, "vitest": { diff --git a/gui/main.go b/gui/main.go index 8d621d21..7cf9d0f0 100644 --- a/gui/main.go +++ b/gui/main.go @@ -3,8 +3,10 @@ package main import ( "embed" "log" + "runtime" "github.com/gravitl/netclient/config" + "github.com/gravitl/netclient/functions" "github.com/gravitl/netmaker/logger" "github.com/wailsapp/wails/v2" "github.com/wailsapp/wails/v2/pkg/options" @@ -22,15 +24,17 @@ var appIcon = GetFileAsBytes("./appicon.png") var version = "v0.20.3" -var url = "http://127.0.0.1:8090" +var url = "http://" + functions.DefaultHttpServerAddr + ":" + functions.DefaultHttpServerPort func main() { log.Println("staring netclient gui version: ", version) // temp.. version should be displayed in about dialog - http, err := config.ReadGUIConfig() - if err != nil { - logger.FatalLog("error reading gui config", err.Error()) + if runtime.GOOS != "windows" { + http, err := config.ReadGUIConfig() + if err != nil { + logger.FatalLog("error reading gui config", err.Error()) + } + url = "http://" + http.Address + ":" + http.Port } - url = "http://" + http.Address + ":" + http.Port // Create an instance of the guiApp structure guiApp := NewApp() guiApp.GoGetNetclientConfig() @@ -68,7 +72,7 @@ func main() { } // Create application with options - err = wails.Run(appOptions) + err := wails.Run(appOptions) if err != nil { println("Error:", err.Error()) diff --git a/ncutils/netclientutils_windows.go b/ncutils/netclientutils_windows.go index 93756b48..27f79a6a 100644 --- a/ncutils/netclientutils_windows.go +++ b/ncutils/netclientutils_windows.go @@ -14,7 +14,7 @@ import ( //go:embed windowsdaemon/winsw.exe var winswContent embed.FS -const WIN_PATH = "C:\\Program Files (x86)\\Netclient\\" +const WIN_PATH = "C:\\Program Files\\Netclient\\" // RunCmd - runs a local command func RunCmd(command string, printerr bool) (string, error) { diff --git a/ncutils/windowsdaemon/winsw.exe b/ncutils/windowsdaemon/winsw.exe index 9eb37599..6806bb40 100644 Binary files a/ncutils/windowsdaemon/winsw.exe and b/ncutils/windowsdaemon/winsw.exe differ diff --git a/nmproxy/common/common.go b/nmproxy/common/common.go index 64db00fc..77800ea7 100644 --- a/nmproxy/common/common.go +++ b/nmproxy/common/common.go @@ -15,7 +15,7 @@ const ( // MacAppDataPath - mac path MacAppDataPath = "/Applications/Netclient/" // WindowsAppDataPath - windows path - WindowsAppDataPath = "C:\\Program Files (x86)\\Netclient\\" + WindowsAppDataPath = "C:\\Program Files\\Netclient\\" ) // RunCmd - runs a local command diff --git a/nmproxy/stun/stun.go b/nmproxy/stun/stun.go index 46eedbef..51477f34 100644 --- a/nmproxy/stun/stun.go +++ b/nmproxy/stun/stun.go @@ -9,6 +9,7 @@ import ( "github.com/gravitl/netclient/nmproxy/models" "github.com/gravitl/netmaker/logger" nmmodels "github.com/gravitl/netmaker/models" + "golang.org/x/exp/slog" "gortc.io/stun" ) @@ -55,6 +56,7 @@ func HolePunch(stunList []nmmodels.StunServer, portToStun int) (publicIP net.IP, IP: net.ParseIP(""), Port: portToStun, } + slog.Debug(fmt.Sprintf("hole punching port %d via stun server %s:%d", portToStun, stunServer.Domain, stunServer.Port)) publicIP, publicPort, err = doStunTransaction(l, s) if err != nil { logger.Log(0, "stun transaction failed: ", stunServer.Domain, err.Error()) @@ -65,6 +67,7 @@ func HolePunch(stunList []nmmodels.StunServer, portToStun int) (publicIP net.IP, } break } + slog.Debug("hole punching complete", "public ip", publicIP.String(), "public port", strconv.Itoa(publicPort)) return } diff --git a/nmproxy/turn/turn_helper.go b/nmproxy/turn/turn_helper.go index 774c7bcf..c1bbea45 100644 --- a/nmproxy/turn/turn_helper.go +++ b/nmproxy/turn/turn_helper.go @@ -23,10 +23,12 @@ import ( var ( // PeerSignalCh - channel to recieve peer signals PeerSignalCh = make(chan nm_models.Signal, 50) - // PeerConnectionCheckInterval - time interval to check peer connection status - PeerConnectionCheckInterval = time.Minute + // peerConnectionCheckInterval - time interval to check peer connection status + peerConnectionCheckInterval = time.Second * 90 // LastHandShakeThreshold - threshold for considering inactive connection LastHandShakeThreshold = time.Minute * 3 + + ResetCh = make(chan struct{}, 2) ) // WatchPeerSignals - processes the peer signals for any turn updates from peers @@ -152,12 +154,16 @@ func handleDisconnect(signal nm_models.Signal) error { // if connection is bad, host will signal peers to use turn func WatchPeerConnections(ctx context.Context, waitg *sync.WaitGroup) { defer waitg.Done() - t := time.NewTicker(time.Minute) + t := time.NewTicker(peerConnectionCheckInterval) defer t.Stop() for { select { case <-ctx.Done(): return + case <-ResetCh: + if t != nil { + t.Reset(peerConnectionCheckInterval) + } case <-t.C: iface, err := wg.GetWgIface(ncutils.GetInterfaceName()) if err != nil {