5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-22 09:30:28 +00:00

Merge pull request #896 from yggdrasil-network/develop

Version 0.4.3
This commit is contained in:
Neil Alexander 2022-02-06 15:24:01 +00:00 committed by GitHub
commit 559e31c502
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 612 additions and 68 deletions

View File

@ -25,6 +25,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- in case of vulnerabilities.
-->
## [0.4.3] - 2022-02-06
### Added
- `bytes_sent`, `bytes_recvd` and `uptime` have been added to `getPeers`
- Clearer logging when connections are rejected due to incompatible peer versions
### Fixed
- Latency-based parent selection tiebreak is now reliable on platforms even with low timer resolution
- Tree distance calculation offsets have been corrected
## [0.4.2] - 2021-11-03
### Fixed
- Reverted a dependency update which resulted in problems building with Go 1.16 and running on Windows

View File

@ -9,8 +9,11 @@ environment:
CHERE_INVOKING: enabled_from_arguments
build_script:
- cmd: >-
cd %APPVEYOR_BUILD_FOLDER%
- cmd: cd %APPVEYOR_BUILD_FOLDER%
- curl -o C:\projects\golang.zip https://dl.google.com/go/go1.17.5.windows-amd64.zip
- 7z x C:\projects\golang.zip -oC:\projects\
- cmd: set PATH=C:\projects\go\bin;%PATH%
- cmd: set GOROOT=C:\projects\go
- c:\msys64\usr\bin\bash -lc "./contrib/msi/build-msi.sh x64"
- c:\msys64\usr\bin\bash -lc "./contrib/msi/build-msi.sh x86"

22
build
View File

@ -9,13 +9,11 @@ PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)}
LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER"
ARGS="-v"
while getopts "uaitc:l:dro:p" option
while getopts "utc:l:dro:p" option
do
case "$option"
in
u) UPX=true;;
i) IOS=true;;
a) ANDROID=true;;
t) TABLES=true;;
c) GCFLAGS="$GCFLAGS $OPTARG";;
l) LDFLAGS="$LDFLAGS $OPTARG";;
@ -30,25 +28,11 @@ if [ -z $TABLES ] && [ -z $DEBUG ]; then
LDFLAGS="$LDFLAGS -s -w"
fi
if [ $IOS ]; then
echo "Building framework for iOS"
go get golang.org/x/mobile/bind
gomobile bind -target ios -tags mobile -o Yggdrasil.framework -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
github.com/yggdrasil-network/yggdrasil-extras/src/mobile \
github.com/yggdrasil-network/yggdrasil-go/src/config
elif [ $ANDROID ]; then
echo "Building aar for Android"
go get golang.org/x/mobile/bind
gomobile bind -target android -tags mobile -o yggdrasil.aar -ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
github.com/yggdrasil-network/yggdrasil-extras/src/mobile \
github.com/yggdrasil-network/yggdrasil-go/src/config
else
for CMD in yggdrasil yggdrasilctl ; do
for CMD in yggdrasil yggdrasilctl ; do
echo "Building: $CMD"
go build $ARGS -ldflags="$LDFLAGS" -gcflags="$GCFLAGS" ./cmd/$CMD
if [ $UPX ]; then
upx --brute $CMD
fi
done
fi
done

View File

@ -79,6 +79,7 @@ PKGNAME=$(sh contrib/semver/name.sh)
PKGVERSION=$(sh contrib/semver/version.sh --bare)
PKGARCH=${PKGARCH-amd64}
PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 ))
[ "$PKGARCH" = "amd64" ] && PKGHOSTARCH="x86_64" || PKGHOSTARCH=${PKGARCH}
# Create the PackageInfo file
cat > pkgbuild/flat/base.pkg/PackageInfo << EOF
@ -98,7 +99,7 @@ cat > pkgbuild/flat/Distribution << EOF
<?xml version="1.0" encoding="utf-8"?>
<installer-script minSpecVersion="1.000000" authoringTool="com.apple.PackageMaker" authoringToolVersion="3.0.3" authoringToolBuild="174">
<title>Yggdrasil (${PKGNAME}-${PKGVERSION})</title>
<options customize="never" allow-external-scripts="no"/>
<options customize="never" allow-external-scripts="no" hostArchitectures="${PKGHOSTARCH}" />
<domains enable_anywhere="true"/>
<installation-check script="pm_install_check();"/>
<script>

52
contrib/mobile/build Executable file
View File

