From a7f5c427d467f9f5db984a3eba6c1a0e7ccd26a7 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 3 Dec 2018 17:44:26 +0000 Subject: [PATCH 01/52] Tag releases in master using CI (also checks for v0.x.0 instead of v0.x when deciding version numbers) --- .circleci/config.yml | 12 ++++++++++++ contrib/.DS_Store | Bin 0 -> 6148 bytes contrib/semver/version.sh | 11 +++++++---- 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 contrib/.DS_Store diff --git a/.circleci/config.yml b/.circleci/config.yml index fa5ebcac..90bba23b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,8 @@ jobs: mkdir /tmp/upload echo 'export CINAME=$(sh contrib/semver/name.sh)' >> $BASH_ENV echo 'export CIVERSION=$(sh contrib/semver/version.sh | cut -c 2-)' >> $BASH_ENV + git config --global user.email "$(git log --format='%ae' HEAD -1)"; + git config --global user.name "$(git log --format='%an' HEAD -1)"; - run: name: Install alien @@ -98,3 +100,13 @@ jobs: - store_artifacts: path: /tmp/upload destination: / + + - run: + name: Create tags (master branch only) + command: > + if [ "${CIRCLE_BRANCH}" == "master" ]; then + git tag -f -a $(sh contrib/semver/version.sh) -m "Created by CircleCI" && git push -f --tags; + else + echo "Only runs for master branch (this is ${CIRCLE_BRANCH})"; + fi; + when: on_success diff --git a/contrib/.DS_Store b/contrib/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..799616ae9f2aed17d20533c4052922a02fadaab9 GIT binary patch literal 6148 zcmeHKPfx-y6mJ2gV2m70)LSp!I50Kf#blXy@Mbcj2Q{!|C`)iNY)BL_`yBd>`~rR* z-)jpI(TfLT$a~A{@Ads@)8CeMWsGrW5Lk>=7-IqyF;{}-8^Jj0oaBrLk*hI$maxDd zCU<^sE}Iv_;EG-v>D2wuH`O59aLpSx( zLE?D*3+$bEY1cRQX&m>aw&$OPonfo8ei%oo7e<}FDh`7Vq+FhdQ4kNEcn}4N8pqWE zAxfgus%(u$)=sTnm6o+XuF6rPQLDd;Dx5!bYMy5Y@J&ip0yIR4T^$! nnZ{`e80sj7Ts(?5L6v}Cq5)_d%rt@rgnk4R4b%_=f6BlIbwN_$ literal 0 HcmV?d00001 diff --git a/contrib/semver/version.sh b/contrib/semver/version.sh index bd009a9a..215753bb 100644 --- a/contrib/semver/version.sh +++ b/contrib/semver/version.sh @@ -4,7 +4,7 @@ DEVELOPBRANCH="yggdrasil-network/develop" # Get the last tag -TAG=$(git describe --abbrev=0 --tags --match="v[0-9]*\.[0-9]*" 2>/dev/null) +TAG=$(git describe --abbrev=0 --tags --match="v[0-9]*\.[0-9]*\.0" 2>/dev/null) # Get last merge to master MERGE=$(git rev-list $TAG..master --grep "from $DEVELOPBRANCH" 2>/dev/null | head -n 1) @@ -31,8 +31,12 @@ MINOR=$(echo $TAG | cut -c 2- | cut -d "." -f 2) BRANCH=$(git rev-parse --abbrev-ref HEAD) # Output in the desired format -if [ $PATCH = 0 ]; then - printf 'v%d.%d' "$MAJOR" "$MINOR" +if [ $PATCH == 0 ]; then + if [ ! -z $FULL ]; then + printf 'v%d.%d.0' "$MAJOR" "$MINOR" + else + printf 'v%d.%d' "$MAJOR" "$MINOR" + fi else printf 'v%d.%d.%d' "$MAJOR" "$MINOR" "$PATCH" fi @@ -43,4 +47,3 @@ if [ $BRANCH != "master" ]; then printf -- "-%04d" "$BUILD" fi fi - From 8a04cbe3c8e9f9c05d35d728002addde5710c15d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 3 Dec 2018 17:49:03 +0000 Subject: [PATCH 02/52] Try to fix CircleCI shell error --- contrib/semver/version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/semver/version.sh b/contrib/semver/version.sh index 215753bb..6eeffc5f 100644 --- a/contrib/semver/version.sh +++ b/contrib/semver/version.sh @@ -31,7 +31,7 @@ MINOR=$(echo $TAG | cut -c 2- | cut -d "." -f 2) BRANCH=$(git rev-parse --abbrev-ref HEAD) # Output in the desired format -if [ $PATCH == 0 ]; then +if [ $PATCH = 0 ]; then if [ ! -z $FULL ]; then printf 'v%d.%d.0' "$MAJOR" "$MINOR" else From 3d4b49b6933a539052dc72131ef497a8fe2d7d48 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Mon, 3 Dec 2018 19:21:23 -0600 Subject: [PATCH 03/52] reset the switch speed info for a peer whenever it changes coords, instead of only if they're a parent and change coords. Also, make sure packets in the sim preserve order when sending, to avoid races when testing --- src/yggdrasil/debug.go | 54 ++++++++++++++++++++++++++--------------- src/yggdrasil/switch.go | 28 ++++++++++----------- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/yggdrasil/debug.go b/src/yggdrasil/debug.go index 91f57708..7da84749 100644 --- a/src/yggdrasil/debug.go +++ b/src/yggdrasil/debug.go @@ -504,27 +504,43 @@ func (c *Core) DEBUG_addAllowedEncryptionPublicKey(boxStr string) { func DEBUG_simLinkPeers(p, q *peer) { // Sets q.out() to point to p and starts p.linkLoop() - p.linkOut, q.linkOut = make(chan []byte, 1), make(chan []byte, 1) - go func() { - for bs := range p.linkOut { - q.handlePacket(bs) + goWorkers := func(source, dest *peer) { + source.linkOut = make(chan []byte, 1) + send := make(chan []byte, 1) + source.out = func(bs []byte) { + send <- bs } - }() - go func() { - for bs := range q.linkOut { - p.handlePacket(bs) - } - }() - p.out = func(bs []byte) { - p.core.switchTable.idleIn <- p.port - go q.handlePacket(bs) + go source.linkLoop() + go func() { + var packets [][]byte + for { + select { + case packet := <-source.linkOut: + packets = append(packets, packet) + continue + case packet := <-send: + packets = append(packets, packet) + source.core.switchTable.idleIn <- source.port + continue + default: + } + if len(packets) > 0 { + dest.handlePacket(packets[0]) + packets = packets[1:] + continue + } + select { + case packet := <-source.linkOut: + packets = append(packets, packet) + case packet := <-send: + packets = append(packets, packet) + source.core.switchTable.idleIn <- source.port + } + } + }() } - q.out = func(bs []byte) { - q.core.switchTable.idleIn <- q.port - go p.handlePacket(bs) - } - go p.linkLoop() - go q.linkLoop() + goWorkers(p, q) + goWorkers(q, p) p.core.switchTable.idleIn <- p.port q.core.switchTable.idleIn <- q.port } diff --git a/src/yggdrasil/switch.go b/src/yggdrasil/switch.go index b04578ca..99661031 100644 --- a/src/yggdrasil/switch.go +++ b/src/yggdrasil/switch.go @@ -377,6 +377,11 @@ func (t *switchTable) unlockedHandleMsg(msg *switchMsg, fromPort switchPort, rep doUpdate := false oldSender := t.data.peers[fromPort] if !equiv(&sender.locator, &oldSender.locator) { + // Reset faster info, we'll start refilling it right after this + sender.faster = nil + for _, peer := range t.data.peers { + delete(peer.faster, sender.port) + } doUpdate = true } // Update the matrix of peer "faster" thresholds @@ -387,25 +392,20 @@ func (t *switchTable) unlockedHandleMsg(msg *switchMsg, fromPort switchPort, rep for port, peer := range t.data.peers { if port == fromPort { continue - } - switch { - case msg.Root != peer.locator.root: - // Different roots, blindly guess that the relationships will stay the same? - sender.faster[port] = oldSender.faster[peer.port] - case sender.locator.tstamp <= peer.locator.tstamp: - // Slower than this node, penalize (more than the reward amount) - if oldSender.faster[port] > 1 { - sender.faster[port] = oldSender.faster[peer.port] - 2 - } else { - sender.faster[port] = 0 - } - default: + } else if sender.locator.root != peer.locator.root || sender.locator.tstamp > peer.locator.tstamp { // We were faster than this node, so increment, as long as we don't overflow because of it if oldSender.faster[peer.port] < switch_faster_threshold { sender.faster[port] = oldSender.faster[peer.port] + 1 } else { sender.faster[port] = switch_faster_threshold } + } else { + // Slower than this node, penalize (more than the reward amount) + if oldSender.faster[port] > 1 { + sender.faster[port] = oldSender.faster[peer.port] - 2 + } else { + sender.faster[port] = 0 + } } } } @@ -457,12 +457,10 @@ func (t *switchTable) unlockedHandleMsg(msg *switchMsg, fromPort switchPort, rep // First, reset all faster-related info to 0. // Then, de-parent the node and reprocess all messages to find a new parent. t.parent = 0 - sender.faster = nil for _, peer := range t.data.peers { if peer.port == sender.port { continue } - delete(peer.faster, sender.port) t.unlockedHandleMsg(&peer.msg, peer.port, true) } // Process the sender last, to avoid keeping them as a parent if at all possible. From 9f4fc3669ba56140f158f404247ea7e2721b30f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Christian=20Gr=C3=BCnhage?= Date: Tue, 4 Dec 2018 13:00:01 +0100 Subject: [PATCH 04/52] Reduce container image size --- contrib/docker/Dockerfile | 28 ++++++++++++++++------------ contrib/docker/entrypoint.sh | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) mode change 100644 => 100755 contrib/docker/entrypoint.sh diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index a5174eb4..6b4bfcb6 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -1,18 +1,22 @@ -FROM golang:stretch -MAINTAINER Christer Waren/CWINFO "christer.waren@cwinfo.org" - -RUN apt-get update \ - && apt-get upgrade -y - -ADD . /src +FROM docker.io/golang:alpine as builder +COPY . /src WORKDIR /src +RUN apk add git && ./build -RUN adduser --system --home /etc/yggdrasil-network --uid 1000 yggdrasil-network \ - && rm -rf build_* && ./build \ - && cp yggdrasil /usr/bin \ - && cp contrib/docker/entrypoint.sh / +FROM docker.io/alpine +LABEL maintainer="Christer Waren/CWINFO " + +COPY --from=builder /src/yggdrasil /usr/bin/yggdrasil +COPY --from=builder /src/yggdrasilctl /usr/bin/yggdrasilctl +COPY contrib/docker/entrypoint.sh /usr/bin/entrypoint.sh + +# RUN addgroup -g 1000 -S yggdrasil-network \ +# && adduser -u 1000 -S -g 1000 --home /etc/yggdrasil-network yggdrasil-network +# +# USER yggdrasil-network +# TODO: Make running unprivileged work VOLUME [ "/etc/yggdrasil-network" ] -ENTRYPOINT [ "/entrypoint.sh" ] +ENTRYPOINT [ "/usr/bin/entrypoint.sh" ] diff --git a/contrib/docker/entrypoint.sh b/contrib/docker/entrypoint.sh old mode 100644 new mode 100755 index f1a9d3e5..26c685a8 --- a/contrib/docker/entrypoint.sh +++ b/contrib/docker/entrypoint.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -e From eae8f9a666ce0b8e59deb1b5fa335e892d136df0 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 5 Dec 2018 22:39:04 +0000 Subject: [PATCH 05/52] Try to SO_REUSEPORT on UNIX platforms --- src/yggdrasil/multicast.go | 6 +++++- src/yggdrasil/multicast_other.go | 9 +++++++++ src/yggdrasil/multicast_unix.go | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/yggdrasil/multicast_other.go create mode 100644 src/yggdrasil/multicast_unix.go diff --git a/src/yggdrasil/multicast.go b/src/yggdrasil/multicast.go index 697744cb..749dfcdb 100644 --- a/src/yggdrasil/multicast.go +++ b/src/yggdrasil/multicast.go @@ -1,6 +1,7 @@ package yggdrasil import ( + "context" "fmt" "net" "time" @@ -35,7 +36,10 @@ func (m *multicast) start() error { return err } listenString := fmt.Sprintf("[::]:%v", addr.Port) - conn, err := net.ListenPacket("udp6", listenString) + lc := net.ListenConfig{ + Control: multicastReuse, + } + conn, err := lc.ListenPacket(context.Background(), "udp6", listenString) if err != nil { return err } diff --git a/src/yggdrasil/multicast_other.go b/src/yggdrasil/multicast_other.go new file mode 100644 index 00000000..98fe2df1 --- /dev/null +++ b/src/yggdrasil/multicast_other.go @@ -0,0 +1,9 @@ +// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd + +package yggdrasil + +import "syscall" + +func multicastReuse(network string, address string, c syscall.RawConn) error { + return nil +} diff --git a/src/yggdrasil/multicast_unix.go b/src/yggdrasil/multicast_unix.go new file mode 100644 index 00000000..9c6d1f11 --- /dev/null +++ b/src/yggdrasil/multicast_unix.go @@ -0,0 +1,22 @@ +// +build linux darwin netbsd freebsd openbsd dragonflybsd + +package yggdrasil + +import "syscall" +import "golang.org/x/sys/unix" + +func multicastReuse(network string, address string, c syscall.RawConn) error { + var control error + var reuseport error + + control = c.Control(func(fd uintptr) { + reuseport = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + }) + + switch { + case reuseport != nil: + return reuseport + default: + return control + } +} From ae48a1721e665c7cc4213cca7d93748301bd702f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 5 Dec 2018 23:10:50 +0000 Subject: [PATCH 06/52] Try to SO_REUSEADDR on Windows --- src/yggdrasil/multicast_other.go | 2 +- src/yggdrasil/multicast_windows.go | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/yggdrasil/multicast_windows.go diff --git a/src/yggdrasil/multicast_other.go b/src/yggdrasil/multicast_other.go index 98fe2df1..8a4ce56c 100644 --- a/src/yggdrasil/multicast_other.go +++ b/src/yggdrasil/multicast_other.go @@ -1,4 +1,4 @@ -// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd +// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd,!windows package yggdrasil diff --git a/src/yggdrasil/multicast_windows.go b/src/yggdrasil/multicast_windows.go new file mode 100644 index 00000000..13f20315 --- /dev/null +++ b/src/yggdrasil/multicast_windows.go @@ -0,0 +1,22 @@ +// +build windows + +package yggdrasil + +import "syscall" +import "golang.org/x/sys/windows" + +func multicastReuse(network string, address string, c syscall.RawConn) error { + var control error + var reuseaddr error + + control = c.Control(func(fd uintptr) { + reuseaddr = windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_REUSEADDR, 1) + }) + + switch { + case reuseaddr != nil: + return reuseaddr + default: + return control + } +} From 2eedcce3fd37852b2b06562cf3a02b906d566453 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 5 Dec 2018 23:39:28 +0000 Subject: [PATCH 07/52] Update changelog --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c72c27a..c779c375 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,25 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.x.x] - TBD +### Added +- Crypto-key routing support for both IPv4 and IPv6 +- Add `SwitchOptions` in configuration file for tuning the switch +- Add `dhtPing` to the admin socket to aid in crawling the network +- New macOS .pkgs built automatically by CircleCI +- Add Docker support +- Add `-json` command line flag for generating and normalising configuration in plain JSON + +### Changed +- Switched to Chord DHT (instead of Kademlia, although protocol-compatible) +- Admin socket clean-up (making some names consistent) +- Latency-based parent selection for the switch instead of uptime-based +- Real peering endpoints now shown in the admin socket `getPeers` call + +### Fixed +- Memory leaks in the DHT fixed +- Crash where ICMPv6 NDP goroutine would incorrectly start in TUN mode fixed + ## [0.2.7] - 2018-10-13 ### Added - Session firewall, which makes it possible to control who can open sessions with your node From fe772dd38e161609ee1d907ab0ef17c24880cd52 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Wed, 5 Dec 2018 18:22:39 -0600 Subject: [PATCH 08/52] switch bugfixes --- CHANGELOG.md | 1 + src/yggdrasil/switch.go | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c779c375..b91caca4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - Memory leaks in the DHT fixed - Crash where ICMPv6 NDP goroutine would incorrectly start in TUN mode fixed +- Remove peers from the switch table of they stop sending switch messages but keep the TCP connection alive ## [0.2.7] - 2018-10-13 ### Added diff --git a/src/yggdrasil/switch.go b/src/yggdrasil/switch.go index 99661031..920926b4 100644 --- a/src/yggdrasil/switch.go +++ b/src/yggdrasil/switch.go @@ -208,6 +208,7 @@ func (t *switchTable) doMaintenance() { defer t.mutex.Unlock() // Release lock when we're done t.cleanRoot() t.cleanDropped() + t.cleanPeers() } // Updates the root periodically if it is ourself, or promotes ourself to root if we're better than the current root or if the current root has timed out. @@ -258,11 +259,33 @@ func (t *switchTable) forgetPeer(port switchPort) { if port != t.parent { return } + t.parent = 0 for _, info := range t.data.peers { t.unlockedHandleMsg(&info.msg, info.port, true) } } +// Clean all unresponsive peers from the table, needed in case a peer stops updating. +// Needed in case a non-parent peer keeps the connection open but stops sending updates. +// Also reclaims space from deleted peers by copying the map. +func (t switchTable) cleanPeers() { + now := time.Now() + for port, peer := range t.data.peers { + if now.Sub(peer.time) > switch_timeout+switch_throttle { + // Longer than switch_timeout to make sure we don't remove a working peer because the root stopped responding. + delete(t.data.peers, port) + } + } + if _, isIn := t.data.peers[t.parent]; !isIn { + // The root timestamp would probably time out before this happens, but better safe than sorry. + // We removed the current parent, so find a new one. + t.parent = 0 + for _, peer := range t.data.peers { + t.unlockedHandleMsg(&peer.msg, peer.port, true) + } + } +} + // Dropped is a list of roots that are better than the current root, but stopped sending new timestamps. // If we switch to a new root, and that root is better than an old root that previously timed out, then we can clean up the old dropped root infos. // This function is called periodically to do that cleanup. @@ -379,9 +402,6 @@ func (t *switchTable) unlockedHandleMsg(msg *switchMsg, fromPort switchPort, rep if !equiv(&sender.locator, &oldSender.locator) { // Reset faster info, we'll start refilling it right after this sender.faster = nil - for _, peer := range t.data.peers { - delete(peer.faster, sender.port) - } doUpdate = true } // Update the matrix of peer "faster" thresholds From d0c2ce90bbf194995f331003f10852a29872f49f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 7 Dec 2018 22:03:57 +0000 Subject: [PATCH 09/52] Fix semver when git history is not present --- contrib/semver/name.sh | 4 ++-- contrib/semver/version.sh | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/contrib/semver/name.sh b/contrib/semver/name.sh index d749d3ff..9dbdca33 100644 --- a/contrib/semver/name.sh +++ b/contrib/semver/name.sh @@ -1,10 +1,10 @@ #!/bin/sh # Get the branch name, removing any "/" characters from pull requests -BRANCH=$(git symbolic-ref --short HEAD | tr -d "/" 2>/dev/null) +BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null | tr -d "/") # Check if the branch name is not master -if [ "$BRANCH" = "master" ]; then +if [ "$BRANCH" = "master" ] || [ $? != 0 ]; then printf "yggdrasil" exit 0 fi diff --git a/contrib/semver/version.sh b/contrib/semver/version.sh index 6eeffc5f..c23abf41 100644 --- a/contrib/semver/version.sh +++ b/contrib/semver/version.sh @@ -16,6 +16,11 @@ PATCH=$(git rev-list $TAG..master --count --merges --grep="from $DEVELOPBRANCH" if [ $? != 0 ]; then PATCH=$(git rev-list HEAD --count 2>/dev/null) + if [ $? != 0 ]; then + printf 'unknown' + exit -1 + fi + printf 'v0.0.%d' "$PATCH" exit -1 fi From 8bd566d4d8bb35ad47b414574d2315ed17ec6a3b Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 7 Dec 2018 22:05:36 +0000 Subject: [PATCH 10/52] Remove VERSION --- VERSION | 1 - 1 file changed, 1 deletion(-) delete mode 100644 VERSION diff --git a/VERSION b/VERSION deleted file mode 100644 index 3b04cfb6..00000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.2 From 4bc009d8457f40dfaef4addc23bf9baabe1f360a Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 7 Dec 2018 22:17:09 +0000 Subject: [PATCH 11/52] Update semver behaviour --- contrib/semver/name.sh | 15 ++++++++++++--- contrib/semver/version.sh | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/contrib/semver/name.sh b/contrib/semver/name.sh index 9dbdca33..9cab7e96 100644 --- a/contrib/semver/name.sh +++ b/contrib/semver/name.sh @@ -1,10 +1,19 @@ #!/bin/sh -# Get the branch name, removing any "/" characters from pull requests -BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null | tr -d "/") +# Get the current branch name +BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null) + +# Complain if the git history is not available +if [ $? != 0 ]; then + printf "unknown" + exit -1 +fi + +# Remove "/" characters from the branch name if present +BRANCH=$(echo $BRANCH | tr -d "/") # Check if the branch name is not master -if [ "$BRANCH" = "master" ] || [ $? != 0 ]; then +if [ "$BRANCH" = "master" ]; then printf "yggdrasil" exit 0 fi diff --git a/contrib/semver/version.sh b/contrib/semver/version.sh index c23abf41..f7769a34 100644 --- a/contrib/semver/version.sh +++ b/contrib/semver/version.sh @@ -16,6 +16,7 @@ PATCH=$(git rev-list $TAG..master --count --merges --grep="from $DEVELOPBRANCH" if [ $? != 0 ]; then PATCH=$(git rev-list HEAD --count 2>/dev/null) + # Complain if the git history is not available if [ $? != 0 ]; then printf 'unknown' exit -1 From 8e784438c7ebb77eb903c964192012d8a0826d02 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 7 Dec 2018 22:20:11 +0000 Subject: [PATCH 12/52] Imprint build name and version number if available --- build | 5 +++-- src/yggdrasil/core.go | 21 +++++++++++++++++++++ yggdrasil.go | 5 +++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/build b/build index c07e5eac..2e7c20cc 100755 --- a/build +++ b/build @@ -14,10 +14,11 @@ go get -d -v yggdrasil for file in *.go ; do echo "Building: $file" #go build $@ $file + IMPRINT="-X yggdrasil.buildName=$(sh contrib/semver/name.sh) -X yggdrasil.buildVersion=$(sh contrib/semver/version.sh)" if [ $DEBUG ]; then - go build -tags debug -v $file + go build -ldflags="$IMPRINT" -tags debug -v $file else - go build -ldflags="-s -w" -v $file + go build -ldflags="$IMPRINT -s -w" -v $file fi if [ $UPX ]; then upx --brute ${file%.go} diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index 706b8aa3..54f1820c 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -12,6 +12,9 @@ import ( "yggdrasil/defaults" ) +var buildName string +var buildVersion string + // The Core object represents the Yggdrasil node. You should create a Core // object for each Yggdrasil node you plan to run. type Core struct { @@ -59,6 +62,24 @@ func (c *Core) init(bpub *boxPubKey, c.tun.init(c) } +// Get the current build name. This is usually injected if built from git, +// or returns "unknown" otherwise. +func GetBuildName() string { + if buildName == "" { + return "unknown" + } + return buildName +} + +// Get the current build version. This is usually injected if built from git, +// or returns "unknown" otherwise. +func GetBuildVersion() string { + if buildVersion == "" { + return "unknown" + } + return buildVersion +} + // Starts up Yggdrasil using the provided NodeConfig, and outputs debug logging // through the provided log.Logger. The started stack will include TCP and UDP // sockets, a multicast discovery socket, an admin socket, router, switch and diff --git a/yggdrasil.go b/yggdrasil.go index 5244a8ec..d326d18e 100644 --- a/yggdrasil.go +++ b/yggdrasil.go @@ -100,10 +100,15 @@ func main() { normaliseconf := flag.Bool("normaliseconf", false, "use in combination with either -useconf or -useconffile, outputs your configuration normalised") confjson := flag.Bool("json", false, "print configuration from -genconf or -normaliseconf as JSON instead of HJSON") autoconf := flag.Bool("autoconf", false, "automatic mode (dynamic IP, peer with IPv6 neighbors)") + version := flag.Bool("version", false, "prints the version of this build") flag.Parse() var cfg *nodeConfig switch { + case *version: + fmt.Println("Build name:", yggdrasil.GetBuildName()) + fmt.Println("Build version:", yggdrasil.GetBuildVersion()) + os.Exit(0) case *autoconf: // Use an autoconf-generated config, this will give us random keys and // port numbers, and will use an automatically selected TUN/TAP interface. From 3524c6eff617ede773ee83dce1d50a2601088846 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 7 Dec 2018 22:22:46 +0000 Subject: [PATCH 13/52] Add build name and version to getSelf call on admin socket --- src/yggdrasil/admin.go | 2 ++ yggdrasilctl.go | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index 2b5bc645..af59734e 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -556,6 +556,8 @@ func (a *admin) getData_getSelf() *admin_nodeInfo { table := a.core.switchTable.table.Load().(lookupTable) coords := table.self.getCoords() self := admin_nodeInfo{ + {"build_name", GetBuildName()}, + {"build_version", GetBuildVersion()}, {"box_pub_key", hex.EncodeToString(a.core.boxPub[:])}, {"ip", a.core.GetAddress().String()}, {"subnet", a.core.GetSubnet().String()}, diff --git a/yggdrasilctl.go b/yggdrasilctl.go index 79b5f86d..6919ec33 100644 --- a/yggdrasilctl.go +++ b/yggdrasilctl.go @@ -181,6 +181,12 @@ func main() { } case "getself": for k, v := range res["self"].(map[string]interface{}) { + if buildname, ok := v.(map[string]interface{})["build_name"].(string); ok { + fmt.Println("Build name:", buildname) + } + if buildversion, ok := v.(map[string]interface{})["build_version"].(string); ok { + fmt.Println("Build version:", buildversion) + } fmt.Println("IPv6 address:", k) if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok { fmt.Println("IPv6 subnet:", subnet) From 5149c6c349d6540772799259c6a0e30a3aa66f33 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 7 Dec 2018 22:24:01 +0000 Subject: [PATCH 14/52] Show build name and version at startup if available --- src/yggdrasil/core.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index 54f1820c..b57bd863 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -86,6 +86,14 @@ func GetBuildVersion() string { // DHT node. func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error { c.log = log + + if buildName != "" { + c.log.Println("Build name:", buildName) + } + if buildVersion != "" { + c.log.Println("Build version:", buildVersion) + } + c.log.Println("Starting up...") var boxPub boxPubKey From f99c2241719e74b175abf5af74cdf938d78c034d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 7 Dec 2018 22:31:37 +0000 Subject: [PATCH 15/52] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b91caca4..fa5d08dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - New macOS .pkgs built automatically by CircleCI - Add Docker support - Add `-json` command line flag for generating and normalising configuration in plain JSON +- Build nae and version numbers are now imprinted onto the build, accessible through `yggdrasil -version` and `yggdrasilctl getSelf` ### Changed - Switched to Chord DHT (instead of Kademlia, although protocol-compatible) From ffbdef292f3c2638263b6f5d4bfb3a46ac8fd92e Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 7 Dec 2018 17:30:07 -0600 Subject: [PATCH 16/52] Fix typo in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa5d08dc..1791bb74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - New macOS .pkgs built automatically by CircleCI - Add Docker support - Add `-json` command line flag for generating and normalising configuration in plain JSON -- Build nae and version numbers are now imprinted onto the build, accessible through `yggdrasil -version` and `yggdrasilctl getSelf` +- Build name and version numbers are now imprinted onto the build, accessible through `yggdrasil -version` and `yggdrasilctl getSelf` ### Changed - Switched to Chord DHT (instead of Kademlia, although protocol-compatible) From 586781b49c18b7e9b4340f2b8f850c951bbbd696 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 7 Dec 2018 19:56:04 -0600 Subject: [PATCH 17/52] convert to go module --- build | 16 +++++-------- yggdrasil.go => cmd/yggdrasil/main.go | 6 ++--- yggdrasilctl.go => cmd/yggdrasilctl/main.go | 24 ++++++++++--------- contrib/config/yggdrasilconf.go | 2 +- go.mod | 14 +++++++++++ go.sum | 20 ++++++++++++++++ misc/genkeys.go | 2 +- misc/sim/run-sim | 2 -- misc/sim/treesim.go | 2 +- src/{yggdrasil => }/config/config.go | 0 src/{yggdrasil => }/config/i2p.go | 0 src/{yggdrasil => }/config/tor.go | 0 src/{yggdrasil => }/defaults/defaults.go | 0 .../defaults/defaults_darwin.go | 0 .../defaults/defaults_freebsd.go | 0 .../defaults/defaults_linux.go | 0 .../defaults/defaults_netbsd.go | 0 .../defaults/defaults_openbsd.go | 0 .../defaults/defaults_other.go | 0 .../defaults/defaults_windows.go | 0 src/yggdrasil/admin.go | 2 +- src/yggdrasil/core.go | 4 ++-- src/yggdrasil/debug.go | 2 +- src/yggdrasil/tun.go | 3 ++- 24 files changed, 65 insertions(+), 34 deletions(-) rename yggdrasil.go => cmd/yggdrasil/main.go (98%) rename yggdrasilctl.go => cmd/yggdrasilctl/main.go (98%) create mode 100644 go.mod create mode 100644 go.sum rename src/{yggdrasil => }/config/config.go (100%) rename src/{yggdrasil => }/config/i2p.go (100%) rename src/{yggdrasil => }/config/tor.go (100%) rename src/{yggdrasil => }/defaults/defaults.go (100%) rename src/{yggdrasil => }/defaults/defaults_darwin.go (100%) rename src/{yggdrasil => }/defaults/defaults_freebsd.go (100%) rename src/{yggdrasil => }/defaults/defaults_linux.go (100%) rename src/{yggdrasil => }/defaults/defaults_netbsd.go (100%) rename src/{yggdrasil => }/defaults/defaults_openbsd.go (100%) rename src/{yggdrasil => }/defaults/defaults_other.go (100%) rename src/{yggdrasil => }/defaults/defaults_windows.go (100%) diff --git a/build b/build index 2e7c20cc..a62c92d4 100755 --- a/build +++ b/build @@ -7,20 +7,16 @@ do d) DEBUG=true;; esac done -export GOPATH=$PWD echo "Downloading..." -go get -d -v -go get -d -v yggdrasil -for file in *.go ; do - echo "Building: $file" - #go build $@ $file - IMPRINT="-X yggdrasil.buildName=$(sh contrib/semver/name.sh) -X yggdrasil.buildVersion=$(sh contrib/semver/version.sh)" +for CMD in `ls cmd/` ; do + echo "Building: $CMD" + IMPRINT="-X github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.buildName=$(sh contrib/semver/name.sh) -X github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.buildVersion=$(sh contrib/semver/version.sh)" if [ $DEBUG ]; then - go build -ldflags="$IMPRINT" -tags debug -v $file + go build -ldflags="$IMPRINT" -tags debug -v ./cmd/$CMD else - go build -ldflags="$IMPRINT -s -w" -v $file + go build -ldflags="$IMPRINT -s -w" -v ./cmd/$CMD fi if [ $UPX ]; then - upx --brute ${file%.go} + upx --brute $CMD fi done diff --git a/yggdrasil.go b/cmd/yggdrasil/main.go similarity index 98% rename from yggdrasil.go rename to cmd/yggdrasil/main.go index d326d18e..5b756908 100644 --- a/yggdrasil.go +++ b/cmd/yggdrasil/main.go @@ -21,9 +21,9 @@ import ( "github.com/mitchellh/mapstructure" "github.com/neilalexander/hjson-go" - "yggdrasil" - "yggdrasil/config" - "yggdrasil/defaults" + "github.com/yggdrasil-network/yggdrasil-go/src/config" + "github.com/yggdrasil-network/yggdrasil-go/src/defaults" + "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil" ) type nodeConfig = config.NodeConfig diff --git a/yggdrasilctl.go b/cmd/yggdrasilctl/main.go similarity index 98% rename from yggdrasilctl.go rename to cmd/yggdrasilctl/main.go index 6919ec33..ca3078b1 100644 --- a/yggdrasilctl.go +++ b/cmd/yggdrasilctl/main.go @@ -1,17 +1,19 @@ package main -import "errors" -import "flag" -import "fmt" -import "strings" -import "net" -import "net/url" -import "sort" -import "encoding/json" -import "strconv" -import "os" +import ( + "encoding/json" + "errors" + "flag" + "fmt" + "net" + "net/url" + "os" + "sort" + "strconv" + "strings" -import "yggdrasil/defaults" + "github.com/yggdrasil-network/yggdrasil-go/src/defaults" +) type admin_info map[string]interface{} diff --git a/contrib/config/yggdrasilconf.go b/contrib/config/yggdrasilconf.go index bc6e1326..78c0e6d7 100644 --- a/contrib/config/yggdrasilconf.go +++ b/contrib/config/yggdrasilconf.go @@ -17,7 +17,7 @@ import ( "github.com/neilalexander/hjson-go" "golang.org/x/text/encoding/unicode" - "yggdrasil/config" + "github.com/yggdrasil-network/yggdrasil-go/src/config" ) type nodeConfig = config.NodeConfig diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..1622ad40 --- /dev/null +++ b/go.mod @@ -0,0 +1,14 @@ +module github.com/yggdrasil-network/yggdrasil-go + +require ( + github.com/docker/libcontainer v2.2.1+incompatible + github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0 + github.com/mitchellh/mapstructure v1.1.2 + github.com/neilalexander/hjson-go v3.0.0+incompatible + github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 + github.com/yggdrasil-network/water v0.0.0-20180615095340-f732c88f34ae + golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 + golang.org/x/net v0.0.0-20181207154023-610586996380 + golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e + golang.org/x/text v0.3.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..2c8b145d --- /dev/null +++ b/go.sum @@ -0,0 +1,20 @@ +github.com/docker/libcontainer v2.2.1+incompatible h1:++SbbkCw+X8vAd4j2gOCzZ2Nn7s2xFALTf7LZKmM1/0= +github.com/docker/libcontainer v2.2.1+incompatible/go.mod h1:osvj61pYsqhNCMLGX31xr7klUBhHb/ZBuXS0o1Fvwbw= +github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0 h1:YnZmFjg0Nvk8851WTVWlqMC1ecJH07Ctz+Ezxx4u54g= +github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0/go.mod h1:rUi0/YffDo1oXBOGn1KRq7Fr07LX48XEBecQnmwjsAo= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/neilalexander/hjson-go v3.0.0+incompatible h1:MRqki7QoLwAe9kD12DF4yy6r04KKxvjBcMGvVGNNQ8g= +github.com/neilalexander/hjson-go v3.0.0+incompatible/go.mod h1:l+Zao6IpQ+6d/y7LnYnOfbfOeU/9xRiTi4HLVpnkcTg= +github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 h1:1zN6ImoqhSJhN8hGXFaJlSC8msLmIbX8bFqOfWLKw0w= +github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091/go.mod h1:N20Z5Y8oye9a7HmytmZ+tr8Q2vlP0tAHP13kTHzwvQY= +github.com/yggdrasil-network/water v0.0.0-20180615095340-f732c88f34ae h1:MYCANF1kehCG6x6G+/9txLfq6n3lS5Vp0Mxn1hdiBAc= +github.com/yggdrasil-network/water v0.0.0-20180615095340-f732c88f34ae/go.mod h1:R0SBCsugm+Sf1katgTb2t7GXMm+nRIv43tM4VDZbaOs= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20181207154023-610586996380 h1:zPQexyRtNYBc7bcHmehl1dH6TB3qn8zytv8cBGLDNY0= +golang.org/x/net v0.0.0-20181207154023-610586996380/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e h1:njOxP/wVblhCLIUhjHXf6X+dzTt5OQ3vMQo9mkOIKIo= +golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/misc/genkeys.go b/misc/genkeys.go index 6e2df3f9..e995805f 100644 --- a/misc/genkeys.go +++ b/misc/genkeys.go @@ -16,7 +16,7 @@ import "encoding/hex" import "flag" import "fmt" import "runtime" -import . "yggdrasil" +import . "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil" var doSig = flag.Bool("sig", false, "generate new signing keys instead") diff --git a/misc/sim/run-sim b/misc/sim/run-sim index abe108cf..14057e81 100755 --- a/misc/sim/run-sim +++ b/misc/sim/run-sim @@ -1,4 +1,2 @@ #!/bin/bash -export GOPATH=$PWD -go get -d yggdrasil go run -tags debug misc/sim/treesim.go "$@" diff --git a/misc/sim/treesim.go b/misc/sim/treesim.go index 8a4bb2a1..f4cd75fa 100644 --- a/misc/sim/treesim.go +++ b/misc/sim/treesim.go @@ -12,7 +12,7 @@ import "runtime" import "runtime/pprof" import "flag" -import . "yggdrasil" +import . "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil" //////////////////////////////////////////////////////////////////////////////// diff --git a/src/yggdrasil/config/config.go b/src/config/config.go similarity index 100% rename from src/yggdrasil/config/config.go rename to src/config/config.go diff --git a/src/yggdrasil/config/i2p.go b/src/config/i2p.go similarity index 100% rename from src/yggdrasil/config/i2p.go rename to src/config/i2p.go diff --git a/src/yggdrasil/config/tor.go b/src/config/tor.go similarity index 100% rename from src/yggdrasil/config/tor.go rename to src/config/tor.go diff --git a/src/yggdrasil/defaults/defaults.go b/src/defaults/defaults.go similarity index 100% rename from src/yggdrasil/defaults/defaults.go rename to src/defaults/defaults.go diff --git a/src/yggdrasil/defaults/defaults_darwin.go b/src/defaults/defaults_darwin.go similarity index 100% rename from src/yggdrasil/defaults/defaults_darwin.go rename to src/defaults/defaults_darwin.go diff --git a/src/yggdrasil/defaults/defaults_freebsd.go b/src/defaults/defaults_freebsd.go similarity index 100% rename from src/yggdrasil/defaults/defaults_freebsd.go rename to src/defaults/defaults_freebsd.go diff --git a/src/yggdrasil/defaults/defaults_linux.go b/src/defaults/defaults_linux.go similarity index 100% rename from src/yggdrasil/defaults/defaults_linux.go rename to src/defaults/defaults_linux.go diff --git a/src/yggdrasil/defaults/defaults_netbsd.go b/src/defaults/defaults_netbsd.go similarity index 100% rename from src/yggdrasil/defaults/defaults_netbsd.go rename to src/defaults/defaults_netbsd.go diff --git a/src/yggdrasil/defaults/defaults_openbsd.go b/src/defaults/defaults_openbsd.go similarity index 100% rename from src/yggdrasil/defaults/defaults_openbsd.go rename to src/defaults/defaults_openbsd.go diff --git a/src/yggdrasil/defaults/defaults_other.go b/src/defaults/defaults_other.go similarity index 100% rename from src/yggdrasil/defaults/defaults_other.go rename to src/defaults/defaults_other.go diff --git a/src/yggdrasil/defaults/defaults_windows.go b/src/defaults/defaults_windows.go similarity index 100% rename from src/yggdrasil/defaults/defaults_windows.go rename to src/defaults/defaults_windows.go diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index af59734e..ebd11d9c 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -14,7 +14,7 @@ import ( "sync/atomic" "time" - "yggdrasil/defaults" + "github.com/yggdrasil-network/yggdrasil-go/src/defaults" ) // TODO: Add authentication diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index b57bd863..682d815e 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -8,8 +8,8 @@ import ( "net" "regexp" - "yggdrasil/config" - "yggdrasil/defaults" + "github.com/yggdrasil-network/yggdrasil-go/src/config" + "github.com/yggdrasil-network/yggdrasil-go/src/defaults" ) var buildName string diff --git a/src/yggdrasil/debug.go b/src/yggdrasil/debug.go index 7da84749..e463518d 100644 --- a/src/yggdrasil/debug.go +++ b/src/yggdrasil/debug.go @@ -22,7 +22,7 @@ import "net/http" import "runtime" import "os" -import "yggdrasil/defaults" +import "github.com/yggdrasil-network/yggdrasil-go/src/defaults" // Start the profiler in debug builds, if the required environment variable is set. func init() { diff --git a/src/yggdrasil/tun.go b/src/yggdrasil/tun.go index 4b3617c0..e4625020 100644 --- a/src/yggdrasil/tun.go +++ b/src/yggdrasil/tun.go @@ -6,10 +6,11 @@ import ( "bytes" "errors" "time" - "yggdrasil/defaults" "github.com/songgao/packets/ethernet" "github.com/yggdrasil-network/water" + + "github.com/yggdrasil-network/yggdrasil-go/src/defaults" ) const tun_IPv6_HEADER_LENGTH = 40 From 2d5f99a00847cdca264dd0fbc6afa4cc14f73168 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 7 Dec 2018 20:19:19 -0600 Subject: [PATCH 18/52] remove working_directory from circleci config, let it use the default, as per their blog post on go modules in 1.11 --- .circleci/config.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 90bba23b..32a789c2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,8 +7,6 @@ jobs: docker: - image: circleci/golang:1.11 - working_directory: /go/src/github.com/{{ORG_NAME}}/{{REPO_NAME}} - steps: - checkout From bd2d70674569750f0719b1d6bbdcae964a384f89 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 7 Dec 2018 20:36:30 -0600 Subject: [PATCH 19/52] fix bug from go vet while I'm at it --- src/yggdrasil/switch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yggdrasil/switch.go b/src/yggdrasil/switch.go index 920926b4..99ed25b4 100644 --- a/src/yggdrasil/switch.go +++ b/src/yggdrasil/switch.go @@ -268,7 +268,7 @@ func (t *switchTable) forgetPeer(port switchPort) { // Clean all unresponsive peers from the table, needed in case a peer stops updating. // Needed in case a non-parent peer keeps the connection open but stops sending updates. // Also reclaims space from deleted peers by copying the map. -func (t switchTable) cleanPeers() { +func (t *switchTable) cleanPeers() { now := time.Now() for port, peer := range t.data.peers { if now.Sub(peer.time) > switch_timeout+switch_throttle { From af478e0e4514474c64d7b7e4dfdf520e1a376fdc Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 8 Dec 2018 00:42:13 -0600 Subject: [PATCH 20/52] fix very special case bug when trying to dhtPing the root via the admin api --- src/yggdrasil/admin.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index ebd11d9c..7d82b135 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -739,6 +739,10 @@ func (a *admin) admin_dhtPing(keyString, coordString, targetString string) (dhtR } var coords []byte for _, cstr := range strings.Split(strings.Trim(coordString, "[]"), " ") { + if cstr == "" { + // Special case, happens if trimmed is the empty string, e.g. this is the root + continue + } if u64, err := strconv.ParseUint(cstr, 10, 8); err != nil { return dhtRes{}, err } else { From 2da3ef420c13a2da1e253be0bcafa4db2157d09b Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 8 Dec 2018 10:30:43 +0000 Subject: [PATCH 21/52] Update documentation, remove stray .DS_Store file --- CHANGELOG.md | 1 + README.md | 2 +- contrib/.DS_Store | Bin 6148 -> 0 bytes 3 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 contrib/.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index 1791bb74..cc31b965 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Admin socket clean-up (making some names consistent) - Latency-based parent selection for the switch instead of uptime-based - Real peering endpoints now shown in the admin socket `getPeers` call +- Reuse the multicast port on supported platforms so that multiple Yggdrasil processes can run ### Fixed - Memory leaks in the DHT fixed diff --git a/README.md b/README.md index 15731952..11a4cbe5 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ You're encouraged to play with it, but it is strongly advised not to use it for ## Building -1. Install Go (tested on 1.9+, [godeb](https://github.com/niemeyer/godeb) is recommended for debian-based linux distributions). +1. Install Go (requires 1.11 or later, [godeb](https://github.com/niemeyer/godeb) is recommended for Debian-based Linux distributions). 2. Clone this repository. 2. `./build` diff --git a/contrib/.DS_Store b/contrib/.DS_Store deleted file mode 100644 index 799616ae9f2aed17d20533c4052922a02fadaab9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKPfx-y6mJ2gV2m70)LSp!I50Kf#blXy@Mbcj2Q{!|C`)iNY)BL_`yBd>`~rR* z-)jpI(TfLT$a~A{@Ads@)8CeMWsGrW5Lk>=7-IqyF;{}-8^Jj0oaBrLk*hI$maxDd zCU<^sE}Iv_;EG-v>D2wuH`O59aLpSx( zLE?D*3+$bEY1cRQX&m>aw&$OPonfo8ei%oo7e<}FDh`7Vq+FhdQ4kNEcn}4N8pqWE zAxfgus%(u$)=sTnm6o+XuF6rPQLDd;Dx5!bYMy5Y@J&ip0yIR4T^$! nnZ{`e80sj7Ts(?5L6v}Cq5)_d%rt@rgnk4R4b%_=f6BlIbwN_$ From 5315bc25c5d676a5a0b25c68d669965e490bf1c4 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 8 Dec 2018 10:33:33 +0000 Subject: [PATCH 22/52] Return 1 instead of -1 from semver/deb --- contrib/deb/generate.sh | 4 ++-- contrib/semver/name.sh | 2 +- contrib/semver/version.sh | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/deb/generate.sh b/contrib/deb/generate.sh index 9d5064bd..f99d8348 100644 --- a/contrib/deb/generate.sh +++ b/contrib/deb/generate.sh @@ -7,7 +7,7 @@ if [ `pwd` != `git rev-parse --show-toplevel` ] then echo "You should run this script from the top-level directory of the git repo" - exit -1 + exit 1 fi PKGBRANCH=$(basename `git name-rev --name-only HEAD`) @@ -29,7 +29,7 @@ elif [ $PKGARCH = "armhf" ]; then GOARCH=arm GOOS=linux GOARM=7 ./build elif [ $PKGARCH = "arm64" ]; then GOARCH=arm64 GOOS=linux ./build else echo "Specify PKGARCH=amd64,i386,mips,mipsel,armhf,arm64" - exit -1 + exit 1 fi echo "Building $PKGFILE" diff --git a/contrib/semver/name.sh b/contrib/semver/name.sh index 9cab7e96..935cc750 100644 --- a/contrib/semver/name.sh +++ b/contrib/semver/name.sh @@ -6,7 +6,7 @@ BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null) # Complain if the git history is not available if [ $? != 0 ]; then printf "unknown" - exit -1 + exit 1 fi # Remove "/" characters from the branch name if present diff --git a/contrib/semver/version.sh b/contrib/semver/version.sh index f7769a34..143bd906 100644 --- a/contrib/semver/version.sh +++ b/contrib/semver/version.sh @@ -19,11 +19,11 @@ if [ $? != 0 ]; then # Complain if the git history is not available if [ $? != 0 ]; then printf 'unknown' - exit -1 + exit 1 fi printf 'v0.0.%d' "$PATCH" - exit -1 + exit 1 fi # Get the number of merges on the current branch since the last tag From 9d0b8ac6f4350a3fe490fac55fb8badf1f73571d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 8 Dec 2018 10:51:31 +0000 Subject: [PATCH 23/52] Strip v from version during imprint --- build | 2 +- contrib/semver/version.sh | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/build b/build index a62c92d4..8dd23ef4 100755 --- a/build +++ b/build @@ -10,7 +10,7 @@ done echo "Downloading..." for CMD in `ls cmd/` ; do echo "Building: $CMD" - IMPRINT="-X github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.buildName=$(sh contrib/semver/name.sh) -X github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.buildVersion=$(sh contrib/semver/version.sh)" + IMPRINT="-X github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.buildName=$(sh contrib/semver/name.sh) -X github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.buildVersion=$(sh contrib/semver/version.sh --bare)" if [ $DEBUG ]; then go build -ldflags="$IMPRINT" -tags debug -v ./cmd/$CMD else diff --git a/contrib/semver/version.sh b/contrib/semver/version.sh index 143bd906..480c4dda 100644 --- a/contrib/semver/version.sh +++ b/contrib/semver/version.sh @@ -12,6 +12,13 @@ MERGE=$(git rev-list $TAG..master --grep "from $DEVELOPBRANCH" 2>/dev/null | hea # Get the number of merges since the last merge to master PATCH=$(git rev-list $TAG..master --count --merges --grep="from $DEVELOPBRANCH" 2>/dev/null) +# Decide whether we should prepend the version with "v" - the default is that +# we do because we use it in git tags, but we might not always need it +PREPEND="v" +if [ "$1" == "--bare" ]; then + PREPEND="" +fi + # If it fails then there's no last tag - go from the first commit if [ $? != 0 ]; then PATCH=$(git rev-list HEAD --count 2>/dev/null) @@ -22,7 +29,7 @@ if [ $? != 0 ]; then exit 1 fi - printf 'v0.0.%d' "$PATCH" + printf '%s0.0.%d' "$PREPEND" "$PATCH" exit 1 fi @@ -39,12 +46,12 @@ BRANCH=$(git rev-parse --abbrev-ref HEAD) # Output in the desired format if [ $PATCH = 0 ]; then if [ ! -z $FULL ]; then - printf 'v%d.%d.0' "$MAJOR" "$MINOR" + printf '%s%d.%d.0' "$PREPEND" "$MAJOR" "$MINOR" else - printf 'v%d.%d' "$MAJOR" "$MINOR" + printf '%s%d.%d' "$PREPEND" "$MAJOR" "$MINOR" fi else - printf 'v%d.%d.%d' "$MAJOR" "$MINOR" "$PATCH" + printf '%s%d.%d.%d' "$PREPEND" "$MAJOR" "$MINOR" "$PATCH" fi # Add the build tag on non-master branches From f2d01aa54db864282a2813883937d77aaec0cd68 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 8 Dec 2018 10:54:47 +0000 Subject: [PATCH 24/52] Use bare version in deb/macos packages instead of cut --- contrib/deb/generate.sh | 2 +- contrib/macos/create-pkg.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/deb/generate.sh b/contrib/deb/generate.sh index f99d8348..5af31d5c 100644 --- a/contrib/deb/generate.sh +++ b/contrib/deb/generate.sh @@ -12,7 +12,7 @@ fi PKGBRANCH=$(basename `git name-rev --name-only HEAD`) PKGNAME=$(sh contrib/semver/name.sh) -PKGVERSION=$(sh contrib/semver/version.sh | cut -c 2-) +PKGVERSION=$(sh contrib/semver/version.sh --bare) PKGARCH=${PKGARCH-amd64} PKGFILE=$PKGNAME-$PKGVERSION-$PKGARCH.deb PKGREPLACES=yggdrasil diff --git a/contrib/macos/create-pkg.sh b/contrib/macos/create-pkg.sh index 167184e3..cc9a74f7 100755 --- a/contrib/macos/create-pkg.sh +++ b/contrib/macos/create-pkg.sh @@ -72,7 +72,7 @@ chmod +x pkgbuild/root/usr/local/bin/yggdrasilctl # Work out metadata for the package info PKGNAME=$(sh contrib/semver/name.sh) -PKGVERSION=$(sh contrib/semver/version.sh | cut -c 2-) +PKGVERSION=$(sh contrib/semver/version.sh --bare) PKGARCH=${PKGARCH-amd64} PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 )) From 02f98a2592290ad4eb17a7bee14cb77400316f3c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 8 Dec 2018 11:01:05 +0000 Subject: [PATCH 25/52] Only show build name and version if it is known --- cmd/yggdrasilctl/main.go | 4 ++-- src/yggdrasil/admin.go | 9 +++++++-- src/yggdrasil/core.go | 8 ++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index ca3078b1..dcbde87a 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -183,10 +183,10 @@ func main() { } case "getself": for k, v := range res["self"].(map[string]interface{}) { - if buildname, ok := v.(map[string]interface{})["build_name"].(string); ok { + if buildname, ok := v.(map[string]interface{})["build_name"].(string); ok && buildname != "unknown" { fmt.Println("Build name:", buildname) } - if buildversion, ok := v.(map[string]interface{})["build_version"].(string); ok { + if buildversion, ok := v.(map[string]interface{})["build_version"].(string); ok && buildversion != "unknown" { fmt.Println("Build version:", buildversion) } fmt.Println("IPv6 address:", k) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index 7d82b135..2c65b6a8 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -556,13 +556,18 @@ func (a *admin) getData_getSelf() *admin_nodeInfo { table := a.core.switchTable.table.Load().(lookupTable) coords := table.self.getCoords() self := admin_nodeInfo{ - {"build_name", GetBuildName()}, - {"build_version", GetBuildVersion()}, {"box_pub_key", hex.EncodeToString(a.core.boxPub[:])}, {"ip", a.core.GetAddress().String()}, {"subnet", a.core.GetSubnet().String()}, {"coords", fmt.Sprint(coords)}, } + if name := GetBuildName(); name != "unknown" { + self = append(self, admin_pair{"build_name", name}) + } + if version := GetBuildVersion(); version != "unknown" { + self = append(self, admin_pair{"build_version", version}) + } + return &self } diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index 682d815e..5ab91a74 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -87,11 +87,11 @@ func GetBuildVersion() string { func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error { c.log = log - if buildName != "" { - c.log.Println("Build name:", buildName) + if name := GetBuildName(); name != "unknown" { + c.log.Println("Build name:", name) } - if buildVersion != "" { - c.log.Println("Build version:", buildVersion) + if version := GetBuildVersion(); version != "unknown" { + c.log.Println("Build version:", version) } c.log.Println("Starting up...") From 22e650507960a5a062d6a4f85552241666b409d6 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 8 Dec 2018 11:28:47 +0000 Subject: [PATCH 26/52] Fix bug from #228 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 32a789c2..f3092ba1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,7 +15,7 @@ jobs: command: | mkdir /tmp/upload echo 'export CINAME=$(sh contrib/semver/name.sh)' >> $BASH_ENV - echo 'export CIVERSION=$(sh contrib/semver/version.sh | cut -c 2-)' >> $BASH_ENV + echo 'export CIVERSION=$(sh contrib/semver/version.sh --bare)' >> $BASH_ENV git config --global user.email "$(git log --format='%ae' HEAD -1)"; git config --global user.name "$(git log --format='%an' HEAD -1)"; From 3b2044666d65594bd57651a6724ede973e774971 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 8 Dec 2018 11:31:20 +0000 Subject: [PATCH 27/52] Fix bug in semver version.sh --- contrib/semver/version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/semver/version.sh b/contrib/semver/version.sh index 480c4dda..331046f3 100644 --- a/contrib/semver/version.sh +++ b/contrib/semver/version.sh @@ -15,7 +15,7 @@ PATCH=$(git rev-list $TAG..master --count --merges --grep="from $DEVELOPBRANCH" # Decide whether we should prepend the version with "v" - the default is that # we do because we use it in git tags, but we might not always need it PREPEND="v" -if [ "$1" == "--bare" ]; then +if [ "$1" = "--bare" ]; then PREPEND="" fi From 34949f7c328eeaf7e62e7e14e07723d0e7570dfa Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 8 Dec 2018 13:21:58 +0000 Subject: [PATCH 28/52] Fix go.mod for neilalexander/hjson-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1622ad40..db6d359a 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ require ( github.com/docker/libcontainer v2.2.1+incompatible github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0 github.com/mitchellh/mapstructure v1.1.2 - github.com/neilalexander/hjson-go v3.0.0+incompatible + github.com/neilalexander/hjson-go v0.0.0-20180509131856-23267a251165 github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 github.com/yggdrasil-network/water v0.0.0-20180615095340-f732c88f34ae golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 diff --git a/go.sum b/go.sum index 2c8b145d..7d064112 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0 h1:YnZmFjg0Nvk github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0/go.mod h1:rUi0/YffDo1oXBOGn1KRq7Fr07LX48XEBecQnmwjsAo= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/neilalexander/hjson-go v3.0.0+incompatible h1:MRqki7QoLwAe9kD12DF4yy6r04KKxvjBcMGvVGNNQ8g= -github.com/neilalexander/hjson-go v3.0.0+incompatible/go.mod h1:l+Zao6IpQ+6d/y7LnYnOfbfOeU/9xRiTi4HLVpnkcTg= +github.com/neilalexander/hjson-go v0.0.0-20180509131856-23267a251165 h1:Oo7Yfu5lEQLGvvh2p9Z8FRHJIsl7fdOCK9xXFNBkqmQ= +github.com/neilalexander/hjson-go v0.0.0-20180509131856-23267a251165/go.mod h1:l+Zao6IpQ+6d/y7LnYnOfbfOeU/9xRiTi4HLVpnkcTg= github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 h1:1zN6ImoqhSJhN8hGXFaJlSC8msLmIbX8bFqOfWLKw0w= github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091/go.mod h1:N20Z5Y8oye9a7HmytmZ+tr8Q2vlP0tAHP13kTHzwvQY= github.com/yggdrasil-network/water v0.0.0-20180615095340-f732c88f34ae h1:MYCANF1kehCG6x6G+/9txLfq6n3lS5Vp0Mxn1hdiBAc= From ba4507c02edf991b584535feaa828f3663e74bb6 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 13:33:18 +0000 Subject: [PATCH 29/52] Update yggdrasilctl help (fixes #194) --- cmd/yggdrasilctl/main.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index dcbde87a..ab8ee595 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -18,18 +18,26 @@ import ( type admin_info map[string]interface{} func main() { + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n", os.Args[0]) + fmt.Println("Options:") + flag.PrintDefaults() + fmt.Println("Commands:\n - Use \"list\" for a list of available commands") + 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 getDHT") + fmt.Println(" - ", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getDHT") + } server := flag.String("endpoint", defaults.GetDefaults().DefaultAdminListen, "Admin socket endpoint") - injson := flag.Bool("json", false, "Output in JSON format") + injson := flag.Bool("json", false, "Output in JSON format (as opposed to pretty-print)") verbose := flag.Bool("v", false, "Verbose output (includes public keys)") flag.Parse() args := flag.Args() if len(args) == 0 { - fmt.Println("usage:", os.Args[0], "[-endpoint=proto://server] [-v] [-json] command [key=value] [...]") - fmt.Println("example:", os.Args[0], "getPeers") - fmt.Println("example:", os.Args[0], "setTunTap name=auto mtu=1500 tap_mode=false") - fmt.Println("example:", os.Args[0], "-endpoint=tcp://localhost:9001 getDHT") - fmt.Println("example:", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getDHT") + flag.Usage() return } From e759fb1c3855a5e9d319c6f1ebc491f0a1bfd06e Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 13:37:19 +0000 Subject: [PATCH 30/52] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc31b965..a073532f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Latency-based parent selection for the switch instead of uptime-based - Real peering endpoints now shown in the admin socket `getPeers` call - Reuse the multicast port on supported platforms so that multiple Yggdrasil processes can run +- `yggdrasilctl` now has more useful help text (with `-help` or when no arguments passed) ### Fixed - Memory leaks in the DHT fixed From 0fdc814c4ac7bae91b7d1a8868ac41f281ce882b Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 14:32:24 +0000 Subject: [PATCH 31/52] Allow specifying PKGSRC=, PKGVER= and PKGNAME= to build script --- build | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/build b/build index 8dd23ef4..5f13f844 100755 --- a/build +++ b/build @@ -1,5 +1,8 @@ #!/bin/sh -while getopts ud option +PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil} +PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)} +PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)} +while getopts "ud" option do case "${option}" in @@ -10,7 +13,7 @@ done echo "Downloading..." for CMD in `ls cmd/` ; do echo "Building: $CMD" - IMPRINT="-X github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.buildName=$(sh contrib/semver/name.sh) -X github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.buildVersion=$(sh contrib/semver/version.sh --bare)" + IMPRINT="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" if [ $DEBUG ]; then go build -ldflags="$IMPRINT" -tags debug -v ./cmd/$CMD else From 80d087404f62dec363779160bbe54ba885370e2e Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 17:46:48 +0000 Subject: [PATCH 32/52] Allow disabling admin socket with AdminListen="none" --- src/config/config.go | 2 +- src/yggdrasil/admin.go | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/config/config.go b/src/config/config.go index 904907b2..9671eca3 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -3,7 +3,7 @@ package config // NodeConfig defines all configuration values needed to run a signle yggdrasil node type NodeConfig struct { Listen string `comment:"Listen address for peer connections. Default is to listen for all\nTCP connections over IPv4 and IPv6 with a random port."` - 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."` + 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."` Peers []string `comment:"List of connection strings for static peers in URI format, e.g.\ntcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j."` InterfacePeers map[string][]string `comment:"List of connection strings for static peers in URI format, arranged\nby source interface, e.g. { \"eth0\": [ tcp://a.b.c.d:e ] }. Note that\nSOCKS peerings will NOT be affected by this option and should go in\nthe \"Peers\" section instead."` ReadTimeout int32 `comment:"Read timeout for connections, specified in milliseconds. If less\nthan 6000 and not negative, 6000 (the default) is used. If negative,\nreads won't time out."` diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index 2c65b6a8..19c8d0ad 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -326,7 +326,9 @@ func (a *admin) init(c *Core, listenaddr string) { // start runs the admin API socket to listen for / respond to admin API calls. func (a *admin) start() error { - go a.listen() + if a.listenaddr != "none" { + go a.listen() + } return nil } From 5ed197b3ca7992b7599c2d295a4d8077a955e82a Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 17:48:35 +0000 Subject: [PATCH 33/52] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a073532f..d2c58a27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add Docker support - Add `-json` command line flag for generating and normalising configuration in plain JSON - Build name and version numbers are now imprinted onto the build, accessible through `yggdrasil -version` and `yggdrasilctl getSelf` +- Add ability to disable admin socket by setting `AdminListen` to `"none"` ### Changed - Switched to Chord DHT (instead of Kademlia, although protocol-compatible) From 6801d713a7e73f7ec661cf71137432a5d0d4402b Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 17:53:31 +0000 Subject: [PATCH 34/52] Also don't start if AdminListen is empty --- src/yggdrasil/admin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index 19c8d0ad..dea4577a 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -326,7 +326,7 @@ func (a *admin) init(c *Core, listenaddr string) { // start runs the admin API socket to listen for / respond to admin API calls. func (a *admin) start() error { - if a.listenaddr != "none" { + if a.listenaddr != "none" && a.listenaddr != "" { go a.listen() } return nil From bec044346e0c568c67b342e3864fc19b0db7af10 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 22:31:58 +0000 Subject: [PATCH 35/52] Add -t, -c and -l to build script for specifying DWARF tables, GCFLAGS and LDFLAGS --- build | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/build b/build index 5f13f844..e463c852 100755 --- a/build +++ b/build @@ -1,23 +1,34 @@ #!/bin/sh + PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil} PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)} PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)} -while getopts "ud" option + +LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" + +while getopts "udtc:l:" option do case "${option}" in u) UPX=true;; d) DEBUG=true;; + t) TABLES=true;; + c) GCFLAGS="$GCFLAGS $OPTARG";; + l) LDFLAGS="$LDFLAGS $OPTARG";; esac done -echo "Downloading..." + +if [ -z $TABLES ]; then + STRIP="-s -w" +fi + for CMD in `ls cmd/` ; do echo "Building: $CMD" - IMPRINT="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER" + if [ $DEBUG ]; then - go build -ldflags="$IMPRINT" -tags debug -v ./cmd/$CMD + go build -ldflags="$LDFLAGS" -gcflags="$GCFLAGS" -tags debug -v ./cmd/$CMD else - go build -ldflags="$IMPRINT -s -w" -v ./cmd/$CMD + go build -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" -v ./cmd/$CMD fi if [ $UPX ]; then upx --brute $CMD From 08ad163dfe79bee2b5f8e6880ec9b598adfdc4ee Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 23:10:12 +0000 Subject: [PATCH 36/52] Add starting point for an RPM spec file --- contrib/rpm/yggdrasil.spec | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 contrib/rpm/yggdrasil.spec diff --git a/contrib/rpm/yggdrasil.spec b/contrib/rpm/yggdrasil.spec new file mode 100644 index 00000000..bab50906 --- /dev/null +++ b/contrib/rpm/yggdrasil.spec @@ -0,0 +1,47 @@ +Name: yggdrasil +Version: 0.3.0 +Release: 1%{?dist} +Summary: End-to-end encrypted IPv6 networking + +License: GPLv3 +URL: https://yggdrasil-network.github.io +Source0: https://codeload.github.com/yggdrasil-network/yggdrasil-go/tar.gz/v0.3.0 + +%{?systemd_requires} +BuildRequires: systemd golang >= 1.11 + +%description +Yggdrasil is a proof-of-concept to explore a wholly different approach to +network routing. Whereas current computer networks depend heavily on very +centralised design and configuration, Yggdrasil breaks this mould by making +use of a global spanning tree to form a scalable IPv6 encrypted mesh network. + +%prep +%setup -qn yggdrasil-go-%{version} + +%build +./build -t -l "-linkmode=external" + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/%{_bindir} +mkdir -p %{buildroot}/%{_sysconfdir}/systemd/system +install -m 0755 yggdrasil %{buildroot}/%{_bindir}/yggdrasil +install -m 0755 yggdrasilctl %{buildroot}/%{_bindir}/yggdrasilctl +install -m 0755 contrib/systemd/yggdrasil.service %{buildroot}/%{_sysconfdir}/systemd/system/yggdrasil.service +install -m 0755 contrib/systemd/yggdrasil-resume.service %{buildroot}/%{_sysconfdir}/systemd/system/yggdrasil-resume.service + +%files +%{_bindir}/yggdrasil +%{_bindir}/yggdrasilctl +%{_sysconfdir}/systemd/system/yggdrasil.service +%{_sysconfdir}/systemd/system/yggdrasil-resume.service + +%post +%systemd_post yggdrasil.service + +%preun +%systemd_preun yggdrasil.service + +%postun +%systemd_postun_with_restart yggdrasil.service From f6cdb8e38e6e847d46b3f69682ab8ceb2913e0bd Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 9 Dec 2018 23:35:40 +0000 Subject: [PATCH 37/52] Update CHANGELOG.md --- CHANGELOG.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2c58a27..8501f3e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,29 +25,29 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> -## [0.x.x] - TBD +## [0.3.0] - 2018-12-12 ### Added -- Crypto-key routing support for both IPv4 and IPv6 -- Add `SwitchOptions` in configuration file for tuning the switch +- Crypto-key routing support for tunnelling both IPv4 and IPv6 over Yggdrasil +- Add advanced `SwitchOptions` in configuration file for tuning the switch - Add `dhtPing` to the admin socket to aid in crawling the network - New macOS .pkgs built automatically by CircleCI -- Add Docker support -- Add `-json` command line flag for generating and normalising configuration in plain JSON +- Add Dockerfile to repository for Docker support +- Add `-json` command line flag for generating and normalising configuration in plain JSON instead of HJSON - Build name and version numbers are now imprinted onto the build, accessible through `yggdrasil -version` and `yggdrasilctl getSelf` - Add ability to disable admin socket by setting `AdminListen` to `"none"` ### Changed -- Switched to Chord DHT (instead of Kademlia, although protocol-compatible) -- Admin socket clean-up (making some names consistent) -- Latency-based parent selection for the switch instead of uptime-based -- Real peering endpoints now shown in the admin socket `getPeers` call +- Switched to Chord DHT (instead of Kademlia, although still compatible at the protocol level) +- Cleaned up some of the parameter naming in the admin socket +- Latency-based parent selection for the switch instead of uptime-based (should help to avoid high latency links somewhat) +- Real peering endpoints now shown in the admin socket `getPeers` call to help identify peerings - Reuse the multicast port on supported platforms so that multiple Yggdrasil processes can run - `yggdrasilctl` now has more useful help text (with `-help` or when no arguments passed) ### Fixed - Memory leaks in the DHT fixed -- Crash where ICMPv6 NDP goroutine would incorrectly start in TUN mode fixed -- Remove peers from the switch table of they stop sending switch messages but keep the TCP connection alive +- Crash fixed where the ICMPv6 NDP goroutine would incorrectly start in TUN mode +- Removing peers from the switch table if they stop sending switch messages but keep the TCP connection alive ## [0.2.7] - 2018-10-13 ### Added From f791df4977fc3fb4ab4c884d187d1b4edd7ac744 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 00:00:23 +0000 Subject: [PATCH 38/52] Try to chmod 660 the admin socket if using AF_UNIX --- src/yggdrasil/admin.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index dea4577a..50fdcf90 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -344,6 +344,11 @@ func (a *admin) listen() { switch strings.ToLower(u.Scheme) { case "unix": a.listener, err = net.Listen("unix", a.listenaddr[7:]) + if err == nil { + if err := os.Chmod(a.listenaddr[7:], 0660); err != nil { + a.core.log.Printf("WARNING:", a.listenaddr[:7], "may have unsafe permissions!") + } + } case "tcp": a.listener, err = net.Listen("tcp", u.Host) default: From 06c6dfc67f3c5aa90356e3ccf2ca326f7d8cfa62 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 00:19:21 +0000 Subject: [PATCH 39/52] Complain if socket file already exists --- src/yggdrasil/admin.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index 50fdcf90..720c30f8 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -343,11 +343,14 @@ func (a *admin) listen() { if err == nil { switch strings.ToLower(u.Scheme) { case "unix": + if _, err := os.Stat(a.listenaddr[7:]); err == nil { + a.core.log.Println("WARNING:", a.listenaddr[7:], "already exists and may be in use by another process") + } a.listener, err = net.Listen("unix", a.listenaddr[7:]) if err == nil { if err := os.Chmod(a.listenaddr[7:], 0660); err != nil { - a.core.log.Printf("WARNING:", a.listenaddr[:7], "may have unsafe permissions!") - } + a.core.log.Println("WARNING:", a.listenaddr[:7], "may have unsafe permissions!") + } } case "tcp": a.listener, err = net.Listen("tcp", u.Host) From 74a904d04cca967c3a3b8b88f775fecdf07b6514 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 00:26:12 +0000 Subject: [PATCH 40/52] Don't os.Chmod if we suspect the socket belongs to an abstract namespace --- src/yggdrasil/admin.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index 720c30f8..2c3dc345 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -348,8 +348,12 @@ func (a *admin) listen() { } a.listener, err = net.Listen("unix", a.listenaddr[7:]) if err == nil { - if err := os.Chmod(a.listenaddr[7:], 0660); err != nil { - a.core.log.Println("WARNING:", a.listenaddr[:7], "may have unsafe permissions!") + switch a.listenaddr[7:8] { + case "@": // maybe abstract namespace + default: + if err := os.Chmod(a.listenaddr[7:], 0660); err != nil { + a.core.log.Println("WARNING:", a.listenaddr[:7], "may have unsafe permissions!") + } } } case "tcp": From bbe2f56b74ba7632de990361640dc7b3751300dd Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 00:31:31 +0000 Subject: [PATCH 41/52] Default to /var/run/yggdrasil.sock for admin on darwin/macOS --- src/defaults/defaults_darwin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/defaults/defaults_darwin.go b/src/defaults/defaults_darwin.go index 778162c0..68a13931 100644 --- a/src/defaults/defaults_darwin.go +++ b/src/defaults/defaults_darwin.go @@ -7,7 +7,7 @@ package defaults func GetDefaults() platformDefaultParameters { return platformDefaultParameters{ // Admin - DefaultAdminListen: "tcp://localhost:9001", + DefaultAdminListen: "unix:///var/run/yggdrasil.sock", // TUN/TAP MaximumIfMTU: 65535, From 8aaaeb26eb5d80ef753a64e14108ed5cfedf5880 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 00:37:32 +0000 Subject: [PATCH 42/52] Default to /var/run/yggdrasil.sock for admin on Linux, BSDs --- src/defaults/defaults_freebsd.go | 2 +- src/defaults/defaults_linux.go | 2 +- src/defaults/defaults_netbsd.go | 2 +- src/defaults/defaults_openbsd.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/defaults/defaults_freebsd.go b/src/defaults/defaults_freebsd.go index 7c5c7752..4ba7face 100644 --- a/src/defaults/defaults_freebsd.go +++ b/src/defaults/defaults_freebsd.go @@ -7,7 +7,7 @@ package defaults func GetDefaults() platformDefaultParameters { return platformDefaultParameters{ // Admin - DefaultAdminListen: "tcp://localhost:9001", + DefaultAdminListen: "unix:///var/run/yggdrasil.sock", // TUN/TAP MaximumIfMTU: 32767, diff --git a/src/defaults/defaults_linux.go b/src/defaults/defaults_linux.go index 85287eeb..e3e23e20 100644 --- a/src/defaults/defaults_linux.go +++ b/src/defaults/defaults_linux.go @@ -7,7 +7,7 @@ package defaults func GetDefaults() platformDefaultParameters { return platformDefaultParameters{ // Admin - DefaultAdminListen: "tcp://localhost:9001", + DefaultAdminListen: "unix:///var/run/yggdrasil.sock", // TUN/TAP MaximumIfMTU: 65535, diff --git a/src/defaults/defaults_netbsd.go b/src/defaults/defaults_netbsd.go index 8e8f7b5f..7879a415 100644 --- a/src/defaults/defaults_netbsd.go +++ b/src/defaults/defaults_netbsd.go @@ -7,7 +7,7 @@ package defaults func GetDefaults() platformDefaultParameters { return platformDefaultParameters{ // Admin - DefaultAdminListen: "tcp://localhost:9001", + DefaultAdminListen: "unix:///var/run/yggdrasil.sock", // TUN/TAP MaximumIfMTU: 9000, diff --git a/src/defaults/defaults_openbsd.go b/src/defaults/defaults_openbsd.go index 8b3e2bbc..7bfd30e6 100644 --- a/src/defaults/defaults_openbsd.go +++ b/src/defaults/defaults_openbsd.go @@ -7,7 +7,7 @@ package defaults func GetDefaults() platformDefaultParameters { return platformDefaultParameters{ // Admin - DefaultAdminListen: "tcp://localhost:9001", + DefaultAdminListen: "unix:///var/run/yggdrasil.sock", // TUN/TAP MaximumIfMTU: 16384, From 2928fcb046a2ab1e1c525e3aa491730a2523b138 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 00:42:56 +0000 Subject: [PATCH 43/52] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8501f3e9..da8c7022 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed - Switched to Chord DHT (instead of Kademlia, although still compatible at the protocol level) +- The `AdminListen` option and `yggdrasilctl` now default to `unix:///var/run/yggdrasil.sock` on BSDs, macOS and Linux - Cleaned up some of the parameter naming in the admin socket - Latency-based parent selection for the switch instead of uptime-based (should help to avoid high latency links somewhat) - Real peering endpoints now shown in the admin socket `getPeers` call to help identify peerings From dff1dca19c8f713d0f2167ff0ed93cbea27fcae1 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 10:20:59 +0000 Subject: [PATCH 44/52] Add DefaultConfigFile to defaults for yggdrasilctl --- src/defaults/defaults.go | 3 +++ src/defaults/defaults_darwin.go | 3 +++ src/defaults/defaults_freebsd.go | 3 +++ src/defaults/defaults_linux.go | 3 +++ src/defaults/defaults_netbsd.go | 3 +++ src/defaults/defaults_openbsd.go | 3 +++ src/defaults/defaults_other.go | 3 +++ src/defaults/defaults_windows.go | 3 +++ 8 files changed, 24 insertions(+) diff --git a/src/defaults/defaults.go b/src/defaults/defaults.go index 753efc53..3834990e 100644 --- a/src/defaults/defaults.go +++ b/src/defaults/defaults.go @@ -7,6 +7,9 @@ type platformDefaultParameters struct { // Admin socket DefaultAdminListen string + // Configuration (used for yggdrasilctl) + DefaultConfigFile string + // TUN/TAP MaximumIfMTU int DefaultIfMTU int diff --git a/src/defaults/defaults_darwin.go b/src/defaults/defaults_darwin.go index 68a13931..9bac3aad 100644 --- a/src/defaults/defaults_darwin.go +++ b/src/defaults/defaults_darwin.go @@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters { // Admin DefaultAdminListen: "unix:///var/run/yggdrasil.sock", + // Configuration (used for yggdrasilctl) + DefaultConfigFile: "/etc/yggdrasil.conf", + // TUN/TAP MaximumIfMTU: 65535, DefaultIfMTU: 65535, diff --git a/src/defaults/defaults_freebsd.go b/src/defaults/defaults_freebsd.go index 4ba7face..df1a3c65 100644 --- a/src/defaults/defaults_freebsd.go +++ b/src/defaults/defaults_freebsd.go @@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters { // Admin DefaultAdminListen: "unix:///var/run/yggdrasil.sock", + // Configuration (used for yggdrasilctl) + DefaultConfigFile: "/etc/yggdrasil.conf", + // TUN/TAP MaximumIfMTU: 32767, DefaultIfMTU: 32767, diff --git a/src/defaults/defaults_linux.go b/src/defaults/defaults_linux.go index e3e23e20..2f3459ca 100644 --- a/src/defaults/defaults_linux.go +++ b/src/defaults/defaults_linux.go @@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters { // Admin DefaultAdminListen: "unix:///var/run/yggdrasil.sock", + // Configuration (used for yggdrasilctl) + DefaultConfigFile: "/etc/yggdrasil.conf", + // TUN/TAP MaximumIfMTU: 65535, DefaultIfMTU: 65535, diff --git a/src/defaults/defaults_netbsd.go b/src/defaults/defaults_netbsd.go index 7879a415..40476dcb 100644 --- a/src/defaults/defaults_netbsd.go +++ b/src/defaults/defaults_netbsd.go @@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters { // Admin DefaultAdminListen: "unix:///var/run/yggdrasil.sock", + // Configuration (used for yggdrasilctl) + DefaultConfigFile: "/etc/yggdrasil.conf", + // TUN/TAP MaximumIfMTU: 9000, DefaultIfMTU: 9000, diff --git a/src/defaults/defaults_openbsd.go b/src/defaults/defaults_openbsd.go index 7bfd30e6..cd6d202a 100644 --- a/src/defaults/defaults_openbsd.go +++ b/src/defaults/defaults_openbsd.go @@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters { // Admin DefaultAdminListen: "unix:///var/run/yggdrasil.sock", + // Configuration (used for yggdrasilctl) + DefaultConfigFile: "/etc/yggdrasil.conf", + // TUN/TAP MaximumIfMTU: 16384, DefaultIfMTU: 16384, diff --git a/src/defaults/defaults_other.go b/src/defaults/defaults_other.go index d780872b..a01ab7af 100644 --- a/src/defaults/defaults_other.go +++ b/src/defaults/defaults_other.go @@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters { // Admin DefaultAdminListen: "tcp://localhost:9001", + // Configuration (used for yggdrasilctl) + DefaultConfigFile: "/etc/yggdrasil.conf", + // TUN/TAP MaximumIfMTU: 65535, DefaultIfMTU: 65535, diff --git a/src/defaults/defaults_windows.go b/src/defaults/defaults_windows.go index 83877d62..3b04783a 100644 --- a/src/defaults/defaults_windows.go +++ b/src/defaults/defaults_windows.go @@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters { // Admin DefaultAdminListen: "tcp://localhost:9001", + // Configuration (used for yggdrasilctl) + DefaultConfigFile: "C:\\Program Files\\Yggdrasil\\yggdrasil.conf", + // TUN/TAP MaximumIfMTU: 65535, DefaultIfMTU: 65535, From cd11d2eccded97cd0454d2d2918a4725d1baae74 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 10:54:41 +0000 Subject: [PATCH 45/52] Produce more meaningful logging from yggdrasilctl when things go wrong --- cmd/yggdrasilctl/main.go | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index ab8ee595..5b6784c3 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -1,10 +1,12 @@ package main import ( + "bytes" "encoding/json" "errors" "flag" "fmt" + "log" "net" "net/url" "os" @@ -18,10 +20,15 @@ import ( type admin_info map[string]interface{} func main() { + logbuffer := &bytes.Buffer{} + logger := log.New(logbuffer, "", log.Flags()) + + defaultEndpoint := defaults.GetDefaults().DefaultAdminListen + flag.Usage = func() { - fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n", os.Args[0]) + fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n", os.Args[0]) fmt.Println("Options:") - flag.PrintDefaults() + flag.PrintDefaults() fmt.Println("Commands:\n - Use \"list\" for a list of available commands") fmt.Println("Examples:") fmt.Println(" - ", os.Args[0], "list") @@ -30,7 +37,7 @@ func main() { fmt.Println(" - ", os.Args[0], "-endpoint=tcp://localhost:9001 getDHT") fmt.Println(" - ", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getDHT") } - server := flag.String("endpoint", defaults.GetDefaults().DefaultAdminListen, "Admin socket endpoint") + server := flag.String("endpoint", defaultEndpoint, "Admin socket endpoint") injson := flag.Bool("json", false, "Output in JSON format (as opposed to pretty-print)") verbose := flag.Bool("v", false, "Verbose output (includes public keys)") flag.Parse() @@ -46,18 +53,24 @@ func main() { if err == nil { switch strings.ToLower(u.Scheme) { case "unix": + logger.Println("Connecting to UNIX socket", (*server)[7:]) conn, err = net.Dial("unix", (*server)[7:]) case "tcp": + logger.Println("Connecting to TCP socket", u.Host) conn, err = net.Dial("tcp", u.Host) default: + logger.Println("Unknown protocol", u.Scheme, "- please check your endpoint") err = errors.New("protocol not supported") } } else { + logger.Println("Connecting to TCP socket", u.Host) conn, err = net.Dial("tcp", *server) } if err != nil { + fmt.Print(logbuffer) panic(err) } + logger.Println("Connected") defer conn.Close() decoder := json.NewDecoder(conn) @@ -67,11 +80,13 @@ func main() { for c, a := range args { if c == 0 { + logger.Printf("Sending request: %v\n", a) send["request"] = a continue } tokens := strings.Split(a, "=") if i, err := strconv.Atoi(tokens[1]); err == nil { + logger.Printf("Sending parameter %s: %d\n", tokens[0], i) send[tokens[0]] = i } else { switch strings.ToLower(tokens[1]) { @@ -82,28 +97,32 @@ func main() { default: send[tokens[0]] = tokens[1] } + logger.Printf("Sending parameter %s: %v\n", tokens[0], send[tokens[0]]) } } if err := encoder.Encode(&send); err != nil { + fmt.Print(logbuffer) panic(err) } + logger.Printf("Request sent") if err := decoder.Decode(&recv); err == nil { + logger.Printf("Response received") if recv["status"] == "error" { if err, ok := recv["error"]; ok { - fmt.Println("Error:", err) + fmt.Println("Admin socket returned an error:", err) } else { - fmt.Println("Unspecified error occured") + fmt.Println("Admin socket returned an error but didn't specify any error text") } os.Exit(1) } if _, ok := recv["request"]; !ok { fmt.Println("Missing request in response (malformed response?)") - return + os.Exit(1) } if _, ok := recv["response"]; !ok { fmt.Println("Missing response body (malformed response?)") - return + os.Exit(1) } req := recv["request"].(map[string]interface{}) res := recv["response"].(map[string]interface{}) @@ -243,7 +262,7 @@ func main() { queuesize := v.(map[string]interface{})["queue_size"].(float64) queuepackets := v.(map[string]interface{})["queue_packets"].(float64) queueid := v.(map[string]interface{})["queue_id"].(string) - portqueues[queueport] += 1 + portqueues[queueport]++ portqueuesize[queueport] += queuesize portqueuepackets[queueport] += queuepackets queuesizepercent := (100 / maximumqueuesize) * queuesize @@ -331,9 +350,11 @@ func main() { fmt.Println(string(json)) } } + } else { + logger.Println("Error receiving response:", err) } - if v, ok := recv["status"]; ok && v == "error" { + if v, ok := recv["status"]; ok && v != "success" { os.Exit(1) } os.Exit(0) From d29b5a074a7cba359e9478fba0d40490c457fa31 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 11:09:10 +0000 Subject: [PATCH 46/52] Try to use default config file location to find AdminListen when yggdrasilctl is not given an endpoint --- cmd/yggdrasilctl/main.go | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 5b6784c3..1fdf1bcd 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -6,6 +6,7 @@ import ( "errors" "flag" "fmt" + "io/ioutil" "log" "net" "net/url" @@ -14,6 +15,9 @@ import ( "strconv" "strings" + "golang.org/x/text/encoding/unicode" + + "github.com/neilalexander/hjson-go" "github.com/yggdrasil-network/yggdrasil-go/src/defaults" ) @@ -48,6 +52,37 @@ func main() { return } + if *server == defaultEndpoint { + if config, err := ioutil.ReadFile(defaults.GetDefaults().DefaultConfigFile); err == nil { + if bytes.Compare(config[0:2], []byte{0xFF, 0xFE}) == 0 || + bytes.Compare(config[0:2], []byte{0xFE, 0xFF}) == 0 { + utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM) + decoder := utf.NewDecoder() + config, err = decoder.Bytes(config) + if err != nil { + panic(err) + } + } + var dat map[string]interface{} + if err := hjson.Unmarshal(config, &dat); err != nil { + panic(err) + } + if ep, ok := dat["AdminListen"].(string); ok && (ep != "none" && ep != "") { + defaultEndpoint = ep + logger.Println("Found platform default config file", defaults.GetDefaults().DefaultConfigFile) + logger.Println("Using endpoint", defaultEndpoint, "from AdminListen") + } else { + logger.Println("Configuration file doesn't contain appropriate AdminListen option") + logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) + } + } else { + logger.Println("Can't open config file from default location", defaults.GetDefaults().DefaultConfigFile) + logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) + } + } else { + logger.Println("Using endpoint", *server, "from command line") + } + var conn net.Conn u, err := url.Parse(*server) if err == nil { @@ -59,7 +94,7 @@ func main() { logger.Println("Connecting to TCP socket", u.Host) conn, err = net.Dial("tcp", u.Host) default: - logger.Println("Unknown protocol", u.Scheme, "- please check your endpoint") + logger.Println("Unknown protocol or malformed address - check your endpoint") err = errors.New("protocol not supported") } } else { From b4b3609678942f0fac200595b66c440295a6f472 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 11:12:40 +0000 Subject: [PATCH 47/52] Really use the correct endpoint --- cmd/yggdrasilctl/main.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 1fdf1bcd..9646f6c1 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -27,7 +27,7 @@ func main() { logbuffer := &bytes.Buffer{} logger := log.New(logbuffer, "", log.Flags()) - defaultEndpoint := defaults.GetDefaults().DefaultAdminListen + endpoint := defaults.GetDefaults().DefaultAdminListen flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n", os.Args[0]) @@ -41,7 +41,7 @@ func main() { fmt.Println(" - ", os.Args[0], "-endpoint=tcp://localhost:9001 getDHT") fmt.Println(" - ", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getDHT") } - server := flag.String("endpoint", defaultEndpoint, "Admin socket endpoint") + server := flag.String("endpoint", endpoint, "Admin socket endpoint") injson := flag.Bool("json", false, "Output in JSON format (as opposed to pretty-print)") verbose := flag.Bool("v", false, "Verbose output (includes public keys)") flag.Parse() @@ -52,7 +52,7 @@ func main() { return } - if *server == defaultEndpoint { + if *server == endpoint { if config, err := ioutil.ReadFile(defaults.GetDefaults().DefaultConfigFile); err == nil { if bytes.Compare(config[0:2], []byte{0xFF, 0xFE}) == 0 || bytes.Compare(config[0:2], []byte{0xFE, 0xFF}) == 0 { @@ -68,9 +68,9 @@ func main() { panic(err) } if ep, ok := dat["AdminListen"].(string); ok && (ep != "none" && ep != "") { - defaultEndpoint = ep + endpoint = ep logger.Println("Found platform default config file", defaults.GetDefaults().DefaultConfigFile) - logger.Println("Using endpoint", defaultEndpoint, "from AdminListen") + logger.Println("Using endpoint", endpoint, "from AdminListen") } else { logger.Println("Configuration file doesn't contain appropriate AdminListen option") logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) @@ -80,16 +80,16 @@ func main() { logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) } } else { - logger.Println("Using endpoint", *server, "from command line") + logger.Println("Using endpoint", endpoint, "from command line") } var conn net.Conn - u, err := url.Parse(*server) + u, err := url.Parse(endpoint) if err == nil { switch strings.ToLower(u.Scheme) { case "unix": - logger.Println("Connecting to UNIX socket", (*server)[7:]) - conn, err = net.Dial("unix", (*server)[7:]) + logger.Println("Connecting to UNIX socket", endpoint[7:]) + conn, err = net.Dial("unix", endpoint[7:]) case "tcp": logger.Println("Connecting to TCP socket", u.Host) conn, err = net.Dial("tcp", u.Host) @@ -99,7 +99,7 @@ func main() { } } else { logger.Println("Connecting to TCP socket", u.Host) - conn, err = net.Dial("tcp", *server) + conn, err = net.Dial("tcp", endpoint) } if err != nil { fmt.Print(logbuffer) From c78e1b98cccdfe1e83dddabdc95b849d2ef7aac2 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 11:29:42 +0000 Subject: [PATCH 48/52] Show yggdrasilctl log buffer on panic --- cmd/yggdrasilctl/main.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 9646f6c1..b37c2561 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -26,6 +26,13 @@ type admin_info map[string]interface{} func main() { logbuffer := &bytes.Buffer{} logger := log.New(logbuffer, "", log.Flags()) + defer func() { + if r := recover(); r != nil { + logger.Println("Fatal error:", r) + fmt.Print(logbuffer) + os.Exit(1) + } + }() endpoint := defaults.GetDefaults().DefaultAdminListen @@ -102,7 +109,6 @@ func main() { conn, err = net.Dial("tcp", endpoint) } if err != nil { - fmt.Print(logbuffer) panic(err) } logger.Println("Connected") @@ -137,7 +143,6 @@ func main() { } if err := encoder.Encode(&send); err != nil { - fmt.Print(logbuffer) panic(err) } logger.Printf("Request sent") From 3eb1a40c684b32f07ef485b44723323c5db6c73f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 11:34:37 +0000 Subject: [PATCH 49/52] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da8c7022..2db4dde1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `-json` command line flag for generating and normalising configuration in plain JSON instead of HJSON - Build name and version numbers are now imprinted onto the build, accessible through `yggdrasil -version` and `yggdrasilctl getSelf` - Add ability to disable admin socket by setting `AdminListen` to `"none"` +- `yggdrasilctl` now tries to look for the default configuration file to find `AdminListen` if `-endpoint` is not specified +- `yggdrasilctl` now returns more useful logging in the event of a fatal error ### Changed - Switched to Chord DHT (instead of Kademlia, although still compatible at the protocol level) From f09adc21926cef760b98ac0ebbf6633b201aa038 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 22:04:37 +0000 Subject: [PATCH 50/52] Update getRoutes format --- src/yggdrasil/admin.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index dea4577a..253a9bfb 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -268,11 +268,11 @@ func (a *admin) init(c *Core, listenaddr string) { return admin_info{"source_subnets": subnets}, nil }) a.addHandler("getRoutes", []string{}, func(in admin_info) (admin_info, error) { - var routes []string + routes := make(admin_info) a.core.router.doAdmin(func() { getRoutes := func(ckrs []cryptokey_route) { for _, ckr := range ckrs { - routes = append(routes, fmt.Sprintf("%s via %s", ckr.subnet.String(), hex.EncodeToString(ckr.destination[:]))) + routes[ckr.subnet.String()] = hex.EncodeToString(ckr.destination[:]) } } getRoutes(a.core.router.cryptokey.ipv4routes) From 65e34bbbab68811b362e6176b79e2409afde2a4d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 22:19:08 +0000 Subject: [PATCH 51/52] Enforce maximum CKR routing cache size --- src/yggdrasil/ckr.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/yggdrasil/ckr.go b/src/yggdrasil/ckr.go index b73946c4..2324f612 100644 --- a/src/yggdrasil/ckr.go +++ b/src/yggdrasil/ckr.go @@ -241,6 +241,16 @@ func (c *cryptokey) getPublicKeyForAddress(addr address, addrlen int) (boxPubKey for _, route := range *routingtable { // Does this subnet match the given IP? if route.subnet.Contains(ip) { + // Check if the routing cache is above a certain size, if it is evict + // a random entry so we can make room for this one. We take advantage + // of the fact that the iteration order is random here + if len(*routingcache) > 1024 { + for k := range *routingcache { + delete(*routingcache, k) + break + } + } + // Cache the entry for future packets to get a faster lookup (*routingcache)[addr] = route From 90ace46587f7f037df6f1698047886737cfd1e21 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 10 Dec 2018 22:30:31 +0000 Subject: [PATCH 52/52] Enforce CKR cache size more strongly --- src/yggdrasil/ckr.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/yggdrasil/ckr.go b/src/yggdrasil/ckr.go index 2324f612..d88b8d3c 100644 --- a/src/yggdrasil/ckr.go +++ b/src/yggdrasil/ckr.go @@ -244,11 +244,11 @@ func (c *cryptokey) getPublicKeyForAddress(addr address, addrlen int) (boxPubKey // Check if the routing cache is above a certain size, if it is evict // a random entry so we can make room for this one. We take advantage // of the fact that the iteration order is random here - if len(*routingcache) > 1024 { - for k := range *routingcache { - delete(*routingcache, k) + for k := range *routingcache { + if len(*routingcache) < 1024 { break } + delete(*routingcache, k) } // Cache the entry for future packets to get a faster lookup