Skip to content

Commit

Permalink
Merge pull request #896 from yggdrasil-network/develop
Browse files Browse the repository at this point in the history
Version 0.4.3
  • Loading branch information
neilalexander authored Feb 6, 2022
2 parents e4e5883 + 31717a8 commit 559e31c
Show file tree
Hide file tree
Showing 20 changed files with 612 additions and 68 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
32 changes: 8 additions & 24 deletions build
Original file line number Diff line number Diff line change
Expand Up @@ -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";;
Expand All @@ -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
echo "Building: $CMD"
go build $ARGS -ldflags="$LDFLAGS" -gcflags="$GCFLAGS" ./cmd/$CMD
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
if [ $UPX ]; then
upx --brute $CMD
fi
done
3 changes: 2 additions & 1 deletion contrib/macos/create-pkg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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>
Expand Down
52 changes: 52 additions & 0 deletions contrib/mobile/build
Original file line number Diff line number Diff line change
@@ -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 changes: 178 additions & 0 deletions contrib/mobile/mobile.go
Original file line number Diff line number Diff line change
@@ -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()
}
12 changes: 12 additions & 0 deletions contrib/mobile/mobile_android.go
Original file line number Diff line number Diff line change
@@ -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
}
27 changes: 27 additions & 0 deletions contrib/mobile/mobile_ios.go
Original file line number Diff line number Diff line change
@@ -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
}
13 changes: 13 additions & 0 deletions contrib/mobile/mobile_other.go
Original file line number Diff line number Diff line change
@@ -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
}
16 changes: 16 additions & 0 deletions contrib/mobile/mobile_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
Loading

0 comments on commit 559e31c

Please sign in to comment.