@ -0,0 +1,52 @@
#!/bin/sh
set -ef
[ ! -d contrib/mobile ] && (echo "Must run ./contrib/mobile/build [-i] [-a] from the repository top level folder"; exit 1)
PKGSRC=${PKGSRC:-github.com/yggdrasil-network/yggdrasil-go/src/version}
PKGNAME=${PKGNAME:-$(sh contrib/semver/name.sh)}
PKGVER=${PKGVER:-$(sh contrib/semver/version.sh --bare)}
LDFLAGS="-X $PKGSRC.buildName=$PKGNAME -X $PKGSRC.buildVersion=$PKGVER"
ARGS="-v"
while getopts "aitc:l:d" option
do
case "$option"
in
i) IOS=true;;
a) ANDROID=true;;
t) TABLES=true;;
c) GCFLAGS="$GCFLAGS $OPTARG";;
l) LDFLAGS="$LDFLAGS $OPTARG";;
d) ARGS="$ARGS -tags debug" DEBUG=true;;
esac
done
if [ -z $TABLES ] && [ -z $DEBUG ]; then
LDFLAGS="$LDFLAGS -s -w"
fi
if [ ! $IOS ] && [ ! $ANDROID ]; then
echo "Must specify -a (Android), -i (iOS) or both"
exit 1
fi
if [ $IOS ]; then
echo "Building framework for iOS"
go get golang.org/x/mobile/bind
gomobile bind \
-target ios -tags mobile -o Yggdrasil.xcframework \
-ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
./contrib/mobile ./src/config;
fi
if [ $ANDROID ]; then
echo "Building aar for Android"
go get golang.org/x/mobile/bind
gomobile bind \
-target android -tags mobile -o yggdrasil.aar \
-ldflags="$LDFLAGS $STRIP" -gcflags="$GCFLAGS" \
./contrib/mobile ./src/config;
fi

178
contrib/mobile/mobile.go Normal file
View File

@ -0,0 +1,178 @@
package mobile
import (
"encoding/hex"
"encoding/json"
"fmt"
"net"
"github.com/gologme/log"
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/config"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
"github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc"
"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
"github.com/yggdrasil-network/yggdrasil-go/src/version"
_ "golang.org/x/mobile/bind"
)
// Yggdrasil mobile package is meant to "plug the gap" for mobile support, as
// Gomobile will not create headers for Swift/Obj-C etc if they have complex
// (non-native) types. Therefore for iOS we will expose some nice simple
// functions. Note that in the case of iOS we handle reading/writing to/from TUN
// in Swift therefore we use the "dummy" TUN interface instead.
type Yggdrasil struct {
core core.Core
iprwc *ipv6rwc.ReadWriteCloser
config *config.NodeConfig
multicast multicast.Multicast
log MobileLogger
}
// StartAutoconfigure starts a node with a randomly generated config
func (m *Yggdrasil) StartAutoconfigure() error {
return m.StartJSON([]byte("{}"))
}
// StartJSON starts a node with the given JSON config. You can get JSON config
// (rather than HJSON) by using the GenerateConfigJSON() function
func (m *Yggdrasil) StartJSON(configjson []byte) error {
logger := log.New(m.log, "", 0)
logger.EnableLevel("error")
logger.EnableLevel("warn")
logger.EnableLevel("info")
m.config = defaults.GenerateConfig()
if err := json.Unmarshal(configjson, &m.config); err != nil {
return err
}
m.config.IfName = "none"
if err := m.core.Start(m.config, logger); err != nil {
logger.Errorln("An error occured starting Yggdrasil:", err)
return err
}
mtu := m.config.IfMTU
m.iprwc = ipv6rwc.NewReadWriteCloser(&m.core)
if m.iprwc.MaxMTU() < mtu {
mtu = m.iprwc.MaxMTU()
}
m.iprwc.SetMTU(mtu)
if len(m.config.MulticastInterfaces) > 0 {
if err := m.multicast.Init(&m.core, m.config, logger, nil); err != nil {
logger.Errorln("An error occurred initialising multicast:", err)
return err
}
if err := m.multicast.Start(); err != nil {
logger.Errorln("An error occurred starting multicast:", err)
return err
}
}
return nil
}
// Send sends a packet to Yggdrasil. It should be a fully formed
// IPv6 packet
func (m *Yggdrasil) Send(p []byte) error {
if m.iprwc == nil {
return nil
}
_, _ = m.iprwc.Write(p)
return nil
}
// Recv waits for and reads a packet coming from Yggdrasil. It
// will be a fully formed IPv6 packet
func (m *Yggdrasil) Recv() ([]byte, error) {
if m.iprwc == nil {
return nil, nil
}
var buf [65535]byte
n, _ := m.iprwc.Read(buf[:])
return buf[:n], nil
}
// Stop the mobile Yggdrasil instance
func (m *Yggdrasil) Stop() error {
logger := log.New(m.log, "", 0)
logger.EnableLevel("info")
logger.Infof("Stop the mobile Yggdrasil instance %s", "")
if err := m.multicast.Stop(); err != nil {
return err
}
m.core.Stop()
return nil
}
// GenerateConfigJSON generates mobile-friendly configuration in JSON format
func GenerateConfigJSON() []byte {
nc := defaults.GenerateConfig()
nc.IfName = "none"
if json, err := json.Marshal(nc); err == nil {
return json
}
return nil
}
// GetAddressString gets the node's IPv6 address
func (m *Yggdrasil) GetAddressString() string {
ip := m.core.Address()
return ip.String()
}
// GetSubnetString gets the node's IPv6 subnet in CIDR notation
func (m *Yggdrasil) GetSubnetString() string {
subnet := m.core.Subnet()
return subnet.String()
}
// GetPublicKeyString gets the node's public key in hex form
func (m *Yggdrasil) GetPublicKeyString() string {
return hex.EncodeToString(m.core.GetSelf().Key)
}
// GetCoordsString gets the node's coordinates
func (m *Yggdrasil) GetCoordsString() string {
return fmt.Sprintf("%v", m.core.GetSelf().Coords)
}
func (m *Yggdrasil) GetPeersJSON() (result string) {
peers := []struct {
core.Peer
IP string
}{}
for _, v := range m.core.GetPeers() {
a := address.AddrForKey(v.Key)
ip := net.IP(a[:]).String()
peers = append(peers, struct {
core.Peer
IP string
}{
Peer: v,
IP: ip,
})
}
if res, err := json.Marshal(peers); err == nil {
return string(res)
} else {
return "{}"
}
}
func (m *Yggdrasil) GetDHTJSON() (result string) {
if res, err := json.Marshal(m.core.GetDHT()); err == nil {
return string(res)
} else {
return "{}"
}
}
// GetMTU returns the configured node MTU. This must be called AFTER Start.
func (m *Yggdrasil) GetMTU() int {
return int(m.core.MTU())
}
func GetVersion() string {
return version.BuildVersion()
}

