From a60771344ac2270a324c7ce9f1e2913a8f242038 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 23 Oct 2023 23:42:31 +0100 Subject: [PATCH 001/125] Remove DHT from `yggdrasilctl` help text (fixes #1069) --- cmd/yggdrasilctl/cmd_line_env.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/yggdrasilctl/cmd_line_env.go b/cmd/yggdrasilctl/cmd_line_env.go index d96d6950..b350b7e7 100644 --- a/cmd/yggdrasilctl/cmd_line_env.go +++ b/cmd/yggdrasilctl/cmd_line_env.go @@ -39,8 +39,8 @@ func (cmdLineEnv *CmdLineEnv) parseFlagsAndArgs() { fmt.Println(" - ", os.Args[0], "list") fmt.Println(" - ", os.Args[0], "getPeers") fmt.Println(" - ", os.Args[0], "setTunTap name=auto mtu=1500 tap_mode=false") - fmt.Println(" - ", os.Args[0], "-endpoint=tcp://localhost:9001 getDHT") - fmt.Println(" - ", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getDHT") + fmt.Println(" - ", os.Args[0], "-endpoint=tcp://localhost:9001 getPeers") + fmt.Println(" - ", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getPeers") } server := flag.String("endpoint", cmdLineEnv.endpoint, "Admin socket endpoint") From 7934158f5f49e9eea0fac43b21770b2071bc5cf2 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 24 Oct 2023 12:10:48 +0100 Subject: [PATCH 002/125] Use `ubuntu-20.04` image for Debian packages in CI --- .github/workflows/pkg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pkg.yml b/.github/workflows/pkg.yml index dd43fce8..615976f0 100644 --- a/.github/workflows/pkg.yml +++ b/.github/workflows/pkg.yml @@ -16,7 +16,7 @@ jobs: name: Package (Debian, ${{ matrix.pkgarch }}) - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 with: From 8afa737a8ddf02861e5605982b06f64305a793ba Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 24 Oct 2023 22:44:33 +0100 Subject: [PATCH 003/125] Use `ubuntu-20.04` image for router packages in CI --- .github/workflows/pkg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pkg.yml b/.github/workflows/pkg.yml index 615976f0..f47baa0f 100644 --- a/.github/workflows/pkg.yml +++ b/.github/workflows/pkg.yml @@ -107,7 +107,7 @@ jobs: name: Package (Router, ${{ matrix.pkgarch }}) - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 with: From 6873fd44ffdf764f4733b7efd8834856b1b8c5bc Mon Sep 17 00:00:00 2001 From: Revertron Date: Wed, 25 Oct 2023 20:59:19 +0200 Subject: [PATCH 004/125] Fixes logger, adds some log messages. --- contrib/mobile/mobile.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index 3e7a5f21..0b52ffa2 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -48,6 +48,7 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error { logger.EnableLevel("error") logger.EnableLevel("warn") logger.EnableLevel("info") + m.logger = logger m.config = config.GenerateConfig() if err := m.config.UnmarshalHJSON(configjson); err != nil { return err @@ -87,6 +88,7 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error { // Setup the multicast module. if len(m.config.MulticastInterfaces) > 0 { var err error + logger.Infof("Initializing multicast %s", "") options := []multicast.SetupOption{} for _, intf := range m.config.MulticastInterfaces { options = append(options, multicast.MulticastInterface{ @@ -98,9 +100,10 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error { Password: intf.Password, }) } + logger.Infof("Starting multicast %s", "") m.multicast, err = multicast.New(m.core, m.logger, options...) if err != nil { - m.logger.Errorln("An error occurred starting multicast:", err) + logger.Errorln("An error occurred starting multicast:", err) } } @@ -159,15 +162,20 @@ func (m *Yggdrasil) RecvBuffer(buf []byte) (int, error) { func (m *Yggdrasil) Stop() error { logger := log.New(m.log, "", 0) logger.EnableLevel("info") - logger.Infof("Stop the mobile Yggdrasil instance %s", "") - if err := m.multicast.Stop(); err != nil { - return err + logger.Infof("Stopping the mobile Yggdrasil instance %s", "") + if m.multicast != nil { + logger.Infof("Stopping multicast %s", "") + if err := m.multicast.Stop(); err != nil { + return err + } } + logger.Infof("Stopping TUN device %s", "") if m.tun != nil { if err := m.tun.Stop(); err != nil { return err } } + logger.Infof("Stopping Yggdrasil core %s", "") m.core.Stop() return nil } From ea6ccf552f8b5e29b912e5b9d2f91012bca84c50 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 27 Oct 2023 23:15:34 +0100 Subject: [PATCH 005/125] Update dependencies, test cross-builds for FreeBSD and OpenBSD in CI --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7cb75f6..92ad2561 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,6 +119,32 @@ jobs: - name: Unit tests run: go test -v ./... + build-freebsd: + strategy: + fail-fast: false + matrix: + goversion: ["1.20", "1.21"] + goos: + - freebsd + - openbsd + + name: Build (Cross ${{ matrix.goos }}, Go ${{ matrix.goversion }}) + needs: [lint] + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.goversion }} + + - name: Build Yggdrasil + run: go build -v ./... + env: + GOOS: ${{ matrix.goos }} + tests-ok: name: All tests passed needs: [lint, codeql, build-linux, build-windows, build-macos] diff --git a/go.mod b/go.mod index ed6c47c8..3f2f6b76 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/hashicorp/go-syslog v1.0.0 github.com/hjson/hjson-go/v4 v4.3.0 github.com/kardianos/minwinsvc v1.0.2 - github.com/quic-go/quic-go v0.39.0 + github.com/quic-go/quic-go v0.39.3 github.com/vishvananda/netlink v1.1.0 golang.org/x/crypto v0.14.0 golang.org/x/mobile v0.0.0-20231006135142-2b44d11868fe diff --git a/go.sum b/go.sum index 6c0bdb11..e8bbf5f1 100644 --- a/go.sum +++ b/go.sum @@ -52,8 +52,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.0 h1:AgP40iThFMY0bj8jGxROhw3S0FMGa8ryqsmi9tBH3So= -github.com/quic-go/quic-go v0.39.0/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= From d17ac397898391129c834f9966464a6072513249 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 28 Oct 2023 05:26:43 -0500 Subject: [PATCH 006/125] update ironwood dependency, add a debug API call for lookups --- cmd/yggdrasil/main.go | 3 +++ contrib/mobile/mobile.go | 8 +++--- go.mod | 2 +- go.sum | 4 +-- src/admin/options.go | 54 ++++++++++++++++++++++++++++++++++++++++ src/config/config.go | 1 + 6 files changed, 65 insertions(+), 7 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 64cc6ae9..7f820db5 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -216,6 +216,9 @@ func main() { options := []admin.SetupOption{ admin.ListenAddress(cfg.AdminListen), } + if cfg.LogLookups { + options = append(options, admin.LogLookups{}) + } if n.admin, err = admin.New(n.core, logger, options...); err != nil { panic(err) } diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index 0b52ffa2..cf026a70 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -164,10 +164,10 @@ func (m *Yggdrasil) Stop() error { logger.EnableLevel("info") logger.Infof("Stopping the mobile Yggdrasil instance %s", "") if m.multicast != nil { - logger.Infof("Stopping multicast %s", "") - if err := m.multicast.Stop(); err != nil { - return err - } + logger.Infof("Stopping multicast %s", "") + if err := m.multicast.Stop(); err != nil { + return err + } } logger.Infof("Stopping TUN device %s", "") if m.tun != nil { diff --git a/go.mod b/go.mod index 3f2f6b76..faa0e0d8 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20230805085300-86206813435f + github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 diff --git a/go.sum b/go.sum index e8bbf5f1..901eabaa 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20230805085300-86206813435f h1:Fz0zG7ZyQQqk+ROnmHuGrIZO250Lx/YHmp9o48XE+Vw= -github.com/Arceliar/ironwood v0.0.0-20230805085300-86206813435f/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= +github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43 h1:M4NczBPk7Fy0Uy2YvNoXwSkk3dGoGTOYtUjyqpOC5ko= +github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= diff --git a/src/admin/options.go b/src/admin/options.go index 4607384f..b2e273b3 100644 --- a/src/admin/options.go +++ b/src/admin/options.go @@ -1,9 +1,20 @@ package admin +import ( + "encoding/hex" + "encoding/json" + "sync" + "time" + + "github.com/Arceliar/ironwood/network" +) + func (c *AdminSocket) _applyOption(opt SetupOption) { switch v := opt.(type) { case ListenAddress: c.config.listenaddr = v + case LogLookups: + c.logLookups() } } @@ -14,3 +25,46 @@ type SetupOption interface { type ListenAddress string func (a ListenAddress) isSetupOption() {} + +type LogLookups struct{} + +func (l LogLookups) isSetupOption() {} + +func (a *AdminSocket) logLookups() { + type resi struct { + Key string `json:"key"` + Path []uint64 `json:"path"` + Time int64 `json:"time"` + } + type res struct { + Infos []resi `json:"infos"` + } + type info struct { + path []uint64 + time time.Time + } + infos := make(map[string]info) + var m sync.Mutex + a.core.PacketConn.PacketConn.Debug.SetDebugLookupLogger(func(l network.DebugLookupInfo) { + key := hex.EncodeToString(l.Key[:]) + m.Lock() + infos[key] = info{path: l.Path, time: time.Now()} + m.Unlock() + }) + _ = a.AddHandler( + "lookups", "Dump a record of lookups received in the past hour", []string{}, + func(in json.RawMessage) (interface{}, error) { + m.Lock() + rs := make([]resi, 0, len(infos)) + for k, v := range infos { + if time.Since(v.time) > 24*time.Hour { + // TODO? automatic cleanup, so we don't need to call lookups periodically to prevent leaks + delete(infos, k) + } + rs = append(rs, resi{Key: k, Path: v.path, Time: v.time.Unix()}) + } + m.Unlock() + return &res{Infos: rs}, nil + }, + ) +} diff --git a/src/config/config.go b/src/config/config.go index bb94b674..289b6f92 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -53,6 +53,7 @@ type NodeConfig struct { IfMTU uint64 `comment:"Maximum Transmission Unit (MTU) size for your local TUN interface.\nDefault is the largest supported size for your platform. The lowest\npossible value is 1280."` NodeInfoPrivacy bool `comment:"By default, nodeinfo contains some defaults including the platform,\narchitecture and Yggdrasil version. These can help when surveying\nthe network and diagnosing network routing problems. Enabling\nnodeinfo privacy prevents this, so that only items specified in\n\"NodeInfo\" are sent back if specified."` NodeInfo map[string]interface{} `comment:"Optional node info. This must be a { \"key\": \"value\", ... } map\nor set as null. This is entirely optional but, if set, is visible\nto the whole network on request."` + LogLookups bool `json:",omitempty"` } type MulticastInterfaceConfig struct { From 82c54f87eae55c7f0acbb1dfb91a91482b393ce3 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 28 Oct 2023 06:36:01 -0500 Subject: [PATCH 007/125] clean up some debug API output --- src/admin/options.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/admin/options.go b/src/admin/options.go index b2e273b3..03cf74ab 100644 --- a/src/admin/options.go +++ b/src/admin/options.go @@ -1,12 +1,16 @@ package admin import ( + "crypto/ed25519" "encoding/hex" "encoding/json" + "net" "sync" "time" "github.com/Arceliar/ironwood/network" + + "github.com/yggdrasil-network/yggdrasil-go/src/address" ) func (c *AdminSocket) _applyOption(opt SetupOption) { @@ -32,9 +36,10 @@ func (l LogLookups) isSetupOption() {} func (a *AdminSocket) logLookups() { type resi struct { - Key string `json:"key"` - Path []uint64 `json:"path"` - Time int64 `json:"time"` + Address string `json:"addr"` + Key string `json:"key"` + Path []uint64 `json:"path"` + Time int64 `json:"time"` } type res struct { Infos []resi `json:"infos"` @@ -43,12 +48,14 @@ func (a *AdminSocket) logLookups() { path []uint64 time time.Time } - infos := make(map[string]info) + type edk [ed25519.PublicKeySize]byte + infos := make(map[edk]info) var m sync.Mutex a.core.PacketConn.PacketConn.Debug.SetDebugLookupLogger(func(l network.DebugLookupInfo) { - key := hex.EncodeToString(l.Key[:]) + var k edk + copy(k[:], l.Key[:]) m.Lock() - infos[key] = info{path: l.Path, time: time.Now()} + infos[k] = info{path: l.Path, time: time.Now()} m.Unlock() }) _ = a.AddHandler( @@ -61,7 +68,9 @@ func (a *AdminSocket) logLookups() { // TODO? automatic cleanup, so we don't need to call lookups periodically to prevent leaks delete(infos, k) } - rs = append(rs, resi{Key: k, Path: v.path, Time: v.time.Unix()}) + a := address.AddrForKey(ed25519.PublicKey(k[:])) + addr := net.IP(a[:]).String() + rs = append(rs, resi{Address: addr, Key: hex.EncodeToString(k[:]), Path: v.path, Time: v.time.Unix()}) } m.Unlock() return &res{Infos: rs}, nil From 0b578a637a86468f22a6e142901340d93889e52b Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 28 Oct 2023 14:58:52 +0100 Subject: [PATCH 008/125] Debian package updates (#1073) * Update Debian package * Don't put `AdminListen` in config by default, fix path in Debian package * Fix path in unit file * Preserve original service files for other packages --------- Co-authored-by: Neil Alexander --- build | 2 +- cmd/yggdrasil/main.go | 1 + contrib/.DS_Store | Bin 0 -> 6148 bytes contrib/deb/generate.sh | 65 ++++++++++++------ .../yggdrasil-default-config.service.debian | 13 ++++ contrib/systemd/yggdrasil.service.debian | 25 +++++++ src/config/config.go | 2 +- 7 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 contrib/.DS_Store create mode 100644 contrib/systemd/yggdrasil-default-config.service.debian create mode 100644 contrib/systemd/yggdrasil.service.debian diff --git a/build b/build index c7214438..de5d9edc 100755 --- a/build +++ b/build @@ -6,7 +6,7 @@ PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/version} PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)} PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)} -LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" +LDFLAGS="${LDFLAGS} -X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" ARGS="-v" while getopts "utc:l:dro:p" option diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 7f820db5..e0b33990 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -113,6 +113,7 @@ func main() { _ = f.Close() case *genconf: + cfg.AdminListen = "" var bs []byte if *confjson { bs, err = json.MarshalIndent(cfg, "", " ") diff --git a/contrib/.DS_Store b/contrib/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6116147462bb7351bfd2bb86ff6280de2c119bb6 GIT binary patch literal 6148 zcmeHKO^?$s5FNMOHf2HT0nlEMB5`e@%g4fsOX)5Lt`xxmP)V9ns!ii6Nw=V?QqS-o z_zQ>|e+2#uCwODKRg$t-c7;5Z{T%zv#Ce(6H4%yKEZ8S%5RrqzSh>vB!lRE-Zv9q<7B2-JP4V+6 zrU^-k_4mHve=YDYBkBy%KLRCvpcd{Ep`>{~aiic@rhtaz7g(PQtSVTN26O^$VJ6~N zfm@?@nDdaMVm?7Wa%ogxSFn~z8j&pUew@Yg=gHI$l@8ziX*f>OcKfF&l`A{dnp1Oj zoj1Mra^6e5be43z_!VD0mooI%ZO?x(9?tuXt4A_Qy>T>*mBTm~g7W(1I11#vD`!!V zDBqqQaOzII-`HC$4h|2R?&1Aq(_QS}ZQp6S5AHo&F6+*z{;^NPfcHVFIhQ zvMUDH!0K+E`?MEFp^R7;=I`Kbdr(?Zl2@dBgwbqw}BJ*fF@$ zsFn^?>IeX=pj#Q*{HK9^T!S5hD~%X|3GE8huEHEKgmy>2Yj_=lD~;NnggJZ&b7x^r zC_>#G@m)nH(a~sYtAJG?uRvK}HhBMka`yQ@?_{s60#){dN|%| uU6i*dY|L9}R4%B@cB~q_74M-a! /tmp/$PKGNAME/debian/changelog << EOF Please see https://github.com/yggdrasil-network/yggdrasil-go/ @@ -68,35 +71,52 @@ EOF cat > /tmp/$PKGNAME/debian/install << EOF usr/bin/yggdrasil usr/bin usr/bin/yggdrasilctl usr/bin -etc/systemd/system/*.service etc/systemd/system +usr/lib/systemd/system/*.service usr/lib/systemd/system EOF cat > /tmp/$PKGNAME/debian/postinst << EOF #!/bin/sh +systemctl daemon-reload + if ! getent group yggdrasil 2>&1 > /dev/null; then - groupadd --system --force yggdrasil || echo "Failed to create group 'yggdrasil' - please create it manually and reinstall" + groupadd --system --force yggdrasil fi -if [ -f /etc/yggdrasil.conf ]; +if [ ! -d /etc/yggdrasil ]; +then + mkdir -p /etc/yggdrasil + chown root:yggdrasil /etc/yggdrasil + chmod 750 /etc/yggdrasil +fi + +if [ ! -f /etc/yggdrasil/yggdrasil.conf ]; +then + test -f /etc/yggdrasil.conf && mv /etc/yggdrasil.conf /etc/yggdrasil/yggdrasil.conf +fi + +if [ -f /etc/yggdrasil/yggdrasil.conf ]; then mkdir -p /var/backups echo "Backing up configuration file to /var/backups/yggdrasil.conf.`date +%Y%m%d`" - cp /etc/yggdrasil.conf /var/backups/yggdrasil.conf.`date +%Y%m%d` - echo "Normalising and updating /etc/yggdrasil.conf" - /usr/bin/yggdrasil -useconf -normaliseconf < /var/backups/yggdrasil.conf.`date +%Y%m%d` > /etc/yggdrasil.conf - chgrp yggdrasil /etc/yggdrasil.conf + cp /etc/yggdrasil/yggdrasil.conf /var/backups/yggdrasil.conf.`date +%Y%m%d` - if command -v systemctl >/dev/null; then - systemctl daemon-reload >/dev/null || true - systemctl enable yggdrasil || true - systemctl start yggdrasil || true - fi + echo "Normalising and updating /etc/yggdrasil/yggdrasil.conf" + /usr/bin/yggdrasil -useconf -normaliseconf < /var/backups/yggdrasil.conf.`date +%Y%m%d` > /etc/yggdrasil/yggdrasil.conf + + chown root:yggdrasil /etc/yggdrasil/yggdrasil.conf + chmod 640 /etc/yggdrasil/yggdrasil.conf else - echo "Generating initial configuration file /etc/yggdrasil.conf" - echo "Please familiarise yourself with this file before starting Yggdrasil" - sh -c 'umask 0027 && /usr/bin/yggdrasil -genconf > /etc/yggdrasil.conf' - chgrp yggdrasil /etc/yggdrasil.conf + echo "Generating initial configuration file /etc/yggdrasil/yggdrasil.conf" + /usr/bin/yggdrasil -genconf > /etc/yggdrasil/yggdrasil.conf + + chown root:yggdrasil /etc/yggdrasil/yggdrasil.conf + chmod 640 /etc/yggdrasil/yggdrasil.conf fi + +systemctl enable yggdrasil +systemctl restart yggdrasil + +exit 0 EOF cat > /tmp/$PKGNAME/debian/prerm << EOF #!/bin/sh @@ -110,13 +130,14 @@ EOF cp yggdrasil /tmp/$PKGNAME/usr/bin/ cp yggdrasilctl /tmp/$PKGNAME/usr/bin/ -cp contrib/systemd/*.service /tmp/$PKGNAME/etc/systemd/system/ +cp contrib/systemd/yggdrasil-default-config.service.debian /tmp/$PKGNAME/usr/lib/systemd/system/yggdrasil-default-config.service +cp contrib/systemd/yggdrasil.service.debian /tmp/$PKGNAME/usr/lib/systemd/system/yggdrasil.service -tar -czvf /tmp/$PKGNAME/data.tar.gz -C /tmp/$PKGNAME/ \ +tar --no-xattrs -czvf /tmp/$PKGNAME/data.tar.gz -C /tmp/$PKGNAME/ \ usr/bin/yggdrasil usr/bin/yggdrasilctl \ - etc/systemd/system/yggdrasil.service \ - etc/systemd/system/yggdrasil-default-config.service -tar -czvf /tmp/$PKGNAME/control.tar.gz -C /tmp/$PKGNAME/debian . + usr/lib/systemd/system/yggdrasil.service \ + usr/lib/systemd/system/yggdrasil-default-config.service +tar --no-xattrs -czvf /tmp/$PKGNAME/control.tar.gz -C /tmp/$PKGNAME/debian . echo 2.0 > /tmp/$PKGNAME/debian-binary ar -r $PKGFILE \ diff --git a/contrib/systemd/yggdrasil-default-config.service.debian b/contrib/systemd/yggdrasil-default-config.service.debian new file mode 100644 index 00000000..dc3fdc5a --- /dev/null +++ b/contrib/systemd/yggdrasil-default-config.service.debian @@ -0,0 +1,13 @@ +[Unit] +Description=Yggdrasil default config generator +ConditionPathExists=|!/etc/yggdrasil/yggdrasil.conf +ConditionFileNotEmpty=|!/etc/yggdrasil/yggdrasil.conf +Wants=local-fs.target +After=local-fs.target + +[Service] +Type=oneshot +Group=yggdrasil +ExecStartPre=/usr/bin/mkdir -p /etc/yggdrasil +ExecStart=/usr/bin/yggdrasil -genconf > /etc/yggdrasil/yggdrasil.conf +ExecStartPost=/usr/bin/chmod -R 0640 /etc/yggdrasil diff --git a/contrib/systemd/yggdrasil.service.debian b/contrib/systemd/yggdrasil.service.debian new file mode 100644 index 00000000..0f3c7a8d --- /dev/null +++ b/contrib/systemd/yggdrasil.service.debian @@ -0,0 +1,25 @@ +[Unit] +Description=Yggdrasil Network +Wants=network-online.target +Wants=yggdrasil-default-config.service +After=network-online.target +After=yggdrasil-default-config.service + +[Service] +Group=yggdrasil +ProtectHome=true +ProtectSystem=strict +NoNewPrivileges=true +RuntimeDirectory=yggdrasil +ReadWritePaths=/var/run/yggdrasil/ /run/yggdrasil/ +SyslogIdentifier=yggdrasil +CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE +AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE +ExecStartPre=+-/sbin/modprobe tun +ExecStart=/usr/bin/yggdrasil -useconffile /etc/yggdrasil/yggdrasil.conf +ExecReload=/bin/kill -HUP $MAINPID +Restart=always +TimeoutStopSec=5 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/src/config/config.go b/src/config/config.go index 289b6f92..e899a35d 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -46,7 +46,7 @@ type NodeConfig struct { Peers []string `comment:"List of connection strings for outbound peer connections in URI format,\ne.g. tls://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j. These connections\nwill obey the operating system routing table, therefore you should\nuse this section when you may connect via different interfaces."` InterfacePeers map[string][]string `comment:"List of connection strings for outbound peer connections in URI format,\narranged by source interface, e.g. { \"eth0\": [ \"tls://a.b.c.d:e\" ] }.\nNote that SOCKS peerings will NOT be affected by this option and should\ngo in the \"Peers\" section instead."` Listen []string `comment:"Listen addresses for incoming connections. You will need to add\nlisteners in order to accept incoming peerings from non-local nodes.\nMulticast peer discovery will work regardless of any listeners set\nhere. Each listener should be specified in URI format as above, e.g.\ntls://0.0.0.0:0 or tls://[::]:0 to listen on all interfaces."` - AdminListen string `comment:"Listen address for admin connections. Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X. To disable\nthe admin socket, use the value \"none\" instead."` + AdminListen string `json:",omitempty" comment:"Listen address for admin connections. Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X. To disable\nthe admin socket, use the value \"none\" instead."` MulticastInterfaces []MulticastInterfaceConfig `comment:"Configuration for which interfaces multicast peer discovery should be\nenabled on. Each entry in the list should be a json object which may\ncontain Regex, Beacon, Listen, and Port. Regex is a regular expression\nwhich is matched against an interface name, and interfaces use the\nfirst configuration that they match gainst. Beacon configures whether\nor not the node should send link-local multicast beacons to advertise\ntheir presence, while listening for incoming connections on Port.\nListen controls whether or not the node listens for multicast beacons\nand opens outgoing connections."` AllowedPublicKeys []string `comment:"List of peer public keys to allow incoming peering connections\nfrom. If left empty/undefined then all connections will be allowed\nby default. This does not affect outgoing peerings, nor does it\naffect link-local peers discovered via multicast."` IfName string `comment:"Local network interface name for TUN adapter, or \"auto\" to select\nan interface automatically, or \"none\" to run without TUN."` From 01c1498bd52291ba246c8f00d0bd5511b16c1959 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 28 Oct 2023 15:07:45 +0100 Subject: [PATCH 009/125] Yggdrasil 0.5 release notes --- CHANGELOG.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 001b3182..50296af0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,22 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> -## [0.5.0] - Release Candidate 3 - -### Fixed - -* Restored `removePeer` admin socket endpoint -* Fixed the `RetryPeersNow` API call for mobile - -## [0.5.0] - Release Candidate 2 - -### Fixed - -* A bug which could result in high CPU usage after a network interface change has been fixed -* TLS listeners no longer require a TLS client certificate, as it is not necessary -* A panic in the mobile wrapper has been fixed when getting peers JSON - -## [0.5.0] - Release Candidate 1 +## [0.5.0] - 2023-10-28 ### Added From d781fef760d2e8152f2fa955e51ee03028a3da9a Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 28 Oct 2023 15:20:56 +0100 Subject: [PATCH 010/125] Release: Yggdrasil 0.5.0 --- contrib/deb/generate.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/deb/generate.sh b/contrib/deb/generate.sh index 5b4275a9..41ca6fe5 100644 --- a/contrib/deb/generate.sh +++ b/contrib/deb/generate.sh @@ -41,7 +41,7 @@ echo "Building $PKGFILE" mkdir -p /tmp/$PKGNAME/ mkdir -p /tmp/$PKGNAME/debian/ mkdir -p /tmp/$PKGNAME/usr/bin/ -mkdir -p /tmp/$PKGNAME/usr/lib/systemd/system/ +mkdir -p /tmp/$PKGNAME/lib/systemd/system/ cat > /tmp/$PKGNAME/debian/changelog << EOF Please see https://github.com/yggdrasil-network/yggdrasil-go/ @@ -71,7 +71,7 @@ EOF cat > /tmp/$PKGNAME/debian/install << EOF usr/bin/yggdrasil usr/bin usr/bin/yggdrasilctl usr/bin -usr/lib/systemd/system/*.service usr/lib/systemd/system +lib/systemd/system/*.service lib/systemd/system EOF cat > /tmp/$PKGNAME/debian/postinst << EOF #!/bin/sh @@ -130,13 +130,13 @@ EOF cp yggdrasil /tmp/$PKGNAME/usr/bin/ cp yggdrasilctl /tmp/$PKGNAME/usr/bin/ -cp contrib/systemd/yggdrasil-default-config.service.debian /tmp/$PKGNAME/usr/lib/systemd/system/yggdrasil-default-config.service -cp contrib/systemd/yggdrasil.service.debian /tmp/$PKGNAME/usr/lib/systemd/system/yggdrasil.service +cp contrib/systemd/yggdrasil-default-config.service.debian /tmp/$PKGNAME/lib/systemd/system/yggdrasil-default-config.service +cp contrib/systemd/yggdrasil.service.debian /tmp/$PKGNAME/lib/systemd/system/yggdrasil.service tar --no-xattrs -czvf /tmp/$PKGNAME/data.tar.gz -C /tmp/$PKGNAME/ \ usr/bin/yggdrasil usr/bin/yggdrasilctl \ - usr/lib/systemd/system/yggdrasil.service \ - usr/lib/systemd/system/yggdrasil-default-config.service + lib/systemd/system/yggdrasil.service \ + lib/systemd/system/yggdrasil-default-config.service tar --no-xattrs -czvf /tmp/$PKGNAME/control.tar.gz -C /tmp/$PKGNAME/debian . echo 2.0 > /tmp/$PKGNAME/debian-binary From a6b316ef085553761b20af61ecfc4acefbf2bbec Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 28 Oct 2023 16:21:50 +0100 Subject: [PATCH 011/125] Release: Yggdrasil 0.5.1 --- CHANGELOG.md | 6 ++++++ cmd/yggdrasil/main.go | 1 + contrib/deb/generate.sh | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50296af0..d0e9e3da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.1] - 2023-10-28 + +### Fixed + +* Fix the Debian package so that upgrades are handled more smoothly + ## [0.5.0] - 2023-10-28 ### Added diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index e0b33990..975e4945 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -156,6 +156,7 @@ func main() { return case *normaliseconf: + cfg.AdminListen = "" var bs []byte if *confjson { bs, err = json.MarshalIndent(cfg, "", " ") diff --git a/contrib/deb/generate.sh b/contrib/deb/generate.sh index 41ca6fe5..69eaa764 100644 --- a/contrib/deb/generate.sh +++ b/contrib/deb/generate.sh @@ -22,7 +22,7 @@ if [ $PKGBRANCH = "master" ]; then fi export LDFLAGS="-X github.com/yggdrasil-network/yggdrasil-go/src/config.defaultConfig=/etc/yggdrasil/yggdrasil.conf" -export LDFLAGS="${LDFLAGS} -X github.com/yggdrasil-network/yggdrasil-go/src/config.defaultAdminListen=unix://var/run/yggdrasil/yggdrasil.sock" +export LDFLAGS="${LDFLAGS} -X github.com/yggdrasil-network/yggdrasil-go/src/config.defaultAdminListen=unix:///var/run/yggdrasil/yggdrasil.sock" if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build elif [ $PKGARCH = "i386" ]; then GOARCH=386 GOOS=linux ./build From 7f9d4f3f6d06262e212a8dd101d51fda134332da Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 28 Oct 2023 18:21:26 +0100 Subject: [PATCH 012/125] Don't import `LDFLAGS` from the environment --- build | 2 +- contrib/deb/generate.sh | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build b/build index de5d9edc..c7214438 100755 --- a/build +++ b/build @@ -6,7 +6,7 @@ PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/version} PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)} PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)} -LDFLAGS="${LDFLAGS} -X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" +LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" ARGS="-v" while getopts "utc:l:dro:p" option diff --git a/contrib/deb/generate.sh b/contrib/deb/generate.sh index 69eaa764..8d39eb1d 100644 --- a/contrib/deb/generate.sh +++ b/contrib/deb/generate.sh @@ -21,16 +21,16 @@ if [ $PKGBRANCH = "master" ]; then PKGREPLACES=yggdrasil-develop fi -export LDFLAGS="-X github.com/yggdrasil-network/yggdrasil-go/src/config.defaultConfig=/etc/yggdrasil/yggdrasil.conf" -export LDFLAGS="${LDFLAGS} -X github.com/yggdrasil-network/yggdrasil-go/src/config.defaultAdminListen=unix:///var/run/yggdrasil/yggdrasil.sock" +GOLDFLAGS="-X github.com/yggdrasil-network/yggdrasil-go/src/config.defaultConfig=/etc/yggdrasil/yggdrasil.conf" +GOLDFLAGS="${GOLDFLAGS} -X github.com/yggdrasil-network/yggdrasil-go/src/config.defaultAdminListen=unix:///var/run/yggdrasil/yggdrasil.sock" -if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build -elif [ $PKGARCH = "i386" ]; then GOARCH=386 GOOS=linux ./build -elif [ $PKGARCH = "mipsel" ]; then GOARCH=mipsle GOOS=linux ./build -elif [ $PKGARCH = "mips" ]; then GOARCH=mips64 GOOS=linux ./build -elif [ $PKGARCH = "armhf" ]; then GOARCH=arm GOOS=linux GOARM=6 ./build -elif [ $PKGARCH = "arm64" ]; then GOARCH=arm64 GOOS=linux ./build -elif [ $PKGARCH = "armel" ]; then GOARCH=arm GOOS=linux GOARM=5 ./build +if [ $PKGARCH = "amd64" ]; then GOARCH=amd64 GOOS=linux ./build -l "${GOLDFLAGS}" +elif [ $PKGARCH = "i386" ]; then GOARCH=386 GOOS=linux ./build -l "${GOLDFLAGS}" +elif [ $PKGARCH = "mipsel" ]; then GOARCH=mipsle GOOS=linux ./build -l "${GOLDFLAGS}" +elif [ $PKGARCH = "mips" ]; then GOARCH=mips64 GOOS=linux ./build -l "${GOLDFLAGS}" +elif [ $PKGARCH = "armhf" ]; then GOARCH=arm GOOS=linux GOARM=6 ./build -l "${GOLDFLAGS}" +elif [ $PKGARCH = "arm64" ]; then GOARCH=arm64 GOOS=linux ./build -l "${GOLDFLAGS}" +elif [ $PKGARCH = "armel" ]; then GOARCH=arm GOOS=linux GOARM=5 ./build -l "${GOLDFLAGS}" else echo "Specify PKGARCH=amd64,i386,mips,mipsel,armhf,arm64,armel" exit 1 From e41b838d8f119b4c71f7a27995c5a941185164c5 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 28 Oct 2023 21:28:38 +0100 Subject: [PATCH 013/125] Don't panic at startup when duplicate peers are configured Fixes #1077 --- src/core/options.go | 10 +++++++++- src/core/options_test.go | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/core/options_test.go diff --git a/src/core/options.go b/src/core/options.go index ffbdae73..581c033b 100644 --- a/src/core/options.go +++ b/src/core/options.go @@ -13,7 +13,15 @@ func (c *Core) _applyOption(opt SetupOption) (err error) { if err != nil { return fmt.Errorf("unable to parse peering URI: %w", err) } - return c.links.add(u, v.SourceInterface, linkTypePersistent) + err = c.links.add(u, v.SourceInterface, linkTypePersistent) + switch err { + case ErrLinkAlreadyConfigured: + // Don't return this error, otherwise we'll panic at startup + // if there are multiple of the same peer configured + return nil + default: + return err + } case ListenAddress: c.config._listeners[v] = struct{}{} case NodeInfo: diff --git a/src/core/options_test.go b/src/core/options_test.go new file mode 100644 index 00000000..bab22fb1 --- /dev/null +++ b/src/core/options_test.go @@ -0,0 +1,41 @@ +package core + +import ( + "net/url" + "testing" + + "github.com/yggdrasil-network/yggdrasil-go/src/config" +) + +// Tests that duplicate peers in the configuration file +// won't cause an error when the node starts. Otherwise +// we can panic unnecessarily. +func TestDuplicatePeerAtStartup(t *testing.T) { + cfg := config.GenerateConfig() + for i := 0; i < 5; i++ { + cfg.Peers = append(cfg.Peers, "tcp://1.2.3.4:4321") + } + if _, err := New(cfg.Certificate, nil); err != nil { + t.Fatal(err) + } +} + +// Tests that duplicate peers given to us through the +// API will still error as expected, even if they didn't +// at startup. We expect to notify the user through the +// admin socket if they try to add a peer that is already +// configured. +func TestDuplicatePeerFromAPI(t *testing.T) { + cfg := config.GenerateConfig() + c, err := New(cfg.Certificate, nil) + if err != nil { + t.Fatal(err) + } + u, _ := url.Parse("tcp://1.2.3.4:4321") + if err := c.AddPeer(u, ""); err != nil { + t.Fatalf("Adding peer failed on first attempt: %s", err) + } + if err := c.AddPeer(u, ""); err == nil { + t.Fatalf("Adding peer should have failed on second attempt") + } +} From 41e045fe5bf18eb08b3e467f499ef4f469fad329 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 3 Nov 2023 21:55:42 -0500 Subject: [PATCH 014/125] update ironwood dependency --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index faa0e0d8..1b79c4fa 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43 + github.com/Arceliar/ironwood v0.0.0-20231104025256-ec84c695fc44 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 diff --git a/go.sum b/go.sum index 901eabaa..3208f003 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43 h1:M4NczBPk7Fy0Uy2YvNoXwSkk3dGoGTOYtUjyqpOC5ko= -github.com/Arceliar/ironwood v0.0.0-20231028101932-ceac99571f43/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= +github.com/Arceliar/ironwood v0.0.0-20231104025256-ec84c695fc44 h1:u328GAZGtL0W4oFWQs4YWHZT215LL6Lw9aYJxx76UVs= +github.com/Arceliar/ironwood v0.0.0-20231104025256-ec84c695fc44/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From ae997a5acbe6a522841b1f51cadbdde05998ff64 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 4 Nov 2023 17:56:52 +0000 Subject: [PATCH 015/125] Improve TUN setup logging (#1093) (#1095) Co-authored-by: Neil Alexander --- src/tun/tun_bsd.go | 2 +- src/tun/tun_darwin.go | 15 ++++++++------- src/tun/tun_linux.go | 12 ++++++------ src/tun/tun_other.go | 2 +- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/tun/tun_bsd.go b/src/tun/tun_bsd.go index 5f42f52b..da5b3297 100644 --- a/src/tun/tun_bsd.go +++ b/src/tun/tun_bsd.go @@ -78,7 +78,7 @@ type in6_ifreq_lifetime struct { func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { iface, err := wgtun.CreateTUN(ifname, int(mtu)) if err != nil { - panic(err) + return fmt.Errorf("failed to create TUN: %w", err) } tun.iface = iface if mtu, err := iface.MTU(); err == nil { diff --git a/src/tun/tun_darwin.go b/src/tun/tun_darwin.go index 8fde93a1..71f82701 100644 --- a/src/tun/tun_darwin.go +++ b/src/tun/tun_darwin.go @@ -7,6 +7,7 @@ package tun import ( "encoding/binary" + "fmt" "os" "strconv" "strings" @@ -24,7 +25,7 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { } iface, err := wgtun.CreateTUN(ifname, int(mtu)) if err != nil { - panic(err) + return fmt.Errorf("failed to create TUN: %w", err) } tun.iface = iface if m, err := iface.MTU(); err == nil { @@ -42,17 +43,17 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { func (tun *TunAdapter) setupFD(fd int32, addr string, mtu uint64) error { dfd, err := unix.Dup(int(fd)) if err != nil { - return err + return fmt.Errorf("failed to duplicate FD: %w", err) } err = unix.SetNonblock(dfd, true) if err != nil { unix.Close(dfd) - return err + return fmt.Errorf("failed to set FD as non-blocking: %w", err) } iface, err := wgtun.CreateTUNFromFile(os.NewFile(uintptr(dfd), "/dev/tun"), 0) if err != nil { unix.Close(dfd) - return err + return fmt.Errorf("failed to create TUN from FD: %w", err) } tun.iface = iface if m, err := iface.MTU(); err == nil { @@ -111,7 +112,7 @@ func (tun *TunAdapter) setupAddress(addr string) error { if fd, err = unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0); err != nil { tun.log.Printf("Create AF_SYSTEM socket failed: %v.", err) - return err + return fmt.Errorf("failed to open AF_SYSTEM: %w", err) } var ar in6_aliasreq @@ -149,13 +150,13 @@ func (tun *TunAdapter) setupAddress(addr string) error { if _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(darwin_SIOCAIFADDR_IN6), uintptr(unsafe.Pointer(&ar))); errno != 0 { // nolint:staticcheck err = errno tun.log.Errorf("Error in darwin_SIOCAIFADDR_IN6: %v", errno) - return err + return fmt.Errorf("failed to call SIOCAIFADDR_IN6: %w", err) } if _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(unix.SIOCSIFMTU), uintptr(unsafe.Pointer(&ir))); errno != 0 { // nolint:staticcheck err = errno tun.log.Errorf("Error in SIOCSIFMTU: %v", errno) - return err + return fmt.Errorf("failed to call SIOCSIFMTU: %w", err) } return err diff --git a/src/tun/tun_linux.go b/src/tun/tun_linux.go index 9cf21446..98d63db4 100644 --- a/src/tun/tun_linux.go +++ b/src/tun/tun_linux.go @@ -19,7 +19,7 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { } iface, err := wgtun.CreateTUN(ifname, int(mtu)) if err != nil { - panic(err) + return fmt.Errorf("failed to create TUN: %w", err) } tun.iface = iface if mtu, err := iface.MTU(); err == nil { @@ -45,20 +45,20 @@ func (tun *TunAdapter) setupFD(fd int32, addr string, mtu uint64) error { func (tun *TunAdapter) setupAddress(addr string) error { nladdr, err := netlink.ParseAddr(addr) if err != nil { - return err + return fmt.Errorf("couldn't parse address %q: %w", addr, err) } nlintf, err := netlink.LinkByName(tun.Name()) if err != nil { - return err + return fmt.Errorf("failed to find link by name: %w", err) } if err := netlink.AddrAdd(nlintf, nladdr); err != nil { - return err + return fmt.Errorf("failed to add address to link: %w", err) } if err := netlink.LinkSetMTU(nlintf, int(tun.mtu)); err != nil { - return err + return fmt.Errorf("failed to set link MTU: %w", err) } if err := netlink.LinkSetUp(nlintf); err != nil { - return err + return fmt.Errorf("failed to bring link up: %w", err) } // Friendly output tun.log.Infof("Interface name: %s", tun.Name()) diff --git a/src/tun/tun_other.go b/src/tun/tun_other.go index bf8ac892..0ddd0c1e 100644 --- a/src/tun/tun_other.go +++ b/src/tun/tun_other.go @@ -16,7 +16,7 @@ import ( func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { iface, err := wgtun.CreateTUN(ifname, mtu) if err != nil { - panic(err) + return fmt.Errorf("failed to create TUN: %w", err) } tun.iface = iface if mtu, err := iface.MTU(); err == nil { From ddb75700a08ebca65e8a6dfac825f4ec781af43c Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 4 Nov 2023 17:57:04 +0000 Subject: [PATCH 016/125] Report errors during handshake stage (#1091) Co-authored-by: Neil Alexander --- src/core/link.go | 5 +++-- src/core/version.go | 27 +++++++++++++++------------ src/core/version_test.go | 6 +++--- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index c3808698..f3cb4318 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -546,8 +546,9 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn) e } meta = version_metadata{} base := version_getBaseMetadata() - if !meta.decode(conn, options.password) { - return conn.Close() + if err := meta.decode(conn, options.password); err != nil { + _ = conn.Close() + return err } if !meta.check() { return fmt.Errorf("remote node incompatible version (local %s, remote %s)", diff --git a/src/core/version.go b/src/core/version.go index 332e18c8..28b16430 100644 --- a/src/core/version.go +++ b/src/core/version.go @@ -87,22 +87,22 @@ func (m *version_metadata) encode(privateKey ed25519.PrivateKey, password []byte } // Decodes version metadata from its wire format into the struct. -func (m *version_metadata) decode(r io.Reader, password []byte) bool { +func (m *version_metadata) decode(r io.Reader, password []byte) error { bh := [6]byte{} if _, err := io.ReadFull(r, bh[:]); err != nil { - return false + return err } meta := [4]byte{'m', 'e', 't', 'a'} if !bytes.Equal(bh[:4], meta[:]) { - return false + return fmt.Errorf("invalid handshake preamble") } - bs := make([]byte, binary.BigEndian.Uint16(bh[4:6])) + hl := binary.BigEndian.Uint16(bh[4:6]) + if hl < ed25519.SignatureSize { + return fmt.Errorf("invalid handshake length") + } + bs := make([]byte, hl) if _, err := io.ReadFull(r, bs); err != nil { - return false - } - - if len(bs) < ed25519.SignatureSize { - return false + return err } sig := bs[len(bs)-ed25519.SignatureSize:] bs = bs[:len(bs)-ed25519.SignatureSize] @@ -132,14 +132,17 @@ func (m *version_metadata) decode(r io.Reader, password []byte) bool { hasher, err := blake2b.New512(password) if err != nil { - return false + return fmt.Errorf("invalid password supplied") } n, err := hasher.Write(m.publicKey) if err != nil || n != ed25519.PublicKeySize { - return false + return fmt.Errorf("failed to generate hash") } hash := hasher.Sum(nil) - return ed25519.Verify(m.publicKey, hash, sig) + if !ed25519.Verify(m.publicKey, hash, sig) { + return fmt.Errorf("password is incorrect") + } + return nil } // Checks that the "meta" bytes and the version numbers are the expected values. diff --git a/src/core/version_test.go b/src/core/version_test.go index 7efe2f35..512c6e59 100644 --- a/src/core/version_test.go +++ b/src/core/version_test.go @@ -34,7 +34,7 @@ func TestVersionPasswordAuth(t *testing.T) { } var decoded version_metadata - if allowed := decoded.decode(bytes.NewBuffer(encoded), tt.password2); allowed != tt.allowed { + if allowed := decoded.decode(bytes.NewBuffer(encoded), tt.password2) == nil; allowed != tt.allowed { t.Fatalf("Permutation %q -> %q should have been %v but was %v", tt.password1, tt.password2, tt.allowed, allowed) } } @@ -67,8 +67,8 @@ func TestVersionRoundtrip(t *testing.T) { } encoded := bytes.NewBuffer(meta) decoded := &version_metadata{} - if !decoded.decode(encoded, password) { - t.Fatalf("failed to decode") + if err := decoded.decode(encoded, password); err != nil { + t.Fatalf("failed to decode: %s", err) } if !reflect.DeepEqual(test, decoded) { t.Fatalf("round-trip failed\nwant: %+v\n got: %+v", test, decoded) From 93a5adfd189ff8ecd233693dc123b0ef7e11216f Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 4 Nov 2023 17:57:15 +0000 Subject: [PATCH 017/125] Add `sockstls://` (#1090) Closes #1087. Co-authored-by: Neil Alexander --- src/core/link.go | 34 +++++++++++++++++----------------- src/core/link_socks.go | 12 +++++++++++- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index f3cb4318..0b2efc57 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -179,6 +179,22 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { } options.password = []byte(p) } + // SNI headers must contain hostnames and not IP addresses, so we must make sure + // that we do not populate the SNI with an IP literal. We do this by splitting + // the host-port combo from the query option and then seeing if it parses to an + // IP address successfully or not. + if sni := u.Query().Get("sni"); sni != "" { + if net.ParseIP(sni) == nil { + options.tlsSNI = sni + } + } + // If the SNI is not configured still because the above failed then we'll try + // again but this time we'll use the host part of the peering URI instead. + if options.tlsSNI == "" { + if host, _, err := net.SplitHostPort(u.Host); err == nil && net.ParseIP(host) == nil { + options.tlsSNI = host + } + } // If we think we're already connected to this peer, load up // the existing peer state. Try to kick the peer if possible, @@ -497,24 +513,8 @@ func (l *links) connect(ctx context.Context, u *url.URL, info linkInfo, options case "tcp": dialer = l.tcp case "tls": - // SNI headers must contain hostnames and not IP addresses, so we must make sure - // that we do not populate the SNI with an IP literal. We do this by splitting - // the host-port combo from the query option and then seeing if it parses to an - // IP address successfully or not. - if sni := u.Query().Get("sni"); sni != "" { - if net.ParseIP(sni) == nil { - options.tlsSNI = sni - } - } - // If the SNI is not configured still because the above failed then we'll try - // again but this time we'll use the host part of the peering URI instead. - if options.tlsSNI == "" { - if host, _, err := net.SplitHostPort(u.Host); err == nil && net.ParseIP(host) == nil { - options.tlsSNI = host - } - } dialer = l.tls - case "socks": + case "socks", "sockstls": dialer = l.socks case "unix": dialer = l.unix diff --git a/src/core/link_socks.go b/src/core/link_socks.go index 1a038fa6..b92374d4 100644 --- a/src/core/link_socks.go +++ b/src/core/link_socks.go @@ -2,6 +2,7 @@ package core import ( "context" + "crypto/tls" "fmt" "net" "net/url" @@ -34,7 +35,16 @@ func (l *linkSOCKS) dial(_ context.Context, url *url.URL, info linkInfo, options return nil, fmt.Errorf("failed to configure proxy") } pathtokens := strings.Split(strings.Trim(url.Path, "/"), "/") - return dialer.Dial("tcp", pathtokens[0]) + conn, err := dialer.Dial("tcp", pathtokens[0]) + if err != nil { + return nil, fmt.Errorf("failed to dial: %w", err) + } + if url.Scheme == "sockstls" { + tlsconfig := l.tls.config.Clone() + tlsconfig.ServerName = options.tlsSNI + conn = tls.Client(conn, tlsconfig) + } + return conn, nil } func (l *linkSOCKS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { From 0346af46dae233e7d95d2a08e2b992382e1f2d64 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 4 Nov 2023 18:42:42 +0000 Subject: [PATCH 018/125] Don't panic when connect returns `nil` (fixes #1086) (#1089) * Don't panic when connect returns `nil` (fixes #1086) It isn't clear to me why this would happen but let's guard the condition anyway. * Log inconsistent error state --------- Co-authored-by: Neil Alexander --- src/core/link.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/link.go b/src/core/link.go index 0b2efc57..af4a5a59 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -273,7 +273,10 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { } conn, err := l.connect(state.ctx, u, info, options) - if err != nil { + if err != nil || conn == nil { + if err == nil && conn == nil { + l.core.log.Warnf("Link %q reached inconsistent error state", u.String()) + } if linkType == linkTypePersistent { // If the link is a persistent configured peering, // store information about the connection error so From 49c424ef213589d63215f10dc1958b2e93fb1e6c Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 4 Nov 2023 18:42:51 +0000 Subject: [PATCH 019/125] Add `-publickey` command line switch (#1096) Co-authored-by: Neil Alexander --- cmd/yggdrasil/main.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 975e4945..a225755c 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -48,8 +48,9 @@ func main() { autoconf := flag.Bool("autoconf", false, "automatic mode (dynamic IP, peer with IPv6 neighbors)") ver := flag.Bool("version", false, "prints the version of this build") logto := flag.String("logto", "stdout", "file path to log to, \"syslog\" or \"stdout\"") - getaddr := flag.Bool("address", false, "returns the IPv6 address as derived from the supplied configuration") - getsnet := flag.Bool("subnet", false, "returns the IPv6 subnet as derived from the supplied configuration") + getaddr := flag.Bool("address", false, "use in combination with either -useconf or -useconffile, outputs your IPv6 address") + getsnet := flag.Bool("subnet", false, "use in combination with either -useconf or -useconffile, outputs your IPv6 subnet") + getpkey := flag.Bool("publickey", false, "use in combination with either -useconf or -useconffile, outputs your public key") loglevel := flag.String("loglevel", "info", "loglevel to enable") flag.Parse() @@ -155,6 +156,10 @@ func main() { fmt.Println(ipnet.String()) return + case *getpkey: + fmt.Println(hex.EncodeToString(publicKey)) + return + case *normaliseconf: cfg.AdminListen = "" var bs []byte From 7ac38e3e58d2134802fcd0e7ae42f54bfd92314a Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 6 Nov 2023 09:25:15 +0000 Subject: [PATCH 020/125] Release: Yggdrasil 0.5.2 --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0e9e3da..c91e83ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,25 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.2] - 2023-11-06 + +### Added + +* New `-publickey` command line option that prints the derived public key from a configuration file +* Support for connecting to TLS peers via SOCKS with the new `sockstls://` link schema + +### Changed + +* Stabilise tree parent selection algorithm +* Improved logging when the TUN interface fails to set up + +### Fixed + +* Fixed a panic that could occur when a connection reaches an inconsistent error state +* The admin socket will now report more peering handshake error conditions in `getPeers` +* Yggdrasil will no longer panic at startup when duplicate peers are configured +* The `build` script will no longer incorrectly import `LDFLAGS` from the environment + ## [0.5.1] - 2023-10-28 ### Fixed From 6677d70648b076d25a8db0dfe5fe886e7ae3190e Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 9 Nov 2023 22:06:19 -0600 Subject: [PATCH 021/125] update ironwood, fixed data race from buffered pathfinder traffic --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1b79c4fa..164aa3d0 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20231104025256-ec84c695fc44 + github.com/Arceliar/ironwood v0.0.0-20231110040415-4972641b0b94 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 diff --git a/go.sum b/go.sum index 3208f003..4b3a8198 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20231104025256-ec84c695fc44 h1:u328GAZGtL0W4oFWQs4YWHZT215LL6Lw9aYJxx76UVs= -github.com/Arceliar/ironwood v0.0.0-20231104025256-ec84c695fc44/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= +github.com/Arceliar/ironwood v0.0.0-20231110040415-4972641b0b94 h1:9gsjQMpH9uwu5wRD2wJrocsudTw/WRy8oJykdrBz4F8= +github.com/Arceliar/ironwood v0.0.0-20231110040415-4972641b0b94/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From 7aca8691706f5bbc99a986c2205a43646d90ca3d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 21 Nov 2023 10:35:17 +0000 Subject: [PATCH 022/125] Tweak backoff success handling --- src/core/link.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index af4a5a59..f2abd7c6 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -249,6 +249,12 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { } } + // resetBackoff is called by the connection handler when the + // handshake has successfully completed. + resetBackoff := func() { + backoff = 0 + } + // The goroutine is responsible for attempting the connection // and then running the handler. If the connection is persistent // then the loop will run endlessly, using backoffs as needed. @@ -325,10 +331,8 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { // Give the connection to the handler. The handler will block // for the lifetime of the connection. - if err = l.handler(linkType, options, lc); err != nil && err != io.EOF { + if err = l.handler(linkType, options, lc, resetBackoff); err != nil && err != io.EOF { l.core.log.Debugf("Link %s error: %s\n", info.uri, err) - } else { - backoff = 0 } // The handler has stopped running so the connection is dead, @@ -491,7 +495,7 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { // Give the connection to the handler. The handler will block // for the lifetime of the connection. - if err = l.handler(linkTypeIncoming, options, lc); err != nil && err != io.EOF { + if err = l.handler(linkTypeIncoming, options, lc, nil); err != nil && err != io.EOF { l.core.log.Debugf("Link %s error: %s\n", u.Host, err) } @@ -529,7 +533,7 @@ func (l *links) connect(ctx context.Context, u *url.URL, info linkInfo, options return dialer.dial(ctx, u, info, options) } -func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn) error { +func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, success func()) error { meta := version_getBaseMetadata() meta.publicKey = l.core.public meta.priority = options.priority @@ -600,6 +604,9 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn) e } l.core.log.Infof("Connected %s: %s, source %s", dir, remoteStr, localStr) + if success != nil { + success() + } err = l.core.HandleConn(meta.publicKey, conn, priority) switch err { From a0b38972787947fc9dbf5e1e9fc6539213a998ce Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 21 Nov 2023 23:54:27 +0000 Subject: [PATCH 023/125] Cap link backoff at roughly 4.5 hours --- src/core/link.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/link.go b/src/core/link.go index f2abd7c6..0f445ff5 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -235,7 +235,9 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { // The caller should check the return value to decide whether // or not to give up trying. backoffNow := func() bool { - backoff++ + if backoff < 14 { // Cap at roughly 4.5 hours maximum. + backoff++ + } duration := time.Second * time.Duration(math.Exp2(float64(backoff))) select { case <-state.kick: From 0d676c6a3bbd3289b98a5b2572e1149b5d3dc4c2 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sun, 26 Nov 2023 04:56:44 -0600 Subject: [PATCH 024/125] update ironwood dependency --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 164aa3d0..73dfe053 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20231110040415-4972641b0b94 + github.com/Arceliar/ironwood v0.0.0-20231126105342-ad38416a77c8 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 diff --git a/go.sum b/go.sum index 4b3a8198..ba37a002 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20231110040415-4972641b0b94 h1:9gsjQMpH9uwu5wRD2wJrocsudTw/WRy8oJykdrBz4F8= -github.com/Arceliar/ironwood v0.0.0-20231110040415-4972641b0b94/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= +github.com/Arceliar/ironwood v0.0.0-20231126105342-ad38416a77c8 h1:qyXiPZClVoe6QsbsiDP23g0Ze/MNXiHIAL/nVNfauH0= +github.com/Arceliar/ironwood v0.0.0-20231126105342-ad38416a77c8/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From 39c4b24395a471d032a96f9bac1e69e17cafb99b Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 26 Nov 2023 16:19:00 +0000 Subject: [PATCH 025/125] Don't use 0-RTT for QUIC --- src/core/link_quic.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/link_quic.go b/src/core/link_quic.go index 976aba6a..a2db6e05 100644 --- a/src/core/link_quic.go +++ b/src/core/link_quic.go @@ -24,7 +24,7 @@ type linkQUICStream struct { } type linkQUICListener struct { - *quic.EarlyListener + *quic.Listener ch <-chan *linkQUICStream } @@ -50,11 +50,11 @@ func (l *links) newLinkQUIC() *linkQUIC { } func (l *linkQUIC) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { - qc, err := quic.DialAddrEarly(ctx, url.Host, l.tlsconfig, l.quicconfig) + qc, err := quic.DialAddr(ctx, url.Host, l.tlsconfig, l.quicconfig) if err != nil { return nil, err } - qs, err := qc.OpenStream() + qs, err := qc.OpenStreamSync(ctx) if err != nil { return nil, err } @@ -65,14 +65,14 @@ func (l *linkQUIC) dial(ctx context.Context, url *url.URL, info linkInfo, option } func (l *linkQUIC) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { - ql, err := quic.ListenAddrEarly(url.Host, l.tlsconfig, l.quicconfig) + ql, err := quic.ListenAddr(url.Host, l.tlsconfig, l.quicconfig) if err != nil { return nil, err } ch := make(chan *linkQUICStream) lql := &linkQUICListener{ - EarlyListener: ql, - ch: ch, + Listener: ql, + ch: ch, } go func() { for { From f6f669617fffd75b96de6977c3b75b5eff2985c1 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 26 Nov 2023 16:20:52 +0000 Subject: [PATCH 026/125] Fix `-normaliseconf` when using `PrivateKeyPath` --- cmd/yggdrasil/main.go | 3 +++ src/config/config.go | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index a225755c..b133ed36 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -162,6 +162,9 @@ func main() { case *normaliseconf: cfg.AdminListen = "" + if cfg.PrivateKeyPath != "" { + cfg.PrivateKey = nil + } var bs []byte if *confjson { bs, err = json.MarshalIndent(cfg, "", " ") diff --git a/src/config/config.go b/src/config/config.go index e899a35d..aac51467 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -40,8 +40,8 @@ import ( // options that are necessary for an Yggdrasil node to run. You will need to // supply one of these structs to the Yggdrasil core when starting a node. type NodeConfig struct { - PrivateKey KeyBytes `comment:"Your private key. DO NOT share this with anyone!"` - PrivateKeyPath string `json:",omitempty"` + PrivateKey KeyBytes `json:",omitempty" comment:"Your private key. DO NOT share this with anyone!"` + PrivateKeyPath string `json:",omitempty" comment:"The path to your private key file in PEM format."` Certificate *tls.Certificate `json:"-"` Peers []string `comment:"List of connection strings for outbound peer connections in URI format,\ne.g. tls://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j. These connections\nwill obey the operating system routing table, therefore you should\nuse this section when you may connect via different interfaces."` InterfacePeers map[string][]string `comment:"List of connection strings for outbound peer connections in URI format,\narranged by source interface, e.g. { \"eth0\": [ \"tls://a.b.c.d:e\" ] }.\nNote that SOCKS peerings will NOT be affected by this option and should\ngo in the \"Peers\" section instead."` From fef553ed185b279145a132461da862f8f8a98f79 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 26 Nov 2023 16:28:48 +0000 Subject: [PATCH 027/125] Tweak logging --- cmd/yggdrasil/main.go | 6 +++--- src/core/link.go | 4 ++-- src/tun/iface.go | 2 +- src/tun/tun_darwin.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index b133ed36..a1c79492 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -216,9 +216,9 @@ func main() { panic(err) } address, subnet := n.core.Address(), n.core.Subnet() - logger.Infof("Your public key is %s", hex.EncodeToString(n.core.PublicKey())) - logger.Infof("Your IPv6 address is %s", address.String()) - logger.Infof("Your IPv6 subnet is %s", subnet.String()) + logger.Printf("Your public key is %s", hex.EncodeToString(n.core.PublicKey())) + logger.Printf("Your IPv6 address is %s", address.String()) + logger.Printf("Your IPv6 subnet is %s", subnet.String()) } // Setup the admin socket. diff --git a/src/core/link.go b/src/core/link.go index 0f445ff5..09f815c2 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -432,8 +432,8 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { } go func() { - l.core.log.Printf("%s listener started on %s", strings.ToUpper(u.Scheme), listener.Addr()) - defer l.core.log.Printf("%s listener stopped on %s", strings.ToUpper(u.Scheme), listener.Addr()) + l.core.log.Infof("%s listener started on %s", strings.ToUpper(u.Scheme), listener.Addr()) + defer l.core.log.Infof("%s listener stopped on %s", strings.ToUpper(u.Scheme), listener.Addr()) for { conn, err := listener.Accept() if err != nil { diff --git a/src/tun/iface.go b/src/tun/iface.go index c98b56d6..e06f3a5d 100644 --- a/src/tun/iface.go +++ b/src/tun/iface.go @@ -29,7 +29,7 @@ func (tun *TunAdapter) write() { bs := buf[TUN_OFFSET_BYTES:] n, err := tun.rwc.Read(bs) if err != nil { - tun.log.Errorln("Exiting tun writer due to core read error:", err) + tun.log.Errorln("Exiting TUN writer due to core read error:", err) return } if !tun.isEnabled { diff --git a/src/tun/tun_darwin.go b/src/tun/tun_darwin.go index 71f82701..deeb115e 100644 --- a/src/tun/tun_darwin.go +++ b/src/tun/tun_darwin.go @@ -111,7 +111,7 @@ func (tun *TunAdapter) setupAddress(addr string) error { var err error if fd, err = unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0); err != nil { - tun.log.Printf("Create AF_SYSTEM socket failed: %v.", err) + tun.log.Errorf("Create AF_SYSTEM socket failed: %v.", err) return fmt.Errorf("failed to open AF_SYSTEM: %w", err) } From 676ae52503a5f0c86314958a5817afe949deb1e3 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 26 Nov 2023 18:42:08 +0000 Subject: [PATCH 028/125] Release: Yggdrasil 0.5.3 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c91e83ba..fc7f9f73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.3] - 2023-11-26 + +### Fixed + +* Fixed a data race from buffered pathfinder traffic +* Fix a bug where the next-hop selection may not take shortcuts through treespace +* Backoffs are now reset correctly when a successful handshake is completed +* Backoffs will no longer exceed roughly 4.5 hours when peers are down for a long time +* The `-normaliseconf` option will now work correctly with `PrivateKeyPath` +* Improved the reliability of QUIC peering setup by disabling 0-RTT + ## [0.5.2] - 2023-11-06 ### Added From 741f825b8ed3e78664997f49c786dd51fa6a3805 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Mon, 27 Nov 2023 07:18:16 -0600 Subject: [PATCH 029/125] update ironwood dependency, should fix bloom filter encoding crash --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 73dfe053..6ce5beb0 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20231126105342-ad38416a77c8 + github.com/Arceliar/ironwood v0.0.0-20231127131626-465b82dfb5bd github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 diff --git a/go.sum b/go.sum index ba37a002..e89d0fcf 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20231126105342-ad38416a77c8 h1:qyXiPZClVoe6QsbsiDP23g0Ze/MNXiHIAL/nVNfauH0= -github.com/Arceliar/ironwood v0.0.0-20231126105342-ad38416a77c8/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= +github.com/Arceliar/ironwood v0.0.0-20231127131626-465b82dfb5bd h1:458tnmZ4zM2gbLtefdYbaxyAJevDNEWu6tLKEqbK4wg= +github.com/Arceliar/ironwood v0.0.0-20231127131626-465b82dfb5bd/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From 3d15da34ad9021add84f5df00cdf65341cb29829 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 27 Nov 2023 14:17:16 +0000 Subject: [PATCH 030/125] Release: Yggdrasil 0.5.4 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc7f9f73..b2715486 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.4] - 2023-11-27 + +### Fixed + +* Fixed a crash that could happen when calculating the size of bloom filters during encoding + ## [0.5.3] - 2023-11-26 ### Fixed From 6b6cd0bed553ada887632524994e4de4e839688e Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 28 Nov 2023 13:24:54 +0000 Subject: [PATCH 031/125] Fix `PPROFLISTEN` --- src/core/debug.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/debug.go b/src/core/debug.go index a6eb5e2a..354c2ecd 100644 --- a/src/core/debug.go +++ b/src/core/debug.go @@ -12,6 +12,8 @@ func init() { envVarName := "PPROFLISTEN" if hostPort := os.Getenv(envVarName); hostPort != "" { fmt.Fprintf(os.Stderr, "DEBUG: Starting pprof on %s\n", hostPort) - go fmt.Println(http.ListenAndServe(hostPort, nil)) + go func() { + fmt.Fprintf(os.Stderr, "DEBUG: %s", http.ListenAndServe(hostPort, nil)) + }() } } From 3dfa6d0cc9f4020f065392b3f8eeaca9680b347e Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 3 Dec 2023 17:55:12 +0000 Subject: [PATCH 032/125] Validate public key lengths on `debug_` API endpoints (fixes #1113) --- src/core/proto.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/core/proto.go b/src/core/proto.go index d8cae737..bffc2022 100644 --- a/src/core/proto.go +++ b/src/core/proto.go @@ -251,15 +251,16 @@ func (p *protoHandler) getSelfHandler(in json.RawMessage) (interface{}, error) { if kbs, err = hex.DecodeString(req.Key); err != nil { return nil, err } + if len(kbs) != ed25519.PublicKeySize { + return nil, fmt.Errorf("invalid public key length") + } copy(key[:], kbs) ch := make(chan []byte, 1) p.sendGetSelfRequest(key, func(info []byte) { ch <- info }) - timer := time.NewTimer(6 * time.Second) - defer timer.Stop() select { - case <-timer.C: + case <-time.After(6 * time.Second): return nil, errors.New("timeout") case info := <-ch: var msg json.RawMessage @@ -291,15 +292,16 @@ func (p *protoHandler) getPeersHandler(in json.RawMessage) (interface{}, error) if kbs, err = hex.DecodeString(req.Key); err != nil { return nil, err } + if len(kbs) != ed25519.PublicKeySize { + return nil, fmt.Errorf("invalid public key length") + } copy(key[:], kbs) ch := make(chan []byte, 1) p.sendGetPeersRequest(key, func(info []byte) { ch <- info }) - timer := time.NewTimer(6 * time.Second) - defer timer.Stop() select { - case <-timer.C: + case <-time.After(6 * time.Second): return nil, errors.New("timeout") case info := <-ch: ks := make(map[string][]string) @@ -341,15 +343,16 @@ func (p *protoHandler) getTreeHandler(in json.RawMessage) (interface{}, error) { if kbs, err = hex.DecodeString(req.Key); err != nil { return nil, err } + if len(kbs) != ed25519.PublicKeySize { + return nil, fmt.Errorf("invalid public key length") + } copy(key[:], kbs) ch := make(chan []byte, 1) p.sendGetTreeRequest(key, func(info []byte) { ch <- info }) - timer := time.NewTimer(6 * time.Second) - defer timer.Stop() select { - case <-timer.C: + case <-time.After(6 * time.Second): return nil, errors.New("timeout") case info := <-ch: ks := make(map[string][]string) From 1e9a59edf99b232cf160982e42c6bc3a807eaf0e Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 5 Jan 2024 11:45:20 +0000 Subject: [PATCH 033/125] Update behaviour in QUIC listener handler --- src/core/link_quic.go | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/core/link_quic.go b/src/core/link_quic.go index a2db6e05..9ad5456d 100644 --- a/src/core/link_quic.go +++ b/src/core/link_quic.go @@ -3,6 +3,7 @@ package core import ( "context" "crypto/tls" + "fmt" "net" "net/url" "time" @@ -77,18 +78,22 @@ func (l *linkQUIC) listen(ctx context.Context, url *url.URL, _ string) (net.List go func() { for { qc, err := ql.Accept(ctx) - if err != nil { + switch err { + case context.Canceled, context.DeadlineExceeded: ql.Close() + fallthrough + case quic.ErrServerClosed: return - } - qs, err := qc.AcceptStream(ctx) - if err != nil { - ql.Close() - return - } - ch <- &linkQUICStream{ - Connection: qc, - Stream: qs, + case nil: + qs, err := qc.AcceptStream(ctx) + if err != nil { + _ = qc.CloseWithError(1, fmt.Sprintf("stream error: %s", err)) + continue + } + ch <- &linkQUICStream{ + Connection: qc, + Stream: qs, + } } } }() From 768278a8e6508a82ab5e2e4655c224be657a8e23 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 11 Jan 2024 22:37:05 +0000 Subject: [PATCH 034/125] Improve `getPeers` sorting --- src/admin/getpeers.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index c6cd5be4..9bc3872f 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -56,10 +56,16 @@ func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersRespons res.Peers = append(res.Peers, peer) } sort.Slice(res.Peers, func(i, j int) bool { - if res.Peers[i].Port == res.Peers[j].Port { - return res.Peers[i].Priority < res.Peers[j].Priority + if res.Peers[i].Inbound == res.Peers[j].Inbound { + if res.Peers[i].PublicKey == res.Peers[j].PublicKey { + if res.Peers[i].Priority == res.Peers[j].Priority { + return res.Peers[i].Uptime > res.Peers[j].Uptime + } + return res.Peers[i].Priority < res.Peers[j].Priority + } + return res.Peers[i].PublicKey < res.Peers[j].PublicKey } - return res.Peers[i].Port < res.Peers[j].Port + return !res.Peers[i].Inbound && res.Peers[j].Inbound }) return nil } From 5da4c1131e224f63d376eec594c31ef29c1c427d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 15 Jan 2024 19:07:17 +0000 Subject: [PATCH 035/125] Update ironwood to `ddd1fa6` --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6ce5beb0..d63cecc0 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20231127131626-465b82dfb5bd + github.com/Arceliar/ironwood v0.0.0-20240115190409-ddd1fa67c018 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 diff --git a/go.sum b/go.sum index e89d0fcf..6b1cdabb 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20231127131626-465b82dfb5bd h1:458tnmZ4zM2gbLtefdYbaxyAJevDNEWu6tLKEqbK4wg= -github.com/Arceliar/ironwood v0.0.0-20231127131626-465b82dfb5bd/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= +github.com/Arceliar/ironwood v0.0.0-20240115190409-ddd1fa67c018 h1:7r/T7qJht4CaPl74AgU7dG5N6g7+2230/9BhrbtRijk= +github.com/Arceliar/ironwood v0.0.0-20240115190409-ddd1fa67c018/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From 9f4c89acad2e0cab52ab5e154212edcd000ce893 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 15 Jan 2024 23:00:58 +0000 Subject: [PATCH 036/125] Update dependencies --- go.mod | 14 +++++++------- go.sum | 28 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index d63cecc0..f3b63daf 100644 --- a/go.mod +++ b/go.mod @@ -8,15 +8,15 @@ require ( github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 github.com/hashicorp/go-syslog v1.0.0 - github.com/hjson/hjson-go/v4 v4.3.0 + github.com/hjson/hjson-go/v4 v4.4.0 github.com/kardianos/minwinsvc v1.0.2 - github.com/quic-go/quic-go v0.39.3 + github.com/quic-go/quic-go v0.40.1 github.com/vishvananda/netlink v1.1.0 - golang.org/x/crypto v0.14.0 + golang.org/x/crypto v0.18.0 golang.org/x/mobile v0.0.0-20231006135142-2b44d11868fe - golang.org/x/net v0.17.0 - golang.org/x/sys v0.13.0 - golang.org/x/text v0.13.0 + golang.org/x/net v0.20.0 + golang.org/x/sys v0.16.0 + golang.org/x/text v0.14.0 golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 golang.zx2c4.com/wireguard/windows v0.5.3 ) @@ -28,7 +28,7 @@ require ( github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/onsi/ginkgo/v2 v2.9.5 // indirect - github.com/quic-go/qtls-go1-20 v0.3.4 // indirect + github.com/quic-go/qtls-go1-20 v0.4.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect go.uber.org/mock v0.3.0 // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect diff --git a/go.sum b/go.sum index 6b1cdabb..6cd0ab72 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hjson/hjson-go/v4 v4.3.0 h1:dyrzJdqqFGhHt+FSrs5n9s6b0fPM8oSJdWo+oS3YnJw= -github.com/hjson/hjson-go/v4 v4.3.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= +github.com/hjson/hjson-go/v4 v4.4.0 h1:D/NPvqOCH6/eisTb5/ztuIS8GUvmpHaLOcNk1Bjr298= +github.com/hjson/hjson-go/v4 v4.4.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/kardianos/minwinsvc v1.0.2 h1:JmZKFJQrmTGa/WiW+vkJXKmfzdjabuEW4Tirj5lLdR0= github.com/kardianos/minwinsvc v1.0.2/go.mod h1:LUZNYhNmxujx2tR7FbdxqYJ9XDDoCd3MQcl1o//FWl4= @@ -50,10 +50,10 @@ github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3Ro github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg= -github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= -github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= +github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= +github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= +github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -72,8 +72,8 @@ go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mobile v0.0.0-20231006135142-2b44d11868fe h1:lrXv4yHeD9FA8PSJATWowP1QvexpyAPWmPia+Kbzql8= @@ -87,8 +87,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -105,8 +105,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -116,8 +116,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= From 180d7bf499cbdb5d0aa732de02ef1600ab14284a Mon Sep 17 00:00:00 2001 From: Neil Date: Mon, 15 Jan 2024 23:09:07 +0000 Subject: [PATCH 037/125] Adjust default backoff max to just over 1 hour, add `?maxbackoff=` peer option (#1124) Co-authored-by: Neil Alexander --- src/core/link.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index 09f815c2..08a6a99e 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "fmt" "io" - "math" "net" "net/netip" "net/url" @@ -28,6 +27,9 @@ const ( linkTypeIncoming // Incoming connection ) +const defaultBackoffLimit = time.Second << 12 // 1h8m16s +const minimumBackoffLimit = time.Second * 30 + type links struct { phony.Inbox core *Core @@ -69,6 +71,7 @@ type linkOptions struct { priority uint8 tlsSNI string password []byte + maxBackoff time.Duration } type Listener struct { @@ -136,6 +139,7 @@ const ErrLinkPriorityInvalid = linkError("priority value is invalid") const ErrLinkPinnedKeyInvalid = linkError("pinned public key is invalid") const ErrLinkPasswordInvalid = linkError("password is invalid") const ErrLinkUnrecognisedSchema = linkError("link schema unknown") +const ErrLinkMaxBackoffInvalid = linkError("max backoff duration invalid") func (l *links) add(u *url.URL, sintf string, linkType linkType) error { var retErr error @@ -150,7 +154,9 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { // Collect together the link options, these are global options // that are not specific to any given protocol. - var options linkOptions + options := linkOptions{ + maxBackoff: defaultBackoffLimit, + } for _, pubkey := range u.Query()["key"] { sigPub, err := hex.DecodeString(pubkey) if err != nil { @@ -179,6 +185,14 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { } options.password = []byte(p) } + if p := u.Query().Get("maxbackoff"); p != "" { + d, err := time.ParseDuration(p) + if err != nil || d < minimumBackoffLimit { + retErr = ErrLinkMaxBackoffInvalid + return + } + options.maxBackoff = d + } // SNI headers must contain hostnames and not IP addresses, so we must make sure // that we do not populate the SNI with an IP literal. We do this by splitting // the host-port combo from the query option and then seeing if it parses to an @@ -235,10 +249,13 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { // The caller should check the return value to decide whether // or not to give up trying. backoffNow := func() bool { - if backoff < 14 { // Cap at roughly 4.5 hours maximum. + if backoff < 32 { backoff++ } - duration := time.Second * time.Duration(math.Exp2(float64(backoff))) + duration := time.Second << backoff + if duration > options.maxBackoff { + duration = options.maxBackoff + } select { case <-state.kick: return true From 81f2c711b484d05fbbab2394dd8860700294cbf2 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 15 Jan 2024 23:14:43 +0000 Subject: [PATCH 038/125] Fix panic in `getPeers` on abstract UNIX socket names Fixes #1111 --- cmd/yggdrasilctl/main.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 8f99e0d2..db823417 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -183,13 +183,13 @@ func run() int { if peer.Inbound { dir = "In" } - uri, err := url.Parse(peer.URI) - if err != nil { - panic(err) + uristring := peer.URI + if uri, err := url.Parse(peer.URI); err == nil { + uri.RawQuery = "" + uristring = uri.String() } - uri.RawQuery = "" table.Append([]string{ - uri.String(), + uristring, state, dir, peer.IPAddress, From 2c20a043692a5f54f67480971830aa56c4d3de03 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 27 Jan 2024 22:54:54 +0000 Subject: [PATCH 039/125] Release: Yggdrasil 0.5.5 --- CHANGELOG.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2715486..aa3fd33e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.5] - 2024-01-27 + +### Added + +* A new peer option `?maxbackoff=X` has been added to control the maximum backoff time for a given peer, supports duration values like `5m`, `1h` etc + +### Changed + +* The maximum backoff period for failing peer connections has been reduced to just over 1 hour, compared to 4.5 hours before +* The `getPeers` endpoint now sorts peers in a more stable fashion +* Upgrade dependencies + +### Fixed + +* A bug where QUIC listeners could stop listening for incoming connections unexpectedly has been fixed +* The priority tiebreak between multiple peerings to the same node has been fixed +* Peer connection ordering is no longer sensitive to poor system time resolution +* The admin socket now verifies the length of input public keys +* The `PPROFLISTEN` environment variable has been fixed and now starts the pprof listener correctly +* A panic in `getPeers` has been fixed when using abstract UNIX sockets on Linux + ## [0.5.4] - 2023-11-27 ### Fixed From 2d644eabc38ff4b3ebc0556315f97fdab30d7ec2 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 21 Mar 2024 21:33:07 -0500 Subject: [PATCH 040/125] update ironwood (updates bloom dependency) --- go.mod | 6 +++--- go.sum | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index f3b63daf..cf717d15 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20240115190409-ddd1fa67c018 + github.com/Arceliar/ironwood v0.0.0-20240321132619-86dcce58a105 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 @@ -22,8 +22,8 @@ require ( ) require ( - github.com/bits-and-blooms/bitset v1.5.0 // indirect - github.com/bits-and-blooms/bloom/v3 v3.3.1 // indirect + github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/bits-and-blooms/bloom/v3 v3.7.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/mattn/go-colorable v0.1.13 // indirect diff --git a/go.sum b/go.sum index 6cd0ab72..c1fa1adc 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,13 @@ -github.com/Arceliar/ironwood v0.0.0-20240115190409-ddd1fa67c018 h1:7r/T7qJht4CaPl74AgU7dG5N6g7+2230/9BhrbtRijk= -github.com/Arceliar/ironwood v0.0.0-20240115190409-ddd1fa67c018/go.mod h1:5x7fWW0mshe9WQ1lvSMmmHBYC3BeHH9gpwW5tz7cbfw= +github.com/Arceliar/ironwood v0.0.0-20240321132619-86dcce58a105 h1:H7OQD74Pd7FVA7i6rOIun8rzKY8uhJf7hAV02N/L17M= +github.com/Arceliar/ironwood v0.0.0-20240321132619-86dcce58a105/go.mod h1:U5njW14T0/EAvTtVdNpRDUaWsbtcaQmZjHHmUUH43B8= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= -github.com/bits-and-blooms/bitset v1.3.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= -github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bloom/v3 v3.3.1 h1:K2+A19bXT8gJR5mU7y+1yW6hsKfNCjcP2uNfLFKncjQ= -github.com/bits-and-blooms/bloom/v3 v3.3.1/go.mod h1:bhUUknWd5khVbTe4UgMCSiOOVJzr3tMoijSK3WwvW90= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bloom/v3 v3.7.0 h1:VfknkqV4xI+PsaDIsoHueyxVDZrfvMn56jeWUzvzdls= +github.com/bits-and-blooms/bloom/v3 v3.7.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg= github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo= github.com/cheggaaa/pb/v3 v3.1.4/go.mod h1:6wVjILNBaXMs8c21qRiaUM8BR82erfgau1DQ4iUXmSA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= From 6cbe56adfe43a9d95781f110611c4188b34b34c8 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 25 May 2024 06:15:36 -0500 Subject: [PATCH 041/125] fix incorrect pool use --- src/core/core.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.go b/src/core/core.go index 79c59d5d..41858cb1 100644 --- a/src/core/core.go +++ b/src/core/core.go @@ -212,7 +212,7 @@ func (c *Core) ReadFrom(p []byte) (n int, from net.Addr, err error) { func (c *Core) WriteTo(p []byte, addr net.Addr) (n int, err error) { buf := allocBytes(0) - defer freeBytes(buf) + defer func() { freeBytes(buf) }() buf = append(buf, typeSessionTraffic) buf = append(buf, p...) n, err = c.PacketConn.WriteTo(buf, addr) From 6f3a0a71d43c8f25cf8d34346e5e3948fe4221ef Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 25 May 2024 06:16:11 -0500 Subject: [PATCH 042/125] update ironwood and other dependencies --- go.mod | 12 ++++++------ go.sum | 33 +++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index cf717d15..c4847dff 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.20 require ( - github.com/Arceliar/ironwood v0.0.0-20240321132619-86dcce58a105 + github.com/Arceliar/ironwood v0.0.0-20240525111224-8b482710326e github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 @@ -12,17 +12,17 @@ require ( github.com/kardianos/minwinsvc v1.0.2 github.com/quic-go/quic-go v0.40.1 github.com/vishvananda/netlink v1.1.0 - golang.org/x/crypto v0.18.0 + golang.org/x/crypto v0.23.0 golang.org/x/mobile v0.0.0-20231006135142-2b44d11868fe - golang.org/x/net v0.20.0 - golang.org/x/sys v0.16.0 - golang.org/x/text v0.14.0 + golang.org/x/net v0.21.0 + golang.org/x/sys v0.20.0 + golang.org/x/text v0.15.0 golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 golang.zx2c4.com/wireguard/windows v0.5.3 ) require ( - github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/bits-and-blooms/bloom/v3 v3.7.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect diff --git a/go.sum b/go.sum index c1fa1adc..8afa93f3 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,12 @@ -github.com/Arceliar/ironwood v0.0.0-20240321132619-86dcce58a105 h1:H7OQD74Pd7FVA7i6rOIun8rzKY8uhJf7hAV02N/L17M= -github.com/Arceliar/ironwood v0.0.0-20240321132619-86dcce58a105/go.mod h1:U5njW14T0/EAvTtVdNpRDUaWsbtcaQmZjHHmUUH43B8= +github.com/Arceliar/ironwood v0.0.0-20240525111224-8b482710326e h1:fBcasrsrE1kVlsAlyG7Rz5/wvGFKHO4z3GfHzEc0xwE= +github.com/Arceliar/ironwood v0.0.0-20240525111224-8b482710326e/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= -github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bits-and-blooms/bloom/v3 v3.7.0 h1:VfknkqV4xI+PsaDIsoHueyxVDZrfvMn56jeWUzvzdls= github.com/bits-and-blooms/bloom/v3 v3.7.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg= github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo= @@ -70,9 +71,9 @@ go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mobile v0.0.0-20231006135142-2b44d11868fe h1:lrXv4yHeD9FA8PSJATWowP1QvexpyAPWmPia+Kbzql8= @@ -85,9 +86,9 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -103,20 +104,24 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= From 5da1fbe39748a6e057c1eef02fb4eb6b124840b7 Mon Sep 17 00:00:00 2001 From: trashpile-shenanigans Date: Mon, 27 May 2024 23:53:52 +0300 Subject: [PATCH 043/125] Bump minimum required go version to 1.20 in documentation as required by quic-go dependency (#1138) --- CHANGELOG.md | 2 +- README.md | 2 +- contrib/msi/build-msi.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa3fd33e..6e663441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -189,7 +189,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed -* Go 1.17 is now required to build Yggdrasil +* Go 1.20 is now required to build Yggdrasil ## [0.4.3] - 2022-02-06 diff --git a/README.md b/README.md index d0afae47..527c6c2d 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ or tools in the `contrib` folder. If you want to build from source, as opposed to installing one of the pre-built packages: -1. Install [Go](https://golang.org) (requires Go 1.17 or later) +1. Install [Go](https://golang.org) (requires Go 1.20 or later) 2. Clone this repository 2. Run `./build` diff --git a/contrib/msi/build-msi.sh b/contrib/msi/build-msi.sh index 38b9b810..94d57147 100644 --- a/contrib/msi/build-msi.sh +++ b/contrib/msi/build-msi.sh @@ -1,7 +1,7 @@ #!/bin/sh # This script generates an MSI file for Yggdrasil for a given architecture. It -# needs to run on Windows within MSYS2 and Go 1.17 or later must be installed on +# needs to run on Windows within MSYS2 and Go 1.20 or later must be installed on # the system and within the PATH. This is ran currently by GitHub Actions (see # the workflows in the repository). # From f56f9c124ca5aec0b7d51ec2a37e5a5ba554dce0 Mon Sep 17 00:00:00 2001 From: Paul Donald Date: Mon, 27 May 2024 22:57:28 +0200 Subject: [PATCH 044/125] Minor Fixes (#1107) * Minor comment fixes. * Optimize PeerEntry for memory efficiency * Improve NodeConfig for memory alignment --- cmd/yggdrasil/main.go | 8 ++++---- contrib/mobile/mobile.go | 4 ++-- src/admin/getpeers.go | 2 +- src/config/config.go | 2 +- src/core/link.go | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index a1c79492..82b85cd4 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -188,7 +188,7 @@ func main() { n := &node{} - // Setup the Yggdrasil node itself. + // Set up the Yggdrasil node itself. { options := []core.SetupOption{ core.NodeInfo(cfg.NodeInfo), @@ -221,7 +221,7 @@ func main() { logger.Printf("Your IPv6 subnet is %s", subnet.String()) } - // Setup the admin socket. + // Set up the admin socket. { options := []admin.SetupOption{ admin.ListenAddress(cfg.AdminListen), @@ -237,7 +237,7 @@ func main() { } } - // Setup the multicast module. + // Set up the multicast module. { options := []multicast.SetupOption{} for _, intf := range cfg.MulticastInterfaces { @@ -258,7 +258,7 @@ func main() { } } - // Setup the TUN module. + // Set up the TUN module. { options := []tun.SetupOption{ tun.InterfaceName(cfg.IfName), diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index cf026a70..82e73485 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -53,7 +53,7 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error { if err := m.config.UnmarshalHJSON(configjson); err != nil { return err } - // Setup the Yggdrasil node itself. + // Set up the Yggdrasil node itself. { options := []core.SetupOption{} for _, peer := range m.config.Peers { @@ -85,7 +85,7 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error { logger.Infof("Your IPv6 subnet is %s", subnet.String()) } - // Setup the multicast module. + // Set up the multicast module. if len(m.config.MulticastInterfaces) > 0 { var err error logger.Infof("Initializing multicast %s", "") diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index 9bc3872f..aad98294 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -27,8 +27,8 @@ type PeerEntry struct { RXBytes DataUnit `json:"bytes_recvd,omitempty"` TXBytes DataUnit `json:"bytes_sent,omitempty"` Uptime float64 `json:"uptime,omitempty"` - LastError string `json:"last_error,omitempty"` LastErrorTime time.Duration `json:"last_error_time,omitempty"` + LastError string `json:"last_error,omitempty"` } func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersResponse) error { diff --git a/src/config/config.go b/src/config/config.go index aac51467..9a7f7180 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -51,9 +51,9 @@ type NodeConfig struct { AllowedPublicKeys []string `comment:"List of peer public keys to allow incoming peering connections\nfrom. If left empty/undefined then all connections will be allowed\nby default. This does not affect outgoing peerings, nor does it\naffect link-local peers discovered via multicast."` IfName string `comment:"Local network interface name for TUN adapter, or \"auto\" to select\nan interface automatically, or \"none\" to run without TUN."` IfMTU uint64 `comment:"Maximum Transmission Unit (MTU) size for your local TUN interface.\nDefault is the largest supported size for your platform. The lowest\npossible value is 1280."` + LogLookups bool `json:",omitempty"` NodeInfoPrivacy bool `comment:"By default, nodeinfo contains some defaults including the platform,\narchitecture and Yggdrasil version. These can help when surveying\nthe network and diagnosing network routing problems. Enabling\nnodeinfo privacy prevents this, so that only items specified in\n\"NodeInfo\" are sent back if specified."` NodeInfo map[string]interface{} `comment:"Optional node info. This must be a { \"key\": \"value\", ... } map\nor set as null. This is entirely optional but, if set, is visible\nto the whole network on request."` - LogLookups bool `json:",omitempty"` } type MulticastInterfaceConfig struct { diff --git a/src/core/link.go b/src/core/link.go index 08a6a99e..6bcbec59 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -63,7 +63,7 @@ type link struct { // The remaining fields can only be modified safely from within the links actor _conn *linkConn // Connected link, if any, nil if not connected _err error // Last error on the connection, if any - _errtime time.Time // Last time an error occured + _errtime time.Time // Last time an error occurred } type linkOptions struct { From 5d9c5b3c9b2f51d6a5076a50624146513ac41ece Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 27 May 2024 22:03:41 +0100 Subject: [PATCH 045/125] Minimum Go 1.21, update `quic-go`, update some CI actions --- .github/workflows/ci.yml | 18 ++++++++--------- .github/workflows/pkg.yml | 16 +++++++-------- README.md | 2 +- contrib/msi/build-msi.sh | 2 +- go.mod | 18 ++++++++--------- go.sum | 42 +++++++++++++++++++++++---------------- 6 files changed, 53 insertions(+), 45 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92ad2561..356b49de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v5 with: go-version: 1.21 - uses: actions/checkout@v3 @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.20", "1.21"] + goversion: ["1.21", "1.22"] name: Build & Test (Linux, Go ${{ matrix.goversion }}) needs: [lint] @@ -61,7 +61,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.goversion }} @@ -75,7 +75,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.20", "1.21"] + goversion: ["1.21", "1.22"] name: Build & Test (Windows, Go ${{ matrix.goversion }}) needs: [lint] @@ -85,7 +85,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.goversion }} @@ -99,7 +99,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.20", "1.21"] + goversion: ["1.21", "1.22"] name: Build & Test (macOS, Go ${{ matrix.goversion }}) needs: [lint] @@ -109,7 +109,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.goversion }} @@ -123,7 +123,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.20", "1.21"] + goversion: ["1.21", "1.22"] goos: - freebsd - openbsd @@ -136,7 +136,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.goversion }} diff --git a/.github/workflows/pkg.yml b/.github/workflows/pkg.yml index f47baa0f..a3ccfe43 100644 --- a/.github/workflows/pkg.yml +++ b/.github/workflows/pkg.yml @@ -23,9 +23,9 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "stable" - name: Build package env: @@ -54,9 +54,9 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "stable" - name: Build package env: @@ -85,9 +85,9 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "stable" - name: Build package run: sh contrib/msi/build-msi.sh ${{ matrix.pkgarch }} @@ -120,9 +120,9 @@ jobs: path: vyatta-yggdrasil - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "stable" - name: Build package env: diff --git a/README.md b/README.md index 527c6c2d..8449f073 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ or tools in the `contrib` folder. If you want to build from source, as opposed to installing one of the pre-built packages: -1. Install [Go](https://golang.org) (requires Go 1.20 or later) +1. Install [Go](https://golang.org) (requires Go 1.21 or later) 2. Clone this repository 2. Run `./build` diff --git a/contrib/msi/build-msi.sh b/contrib/msi/build-msi.sh index 94d57147..3c37393e 100644 --- a/contrib/msi/build-msi.sh +++ b/contrib/msi/build-msi.sh @@ -1,7 +1,7 @@ #!/bin/sh # This script generates an MSI file for Yggdrasil for a given architecture. It -# needs to run on Windows within MSYS2 and Go 1.20 or later must be installed on +# needs to run on Windows within MSYS2 and Go 1.21 or later must be installed on # the system and within the PATH. This is ran currently by GitHub Actions (see # the workflows in the repository). # diff --git a/go.mod b/go.mod index c4847dff..7b3b7cc9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/yggdrasil-network/yggdrasil-go -go 1.20 +go 1.21 require ( github.com/Arceliar/ironwood v0.0.0-20240525111224-8b482710326e @@ -10,11 +10,11 @@ require ( github.com/hashicorp/go-syslog v1.0.0 github.com/hjson/hjson-go/v4 v4.4.0 github.com/kardianos/minwinsvc v1.0.2 - github.com/quic-go/quic-go v0.40.1 + github.com/quic-go/quic-go v0.44.0 github.com/vishvananda/netlink v1.1.0 golang.org/x/crypto v0.23.0 - golang.org/x/mobile v0.0.0-20231006135142-2b44d11868fe - golang.org/x/net v0.21.0 + golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b + golang.org/x/net v0.25.0 golang.org/x/sys v0.20.0 golang.org/x/text v0.15.0 golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 @@ -28,12 +28,12 @@ require ( github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/onsi/ginkgo/v2 v2.9.5 // indirect - github.com/quic-go/qtls-go1-20 v0.4.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect - go.uber.org/mock v0.3.0 // indirect - golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/tools v0.14.0 // indirect + go.uber.org/mock v0.4.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/tools v0.21.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect ) diff --git a/go.sum b/go.sum index 8afa93f3..137b5b8c 100644 --- a/go.sum +++ b/go.sum @@ -20,12 +20,15 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gologme/log v1.3.0 h1:l781G4dE+pbigClDSDzSaaYKtiueHCILUa/qSDsmHAo= github.com/gologme/log v1.3.0/go.mod h1:yKT+DvIPdDdDoPtqFrFxheooyVmoqi0BAsw+erN3wA4= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= @@ -48,12 +51,11 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= -github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= -github.com/quic-go/quic-go v0.40.1/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c= +github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= +github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -67,32 +69,34 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo= -go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/mobile v0.0.0-20231006135142-2b44d11868fe h1:lrXv4yHeD9FA8PSJATWowP1QvexpyAPWmPia+Kbzql8= -golang.org/x/mobile v0.0.0-20231006135142-2b44d11868fe/go.mod h1:BrnXpEObnFxpaT75Jo9hsCazwOWcp7nVIa8NNuH5cuA= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b h1:WX7nnnLfCEXg+FmdYZPai2XuP3VqCP1HZVMST0n9DF0= +golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b/go.mod h1:EiXZlVfUTaAyySFVJb9rsODuiO+WXu8HrUuySb7nYFw= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -122,12 +126,14 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= @@ -136,6 +142,8 @@ golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675/go.mod h1:whfbyDBt golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From c2811c0cdc348a5575580d75d03cd8576f9060fb Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 27 May 2024 22:14:28 +0100 Subject: [PATCH 046/125] Update more GHA actions due to deprecations --- .github/workflows/ci.yml | 12 ++++++------ .github/workflows/pkg.yml | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 356b49de..a3f34789 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/setup-go@v5 with: go-version: 1.21 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v2 @@ -58,7 +58,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 @@ -82,7 +82,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 @@ -106,7 +106,7 @@ jobs: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 @@ -133,7 +133,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 diff --git a/.github/workflows/pkg.yml b/.github/workflows/pkg.yml index a3ccfe43..c0045221 100644 --- a/.github/workflows/pkg.yml +++ b/.github/workflows/pkg.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -33,7 +33,7 @@ jobs: run: sh contrib/deb/generate.sh - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Debian package (${{ matrix.pkgarch }}) path: "*.deb" @@ -49,7 +49,7 @@ jobs: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -64,7 +64,7 @@ jobs: run: sh contrib/macos/create-pkg.sh - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: macOS package (${{ matrix.pkgarch }}) path: "*.pkg" @@ -80,7 +80,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -93,7 +93,7 @@ jobs: run: sh contrib/msi/build-msi.sh ${{ matrix.pkgarch }} - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Windows package (${{ matrix.pkgarch }}) path: "*.msi" @@ -109,12 +109,12 @@ jobs: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 path: yggdrasil - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: neilalexander/vyatta-yggdrasil path: vyatta-yggdrasil @@ -130,7 +130,7 @@ jobs: run: cd /home/runner/work/yggdrasil-go/yggdrasil-go/vyatta-yggdrasil && ./build-${{ matrix.pkgarch }} - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Router package (${{ matrix.pkgarch }}) path: "/home/runner/work/yggdrasil-go/yggdrasil-go/vyatta-yggdrasil/*.deb" From 2831d73f73c273baf773a8b841bd425483c9d42a Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 27 May 2024 22:52:48 +0100 Subject: [PATCH 047/125] Try to fix WiX for Windows MSI builds --- .github/workflows/pkg.yml | 3 +++ contrib/msi/build-msi.sh | 26 +++++++++----------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/.github/workflows/pkg.yml b/.github/workflows/pkg.yml index c0045221..1484618e 100644 --- a/.github/workflows/pkg.yml +++ b/.github/workflows/pkg.yml @@ -89,6 +89,9 @@ jobs: with: go-version: "stable" + - name: Setup .NET Core SDK + uses: actions/setup-dotnet@v4 + - name: Build package run: sh contrib/msi/build-msi.sh ${{ matrix.pkgarch }} diff --git a/contrib/msi/build-msi.sh b/contrib/msi/build-msi.sh index 3c37393e..857aeec9 100644 --- a/contrib/msi/build-msi.sh +++ b/contrib/msi/build-msi.sh @@ -16,20 +16,7 @@ then fi # Download the wix tools! -if [ ! -d wixbin ]; -then - curl -LO https://wixtoolset.org/downloads/v3.14.0.3910/wix314-binaries.zip - if [ `md5sum wix314-binaries.zip | cut -f 1 -d " "` != "34f655cf108086838dd5a76d4318063b" ]; - then - echo "wix package didn't match expected checksum" - exit 1 - fi - mkdir -p wixbin - unzip -o wix314-binaries.zip -d wixbin || ( - echo "failed to unzip WiX" - exit 1 - ) -fi +dotnet tool install --global wix --version 5.0.0 # Build Yggdrasil! [ "${PKGARCH}" == "x64" ] && GOOS=windows GOARCH=amd64 CGO_ENABLED=0 ./build @@ -61,6 +48,11 @@ PKGVERSIONMS=$(echo $PKGVERSION | tr - .) if [ ! -d wintun ]; then curl -o wintun.zip https://www.wintun.net/builds/wintun-0.14.1.zip + if [ `sha256sum wintun.zip | cut -f 1 -d " "` != "07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51" ]; + then + echo "wintun package didn't match expected checksum" + exit 1 + fi unzip wintun.zip fi if [ $PKGARCH = "x64" ]; then @@ -101,7 +93,7 @@ cat > wix.xml << EOF Description="Yggdrasil Network Installer" Comments="Yggdrasil Network standalone router for Windows." Manufacturer="github.com/yggdrasil-network" - InstallerVersion="200" + InstallerVersion="500" InstallScope="perMachine" Languages="1033" Compressed="yes" @@ -205,5 +197,5 @@ EOF # Generate the MSI CANDLEFLAGS="-nologo" LIGHTFLAGS="-nologo -spdb -sice:ICE71 -sice:ICE61" -wixbin/candle $CANDLEFLAGS -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj -arch ${PKGARCH} wix.xml && \ -wixbin/light $LIGHTFLAGS -ext WixUtilExtension.dll -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj +candle $CANDLEFLAGS -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj -arch ${PKGARCH} wix.xml && \ +light $LIGHTFLAGS -ext WixUtilExtension.dll -out ${PKGNAME}-${PKGVERSION}-${PKGARCH}.msi ${PKGNAME}-${PKGVERSION}-${PKGARCH}.wixobj From fcefb20993c51e06c140e922b61d7a9286c977b1 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 28 May 2024 10:03:48 +0100 Subject: [PATCH 048/125] Fix interval check when sending multicast beacons --- src/multicast/multicast.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index 741c4315..bf10370f 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -358,6 +358,7 @@ func (m *Multicast) _announce() { if linfo.interval.Seconds() < 15 { linfo.interval += time.Second } + linfo.time = time.Now() break } } From f788a18befe25579d9406f51a2d22cc1a1a26d26 Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 30 May 2024 22:46:06 +0100 Subject: [PATCH 049/125] Measure RTT, report in `getPeers` (#1143) Co-authored-by: Neil Alexander --- cmd/yggdrasilctl/main.go | 7 +++++-- go.mod | 2 +- go.sum | 4 ++-- src/admin/getpeers.go | 4 ++++ src/core/api.go | 2 ++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index db823417..2a1d70b1 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -174,11 +174,13 @@ func run() int { if err := json.Unmarshal(recv.Response, &resp); err != nil { panic(err) } - table.SetHeader([]string{"URI", "State", "Dir", "IP Address", "Uptime", "RX", "TX", "Pr", "Last Error"}) + table.SetHeader([]string{"URI", "State", "Dir", "IP Address", "Uptime", "RTT", "RX", "TX", "Pr", "Last Error"}) for _, peer := range resp.Peers { - state, lasterr, dir := "Up", "-", "Out" + state, lasterr, dir, rtt := "Up", "-", "Out", "-" if !peer.Up { state, lasterr = "Down", fmt.Sprintf("%s ago: %s", peer.LastErrorTime.Round(time.Second), peer.LastError) + } else if rttms := float64(peer.Latency.Microseconds()) / 1000; rttms > 0 { + rtt = fmt.Sprintf("%.02fms", rttms) } if peer.Inbound { dir = "In" @@ -194,6 +196,7 @@ func run() int { dir, peer.IPAddress, (time.Duration(peer.Uptime) * time.Second).String(), + rtt, peer.RXBytes.String(), peer.TXBytes.String(), fmt.Sprintf("%d", peer.Priority), diff --git a/go.mod b/go.mod index 7b3b7cc9..3dd8c848 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20240525111224-8b482710326e + github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.4 github.com/gologme/log v1.3.0 diff --git a/go.sum b/go.sum index 137b5b8c..7ee76861 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20240525111224-8b482710326e h1:fBcasrsrE1kVlsAlyG7Rz5/wvGFKHO4z3GfHzEc0xwE= -github.com/Arceliar/ironwood v0.0.0-20240525111224-8b482710326e/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= +github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2 h1:SBdYBKeXYUUFef5wi2CMhYmXFVGiYaRpTvbki0Bu+JQ= +github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index aad98294..f79877ca 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -27,6 +27,7 @@ type PeerEntry struct { RXBytes DataUnit `json:"bytes_recvd,omitempty"` TXBytes DataUnit `json:"bytes_sent,omitempty"` Uptime float64 `json:"uptime,omitempty"` + Latency time.Duration `json:"latency_ms,omitempty"` LastErrorTime time.Duration `json:"last_error_time,omitempty"` LastError string `json:"last_error,omitempty"` } @@ -45,6 +46,9 @@ func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersRespons TXBytes: DataUnit(p.TXBytes), Uptime: p.Uptime.Seconds(), } + if p.Latency > 0 { + peer.Latency = p.Latency + } if addr := address.AddrForKey(p.Key); addr != nil { peer.PublicKey = hex.EncodeToString(p.Key) peer.IPAddress = net.IP(addr[:]).String() diff --git a/src/core/api.go b/src/core/api.go index b5fa93cb..875d7bf2 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -33,6 +33,7 @@ type PeerInfo struct { RXBytes uint64 TXBytes uint64 Uptime time.Duration + Latency time.Duration } type TreeEntryInfo struct { @@ -92,6 +93,7 @@ func (c *Core) GetPeers() []PeerInfo { peerinfo.Root = p.Root peerinfo.Port = p.Port peerinfo.Priority = p.Priority + peerinfo.Latency = p.Latency } peers = append(peers, peerinfo) } From fec96a38a423142ac1712eb63ad7651c5e7a82aa Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 30 May 2024 23:30:05 +0100 Subject: [PATCH 050/125] Release: Yggdrasil v0.5.6 (#1144) * Changelog updates for Yggdrasil v0.5.6 * Fix spelling error --------- Co-authored-by: Neil Alexander Co-authored-by: Arceliar --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e663441..b339294c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,26 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.6] - 2024-05-30 + +* Go 1.21 is now required to build Yggdrasil + +### Added + +* The `getPeers` endpoint now reports the RTT/latency of directly connected peers + +### Changed + +* The tree parent selection algorithm now prefers the lowest latency peers instead of the most stable +* Session key exchange logic has been changed to improve throughput and reduce occasional jitter + +### Fixed + +* Bloom filter hashing now works correctly on big-endian architectures +* Incorrect buffer pool usage has been fixed, reducing memory allocations +* The multicast beacon interval now backs off correctly, reducing the number of beacons sent +* A denial-of-service vulnerability in the QUIC library has been fixed with a dependency update + ## [0.5.5] - 2024-01-27 ### Added From c505097be077ee2af02ce37a9f73e2efa08feeb7 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 26 Jun 2024 23:17:11 +0100 Subject: [PATCH 051/125] Update mobile build for iOS/macOS framework generation --- contrib/mobile/{mobile_ios.go => mobile_apple.go} | 4 ++-- contrib/mobile/mobile_other.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename contrib/mobile/{mobile_ios.go => mobile_apple.go} (94%) diff --git a/contrib/mobile/mobile_ios.go b/contrib/mobile/mobile_apple.go similarity index 94% rename from contrib/mobile/mobile_ios.go rename to contrib/mobile/mobile_apple.go index c7747ea3..2c53fa94 100644 --- a/contrib/mobile/mobile_ios.go +++ b/contrib/mobile/mobile_apple.go @@ -1,5 +1,5 @@ -//go:build ios -// +build ios +//go:build ios || darwin +// +build ios darwin package mobile diff --git a/contrib/mobile/mobile_other.go b/contrib/mobile/mobile_other.go index aceeb7e2..10804b3e 100644 --- a/contrib/mobile/mobile_other.go +++ b/contrib/mobile/mobile_other.go @@ -1,5 +1,5 @@ -//go:build !android && !ios -// +build !android,!ios +//go:build !android && !ios && !darwin +// +build !android,!ios,!darwin package mobile From 8ecc402d7c48da048cf700f5c6028737a14abfad Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 20 Jul 2024 11:31:08 +0100 Subject: [PATCH 052/125] Allow multiple connections to the same link-local address Note that this may mean that currently we end up with two links to each multicast-discovered peer, one incoming and one outgoing --- src/core/link.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index 6bcbec59..fb780040 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -7,7 +7,6 @@ import ( "fmt" "io" "net" - "net/netip" "net/url" "strconv" "strings" @@ -641,16 +640,6 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, s func urlForLinkInfo(u url.URL) url.URL { u.RawQuery = "" - if host, _, err := net.SplitHostPort(u.Host); err == nil { - if addr, err := netip.ParseAddr(host); err == nil { - // For peers that look like multicast peers (i.e. - // link-local addresses), we will ignore the port number, - // otherwise we might open multiple connections to them. - if addr.IsLinkLocalUnicast() { - u.Host = fmt.Sprintf("[%s]", addr.String()) - } - } - } return u } From 04c0acf71b8e21679f9b68e8145e9c3094da59ff Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 20 Jul 2024 12:31:58 +0100 Subject: [PATCH 053/125] Various clean-ups --- src/admin/addpeer.go | 2 +- src/admin/admin.go | 22 ---------------------- src/admin/getpaths.go | 2 +- src/admin/getpeers.go | 2 +- src/admin/getself.go | 2 +- src/admin/getsessions.go | 2 +- src/admin/gettree.go | 6 +----- src/admin/removepeer.go | 2 +- src/core/link.go | 4 ++-- src/core/link_tcp_darwin.go | 2 +- src/multicast/admin.go | 2 +- 11 files changed, 11 insertions(+), 37 deletions(-) diff --git a/src/admin/addpeer.go b/src/admin/addpeer.go index 843ed52a..a897e45e 100644 --- a/src/admin/addpeer.go +++ b/src/admin/addpeer.go @@ -12,7 +12,7 @@ type AddPeerRequest struct { type AddPeerResponse struct{} -func (a *AdminSocket) addPeerHandler(req *AddPeerRequest, res *AddPeerResponse) error { +func (a *AdminSocket) addPeerHandler(req *AddPeerRequest, _ *AddPeerResponse) error { u, err := url.Parse(req.Uri) if err != nil { return fmt.Errorf("unable to parse peering URI: %w", err) diff --git a/src/admin/admin.go b/src/admin/admin.go index 8fa76c07..7cca1bbb 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -201,10 +201,6 @@ func (a *AdminSocket) SetupAdminHandlers() { return res, nil }, ) - //_ = a.AddHandler("getNodeInfo", []string{"key"}, t.proto.nodeinfo.nodeInfoAdminHandler) - //_ = a.AddHandler("debug_remoteGetSelf", []string{"key"}, t.proto.getSelfHandler) - //_ = a.AddHandler("debug_remoteGetPeers", []string{"key"}, t.proto.getPeersHandler) - //_ = a.AddHandler("debug_remoteGetDHT", []string{"key"}, t.proto.getDHTHandler) } // IsStarted returns true if the module has been started. @@ -269,7 +265,6 @@ func (a *AdminSocket) listen() { case "tcp": a.listener, err = net.Listen("tcp", u.Host) default: - // err = errors.New(fmt.Sprint("protocol not supported: ", u.Scheme)) a.listener, err = net.Listen("tcp", listenaddr) } } else { @@ -309,23 +304,6 @@ func (a *AdminSocket) handleRequest(conn net.Conn) { defer conn.Close() - /* - defer func() { - r := recover() - if r != nil { - fmt.Println("ERROR:", r) - a.log.Debugln("Admin socket error:", r) - if err := encoder.Encode(&ErrorResponse{ - Error: "Check your syntax and input types", - }); err != nil { - fmt.Println("ERROR 2:", err) - a.log.Debugln("Admin socket JSON encode error:", err) - } - conn.Close() - } - }() - */ - for { var err error var buf json.RawMessage diff --git a/src/admin/getpaths.go b/src/admin/getpaths.go index 66e11bd2..34de4532 100644 --- a/src/admin/getpaths.go +++ b/src/admin/getpaths.go @@ -23,7 +23,7 @@ type PathEntry struct { Sequence uint64 `json:"sequence"` } -func (a *AdminSocket) getPathsHandler(req *GetPathsRequest, res *GetPathsResponse) error { +func (a *AdminSocket) getPathsHandler(_ *GetPathsRequest, res *GetPathsResponse) error { paths := a.core.GetPaths() res.Paths = make([]PathEntry, 0, len(paths)) for _, p := range paths { diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index f79877ca..e44428c3 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -32,7 +32,7 @@ type PeerEntry struct { LastError string `json:"last_error,omitempty"` } -func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersResponse) error { +func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse) error { peers := a.core.GetPeers() res.Peers = make([]PeerEntry, 0, len(peers)) for _, p := range peers { diff --git a/src/admin/getself.go b/src/admin/getself.go index 9b052101..b1a01567 100644 --- a/src/admin/getself.go +++ b/src/admin/getself.go @@ -17,7 +17,7 @@ type GetSelfResponse struct { Subnet string `json:"subnet"` } -func (a *AdminSocket) getSelfHandler(req *GetSelfRequest, res *GetSelfResponse) error { +func (a *AdminSocket) getSelfHandler(_ *GetSelfRequest, res *GetSelfResponse) error { self := a.core.GetSelf() snet := a.core.Subnet() res.BuildName = version.BuildName() diff --git a/src/admin/getsessions.go b/src/admin/getsessions.go index 324119d4..e6702f88 100644 --- a/src/admin/getsessions.go +++ b/src/admin/getsessions.go @@ -23,7 +23,7 @@ type SessionEntry struct { Uptime float64 `json:"uptime"` } -func (a *AdminSocket) getSessionsHandler(req *GetSessionsRequest, res *GetSessionsResponse) error { +func (a *AdminSocket) getSessionsHandler(_ *GetSessionsRequest, res *GetSessionsResponse) error { sessions := a.core.GetSessions() res.Sessions = make([]SessionEntry, 0, len(sessions)) for _, s := range sessions { diff --git a/src/admin/gettree.go b/src/admin/gettree.go index 06cf8e73..4b6f32a8 100644 --- a/src/admin/gettree.go +++ b/src/admin/gettree.go @@ -20,11 +20,9 @@ type TreeEntry struct { PublicKey string `json:"key"` Parent string `json:"parent"` Sequence uint64 `json:"sequence"` - //Port uint64 `json:"port"` - //Rest uint64 `json:"rest"` } -func (a *AdminSocket) getTreeHandler(req *GetTreeRequest, res *GetTreeResponse) error { +func (a *AdminSocket) getTreeHandler(_ *GetTreeRequest, res *GetTreeResponse) error { tree := a.core.GetTree() res.Tree = make([]TreeEntry, 0, len(tree)) for _, d := range tree { @@ -34,8 +32,6 @@ func (a *AdminSocket) getTreeHandler(req *GetTreeRequest, res *GetTreeResponse) PublicKey: hex.EncodeToString(d.Key[:]), Parent: hex.EncodeToString(d.Parent[:]), Sequence: d.Sequence, - //Port: d.Port, - //Rest: d.Rest, }) } sort.SliceStable(res.Tree, func(i, j int) bool { diff --git a/src/admin/removepeer.go b/src/admin/removepeer.go index 6b2e162e..6f368656 100644 --- a/src/admin/removepeer.go +++ b/src/admin/removepeer.go @@ -12,7 +12,7 @@ type RemovePeerRequest struct { type RemovePeerResponse struct{} -func (a *AdminSocket) removePeerHandler(req *RemovePeerRequest, res *RemovePeerResponse) error { +func (a *AdminSocket) removePeerHandler(req *RemovePeerRequest, _ *RemovePeerResponse) error { u, err := url.Parse(req.Uri) if err != nil { return fmt.Errorf("unable to parse peering URI: %w", err) diff --git a/src/core/link.go b/src/core/link.go index fb780040..b646605c 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -378,7 +378,7 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { return retErr } -func (l *links) remove(u *url.URL, sintf string, linkType linkType) error { +func (l *links) remove(u *url.URL, sintf string, _ linkType) error { var retErr error phony.Block(l, func() { // Generate the link info and see whether we think we already @@ -566,7 +566,7 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, s switch { case err != nil: return fmt.Errorf("write handshake: %w", err) - case err == nil && n != len(metaBytes): + case n != len(metaBytes): return fmt.Errorf("incomplete handshake send") } meta = version_metadata{} diff --git a/src/core/link_tcp_darwin.go b/src/core/link_tcp_darwin.go index daa51df0..4c19ba93 100644 --- a/src/core/link_tcp_darwin.go +++ b/src/core/link_tcp_darwin.go @@ -28,6 +28,6 @@ func (t *linkTCP) tcpContext(network, address string, c syscall.RawConn) error { } } -func (t *linkTCP) getControl(sintf string) func(string, string, syscall.RawConn) error { +func (t *linkTCP) getControl(_ string) func(string, string, syscall.RawConn) error { return t.tcpContext } diff --git a/src/multicast/admin.go b/src/multicast/admin.go index 9bcc257b..8b29716d 100644 --- a/src/multicast/admin.go +++ b/src/multicast/admin.go @@ -11,7 +11,7 @@ type GetMulticastInterfacesResponse struct { Interfaces []string `json:"multicast_interfaces"` } -func (m *Multicast) getMulticastInterfacesHandler(req *GetMulticastInterfacesRequest, res *GetMulticastInterfacesResponse) error { +func (m *Multicast) getMulticastInterfacesHandler(_ *GetMulticastInterfacesRequest, res *GetMulticastInterfacesResponse) error { res.Interfaces = []string{} for _, v := range m.Interfaces() { res.Interfaces = append(res.Interfaces, v.Name) From 02d92ff81c2dd986323492ef9f6af26a2bab5ec5 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 20 Jul 2024 15:24:30 +0100 Subject: [PATCH 054/125] TUN vectorised reads/writes (#1145) This PR updates the Wireguard dependency and updates to use new vectorised reads/writes, which should reduce the number of syscalls and improve performance. This will only make a difference on Linux as this is the only platform for which the Wireguard TUN library supports vectorised reads/writes. For other platforms, single reads and writes will be performed as usual. --------- Co-authored-by: Neil Alexander --- go.mod | 2 +- go.sum | 8 ++++-- src/tun/iface.go | 56 ++++++++++++++++++++++++++++-------------- src/tun/tun.go | 32 ++++++++++++++++++++++-- src/tun/tun_bsd.go | 3 +++ src/tun/tun_darwin.go | 6 +++++ src/tun/tun_linux.go | 3 +++ src/tun/tun_other.go | 3 +++ src/tun/tun_windows.go | 3 +++ 9 files changed, 92 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index 3dd8c848..eec96260 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/net v0.25.0 golang.org/x/sys v0.20.0 golang.org/x/text v0.15.0 - golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 + golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 ) diff --git a/go.sum b/go.sum index 7ee76861..b7d97986 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,8 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gologme/log v1.3.0 h1:l781G4dE+pbigClDSDzSaaYKtiueHCILUa/qSDsmHAo= github.com/gologme/log v1.3.0/go.mod h1:yKT+DvIPdDdDoPtqFrFxheooyVmoqi0BAsw+erN3wA4= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= @@ -137,8 +139,8 @@ golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= -golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 h1:/J/RVnr7ng4fWPRH3xa4WtBJ1Jp+Auu4YNLmGiPv5QU= -golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675/go.mod h1:whfbyDBt09xhCYQWtO2+3UVjlaq6/9hDZrjg2ZE6SyA= +golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4= +golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA= golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= @@ -147,3 +149,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ= +gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY= diff --git a/src/tun/iface.go b/src/tun/iface.go index e06f3a5d..3a4c55f4 100644 --- a/src/tun/iface.go +++ b/src/tun/iface.go @@ -1,42 +1,60 @@ package tun -const TUN_OFFSET_BYTES = 4 +const TUN_OFFSET_BYTES = 80 // sizeof(virtio_net_hdr) func (tun *TunAdapter) read() { - var buf [TUN_OFFSET_BYTES + 65535]byte + vs := tun.iface.BatchSize() + bufs := make([][]byte, vs) + sizes := make([]int, vs) + for i := range bufs { + bufs[i] = make([]byte, TUN_OFFSET_BYTES+65535) + } for { - n, err := tun.iface.Read(buf[:], TUN_OFFSET_BYTES) - if n <= TUN_OFFSET_BYTES || err != nil { + n, err := tun.iface.Read(bufs, sizes, TUN_OFFSET_BYTES) + if err != nil { tun.log.Errorln("Error reading TUN:", err) - ferr := tun.iface.Flush() - if ferr != nil { - tun.log.Errorln("Unable to flush packets:", ferr) - } return } - begin := TUN_OFFSET_BYTES - end := begin + n - bs := buf[begin:end] - if _, err := tun.rwc.Write(bs); err != nil { - tun.log.Debugln("Unable to send packet:", err) + for i, b := range bufs[:n] { + if _, err := tun.rwc.Write(b[TUN_OFFSET_BYTES : TUN_OFFSET_BYTES+sizes[i]]); err != nil { + tun.log.Debugln("Unable to send packet:", err) + } } } } -func (tun *TunAdapter) write() { - var buf [TUN_OFFSET_BYTES + 65535]byte +func (tun *TunAdapter) queue() { for { - bs := buf[TUN_OFFSET_BYTES:] - n, err := tun.rwc.Read(bs) + p := bufPool.Get().([]byte)[:bufPoolSize] + n, err := tun.rwc.Read(p) if err != nil { tun.log.Errorln("Exiting TUN writer due to core read error:", err) return } + tun.ch <- p[:n] + } +} + +func (tun *TunAdapter) write() { + vs := cap(tun.ch) + bufs := make([][]byte, vs) + for i := range bufs { + bufs[i] = make([]byte, TUN_OFFSET_BYTES+65535) + } + for { + n := len(tun.ch) + if n == 0 { + n = 1 // Nothing queued up yet, wait for it instead + } + for i := 0; i < n; i++ { + msg := <-tun.ch + bufs[i] = append(bufs[i][:TUN_OFFSET_BYTES], msg...) + bufPool.Put(msg) // nolint:staticcheck + } if !tun.isEnabled { continue // Nothing to do, the tun isn't enabled } - bs = buf[:TUN_OFFSET_BYTES+n] - if _, err = tun.iface.Write(bs, TUN_OFFSET_BYTES); err != nil { + if _, err := tun.iface.Write(bufs[:n], TUN_OFFSET_BYTES); err != nil { tun.Act(nil, func() { if !tun.isOpen { tun.log.Errorln("TUN iface write error:", err) diff --git a/src/tun/tun.go b/src/tun/tun.go index 83c82670..e6795c64 100644 --- a/src/tun/tun.go +++ b/src/tun/tun.go @@ -10,9 +10,11 @@ import ( "fmt" "io" "net" + "sync" + "time" "github.com/Arceliar/phony" - "golang.zx2c4.com/wireguard/tun" + wgtun "golang.zx2c4.com/wireguard/tun" "github.com/yggdrasil-network/yggdrasil-go/src/address" "github.com/yggdrasil-network/yggdrasil-go/src/config" @@ -39,7 +41,7 @@ type TunAdapter struct { addr address.Address subnet address.Subnet mtu uint64 - iface tun.Device + iface wgtun.Device phony.Inbox // Currently only used for _handlePacket from the reader, TODO: all the stuff that currently needs a mutex below isOpen bool isEnabled bool // Used by the writer to drop sessionTraffic if not enabled @@ -48,6 +50,7 @@ type TunAdapter struct { name InterfaceName mtu InterfaceMTU } + ch chan []byte } // Gets the maximum supported MTU for the platform based on the defaults in @@ -62,6 +65,20 @@ func getSupportedMTU(mtu uint64) uint64 { return mtu } +func waitForTUNUp(ch <-chan wgtun.Event) bool { + t := time.After(time.Second * 5) + for { + select { + case ev := <-ch: + if ev == wgtun.EventUp { + return true + } + case <-t: + return false + } + } +} + // Name returns the name of the adapter, e.g. "tun0". On Windows, this may // return a canonical adapter name instead. func (tun *TunAdapter) Name() string { @@ -145,6 +162,8 @@ func (tun *TunAdapter) _start() error { tun.rwc.SetMTU(tun.MTU()) tun.isOpen = true tun.isEnabled = true + tun.ch = make(chan []byte, tun.iface.BatchSize()) + go tun.queue() go tun.read() go tun.write() return nil @@ -178,3 +197,12 @@ func (tun *TunAdapter) _stop() error { } return nil } + +const bufPoolSize = TUN_OFFSET_BYTES + 65535 + +var bufPool = sync.Pool{ + New: func() any { + b := [bufPoolSize]byte{} + return b[:] + }, +} diff --git a/src/tun/tun_bsd.go b/src/tun/tun_bsd.go index da5b3297..7f26260c 100644 --- a/src/tun/tun_bsd.go +++ b/src/tun/tun_bsd.go @@ -80,6 +80,9 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if err != nil { return fmt.Errorf("failed to create TUN: %w", err) } + if !waitForTUNUp(iface.Events()) { + return fmt.Errorf("TUN did not come up in time") + } tun.iface = iface if mtu, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(mtu)) diff --git a/src/tun/tun_darwin.go b/src/tun/tun_darwin.go index deeb115e..a9d734bb 100644 --- a/src/tun/tun_darwin.go +++ b/src/tun/tun_darwin.go @@ -27,6 +27,9 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if err != nil { return fmt.Errorf("failed to create TUN: %w", err) } + if !waitForTUNUp(iface.Events()) { + return fmt.Errorf("TUN did not come up in time") + } tun.iface = iface if m, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(m)) @@ -55,6 +58,9 @@ func (tun *TunAdapter) setupFD(fd int32, addr string, mtu uint64) error { unix.Close(dfd) return fmt.Errorf("failed to create TUN from FD: %w", err) } + if !waitForTUNUp(iface.Events()) { + return fmt.Errorf("TUN did not come up in time") + } tun.iface = iface if m, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(m)) diff --git a/src/tun/tun_linux.go b/src/tun/tun_linux.go index 98d63db4..c98cdd73 100644 --- a/src/tun/tun_linux.go +++ b/src/tun/tun_linux.go @@ -21,6 +21,9 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if err != nil { return fmt.Errorf("failed to create TUN: %w", err) } + if !waitForTUNUp(iface.Events()) { + return fmt.Errorf("TUN did not come up in time") + } tun.iface = iface if mtu, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(mtu)) diff --git a/src/tun/tun_other.go b/src/tun/tun_other.go index 0ddd0c1e..fc940818 100644 --- a/src/tun/tun_other.go +++ b/src/tun/tun_other.go @@ -18,6 +18,9 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if err != nil { return fmt.Errorf("failed to create TUN: %w", err) } + if !waitForTUNUp(iface.Events()) { + return fmt.Errorf("TUN did not come up in time") + } tun.iface = iface if mtu, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(mtu)) diff --git a/src/tun/tun_windows.go b/src/tun/tun_windows.go index 19d9248c..7bcdb7ac 100644 --- a/src/tun/tun_windows.go +++ b/src/tun/tun_windows.go @@ -34,6 +34,9 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if iface, err = wgtun.CreateTUNWithRequestedGUID(ifname, &guid, int(mtu)); err != nil { return err } + if !waitForTUNUp(iface.Events()) { + return fmt.Errorf("TUN did not come up in time") + } tun.iface = iface if addr != "" { if err = tun.setupAddress(addr); err != nil { From da7ebde828ee6cf0a2c896676e6d409448850fb4 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 20 Jul 2024 15:37:31 +0100 Subject: [PATCH 055/125] Update dependencies --- go.mod | 22 +++++++++++----------- go.sum | 45 ++++++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index eec96260..d32d1143 100644 --- a/go.mod +++ b/go.mod @@ -5,18 +5,18 @@ go 1.21 require ( github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d - github.com/cheggaaa/pb/v3 v3.1.4 + github.com/cheggaaa/pb/v3 v3.1.5 github.com/gologme/log v1.3.0 github.com/hashicorp/go-syslog v1.0.0 github.com/hjson/hjson-go/v4 v4.4.0 github.com/kardianos/minwinsvc v1.0.2 - github.com/quic-go/quic-go v0.44.0 + github.com/quic-go/quic-go v0.45.1 github.com/vishvananda/netlink v1.1.0 - golang.org/x/crypto v0.23.0 - golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b - golang.org/x/net v0.25.0 - golang.org/x/sys v0.20.0 - golang.org/x/text v0.15.0 + golang.org/x/crypto v0.25.0 + golang.org/x/mobile v0.0.0-20240716161057-1ad2df20a8b6 + golang.org/x/net v0.27.0 + golang.org/x/sys v0.22.0 + golang.org/x/text v0.16.0 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 ) @@ -30,10 +30,10 @@ require ( github.com/onsi/ginkgo/v2 v2.9.5 // indirect github.com/rivo/uniseg v0.2.0 // indirect go.uber.org/mock v0.4.0 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/mod v0.17.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/mod v0.19.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/tools v0.21.0 // indirect + golang.org/x/tools v0.23.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect ) @@ -41,7 +41,7 @@ require ( github.com/VividCortex/ewma v1.2.0 // indirect github.com/fatih/color v1.15.0 // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/olekukonko/tablewriter v0.0.5 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect ) diff --git a/go.sum b/go.sum index b7d97986..be42c112 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,8 @@ github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJR github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bits-and-blooms/bloom/v3 v3.7.0 h1:VfknkqV4xI+PsaDIsoHueyxVDZrfvMn56jeWUzvzdls= github.com/bits-and-blooms/bloom/v3 v3.7.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg= -github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo= -github.com/cheggaaa/pb/v3 v3.1.4/go.mod h1:6wVjILNBaXMs8c21qRiaUM8BR82erfgau1DQ4iUXmSA= +github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk= +github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -46,8 +46,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= @@ -56,8 +56,8 @@ github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= -github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= +github.com/quic-go/quic-go v0.45.1 h1:tPfeYCk+uZHjmDRwHHQmvHRYL2t44ROTujLeFVBmjCA= +github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -76,24 +76,25 @@ go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b h1:WX7nnnLfCEXg+FmdYZPai2XuP3VqCP1HZVMST0n9DF0= -golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b/go.mod h1:EiXZlVfUTaAyySFVJb9rsODuiO+WXu8HrUuySb7nYFw= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mobile v0.0.0-20240716161057-1ad2df20a8b6 h1:/VlmIrkuLf2wzPjkZ8imSpckHoW7Y71h66dxbLHSpi8= +golang.org/x/mobile v0.0.0-20240716161057-1ad2df20a8b6/go.mod h1:TCsc78+c4cqb8IKEosz2LwJ6YRNkIjMuAYeHYjchGDE= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -112,8 +113,9 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -126,16 +128,17 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= @@ -143,8 +146,8 @@ golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uI golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA= golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From 5ea16e63a1574ca2e4e07c52d167350241a6ff1c Mon Sep 17 00:00:00 2001 From: Vasyl Gello Date: Tue, 23 Jul 2024 21:58:11 +0000 Subject: [PATCH 056/125] Implement websocket (ws:// and wss://) links (#1152) ws:// can be listened and dialed wss:// is a convenience link for ws:// that supports dialing to ws:// peer. --------- Signed-off-by: Vasyl Gello Co-authored-by: Neil Alexander --- go.mod | 1 + go.sum | 2 + src/core/link.go | 12 +++++ src/core/link_ws.go | 123 +++++++++++++++++++++++++++++++++++++++++++ src/core/link_wss.go | 43 +++++++++++++++ 5 files changed, 181 insertions(+) create mode 100644 src/core/link_ws.go create mode 100644 src/core/link_wss.go diff --git a/go.mod b/go.mod index d32d1143..5ff4479a 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( golang.org/x/text v0.16.0 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 + nhooyr.io/websocket v1.8.11 ) require ( diff --git a/go.sum b/go.sum index be42c112..1cb8f5b8 100644 --- a/go.sum +++ b/go.sum @@ -154,3 +154,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY= +nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= +nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/src/core/link.go b/src/core/link.go index b646605c..f45c2cee 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -37,6 +37,8 @@ type links struct { unix *linkUNIX // UNIX interface support socks *linkSOCKS // SOCKS interface support quic *linkQUIC // QUIC interface support + ws *linkWS // WS interface support + wss *linkWSS // WSS interface support // _links can only be modified safely from within the links actor _links map[linkInfo]*link // *link is nil if connection in progress } @@ -97,6 +99,8 @@ func (l *links) init(c *Core) error { l.unix = l.newLinkUNIX() l.socks = l.newLinkSOCKS() l.quic = l.newLinkQUIC() + l.ws = l.newLinkWS() + l.wss = l.newLinkWSS() l._links = make(map[linkInfo]*link) var listeners []ListenAddress @@ -417,6 +421,10 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { protocol = l.unix case "quic": protocol = l.quic + case "ws": + protocol = l.ws + case "wss": + protocol = l.wss default: cancel() return nil, ErrLinkUnrecognisedSchema @@ -545,6 +553,10 @@ func (l *links) connect(ctx context.Context, u *url.URL, info linkInfo, options dialer = l.unix case "quic": dialer = l.quic + case "ws": + dialer = l.ws + case "wss": + dialer = l.wss default: return nil, ErrLinkUnrecognisedSchema } diff --git a/src/core/link_ws.go b/src/core/link_ws.go new file mode 100644 index 00000000..f323b025 --- /dev/null +++ b/src/core/link_ws.go @@ -0,0 +1,123 @@ +package core + +import ( + "context" + "net" + "net/http" + "net/url" + "time" + + "github.com/Arceliar/phony" + "nhooyr.io/websocket" +) + +type linkWS struct { + phony.Inbox + *links +} + +type linkWSConn struct { + net.Conn +} + +type linkWSListener struct { + ch chan *linkWSConn + ctx context.Context + httpServer *http.Server + listener net.Listener +} + +type wsServer struct { + ch chan *linkWSConn + ctx context.Context +} + +func (l *linkWSListener) Accept() (net.Conn, error) { + qs := <-l.ch + if qs == nil { + return nil, context.Canceled + } + return qs, nil +} + +func (l *linkWSListener) Addr() net.Addr { + return l.listener.Addr() +} + +func (l *linkWSListener) Close() error { + if err := l.httpServer.Shutdown(l.ctx); err != nil { + return err + } + return l.listener.Close() +} + +func (s *wsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/health" || r.URL.Path == "/healthz" { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("OK")) + return + } + + c, err := websocket.Accept(w, r, &websocket.AcceptOptions{ + Subprotocols: []string{"ygg-ws"}, + }) + if err != nil { + return + } + + if c.Subprotocol() != "ygg-ws" { + c.Close(websocket.StatusPolicyViolation, "client must speak the ygg-ws subprotocol") + return + } + + s.ch <- &linkWSConn{ + Conn: websocket.NetConn(s.ctx, c, websocket.MessageBinary), + } +} + +func (l *links) newLinkWS() *linkWS { + lt := &linkWS{ + links: l, + } + return lt +} + +func (l *linkWS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { + wsconn, _, err := websocket.Dial(ctx, url.String(), &websocket.DialOptions{ + Subprotocols: []string{"ygg-ws"}, + }) + if err != nil { + return nil, err + } + return &linkWSConn{ + Conn: websocket.NetConn(ctx, wsconn, websocket.MessageBinary), + }, nil +} + +func (l *linkWS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { + nl, err := net.Listen("tcp", url.Host) + if err != nil { + return nil, err + } + + ch := make(chan *linkWSConn) + + httpServer := &http.Server{ + Handler: &wsServer{ + ch: ch, + ctx: ctx, + }, + BaseContext: func(_ net.Listener) context.Context { return ctx }, + ReadTimeout: time.Second * 10, + WriteTimeout: time.Second * 10, + } + + lwl := &linkWSListener{ + ch: ch, + ctx: ctx, + httpServer: httpServer, + listener: nl, + } + go lwl.httpServer.Serve(nl) // nolint:errcheck + return lwl, nil +} diff --git a/src/core/link_wss.go b/src/core/link_wss.go new file mode 100644 index 00000000..a9a8df24 --- /dev/null +++ b/src/core/link_wss.go @@ -0,0 +1,43 @@ +package core + +import ( + "context" + "fmt" + "net" + "net/url" + + "github.com/Arceliar/phony" + "nhooyr.io/websocket" +) + +type linkWSS struct { + phony.Inbox + *links +} + +type linkWSSConn struct { + net.Conn +} + +func (l *links) newLinkWSS() *linkWSS { + lwss := &linkWSS{ + links: l, + } + return lwss +} + +func (l *linkWSS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { + wsconn, _, err := websocket.Dial(ctx, url.String(), &websocket.DialOptions{ + Subprotocols: []string{"ygg-ws"}, + }) + if err != nil { + return nil, err + } + return &linkWSSConn{ + Conn: websocket.NetConn(ctx, wsconn, websocket.MessageBinary), + }, nil +} + +func (l *linkWSS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { + return nil, fmt.Errorf("WSS listener not supported, use WS listener behind reverse proxy instead") +} From 4fbdeb4e3fd77dfc2bef8f9784bf14213d5461e4 Mon Sep 17 00:00:00 2001 From: Revertron <105154+Revertron@users.noreply.github.com> Date: Thu, 25 Jul 2024 14:55:14 +0200 Subject: [PATCH 057/125] Fixed Windows service life-cycle. (#1153) This fix fixes two issues: https://github.com/yggdrasil-network/yggdrasil-go/issues/993 & https://github.com/yggdrasil-network/yggdrasil-go/issues/1098 --- cmd/yggdrasil/main.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 82b85cd4..29afdf5d 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -53,13 +53,13 @@ func main() { getpkey := flag.Bool("publickey", false, "use in combination with either -useconf or -useconffile, outputs your public key") loglevel := flag.String("loglevel", "info", "loglevel to enable") flag.Parse() - + + done := make(chan struct{}) + defer close(done) + // Catch interrupts from the operating system to exit gracefully. ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) - // Capture the service being stopped on Windows. - minwinsvc.SetOnExit(cancel) - // Create a new logger that logs output to stdout. var logger *log.Logger switch *logto { @@ -271,6 +271,14 @@ func main() { n.tun.SetupAdminHandlers(n.admin) } } + + //Windows service shutdown + minwinsvc.SetOnExit(func() { + logger.Infof("Shutting down service ...") + cancel() + // Wait for all parts to shutdown properly + <-done + }) // Block until we are told to shut down. <-ctx.Done() From 9950d1225d1284ed8f47da3f027bb1444954c0d2 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 1 Aug 2024 21:53:48 +0100 Subject: [PATCH 058/125] Improve link and handshake errors --- src/core/link.go | 10 ++++++---- src/core/version.go | 23 ++++++++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index f45c2cee..ee2ad06f 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -140,7 +140,7 @@ const ErrLinkAlreadyConfigured = linkError("peer is already configured") const ErrLinkNotConfigured = linkError("peer is not configured") const ErrLinkPriorityInvalid = linkError("priority value is invalid") const ErrLinkPinnedKeyInvalid = linkError("pinned public key is invalid") -const ErrLinkPasswordInvalid = linkError("password is invalid") +const ErrLinkPasswordInvalid = linkError("invalid password supplied") const ErrLinkUnrecognisedSchema = linkError("link schema unknown") const ErrLinkMaxBackoffInvalid = linkError("max backoff duration invalid") @@ -363,9 +363,11 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { _ = lc.Close() phony.Block(l, func() { state._conn = nil - if state._err = err; state._err != nil { - state._errtime = time.Now() + if err == nil { + err = fmt.Errorf("remote side closed the connection") } + state._err = err + state._errtime = time.Now() }) // If the link is persistently configured, back off if needed @@ -647,7 +649,7 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, s l.core.log.Infof("Disconnected %s: %s, source %s; error: %s", dir, remoteStr, localStr, err) } - return nil + return err } func urlForLinkInfo(u url.URL) url.URL { diff --git a/src/core/version.go b/src/core/version.go index 28b16430..bb3b9538 100644 --- a/src/core/version.go +++ b/src/core/version.go @@ -8,7 +8,6 @@ import ( "bytes" "crypto/ed25519" "encoding/binary" - "fmt" "io" "golang.org/x/crypto/blake2b" @@ -38,6 +37,16 @@ const ( metaPriority // uint8 ) +type handshakeError string + +func (e handshakeError) Error() string { return string(e) } + +const ErrHandshakeInvalidPreamble = handshakeError("invalid handshake, remote side is not Yggdrasil") +const ErrHandshakeInvalidLength = handshakeError("invalid handshake length, possible version mismatch") +const ErrHandshakeInvalidPassword = handshakeError("invalid password supplied, check your config") +const ErrHandshakeHashFailure = handshakeError("invalid hash length") +const ErrHandshakeIncorrectPassword = handshakeError("password does not match remote side") + // Gets a base metadata with no keys set, but with the correct version numbers. func version_getBaseMetadata() version_metadata { return version_metadata{ @@ -77,7 +86,7 @@ func (m *version_metadata) encode(privateKey ed25519.PrivateKey, password []byte return nil, err } if n != ed25519.PublicKeySize { - return nil, fmt.Errorf("hash writer only wrote %d bytes", n) + return nil, ErrHandshakeHashFailure } hash := hasher.Sum(nil) bs = append(bs, ed25519.Sign(privateKey, hash)...) @@ -94,11 +103,11 @@ func (m *version_metadata) decode(r io.Reader, password []byte) error { } meta := [4]byte{'m', 'e', 't', 'a'} if !bytes.Equal(bh[:4], meta[:]) { - return fmt.Errorf("invalid handshake preamble") + return ErrHandshakeInvalidPreamble } hl := binary.BigEndian.Uint16(bh[4:6]) if hl < ed25519.SignatureSize { - return fmt.Errorf("invalid handshake length") + return ErrHandshakeInvalidLength } bs := make([]byte, hl) if _, err := io.ReadFull(r, bs); err != nil { @@ -132,15 +141,15 @@ func (m *version_metadata) decode(r io.Reader, password []byte) error { hasher, err := blake2b.New512(password) if err != nil { - return fmt.Errorf("invalid password supplied") + return ErrHandshakeInvalidPassword } n, err := hasher.Write(m.publicKey) if err != nil || n != ed25519.PublicKeySize { - return fmt.Errorf("failed to generate hash") + return ErrHandshakeHashFailure } hash := hasher.Sum(nil) if !ed25519.Verify(m.publicKey, hash, sig) { - return fmt.Errorf("password is incorrect") + return ErrHandshakeIncorrectPassword } return nil } From edf179ed26df30b30665f703b366f2688fefde92 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 5 Aug 2024 19:18:38 +0100 Subject: [PATCH 059/125] Yggdrasil 0.5.7 --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b339294c..323206d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,25 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.7] - 2024-08-05 + +### Added + +* WebSocket support for peerings, by using the new `ws://` scheme in `Listen` and `Peers` + * Additionally, the `wss://` scheme can be used to connect to a WebSocket peer behind a HTTPS reverse proxy + +### Changed + +* On Linux, the TUN adapter now uses vectorised reads/writes where possible, which should reduce the amount of CPU time spent on syscalls and potentially improve throughput +* Link error handling has been improved and various link error messages have been rewritten to be clearer +* Upgrade dependencies + +### Fixed + +* Multiple multicast connections to the same remote machine should now work correctly + * You may get two connections in some cases, one inbound and one outbound, this is known and will not cause problems +* Running as a Windows service should be more reliable with service startup and shutdown bugs fixed + ## [0.5.6] - 2024-05-30 * Go 1.21 is now required to build Yggdrasil From 5e5de3a34314d9ac3f549a93e3e30a5a9ce66966 Mon Sep 17 00:00:00 2001 From: Revertron <105154+Revertron@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:28:15 +0200 Subject: [PATCH 060/125] Fixed wait for TUN to come up (#1157) So, the function waiting for TUN to come up never succeeds: ``` func waitForTUNUp(ch <-chan wgtun.Event) bool { t := time.After(time.Second * 5) for { select { case ev := <-ch: if ev == wgtun.EventUp { return true } case <-t: return false } } } ``` I've tried the sleep for one second, and it works flawlessly on several PCs. Another point - sometimes, if the service stop abruptly (in case of some errors) there is an old hidden device in the system, that we need to uninstall, and then create new. --- src/tun/tun_windows.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/tun/tun_windows.go b/src/tun/tun_windows.go index 7bcdb7ac..a2861894 100644 --- a/src/tun/tun_windows.go +++ b/src/tun/tun_windows.go @@ -8,10 +8,12 @@ import ( "fmt" "log" "net/netip" + "time" "github.com/yggdrasil-network/yggdrasil-go/src/config" "golang.org/x/sys/windows" + "golang.zx2c4.com/wintun" wgtun "golang.zx2c4.com/wireguard/tun" "golang.zx2c4.com/wireguard/windows/elevate" "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" @@ -31,14 +33,23 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if guid, err = windows.GUIDFromString("{8f59971a-7872-4aa6-b2eb-061fc4e9d0a7}"); err != nil { return err } - if iface, err = wgtun.CreateTUNWithRequestedGUID(ifname, &guid, int(mtu)); err != nil { - return err - } - if !waitForTUNUp(iface.Events()) { - return fmt.Errorf("TUN did not come up in time") + iface, err = wgtun.CreateTUNWithRequestedGUID(ifname, &guid, int(mtu)) + if err != nil { + // Very rare condition, it will purge the old device and create new + tun.log.Printf("Error creating TUN: '%s'", err) + wintun.Uninstall() + time.Sleep(3 * time.Second) + tun.log.Printf("Trying again") + iface, err = wgtun.CreateTUNWithRequestedGUID(ifname, &guid, int(mtu)) + if err != nil { + return err + } } + tun.log.Printf("Waiting for TUN to come up") + time.Sleep(1 * time.Second) tun.iface = iface if addr != "" { + tun.log.Printf("Setting up address") if err = tun.setupAddress(addr); err != nil { tun.log.Errorln("Failed to set up TUN address:", err) return err @@ -51,6 +62,7 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if mtu, err := iface.MTU(); err == nil { tun.mtu = uint64(mtu) } + tun.log.Printf("TUN is set up successfully") return nil }) } From 63cd7575258a68d7ceda425c80766c4dd6e9b42d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 7 Aug 2024 19:52:19 +0100 Subject: [PATCH 061/125] Remove `waitForTUNUp` from TUN Causes issues such as #1156. --- src/tun/tun.go | 15 --------------- src/tun/tun_bsd.go | 3 --- src/tun/tun_darwin.go | 3 --- src/tun/tun_linux.go | 3 --- src/tun/tun_other.go | 3 --- 5 files changed, 27 deletions(-) diff --git a/src/tun/tun.go b/src/tun/tun.go index e6795c64..e7ba3a0f 100644 --- a/src/tun/tun.go +++ b/src/tun/tun.go @@ -11,7 +11,6 @@ import ( "io" "net" "sync" - "time" "github.com/Arceliar/phony" wgtun "golang.zx2c4.com/wireguard/tun" @@ -65,20 +64,6 @@ func getSupportedMTU(mtu uint64) uint64 { return mtu } -func waitForTUNUp(ch <-chan wgtun.Event) bool { - t := time.After(time.Second * 5) - for { - select { - case ev := <-ch: - if ev == wgtun.EventUp { - return true - } - case <-t: - return false - } - } -} - // Name returns the name of the adapter, e.g. "tun0". On Windows, this may // return a canonical adapter name instead. func (tun *TunAdapter) Name() string { diff --git a/src/tun/tun_bsd.go b/src/tun/tun_bsd.go index 7f26260c..da5b3297 100644 --- a/src/tun/tun_bsd.go +++ b/src/tun/tun_bsd.go @@ -80,9 +80,6 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if err != nil { return fmt.Errorf("failed to create TUN: %w", err) } - if !waitForTUNUp(iface.Events()) { - return fmt.Errorf("TUN did not come up in time") - } tun.iface = iface if mtu, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(mtu)) diff --git a/src/tun/tun_darwin.go b/src/tun/tun_darwin.go index a9d734bb..aa30b7f3 100644 --- a/src/tun/tun_darwin.go +++ b/src/tun/tun_darwin.go @@ -27,9 +27,6 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if err != nil { return fmt.Errorf("failed to create TUN: %w", err) } - if !waitForTUNUp(iface.Events()) { - return fmt.Errorf("TUN did not come up in time") - } tun.iface = iface if m, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(m)) diff --git a/src/tun/tun_linux.go b/src/tun/tun_linux.go index c98cdd73..98d63db4 100644 --- a/src/tun/tun_linux.go +++ b/src/tun/tun_linux.go @@ -21,9 +21,6 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if err != nil { return fmt.Errorf("failed to create TUN: %w", err) } - if !waitForTUNUp(iface.Events()) { - return fmt.Errorf("TUN did not come up in time") - } tun.iface = iface if mtu, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(mtu)) diff --git a/src/tun/tun_other.go b/src/tun/tun_other.go index fc940818..0ddd0c1e 100644 --- a/src/tun/tun_other.go +++ b/src/tun/tun_other.go @@ -18,9 +18,6 @@ func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { if err != nil { return fmt.Errorf("failed to create TUN: %w", err) } - if !waitForTUNUp(iface.Events()) { - return fmt.Errorf("TUN did not come up in time") - } tun.iface = iface if mtu, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(mtu)) From af9ff34995aa8da5670227fc1a8981051ceaec65 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 7 Aug 2024 19:55:10 +0100 Subject: [PATCH 062/125] Fix macOS build --- src/tun/tun_darwin.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tun/tun_darwin.go b/src/tun/tun_darwin.go index aa30b7f3..deeb115e 100644 --- a/src/tun/tun_darwin.go +++ b/src/tun/tun_darwin.go @@ -55,9 +55,6 @@ func (tun *TunAdapter) setupFD(fd int32, addr string, mtu uint64) error { unix.Close(dfd) return fmt.Errorf("failed to create TUN from FD: %w", err) } - if !waitForTUNUp(iface.Events()) { - return fmt.Errorf("TUN did not come up in time") - } tun.iface = iface if m, err := iface.MTU(); err == nil { tun.mtu = getSupportedMTU(uint64(m)) From ef989bef6362ad42eec9376a512a5d7be2b7e9e7 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 11 Aug 2024 10:41:58 +0100 Subject: [PATCH 063/125] Multicast module state tweaks --- src/multicast/multicast.go | 26 +++++++++++++++----------- src/multicast/multicast_darwin_cgo.go | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index bf10370f..0fe72dc7 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -9,6 +9,7 @@ import ( "math/rand" "net" "net/url" + "sync/atomic" "time" "github.com/Arceliar/phony" @@ -28,7 +29,7 @@ type Multicast struct { core *core.Core log *log.Logger sock *ipv6.PacketConn - _isOpen bool + running atomic.Bool _listeners map[string]*listenerInfo _interfaces map[string]*interfaceInfo _timer *time.Timer @@ -79,7 +80,7 @@ func New(core *core.Core, log *log.Logger, opts ...SetupOption) (*Multicast, err } func (m *Multicast) _start() error { - if m._isOpen { + if !m.running.CompareAndSwap(false, true) { return fmt.Errorf("multicast module is already started") } var anyEnabled bool @@ -87,12 +88,14 @@ func (m *Multicast) _start() error { anyEnabled = anyEnabled || intf.Beacon || intf.Listen } if !anyEnabled { + m.running.Store(false) return nil } m.log.Debugln("Starting multicast module") defer m.log.Debugln("Started multicast module") addr, err := net.ResolveUDPAddr("udp", string(m.config._groupAddr)) if err != nil { + m.running.Store(false) return err } listenString := fmt.Sprintf("[::]:%v", addr.Port) @@ -101,6 +104,7 @@ func (m *Multicast) _start() error { } conn, err := lc.ListenPacket(context.Background(), "udp6", listenString) if err != nil { + m.running.Store(false) return err } m.sock = ipv6.NewPacketConn(conn) @@ -108,7 +112,6 @@ func (m *Multicast) _start() error { // Windows can't set this flag, so we need to handle it in other ways } - m._isOpen = true go m.listen() m.Act(nil, m._multicastStarted) m.Act(nil, m._announce) @@ -118,11 +121,7 @@ func (m *Multicast) _start() error { // IsStarted returns true if the module has been started. func (m *Multicast) IsStarted() bool { - var isOpen bool - phony.Block(m, func() { - isOpen = m._isOpen - }) - return isOpen + return m.running.Load() } // Stop stops the multicast module. @@ -136,8 +135,10 @@ func (m *Multicast) Stop() error { } func (m *Multicast) _stop() error { + if !m.running.CompareAndSwap(true, false) { + return nil + } m.log.Infoln("Stopping multicast module") - m._isOpen = false if m.sock != nil { m.sock.Close() } @@ -233,7 +234,7 @@ func (m *Multicast) AnnounceNow() { } func (m *Multicast) _announce() { - if !m._isOpen { + if !m.running.Load() { return } m._updateInterfaces() @@ -250,7 +251,7 @@ func (m *Multicast) _announce() { for name, info := range m._listeners { // Prepare our stop function! stop := func() { - info.listener.Close() + info.listener.Cancel() delete(m._listeners, name) m.log.Debugln("No longer multicasting on", name) } @@ -376,6 +377,9 @@ func (m *Multicast) listen() { bs := make([]byte, 2048) hb := make([]byte, 0, blake2b.Size) // Reused to reduce hash allocations for { + if !m.running.Load() { + return + } n, rcm, fromAddr, err := m.sock.ReadFrom(bs) if err != nil { if !m.IsStarted() { diff --git a/src/multicast/multicast_darwin_cgo.go b/src/multicast/multicast_darwin_cgo.go index 5c2af7ab..16266381 100644 --- a/src/multicast/multicast_darwin_cgo.go +++ b/src/multicast/multicast_darwin_cgo.go @@ -31,7 +31,7 @@ import ( ) func (m *Multicast) _multicastStarted() { - if !m._isOpen { + if !m.running.Load() { return } C.StopAWDLBrowsing() From b1283e15f63dc7a553e0381efed6abdfa6006819 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 11 Aug 2024 10:42:25 +0100 Subject: [PATCH 064/125] Link state tracking tweaks and improved shutdown --- src/core/link.go | 66 +++++++++++++++++++------------------------ src/core/link_tcp.go | 2 -- src/core/link_tls.go | 10 +++---- src/core/link_unix.go | 6 ++-- src/core/link_ws.go | 6 +++- 5 files changed, 40 insertions(+), 50 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index ee2ad06f..1ead4e32 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/hex" + "errors" "fmt" "io" "net" @@ -40,7 +41,8 @@ type links struct { ws *linkWS // WS interface support wss *linkWSS // WSS interface support // _links can only be modified safely from within the links actor - _links map[linkInfo]*link // *link is nil if connection in progress + _links map[linkInfo]*link // *link is nil if connection in progress + _listeners map[*Listener]context.CancelFunc } type linkProtocol interface { @@ -85,13 +87,6 @@ func (l *Listener) Addr() net.Addr { return l.listener.Addr() } -func (l *Listener) Close() error { - l.Cancel() - err := l.listener.Close() - <-l.ctx.Done() - return err -} - func (l *links) init(c *Core) error { l.core = c l.tcp = l.newLinkTCP() @@ -102,32 +97,18 @@ func (l *links) init(c *Core) error { l.ws = l.newLinkWS() l.wss = l.newLinkWSS() l._links = make(map[linkInfo]*link) - - var listeners []ListenAddress - phony.Block(c, func() { - listeners = make([]ListenAddress, 0, len(c.config._listeners)) - for listener := range c.config._listeners { - listeners = append(listeners, listener) - } - }) + l._listeners = make(map[*Listener]context.CancelFunc) return nil } func (l *links) shutdown() { - phony.Block(l.tcp, func() { - for l := range l.tcp._listeners { - _ = l.Close() + phony.Block(l, func() { + for listener := range l._listeners { + _ = listener.listener.Close() } - }) - phony.Block(l.tls, func() { - for l := range l.tls._listeners { - _ = l.Close() - } - }) - phony.Block(l.unix, func() { - for l := range l.unix._listeners { - _ = l.Close() + for _, link := range l._links { + _ = link._conn.Close() } }) } @@ -457,11 +438,18 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { options.password = []byte(p) } + phony.Block(l, func() { + l._listeners[li] = cancel + }) + go func() { - l.core.log.Infof("%s listener started on %s", strings.ToUpper(u.Scheme), listener.Addr()) - defer l.core.log.Infof("%s listener stopped on %s", strings.ToUpper(u.Scheme), listener.Addr()) + l.core.log.Infof("%s listener started on %s", strings.ToUpper(u.Scheme), li.listener.Addr()) + defer l.core.log.Infof("%s listener stopped on %s", strings.ToUpper(u.Scheme), li.listener.Addr()) + defer phony.Block(l, func() { + delete(l._listeners, li) + }) for { - conn, err := listener.Accept() + conn, err := li.listener.Accept() if err != nil { return } @@ -517,13 +505,22 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { // Store the state of the link so that it can be queried later. l._links[info] = state }) + defer phony.Block(l, func() { + if l._links[info] == state { + delete(l._links, info) + } + }) if lc == nil { return } // Give the connection to the handler. The handler will block // for the lifetime of the connection. - if err = l.handler(linkTypeIncoming, options, lc, nil); err != nil && err != io.EOF { + switch err = l.handler(linkTypeIncoming, options, lc, nil); { + case err == nil: + case errors.Is(err, io.EOF): + case errors.Is(err, net.ErrClosed): + default: l.core.log.Debugf("Link %s error: %s\n", u.Host, err) } @@ -531,11 +528,6 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { // try to close the underlying socket just in case and then // drop the link state. _ = lc.Close() - phony.Block(l, func() { - if l._links[info] == state { - delete(l._links, info) - } - }) }(conn) } }() diff --git a/src/core/link_tcp.go b/src/core/link_tcp.go index f595aeb9..4ee50941 100644 --- a/src/core/link_tcp.go +++ b/src/core/link_tcp.go @@ -15,7 +15,6 @@ type linkTCP struct { phony.Inbox *links listenconfig *net.ListenConfig - _listeners map[*Listener]context.CancelFunc } func (l *links) newLinkTCP() *linkTCP { @@ -24,7 +23,6 @@ func (l *links) newLinkTCP() *linkTCP { listenconfig: &net.ListenConfig{ KeepAlive: -1, }, - _listeners: map[*Listener]context.CancelFunc{}, } lt.listenconfig.Control = lt.tcpContext return lt diff --git a/src/core/link_tls.go b/src/core/link_tls.go index a93227f6..d51d0ce5 100644 --- a/src/core/link_tls.go +++ b/src/core/link_tls.go @@ -13,10 +13,9 @@ import ( type linkTLS struct { phony.Inbox *links - tcp *linkTCP - listener *net.ListenConfig - config *tls.Config - _listeners map[*Listener]context.CancelFunc + tcp *linkTCP + listener *net.ListenConfig + config *tls.Config } func (l *links) newLinkTLS(tcp *linkTCP) *linkTLS { @@ -27,8 +26,7 @@ func (l *links) newLinkTLS(tcp *linkTCP) *linkTLS { Control: tcp.tcpContext, KeepAlive: -1, }, - config: l.core.config.tls.Clone(), - _listeners: map[*Listener]context.CancelFunc{}, + config: l.core.config.tls.Clone(), } return lt } diff --git a/src/core/link_unix.go b/src/core/link_unix.go index 8dde8946..ddbfa0ad 100644 --- a/src/core/link_unix.go +++ b/src/core/link_unix.go @@ -12,9 +12,8 @@ import ( type linkUNIX struct { phony.Inbox *links - dialer *net.Dialer - listener *net.ListenConfig - _listeners map[*Listener]context.CancelFunc + dialer *net.Dialer + listener *net.ListenConfig } func (l *links) newLinkUNIX() *linkUNIX { @@ -27,7 +26,6 @@ func (l *links) newLinkUNIX() *linkUNIX { listener: &net.ListenConfig{ KeepAlive: -1, }, - _listeners: map[*Listener]context.CancelFunc{}, } return lt } diff --git a/src/core/link_ws.go b/src/core/link_ws.go index f323b025..7a7d66f7 100644 --- a/src/core/link_ws.go +++ b/src/core/link_ws.go @@ -14,6 +14,7 @@ import ( type linkWS struct { phony.Inbox *links + listenconfig *net.ListenConfig } type linkWSConn struct { @@ -78,6 +79,9 @@ func (s *wsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (l *links) newLinkWS() *linkWS { lt := &linkWS{ links: l, + listenconfig: &net.ListenConfig{ + KeepAlive: -1, + }, } return lt } @@ -95,7 +99,7 @@ func (l *linkWS) dial(ctx context.Context, url *url.URL, info linkInfo, options } func (l *linkWS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { - nl, err := net.Listen("tcp", url.Host) + nl, err := l.listenconfig.Listen(ctx, "tcp", url.Host) if err != nil { return nil, err } From 340cedbe145ec40de2648dab658795ec21e11992 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 12 Aug 2024 19:17:40 +0100 Subject: [PATCH 065/125] Yggdrasil 0.5.8 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 323206d9..34c7fe30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.8] - 2024-08-12 + +### Fixed + +* A bug which caused startup problems on Windows and FreeBSD should be fixed +* Resolved some minor link state and listener management bugs during shutdown + ## [0.5.7] - 2024-08-05 ### Added From 947b6ad7aa93eb2174bf16ddac844c7afaf2677d Mon Sep 17 00:00:00 2001 From: Sergey Bobrenok Date: Fri, 16 Aug 2024 20:28:57 +0300 Subject: [PATCH 066/125] Restore local peer discovery mechanism on Android 11+ (#1158) This solution is bases on https://github.com/wlynxg/anet project. `github.com/wlynxg/anet` is a partial alternative implementation of the `golang.org/x/net` module. The goal of `anet` module is to provide workarounds of the issues https://github.com/golang/go/issues/40569 and https://github.com/golang/go/issues/68082 on Android 11+. Tested on AOSP 13. Resolves: #1149 --- go.mod | 1 + go.sum | 2 ++ src/multicast/multicast.go | 10 +++++++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5ff4479a..52b699d8 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/kardianos/minwinsvc v1.0.2 github.com/quic-go/quic-go v0.45.1 github.com/vishvananda/netlink v1.1.0 + github.com/wlynxg/anet v0.0.4-0.20240806025826-e684438fc7c6 golang.org/x/crypto v0.25.0 golang.org/x/mobile v0.0.0-20240716161057-1ad2df20a8b6 golang.org/x/net v0.27.0 diff --git a/go.sum b/go.sum index 1cb8f5b8..a3c2888e 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,8 @@ github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYp github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/wlynxg/anet v0.0.4-0.20240806025826-e684438fc7c6 h1:c/wkXIJvpg2oot7iFqPESTBAO9UvhWTBnW97y9aPgyU= +github.com/wlynxg/anet v0.0.4-0.20240806025826-e684438fc7c6/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index 0fe72dc7..902d7729 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -14,6 +14,7 @@ import ( "github.com/Arceliar/phony" "github.com/gologme/log" + "github.com/wlynxg/anet" "github.com/yggdrasil-network/yggdrasil-go/src/core" "golang.org/x/crypto/blake2b" @@ -148,7 +149,8 @@ func (m *Multicast) _stop() error { func (m *Multicast) _updateInterfaces() { interfaces := m._getAllowedInterfaces() for name, info := range interfaces { - addrs, err := info.iface.Addrs() + // 'anet' package is used here to avoid https://github.com/golang/go/issues/40569 + addrs, err := anet.InterfaceAddrsByInterface(&info.iface) if err != nil { m.log.Warnf("Failed up get addresses for interface %s: %s", name, err) delete(interfaces, name) @@ -156,6 +158,7 @@ func (m *Multicast) _updateInterfaces() { } info.addrs = addrs interfaces[name] = info + m.log.Debugf("Discovered addresses for interface %s: %s", name, addrs) } m._interfaces = interfaces } @@ -174,10 +177,11 @@ func (m *Multicast) Interfaces() map[string]net.Interface { func (m *Multicast) _getAllowedInterfaces() map[string]*interfaceInfo { interfaces := make(map[string]*interfaceInfo) // Ask the system for network interfaces - allifaces, err := net.Interfaces() + // 'anet' package is used here to avoid https://github.com/golang/go/issues/40569 + allifaces, err := anet.Interfaces() if err != nil { // Don't panic, since this may be from e.g. too many open files (from too much connection spam) - // TODO? log something + m.log.Debugf("Failed to get interfaces: %s", err) return nil } // Work out which interfaces to announce on From c4b29b735cff4448e0343fe0fbfdb4e668d13660 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 21 Sep 2024 23:05:23 +0100 Subject: [PATCH 067/125] Link costing based on average RTT (#1171) This PR updates Ironwood to include the new RTT-based link costing and updates `yggdrasilctl` to report the cost in `getPeers`. Co-authored-by: Neil Alexander --- .github/workflows/ci.yml | 12 ++++++------ .golangci.yml | 5 +++-- cmd/yggdrasilctl/main.go | 3 ++- contrib/mobile/mobile.go | 2 -- go.mod | 5 ++--- go.sum | 6 ++---- src/admin/getpeers.go | 2 ++ src/core/api.go | 2 ++ 8 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3f34789..57a0d2a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,10 +17,10 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.21 + go-version: stable - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v6 with: args: --issues-exit-code=1 @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.21", "1.22"] + goversion: ["1.21", "1.22", "1.23"] name: Build & Test (Linux, Go ${{ matrix.goversion }}) needs: [lint] @@ -75,7 +75,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.21", "1.22"] + goversion: ["1.21", "1.22", "1.23"] name: Build & Test (Windows, Go ${{ matrix.goversion }}) needs: [lint] @@ -99,7 +99,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.21", "1.22"] + goversion: ["1.21", "1.22", "1.23"] name: Build & Test (macOS, Go ${{ matrix.goversion }}) needs: [lint] @@ -123,7 +123,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.21", "1.22"] + goversion: ["1.21", "1.22", "1.23"] goos: - freebsd - openbsd diff --git a/.golangci.yml b/.golangci.yml index c35edee4..836af618 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,9 +2,10 @@ run: build-tags: - lint issues-exit-code: 0 # TODO: change this to 1 when we want it to fail builds - skip-dirs: +issues: + exclude-dirs: - contrib/ - misc/ linters: disable: - - gocyclo \ No newline at end of file + - gocyclo diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 2a1d70b1..8a30f438 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -174,7 +174,7 @@ func run() int { if err := json.Unmarshal(recv.Response, &resp); err != nil { panic(err) } - table.SetHeader([]string{"URI", "State", "Dir", "IP Address", "Uptime", "RTT", "RX", "TX", "Pr", "Last Error"}) + table.SetHeader([]string{"URI", "State", "Dir", "IP Address", "Uptime", "RTT", "RX", "TX", "Pr", "Cost", "Last Error"}) for _, peer := range resp.Peers { state, lasterr, dir, rtt := "Up", "-", "Out", "-" if !peer.Up { @@ -200,6 +200,7 @@ func run() int { peer.RXBytes.String(), peer.TXBytes.String(), fmt.Sprintf("%d", peer.Priority), + fmt.Sprintf("%d", peer.Cost), lasterr, }) } diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index 82e73485..06f48027 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -15,8 +15,6 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/multicast" "github.com/yggdrasil-network/yggdrasil-go/src/tun" "github.com/yggdrasil-network/yggdrasil-go/src/version" - - _ "golang.org/x/mobile/bind" ) // Yggdrasil mobile package is meant to "plug the gap" for mobile support, as diff --git a/go.mod b/go.mod index 52b699d8..e10feb95 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2 + github.com/Arceliar/ironwood v0.0.0-20240921214443-277f642d5db3 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 github.com/gologme/log v1.3.0 @@ -14,10 +14,10 @@ require ( github.com/vishvananda/netlink v1.1.0 github.com/wlynxg/anet v0.0.4-0.20240806025826-e684438fc7c6 golang.org/x/crypto v0.25.0 - golang.org/x/mobile v0.0.0-20240716161057-1ad2df20a8b6 golang.org/x/net v0.27.0 golang.org/x/sys v0.22.0 golang.org/x/text v0.16.0 + golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 nhooyr.io/websocket v1.8.11 @@ -36,7 +36,6 @@ require ( golang.org/x/mod v0.19.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/tools v0.23.0 // indirect - golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect ) require ( diff --git a/go.sum b/go.sum index a3c2888e..5ddf4169 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2 h1:SBdYBKeXYUUFef5wi2CMhYmXFVGiYaRpTvbki0Bu+JQ= -github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= +github.com/Arceliar/ironwood v0.0.0-20240921214443-277f642d5db3 h1:OJ49qTfdw5MNkpnRraNEsVQbHahSvShh8Z9WYpZrYa0= +github.com/Arceliar/ironwood v0.0.0-20240921214443-277f642d5db3/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= @@ -83,8 +83,6 @@ golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mobile v0.0.0-20240716161057-1ad2df20a8b6 h1:/VlmIrkuLf2wzPjkZ8imSpckHoW7Y71h66dxbLHSpi8= -golang.org/x/mobile v0.0.0-20240716161057-1ad2df20a8b6/go.mod h1:TCsc78+c4cqb8IKEosz2LwJ6YRNkIjMuAYeHYjchGDE= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index e44428c3..48234fb1 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -24,6 +24,7 @@ type PeerEntry struct { PublicKey string `json:"key"` Port uint64 `json:"port"` Priority uint64 `json:"priority"` + Cost uint64 `json:"cost"` RXBytes DataUnit `json:"bytes_recvd,omitempty"` TXBytes DataUnit `json:"bytes_sent,omitempty"` Uptime float64 `json:"uptime,omitempty"` @@ -41,6 +42,7 @@ func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse) Up: p.Up, Inbound: p.Inbound, Priority: uint64(p.Priority), // can't be uint8 thanks to gobind + Cost: p.Cost, URI: p.URI, RXBytes: DataUnit(p.RXBytes), TXBytes: DataUnit(p.TXBytes), diff --git a/src/core/api.go b/src/core/api.go index 875d7bf2..c236b1b5 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -30,6 +30,7 @@ type PeerInfo struct { Coords []uint64 Port uint64 Priority uint8 + Cost uint64 RXBytes uint64 TXBytes uint64 Uptime time.Duration @@ -94,6 +95,7 @@ func (c *Core) GetPeers() []PeerInfo { peerinfo.Port = p.Port peerinfo.Priority = p.Priority peerinfo.Latency = p.Latency + peerinfo.Cost = p.Cost } peers = append(peers, peerinfo) } From 34f087de1c24e39fce7201bfe8d238f7e5bc85cf Mon Sep 17 00:00:00 2001 From: cathugger Date: Sun, 22 Sep 2024 15:46:54 +0000 Subject: [PATCH 068/125] argument to change uid/gid (#927) different from https://github.com/yggdrasil-network/yggdrasil-go/pull/817 in that it can resolve user names, automatically use user's primary gid & allows specifying gid in the same argument, with `:` eg `username:groupname`. feel free to criticize & suggest different argument name & description because i didn't put much of thought to that. --------- Co-authored-by: Neil Co-authored-by: VNAT Co-authored-by: Neil Alexander --- cmd/yggdrasil/chuser_other.go | 10 ++++ cmd/yggdrasil/chuser_unix.go | 87 +++++++++++++++++++++++++++++++++++ cmd/yggdrasil/main.go | 9 ++++ 3 files changed, 106 insertions(+) create mode 100644 cmd/yggdrasil/chuser_other.go create mode 100644 cmd/yggdrasil/chuser_unix.go diff --git a/cmd/yggdrasil/chuser_other.go b/cmd/yggdrasil/chuser_other.go new file mode 100644 index 00000000..702f3715 --- /dev/null +++ b/cmd/yggdrasil/chuser_other.go @@ -0,0 +1,10 @@ +//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris + +package main + +import "errors" + +func chuser(user string) error { + return errors.New("setting uid/gid is not supported on this platform") +} diff --git a/cmd/yggdrasil/chuser_unix.go b/cmd/yggdrasil/chuser_unix.go new file mode 100644 index 00000000..6e802c69 --- /dev/null +++ b/cmd/yggdrasil/chuser_unix.go @@ -0,0 +1,87 @@ +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris + +package main + +import ( + "errors" + "fmt" + "math" + osuser "os/user" + "strconv" + "strings" + "syscall" +) + +func chuser(user string) error { + group := "" + if i := strings.IndexByte(user, ':'); i >= 0 { + user, group = user[:i], user[i+1:] + } + + u := (*osuser.User)(nil) + g := (*osuser.Group)(nil) + + if user != "" { + if _, err := strconv.ParseUint(user, 10, 32); err == nil { + u, err = osuser.LookupId(user) + if err != nil { + return fmt.Errorf("failed to lookup user by id %q: %v", user, err) + } + } else { + u, err = osuser.Lookup(user) + if err != nil { + return fmt.Errorf("failed to lookup user by name %q: %v", user, err) + } + } + } + if group != "" { + if _, err := strconv.ParseUint(group, 10, 32); err == nil { + g, err = osuser.LookupGroupId(group) + if err != nil { + return fmt.Errorf("failed to lookup group by id %q: %v", user, err) + } + } else { + g, err = osuser.LookupGroup(group) + if err != nil { + return fmt.Errorf("failed to lookup group by name %q: %v", user, err) + } + } + } + + if g != nil { + gid, _ := strconv.ParseUint(g.Gid, 10, 32) + var err error + if gid < math.MaxInt { + err = syscall.Setgid(int(gid)) + } else { + err = errors.New("gid too big") + } + + if err != nil { + return fmt.Errorf("failed to setgid %d: %v", gid, err) + } + } else if u != nil { + gid, _ := strconv.ParseUint(u.Gid, 10, 32) + err := syscall.Setgid(int(uint32(gid))) + if err != nil { + return fmt.Errorf("failed to setgid %d: %v", gid, err) + } + } + + if u != nil { + uid, _ := strconv.ParseUint(u.Uid, 10, 32) + var err error + if uid < math.MaxInt { + err = syscall.Setuid(int(uid)) + } else { + err = errors.New("uid too big") + } + + if err != nil { + return fmt.Errorf("failed to setuid %d: %v", uid, err) + } + } + + return nil +} diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 29afdf5d..3a00b3fc 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -52,6 +52,7 @@ func main() { getsnet := flag.Bool("subnet", false, "use in combination with either -useconf or -useconffile, outputs your IPv6 subnet") getpkey := flag.Bool("publickey", false, "use in combination with either -useconf or -useconffile, outputs your public key") loglevel := flag.String("loglevel", "info", "loglevel to enable") + chuserto := flag.String("user", "", "user (and, optionally, group) to set UID/GID to") flag.Parse() done := make(chan struct{}) @@ -280,6 +281,14 @@ func main() { <-done }) + // Change user if requested + if *chuserto != "" { + err = chuser(*chuserto) + if err != nil { + panic(err) + } + } + // Block until we are told to shut down. <-ctx.Done() From 5461bb380e9519a724b3c6e45b5ac913ab7528c3 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 22 Sep 2024 16:51:04 +0100 Subject: [PATCH 069/125] Update dependencies --- go.mod | 20 ++++++++++---------- go.sum | 45 ++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index e10feb95..4fb6f6c9 100644 --- a/go.mod +++ b/go.mod @@ -10,17 +10,17 @@ require ( github.com/hashicorp/go-syslog v1.0.0 github.com/hjson/hjson-go/v4 v4.4.0 github.com/kardianos/minwinsvc v1.0.2 - github.com/quic-go/quic-go v0.45.1 - github.com/vishvananda/netlink v1.1.0 - github.com/wlynxg/anet v0.0.4-0.20240806025826-e684438fc7c6 - golang.org/x/crypto v0.25.0 - golang.org/x/net v0.27.0 - golang.org/x/sys v0.22.0 - golang.org/x/text v0.16.0 + github.com/quic-go/quic-go v0.46.0 + github.com/vishvananda/netlink v1.3.0 + github.com/wlynxg/anet v0.0.4 + golang.org/x/crypto v0.27.0 + golang.org/x/net v0.29.0 + golang.org/x/sys v0.25.0 + golang.org/x/text v0.18.0 golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 - nhooyr.io/websocket v1.8.11 + nhooyr.io/websocket v1.8.17 ) require ( @@ -34,7 +34,7 @@ require ( go.uber.org/mock v0.4.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect - golang.org/x/sync v0.7.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/tools v0.23.0 // indirect ) @@ -44,5 +44,5 @@ require ( github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/olekukonko/tablewriter v0.0.5 - github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect + github.com/vishvananda/netns v0.0.4 // indirect ) diff --git a/go.sum b/go.sum index 5ddf4169..f95b4c71 100644 --- a/go.sum +++ b/go.sum @@ -56,8 +56,8 @@ github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/quic-go/quic-go v0.45.1 h1:tPfeYCk+uZHjmDRwHHQmvHRYL2t44ROTujLeFVBmjCA= -github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= +github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -65,13 +65,12 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= -github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= -github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/wlynxg/anet v0.0.4-0.20240806025826-e684438fc7c6 h1:c/wkXIJvpg2oot7iFqPESTBAO9UvhWTBnW97y9aPgyU= -github.com/wlynxg/anet v0.0.4-0.20240806025826-e684438fc7c6/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk= +github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= +github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= +github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= +github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= @@ -79,8 +78,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -93,29 +92,29 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -129,8 +128,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -154,5 +153,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY= -nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= -nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= +nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 361b9fd6fc7ef792880728a9fe34a0620cff7143 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 22 Sep 2024 16:54:58 +0100 Subject: [PATCH 070/125] Update WebSocket dependency to new import path --- go.mod | 2 +- go.sum | 4 ++-- src/core/link_ws.go | 2 +- src/core/link_wss.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 4fb6f6c9..11e7374f 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/Arceliar/ironwood v0.0.0-20240921214443-277f642d5db3 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 + github.com/coder/websocket v1.8.12 github.com/gologme/log v1.3.0 github.com/hashicorp/go-syslog v1.0.0 github.com/hjson/hjson-go/v4 v4.4.0 @@ -20,7 +21,6 @@ require ( golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 - nhooyr.io/websocket v1.8.17 ) require ( diff --git a/go.sum b/go.sum index f95b4c71..8d0046a0 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= +github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -153,5 +155,3 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY= -nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= -nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/src/core/link_ws.go b/src/core/link_ws.go index 7a7d66f7..0602ed28 100644 --- a/src/core/link_ws.go +++ b/src/core/link_ws.go @@ -8,7 +8,7 @@ import ( "time" "github.com/Arceliar/phony" - "nhooyr.io/websocket" + "github.com/coder/websocket" ) type linkWS struct { diff --git a/src/core/link_wss.go b/src/core/link_wss.go index a9a8df24..0bdb4f3a 100644 --- a/src/core/link_wss.go +++ b/src/core/link_wss.go @@ -7,7 +7,7 @@ import ( "net/url" "github.com/Arceliar/phony" - "nhooyr.io/websocket" + "github.com/coder/websocket" ) type linkWSS struct { From e138fa679c8bf32e02f07cc0c3bba5a2dd5e9e9c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 22 Sep 2024 17:05:25 +0100 Subject: [PATCH 071/125] Fix link panic when shutting down (closes #1168) --- src/core/link.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/link.go b/src/core/link.go index 1ead4e32..2eb480d2 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -108,7 +108,9 @@ func (l *links) shutdown() { _ = listener.listener.Close() } for _, link := range l._links { - _ = link._conn.Close() + if link._conn != nil { + _ = link._conn.Close() + } } }) } From b8ab843a98e25d7212beccff3db2b56f0726546c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 23 Sep 2024 22:40:52 +0100 Subject: [PATCH 072/125] Update admin socket response sorting --- src/admin/getpaths.go | 6 +++--- src/admin/getpeers.go | 32 +++++++++++++++++++++----------- src/admin/getsessions.go | 6 +++--- src/admin/gettree.go | 6 +++--- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/admin/getpaths.go b/src/admin/getpaths.go index 34de4532..250f4c6a 100644 --- a/src/admin/getpaths.go +++ b/src/admin/getpaths.go @@ -3,7 +3,7 @@ package admin import ( "encoding/hex" "net" - "sort" + "slices" "strings" "github.com/yggdrasil-network/yggdrasil-go/src/address" @@ -35,8 +35,8 @@ func (a *AdminSocket) getPathsHandler(_ *GetPathsRequest, res *GetPathsResponse) Sequence: p.Sequence, }) } - sort.SliceStable(res.Paths, func(i, j int) bool { - return strings.Compare(res.Paths[i].PublicKey, res.Paths[j].PublicKey) < 0 + slices.SortStableFunc(res.Paths, func(a, b PathEntry) int { + return strings.Compare(a.PublicKey, b.PublicKey) }) return nil } diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index 48234fb1..2c2f8d8a 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -3,7 +3,8 @@ package admin import ( "encoding/hex" "net" - "sort" + "slices" + "strings" "time" "github.com/yggdrasil-network/yggdrasil-go/src/address" @@ -61,17 +62,26 @@ func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse) } res.Peers = append(res.Peers, peer) } - sort.Slice(res.Peers, func(i, j int) bool { - if res.Peers[i].Inbound == res.Peers[j].Inbound { - if res.Peers[i].PublicKey == res.Peers[j].PublicKey { - if res.Peers[i].Priority == res.Peers[j].Priority { - return res.Peers[i].Uptime > res.Peers[j].Uptime - } - return res.Peers[i].Priority < res.Peers[j].Priority - } - return res.Peers[i].PublicKey < res.Peers[j].PublicKey + slices.SortStableFunc(res.Peers, func(a, b PeerEntry) int { + if !a.Inbound && b.Inbound { + return -1 } - return !res.Peers[i].Inbound && res.Peers[j].Inbound + if a.Inbound && !b.Inbound { + return 1 + } + if d := strings.Compare(a.PublicKey, b.PublicKey); d != 0 { + return d + } + if d := a.Priority - b.Priority; d != 0 { + return int(d) + } + if d := a.Cost - b.Cost; d != 0 { + return int(d) + } + if d := a.Uptime - b.Uptime; d != 0 { + return int(d) + } + return 0 }) return nil } diff --git a/src/admin/getsessions.go b/src/admin/getsessions.go index e6702f88..2d76a35b 100644 --- a/src/admin/getsessions.go +++ b/src/admin/getsessions.go @@ -3,7 +3,7 @@ package admin import ( "encoding/hex" "net" - "sort" + "slices" "strings" "github.com/yggdrasil-network/yggdrasil-go/src/address" @@ -36,8 +36,8 @@ func (a *AdminSocket) getSessionsHandler(_ *GetSessionsRequest, res *GetSessions Uptime: s.Uptime.Seconds(), }) } - sort.SliceStable(res.Sessions, func(i, j int) bool { - return strings.Compare(res.Sessions[i].PublicKey, res.Sessions[j].PublicKey) < 0 + slices.SortStableFunc(res.Sessions, func(a, b SessionEntry) int { + return strings.Compare(a.PublicKey, b.PublicKey) }) return nil } diff --git a/src/admin/gettree.go b/src/admin/gettree.go index 4b6f32a8..993827d9 100644 --- a/src/admin/gettree.go +++ b/src/admin/gettree.go @@ -3,7 +3,7 @@ package admin import ( "encoding/hex" "net" - "sort" + "slices" "strings" "github.com/yggdrasil-network/yggdrasil-go/src/address" @@ -34,8 +34,8 @@ func (a *AdminSocket) getTreeHandler(_ *GetTreeRequest, res *GetTreeResponse) er Sequence: d.Sequence, }) } - sort.SliceStable(res.Tree, func(i, j int) bool { - return strings.Compare(res.Tree[i].PublicKey, res.Tree[j].PublicKey) < 0 + slices.SortStableFunc(res.Tree, func(a, b TreeEntry) int { + return strings.Compare(a.PublicKey, b.PublicKey) }) return nil } From 43a1a3de64acfacdadc5c9ff00ca8fdb4b7fdc40 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 28 Sep 2024 18:52:04 -0500 Subject: [PATCH 073/125] update ironwood dependency --- cmd/yggdrasil/main.go | 6 +++--- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 3a00b3fc..0ae8ab42 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -54,10 +54,10 @@ func main() { loglevel := flag.String("loglevel", "info", "loglevel to enable") chuserto := flag.String("user", "", "user (and, optionally, group) to set UID/GID to") flag.Parse() - + done := make(chan struct{}) defer close(done) - + // Catch interrupts from the operating system to exit gracefully. ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) @@ -272,7 +272,7 @@ func main() { n.tun.SetupAdminHandlers(n.admin) } } - + //Windows service shutdown minwinsvc.SetOnExit(func() { logger.Infof("Shutting down service ...") diff --git a/go.mod b/go.mod index 11e7374f..b46110bf 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20240921214443-277f642d5db3 + github.com/Arceliar/ironwood v0.0.0-20240928234310-ca35d0d0d13e github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 github.com/coder/websocket v1.8.12 diff --git a/go.sum b/go.sum index 8d0046a0..91acd28e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20240921214443-277f642d5db3 h1:OJ49qTfdw5MNkpnRraNEsVQbHahSvShh8Z9WYpZrYa0= -github.com/Arceliar/ironwood v0.0.0-20240921214443-277f642d5db3/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= +github.com/Arceliar/ironwood v0.0.0-20240928234310-ca35d0d0d13e h1:fXwNf5X37q+1nKCCDkQ7XTdcCmUef3H3zvaMt+QUO7o= +github.com/Arceliar/ironwood v0.0.0-20240928234310-ca35d0d0d13e/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From c00779c7d3959ddad37ab63923aad567afb176fb Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 29 Sep 2024 20:58:10 +0100 Subject: [PATCH 074/125] Multicast interface detection and shutdown tweaks May help with #1173. --- src/core/link.go | 5 ++++- src/multicast/multicast.go | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/link.go b/src/core/link.go index 2eb480d2..4a8df538 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -422,7 +422,10 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { li := &Listener{ listener: listener, ctx: ctx, - Cancel: cancel, + Cancel: func() { + cancel() + _ = listener.Close() + }, } var options linkOptions diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index 902d7729..32f5dcad 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -190,6 +190,8 @@ func (m *Multicast) _getAllowedInterfaces() map[string]*interfaceInfo { switch { case iface.Flags&net.FlagUp == 0: continue // Ignore interfaces that are down + case iface.Flags&net.FlagRunning == 0: + continue // Ignore interfaces that are not running case iface.Flags&net.FlagMulticast == 0: continue // Ignore non-multicast interfaces case iface.Flags&net.FlagPointToPoint != 0: From 98a6fdb4f2b372c3feb620f0c49f3d7bf696907e Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Sun, 29 Sep 2024 23:05:38 +0300 Subject: [PATCH 075/125] tun: bsd: remove redundant ioctl to set MTU (#1172) wireguard's CreateTUN() sets the MTU using the same ioctl(2), on both FreeBSD and OpenBSD. Tested on OpenBSD (outputwith this patch): ``` # ktrace ./yggdrasil -autoconf | grep Interface 2024/09/24 17:26:29 Interface name: tun0 2024/09/24 17:26:29 Interface IPv6: 201:26e:68f0:502e:f445:13eb:2fe1:f7cd/7 2024/09/24 17:26:29 Interface MTU: 16384 ``` ``` $ ifconfig tun0 | head -n1 tun0: flags=8051 mtu 16384 ``` ``` # kdump | grep ioctl 53097 yggdrasil CALL ioctl(10,SIOCGIFMTU,0xc0000376b8) 53097 yggdrasil RET ioctl 0 53097 yggdrasil CALL ioctl(10,SIOCSIFMTU,0xc0000376c0) 53097 yggdrasil RET ioctl 0 53097 yggdrasil CALL ioctl(10,SIOCGIFMTU,0xc0000377f8) 53097 yggdrasil RET ioctl 0 53097 yggdrasil CALL ioctl(10,_IOW('i',12,0x20),0xc00003777c) 53097 yggdrasil RET ioctl -1 errno 25 Inappropriate ioctl for device "2024/09/24 17:26:29 Error in SIOCSIFADDR_IN6: inappropriate ioctl for device ``` (The completely broken address ioctl is another story...) --- src/tun/tun_bsd.go | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/tun/tun_bsd.go b/src/tun/tun_bsd.go index da5b3297..3064546b 100644 --- a/src/tun/tun_bsd.go +++ b/src/tun/tun_bsd.go @@ -54,11 +54,6 @@ struct in6_ifreq { 290 }; */ -type in6_ifreq_mtu struct { - ifr_name [syscall.IFNAMSIZ]byte - ifru_mtu int -} - type in6_ifreq_addr struct { ifr_name [syscall.IFNAMSIZ]byte ifru_addr sockaddr_in6 @@ -112,26 +107,6 @@ func (tun *TunAdapter) setupAddress(addr string) error { tun.log.Infof("Interface IPv6: %s", addr) tun.log.Infof("Interface MTU: %d", tun.mtu) - // Create the MTU request - var ir in6_ifreq_mtu - copy(ir.ifr_name[:], tun.Name()) - ir.ifru_mtu = int(tun.mtu) - - // Set the MTU - if _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(sfd), uintptr(syscall.SIOCSIFMTU), uintptr(unsafe.Pointer(&ir))); errno != 0 { - err = errno - tun.log.Errorf("Error in SIOCSIFMTU: %v", errno) - - // Fall back to ifconfig to set the MTU - cmd := exec.Command("ifconfig", tun.Name(), "mtu", string(tun.mtu)) - tun.log.Warnf("Using ifconfig as fallback: %v", strings.Join(cmd.Args, " ")) - output, err := cmd.CombinedOutput() - if err != nil { - tun.log.Errorf("SIOCSIFMTU fallback failed: %v.", err) - tun.log.Traceln(string(output)) - } - } - // Create the address request // FIXME: I don't work! var ar in6_ifreq_addr From d6fd305f125ed27708ed4b8afc798bbf3bac67b8 Mon Sep 17 00:00:00 2001 From: Sergey Bobrenok Date: Sun, 29 Sep 2024 23:06:36 +0300 Subject: [PATCH 076/125] Fix Android build with Go 1.23.0 or later (#1166) The `github.com/wlynxg/anet` library depends on the `//go:linkname` linker feature [1]. However, since Go 1.23.0, the usage of `//go:linkname` has been restricted [2]. And now it's necessary to explicitly specify `-checklinkname=0` linker flag to use it. [1] https://github.com/wlynxg/anet/blob/main/README.md#how-to-build-with-go-1230-or-later [2] https://tip.golang.org/doc/go1.23#linker Resolves: #1165 --- contrib/mobile/build | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contrib/mobile/build b/contrib/mobile/build index 3f6b9bfc..9be9529b 100755 --- a/contrib/mobile/build +++ b/contrib/mobile/build @@ -7,6 +7,7 @@ set -ef PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/version} PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)} PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)} +GOVER=$(go version | { read _ _ version _; echo ${version#go}; }) LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" ARGS="-v" @@ -33,6 +34,15 @@ if [ ! $IOS ] && [ ! $ANDROID ]; then exit 1 fi +ver_le() { + printf "$1\n$2\n" | sort -VC +} + +if [ $ANDROID ] && ver_le 1.23.0 $GOVER ; then + # github.com/wlynxg/anet library relies on //go:linkname + LDFLAGS="$LDFLAGS -checklinkname=0" +fi + if [ $IOS ]; then echo "Building framework for iOS" go get golang.org/x/mobile/bind From d1b849588f1dc4bcc2d5c2b3551628d42beeb67b Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 29 Sep 2024 21:23:45 +0100 Subject: [PATCH 077/125] Fix bug where ephemeral links would try to reconnect in a fast loop Helps #1141, although not a complete solution. --- src/core/link.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/link.go b/src/core/link.go index 4a8df538..66cf517d 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -359,8 +359,9 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { if backoffNow() { continue } - return } + // Ephemeral or incoming connections don't reconnect. + return } }() }) From 377bc664c9b2458ea2906fd9e4f3a6788cd1327f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 29 Sep 2024 21:38:56 +0100 Subject: [PATCH 078/125] The `AllowedPublicKeys` option should not apply to multicast listeners Another fix for #1141. --- src/core/api.go | 9 ++++++++- src/core/core.go | 2 +- src/core/link.go | 34 ++++++++++++++++++---------------- src/multicast/multicast.go | 2 +- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/core/api.go b/src/core/api.go index c236b1b5..2aa1ba87 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -150,7 +150,14 @@ func (c *Core) GetSessions() []SessionInfo { // parsed from a string of the form e.g. "tcp://a.b.c.d:e". In the case of a // link-local address, the interface should be provided as the second argument. func (c *Core) Listen(u *url.URL, sintf string) (*Listener, error) { - return c.links.listen(u, sintf) + return c.links.listen(u, sintf, false) +} + +// ListenLocal starts a listener, like the Listen function, but is used for +// more trustworthy situations where you want to ignore AllowedPublicKeys, i.e. +// with multicast listeners. +func (c *Core) ListenLocal(u *url.URL, sintf string) (*Listener, error) { + return c.links.listen(u, sintf, true) } // Address gets the IPv6 address of the Yggdrasil node. This is always a /128 diff --git a/src/core/core.go b/src/core/core.go index 41858cb1..2b206ee1 100644 --- a/src/core/core.go +++ b/src/core/core.go @@ -127,7 +127,7 @@ func New(cert *tls.Certificate, logger Logger, opts ...SetupOption) (*Core, erro c.log.Errorf("Invalid listener URI %q specified, ignoring\n", listenaddr) continue } - if _, err = c.links.listen(u, ""); err != nil { + if _, err = c.links.listen(u, "", false); err != nil { c.log.Errorf("Failed to start listener %q: %s\n", listenaddr, err) } } diff --git a/src/core/link.go b/src/core/link.go index 66cf517d..04fe0266 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -336,7 +336,7 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { // Give the connection to the handler. The handler will block // for the lifetime of the connection. - if err = l.handler(linkType, options, lc, resetBackoff); err != nil && err != io.EOF { + if err = l.handler(linkType, options, lc, resetBackoff, false); err != nil && err != io.EOF { l.core.log.Debugf("Link %s error: %s\n", info.uri, err) } @@ -395,7 +395,7 @@ func (l *links) remove(u *url.URL, sintf string, _ linkType) error { return retErr } -func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { +func (l *links) listen(u *url.URL, sintf string, local bool) (*Listener, error) { ctx, cancel := context.WithCancel(l.core.ctx) var protocol linkProtocol switch strings.ToLower(u.Scheme) { @@ -522,7 +522,7 @@ func (l *links) listen(u *url.URL, sintf string) (*Listener, error) { // Give the connection to the handler. The handler will block // for the lifetime of the connection. - switch err = l.handler(linkTypeIncoming, options, lc, nil); { + switch err = l.handler(linkTypeIncoming, options, lc, nil, local); { case err == nil: case errors.Is(err, io.EOF): case errors.Is(err, net.ErrClosed): @@ -563,7 +563,7 @@ func (l *links) connect(ctx context.Context, u *url.URL, info linkInfo, options return dialer.dial(ctx, u, info, options) } -func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, success func()) error { +func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, success func(), local bool) error { meta := version_getBaseMetadata() meta.publicKey = l.core.public meta.priority = options.priority @@ -606,19 +606,21 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, s } } // Check if we're authorized to connect to this key / IP - var allowed map[[32]byte]struct{} - phony.Block(l.core, func() { - allowed = l.core.config._allowedPublicKeys - }) - isallowed := len(allowed) == 0 - for k := range allowed { - if bytes.Equal(k[:], meta.publicKey) { - isallowed = true - break + if !local { + var allowed map[[32]byte]struct{} + phony.Block(l.core, func() { + allowed = l.core.config._allowedPublicKeys + }) + isallowed := len(allowed) == 0 + for k := range allowed { + if bytes.Equal(k[:], meta.publicKey) { + isallowed = true + break + } + } + if linkType == linkTypeIncoming && !isallowed { + return fmt.Errorf("node public key %q is not in AllowedPublicKeys", hex.EncodeToString(meta.publicKey)) } - } - if linkType == linkTypeIncoming && !isallowed { - return fmt.Errorf("node public key %q is not in AllowedPublicKeys", hex.EncodeToString(meta.publicKey)) } dir := "outbound" diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index 32f5dcad..77ea8a50 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -327,7 +327,7 @@ func (m *Multicast) _announce() { Host: net.JoinHostPort(addrIP.String(), fmt.Sprintf("%d", info.port)), RawQuery: v.Encode(), } - if li, err := m.core.Listen(u, iface.Name); err == nil { + if li, err := m.core.ListenLocal(u, iface.Name); err == nil { m.log.Debugln("Started multicasting on", iface.Name) // Store the listener so that we can stop it later if needed linfo = &listenerInfo{listener: li, time: time.Now(), port: info.port} From 6d5243bd9afb841f8968a481fbfd0b1c79ebfe69 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 29 Sep 2024 22:04:41 +0100 Subject: [PATCH 079/125] Add unit test for `AllowedPublicKeys` --- src/core/core_test.go | 87 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/core/core_test.go b/src/core/core_test.go index cece33c2..f186f43f 100644 --- a/src/core/core_test.go +++ b/src/core/core_test.go @@ -25,6 +25,27 @@ func GetLoggerWithPrefix(prefix string, verbose bool) *log.Logger { return l } +func require_NoError(t *testing.T, err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } +} + +func require_Equal[T comparable](t *testing.T, a, b T) { + t.Helper() + if a != b { + t.Fatalf("%v != %v", a, b) + } +} + +func require_True(t *testing.T, a bool) { + t.Helper() + if !a { + t.Fatal("expected true") + } +} + // CreateAndConnectTwo creates two nodes. nodeB connects to nodeA. // Verbosity flag is passed to logger. func CreateAndConnectTwo(t testing.TB, verbose bool) (nodeA *Core, nodeB *Core) { @@ -201,3 +222,69 @@ func BenchmarkCore_Start_Transfer(b *testing.B) { } <-done } + +func TestAllowedPublicKeys(t *testing.T) { + logger := GetLoggerWithPrefix("", false) + cfgA, cfgB := config.GenerateConfig(), config.GenerateConfig() + require_NoError(t, cfgA.GenerateSelfSignedCertificate()) + require_NoError(t, cfgB.GenerateSelfSignedCertificate()) + + nodeA, err := New(cfgA.Certificate, logger, AllowedPublicKey("abcdef")) + require_NoError(t, err) + defer nodeA.Stop() + + nodeB, err := New(cfgB.Certificate, logger) + require_NoError(t, err) + defer nodeB.Stop() + + u, err := url.Parse("tcp://localhost:0") + require_NoError(t, err) + + l, err := nodeA.Listen(u, "") + require_NoError(t, err) + + u, err = url.Parse("tcp://" + l.Addr().String()) + require_NoError(t, err) + + require_NoError(t, nodeB.AddPeer(u, "")) + + time.Sleep(time.Second) + + peers := nodeB.GetPeers() + require_Equal(t, len(peers), 1) + require_True(t, !peers[0].Up) + require_True(t, peers[0].LastError != nil) +} + +func TestAllowedPublicKeysLocal(t *testing.T) { + logger := GetLoggerWithPrefix("", false) + cfgA, cfgB := config.GenerateConfig(), config.GenerateConfig() + require_NoError(t, cfgA.GenerateSelfSignedCertificate()) + require_NoError(t, cfgB.GenerateSelfSignedCertificate()) + + nodeA, err := New(cfgA.Certificate, logger, AllowedPublicKey("abcdef")) + require_NoError(t, err) + defer nodeA.Stop() + + nodeB, err := New(cfgB.Certificate, logger) + require_NoError(t, err) + defer nodeB.Stop() + + u, err := url.Parse("tcp://localhost:0") + require_NoError(t, err) + + l, err := nodeA.ListenLocal(u, "") + require_NoError(t, err) + + u, err = url.Parse("tcp://" + l.Addr().String()) + require_NoError(t, err) + + require_NoError(t, nodeB.AddPeer(u, "")) + + time.Sleep(time.Second) + + peers := nodeB.GetPeers() + require_Equal(t, len(peers), 1) + require_True(t, peers[0].Up) + require_True(t, peers[0].LastError == nil) +} From ccda1075c08d95804e6f84a789930589356cc9da Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Mon, 30 Sep 2024 16:24:20 +0300 Subject: [PATCH 080/125] Fix ioctl(2) code for OpenBSD (#1175) This cleans up the mess to configure an IP address on a tun(4) device. Handrolling a hardcoded ioctl(2) request is far from perfect, but Go (golang.org/sys/unix) is to blame here. Tested on OpenBSD 7.6 -current where yggdrasil now drives the interface would use of ifconfig or other helpers. --- src/tun/{tun_bsd.go => tun_freebsd.go} | 4 +- src/tun/tun_openbsd.go | 122 +++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 2 deletions(-) rename src/tun/{tun_bsd.go => tun_freebsd.go} (98%) create mode 100644 src/tun/tun_openbsd.go diff --git a/src/tun/tun_bsd.go b/src/tun/tun_freebsd.go similarity index 98% rename from src/tun/tun_bsd.go rename to src/tun/tun_freebsd.go index 3064546b..7b8ab50c 100644 --- a/src/tun/tun_bsd.go +++ b/src/tun/tun_freebsd.go @@ -1,5 +1,5 @@ -//go:build openbsd || freebsd -// +build openbsd freebsd +//go:build freebsd +// +build freebsd package tun diff --git a/src/tun/tun_openbsd.go b/src/tun/tun_openbsd.go new file mode 100644 index 00000000..714db3a8 --- /dev/null +++ b/src/tun/tun_openbsd.go @@ -0,0 +1,122 @@ +//go:build openbsd +// +build openbsd + +package tun + +import ( + "fmt" + "net" + "syscall" + "unsafe" + + "golang.org/x/sys/unix" + + wgtun "golang.zx2c4.com/wireguard/tun" +) + +const ( + SIOCAIFADDR_IN6 = 0x8080691a + ND6_INFINITE_LIFETIME = 0xffffffff +) + +type in6_addrlifetime struct { + ia6t_expire int64 + ia6t_preferred int64 + ia6t_vltime uint32 + ia6t_pltime uint32 +} + +// Match types from the net package, effectively being [16]byte for IPv6 addresses. +type in6_addr [16]uint8 + +type sockaddr_in6 struct { + sin6_len uint8 + sin6_family uint8 + sin6_port uint16 + sin6_flowinfo uint32 + sin6_addr in6_addr + sin6_scope_id uint32 +} + +func (sa6 *sockaddr_in6) setSockaddr(addr [/*16*/]byte /* net.IP or net.IPMask */) { + sa6.sin6_len = uint8(unsafe.Sizeof(*sa6)) + sa6.sin6_family = unix.AF_INET6 + + for i := range sa6.sin6_addr { + sa6.sin6_addr[i] = addr[i] + } +} + +type in6_aliasreq struct { + ifra_name [syscall.IFNAMSIZ]byte + ifra_addr sockaddr_in6 + ifra_dstaddr sockaddr_in6 + ifra_prefixmask sockaddr_in6 + ifra_flags int32 + ifra_lifetime in6_addrlifetime +} + +// Configures the TUN adapter with the correct IPv6 address and MTU. +func (tun *TunAdapter) setup(ifname string, addr string, mtu uint64) error { + iface, err := wgtun.CreateTUN(ifname, int(mtu)) + if err != nil { + return fmt.Errorf("failed to create TUN: %w", err) + } + tun.iface = iface + if mtu, err := iface.MTU(); err == nil { + tun.mtu = getSupportedMTU(uint64(mtu)) + } else { + tun.mtu = 0 + } + if addr != "" { + return tun.setupAddress(addr) + } + return nil +} + +// Configures the "utun" adapter from an existing file descriptor. +func (tun *TunAdapter) setupFD(fd int32, addr string, mtu uint64) error { + return fmt.Errorf("setup via FD not supported on this platform") +} + +func (tun *TunAdapter) setupAddress(addr string) error { + var sfd int + var err error + + ip, prefix, err := net.ParseCIDR(addr) + if err != nil { + tun.log.Errorf("Error in ParseCIDR: %v", err) + return err + } + + // Create system socket + if sfd, err = unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0); err != nil { + tun.log.Printf("Create AF_INET6 socket failed: %v", err) + return err + } + + // Friendly output + tun.log.Infof("Interface name: %s", tun.Name()) + tun.log.Infof("Interface IPv6: %s", addr) + tun.log.Infof("Interface MTU: %d", tun.mtu) + + // Create the address request + var ar in6_aliasreq + copy(ar.ifra_name[:], tun.Name()) + + ar.ifra_addr.setSockaddr(ip) + + prefixmask := net.CIDRMask(prefix.Mask.Size()) + ar.ifra_prefixmask.setSockaddr(prefixmask) + + ar.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME + ar.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME + + // Set the interface address + if err = unix.IoctlSetInt(sfd, SIOCAIFADDR_IN6, int(uintptr(unsafe.Pointer(&ar)))); err != nil { + tun.log.Errorf("Error in SIOCAIFADDR_IN6: %v", err) + return err + } + + return nil +} From 874083da790f69132c468a4f7fa5c07fbd97b5a3 Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Mon, 30 Sep 2024 16:25:04 +0300 Subject: [PATCH 081/125] Replace repeated subscripts with single TrimPrefix (#1176) This stood out to me while reading the code: [7:] is skipping "unix://", so why not do that? Doing so reveals a bug in the last line changed, where chmod(2) failure would print just the prefix, not everything but it... easy to miss, but now this kind of bug can no longer happen. --- src/admin/admin.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/admin/admin.go b/src/admin/admin.go index 7cca1bbb..0b9e5e71 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -238,27 +238,28 @@ func (a *AdminSocket) listen() { if err == nil { switch strings.ToLower(u.Scheme) { case "unix": - if _, err := os.Stat(listenaddr[7:]); err == nil { - a.log.Debugln("Admin socket", listenaddr[7:], "already exists, trying to clean up") - if _, err := net.DialTimeout("unix", listenaddr[7:], time.Second*2); err == nil || err.(net.Error).Timeout() { - a.log.Errorln("Admin socket", listenaddr[7:], "already exists and is in use by another process") + file := strings.TrimPrefix(listenaddr, "unix://") + if _, err := os.Stat(file); err == nil { + a.log.Debugln("Admin socket", file, "already exists, trying to clean up") + if _, err := net.DialTimeout("unix", file, time.Second*2); err == nil || err.(net.Error).Timeout() { + a.log.Errorln("Admin socket", file, "already exists and is in use by another process") os.Exit(1) } else { - if err := os.Remove(listenaddr[7:]); err == nil { - a.log.Debugln(listenaddr[7:], "was cleaned up") + if err := os.Remove(file); err == nil { + a.log.Debugln(file, "was cleaned up") } else { - a.log.Errorln(listenaddr[7:], "already exists and was not cleaned up:", err) + a.log.Errorln(file, "already exists and was not cleaned up:", err) os.Exit(1) } } } - a.listener, err = net.Listen("unix", listenaddr[7:]) + a.listener, err = net.Listen("unix", file) if err == nil { - switch listenaddr[7:8] { + switch file[:1] { case "@": // maybe abstract namespace default: - if err := os.Chmod(listenaddr[7:], 0660); err != nil { - a.log.Warnln("WARNING:", listenaddr[:7], "may have unsafe permissions!") + if err := os.Chmod(file, 0660); err != nil { + a.log.Warnln("WARNING:", file, "may have unsafe permissions!") } } } From d22dc9ecc96d7434e33a7ec3205d5993034183f5 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 10 Oct 2024 09:23:13 +0100 Subject: [PATCH 082/125] TUN: Skip `ErrTooManySegments` --- src/tun/iface.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tun/iface.go b/src/tun/iface.go index 3a4c55f4..f1898281 100644 --- a/src/tun/iface.go +++ b/src/tun/iface.go @@ -1,5 +1,11 @@ package tun +import ( + "errors" + + wgtun "golang.zx2c4.com/wireguard/tun" +) + const TUN_OFFSET_BYTES = 80 // sizeof(virtio_net_hdr) func (tun *TunAdapter) read() { @@ -12,6 +18,10 @@ func (tun *TunAdapter) read() { for { n, err := tun.iface.Read(bufs, sizes, TUN_OFFSET_BYTES) if err != nil { + if errors.Is(err, wgtun.ErrTooManySegments) { + tun.log.Debugln("TUN segments dropped: %v", err) + continue + } tun.log.Errorln("Error reading TUN:", err) return } From 01e73792fe6e505b11e82d2fc05aecba43550908 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 13 Oct 2024 20:04:21 +0100 Subject: [PATCH 083/125] Update to Arceliar/ironwood@0ac2ff3eef3b6be16426f6cf7e0e20cbd75d61aa --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b46110bf..8d524210 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20240928234310-ca35d0d0d13e + github.com/Arceliar/ironwood v0.0.0-20241013112336-0ac2ff3eef3b github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 github.com/coder/websocket v1.8.12 diff --git a/go.sum b/go.sum index 91acd28e..9d9cfa89 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20240928234310-ca35d0d0d13e h1:fXwNf5X37q+1nKCCDkQ7XTdcCmUef3H3zvaMt+QUO7o= -github.com/Arceliar/ironwood v0.0.0-20240928234310-ca35d0d0d13e/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= +github.com/Arceliar/ironwood v0.0.0-20241013112336-0ac2ff3eef3b h1:s2Je0/f6HwM0KI0naVKHvCecAkGwK1FawHtIu/mMPnA= +github.com/Arceliar/ironwood v0.0.0-20241013112336-0ac2ff3eef3b/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From a038a6a8ef90e61840dc96a7ffea39a67b8814c9 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 13 Oct 2024 21:33:47 +0100 Subject: [PATCH 084/125] Update to Arceliar/ironwood@4ea1ec6d68200a2ff6697b408c094f1a5b95bb60 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8d524210..dcce403e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20241013112336-0ac2ff3eef3b + github.com/Arceliar/ironwood v0.0.0-20241013195543-4ea1ec6d6820 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 github.com/coder/websocket v1.8.12 diff --git a/go.sum b/go.sum index 9d9cfa89..c8603166 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20241013112336-0ac2ff3eef3b h1:s2Je0/f6HwM0KI0naVKHvCecAkGwK1FawHtIu/mMPnA= -github.com/Arceliar/ironwood v0.0.0-20241013112336-0ac2ff3eef3b/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= +github.com/Arceliar/ironwood v0.0.0-20241013195543-4ea1ec6d6820 h1:RMcTThCWnFIATUiCYNYZrxL//ZdwDj8Rj9TOk2FAFuM= +github.com/Arceliar/ironwood v0.0.0-20241013195543-4ea1ec6d6820/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From 81e345c1ae96a7fbddfebf07587676333ab8fab9 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 16 Oct 2024 09:46:22 +0100 Subject: [PATCH 085/125] Update to Arceliar/ironwood@f6fb9da97a170f97922e65c6b5afbcc499939503 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dcce403e..7b756860 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20241013195543-4ea1ec6d6820 + github.com/Arceliar/ironwood v0.0.0-20241016082300-f6fb9da97a17 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 github.com/coder/websocket v1.8.12 diff --git a/go.sum b/go.sum index c8603166..2c36a60d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20241013195543-4ea1ec6d6820 h1:RMcTThCWnFIATUiCYNYZrxL//ZdwDj8Rj9TOk2FAFuM= -github.com/Arceliar/ironwood v0.0.0-20241013195543-4ea1ec6d6820/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= +github.com/Arceliar/ironwood v0.0.0-20241016082300-f6fb9da97a17 h1:uOvHqPwu09ndYZQDUL6QvyDcz0M9kwooKYa/PEfLwIU= +github.com/Arceliar/ironwood v0.0.0-20241016082300-f6fb9da97a17/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From 1ee61dcefaa083d79b24e659b2688aeffa837b06 Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Thu, 17 Oct 2024 15:22:22 +0300 Subject: [PATCH 086/125] zap obsolete nonexistent command from usage (#1184) --- cmd/yggdrasilctl/cmd_line_env.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/yggdrasilctl/cmd_line_env.go b/cmd/yggdrasilctl/cmd_line_env.go index b350b7e7..e929b0ba 100644 --- a/cmd/yggdrasilctl/cmd_line_env.go +++ b/cmd/yggdrasilctl/cmd_line_env.go @@ -38,7 +38,6 @@ func (cmdLineEnv *CmdLineEnv) parseFlagsAndArgs() { fmt.Println("Examples:") fmt.Println(" - ", os.Args[0], "list") fmt.Println(" - ", os.Args[0], "getPeers") - fmt.Println(" - ", os.Args[0], "setTunTap name=auto mtu=1500 tap_mode=false") fmt.Println(" - ", os.Args[0], "-endpoint=tcp://localhost:9001 getPeers") fmt.Println(" - ", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getPeers") } From a6429390da831e77c47863e124d39a70e94b47e6 Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Thu, 17 Oct 2024 15:22:46 +0300 Subject: [PATCH 087/125] Use UNIX socket patch from url struct (#1186) No need to extract it again when the url package provides it for us: ``` $ jq -n '{"AdminListen":"unix:///tmp/ygg.sock"}' | ./yggdrasil -useconf | grep 'admin socket' 2024/10/08 22:41:11 UNIX admin socket listening on /tmp/ygg.sock ``` Follow-up on #1176 --- src/admin/admin.go | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/admin/admin.go b/src/admin/admin.go index 0b9e5e71..8823fc5e 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -238,28 +238,27 @@ func (a *AdminSocket) listen() { if err == nil { switch strings.ToLower(u.Scheme) { case "unix": - file := strings.TrimPrefix(listenaddr, "unix://") - if _, err := os.Stat(file); err == nil { - a.log.Debugln("Admin socket", file, "already exists, trying to clean up") - if _, err := net.DialTimeout("unix", file, time.Second*2); err == nil || err.(net.Error).Timeout() { - a.log.Errorln("Admin socket", file, "already exists and is in use by another process") + if _, err := os.Stat(u.Path); err == nil { + a.log.Debugln("Admin socket", u.Path, "already exists, trying to clean up") + if _, err := net.DialTimeout("unix", u.Path, time.Second*2); err == nil || err.(net.Error).Timeout() { + a.log.Errorln("Admin socket", u.Path, "already exists and is in use by another process") os.Exit(1) } else { - if err := os.Remove(file); err == nil { - a.log.Debugln(file, "was cleaned up") + if err := os.Remove(u.Path); err == nil { + a.log.Debugln(u.Path, "was cleaned up") } else { - a.log.Errorln(file, "already exists and was not cleaned up:", err) + a.log.Errorln(u.Path, "already exists and was not cleaned up:", err) os.Exit(1) } } } - a.listener, err = net.Listen("unix", file) + a.listener, err = net.Listen("unix", u.Path) if err == nil { - switch file[:1] { + switch u.Path[:1] { case "@": // maybe abstract namespace default: - if err := os.Chmod(file, 0660); err != nil { - a.log.Warnln("WARNING:", file, "may have unsafe permissions!") + if err := os.Chmod(u.Path, 0660); err != nil { + a.log.Warnln("WARNING:", u.Path, "may have unsafe permissions!") } } } From 0b9469100cf4dbfc5ea904f0182d1575d5c95963 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 17 Oct 2024 13:23:11 +0100 Subject: [PATCH 088/125] Update dependencies --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 7b756860..76641a60 100644 --- a/go.mod +++ b/go.mod @@ -13,11 +13,11 @@ require ( github.com/kardianos/minwinsvc v1.0.2 github.com/quic-go/quic-go v0.46.0 github.com/vishvananda/netlink v1.3.0 - github.com/wlynxg/anet v0.0.4 - golang.org/x/crypto v0.27.0 - golang.org/x/net v0.29.0 - golang.org/x/sys v0.25.0 - golang.org/x/text v0.18.0 + github.com/wlynxg/anet v0.0.5 + golang.org/x/crypto v0.28.0 + golang.org/x/net v0.30.0 + golang.org/x/sys v0.26.0 + golang.org/x/text v0.19.0 golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 diff --git a/go.sum b/go.sum index 2c36a60d..89dd0c7b 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,8 @@ github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQ github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= -github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= -github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= +github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= @@ -80,8 +80,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -94,8 +94,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -115,8 +115,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -130,8 +130,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 0b9c8bd020f971847604e7e1f0e0cfc66e65da49 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 19 Oct 2024 17:09:46 +0100 Subject: [PATCH 089/125] Yggdrasil 0.5.9 (#1191) Changelog updates. Co-authored-by: Neil Alexander --- CHANGELOG.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34c7fe30..39cfa960 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,31 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.9] - 2024-10-19 + +### Added + +* New command line option `-user` for changing the process UID/GID + +### Changed + +* The routing algorithm has been updated with RTT-aware link costing, which should prefer lower latency links over higher latency links where possible + * The calculated cost is an average of the link RTT, but newly established links are costed higher to begin with, such that unstable peerings can be avoided + * Link costs are only used where multiple next-hops are available and will be ignored if there is only one loop-free path to the destination + * This is protocol-compatible with existing v0.5.x nodes but will have the best results when peering with nodes that are also running the latest version + * The `getPeers` endpoint will now report the calculated link cost for each given peer +* Upgrade dependencies + +### Fixed + +* Multicast discovery should now work again when building Yggdrasil as an Android framework +* Multicast discovery will now correctly ignore interfaces that are not marked as running +* Ephemeral links, such as those added by multicast, will no longer try to reconnect in a fast loop, fixing a high CPU issue +* The TUN interface will no longer stop working when hitting a segment read error from vectorised reads +* The `AllowedPublicKeys` option will once again no longer apply to multicast peerings, as was originally intended +* A potential panic when shutting down peering links has been fixed +* A redundant system call for setting MTU on OpenBSD has been removed + ## [0.5.8] - 2024-08-12 ### Fixed From b20ad846a136d619e435a97380a14af3f97376f8 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 20 Oct 2024 21:27:20 +0100 Subject: [PATCH 090/125] When `IfName` is `none`, start queue goroutine, otherwise `iprwc` blocks and some handlers don't run --- src/tun/tun.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tun/tun.go b/src/tun/tun.go index e7ba3a0f..d15a0674 100644 --- a/src/tun/tun.go +++ b/src/tun/tun.go @@ -125,6 +125,7 @@ func (tun *TunAdapter) _start() error { if tun.config.name == "none" || tun.config.name == "dummy" { tun.log.Debugln("Not starting TUN as ifname is none or dummy") tun.isEnabled = false + go tun.queue() go tun.write() return nil } From ef110b018109655633a52b08472b1453fe61068a Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 27 Oct 2024 20:38:15 +0000 Subject: [PATCH 091/125] Update Debian package metadata --- contrib/deb/generate.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contrib/deb/generate.sh b/contrib/deb/generate.sh index 8d39eb1d..5731827c 100644 --- a/contrib/deb/generate.sh +++ b/contrib/deb/generate.sh @@ -50,11 +50,12 @@ echo 9 > /tmp/$PKGNAME/debian/compat cat > /tmp/$PKGNAME/debian/control << EOF Package: $PKGNAME Version: $PKGVERSION -Section: contrib/net -Priority: extra +Section: golang +Priority: optional Architecture: $PKGARCH Replaces: $PKGREPLACES Conflicts: $PKGREPLACES +Depends: systemd Maintainer: Neil Alexander Description: Yggdrasil Network Yggdrasil is an early-stage implementation of a fully end-to-end encrypted IPv6 @@ -102,7 +103,7 @@ then echo "Normalising and updating /etc/yggdrasil/yggdrasil.conf" /usr/bin/yggdrasil -useconf -normaliseconf < /var/backups/yggdrasil.conf.`date +%Y%m%d` > /etc/yggdrasil/yggdrasil.conf - + chown root:yggdrasil /etc/yggdrasil/yggdrasil.conf chmod 640 /etc/yggdrasil/yggdrasil.conf else From ff0ef7ff567b772c6a45a60eb37ed9982a55aac7 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 27 Oct 2024 20:59:05 +0000 Subject: [PATCH 092/125] Update comments in default configuration file --- src/config/config.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/config/config.go b/src/config/config.go index 9a7f7180..64961547 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -43,17 +43,17 @@ type NodeConfig struct { PrivateKey KeyBytes `json:",omitempty" comment:"Your private key. DO NOT share this with anyone!"` PrivateKeyPath string `json:",omitempty" comment:"The path to your private key file in PEM format."` Certificate *tls.Certificate `json:"-"` - Peers []string `comment:"List of connection strings for outbound peer connections in URI format,\ne.g. tls://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j. These connections\nwill obey the operating system routing table, therefore you should\nuse this section when you may connect via different interfaces."` - InterfacePeers map[string][]string `comment:"List of connection strings for outbound peer connections in URI format,\narranged by source interface, e.g. { \"eth0\": [ \"tls://a.b.c.d:e\" ] }.\nNote that SOCKS peerings will NOT be affected by this option and should\ngo in the \"Peers\" section instead."` - Listen []string `comment:"Listen addresses for incoming connections. You will need to add\nlisteners in order to accept incoming peerings from non-local nodes.\nMulticast peer discovery will work regardless of any listeners set\nhere. Each listener should be specified in URI format as above, e.g.\ntls://0.0.0.0:0 or tls://[::]:0 to listen on all interfaces."` + Peers []string `comment:"List of outbound peer connection strings (e.g. tls://a.b.c.d:e or\nsocks://a.b.c.d:e/f.g.h.i:j). Connection strings can contain options,\nsee https://yggdrasil-network.github.io/configurationref.html#peers.\nYggdrasil has no concept of bootstrap nodes - all network traffic\nwill transit peer connections. Therefore make sure to only peer with\nnearby nodes that have good connectivity and low latency. Avoid adding\npeers to this list from distant countries as this will worsen your\nnode's connectivity and performance considerably."` + InterfacePeers map[string][]string `comment:"List of connection strings for outbound peer connections in URI format,\narranged by source interface, e.g. { \"eth0\": [ \"tls://a.b.c.d:e\" ] }.\nYou should only use this option if your machine is multi-homed and you\nwant to establish outbound peer connections on different interfaces.\nOtherwise you should use \"Peers\"."` + Listen []string `comment:"Listen addresses for incoming connections. You will need to add\nlisteners in order to accept incoming peerings from non-local nodes.\nThis is not required if you wish to establish outbound peerings only.\nMulticast peer discovery will work regardless of any listeners set\nhere. Each listener should be specified in URI format as above, e.g.\ntls://0.0.0.0:0 or tls://[::]:0 to listen on all interfaces."` AdminListen string `json:",omitempty" comment:"Listen address for admin connections. Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X. To disable\nthe admin socket, use the value \"none\" instead."` MulticastInterfaces []MulticastInterfaceConfig `comment:"Configuration for which interfaces multicast peer discovery should be\nenabled on. Each entry in the list should be a json object which may\ncontain Regex, Beacon, Listen, and Port. Regex is a regular expression\nwhich is matched against an interface name, and interfaces use the\nfirst configuration that they match gainst. Beacon configures whether\nor not the node should send link-local multicast beacons to advertise\ntheir presence, while listening for incoming connections on Port.\nListen controls whether or not the node listens for multicast beacons\nand opens outgoing connections."` - AllowedPublicKeys []string `comment:"List of peer public keys to allow incoming peering connections\nfrom. If left empty/undefined then all connections will be allowed\nby default. This does not affect outgoing peerings, nor does it\naffect link-local peers discovered via multicast."` + AllowedPublicKeys []string `comment:"List of peer public keys to allow incoming peering connections\nfrom. If left empty/undefined then all connections will be allowed\nby default. This does not affect outgoing peerings, nor does it\naffect link-local peers discovered via multicast.\nWARNING: THIS IS NOT A FIREWALL and DOES NOT limit who can reach\nopen ports or services running on your machine!"` IfName string `comment:"Local network interface name for TUN adapter, or \"auto\" to select\nan interface automatically, or \"none\" to run without TUN."` IfMTU uint64 `comment:"Maximum Transmission Unit (MTU) size for your local TUN interface.\nDefault is the largest supported size for your platform. The lowest\npossible value is 1280."` LogLookups bool `json:",omitempty"` NodeInfoPrivacy bool `comment:"By default, nodeinfo contains some defaults including the platform,\narchitecture and Yggdrasil version. These can help when surveying\nthe network and diagnosing network routing problems. Enabling\nnodeinfo privacy prevents this, so that only items specified in\n\"NodeInfo\" are sent back if specified."` - NodeInfo map[string]interface{} `comment:"Optional node info. This must be a { \"key\": \"value\", ... } map\nor set as null. This is entirely optional but, if set, is visible\nto the whole network on request."` + NodeInfo map[string]interface{} `comment:"Optional nodeinfo. This must be a { \"key\": \"value\", ... } map\nor set as null. This is entirely optional but, if set, is visible\nto the whole network on request."` } type MulticastInterfaceConfig struct { From eef613993fdaa330faeaa187c2d2bca6389c4b86 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 27 Oct 2024 21:06:56 +0000 Subject: [PATCH 093/125] Raise link error when SNI supplied on unsupported link type Closes #1196 --- src/core/link.go | 1 + src/core/link_socks.go | 3 +++ src/core/link_tcp.go | 3 +++ src/core/link_unix.go | 3 +++ src/core/link_ws.go | 3 +++ src/core/link_wss.go | 3 +++ 6 files changed, 16 insertions(+) diff --git a/src/core/link.go b/src/core/link.go index 04fe0266..c2267f24 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -126,6 +126,7 @@ const ErrLinkPinnedKeyInvalid = linkError("pinned public key is invalid") const ErrLinkPasswordInvalid = linkError("invalid password supplied") const ErrLinkUnrecognisedSchema = linkError("link schema unknown") const ErrLinkMaxBackoffInvalid = linkError("max backoff duration invalid") +const ErrLinkSNINotSupported = linkError("SNI not supported on this link type") func (l *links) add(u *url.URL, sintf string, linkType linkType) error { var retErr error diff --git a/src/core/link_socks.go b/src/core/link_socks.go index b92374d4..0f66661b 100644 --- a/src/core/link_socks.go +++ b/src/core/link_socks.go @@ -23,6 +23,9 @@ func (l *links) newLinkSOCKS() *linkSOCKS { } func (l *linkSOCKS) dial(_ context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { + if url.Scheme != "sockstls" && options.tlsSNI != "" { + return nil, ErrLinkSNINotSupported + } var proxyAuth *proxy.Auth if url.User != nil && url.User.Username() != "" { proxyAuth = &proxy.Auth{ diff --git a/src/core/link_tcp.go b/src/core/link_tcp.go index 4ee50941..38c42def 100644 --- a/src/core/link_tcp.go +++ b/src/core/link_tcp.go @@ -67,6 +67,9 @@ func (l *linkTCP) dialersFor(url *url.URL, info linkInfo) ([]*tcpDialer, error) } func (l *linkTCP) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { + if options.tlsSNI != "" { + return nil, ErrLinkSNINotSupported + } dialers, err := l.dialersFor(url, info) if err != nil { return nil, err diff --git a/src/core/link_unix.go b/src/core/link_unix.go index ddbfa0ad..1da6931d 100644 --- a/src/core/link_unix.go +++ b/src/core/link_unix.go @@ -31,6 +31,9 @@ func (l *links) newLinkUNIX() *linkUNIX { } func (l *linkUNIX) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { + if options.tlsSNI != "" { + return nil, ErrLinkSNINotSupported + } addr, err := net.ResolveUnixAddr("unix", url.Path) if err != nil { return nil, err diff --git a/src/core/link_ws.go b/src/core/link_ws.go index 0602ed28..59816098 100644 --- a/src/core/link_ws.go +++ b/src/core/link_ws.go @@ -87,6 +87,9 @@ func (l *links) newLinkWS() *linkWS { } func (l *linkWS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { + if options.tlsSNI != "" { + return nil, ErrLinkSNINotSupported + } wsconn, _, err := websocket.Dial(ctx, url.String(), &websocket.DialOptions{ Subprotocols: []string{"ygg-ws"}, }) diff --git a/src/core/link_wss.go b/src/core/link_wss.go index 0bdb4f3a..f09d7955 100644 --- a/src/core/link_wss.go +++ b/src/core/link_wss.go @@ -27,6 +27,9 @@ func (l *links) newLinkWSS() *linkWSS { } func (l *linkWSS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { + if options.tlsSNI != "" { + return nil, ErrLinkSNINotSupported + } wsconn, _, err := websocket.Dial(ctx, url.String(), &websocket.DialOptions{ Subprotocols: []string{"ygg-ws"}, }) From 834680045a9738df7940cfbab74ccc5e94ff6509 Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Mon, 11 Nov 2024 22:27:02 +0300 Subject: [PATCH 094/125] Create admin socket synchronously before privdrop (#1201) Creating UNIX sockets the listen() goroutine that races against the main one dropping to an unprivileged user may cause startup failure when privdrop happens before privileged filesystem access. Setup or fail in New() and only do listen(2) in listen() to avoid this. ``` # yggdrasil -autoconf -user nobody 2024/11/03 21:15:27 Build name: yggdrasil-go 2024/11/03 21:15:27 Build version: 0.5.9 ... 2024/11/03 21:15:27 Admin socket failed to listen: listen unix /var/run/yggdrasil.sock: bind: permission denied ``` Rerun, now the order is flipped: ``` # yggdrasil -autoconf -user nobody 2024/11/03 21:15:34 Build name: yggdrasil-go 2024/11/03 21:15:34 Build version: 0.5.9 [...] 2024/11/03 21:15:34 UNIX admin socket listening on /var/run/yggdrasil.sock [...] ``` Fixes #927. --- src/admin/admin.go | 90 +++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/admin/admin.go b/src/admin/admin.go index 8823fc5e..996cabd5 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -83,6 +83,52 @@ func New(c *core.Core, log core.Logger, opts ...SetupOption) (*AdminSocket, erro if a.config.listenaddr == "none" || a.config.listenaddr == "" { return nil, nil } + + listenaddr := string(a.config.listenaddr) + u, err := url.Parse(listenaddr) + if err == nil { + switch strings.ToLower(u.Scheme) { + case "unix": + if _, err := os.Stat(u.Path); err == nil { + a.log.Debugln("Admin socket", u.Path, "already exists, trying to clean up") + if _, err := net.DialTimeout("unix", u.Path, time.Second*2); err == nil || err.(net.Error).Timeout() { + a.log.Errorln("Admin socket", u.Path, "already exists and is in use by another process") + os.Exit(1) + } else { + if err := os.Remove(u.Path); err == nil { + a.log.Debugln(u.Path, "was cleaned up") + } else { + a.log.Errorln(u.Path, "already exists and was not cleaned up:", err) + os.Exit(1) + } + } + } + a.listener, err = net.Listen("unix", u.Path) + if err == nil { + switch u.Path[:1] { + case "@": // maybe abstract namespace + default: + if err := os.Chmod(u.Path, 0660); err != nil { + a.log.Warnln("WARNING:", u.Path, "may have unsafe permissions!") + } + } + } + case "tcp": + a.listener, err = net.Listen("tcp", u.Host) + default: + a.listener, err = net.Listen("tcp", listenaddr) + } + } else { + a.listener, err = net.Listen("tcp", listenaddr) + } + if err != nil { + a.log.Errorf("Admin socket failed to listen: %v", err) + os.Exit(1) + } + a.log.Infof("%s admin socket listening on %s", + strings.ToUpper(a.listener.Addr().Network()), + a.listener.Addr().String()) + _ = a.AddHandler("list", "List available commands", []string{}, func(_ json.RawMessage) (interface{}, error) { res := &ListResponse{} for name, handler := range a.handlers { @@ -233,50 +279,6 @@ func (a *AdminSocket) Stop() error { // listen is run by start and manages API connections. func (a *AdminSocket) listen() { - listenaddr := string(a.config.listenaddr) - u, err := url.Parse(listenaddr) - if err == nil { - switch strings.ToLower(u.Scheme) { - case "unix": - if _, err := os.Stat(u.Path); err == nil { - a.log.Debugln("Admin socket", u.Path, "already exists, trying to clean up") - if _, err := net.DialTimeout("unix", u.Path, time.Second*2); err == nil || err.(net.Error).Timeout() { - a.log.Errorln("Admin socket", u.Path, "already exists and is in use by another process") - os.Exit(1) - } else { - if err := os.Remove(u.Path); err == nil { - a.log.Debugln(u.Path, "was cleaned up") - } else { - a.log.Errorln(u.Path, "already exists and was not cleaned up:", err) - os.Exit(1) - } - } - } - a.listener, err = net.Listen("unix", u.Path) - if err == nil { - switch u.Path[:1] { - case "@": // maybe abstract namespace - default: - if err := os.Chmod(u.Path, 0660); err != nil { - a.log.Warnln("WARNING:", u.Path, "may have unsafe permissions!") - } - } - } - case "tcp": - a.listener, err = net.Listen("tcp", u.Host) - default: - a.listener, err = net.Listen("tcp", listenaddr) - } - } else { - a.listener, err = net.Listen("tcp", listenaddr) - } - if err != nil { - a.log.Errorf("Admin socket failed to listen: %v", err) - os.Exit(1) - } - a.log.Infof("%s admin socket listening on %s", - strings.ToUpper(a.listener.Addr().Network()), - a.listener.Addr().String()) defer a.listener.Close() for { conn, err := a.listener.Accept() From 75d2080e53d8b2e98fb471bcc4e561d08ad7f7bc Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Mon, 11 Nov 2024 22:28:28 +0300 Subject: [PATCH 095/125] Set groups when dropping privileges to not leak supplementary group access (#1202) Changing the real and effective user/group IDs and the saved set-user/group-ID is not enough to get rid of intial access permissions. The list of groups must be cleared also, otherwise a process changing from, e.g. `root:root` to `nobody:nobody` retains rights to access `:wheel` files (assuming `root` is a member of the `wheel` group). For example: ``` # id uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty), 5(operator), 20(staff), 31(guest) # ./yggdrasil -autoconf -logto /dev/null -user nobody & [1] 4337 # ps -o command,user,group,supgrp -U nobody COMMAND USER GROUP SUPGRP ./yggdrasil -aut nobody nobody wheel,kmem,sys,tty,operator,staff,guest ``` Fix that so the process runs as mere ``` COMMAND USER GROUP SUPGRP ./yggdrasil -aut nobody nobody nobody ``` Fixes #927. --- cmd/yggdrasil/chuser_unix.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/yggdrasil/chuser_unix.go b/cmd/yggdrasil/chuser_unix.go index 6e802c69..69803773 100644 --- a/cmd/yggdrasil/chuser_unix.go +++ b/cmd/yggdrasil/chuser_unix.go @@ -53,6 +53,9 @@ func chuser(user string) error { gid, _ := strconv.ParseUint(g.Gid, 10, 32) var err error if gid < math.MaxInt { + if err := syscall.Setgroups([]int{int(gid)}); err != nil { + return fmt.Errorf("failed to setgroups %d: %v", gid, err) + } err = syscall.Setgid(int(gid)) } else { err = errors.New("gid too big") @@ -63,6 +66,9 @@ func chuser(user string) error { } } else if u != nil { gid, _ := strconv.ParseUint(u.Gid, 10, 32) + if err := syscall.Setgroups([]int{int(uint32(gid))}); err != nil { + return fmt.Errorf("failed to setgroups %d: %v", gid, err) + } err := syscall.Setgid(int(uint32(gid))) if err != nil { return fmt.Errorf("failed to setgid %d: %v", gid, err) From 42873be09b5912cfbff0053fa94a1cb03112e0cf Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 16 Nov 2024 22:59:03 +0000 Subject: [PATCH 096/125] Reusable peer lookup/dial logic --- cmd/yggdrasil/main.go | 7 ++++++ contrib/mobile/mobile.go | 10 +++++++- src/core/core.go | 1 + src/core/link.go | 38 ++++++++++++++++++++++++++++ src/core/link_quic.go | 29 ++++++++++++--------- src/core/link_socks.go | 46 ++++++++++++++++++++-------------- src/core/link_tcp.go | 54 +++++----------------------------------- src/core/link_tls.go | 36 +++++++++++++-------------- src/core/link_unix.go | 3 --- src/core/link_ws.go | 40 +++++++++++++++++++++-------- src/core/link_wss.go | 48 ++++++++++++++++++++++++++--------- src/core/options.go | 5 ++++ 12 files changed, 193 insertions(+), 124 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 0ae8ab42..3ec6414c 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -191,9 +191,16 @@ func main() { // Set up the Yggdrasil node itself. { + iprange := net.IPNet{ + IP: net.ParseIP("200::"), + Mask: net.CIDRMask(7, 128), + } options := []core.SetupOption{ core.NodeInfo(cfg.NodeInfo), core.NodeInfoPrivacy(cfg.NodeInfoPrivacy), + core.PeerFilter(func(ip net.IP) bool { + return !iprange.Contains(ip) + }), } for _, addr := range cfg.Listen { options = append(options, core.ListenAddress(addr)) diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index 06f48027..abc89f1c 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -53,7 +53,15 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error { } // Set up the Yggdrasil node itself. { - options := []core.SetupOption{} + iprange := net.IPNet{ + IP: net.ParseIP("200::"), + Mask: net.CIDRMask(7, 128), + } + options := []core.SetupOption{ + core.PeerFilter(func(ip net.IP) bool { + return !iprange.Contains(ip) + }), + } for _, peer := range m.config.Peers { options = append(options, core.Peer{URI: peer}) } diff --git a/src/core/core.go b/src/core/core.go index 2b206ee1..a7f9fe96 100644 --- a/src/core/core.go +++ b/src/core/core.go @@ -40,6 +40,7 @@ type Core struct { tls *tls.Config // immutable after startup //_peers map[Peer]*linkInfo // configurable after startup _listeners map[ListenAddress]struct{} // configurable after startup + peerFilter func(ip net.IP) bool // immutable after startup nodeinfo NodeInfo // immutable after startup nodeinfoPrivacy NodeInfoPrivacy // immutable after startup _allowedPublicKeys map[[32]byte]struct{} // configurable after startup diff --git a/src/core/link.go b/src/core/link.go index c2267f24..d7e5b110 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -127,6 +127,7 @@ const ErrLinkPasswordInvalid = linkError("invalid password supplied") const ErrLinkUnrecognisedSchema = linkError("link schema unknown") const ErrLinkMaxBackoffInvalid = linkError("max backoff duration invalid") const ErrLinkSNINotSupported = linkError("SNI not supported on this link type") +const ErrLinkNoSuitableIPs = linkError("no suitable remote IPs") func (l *links) add(u *url.URL, sintf string, linkType linkType) error { var retErr error @@ -653,6 +654,43 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, s return err } +func (l *links) findSuitableIP(url *url.URL, fn func(hostname string, ip net.IP, port int) (net.Conn, error)) (net.Conn, error) { + host, p, err := net.SplitHostPort(url.Host) + if err != nil { + return nil, err + } + port, err := strconv.Atoi(p) + if err != nil { + return nil, err + } + resp, err := net.LookupIP(host) + if err != nil { + return nil, err + } + var _ips [64]net.IP + ips := _ips[:0] + for _, ip := range resp { + if l.core.config.peerFilter != nil && !l.core.config.peerFilter(ip) { + continue + } + ips = append(ips, ip) + } + if len(ips) == 0 { + return nil, ErrLinkNoSuitableIPs + } + for _, ip := range ips { + var conn net.Conn + if conn, err = fn(host, ip, port); err != nil { + url := *url + url.RawQuery = "" + l.core.log.Debugln("Dialling", url.Redacted(), "reported error:", err) + continue + } + return conn, nil + } + return nil, err +} + func urlForLinkInfo(u url.URL) url.URL { u.RawQuery = "" return u diff --git a/src/core/link_quic.go b/src/core/link_quic.go index 9ad5456d..ffb69a6d 100644 --- a/src/core/link_quic.go +++ b/src/core/link_quic.go @@ -51,18 +51,23 @@ func (l *links) newLinkQUIC() *linkQUIC { } func (l *linkQUIC) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { - qc, err := quic.DialAddr(ctx, url.Host, l.tlsconfig, l.quicconfig) - if err != nil { - return nil, err - } - qs, err := qc.OpenStreamSync(ctx) - if err != nil { - return nil, err - } - return &linkQUICStream{ - Connection: qc, - Stream: qs, - }, nil + tlsconfig := l.tlsconfig.Clone() + return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { + tlsconfig.ServerName = hostname + hostport := net.JoinHostPort(ip.String(), fmt.Sprintf("%d", port)) + qc, err := quic.DialAddr(ctx, hostport, l.tlsconfig, l.quicconfig) + if err != nil { + return nil, err + } + qs, err := qc.OpenStreamSync(ctx) + if err != nil { + return nil, err + } + return &linkQUICStream{ + Connection: qc, + Stream: qs, + }, nil + }) } func (l *linkQUIC) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { diff --git a/src/core/link_socks.go b/src/core/link_socks.go index 0f66661b..f33cd190 100644 --- a/src/core/link_socks.go +++ b/src/core/link_socks.go @@ -23,9 +23,6 @@ func (l *links) newLinkSOCKS() *linkSOCKS { } func (l *linkSOCKS) dial(_ context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { - if url.Scheme != "sockstls" && options.tlsSNI != "" { - return nil, ErrLinkSNINotSupported - } var proxyAuth *proxy.Auth if url.User != nil && url.User.Username() != "" { proxyAuth = &proxy.Auth{ @@ -33,21 +30,34 @@ func (l *linkSOCKS) dial(_ context.Context, url *url.URL, info linkInfo, options } proxyAuth.Password, _ = url.User.Password() } - dialer, err := proxy.SOCKS5("tcp", url.Host, proxyAuth, proxy.Direct) - if err != nil { - return nil, fmt.Errorf("failed to configure proxy") - } - pathtokens := strings.Split(strings.Trim(url.Path, "/"), "/") - conn, err := dialer.Dial("tcp", pathtokens[0]) - if err != nil { - return nil, fmt.Errorf("failed to dial: %w", err) - } - if url.Scheme == "sockstls" { - tlsconfig := l.tls.config.Clone() - tlsconfig.ServerName = options.tlsSNI - conn = tls.Client(conn, tlsconfig) - } - return conn, nil + tlsconfig := l.tls.config.Clone() + return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { + hostport := net.JoinHostPort(ip.String(), fmt.Sprintf("%d", port)) + dialer, err := l.tcp.dialerFor(&net.TCPAddr{ + IP: ip, + Port: port, + }, info.sintf) + if err != nil { + return nil, err + } + proxy, err := proxy.SOCKS5("tcp", hostport, proxyAuth, dialer) + if err != nil { + return nil, err + } + pathtokens := strings.Split(strings.Trim(url.Path, "/"), "/") + conn, err := proxy.Dial("tcp", pathtokens[0]) + if err != nil { + return nil, err + } + if url.Scheme == "sockstls" { + tlsconfig.ServerName = hostname + if sni := options.tlsSNI; sni != "" { + tlsconfig.ServerName = sni + } + conn = tls.Client(conn, tlsconfig) + } + return conn, nil + }) } func (l *linkSOCKS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { diff --git a/src/core/link_tcp.go b/src/core/link_tcp.go index 38c42def..3315f5c7 100644 --- a/src/core/link_tcp.go +++ b/src/core/link_tcp.go @@ -5,7 +5,6 @@ import ( "fmt" "net" "net/url" - "strconv" "time" "github.com/Arceliar/phony" @@ -34,59 +33,18 @@ type tcpDialer struct { addr *net.TCPAddr } -func (l *linkTCP) dialersFor(url *url.URL, info linkInfo) ([]*tcpDialer, error) { - host, p, err := net.SplitHostPort(url.Host) - if err != nil { - return nil, err - } - port, err := strconv.Atoi(p) - if err != nil { - return nil, err - } - ips, err := net.LookupIP(host) - if err != nil { - return nil, err - } - dialers := make([]*tcpDialer, 0, len(ips)) - for _, ip := range ips { +func (l *linkTCP) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { + return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { addr := &net.TCPAddr{ IP: ip, Port: port, } - dialer, err := l.dialerFor(addr, info.sintf) + dialer, err := l.tcp.dialerFor(addr, info.sintf) if err != nil { - continue + return nil, err } - dialers = append(dialers, &tcpDialer{ - info: info, - dialer: dialer, - addr: addr, - }) - } - return dialers, nil -} - -func (l *linkTCP) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { - if options.tlsSNI != "" { - return nil, ErrLinkSNINotSupported - } - dialers, err := l.dialersFor(url, info) - if err != nil { - return nil, err - } - if len(dialers) == 0 { - return nil, nil - } - for _, d := range dialers { - var conn net.Conn - conn, err = d.dialer.DialContext(ctx, "tcp", d.addr.String()) - if err != nil { - l.core.log.Warnf("Failed to connect to %s: %s", d.addr, err) - continue - } - return conn, nil - } - return nil, err + return dialer.DialContext(ctx, "tcp", addr.String()) + }) } func (l *linkTCP) listen(ctx context.Context, url *url.URL, sintf string) (net.Listener, error) { diff --git a/src/core/link_tls.go b/src/core/link_tls.go index d51d0ce5..da3c7791 100644 --- a/src/core/link_tls.go +++ b/src/core/link_tls.go @@ -32,28 +32,26 @@ func (l *links) newLinkTLS(tcp *linkTCP) *linkTLS { } func (l *linkTLS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { - dialers, err := l.tcp.dialersFor(url, info) - if err != nil { - return nil, err - } - if len(dialers) == 0 { - return nil, nil - } - for _, d := range dialers { - tlsconfig := l.config.Clone() - tlsconfig.ServerName = options.tlsSNI + tlsconfig := l.config.Clone() + return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { + tlsconfig.ServerName = hostname + if sni := options.tlsSNI; sni != "" { + tlsconfig.ServerName = sni + } + addr := &net.TCPAddr{ + IP: ip, + Port: port, + } + dialer, err := l.tcp.dialerFor(addr, info.sintf) + if err != nil { + return nil, err + } tlsdialer := &tls.Dialer{ - NetDialer: d.dialer, + NetDialer: dialer, Config: tlsconfig, } - var conn net.Conn - conn, err = tlsdialer.DialContext(ctx, "tcp", d.addr.String()) - if err != nil { - continue - } - return conn, nil - } - return nil, err + return tlsdialer.DialContext(ctx, "tcp", addr.String()) + }) } func (l *linkTLS) listen(ctx context.Context, url *url.URL, sintf string) (net.Listener, error) { diff --git a/src/core/link_unix.go b/src/core/link_unix.go index 1da6931d..ddbfa0ad 100644 --- a/src/core/link_unix.go +++ b/src/core/link_unix.go @@ -31,9 +31,6 @@ func (l *links) newLinkUNIX() *linkUNIX { } func (l *linkUNIX) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { - if options.tlsSNI != "" { - return nil, ErrLinkSNINotSupported - } addr, err := net.ResolveUnixAddr("unix", url.Path) if err != nil { return nil, err diff --git a/src/core/link_ws.go b/src/core/link_ws.go index 59816098..86f065a6 100644 --- a/src/core/link_ws.go +++ b/src/core/link_ws.go @@ -2,6 +2,7 @@ package core import ( "context" + "fmt" "net" "net/http" "net/url" @@ -87,18 +88,35 @@ func (l *links) newLinkWS() *linkWS { } func (l *linkWS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { - if options.tlsSNI != "" { - return nil, ErrLinkSNINotSupported - } - wsconn, _, err := websocket.Dial(ctx, url.String(), &websocket.DialOptions{ - Subprotocols: []string{"ygg-ws"}, + return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { + u := *url + u.Host = net.JoinHostPort(ip.String(), fmt.Sprintf("%d", port)) + addr := &net.TCPAddr{ + IP: ip, + Port: port, + } + dialer, err := l.tcp.dialerFor(addr, info.sintf) + if err != nil { + return nil, err + } + wsconn, _, err := websocket.Dial(ctx, u.String(), &websocket.DialOptions{ + HTTPClient: &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: dialer.Dial, + DialContext: dialer.DialContext, + }, + }, + Subprotocols: []string{"ygg-ws"}, + Host: hostname, + }) + if err != nil { + return nil, err + } + return &linkWSConn{ + Conn: websocket.NetConn(ctx, wsconn, websocket.MessageBinary), + }, nil }) - if err != nil { - return nil, err - } - return &linkWSConn{ - Conn: websocket.NetConn(ctx, wsconn, websocket.MessageBinary), - }, nil } func (l *linkWS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { diff --git a/src/core/link_wss.go b/src/core/link_wss.go index f09d7955..4d968c2f 100644 --- a/src/core/link_wss.go +++ b/src/core/link_wss.go @@ -2,8 +2,10 @@ package core import ( "context" + "crypto/tls" "fmt" "net" + "net/http" "net/url" "github.com/Arceliar/phony" @@ -13,6 +15,7 @@ import ( type linkWSS struct { phony.Inbox *links + tlsconfig *tls.Config } type linkWSSConn struct { @@ -21,24 +24,45 @@ type linkWSSConn struct { func (l *links) newLinkWSS() *linkWSS { lwss := &linkWSS{ - links: l, + links: l, + tlsconfig: l.core.config.tls.Clone(), } return lwss } func (l *linkWSS) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { - if options.tlsSNI != "" { - return nil, ErrLinkSNINotSupported - } - wsconn, _, err := websocket.Dial(ctx, url.String(), &websocket.DialOptions{ - Subprotocols: []string{"ygg-ws"}, + tlsconfig := l.tlsconfig.Clone() + return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { + tlsconfig.ServerName = hostname + u := *url + u.Host = net.JoinHostPort(ip.String(), fmt.Sprintf("%d", port)) + addr := &net.TCPAddr{ + IP: ip, + Port: port, + } + dialer, err := l.tcp.dialerFor(addr, info.sintf) + if err != nil { + return nil, err + } + wsconn, _, err := websocket.Dial(ctx, u.String(), &websocket.DialOptions{ + HTTPClient: &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: dialer.Dial, + DialContext: dialer.DialContext, + TLSClientConfig: tlsconfig, + }, + }, + Subprotocols: []string{"ygg-ws"}, + Host: hostname, + }) + if err != nil { + return nil, err + } + return &linkWSConn{ + Conn: websocket.NetConn(ctx, wsconn, websocket.MessageBinary), + }, nil }) - if err != nil { - return nil, err - } - return &linkWSSConn{ - Conn: websocket.NetConn(ctx, wsconn, websocket.MessageBinary), - }, nil } func (l *linkWSS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { diff --git a/src/core/options.go b/src/core/options.go index 581c033b..7e67bfb4 100644 --- a/src/core/options.go +++ b/src/core/options.go @@ -3,6 +3,7 @@ package core import ( "crypto/ed25519" "fmt" + "net" "net/url" ) @@ -24,6 +25,8 @@ func (c *Core) _applyOption(opt SetupOption) (err error) { } case ListenAddress: c.config._listeners[v] = struct{}{} + case PeerFilter: + c.config.peerFilter = v case NodeInfo: c.config.nodeinfo = v case NodeInfoPrivacy: @@ -48,9 +51,11 @@ type Peer struct { type NodeInfo map[string]interface{} type NodeInfoPrivacy bool type AllowedPublicKey ed25519.PublicKey +type PeerFilter func(net.IP) bool func (a ListenAddress) isSetupOption() {} func (a Peer) isSetupOption() {} func (a NodeInfo) isSetupOption() {} func (a NodeInfoPrivacy) isSetupOption() {} func (a AllowedPublicKey) isSetupOption() {} +func (a PeerFilter) isSetupOption() {} From 67ec5a92b33089d1b821717d6e9f96e28f06fe26 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 17 Nov 2024 21:29:26 +0000 Subject: [PATCH 097/125] Fix some lint issues --- src/core/link_tcp.go | 6 ------ src/core/link_wss.go | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/link_tcp.go b/src/core/link_tcp.go index 3315f5c7..e50912d3 100644 --- a/src/core/link_tcp.go +++ b/src/core/link_tcp.go @@ -27,12 +27,6 @@ func (l *links) newLinkTCP() *linkTCP { return lt } -type tcpDialer struct { - info linkInfo - dialer *net.Dialer - addr *net.TCPAddr -} - func (l *linkTCP) dial(ctx context.Context, url *url.URL, info linkInfo, options linkOptions) (net.Conn, error) { return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { addr := &net.TCPAddr{ diff --git a/src/core/link_wss.go b/src/core/link_wss.go index 4d968c2f..1a8d571f 100644 --- a/src/core/link_wss.go +++ b/src/core/link_wss.go @@ -59,7 +59,7 @@ func (l *linkWSS) dial(ctx context.Context, url *url.URL, info linkInfo, options if err != nil { return nil, err } - return &linkWSConn{ + return &linkWSSConn{ Conn: websocket.NetConn(ctx, wsconn, websocket.MessageBinary), }, nil }) From c22a746a1d166b0060ce4b0b0496b82a1a96e29b Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Mon, 18 Nov 2024 00:37:07 +0300 Subject: [PATCH 098/125] Rewrite chuser() for simplicity and correctness (#1203) - Use unambiguous variable names (w/o package name conflict). - Fail on invalid input such as the empty string or `:`. - Do not change group without user, i.e. fail on `:group`. - Parse input using mnemonic APIs. - Do not juggle between integer types. - Unset supplementary groups. - Use set[ug]id(2) to follow the idiom of OpenBSD base programs. (cannot use setres[ug]id(2) as macOS does not have them.) Includes/Supersedes #1202. Fixes #927. I only tested on OpenBSD (so far), but other systems should just work. --- cmd/yggdrasil/chuser_unix.go | 98 ++++++++++--------------------- cmd/yggdrasil/chuser_unix_test.go | 80 +++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 67 deletions(-) create mode 100644 cmd/yggdrasil/chuser_unix_test.go diff --git a/cmd/yggdrasil/chuser_unix.go b/cmd/yggdrasil/chuser_unix.go index 69803773..fc3e5c2c 100644 --- a/cmd/yggdrasil/chuser_unix.go +++ b/cmd/yggdrasil/chuser_unix.go @@ -4,89 +4,53 @@ package main import ( - "errors" "fmt" - "math" - osuser "os/user" + "os/user" "strconv" "strings" - "syscall" + + "golang.org/x/sys/unix" ) -func chuser(user string) error { - group := "" - if i := strings.IndexByte(user, ':'); i >= 0 { - user, group = user[:i], user[i+1:] - } +func chuser(input string) error { + givenUser, givenGroup, _ := strings.Cut(input, ":") - u := (*osuser.User)(nil) - g := (*osuser.Group)(nil) + var ( + err error + usr *user.User + grp *user.Group + uid, gid int + ) - if user != "" { - if _, err := strconv.ParseUint(user, 10, 32); err == nil { - u, err = osuser.LookupId(user) - if err != nil { - return fmt.Errorf("failed to lookup user by id %q: %v", user, err) - } - } else { - u, err = osuser.Lookup(user) - if err != nil { - return fmt.Errorf("failed to lookup user by name %q: %v", user, err) - } + if usr, err = user.LookupId(givenUser); err != nil { + if usr, err = user.Lookup(givenUser); err != nil { + return err } } - if group != "" { - if _, err := strconv.ParseUint(group, 10, 32); err == nil { - g, err = osuser.LookupGroupId(group) - if err != nil { - return fmt.Errorf("failed to lookup group by id %q: %v", user, err) - } - } else { - g, err = osuser.LookupGroup(group) - if err != nil { - return fmt.Errorf("failed to lookup group by name %q: %v", user, err) - } - } + if uid, err = strconv.Atoi(usr.Uid); err != nil { + return err } - if g != nil { - gid, _ := strconv.ParseUint(g.Gid, 10, 32) - var err error - if gid < math.MaxInt { - if err := syscall.Setgroups([]int{int(gid)}); err != nil { - return fmt.Errorf("failed to setgroups %d: %v", gid, err) + if givenGroup != "" { + if grp, err = user.LookupGroupId(givenGroup); err != nil { + if grp, err = user.LookupGroup(givenGroup); err != nil { + return err } - err = syscall.Setgid(int(gid)) - } else { - err = errors.New("gid too big") } - if err != nil { - return fmt.Errorf("failed to setgid %d: %v", gid, err) - } - } else if u != nil { - gid, _ := strconv.ParseUint(u.Gid, 10, 32) - if err := syscall.Setgroups([]int{int(uint32(gid))}); err != nil { - return fmt.Errorf("failed to setgroups %d: %v", gid, err) - } - err := syscall.Setgid(int(uint32(gid))) - if err != nil { - return fmt.Errorf("failed to setgid %d: %v", gid, err) - } + gid, _ = strconv.Atoi(grp.Gid) + } else { + gid, _ = strconv.Atoi(usr.Gid) } - if u != nil { - uid, _ := strconv.ParseUint(u.Uid, 10, 32) - var err error - if uid < math.MaxInt { - err = syscall.Setuid(int(uid)) - } else { - err = errors.New("uid too big") - } - - if err != nil { - return fmt.Errorf("failed to setuid %d: %v", uid, err) - } + if err := unix.Setgroups([]int{gid}); err != nil { + return fmt.Errorf("setgroups: %d: %v", gid, err) + } + if err := unix.Setgid(gid); err != nil { + return fmt.Errorf("setgid: %d: %v", gid, err) + } + if err := unix.Setuid(uid); err != nil { + return fmt.Errorf("setuid: %d: %v", uid, err) } return nil diff --git a/cmd/yggdrasil/chuser_unix_test.go b/cmd/yggdrasil/chuser_unix_test.go new file mode 100644 index 00000000..ad2e3517 --- /dev/null +++ b/cmd/yggdrasil/chuser_unix_test.go @@ -0,0 +1,80 @@ +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris + +package main + +import ( + "testing" + "os/user" +) + +// Usernames must not contain a number sign. +func TestEmptyString (t *testing.T) { + if chuser("") == nil { + t.Fatal("the empty string is not a valid user") + } +} + +// Either omit delimiter and group, or omit both. +func TestEmptyGroup (t *testing.T) { + if chuser("0:") == nil { + t.Fatal("the empty group is not allowed") + } +} + +// Either user only or user and group. +func TestGroupOnly (t *testing.T) { + if chuser(":0") == nil { + t.Fatal("group only is not allowed") + } +} + +// Usenames must not contain the number sign. +func TestInvalidUsername (t *testing.T) { + const username = "#user" + if chuser(username) == nil { + t.Fatalf("'%s' is not a valid username", username) + } +} + +// User IDs must be non-negative. +func TestInvalidUserid (t *testing.T) { + if chuser("-1") == nil { + t.Fatal("User ID cannot be negative") + } +} + +// Change to the current user by ID. +func TestCurrentUserid (t *testing.T) { + usr, err := user.Current() + if err != nil { + t.Fatal(err) + } + + if usr.Uid != "0" { + t.Skip("setgroups(2): Only the superuser may set new groups.") + } + + if err = chuser(usr.Uid); err != nil { + t.Fatal(err) + } +} + +// Change to a common user by name. +func TestCommonUsername (t *testing.T) { + usr, err := user.Current() + if err != nil { + t.Fatal(err) + } + + if usr.Uid != "0" { + t.Skip("setgroups(2): Only the superuser may set new groups.") + } + + if err := chuser("nobody"); err != nil { + if _, ok := err.(user.UnknownUserError); ok { + t.Skip(err) + } + t.Fatal(err) + } +} From 9398cae230170990b5b048f63a22653a714e30ee Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 19 Nov 2024 08:42:27 +0000 Subject: [PATCH 099/125] Expose download/upload rate per peer (#1206) --- cmd/yggdrasilctl/main.go | 12 ++++++++++-- src/admin/admin.go | 16 +++++++++------- src/admin/getpeers.go | 4 ++++ src/core/api.go | 4 ++++ src/core/link.go | 37 ++++++++++++++++++++++++++++++++++--- 5 files changed, 61 insertions(+), 12 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 8a30f438..b73708e6 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -174,9 +174,9 @@ func run() int { if err := json.Unmarshal(recv.Response, &resp); err != nil { panic(err) } - table.SetHeader([]string{"URI", "State", "Dir", "IP Address", "Uptime", "RTT", "RX", "TX", "Pr", "Cost", "Last Error"}) + table.SetHeader([]string{"URI", "State", "Dir", "IP Address", "Uptime", "RTT", "RX", "TX", "Down", "Up", "Pr", "Cost", "Last Error"}) for _, peer := range resp.Peers { - state, lasterr, dir, rtt := "Up", "-", "Out", "-" + state, lasterr, dir, rtt, rxr, txr := "Up", "-", "Out", "-", "-", "-" if !peer.Up { state, lasterr = "Down", fmt.Sprintf("%s ago: %s", peer.LastErrorTime.Round(time.Second), peer.LastError) } else if rttms := float64(peer.Latency.Microseconds()) / 1000; rttms > 0 { @@ -190,6 +190,12 @@ func run() int { uri.RawQuery = "" uristring = uri.String() } + if peer.RXRate > 0 { + rxr = peer.RXRate.String() + "/s" + } + if peer.TXRate > 0 { + txr = peer.TXRate.String() + "/s" + } table.Append([]string{ uristring, state, @@ -199,6 +205,8 @@ func run() int { rtt, peer.RXBytes.String(), peer.TXBytes.String(), + rxr, + txr, fmt.Sprintf("%d", peer.Priority), fmt.Sprintf("%d", peer.Cost), lasterr, diff --git a/src/admin/admin.go b/src/admin/admin.go index 996cabd5..54c1a124 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -356,13 +356,15 @@ type DataUnit uint64 func (d DataUnit) String() string { switch { - case d > 1024*1024*1024*1024: - return fmt.Sprintf("%2.ftb", float64(d)/1024/1024/1024/1024) - case d > 1024*1024*1024: - return fmt.Sprintf("%2.fgb", float64(d)/1024/1024/1024) - case d > 1024*1024: - return fmt.Sprintf("%2.fmb", float64(d)/1024/1024) + case d >= 1024*1024*1024*1024: + return fmt.Sprintf("%2.1fTB", float64(d)/1024/1024/1024/1024) + case d >= 1024*1024*1024: + return fmt.Sprintf("%2.1fGB", float64(d)/1024/1024/1024) + case d >= 1024*1024: + return fmt.Sprintf("%2.1fMB", float64(d)/1024/1024) + case d >= 100: + return fmt.Sprintf("%2.1fKB", float64(d)/1024) default: - return fmt.Sprintf("%2.fkb", float64(d)/1024) + return fmt.Sprintf("%dB", d) } } diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index 2c2f8d8a..34eca243 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -28,6 +28,8 @@ type PeerEntry struct { Cost uint64 `json:"cost"` RXBytes DataUnit `json:"bytes_recvd,omitempty"` TXBytes DataUnit `json:"bytes_sent,omitempty"` + RXRate DataUnit `json:"rate_recvd,omitempty"` + TXRate DataUnit `json:"rate_sent,omitempty"` Uptime float64 `json:"uptime,omitempty"` Latency time.Duration `json:"latency_ms,omitempty"` LastErrorTime time.Duration `json:"last_error_time,omitempty"` @@ -47,6 +49,8 @@ func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse) URI: p.URI, RXBytes: DataUnit(p.RXBytes), TXBytes: DataUnit(p.TXBytes), + RXRate: DataUnit(p.RXRate), + TXRate: DataUnit(p.TXRate), Uptime: p.Uptime.Seconds(), } if p.Latency > 0 { diff --git a/src/core/api.go b/src/core/api.go index 2aa1ba87..cc1bde32 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -33,6 +33,8 @@ type PeerInfo struct { Cost uint64 RXBytes uint64 TXBytes uint64 + RXRate uint64 + TXRate uint64 Uptime time.Duration Latency time.Duration } @@ -87,6 +89,8 @@ func (c *Core) GetPeers() []PeerInfo { peerinfo.Inbound = state.linkType == linkTypeIncoming peerinfo.RXBytes = atomic.LoadUint64(&c.rx) peerinfo.TXBytes = atomic.LoadUint64(&c.tx) + peerinfo.RXRate = atomic.LoadUint64(&c.rxrate) + peerinfo.TXRate = atomic.LoadUint64(&c.txrate) peerinfo.Uptime = time.Since(c.up) } if p, ok := conns[conn]; ok { diff --git a/src/core/link.go b/src/core/link.go index d7e5b110..c21b8db5 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -99,9 +99,36 @@ func (l *links) init(c *Core) error { l._links = make(map[linkInfo]*link) l._listeners = make(map[*Listener]context.CancelFunc) + l.Act(nil, l._updateAverages) return nil } +func (l *links) _updateAverages() { + select { + case <-l.core.ctx.Done(): + return + default: + } + + for _, l := range l._links { + if l._conn == nil { + continue + } + rx := atomic.LoadUint64(&l._conn.rx) + tx := atomic.LoadUint64(&l._conn.tx) + lastrx := atomic.LoadUint64(&l._conn.lastrx) + lasttx := atomic.LoadUint64(&l._conn.lasttx) + atomic.StoreUint64(&l._conn.rxrate, rx-lastrx) + atomic.StoreUint64(&l._conn.txrate, tx-lasttx) + atomic.StoreUint64(&l._conn.lastrx, rx) + atomic.StoreUint64(&l._conn.lasttx, tx) + } + + time.AfterFunc(time.Second, func() { + l.Act(nil, l._updateAverages) + }) +} + func (l *links) shutdown() { phony.Block(l, func() { for listener := range l._listeners { @@ -699,9 +726,13 @@ func urlForLinkInfo(u url.URL) url.URL { type linkConn struct { // tx and rx are at the beginning of the struct to ensure 64-bit alignment // on 32-bit platforms, see https://pkg.go.dev/sync/atomic#pkg-note-BUG - rx uint64 - tx uint64 - up time.Time + rx uint64 + tx uint64 + rxrate uint64 + txrate uint64 + lastrx uint64 + lasttx uint64 + up time.Time net.Conn } From ff9e90c5aa2d7e177577f2d1044c25a278ae2036 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 22 Nov 2024 09:31:38 +0000 Subject: [PATCH 100/125] Update link cost calculation and next-hop selection (update to Arceliar/ironwood@75a6e82) --- go.mod | 2 +- go.sum | 47 ++--------------------------------------------- 2 files changed, 3 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index 76641a60..27fe1110 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20241016082300-f6fb9da97a17 + github.com/Arceliar/ironwood v0.0.0-20241122002527-75a6e82fa380 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 github.com/coder/websocket v1.8.12 diff --git a/go.sum b/go.sum index 89dd0c7b..19674559 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20241016082300-f6fb9da97a17 h1:uOvHqPwu09ndYZQDUL6QvyDcz0M9kwooKYa/PEfLwIU= -github.com/Arceliar/ironwood v0.0.0-20241016082300-f6fb9da97a17/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk= +github.com/Arceliar/ironwood v0.0.0-20241122002527-75a6e82fa380 h1:WRLvBMWzs6NOiPUYA7fMu8XqZFg/clXKorUumfbJNv0= +github.com/Arceliar/ironwood v0.0.0-20241122002527-75a6e82fa380/go.mod h1:SrrElc3FFMpYCODSr11jWbLFeOM8WsY+DbDY/l2AXF0= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= @@ -73,74 +73,31 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4= From b98f98318f9c9f0137f734adc5c6728cc4ae7a2e Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 22 Nov 2024 09:44:30 +0000 Subject: [PATCH 101/125] Tweaks to link handling --- src/core/link.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index c21b8db5..899d73bd 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -154,7 +154,7 @@ const ErrLinkPasswordInvalid = linkError("invalid password supplied") const ErrLinkUnrecognisedSchema = linkError("link schema unknown") const ErrLinkMaxBackoffInvalid = linkError("max backoff duration invalid") const ErrLinkSNINotSupported = linkError("SNI not supported on this link type") -const ErrLinkNoSuitableIPs = linkError("no suitable remote IPs") +const ErrLinkNoSuitableIPs = linkError("peer has no suitable addresses") func (l *links) add(u *url.URL, sintf string, linkType linkType) error { var retErr error @@ -365,8 +365,12 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error { // Give the connection to the handler. The handler will block // for the lifetime of the connection. - if err = l.handler(linkType, options, lc, resetBackoff, false); err != nil && err != io.EOF { - l.core.log.Debugf("Link %s error: %s\n", info.uri, err) + switch err = l.handler(linkType, options, lc, resetBackoff, false); { + case err == nil: + case errors.Is(err, io.EOF): + case errors.Is(err, net.ErrClosed): + default: + l.core.log.Debugf("Link %s error: %s\n", u.Host, err) } // The handler has stopped running so the connection is dead, @@ -697,7 +701,16 @@ func (l *links) findSuitableIP(url *url.URL, fn func(hostname string, ip net.IP, var _ips [64]net.IP ips := _ips[:0] for _, ip := range resp { - if l.core.config.peerFilter != nil && !l.core.config.peerFilter(ip) { + switch { + case ip.IsUnspecified(): + continue + case ip.IsMulticast(): + continue + case ip.IsLinkLocalMulticast(): + continue + case ip.IsInterfaceLocalMulticast(): + continue + case l.core.config.peerFilter != nil && !l.core.config.peerFilter(ip): continue } ips = append(ips, ip) From 2454970e4dbd55d8e9788e0022f4f0ca065e7af5 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 22 Nov 2024 09:47:33 +0000 Subject: [PATCH 102/125] Tweaks to configuration --- src/config/config.go | 6 +++--- src/config/defaults_darwin.go | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/config/config.go b/src/config/config.go index 64961547..5dd7b3d4 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -47,7 +47,7 @@ type NodeConfig struct { InterfacePeers map[string][]string `comment:"List of connection strings for outbound peer connections in URI format,\narranged by source interface, e.g. { \"eth0\": [ \"tls://a.b.c.d:e\" ] }.\nYou should only use this option if your machine is multi-homed and you\nwant to establish outbound peer connections on different interfaces.\nOtherwise you should use \"Peers\"."` Listen []string `comment:"Listen addresses for incoming connections. You will need to add\nlisteners in order to accept incoming peerings from non-local nodes.\nThis is not required if you wish to establish outbound peerings only.\nMulticast peer discovery will work regardless of any listeners set\nhere. Each listener should be specified in URI format as above, e.g.\ntls://0.0.0.0:0 or tls://[::]:0 to listen on all interfaces."` AdminListen string `json:",omitempty" comment:"Listen address for admin connections. Default is to listen for local\nconnections either on TCP/9001 or a UNIX socket depending on your\nplatform. Use this value for yggdrasilctl -endpoint=X. To disable\nthe admin socket, use the value \"none\" instead."` - MulticastInterfaces []MulticastInterfaceConfig `comment:"Configuration for which interfaces multicast peer discovery should be\nenabled on. Each entry in the list should be a json object which may\ncontain Regex, Beacon, Listen, and Port. Regex is a regular expression\nwhich is matched against an interface name, and interfaces use the\nfirst configuration that they match gainst. Beacon configures whether\nor not the node should send link-local multicast beacons to advertise\ntheir presence, while listening for incoming connections on Port.\nListen controls whether or not the node listens for multicast beacons\nand opens outgoing connections."` + MulticastInterfaces []MulticastInterfaceConfig `comment:"Configuration for which interfaces multicast peer discovery should be\nenabled on. Regex is a regular expression which is matched against an\ninterface name, and interfaces use the first configuration that they\nmatch against. Beacon controls whether or not your node advertises its\npresence to others, whereas Listen controls whether or not your node\nlistens out for and tries to connect to other advertising nodes. See\nhttps://yggdrasil-network.github.io/configurationref.html#multicastinterfaces\nfor more supported options."` AllowedPublicKeys []string `comment:"List of peer public keys to allow incoming peering connections\nfrom. If left empty/undefined then all connections will be allowed\nby default. This does not affect outgoing peerings, nor does it\naffect link-local peers discovered via multicast.\nWARNING: THIS IS NOT A FIREWALL and DOES NOT limit who can reach\nopen ports or services running on your machine!"` IfName string `comment:"Local network interface name for TUN adapter, or \"auto\" to select\nan interface automatically, or \"none\" to run without TUN."` IfMTU uint64 `comment:"Maximum Transmission Unit (MTU) size for your local TUN interface.\nDefault is the largest supported size for your platform. The lowest\npossible value is 1280."` @@ -60,8 +60,8 @@ type MulticastInterfaceConfig struct { Regex string Beacon bool Listen bool - Port uint16 - Priority uint64 // really uint8, but gobind won't export it + Port uint16 `json:",omitempty"` + Priority uint64 `json:",omitempty"` // really uint8, but gobind won't export it Password string } diff --git a/src/config/defaults_darwin.go b/src/config/defaults_darwin.go index e851d6b9..11da7484 100644 --- a/src/config/defaults_darwin.go +++ b/src/config/defaults_darwin.go @@ -8,7 +8,7 @@ package config func getDefaults() platformDefaultParameters { return platformDefaultParameters{ // Admin - DefaultAdminListen: "unix:///var/run/yggdrasil.sock", + DefaultAdminListen: "tcp://localhost:9001", // Configuration (used for yggdrasilctl) DefaultConfigFile: "/etc/yggdrasil.conf", @@ -17,6 +17,7 @@ func getDefaults() platformDefaultParameters { DefaultMulticastInterfaces: []MulticastInterfaceConfig{ {Regex: "en.*", Beacon: true, Listen: true}, {Regex: "bridge.*", Beacon: true, Listen: true}, + {Regex: "awdl0", Beacon: false, Listen: false}, }, // TUN From d3b4de46ea156b63e925909b957ff6138e6b07ba Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 23 Nov 2024 13:43:34 +0000 Subject: [PATCH 103/125] Improvements to how link shutdowns are handled --- src/core/link.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index 899d73bd..f30016f9 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -131,8 +131,8 @@ func (l *links) _updateAverages() { func (l *links) shutdown() { phony.Block(l, func() { - for listener := range l._listeners { - _ = listener.listener.Close() + for _, cancel := range l._listeners { + cancel() } for _, link := range l._links { if link._conn != nil { @@ -429,7 +429,7 @@ func (l *links) remove(u *url.URL, sintf string, _ linkType) error { } func (l *links) listen(u *url.URL, sintf string, local bool) (*Listener, error) { - ctx, cancel := context.WithCancel(l.core.ctx) + ctx, ctxcancel := context.WithCancel(l.core.ctx) var protocol linkProtocol switch strings.ToLower(u.Scheme) { case "tcp": @@ -445,21 +445,25 @@ func (l *links) listen(u *url.URL, sintf string, local bool) (*Listener, error) case "wss": protocol = l.wss default: - cancel() + ctxcancel() return nil, ErrLinkUnrecognisedSchema } listener, err := protocol.listen(ctx, u, sintf) if err != nil { - cancel() + ctxcancel() return nil, err } + addr := listener.Addr() + cancel := func() { + ctxcancel() + if err := listener.Close(); err != nil && !errors.Is(err, net.ErrClosed) { + l.core.log.Warnf("Error closing %s listener %s: %s", strings.ToUpper(u.Scheme), addr, err) + } + } li := &Listener{ listener: listener, ctx: ctx, - Cancel: func() { - cancel() - _ = listener.Close() - }, + Cancel: cancel, } var options linkOptions @@ -482,10 +486,11 @@ func (l *links) listen(u *url.URL, sintf string, local bool) (*Listener, error) }) go func() { - l.core.log.Infof("%s listener started on %s", strings.ToUpper(u.Scheme), li.listener.Addr()) - defer l.core.log.Infof("%s listener stopped on %s", strings.ToUpper(u.Scheme), li.listener.Addr()) + l.core.log.Infof("%s listener started on %s", strings.ToUpper(u.Scheme), addr) defer phony.Block(l, func() { + cancel() delete(l._listeners, li) + l.core.log.Infof("%s listener stopped on %s", strings.ToUpper(u.Scheme), addr) }) for { conn, err := li.listener.Accept() From 7790a19e4c78da866bb29c653558a3bfba363ffe Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 23 Nov 2024 14:49:48 +0000 Subject: [PATCH 104/125] New detail in `getMulticastInterfaces` admin endpoint --- cmd/yggdrasilctl/main.go | 16 +++++++++++++-- src/config/defaults_darwin.go | 2 +- src/multicast/admin.go | 37 ++++++++++++++++++++++++++++++----- src/multicast/multicast.go | 18 +++++++++-------- 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index b73708e6..ca0bce1a 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -281,9 +281,21 @@ func run() int { if err := json.Unmarshal(recv.Response, &resp); err != nil { panic(err) } - table.SetHeader([]string{"Interface"}) + fmtBool := func(b bool) string { + if b { + return "Yes" + } + return "-" + } + table.SetHeader([]string{"Name", "Listen Address", "Beacon", "Listen", "Password"}) for _, p := range resp.Interfaces { - table.Append([]string{p}) + table.Append([]string{ + p.Name, + p.Address, + fmtBool(p.Beacon), + fmtBool(p.Listen), + fmtBool(p.Password), + }) } table.Render() diff --git a/src/config/defaults_darwin.go b/src/config/defaults_darwin.go index 11da7484..5f44ef59 100644 --- a/src/config/defaults_darwin.go +++ b/src/config/defaults_darwin.go @@ -8,7 +8,7 @@ package config func getDefaults() platformDefaultParameters { return platformDefaultParameters{ // Admin - DefaultAdminListen: "tcp://localhost:9001", + DefaultAdminListen: "unix:///var/run/yggdrasil.sock", // Configuration (used for yggdrasilctl) DefaultConfigFile: "/etc/yggdrasil.conf", diff --git a/src/multicast/admin.go b/src/multicast/admin.go index 8b29716d..0042f519 100644 --- a/src/multicast/admin.go +++ b/src/multicast/admin.go @@ -2,20 +2,47 @@ package multicast import ( "encoding/json" + "slices" + "strings" + "github.com/Arceliar/phony" "github.com/yggdrasil-network/yggdrasil-go/src/admin" ) type GetMulticastInterfacesRequest struct{} type GetMulticastInterfacesResponse struct { - Interfaces []string `json:"multicast_interfaces"` + Interfaces []MulticastInterfaceState `json:"multicast_interfaces"` +} + +type MulticastInterfaceState struct { + Name string `json:"name"` + Address string `json:"address"` + Beacon bool `json:"beacon"` + Listen bool `json:"listen"` + Password bool `json:"password"` } func (m *Multicast) getMulticastInterfacesHandler(_ *GetMulticastInterfacesRequest, res *GetMulticastInterfacesResponse) error { - res.Interfaces = []string{} - for _, v := range m.Interfaces() { - res.Interfaces = append(res.Interfaces, v.Name) - } + res.Interfaces = []MulticastInterfaceState{} + phony.Block(m, func() { + for name, intf := range m._interfaces { + is := MulticastInterfaceState{ + Name: intf.iface.Name, + Beacon: intf.beacon, + Listen: intf.listen, + Password: len(intf.password) > 0, + } + if li := m._listeners[name]; li != nil && li.listener != nil { + is.Address = li.listener.Addr().String() + } else { + is.Address = "-" + } + res.Interfaces = append(res.Interfaces, is) + } + }) + slices.SortStableFunc(res.Interfaces, func(a, b MulticastInterfaceState) int { + return strings.Compare(a.Name, b.Name) + }) return nil } diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index 77ea8a50..9134501c 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -156,7 +156,13 @@ func (m *Multicast) _updateInterfaces() { delete(interfaces, name) continue } - info.addrs = addrs + for _, addr := range addrs { + addrIP, _, err := net.ParseCIDR(addr.String()) + if err != nil || addrIP.To4() != nil || !addrIP.IsLinkLocalUnicast() { + continue + } + info.addrs = append(info.addrs, addr) + } interfaces[name] = info m.log.Debugf("Discovered addresses for interface %s: %s", name, addrs) } @@ -299,13 +305,9 @@ func (m *Multicast) _announce() { for _, info := range m._interfaces { iface := info.iface for _, addr := range info.addrs { - addrIP, _, _ := net.ParseCIDR(addr.String()) - // Ignore IPv4 addresses - if addrIP.To4() != nil { - continue - } - // Ignore non-link-local addresses - if !addrIP.IsLinkLocalUnicast() { + addrIP, _, err := net.ParseCIDR(addr.String()) + // Ignore IPv4 addresses or non-link-local addresses + if err != nil || addrIP.To4() != nil || !addrIP.IsLinkLocalUnicast() { continue } if info.listen { From bdb2d399c5776a80ea81164f1e9b8013fa934775 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 23 Nov 2024 14:55:14 +0000 Subject: [PATCH 105/125] Update dependencies --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 27fe1110..987a3554 100644 --- a/go.mod +++ b/go.mod @@ -14,10 +14,10 @@ require ( github.com/quic-go/quic-go v0.46.0 github.com/vishvananda/netlink v1.3.0 github.com/wlynxg/anet v0.0.5 - golang.org/x/crypto v0.28.0 - golang.org/x/net v0.30.0 - golang.org/x/sys v0.26.0 - golang.org/x/text v0.19.0 + golang.org/x/crypto v0.29.0 + golang.org/x/net v0.31.0 + golang.org/x/sys v0.27.0 + golang.org/x/text v0.20.0 golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 @@ -34,7 +34,7 @@ require ( go.uber.org/mock v0.4.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect - golang.org/x/sync v0.8.0 // indirect + golang.org/x/sync v0.9.0 // indirect golang.org/x/tools v0.23.0 // indirect ) diff --git a/go.sum b/go.sum index 19674559..8531a2a3 100644 --- a/go.sum +++ b/go.sum @@ -75,25 +75,25 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= From 3ed4a92288ee47dc388af9bf23e0bf66bbab96ae Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 24 Nov 2024 12:56:24 +0000 Subject: [PATCH 106/125] Yggdrasil 0.5.10 (#1207) Changelog updates. Co-authored-by: Neil Alexander --- CHANGELOG.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39cfa960..c442353e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,31 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.10] - 2024-11-24 + +### Added + +* The `getPeers` admin endpoint will now report the current transmit/receive rate for each given peer +* The `getMulticastInterfaces` admin endpoint now reports much more useful information about each interface, rather than just a list of interface names + +### Changed + +* Minor tweaks to the routing algorithm: + * The next-hop selection will now prefer shorter paths when the costed distance is otherwise equal, tiebreaking on peering uptime to fall back to more stable paths + * Link cost calculations have been smoothed out, making the costs less sensitive to sudden spikes in latency +* Reusable name lookup and peer connection logic across different peering types for more consistent behaviour +* Some comments in the configuration file have been revised for clarity +* Upgrade dependencies + +### Fixed + +* Nodes with `IfName` set to `none` will now correctly respond to debug RPC requests +* The admin socket will now be created reliably before dropping privileges with `-user` +* Clear supplementary groups when providing a group ID as well as a user ID to `-user` +* SOCKS and WebSocket peerings should now use the correct source interface when specified in `InterfacePeers` +* `Peers` and `InterfacePeers` addresses that are obviously invalid (such as unspecified or multicast addresses) will now be correctly ignored +* Listeners should now shut down correctly, which should resolve issues where multicast listeners for specific interfaces would not come back up or would log errors + ## [0.5.9] - 2024-10-19 ### Added From b436052b2d7ff9f3cc3acd3c8a55396fa2308563 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 10 Dec 2024 19:02:13 +0000 Subject: [PATCH 107/125] Update to Arceliar/ironwood@9deb08d --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 987a3554..a2909018 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20241122002527-75a6e82fa380 + github.com/Arceliar/ironwood v0.0.0-20241210120540-9deb08d9f8f9 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 github.com/coder/websocket v1.8.12 diff --git a/go.sum b/go.sum index 8531a2a3..d62e2ddb 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20241122002527-75a6e82fa380 h1:WRLvBMWzs6NOiPUYA7fMu8XqZFg/clXKorUumfbJNv0= -github.com/Arceliar/ironwood v0.0.0-20241122002527-75a6e82fa380/go.mod h1:SrrElc3FFMpYCODSr11jWbLFeOM8WsY+DbDY/l2AXF0= +github.com/Arceliar/ironwood v0.0.0-20241210120540-9deb08d9f8f9 h1:myI8fs7+Iw6g/ywvY9QNQOEzny51AklMz4sF0ErtTm8= +github.com/Arceliar/ironwood v0.0.0-20241210120540-9deb08d9f8f9/go.mod h1:SrrElc3FFMpYCODSr11jWbLFeOM8WsY+DbDY/l2AXF0= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From 83ec58afc763ff89d9664876ed2e95fb5842985a Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Thu, 12 Dec 2024 21:37:02 +0300 Subject: [PATCH 108/125] Use unveil(2) on OpenBSD (#1194) After #1175 removed ioctl(2) fallback code shelling out to ifconfig(8), there is no code left (compiled on OpenBSD) that would fork(2) or execve(2). Drop the ability to run any executable file to double down on this, thus reducing the attack surface of this this experimental, internet facing daemon running as root. pledge(2) is doable, but needs more polish. unveil(2), however, is as simple as it gets. On other systems, this code is a NOOP, but can still help to implement similar safety belts. --- cmd/yggdrasil/main.go | 16 ++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 3 files changed, 19 insertions(+) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 3ec6414c..b3cbecf0 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -14,6 +14,8 @@ import ( "strings" "syscall" + "suah.dev/protect" + "github.com/gologme/log" gsyslog "github.com/hashicorp/go-syslog" "github.com/hjson/hjson-go/v4" @@ -39,6 +41,20 @@ type node struct { // The main function is responsible for configuring and starting Yggdrasil. func main() { + // Not all operations are coverable with pledge(2), so immediately + // limit file system access with unveil(2), effectively preventing + // "proc exec" promises right from the start: + // + // - read arbitrary config file + // - create/write arbitrary log file + // - read/write/chmod/remove admin socket, if at all + if err := protect.Unveil("/", "rwc"); err != nil { + panic(fmt.Sprintf("unveil: / rwc: %v", err)) + } + if err := protect.UnveilBlock(); err != nil { + panic(fmt.Sprintf("unveil: %v", err)) + } + genconf := flag.Bool("genconf", false, "print a new config to stdout") useconf := flag.Bool("useconf", false, "read HJSON/JSON config from stdin") useconffile := flag.String("useconffile", "", "read HJSON/JSON config from specified file path") diff --git a/go.mod b/go.mod index a2909018..5608f588 100644 --- a/go.mod +++ b/go.mod @@ -45,4 +45,5 @@ require ( github.com/mattn/go-runewidth v0.0.15 // indirect github.com/olekukonko/tablewriter v0.0.5 github.com/vishvananda/netns v0.0.4 // indirect + suah.dev/protect v1.2.4 ) diff --git a/go.sum b/go.sum index d62e2ddb..061a0769 100644 --- a/go.sum +++ b/go.sum @@ -112,3 +112,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ= gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259/go.mod h1:AVgIgHMwK63XvmAzWG9vLQ41YnVHN0du0tEC46fI7yY= +suah.dev/protect v1.2.4 h1:iVZG/zQB63FKNpITDYM/cXoAeCTIjCiXHuFVByJFDzg= +suah.dev/protect v1.2.4/go.mod h1:vVrquYO3u1Ep9Ez2z8x+6N6/czm+TBmWKZfiXU2tb54= From b2b0396d48ee5d2803a14a5d9d9bd4f86b11d792 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 12 Dec 2024 18:42:53 +0000 Subject: [PATCH 109/125] Update dependencies --- go.mod | 18 +++++++++--------- go.sum | 36 +++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 5608f588..a77ca47d 100644 --- a/go.mod +++ b/go.mod @@ -14,10 +14,10 @@ require ( github.com/quic-go/quic-go v0.46.0 github.com/vishvananda/netlink v1.3.0 github.com/wlynxg/anet v0.0.5 - golang.org/x/crypto v0.29.0 - golang.org/x/net v0.31.0 - golang.org/x/sys v0.27.0 - golang.org/x/text v0.20.0 + golang.org/x/crypto v0.31.0 + golang.org/x/net v0.32.0 + golang.org/x/sys v0.28.0 + golang.org/x/text v0.21.0 golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 @@ -34,16 +34,16 @@ require ( go.uber.org/mock v0.4.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect - golang.org/x/sync v0.9.0 // indirect + golang.org/x/sync v0.10.0 // indirect golang.org/x/tools v0.23.0 // indirect ) require ( github.com/VividCortex/ewma v1.2.0 // indirect - github.com/fatih/color v1.15.0 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/olekukonko/tablewriter v0.0.5 - github.com/vishvananda/netns v0.0.4 // indirect + github.com/vishvananda/netns v0.0.5 // indirect suah.dev/protect v1.2.4 ) diff --git a/go.sum b/go.sum index 061a0769..8aae0a77 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3C github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -45,11 +45,11 @@ github.com/kardianos/minwinsvc v1.0.2/go.mod h1:LUZNYhNmxujx2tR7FbdxqYJ9XDDoCd3M github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= @@ -69,31 +69,33 @@ github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk= github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= -github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= +github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= From 2d587740c11e136dbc094be206bfaeeda8559d3f Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Thu, 12 Dec 2024 21:48:24 +0300 Subject: [PATCH 110/125] genkeys, yggdrasilctl: Use pledge(2) on OpenBSD (#1193) Restrict system operations of CLI tools with https://man.openbsd.org/pledge.2. https://pkg.go.dev/suah.dev/protect abstracts the OS specific code, i.e. is a NOOP on non-OpenBSD systems. This PR is to gauge upstream interest in this direction; my OpenBSD port of yggdrasil already pledges the daemon, resulting in minimal runtime privileges, but there are still a few rough edges: https://github.com/jasperla/openbsd-wip/blob/master/net/yggdrasil/patches/patch-cmd_yggdrasil_main_go#L80 --------- Co-authored-by: Neil --- cmd/genkeys/main.go | 6 ++++++ cmd/yggdrasilctl/main.go | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/cmd/genkeys/main.go b/cmd/genkeys/main.go index 36107c0a..d1a15346 100644 --- a/cmd/genkeys/main.go +++ b/cmd/genkeys/main.go @@ -18,6 +18,8 @@ import ( "runtime" "time" + "suah.dev/protect" + "github.com/yggdrasil-network/yggdrasil-go/src/address" ) @@ -27,6 +29,10 @@ type keySet struct { } func main() { + if err := protect.Pledge("stdio"); err != nil { + panic(err) + } + threads := runtime.GOMAXPROCS(0) fmt.Println("Threads:", threads) start := time.Now() diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index ca0bce1a..51c25dcd 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -13,6 +13,8 @@ import ( "strings" "time" + "suah.dev/protect" + "github.com/olekukonko/tablewriter" "github.com/yggdrasil-network/yggdrasil-go/src/admin" "github.com/yggdrasil-network/yggdrasil-go/src/core" @@ -22,6 +24,11 @@ import ( ) func main() { + // read config, speak DNS/TCP and/or over a UNIX socket + if err := protect.Pledge("stdio rpath inet unix dns"); err != nil { + panic(err) + } + // makes sure we can use defer and still return an error code to the OS os.Exit(run()) } @@ -78,6 +85,11 @@ func run() int { panic(err) } + // config and socket are done, work without unprivileges + if err := protect.Pledge("stdio"); err != nil { + panic(err) + } + logger.Println("Connected") defer conn.Close() From 69451fe969bfadb779bed4eecc46f604800bdd0d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 12 Dec 2024 19:07:55 +0000 Subject: [PATCH 111/125] Specify TLS 1.2-TLS 1.3 supported range for client connections Should fix #1208. --- src/core/link_quic.go | 2 ++ src/core/link_socks.go | 2 ++ src/core/link_tls.go | 2 ++ src/core/link_wss.go | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/core/link_quic.go b/src/core/link_quic.go index ffb69a6d..d23ab184 100644 --- a/src/core/link_quic.go +++ b/src/core/link_quic.go @@ -54,6 +54,8 @@ func (l *linkQUIC) dial(ctx context.Context, url *url.URL, info linkInfo, option tlsconfig := l.tlsconfig.Clone() return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { tlsconfig.ServerName = hostname + tlsconfig.MinVersion = tls.VersionTLS12 + tlsconfig.MaxVersion = tls.VersionTLS13 hostport := net.JoinHostPort(ip.String(), fmt.Sprintf("%d", port)) qc, err := quic.DialAddr(ctx, hostport, l.tlsconfig, l.quicconfig) if err != nil { diff --git a/src/core/link_socks.go b/src/core/link_socks.go index f33cd190..495c8233 100644 --- a/src/core/link_socks.go +++ b/src/core/link_socks.go @@ -51,6 +51,8 @@ func (l *linkSOCKS) dial(_ context.Context, url *url.URL, info linkInfo, options } if url.Scheme == "sockstls" { tlsconfig.ServerName = hostname + tlsconfig.MinVersion = tls.VersionTLS12 + tlsconfig.MaxVersion = tls.VersionTLS13 if sni := options.tlsSNI; sni != "" { tlsconfig.ServerName = sni } diff --git a/src/core/link_tls.go b/src/core/link_tls.go index da3c7791..55da8597 100644 --- a/src/core/link_tls.go +++ b/src/core/link_tls.go @@ -35,6 +35,8 @@ func (l *linkTLS) dial(ctx context.Context, url *url.URL, info linkInfo, options tlsconfig := l.config.Clone() return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { tlsconfig.ServerName = hostname + tlsconfig.MinVersion = tls.VersionTLS12 + tlsconfig.MaxVersion = tls.VersionTLS13 if sni := options.tlsSNI; sni != "" { tlsconfig.ServerName = sni } diff --git a/src/core/link_wss.go b/src/core/link_wss.go index 1a8d571f..1d618324 100644 --- a/src/core/link_wss.go +++ b/src/core/link_wss.go @@ -34,6 +34,8 @@ func (l *linkWSS) dial(ctx context.Context, url *url.URL, info linkInfo, options tlsconfig := l.tlsconfig.Clone() return l.links.findSuitableIP(url, func(hostname string, ip net.IP, port int) (net.Conn, error) { tlsconfig.ServerName = hostname + tlsconfig.MinVersion = tls.VersionTLS12 + tlsconfig.MaxVersion = tls.VersionTLS13 u := *url u.Host = net.JoinHostPort(ip.String(), fmt.Sprintf("%d", port)) addr := &net.TCPAddr{ From 7adf5f18b7ca234c48236e23b2a025be8e8afc13 Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 12 Dec 2024 20:26:54 +0100 Subject: [PATCH 112/125] Yggdrasil 0.5.11 (#1214) Changelog updates. Co-authored-by: Neil Alexander --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c442353e..8169936a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.11] - 2024-12-12 + +### Added + +* Support for `unveil` and `pledge` on OpenBSD + +### Changed + +* The parent selection algorithm now only chooses a new parent if there is a larger cost benefit to doing so, which should help to stabilise the tree +* The bloom filters are now repropagated periodically, to avoid nodes getting stuck with bad state + +### Fixed + +* A memory leak caused by missed cleanup of the peer response map has been fixed +* Other bug fixes with bloom filter propagation for off-tree filters and zero vs one bits +* TLS-based peering connections now support TLS 1.2 again + ## [0.5.10] - 2024-11-24 ### Added From 657f7e0db38e9375a75e8a88bac5ba6e3f02537f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 13 Dec 2024 16:54:14 +0000 Subject: [PATCH 113/125] Fix empty user/group detection on `chuser` This should fix #1216. --- cmd/yggdrasil/chuser_unix.go | 6 ++++++ cmd/yggdrasil/chuser_unix_test.go | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/cmd/yggdrasil/chuser_unix.go b/cmd/yggdrasil/chuser_unix.go index fc3e5c2c..4aa4cc29 100644 --- a/cmd/yggdrasil/chuser_unix.go +++ b/cmd/yggdrasil/chuser_unix.go @@ -14,6 +14,12 @@ import ( func chuser(input string) error { givenUser, givenGroup, _ := strings.Cut(input, ":") + if givenUser == "" { + return fmt.Errorf("user is empty") + } + if strings.Index(input, ":") > -1 && givenGroup == "" { + return fmt.Errorf("group is empty") + } var ( err error diff --git a/cmd/yggdrasil/chuser_unix_test.go b/cmd/yggdrasil/chuser_unix_test.go index ad2e3517..fc624ac2 100644 --- a/cmd/yggdrasil/chuser_unix_test.go +++ b/cmd/yggdrasil/chuser_unix_test.go @@ -4,33 +4,33 @@ package main import ( - "testing" "os/user" + "testing" ) // Usernames must not contain a number sign. -func TestEmptyString (t *testing.T) { +func TestEmptyString(t *testing.T) { if chuser("") == nil { t.Fatal("the empty string is not a valid user") } } // Either omit delimiter and group, or omit both. -func TestEmptyGroup (t *testing.T) { +func TestEmptyGroup(t *testing.T) { if chuser("0:") == nil { t.Fatal("the empty group is not allowed") } } // Either user only or user and group. -func TestGroupOnly (t *testing.T) { +func TestGroupOnly(t *testing.T) { if chuser(":0") == nil { t.Fatal("group only is not allowed") } } // Usenames must not contain the number sign. -func TestInvalidUsername (t *testing.T) { +func TestInvalidUsername(t *testing.T) { const username = "#user" if chuser(username) == nil { t.Fatalf("'%s' is not a valid username", username) @@ -38,14 +38,14 @@ func TestInvalidUsername (t *testing.T) { } // User IDs must be non-negative. -func TestInvalidUserid (t *testing.T) { +func TestInvalidUserid(t *testing.T) { if chuser("-1") == nil { t.Fatal("User ID cannot be negative") } } // Change to the current user by ID. -func TestCurrentUserid (t *testing.T) { +func TestCurrentUserid(t *testing.T) { usr, err := user.Current() if err != nil { t.Fatal(err) @@ -61,7 +61,7 @@ func TestCurrentUserid (t *testing.T) { } // Change to a common user by name. -func TestCommonUsername (t *testing.T) { +func TestCommonUsername(t *testing.T) { usr, err := user.Current() if err != nil { t.Fatal(err) From 04be129878a68d7bbd2fcf2444f1f17b0c52aa36 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 13 Dec 2024 23:12:36 +0000 Subject: [PATCH 114/125] Update to Arceliar/ironwood@743fe2f --- cmd/yggdrasil/chuser_unix.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/yggdrasil/chuser_unix.go b/cmd/yggdrasil/chuser_unix.go index 4aa4cc29..24a706df 100644 --- a/cmd/yggdrasil/chuser_unix.go +++ b/cmd/yggdrasil/chuser_unix.go @@ -17,7 +17,7 @@ func chuser(input string) error { if givenUser == "" { return fmt.Errorf("user is empty") } - if strings.Index(input, ":") > -1 && givenGroup == "" { + if strings.Contains(input, ":") && givenGroup == "" { return fmt.Errorf("group is empty") } diff --git a/go.mod b/go.mod index a77ca47d..d8a7321c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.21 require ( - github.com/Arceliar/ironwood v0.0.0-20241210120540-9deb08d9f8f9 + github.com/Arceliar/ironwood v0.0.0-20241213013129-743fe2fccbd3 github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.1.5 github.com/coder/websocket v1.8.12 diff --git a/go.sum b/go.sum index 8aae0a77..d21246b3 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Arceliar/ironwood v0.0.0-20241210120540-9deb08d9f8f9 h1:myI8fs7+Iw6g/ywvY9QNQOEzny51AklMz4sF0ErtTm8= -github.com/Arceliar/ironwood v0.0.0-20241210120540-9deb08d9f8f9/go.mod h1:SrrElc3FFMpYCODSr11jWbLFeOM8WsY+DbDY/l2AXF0= +github.com/Arceliar/ironwood v0.0.0-20241213013129-743fe2fccbd3 h1:d8N0z+udAnbU5PdjpLSNPTWlqeU/nnYsQ42B6+879aw= +github.com/Arceliar/ironwood v0.0.0-20241213013129-743fe2fccbd3/go.mod h1:SrrElc3FFMpYCODSr11jWbLFeOM8WsY+DbDY/l2AXF0= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= From 9c73bacab90806d913df1ef2b6d79b5ebeb0f98b Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 14 Dec 2024 00:33:26 +0100 Subject: [PATCH 115/125] Update to Go 1.22, quic-go/quic-go@v0.48.2 (#1218) Our dependencies are now moving beyond Go 1.21 so need to update. Co-authored-by: Neil Alexander --- .github/workflows/ci.yml | 8 ++++---- README.md | 2 +- go.mod | 4 ++-- go.sum | 18 ++++++++++++++++++ 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57a0d2a7..ec613e14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.21", "1.22", "1.23"] + goversion: ["1.22", "1.23"] name: Build & Test (Linux, Go ${{ matrix.goversion }}) needs: [lint] @@ -75,7 +75,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.21", "1.22", "1.23"] + goversion: ["1.22", "1.23"] name: Build & Test (Windows, Go ${{ matrix.goversion }}) needs: [lint] @@ -99,7 +99,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.21", "1.22", "1.23"] + goversion: ["1.22", "1.23"] name: Build & Test (macOS, Go ${{ matrix.goversion }}) needs: [lint] @@ -123,7 +123,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.21", "1.22", "1.23"] + goversion: ["1.22", "1.23"] goos: - freebsd - openbsd diff --git a/README.md b/README.md index 8449f073..ea0e1a38 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ or tools in the `contrib` folder. If you want to build from source, as opposed to installing one of the pre-built packages: -1. Install [Go](https://golang.org) (requires Go 1.21 or later) +1. Install [Go](https://golang.org) (requires Go 1.22 or later) 2. Clone this repository 2. Run `./build` diff --git a/go.mod b/go.mod index d8a7321c..222cb1ef 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/yggdrasil-network/yggdrasil-go -go 1.21 +go 1.22 require ( github.com/Arceliar/ironwood v0.0.0-20241213013129-743fe2fccbd3 @@ -11,7 +11,7 @@ require ( github.com/hashicorp/go-syslog v1.0.0 github.com/hjson/hjson-go/v4 v4.4.0 github.com/kardianos/minwinsvc v1.0.2 - github.com/quic-go/quic-go v0.46.0 + github.com/quic-go/quic-go v0.48.2 github.com/vishvananda/netlink v1.3.0 github.com/wlynxg/anet v0.0.5 golang.org/x/crypto v0.31.0 diff --git a/go.sum b/go.sum index d21246b3..c7a4d38f 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,12 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gologme/log v1.3.0 h1:l781G4dE+pbigClDSDzSaaYKtiueHCILUa/qSDsmHAo= @@ -35,6 +39,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hjson/hjson-go/v4 v4.4.0 h1:D/NPvqOCH6/eisTb5/ztuIS8GUvmpHaLOcNk1Bjr298= @@ -54,12 +60,17 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= +github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -76,12 +87,17 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= +golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= @@ -100,6 +116,8 @@ golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4= From 22bc9c44e286568e423305fc67c8f890a351b6a1 Mon Sep 17 00:00:00 2001 From: Peter Gervai Date: Wed, 18 Dec 2024 20:56:46 +0100 Subject: [PATCH 116/125] genkeys print the number of generated keys (#1217) It is good to know how many resources have we carelessly wasted. :-) --- cmd/genkeys/main.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/genkeys/main.go b/cmd/genkeys/main.go index d1a15346..2d007cb8 100644 --- a/cmd/genkeys/main.go +++ b/cmd/genkeys/main.go @@ -26,6 +26,7 @@ import ( type keySet struct { priv ed25519.PrivateKey pub ed25519.PublicKey + count uint64 } func main() { @@ -36,6 +37,8 @@ func main() { threads := runtime.GOMAXPROCS(0) fmt.Println("Threads:", threads) start := time.Now() + var totalKeys uint64 + totalKeys = 0 var currentBest ed25519.PublicKey newKeys := make(chan keySet, threads) for i := 0; i < threads; i++ { @@ -44,8 +47,9 @@ func main() { for { newKey := <-newKeys if isBetter(currentBest, newKey.pub) || len(currentBest) == 0 { + totalKeys += newKey.count currentBest = newKey.pub - fmt.Println("-----", time.Since(start)) + fmt.Println("-----", time.Since(start), "---", totalKeys, "keys tried") fmt.Println("Priv:", hex.EncodeToString(newKey.priv)) fmt.Println("Pub:", hex.EncodeToString(newKey.pub)) addr := address.AddrForKey(newKey.pub) @@ -68,11 +72,14 @@ func isBetter(oldPub, newPub ed25519.PublicKey) bool { func doKeys(out chan<- keySet) { bestKey := make(ed25519.PublicKey, ed25519.PublicKeySize) + var count uint64 + count = 0 for idx := range bestKey { bestKey[idx] = 0xff } for { pub, priv, err := ed25519.GenerateKey(nil) + count++ if err != nil { panic(err) } @@ -80,6 +87,7 @@ func doKeys(out chan<- keySet) { continue } bestKey = pub - out <- keySet{priv, pub} + out <- keySet{priv, pub, count} + count = 0 } } From 1fbcf3b3c2014f128575af0b4381c592536bc90b Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 18 Dec 2024 22:21:23 +0000 Subject: [PATCH 117/125] Rename `latency_ms` to `latency` in `getPeers` response since it isn't even milliseconds anymore --- src/admin/getpeers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index 34eca243..0384b792 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -31,7 +31,7 @@ type PeerEntry struct { RXRate DataUnit `json:"rate_recvd,omitempty"` TXRate DataUnit `json:"rate_sent,omitempty"` Uptime float64 `json:"uptime,omitempty"` - Latency time.Duration `json:"latency_ms,omitempty"` + Latency time.Duration `json:"latency,omitempty"` LastErrorTime time.Duration `json:"last_error_time,omitempty"` LastError string `json:"last_error,omitempty"` } From 213f72b8403ff55a5e38a0fa7d1cd0a093ac4666 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 18 Dec 2024 22:34:30 +0000 Subject: [PATCH 118/125] Yggdrasil 0.5.12 --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8169936a..c7ac1d80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.5.12] - 2024-12-18 + +* Go 1.22 is now required to build Yggdrasil + +### Changed + +* The `latency_ms` field in the admin socket `getPeers` response has been renamed to `latency` + +### Fixed + +* A timing regression which causes a higher level of idle protocol traffic on each peering has been fixed +* The `-user` flag now correctly detects an empty user/group specification + ## [0.5.11] - 2024-12-12 ### Added From 782c0250d743421c7f1ecaeafdf78fc41db97749 Mon Sep 17 00:00:00 2001 From: Klemens Nanni Date: Sun, 22 Dec 2024 14:04:26 +0300 Subject: [PATCH 119/125] Use pledge(2) on OpenBSD (#1215) Straight forward thanks to all privileged operations being done early enough during startup. --- cmd/yggdrasil/main.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index b3cbecf0..b3c9151d 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -312,6 +312,21 @@ func main() { } } + // Promise final modes of operation. At this point, if at all: + // - raw socket is created/open + // - admin socket is created/open + // - privileges are dropped to non-root user + // + // Peers, InterfacePeers, Listen can be UNIX sockets; + // Go's net.Listen.Close() deletes files on shutdown. + promises := []string{"stdio", "cpath", "inet", "unix", "dns"} + if len(cfg.MulticastInterfaces) > 0 { + promises = append(promises, "mcast") + } + if err := protect.Pledge(strings.Join(promises, " ")); err != nil { + panic(fmt.Sprintf("pledge: %v: %v", promises, err)) + } + // Block until we are told to shut down. <-ctx.Done() From 58b727d1f0e22b10fcac01d128d1d1659d78b14c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 18 Feb 2025 12:52:21 +0000 Subject: [PATCH 120/125] Add Go 1.24 to CI --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec613e14..c89445e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.22", "1.23"] + goversion: ["1.22", "1.23", "1.24"] name: Build & Test (Linux, Go ${{ matrix.goversion }}) needs: [lint] @@ -75,7 +75,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.22", "1.23"] + goversion: ["1.22", "1.23", "1.24"] name: Build & Test (Windows, Go ${{ matrix.goversion }}) needs: [lint] @@ -99,7 +99,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.22", "1.23"] + goversion: ["1.22", "1.23", "1.24"] name: Build & Test (macOS, Go ${{ matrix.goversion }}) needs: [lint] @@ -123,7 +123,7 @@ jobs: strategy: fail-fast: false matrix: - goversion: ["1.22", "1.23"] + goversion: ["1.22", "1.23", "1.24"] goos: - freebsd - openbsd From 3b18909f70527ee5f927be3683daf6f949b43578 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 18 Feb 2025 12:56:52 +0000 Subject: [PATCH 121/125] Update dependencies --- go.mod | 12 ++++++------ go.sum | 41 ++++++++++++----------------------------- 2 files changed, 18 insertions(+), 35 deletions(-) diff --git a/go.mod b/go.mod index 222cb1ef..672edd6e 100644 --- a/go.mod +++ b/go.mod @@ -14,10 +14,10 @@ require ( github.com/quic-go/quic-go v0.48.2 github.com/vishvananda/netlink v1.3.0 github.com/wlynxg/anet v0.0.5 - golang.org/x/crypto v0.31.0 - golang.org/x/net v0.32.0 - golang.org/x/sys v0.28.0 - golang.org/x/text v0.21.0 + golang.org/x/crypto v0.33.0 + golang.org/x/net v0.35.0 + golang.org/x/sys v0.30.0 + golang.org/x/text v0.22.0 golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 golang.zx2c4.com/wireguard/windows v0.5.3 @@ -31,10 +31,10 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/onsi/ginkgo/v2 v2.9.5 // indirect github.com/rivo/uniseg v0.2.0 // indirect - go.uber.org/mock v0.4.0 // indirect + go.uber.org/mock v0.5.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect - golang.org/x/sync v0.10.0 // indirect + golang.org/x/sync v0.11.0 // indirect golang.org/x/tools v0.23.0 // indirect ) diff --git a/go.sum b/go.sum index c7a4d38f..d843af40 100644 --- a/go.sum +++ b/go.sum @@ -23,12 +23,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gologme/log v1.3.0 h1:l781G4dE+pbigClDSDzSaaYKtiueHCILUa/qSDsmHAo= @@ -39,8 +35,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hjson/hjson-go/v4 v4.4.0 h1:D/NPvqOCH6/eisTb5/ztuIS8GUvmpHaLOcNk1Bjr298= @@ -60,22 +54,18 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= -github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= -github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= -github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk= @@ -85,39 +75,32 @@ github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zd github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= -golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= -golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= -golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4= From 73705ff09ddfef8b458390aafe84315671952f1a Mon Sep 17 00:00:00 2001 From: patrini32 Date: Thu, 20 Feb 2025 12:45:49 +0300 Subject: [PATCH 122/125] Typo fix (#1232) --- src/address/address.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/address/address.go b/src/address/address.go index d56be80d..c9581c70 100644 --- a/src/address/address.go +++ b/src/address/address.go @@ -113,7 +113,7 @@ func SubnetForKey(publicKey ed25519.PublicKey) *Subnet { return &snet } -// GetKet returns the partial ed25519.PublicKey for the Address. +// GetKey returns the partial ed25519.PublicKey for the Address. // This is used for key lookup. func (a *Address) GetKey() ed25519.PublicKey { var key [ed25519.PublicKeySize]byte @@ -141,7 +141,7 @@ func (a *Address) GetKey() ed25519.PublicKey { return ed25519.PublicKey(key[:]) } -// GetKet returns the partial ed25519.PublicKey for the Subnet. +// GetKey returns the partial ed25519.PublicKey for the Subnet. // This is used for key lookup. func (s *Subnet) GetKey() ed25519.PublicKey { var addr Address From 5b8dbc8b1e297cd580eff36557d23df1ac5daab2 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 31 Mar 2025 10:18:57 +0100 Subject: [PATCH 123/125] Add summary helpers to mobile wrapper --- contrib/mobile/mobile.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index abc89f1c..72ea7d68 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -1,6 +1,7 @@ package mobile import ( + "crypto/ed25519" "encoding/hex" "encoding/json" "net" @@ -273,3 +274,28 @@ func (m *Yggdrasil) GetMTU() int { func GetVersion() string { return version.BuildVersion() } + +type ConfigSummary struct { + PublicKey string + IPv6Address string + IPv6Subnet string +} + +func SummaryForConfig(b []byte) *ConfigSummary { + cfg := config.GenerateConfig() + if err := cfg.UnmarshalHJSON(b); err != nil { + return nil + } + pub := ed25519.PrivateKey(cfg.PrivateKey).Public().(ed25519.PublicKey) + hpub := hex.EncodeToString(pub) + addr := net.IP(address.AddrForKey(pub)[:]) + snet := net.IPNet{ + IP: append(address.SubnetForKey(pub)[:], 0, 0, 0, 0, 0, 0, 0, 0), + Mask: net.CIDRMask(64, 128), + } + return &ConfigSummary{ + PublicKey: hpub, + IPv6Address: addr.String(), + IPv6Subnet: snet.String(), + } +} From 6377d7f0717296e2c94561fcbd1c3b4df5af63bb Mon Sep 17 00:00:00 2001 From: Sergey Alirzaev Date: Tue, 15 Apr 2025 18:15:09 +0200 Subject: [PATCH 124/125] contrib/openrc: remove SIGHUP logic (#1236) as it is long gone from the daemon code and unexpectedly kills the daemon --- contrib/openrc/yggdrasil | 7 ------- 1 file changed, 7 deletions(-) diff --git a/contrib/openrc/yggdrasil b/contrib/openrc/yggdrasil index 4a2e0a13..aece8ecb 100755 --- a/contrib/openrc/yggdrasil +++ b/contrib/openrc/yggdrasil @@ -6,7 +6,6 @@ CONFFILE="/etc/yggdrasil.conf" pidfile="/run/${RC_SVCNAME}.pid" command="/usr/bin/yggdrasil" -extra_started_commands="reload" depend() { use net dns logger @@ -42,12 +41,6 @@ start() { eend $? } -reload() { - ebegin "Reloading ${RC_SVCNAME}" - start-stop-daemon --signal HUP --pidfile "${pidfile}" - eend $? -} - stop() { ebegin "Stopping ${RC_SVCNAME}" start-stop-daemon --stop --pidfile "${pidfile}" --exec "${command}" From 47818a1a7c475c3c214e3b25d961b77d55069086 Mon Sep 17 00:00:00 2001 From: Sergey Alirzaev Date: Tue, 15 Apr 2025 18:17:52 +0200 Subject: [PATCH 125/125] apparmor: add yggdrasilctl policy (#1235) --- contrib/apparmor/usr.bin.yggdrasilctl | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 contrib/apparmor/usr.bin.yggdrasilctl diff --git a/contrib/apparmor/usr.bin.yggdrasilctl b/contrib/apparmor/usr.bin.yggdrasilctl new file mode 100644 index 00000000..2f2c8366 --- /dev/null +++ b/contrib/apparmor/usr.bin.yggdrasilctl @@ -0,0 +1,11 @@ +# Last Modified: Mon Feb 3 22:19:45 2025 +include + +/usr/bin/yggdrasilctl { + include + + /etc/yggdrasil.conf rw, + /run/yggdrasil.sock rw, + owner /sys/kernel/mm/transparent_hugepage/hpage_pmd_size r, + +}