mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-26 08:21:36 +00:00
Merge pull request #1 from yggdrasil-network/develop
Branch Develop: Base to Fork
This commit is contained in:
commit
e5218335c8
@ -7,8 +7,6 @@ jobs:
|
|||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.11
|
- image: circleci/golang:1.11
|
||||||
|
|
||||||
working_directory: /go/src/github.com/{{ORG_NAME}}/{{REPO_NAME}}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
|
||||||
@ -17,7 +15,9 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
mkdir /tmp/upload
|
mkdir /tmp/upload
|
||||||
echo 'export CINAME=$(sh contrib/semver/name.sh)' >> $BASH_ENV
|
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)";
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Install alien
|
name: Install alien
|
||||||
@ -98,3 +98,13 @@ jobs:
|
|||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: /tmp/upload
|
path: /tmp/upload
|
||||||
destination: /
|
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
|
||||||
|
27
CHANGELOG.md
27
CHANGELOG.md
@ -25,6 +25,33 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||||||
- in case of vulnerabilities.
|
- in case of vulnerabilities.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## [0.3.0] - 2018-12-12
|
||||||
|
### Added
|
||||||
|
- 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 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"`
|
||||||
|
- `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)
|
||||||
|
- 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
|
||||||
|
- 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 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
|
## [0.2.7] - 2018-10-13
|
||||||
### Added
|
### Added
|
||||||
- Session firewall, which makes it possible to control who can open sessions with your node
|
- Session firewall, which makes it possible to control who can open sessions with your node
|
||||||
|
@ -15,7 +15,7 @@ You're encouraged to play with it, but it is strongly advised not to use it for
|
|||||||
|
|
||||||
## Building
|
## 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. Clone this repository.
|
||||||
2. `./build`
|
2. `./build`
|
||||||
|
|
||||||
|
33
build
33
build
@ -1,25 +1,36 @@
|
|||||||
#!/bin/sh
|
#!/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)}
|
||||||
|
|
||||||
|
LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER"
|
||||||
|
|
||||||
|
while getopts "udtc:l:" option
|
||||||
do
|
do
|
||||||
case "${option}"
|
case "${option}"
|
||||||
in
|
in
|
||||||
u) UPX=true;;
|
u) UPX=true;;
|
||||||
d) DEBUG=true;;
|
d) DEBUG=true;;
|
||||||
|
t) TABLES=true;;
|
||||||
|
c) GCFLAGS="$GCFLAGS $OPTARG";;
|
||||||
|
l) LDFLAGS="$LDFLAGS $OPTARG";;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
export GOPATH=$PWD
|
|
||||||
echo "Downloading..."
|
if [ -z $TABLES ]; then
|
||||||
go get -d -v
|
STRIP="-s -w"
|
||||||
go get -d -v yggdrasil
|
fi
|
||||||
for file in *.go ; do
|
|
||||||
echo "Building: $file"
|
for CMD in `ls cmd/` ; do
|
||||||
#go build $@ $file
|
echo "Building: $CMD"
|
||||||
|
|
||||||
if [ $DEBUG ]; then
|
if [ $DEBUG ]; then
|
||||||
go build -tags debug -v $file
|
go build -ldflags="$LDFLAGS" -gcflags="$GCFLAGS" -tags debug -v ./cmd/$CMD
|
||||||
else
|
else
|
||||||
go build -ldflags="-s -w" -v $file
|
go build -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" -v ./cmd/$CMD
|
||||||
fi
|
fi
|
||||||
if [ $UPX ]; then
|
if [ $UPX ]; then
|
||||||
upx --brute ${file%.go}
|
upx --brute $CMD
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -21,9 +21,9 @@ import (
|
|||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
"github.com/neilalexander/hjson-go"
|
"github.com/neilalexander/hjson-go"
|
||||||
|
|
||||||
"yggdrasil"
|
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||||
"yggdrasil/config"
|
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
|
||||||
"yggdrasil/defaults"
|
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nodeConfig = config.NodeConfig
|
type nodeConfig = config.NodeConfig
|
||||||
@ -100,10 +100,15 @@ func main() {
|
|||||||
normaliseconf := flag.Bool("normaliseconf", false, "use in combination with either -useconf or -useconffile, outputs your configuration normalised")
|
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")
|
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)")
|
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()
|
flag.Parse()
|
||||||
|
|
||||||
var cfg *nodeConfig
|
var cfg *nodeConfig
|
||||||
switch {
|
switch {
|
||||||
|
case *version:
|
||||||
|
fmt.Println("Build name:", yggdrasil.GetBuildName())
|
||||||
|
fmt.Println("Build version:", yggdrasil.GetBuildVersion())
|
||||||
|
os.Exit(0)
|
||||||
case *autoconf:
|
case *autoconf:
|
||||||
// Use an autoconf-generated config, this will give us random keys and
|
// Use an autoconf-generated config, this will give us random keys and
|
||||||
// port numbers, and will use an automatically selected TUN/TAP interface.
|
// port numbers, and will use an automatically selected TUN/TAP interface.
|
@ -1,53 +1,117 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
import "flag"
|
"bytes"
|
||||||
import "fmt"
|
"encoding/json"
|
||||||
import "strings"
|
"errors"
|
||||||
import "net"
|
"flag"
|
||||||
import "net/url"
|
"fmt"
|
||||||
import "sort"
|
"io/ioutil"
|
||||||
import "encoding/json"
|
"log"
|
||||||
import "strconv"
|
"net"
|
||||||
import "os"
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
import "yggdrasil/defaults"
|
"golang.org/x/text/encoding/unicode"
|
||||||
|
|
||||||
|
"github.com/neilalexander/hjson-go"
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
|
||||||
|
)
|
||||||
|
|
||||||
type admin_info map[string]interface{}
|
type admin_info map[string]interface{}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
server := flag.String("endpoint", defaults.GetDefaults().DefaultAdminListen, "Admin socket endpoint")
|
logbuffer := &bytes.Buffer{}
|
||||||
injson := flag.Bool("json", false, "Output in JSON format")
|
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
|
||||||
|
|
||||||
|
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", 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)")
|
verbose := flag.Bool("v", false, "Verbose output (includes public keys)")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
args := flag.Args()
|
args := flag.Args()
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
fmt.Println("usage:", os.Args[0], "[-endpoint=proto://server] [-v] [-json] command [key=value] [...]")
|
flag.Usage()
|
||||||
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")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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 != "") {
|
||||||
|
endpoint = ep
|
||||||
|
logger.Println("Found platform default config file", defaults.GetDefaults().DefaultConfigFile)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
} 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", endpoint, "from command line")
|
||||||
|
}
|
||||||
|
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
u, err := url.Parse(*server)
|
u, err := url.Parse(endpoint)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
switch strings.ToLower(u.Scheme) {
|
switch strings.ToLower(u.Scheme) {
|
||||||
case "unix":
|
case "unix":
|
||||||
conn, err = net.Dial("unix", (*server)[7:])
|
logger.Println("Connecting to UNIX socket", endpoint[7:])
|
||||||
|
conn, err = net.Dial("unix", endpoint[7:])
|
||||||
case "tcp":
|
case "tcp":
|
||||||
|
logger.Println("Connecting to TCP socket", u.Host)
|
||||||
conn, err = net.Dial("tcp", u.Host)
|
conn, err = net.Dial("tcp", u.Host)
|
||||||
default:
|
default:
|
||||||
|
logger.Println("Unknown protocol or malformed address - check your endpoint")
|
||||||
err = errors.New("protocol not supported")
|
err = errors.New("protocol not supported")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
conn, err = net.Dial("tcp", *server)
|
logger.Println("Connecting to TCP socket", u.Host)
|
||||||
|
conn, err = net.Dial("tcp", endpoint)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
logger.Println("Connected")
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
decoder := json.NewDecoder(conn)
|
decoder := json.NewDecoder(conn)
|
||||||
@ -57,11 +121,13 @@ func main() {
|
|||||||
|
|
||||||
for c, a := range args {
|
for c, a := range args {
|
||||||
if c == 0 {
|
if c == 0 {
|
||||||
|
logger.Printf("Sending request: %v\n", a)
|
||||||
send["request"] = a
|
send["request"] = a
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
tokens := strings.Split(a, "=")
|
tokens := strings.Split(a, "=")
|
||||||
if i, err := strconv.Atoi(tokens[1]); err == nil {
|
if i, err := strconv.Atoi(tokens[1]); err == nil {
|
||||||
|
logger.Printf("Sending parameter %s: %d\n", tokens[0], i)
|
||||||
send[tokens[0]] = i
|
send[tokens[0]] = i
|
||||||
} else {
|
} else {
|
||||||
switch strings.ToLower(tokens[1]) {
|
switch strings.ToLower(tokens[1]) {
|
||||||
@ -72,28 +138,31 @@ func main() {
|
|||||||
default:
|
default:
|
||||||
send[tokens[0]] = tokens[1]
|
send[tokens[0]] = tokens[1]
|
||||||
}
|
}
|
||||||
|
logger.Printf("Sending parameter %s: %v\n", tokens[0], send[tokens[0]])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := encoder.Encode(&send); err != nil {
|
if err := encoder.Encode(&send); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
logger.Printf("Request sent")
|
||||||
if err := decoder.Decode(&recv); err == nil {
|
if err := decoder.Decode(&recv); err == nil {
|
||||||
|
logger.Printf("Response received")
|
||||||
if recv["status"] == "error" {
|
if recv["status"] == "error" {
|
||||||
if err, ok := recv["error"]; ok {
|
if err, ok := recv["error"]; ok {
|
||||||
fmt.Println("Error:", err)
|
fmt.Println("Admin socket returned an error:", err)
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("Unspecified error occured")
|
fmt.Println("Admin socket returned an error but didn't specify any error text")
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if _, ok := recv["request"]; !ok {
|
if _, ok := recv["request"]; !ok {
|
||||||
fmt.Println("Missing request in response (malformed response?)")
|
fmt.Println("Missing request in response (malformed response?)")
|
||||||
return
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if _, ok := recv["response"]; !ok {
|
if _, ok := recv["response"]; !ok {
|
||||||
fmt.Println("Missing response body (malformed response?)")
|
fmt.Println("Missing response body (malformed response?)")
|
||||||
return
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
req := recv["request"].(map[string]interface{})
|
req := recv["request"].(map[string]interface{})
|
||||||
res := recv["response"].(map[string]interface{})
|
res := recv["response"].(map[string]interface{})
|
||||||
@ -181,6 +250,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
case "getself":
|
case "getself":
|
||||||
for k, v := range res["self"].(map[string]interface{}) {
|
for k, v := range res["self"].(map[string]interface{}) {
|
||||||
|
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 && buildversion != "unknown" {
|
||||||
|
fmt.Println("Build version:", buildversion)
|
||||||
|
}
|
||||||
fmt.Println("IPv6 address:", k)
|
fmt.Println("IPv6 address:", k)
|
||||||
if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok {
|
if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok {
|
||||||
fmt.Println("IPv6 subnet:", subnet)
|
fmt.Println("IPv6 subnet:", subnet)
|
||||||
@ -227,7 +302,7 @@ func main() {
|
|||||||
queuesize := v.(map[string]interface{})["queue_size"].(float64)
|
queuesize := v.(map[string]interface{})["queue_size"].(float64)
|
||||||
queuepackets := v.(map[string]interface{})["queue_packets"].(float64)
|
queuepackets := v.(map[string]interface{})["queue_packets"].(float64)
|
||||||
queueid := v.(map[string]interface{})["queue_id"].(string)
|
queueid := v.(map[string]interface{})["queue_id"].(string)
|
||||||
portqueues[queueport] += 1
|
portqueues[queueport]++
|
||||||
portqueuesize[queueport] += queuesize
|
portqueuesize[queueport] += queuesize
|
||||||
portqueuepackets[queueport] += queuepackets
|
portqueuepackets[queueport] += queuepackets
|
||||||
queuesizepercent := (100 / maximumqueuesize) * queuesize
|
queuesizepercent := (100 / maximumqueuesize) * queuesize
|
||||||
@ -315,9 +390,11 @@ func main() {
|
|||||||
fmt.Println(string(json))
|
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(1)
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
@ -17,7 +17,7 @@ import (
|
|||||||
"github.com/neilalexander/hjson-go"
|
"github.com/neilalexander/hjson-go"
|
||||||
"golang.org/x/text/encoding/unicode"
|
"golang.org/x/text/encoding/unicode"
|
||||||
|
|
||||||
"yggdrasil/config"
|
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nodeConfig = config.NodeConfig
|
type nodeConfig = config.NodeConfig
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
if [ `pwd` != `git rev-parse --show-toplevel` ]
|
||||||
then
|
then
|
||||||
echo "You should run this script from the top-level directory of the git repo"
|
echo "You should run this script from the top-level directory of the git repo"
|
||||||
exit -1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
PKGBRANCH=$(basename `git name-rev --name-only HEAD`)
|
||||||
PKGNAME=$(sh contrib/semver/name.sh)
|
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}
|
PKGARCH=${PKGARCH-amd64}
|
||||||
PKGFILE=$PKGNAME-$PKGVERSION-$PKGARCH.deb
|
PKGFILE=$PKGNAME-$PKGVERSION-$PKGARCH.deb
|
||||||
PKGREPLACES=yggdrasil
|
PKGREPLACES=yggdrasil
|
||||||
@ -29,7 +29,7 @@ elif [ $PKGARCH = "armhf" ]; then GOARCH=arm GOOS=linux GOARM=7 ./build
|
|||||||
elif [ $PKGARCH = "arm64" ]; then GOARCH=arm64 GOOS=linux ./build
|
elif [ $PKGARCH = "arm64" ]; then GOARCH=arm64 GOOS=linux ./build
|
||||||
else
|
else
|
||||||
echo "Specify PKGARCH=amd64,i386,mips,mipsel,armhf,arm64"
|
echo "Specify PKGARCH=amd64,i386,mips,mipsel,armhf,arm64"
|
||||||
exit -1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Building $PKGFILE"
|
echo "Building $PKGFILE"
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
FROM golang:stretch
|
FROM docker.io/golang:alpine as builder
|
||||||
MAINTAINER Christer Waren/CWINFO "christer.waren@cwinfo.org"
|
|
||||||
|
|
||||||
RUN apt-get update \
|
|
||||||
&& apt-get upgrade -y
|
|
||||||
|
|
||||||
ADD . /src
|
|
||||||
|
|
||||||
|
COPY . /src
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
RUN apk add git && ./build
|
||||||
|
|
||||||
RUN adduser --system --home /etc/yggdrasil-network --uid 1000 yggdrasil-network \
|
FROM docker.io/alpine
|
||||||
&& rm -rf build_* && ./build \
|
LABEL maintainer="Christer Waren/CWINFO <christer.waren@cwinfo.org>"
|
||||||
&& cp yggdrasil /usr/bin \
|
|
||||||
&& cp contrib/docker/entrypoint.sh /
|
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" ]
|
VOLUME [ "/etc/yggdrasil-network" ]
|
||||||
|
|
||||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
ENTRYPOINT [ "/usr/bin/entrypoint.sh" ]
|
||||||
|
2
contrib/docker/entrypoint.sh
Normal file → Executable file
2
contrib/docker/entrypoint.sh
Normal file → Executable file
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ chmod +x pkgbuild/root/usr/local/bin/yggdrasilctl
|
|||||||
|
|
||||||
# Work out metadata for the package info
|
# Work out metadata for the package info
|
||||||
PKGNAME=$(sh contrib/semver/name.sh)
|
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}
|
PKGARCH=${PKGARCH-amd64}
|
||||||
PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 ))
|
PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 ))
|
||||||
|
|
||||||
|
47
contrib/rpm/yggdrasil.spec
Normal file
47
contrib/rpm/yggdrasil.spec
Normal file
@ -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
|
@ -1,7 +1,16 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Get the branch name, removing any "/" characters from pull requests
|
# Get the current branch name
|
||||||
BRANCH=$(git symbolic-ref --short HEAD | tr -d "/" 2>/dev/null)
|
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
|
# Check if the branch name is not master
|
||||||
if [ "$BRANCH" = "master" ]; then
|
if [ "$BRANCH" = "master" ]; then
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
DEVELOPBRANCH="yggdrasil-network/develop"
|
DEVELOPBRANCH="yggdrasil-network/develop"
|
||||||
|
|
||||||
# Get the last tag
|
# 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
|
# Get last merge to master
|
||||||
MERGE=$(git rev-list $TAG..master --grep "from $DEVELOPBRANCH" 2>/dev/null | head -n 1)
|
MERGE=$(git rev-list $TAG..master --grep "from $DEVELOPBRANCH" 2>/dev/null | head -n 1)
|
||||||
@ -12,12 +12,25 @@ MERGE=$(git rev-list $TAG..master --grep "from $DEVELOPBRANCH" 2>/dev/null | hea
|
|||||||
# Get the number of merges since the last merge to master
|
# 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)
|
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 it fails then there's no last tag - go from the first commit
|
||||||
if [ $? != 0 ]; then
|
if [ $? != 0 ]; then
|
||||||
PATCH=$(git rev-list HEAD --count 2>/dev/null)
|
PATCH=$(git rev-list HEAD --count 2>/dev/null)
|
||||||
|
|
||||||
printf 'v0.0.%d' "$PATCH"
|
# Complain if the git history is not available
|
||||||
exit -1
|
if [ $? != 0 ]; then
|
||||||
|
printf 'unknown'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s0.0.%d' "$PREPEND" "$PATCH"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get the number of merges on the current branch since the last tag
|
# Get the number of merges on the current branch since the last tag
|
||||||
@ -32,9 +45,13 @@ BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|||||||
|
|
||||||
# Output in the desired format
|
# Output in the desired format
|
||||||
if [ $PATCH = 0 ]; then
|
if [ $PATCH = 0 ]; then
|
||||||
printf 'v%d.%d' "$MAJOR" "$MINOR"
|
if [ ! -z $FULL ]; then
|
||||||
|
printf '%s%d.%d.0' "$PREPEND" "$MAJOR" "$MINOR"
|
||||||
|
else
|
||||||
|
printf '%s%d.%d' "$PREPEND" "$MAJOR" "$MINOR"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
printf 'v%d.%d.%d' "$MAJOR" "$MINOR" "$PATCH"
|
printf '%s%d.%d.%d' "$PREPEND" "$MAJOR" "$MINOR" "$PATCH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add the build tag on non-master branches
|
# Add the build tag on non-master branches
|
||||||
@ -43,4 +60,3 @@ if [ $BRANCH != "master" ]; then
|
|||||||
printf -- "-%04d" "$BUILD"
|
printf -- "-%04d" "$BUILD"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
14
go.mod
Normal file
14
go.mod
Normal file
@ -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 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
|
||||||
|
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
|
||||||
|
)
|
20
go.sum
Normal file
20
go.sum
Normal file
@ -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 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=
|
||||||
|
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=
|
@ -16,7 +16,7 @@ import "encoding/hex"
|
|||||||
import "flag"
|
import "flag"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "runtime"
|
import "runtime"
|
||||||
import . "yggdrasil"
|
import . "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
||||||
|
|
||||||
var doSig = flag.Bool("sig", false, "generate new signing keys instead")
|
var doSig = flag.Bool("sig", false, "generate new signing keys instead")
|
||||||
|
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
export GOPATH=$PWD
|
|
||||||
go get -d yggdrasil
|
|
||||||
go run -tags debug misc/sim/treesim.go "$@"
|
go run -tags debug misc/sim/treesim.go "$@"
|
||||||
|
@ -12,7 +12,7 @@ import "runtime"
|
|||||||
import "runtime/pprof"
|
import "runtime/pprof"
|
||||||
import "flag"
|
import "flag"
|
||||||
|
|
||||||
import . "yggdrasil"
|
import . "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package config
|
|||||||
// NodeConfig defines all configuration values needed to run a signle yggdrasil node
|
// NodeConfig defines all configuration values needed to run a signle yggdrasil node
|
||||||
type NodeConfig struct {
|
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."`
|
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."`
|
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."`
|
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."`
|
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."`
|
@ -7,6 +7,9 @@ type platformDefaultParameters struct {
|
|||||||
// Admin socket
|
// Admin socket
|
||||||
DefaultAdminListen string
|
DefaultAdminListen string
|
||||||
|
|
||||||
|
// Configuration (used for yggdrasilctl)
|
||||||
|
DefaultConfigFile string
|
||||||
|
|
||||||
// TUN/TAP
|
// TUN/TAP
|
||||||
MaximumIfMTU int
|
MaximumIfMTU int
|
||||||
DefaultIfMTU int
|
DefaultIfMTU int
|
@ -7,7 +7,10 @@ package defaults
|
|||||||
func GetDefaults() platformDefaultParameters {
|
func GetDefaults() platformDefaultParameters {
|
||||||
return platformDefaultParameters{
|
return platformDefaultParameters{
|
||||||
// Admin
|
// Admin
|
||||||
DefaultAdminListen: "tcp://localhost:9001",
|
DefaultAdminListen: "unix:///var/run/yggdrasil.sock",
|
||||||
|
|
||||||
|
// Configuration (used for yggdrasilctl)
|
||||||
|
DefaultConfigFile: "/etc/yggdrasil.conf",
|
||||||
|
|
||||||
// TUN/TAP
|
// TUN/TAP
|
||||||
MaximumIfMTU: 65535,
|
MaximumIfMTU: 65535,
|
@ -7,7 +7,10 @@ package defaults
|
|||||||
func GetDefaults() platformDefaultParameters {
|
func GetDefaults() platformDefaultParameters {
|
||||||
return platformDefaultParameters{
|
return platformDefaultParameters{
|
||||||
// Admin
|
// Admin
|
||||||
DefaultAdminListen: "tcp://localhost:9001",
|
DefaultAdminListen: "unix:///var/run/yggdrasil.sock",
|
||||||
|
|
||||||
|
// Configuration (used for yggdrasilctl)
|
||||||
|
DefaultConfigFile: "/etc/yggdrasil.conf",
|
||||||
|
|
||||||
// TUN/TAP
|
// TUN/TAP
|
||||||
MaximumIfMTU: 32767,
|
MaximumIfMTU: 32767,
|
@ -7,7 +7,10 @@ package defaults
|
|||||||
func GetDefaults() platformDefaultParameters {
|
func GetDefaults() platformDefaultParameters {
|
||||||
return platformDefaultParameters{
|
return platformDefaultParameters{
|
||||||
// Admin
|
// Admin
|
||||||
DefaultAdminListen: "tcp://localhost:9001",
|
DefaultAdminListen: "unix:///var/run/yggdrasil.sock",
|
||||||
|
|
||||||
|
// Configuration (used for yggdrasilctl)
|
||||||
|
DefaultConfigFile: "/etc/yggdrasil.conf",
|
||||||
|
|
||||||
// TUN/TAP
|
// TUN/TAP
|
||||||
MaximumIfMTU: 65535,
|
MaximumIfMTU: 65535,
|
@ -7,7 +7,10 @@ package defaults
|
|||||||
func GetDefaults() platformDefaultParameters {
|
func GetDefaults() platformDefaultParameters {
|
||||||
return platformDefaultParameters{
|
return platformDefaultParameters{
|
||||||
// Admin
|
// Admin
|
||||||
DefaultAdminListen: "tcp://localhost:9001",
|
DefaultAdminListen: "unix:///var/run/yggdrasil.sock",
|
||||||
|
|
||||||
|
// Configuration (used for yggdrasilctl)
|
||||||
|
DefaultConfigFile: "/etc/yggdrasil.conf",
|
||||||
|
|
||||||
// TUN/TAP
|
// TUN/TAP
|
||||||
MaximumIfMTU: 9000,
|
MaximumIfMTU: 9000,
|
@ -7,7 +7,10 @@ package defaults
|
|||||||
func GetDefaults() platformDefaultParameters {
|
func GetDefaults() platformDefaultParameters {
|
||||||
return platformDefaultParameters{
|
return platformDefaultParameters{
|
||||||
// Admin
|
// Admin
|
||||||
DefaultAdminListen: "tcp://localhost:9001",
|
DefaultAdminListen: "unix:///var/run/yggdrasil.sock",
|
||||||
|
|
||||||
|
// Configuration (used for yggdrasilctl)
|
||||||
|
DefaultConfigFile: "/etc/yggdrasil.conf",
|
||||||
|
|
||||||
// TUN/TAP
|
// TUN/TAP
|
||||||
MaximumIfMTU: 16384,
|
MaximumIfMTU: 16384,
|
@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters {
|
|||||||
// Admin
|
// Admin
|
||||||
DefaultAdminListen: "tcp://localhost:9001",
|
DefaultAdminListen: "tcp://localhost:9001",
|
||||||
|
|
||||||
|
// Configuration (used for yggdrasilctl)
|
||||||
|
DefaultConfigFile: "/etc/yggdrasil.conf",
|
||||||
|
|
||||||
// TUN/TAP
|
// TUN/TAP
|
||||||
MaximumIfMTU: 65535,
|
MaximumIfMTU: 65535,
|
||||||
DefaultIfMTU: 65535,
|
DefaultIfMTU: 65535,
|
@ -9,6 +9,9 @@ func GetDefaults() platformDefaultParameters {
|
|||||||
// Admin
|
// Admin
|
||||||
DefaultAdminListen: "tcp://localhost:9001",
|
DefaultAdminListen: "tcp://localhost:9001",
|
||||||
|
|
||||||
|
// Configuration (used for yggdrasilctl)
|
||||||
|
DefaultConfigFile: "C:\\Program Files\\Yggdrasil\\yggdrasil.conf",
|
||||||
|
|
||||||
// TUN/TAP
|
// TUN/TAP
|
||||||
MaximumIfMTU: 65535,
|
MaximumIfMTU: 65535,
|
||||||
DefaultIfMTU: 65535,
|
DefaultIfMTU: 65535,
|
@ -14,7 +14,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"yggdrasil/defaults"
|
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Add authentication
|
// TODO: Add authentication
|
||||||
@ -268,11 +268,11 @@ func (a *admin) init(c *Core, listenaddr string) {
|
|||||||
return admin_info{"source_subnets": subnets}, nil
|
return admin_info{"source_subnets": subnets}, nil
|
||||||
})
|
})
|
||||||
a.addHandler("getRoutes", []string{}, func(in admin_info) (admin_info, error) {
|
a.addHandler("getRoutes", []string{}, func(in admin_info) (admin_info, error) {
|
||||||
var routes []string
|
routes := make(admin_info)
|
||||||
a.core.router.doAdmin(func() {
|
a.core.router.doAdmin(func() {
|
||||||
getRoutes := func(ckrs []cryptokey_route) {
|
getRoutes := func(ckrs []cryptokey_route) {
|
||||||
for _, ckr := range ckrs {
|
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)
|
getRoutes(a.core.router.cryptokey.ipv4routes)
|
||||||
@ -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.
|
// start runs the admin API socket to listen for / respond to admin API calls.
|
||||||
func (a *admin) start() error {
|
func (a *admin) start() error {
|
||||||
go a.listen()
|
if a.listenaddr != "none" && a.listenaddr != "" {
|
||||||
|
go a.listen()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +343,19 @@ func (a *admin) listen() {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
switch strings.ToLower(u.Scheme) {
|
switch strings.ToLower(u.Scheme) {
|
||||||
case "unix":
|
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:])
|
a.listener, err = net.Listen("unix", a.listenaddr[7:])
|
||||||
|
if err == nil {
|
||||||
|
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":
|
case "tcp":
|
||||||
a.listener, err = net.Listen("tcp", u.Host)
|
a.listener, err = net.Listen("tcp", u.Host)
|
||||||
default:
|
default:
|
||||||
@ -561,6 +575,13 @@ func (a *admin) getData_getSelf() *admin_nodeInfo {
|
|||||||
{"subnet", a.core.GetSubnet().String()},
|
{"subnet", a.core.GetSubnet().String()},
|
||||||
{"coords", fmt.Sprint(coords)},
|
{"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
|
return &self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,6 +758,10 @@ func (a *admin) admin_dhtPing(keyString, coordString, targetString string) (dhtR
|
|||||||
}
|
}
|
||||||
var coords []byte
|
var coords []byte
|
||||||
for _, cstr := range strings.Split(strings.Trim(coordString, "[]"), " ") {
|
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 {
|
if u64, err := strconv.ParseUint(cstr, 10, 8); err != nil {
|
||||||
return dhtRes{}, err
|
return dhtRes{}, err
|
||||||
} else {
|
} else {
|
||||||
|
@ -241,6 +241,16 @@ func (c *cryptokey) getPublicKeyForAddress(addr address, addrlen int) (boxPubKey
|
|||||||
for _, route := range *routingtable {
|
for _, route := range *routingtable {
|
||||||
// Does this subnet match the given IP?
|
// Does this subnet match the given IP?
|
||||||
if route.subnet.Contains(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
|
||||||
|
for k := range *routingcache {
|
||||||
|
if len(*routingcache) < 1024 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
delete(*routingcache, k)
|
||||||
|
}
|
||||||
|
|
||||||
// Cache the entry for future packets to get a faster lookup
|
// Cache the entry for future packets to get a faster lookup
|
||||||
(*routingcache)[addr] = route
|
(*routingcache)[addr] = route
|
||||||
|
|
||||||
|
@ -8,10 +8,13 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"yggdrasil/config"
|
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||||
"yggdrasil/defaults"
|
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var buildName string
|
||||||
|
var buildVersion string
|
||||||
|
|
||||||
// The Core object represents the Yggdrasil node. You should create a Core
|
// The Core object represents the Yggdrasil node. You should create a Core
|
||||||
// object for each Yggdrasil node you plan to run.
|
// object for each Yggdrasil node you plan to run.
|
||||||
type Core struct {
|
type Core struct {
|
||||||
@ -59,12 +62,38 @@ func (c *Core) init(bpub *boxPubKey,
|
|||||||
c.tun.init(c)
|
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
|
// Starts up Yggdrasil using the provided NodeConfig, and outputs debug logging
|
||||||
// through the provided log.Logger. The started stack will include TCP and UDP
|
// through the provided log.Logger. The started stack will include TCP and UDP
|
||||||
// sockets, a multicast discovery socket, an admin socket, router, switch and
|
// sockets, a multicast discovery socket, an admin socket, router, switch and
|
||||||
// DHT node.
|
// DHT node.
|
||||||
func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
|
func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error {
|
||||||
c.log = log
|
c.log = log
|
||||||
|
|
||||||
|
if name := GetBuildName(); name != "unknown" {
|
||||||
|
c.log.Println("Build name:", name)
|
||||||
|
}
|
||||||
|
if version := GetBuildVersion(); version != "unknown" {
|
||||||
|
c.log.Println("Build version:", version)
|
||||||
|
}
|
||||||
|
|
||||||
c.log.Println("Starting up...")
|
c.log.Println("Starting up...")
|
||||||
|
|
||||||
var boxPub boxPubKey
|
var boxPub boxPubKey
|
||||||
|
@ -22,7 +22,7 @@ import "net/http"
|
|||||||
import "runtime"
|
import "runtime"
|
||||||
import "os"
|
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.
|
// Start the profiler in debug builds, if the required environment variable is set.
|
||||||
func init() {
|
func init() {
|
||||||
@ -504,27 +504,43 @@ func (c *Core) DEBUG_addAllowedEncryptionPublicKey(boxStr string) {
|
|||||||
|
|
||||||
func DEBUG_simLinkPeers(p, q *peer) {
|
func DEBUG_simLinkPeers(p, q *peer) {
|
||||||
// Sets q.out() to point to p and starts p.linkLoop()
|
// Sets q.out() to point to p and starts p.linkLoop()
|
||||||
p.linkOut, q.linkOut = make(chan []byte, 1), make(chan []byte, 1)
|
goWorkers := func(source, dest *peer) {
|
||||||
go func() {
|
source.linkOut = make(chan []byte, 1)
|
||||||
for bs := range p.linkOut {
|
send := make(chan []byte, 1)
|
||||||
q.handlePacket(bs)
|
source.out = func(bs []byte) {
|
||||||
|
send <- bs
|
||||||
}
|
}
|
||||||
}()
|
go source.linkLoop()
|
||||||
go func() {
|
go func() {
|
||||||
for bs := range q.linkOut {
|
var packets [][]byte
|
||||||
p.handlePacket(bs)
|
for {
|
||||||
}
|
select {
|
||||||
}()
|
case packet := <-source.linkOut:
|
||||||
p.out = func(bs []byte) {
|
packets = append(packets, packet)
|
||||||
p.core.switchTable.idleIn <- p.port
|
continue
|
||||||
go q.handlePacket(bs)
|
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) {
|
goWorkers(p, q)
|
||||||
q.core.switchTable.idleIn <- q.port
|
goWorkers(q, p)
|
||||||
go p.handlePacket(bs)
|
|
||||||
}
|
|
||||||
go p.linkLoop()
|
|
||||||
go q.linkLoop()
|
|
||||||
p.core.switchTable.idleIn <- p.port
|
p.core.switchTable.idleIn <- p.port
|
||||||
q.core.switchTable.idleIn <- q.port
|
q.core.switchTable.idleIn <- q.port
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package yggdrasil
|
package yggdrasil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
@ -35,7 +36,10 @@ func (m *multicast) start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
listenString := fmt.Sprintf("[::]:%v", addr.Port)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
9
src/yggdrasil/multicast_other.go
Normal file
9
src/yggdrasil/multicast_other.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd,!windows
|
||||||
|
|
||||||
|
package yggdrasil
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func multicastReuse(network string, address string, c syscall.RawConn) error {
|
||||||
|
return nil
|
||||||
|
}
|
22
src/yggdrasil/multicast_unix.go
Normal file
22
src/yggdrasil/multicast_unix.go
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
22
src/yggdrasil/multicast_windows.go
Normal file
22
src/yggdrasil/multicast_windows.go
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -208,6 +208,7 @@ func (t *switchTable) doMaintenance() {
|
|||||||
defer t.mutex.Unlock() // Release lock when we're done
|
defer t.mutex.Unlock() // Release lock when we're done
|
||||||
t.cleanRoot()
|
t.cleanRoot()
|
||||||
t.cleanDropped()
|
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.
|
// 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 {
|
if port != t.parent {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
t.parent = 0
|
||||||
for _, info := range t.data.peers {
|
for _, info := range t.data.peers {
|
||||||
t.unlockedHandleMsg(&info.msg, info.port, true)
|
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.
|
// 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.
|
// 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.
|
// This function is called periodically to do that cleanup.
|
||||||
@ -377,6 +400,8 @@ func (t *switchTable) unlockedHandleMsg(msg *switchMsg, fromPort switchPort, rep
|
|||||||
doUpdate := false
|
doUpdate := false
|
||||||
oldSender := t.data.peers[fromPort]
|
oldSender := t.data.peers[fromPort]
|
||||||
if !equiv(&sender.locator, &oldSender.locator) {
|
if !equiv(&sender.locator, &oldSender.locator) {
|
||||||
|
// Reset faster info, we'll start refilling it right after this
|
||||||
|
sender.faster = nil
|
||||||
doUpdate = true
|
doUpdate = true
|
||||||
}
|
}
|
||||||
// Update the matrix of peer "faster" thresholds
|
// Update the matrix of peer "faster" thresholds
|
||||||
@ -387,25 +412,20 @@ func (t *switchTable) unlockedHandleMsg(msg *switchMsg, fromPort switchPort, rep
|
|||||||
for port, peer := range t.data.peers {
|
for port, peer := range t.data.peers {
|
||||||
if port == fromPort {
|
if port == fromPort {
|
||||||
continue
|
continue
|
||||||
}
|
} else if sender.locator.root != peer.locator.root || sender.locator.tstamp > peer.locator.tstamp {
|
||||||
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:
|
|
||||||
// We were faster than this node, so increment, as long as we don't overflow because of it
|
// 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 {
|
if oldSender.faster[peer.port] < switch_faster_threshold {
|
||||||
sender.faster[port] = oldSender.faster[peer.port] + 1
|
sender.faster[port] = oldSender.faster[peer.port] + 1
|
||||||
} else {
|
} else {
|
||||||
sender.faster[port] = switch_faster_threshold
|
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 +477,10 @@ func (t *switchTable) unlockedHandleMsg(msg *switchMsg, fromPort switchPort, rep
|
|||||||
// First, reset all faster-related info to 0.
|
// First, reset all faster-related info to 0.
|
||||||
// Then, de-parent the node and reprocess all messages to find a new parent.
|
// Then, de-parent the node and reprocess all messages to find a new parent.
|
||||||
t.parent = 0
|
t.parent = 0
|
||||||
sender.faster = nil
|
|
||||||
for _, peer := range t.data.peers {
|
for _, peer := range t.data.peers {
|
||||||
if peer.port == sender.port {
|
if peer.port == sender.port {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
delete(peer.faster, sender.port)
|
|
||||||
t.unlockedHandleMsg(&peer.msg, peer.port, true)
|
t.unlockedHandleMsg(&peer.msg, peer.port, true)
|
||||||
}
|
}
|
||||||
// Process the sender last, to avoid keeping them as a parent if at all possible.
|
// Process the sender last, to avoid keeping them as a parent if at all possible.
|
||||||
|
@ -6,10 +6,11 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
"yggdrasil/defaults"
|
|
||||||
|
|
||||||
"github.com/songgao/packets/ethernet"
|
"github.com/songgao/packets/ethernet"
|
||||||
"github.com/yggdrasil-network/water"
|
"github.com/yggdrasil-network/water"
|
||||||
|
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tun_IPv6_HEADER_LENGTH = 40
|
const tun_IPv6_HEADER_LENGTH = 40
|
||||||
|
Loading…
Reference in New Issue
Block a user