View File

@ -0,0 +1,12 @@
// +build android
package mobile
import "log"
type MobileLogger struct{}
func (nsl MobileLogger) Write(p []byte) (n int, err error) {
log.Println(string(p))
return len(p), nil
}

View File

@ -0,0 +1,27 @@
// +build ios
package mobile
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation
#import <Foundation/Foundation.h>
void Log(const char *text) {
NSString *nss = [NSString stringWithUTF8String:text];
NSLog(@"%@", nss);
}
*/
import "C"
import (
"unsafe"
)
type MobileLogger struct {
}
func (nsl MobileLogger) Write(p []byte) (n int, err error) {
p = append(p, 0)
cstr := (*C.char)(unsafe.Pointer(&p[0]))
C.Log(cstr)
return len(p), nil
}

View File

@ -0,0 +1,13 @@
// +build !android,!ios
package mobile
import "fmt"
type MobileLogger struct {
}
func (nsl MobileLogger) Write(p []byte) (n int, err error) {
fmt.Print(string(p))
return len(p), nil
}

View File

@ -0,0 +1,16 @@
package mobile
import "testing"
func TestStartYggdrasil(t *testing.T) {
ygg := &Yggdrasil{}
if err := ygg.StartAutoconfigure(); err != nil {
t.Fatalf("Failed to start Yggdrasil: %s", err)
}
t.Log("Address:", ygg.GetAddressString())
t.Log("Subnet:", ygg.GetSubnetString())
t.Log("Coords:", ygg.GetCoordsString())
if err := ygg.Stop(); err != nil {
t.Fatalf("Failed to stop Yggdrasil: %s", err)
}
}

View File

@ -21,7 +21,7 @@ fi
if [ "${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}" != "" ];
then
git fetch --all
git checkout ${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}
# git checkout ${APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH}
elif [ "${APPVEYOR_REPO_BRANCH}" != "" ];
then
git fetch --all
@ -76,7 +76,7 @@ PKGVERSIONMS=$(echo $PKGVERSION | tr - .)
# Download the Wintun driver
if [ ! -d wintun ];
then
curl -o wintun.zip https://www.wintun.net/builds/wintun-0.11.zip
curl -o wintun.zip https://www.wintun.net/builds/wintun-0.14.1.zip
unzip wintun.zip
fi
if [ $PKGARCH = "x64" ]; then

View File

@ -3,8 +3,11 @@
# Get the current branch name
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
if [ -n "$APPVEYOR_PULL_REQUEST_NUMBER" ]; then
printf "yggdrasil-pr%s" "$APPVEYOR_PULL_REQUEST_NUMBER"
exit 0
# Complain if the git history is not available
if [ $? != 0 ] || [ -z "$BRANCH" ]; then
elif [ $? != 0 ] || [ -z "$BRANCH" ]; then
printf "yggdrasil"
exit 0
fi

View File

@ -10,7 +10,7 @@ Group=yggdrasil
ProtectHome=true
ProtectSystem=true
SyslogIdentifier=yggdrasil
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
ExecStartPre=+-/sbin/modprobe tun
ExecStart=/usr/bin/yggdrasil -useconffile /etc/yggdrasil.conf
ExecReload=/bin/kill -HUP $MAINPID

14
go.mod
View File

@ -3,7 +3,7 @@ module github.com/yggdrasil-network/yggdrasil-go
go 1.16
require (
github.com/Arceliar/ironwood v0.0.0-20210619124114-6ad55cae5031
github.com/Arceliar/ironwood v0.0.0-20211125050254-8951369625d0
github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/cheggaaa/pb/v3 v3.0.8
@ -17,10 +17,10 @@ require (
github.com/mitchellh/mapstructure v1.4.1
github.com/vishvananda/netlink v1.1.0
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273
golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2
golang.zx2c4.com/wireguard/windows v0.3.14
golang.org/x/mobile v0.0.0-20220112015953-858099ff7816
golang.org/x/net v0.0.0-20211101193420-4a448f8816b3
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b
golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a
golang.zx2c4.com/wireguard/windows v0.4.12
)

71
go.sum
View File

@ -1,7 +1,8 @@
github.com/Arceliar/ironwood v0.0.0-20210619124114-6ad55cae5031 h1:DZVDfYhVdu+0wAiRHoY1olyNkKxIot9UjBnbQFzuUlM=
github.com/Arceliar/ironwood v0.0.0-20210619124114-6ad55cae5031/go.mod h1:RP72rucOFm5udrnEzTmIWLRVGQiV/fSUAQXJ0RST/nk=
github.com/Arceliar/ironwood v0.0.0-20211125050254-8951369625d0 h1:QUqcb7BOcBU2p7Nax7pESOb8hrZYtI0Ts6j4v4mvcQo=
github.com/Arceliar/ironwood v0.0.0-20211125050254-8951369625d0/go.mod h1:RP72rucOFm5udrnEzTmIWLRVGQiV/fSUAQXJ0RST/nk=
github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979 h1:WndgpSW13S32VLQ3ugUxx2EnnWmgba1kCqPkd4Gk1yQ=
github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
@ -38,42 +39,68 @@ github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYp
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA=
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20220112015953-858099ff7816 h1:jhDgkcu3yQ4tasBZ+1YwDmK7eFmuVf1w1k+NGGGxfmE=
golang.org/x/mobile v0.0.0-20220112015953-858099ff7816/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b h1:k+E048sYJHyVnsr1GDrRZWQ32D2C7lWs9JRc0bel53A=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210927181540-4e4d966f7476/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 h1:VrJZAjbekhoRn7n5FBujY31gboH+iB3pdLxn3gE9FjU=
golang.org/x/net v0.0.0-20211101193420-4a448f8816b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 h1:faDu4veV+8pcThn4fewv6TVlNCezafGoC1gM/mxQLbQ=
golang.org/x/sys v0.0.0-20210611083646-a4fc73990273/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc=
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f h1:yQJrRE0hDxDFmZLlRaw+3vusO4fwNHgHIjUOMO7bHYI=
golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b h1:NXqSWXSRUSCaFuvitrWtU169I3876zRTalMRbfd6LL0=
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.zx2c4.com/wireguard v0.0.0-20210510202332-9844c74f67ec/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 h1:wfOOSvHgIzTZ9h5Vb6yUFZNn7uf3bT7PeYsHOO7tYDM=
golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8=
golang.zx2c4.com/wireguard/windows v0.3.14 h1:5yIDYyrQyGkLqV+tzY4ilMNeIvQeMXAz0glZz9u179A=
golang.zx2c4.com/wireguard/windows v0.3.14/go.mod h1:3P4IEAsb+BjlKZmpUXgy74c0iX9AVwwr3WcVJ8nPgME=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 h1:YuekqPskqwCCPM79F1X5Dhv4ezTCj+Ki1oNwiafxkA0=
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wireguard v0.0.0-20211012062646-82d2aa87aa62/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU=
golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a h1:tTbyylK9/D3u/wEP26Vx7L700UpY48nhioJWZM1vhZw=
golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU=
golang.zx2c4.com/wireguard/windows v0.4.12 h1:CUmbdWKVNzTSsVb4yUAiEwL3KsabdJkEPdDjCHxBlhA=
golang.zx2c4.com/wireguard/windows v0.4.12/go.mod h1:PW4y+d9oY83XU9rRwRwrJDwEMuhVjMxu2gfD1cfzS7w=

114
src/address/address_test.go Normal file
View File

@ -0,0 +1,114 @@
package address
import (
"bytes"
"crypto/ed25519"
"math/rand"
"testing"
)
func TestAddress_Address_IsValid(t *testing.T) {
var address Address
rand.Read(address[:])
address[0] = 0
if address.IsValid() {
t.Fatal("invalid address marked as valid")
}
address[0] = 0x03
if address.IsValid() {
t.Fatal("invalid address marked as valid")
}
address[0] = 0x02
if !address.IsValid() {
t.Fatal("valid address marked as invalid")
}
}
func TestAddress_Subnet_IsValid(t *testing.T) {
var subnet Subnet
rand.Read(subnet[:])
subnet[0] = 0
if subnet.IsValid() {
t.Fatal("invalid subnet marked as valid")
}
subnet[0] = 0x02
if subnet.IsValid() {
t.Fatal("invalid subnet marked as valid")
}
subnet[0] = 0x03
if !subnet.IsValid() {
t.Fatal("valid subnet marked as invalid")
}
}
func TestAddress_AddrForKey(t *testing.T) {
publicKey := ed25519.PublicKey{
189, 186, 207, 216, 34, 64, 222, 61, 205, 18, 57, 36, 203, 181, 82, 86,
251, 141, 171, 8, 170, 152, 227, 5, 82, 138, 184, 79, 65, 158, 110, 251,
}
expectedAddress := Address{
2, 0, 132, 138, 96, 79, 187, 126, 67, 132, 101, 219, 141, 182, 104, 149,
}
if *AddrForKey(publicKey) != expectedAddress {
t.Fatal("invalid address returned")
}
}
func TestAddress_SubnetForKey(t *testing.T) {
publicKey := ed25519.PublicKey{
189, 186, 207, 216, 34, 64, 222, 61, 205, 18, 57, 36, 203, 181, 82, 86,
251, 141, 171, 8, 170, 152, 227, 5, 82, 138, 184, 79, 65, 158, 110, 251,
}
expectedSubnet := Subnet{3, 0, 132, 138, 96, 79, 187, 126}
if *SubnetForKey(publicKey) != expectedSubnet {
t.Fatal("invalid subnet returned")
}
}
func TestAddress_Address_GetKey(t *testing.T) {
address := Address{
2, 0, 132, 138, 96, 79, 187, 126, 67, 132, 101, 219, 141, 182, 104, 149,
}
expectedPublicKey := ed25519.PublicKey{
189, 186, 207, 216, 34, 64, 222, 61,
205, 18, 57, 36, 203, 181, 127, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
}
if !bytes.Equal(address.GetKey(), expectedPublicKey) {
t.Fatal("invalid public key returned")
}
}
func TestAddress_Subnet_GetKey(t *testing.T) {
subnet := Subnet{3, 0, 132, 138, 96, 79, 187, 126}
expectedPublicKey := ed25519.PublicKey{
189, 186, 207, 216, 34, 64, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
}
if !bytes.Equal(subnet.GetKey(), expectedPublicKey) {
t.Fatal("invalid public key returned")
}
}

View File

@ -19,6 +19,9 @@ type PeerEntry struct {
Port uint64 `json:"port"`
Coords []uint64 `json:"coords"`
Remote string `json:"remote"`
RXBytes uint64 `json:"bytes_recvd"`
TXBytes uint64 `json:"bytes_sent"`
Uptime float64 `json:"uptime"`
}
func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersResponse) error {
@ -31,6 +34,9 @@ func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersRespons
Port: p.Port,
Coords: p.Coords,
Remote: p.Remote,
RXBytes: p.RXBytes,
TXBytes: p.TXBytes,
Uptime: p.Uptime.Seconds(),
}
}
return nil

54
src/config/config_test.go Normal file
View File

@ -0,0 +1,54 @@
package config
import (
"bytes"
"encoding/hex"
"testing"
)
func TestConfig_Keys(t *testing.T) {
var nodeConfig NodeConfig
nodeConfig.NewKeys()
publicKey1, err := hex.DecodeString(nodeConfig.PublicKey)
if err != nil {
t.Fatal("can not decode generated public key")
}
if len(publicKey1) == 0 {
t.Fatal("empty public key generated")
}
privateKey1, err := hex.DecodeString(nodeConfig.PrivateKey)
if err != nil {
t.Fatal("can not decode generated private key")
}
if len(privateKey1) == 0 {
t.Fatal("empty private key generated")
}
nodeConfig.NewKeys()
publicKey2, err := hex.DecodeString(nodeConfig.PublicKey)
if err != nil {
t.Fatal("can not decode generated public key")
}
if bytes.Equal(publicKey2, publicKey1) {
t.Fatal("same public key generated")
}
privateKey2, err := hex.DecodeString(nodeConfig.PrivateKey)
if err != nil {
t.Fatal("can not decode generated private key")
}
if bytes.Equal(privateKey2, privateKey1) {
t.Fatal("same private key generated")
}
}

View File

@ -2,12 +2,16 @@ package core
import (
"crypto/ed25519"
"sync/atomic"
"time"
//"encoding/hex"
"encoding/json"
//"errors"
//"fmt"
"net"
"net/url"
//"sort"
//"time"
@ -29,6 +33,9 @@ type Peer struct {
Coords []uint64
Port uint64
Remote string
RXBytes uint64
TXBytes uint64
Uptime time.Duration
}
type DHTEntry struct {
@ -74,6 +81,11 @@ func (c *Core) GetPeers() []Peer {
if name := names[p.Conn]; name != "" {
info.Remote = name
}
if linkconn, ok := p.Conn.(*linkConn); ok {
info.RXBytes = atomic.LoadUint64(&linkconn.rx)
info.TXBytes = atomic.LoadUint64(&linkconn.tx)
info.Uptime = time.Since(linkconn.up)
}
peers = append(peers, info)
}
return peers

View File

@ -14,6 +14,8 @@ import (
//"sync/atomic"
"time"
"sync/atomic"
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/util"
"golang.org/x/net/proxy"
@ -40,7 +42,7 @@ type linkInfo struct {
type link struct {
lname string
links *links
conn net.Conn
conn *linkConn
options linkOptions
info linkInfo
incoming bool
@ -124,7 +126,10 @@ func (l *links) call(u *url.URL, sintf string) error {
func (l *links) create(conn net.Conn, name, linkType, local, remote string, incoming, force bool, options linkOptions) (*link, error) {
// Technically anything unique would work for names, but let's pick something human readable, just for debugging
intf := link{
conn: conn,
conn: &linkConn{
Conn: conn,
up: time.Now(),
},
lname: name,
links: l,
options: options,
@ -185,7 +190,14 @@ func (intf *link) handler() (chan struct{}, error) {
return nil, errors.New("failed to decode metadata")
}
if !meta.check() {
intf.links.core.log.Errorf("Failed to connect to node: %s is incompatible version (local %s, remote %s)",
var connectError string
if intf.incoming {
connectError = "Rejected incoming connection"
} else {
connectError = "Failed to connect"
}
intf.links.core.log.Debugf("%s: %s is incompatible version (local %s, remote %s)",
connectError,
intf.lname,
fmt.Sprintf("%d.%d", base.ver, base.minorVer),
fmt.Sprintf("%d.%d", meta.ver, meta.minorVer),
@ -265,3 +277,24 @@ func (intf *link) close() {
func (intf *link) name() string {
return intf.lname
}
type linkConn struct {
// tx and rx are at the beginning of the struct to ensure 64-bit alignment
// on 32-bit platforms, see https://pkg.go.dev/sync/atomic#pkg-note-BUG
rx uint64
tx uint64
up time.Time
net.Conn
}
func (c *linkConn) Read(p []byte) (n int, err error) {
n, err = c.Conn.Read(p)
atomic.AddUint64(&c.rx, uint64(n))
return
}
func (c *linkConn) Write(p []byte) (n int, err error) {
n, err = c.Conn.Write(p)
atomic.AddUint64(&c.tx, uint64(n))
return
}