yggdrasil-network / yggdrasil-extras Goto Github PK
View Code? Open in Web Editor NEWExtra packages to support Yggdrasil on mobile etc
Extra packages to support Yggdrasil on mobile etc
The future branch no longer builds with Go 1.16.4 - and gomobile requires this version since one of the latest commits.
Error we get when building on Go 1.16.4:
gomobile: go build -tags mobile -ldflags -X github.com/yggdrasil-network/yggdrasil-go/src/version.buildName=yggdrasil -X github.com/yggdrasil-network/yggdrasil-go/src/version.buildVersion=0.4.0 -s -w -buildmode=c-shared -o=/tmp/gomobile-work-160332129/android/src/main/jniLibs/armeabi-v7a/libgojni.so ./gobind failed: exit status 2
# github.com/yggdrasil-network/yggdrasil-extras/src/mobile
/go/src/github.com/yggdrasil-network/yggdrasil-extras/src/mobile/mobile.go:61:11: m.core.MaxMTU undefined (type core.Core has no field or method MaxMTU)
/go/src/github.com/yggdrasil-network/yggdrasil-extras/src/mobile/mobile.go:62:15: m.core.MaxMTU undefined (type core.Core has no field or method MaxMTU)
/go/src/github.com/yggdrasil-network/yggdrasil-extras/src/mobile/mobile.go:64:8: m.core.SetMTU undefined (type core.Core has no field or method SetMTU)
/go/src/github.com/yggdrasil-network/yggdrasil-extras/src/mobile/mobile.go:81:15: m.core.Write undefined (type core.Core has no field or method Write)
/go/src/github.com/yggdrasil-network/yggdrasil-extras/src/mobile/mobile.go:89:16: m.core.Read undefined (type core.Core has no field or method Read)
You can reproduce with our Dockerfile @ https://github.com/jdelrue/yggdrasil-mobile-docker/tree/go1.16
should be added to gitignore
Add unit test that could check whether extras code creates yggdrasil connection successfully in Android or iOS. There is no requirements to create java code but only run native calls in such test. This could help properly initialize the library in Android.
Unable to start YggdrasilTunService due to incorrect defaults in MulticastInterfaces.Port (required uint16 but returned Double).
Preconditions:
Build native lib for Android in Yggdrasil develop branch.
vadym@ubuntu:~/yggdrasil-go$ go get github.com/yggdrasil-network/yggdrasil-extras@ffba69b
go: downloading github.com/yggdrasil-network/yggdrasil-extras v0.0.0-20210927081343-ffba69bac4cd
go get: added github.com/yggdrasil-network/yggdrasil-extras v0.0.0-20210927081343-ffba69bac4cd
vadym@ubuntu:~/yggdrasil-go$ ./clean
vadym@ubuntu:~/yggdrasil-go$ ANDROID=true ./build
Building aar for Android
go get: upgraded golang.org/x/mobile v0.0.0-20210527171505-7e972142eb43 => v0.0.0-20210924032853-1c027f395ef7
vadym@ubuntu:~/yggdrasil-go$
Start YggdrasilTunService which receives
var configJson = Mobile.generateConfigJSON()
Appropriate line in extras:
https://github.com/yggdrasil-network/yggdrasil-extras/blob/master/src/mobile/mobile.go#L109
AR: app crashes, configJson has following structure and icorrect port typ
e
Stack trace:
Caused by: go.Universe$proxyerror: json: cannot unmarshal number 0.0 into Go struct field MulticastInterfaceConfig.MulticastInterfaces.Port of type uint16
at mobile.Yggdrasil.startJSON(Native Method)
at org.yggdrasil.app.crispa.YggdrasilTunService.setupTunInterface(YggdrasilTunService.kt:122)
at org.yggdrasil.app.crispa.YggdrasilTunService.onStartCommand(YggdrasilTunService.kt:62)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3326)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1582)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Probable solution: set default port 0 for defauts in MulticastInterfaceConfig
https://github.com/yggdrasil-network/yggdrasil-go/blob/f92d812f3cc02f5f1aa49fa4085dfe523afd313b/src/defaults/defaults_other.go#L18
YggdrasilgetPeersJSON() native method returns null for yggdrasil class instance. this corresponds to
https://github.com/yggdrasil-network/yggdrasil-extras/blob/future/src/mobile/mobile.go#L132
@Chronos88 and @vikulin managed to build Yggdrasil for Android, and I'm trying to refactor some things.
The main problem is that Yggdrasil.stop()
crashes like this:
E/Go: panic: close of closed channel
E/Go: goroutine 3447 [running]:
E/Go: github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.(*link).stop(...)
E/Go: /home/revertron/go/src/github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil/link.go:146
E/Go: github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil.(*Core)._stop(0x94198000)
E/Go: /home/revertron/go/src/github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil/core.go:200 +0xba
E/Go: github.com/Arceliar/phony.Block.func1()
E/Go: /tmp/gomobile-work-516345445/pkg/mod/github.com/!arceliar/[email protected]/actor.go:89 +0x24
E/Go: github.com/Arceliar/phony.(*Inbox).run(0x94198000)
E/Go: /tmp/gomobile-work-516345445/pkg/mod/github.com/!arceliar/[email protected]/actor.go:104 +0xaf
E/Go: created by github.com/Arceliar/phony.(*Inbox).restart
E/Go: /tmp/gomobile-work-516345445/pkg/mod/github.com/!arceliar/[email protected]/actor.go:130 +0x39
App crashes while Yggdrasil.recv() method call:
go.Universe$proxyerror: invalid destination address
at mobile.Yggdrasil.send(Native Method)
at io.github.chronosx88.yggdrasil.YggdrasilTunService.readPacketsFromTun(YggdrasilTunService.kt:204)
at io.github.chronosx88.yggdrasil.YggdrasilTunService.access$readPacketsFromTun(YggdrasilTunService.kt:31)
at io.github.chronosx88.yggdrasil.YggdrasilTunService$setupTunInterface$1.invoke(YggdrasilTunService.kt:128)
at io.github.chronosx88.yggdrasil.YggdrasilTunService$setupTunInterface$1.invoke(YggdrasilTunService.kt:125)
at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
The original project where the issue came from was:
https://github.com/ChronosX88/yggdrasil-android
it requires ifMTU and ifTAPMode in Utils.kt. I opened NodeConfig class from yggdrasil-extras after jar file generation and did not find such fields.
package io.github.chronosx88.yggdrasil
import android.content.Context
import android.os.Build.CPU_ABI
import android.util.Log
import com.google.gson.Gson
import config.NodeConfig
import io.github.chronosx88.yggdrasil.models.config.Config
import org.hjson.JsonValue
import org.hjson.Stringify
import java.io.File
import java.lang.Runtime.getRuntime
val gson = Gson()
fun createNativeYggConfig(config: Config): NodeConfig {
val nativeConfig = NodeConfig()
nativeConfig.adminListen = config.adminListen
nativeConfig.encryptionPrivateKey = config.encryptionPrivateKey
nativeConfig.encryptionPublicKey = config.encryptionPublicKey
nativeConfig.ifMTU = config.ifMTU
nativeConfig.ifName = config.ifName
nativeConfig.ifTAPMode = config.ifTAPMode
nativeConfig.nodeInfoPrivacy = config.nodeInfoPrivacy
nativeConfig.signingPrivateKey = config.signingPrivateKey
nativeConfig.signingPublicKey = config.signingPublicKey
return nativeConfig
}
fun Context.saveYggConfig(config: Config) {
val configJson = gson.toJson(config)
val configFile = File(filesDir, "yggdrasil.conf")
configFile.writeText(configJson)
}
NodeConfig class:
// Code generated by gobind. DO NOT EDIT.
// Java class config.NodeConfig is a proxy for talking to a Go program.
//
// autogenerated by gobind -lang=java github.com/yggdrasil-network/yggdrasil-go/src/config
package config;
import go.Seq;
/**
* NodeConfig is the main configuration structure, containing configuration
options that are necessary for an Yggdrasil node to run. You will need to
supply one of these structs to the Yggdrasil core when starting a node.
*/
public final class NodeConfig implements Seq.Proxy {
static { Config.touch(); }
private final int refnum;
@Override public final int incRefnum() {
Seq.incGoRef(refnum, this);
return refnum;
}
NodeConfig(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
public NodeConfig() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
private static native int __New();
// skipped field NodeConfig.Peers with unsupported type: []string
// skipped field NodeConfig.InterfacePeers with unsupported type: map[string][]string
// skipped field NodeConfig.Listen with unsupported type: []string
public final native String getAdminListen();
public final native void setAdminListen(String v);
// skipped field NodeConfig.MulticastInterfaces with unsupported type: []string
// skipped field NodeConfig.AllowedEncryptionPublicKeys with unsupported type: []string
public final native String getEncryptionPublicKey();
public final native void setEncryptionPublicKey(String v);
public final native String getEncryptionPrivateKey();
public final native void setEncryptionPrivateKey(String v);
public final native String getSigningPublicKey();
public final native void setSigningPublicKey(String v);
public final native String getSigningPrivateKey();
public final native void setSigningPrivateKey(String v);
// skipped field NodeConfig.LinkLocalTCPPort with unsupported type: uint16
public final native String getIfName();
public final native void setIfName(String v);
// skipped field NodeConfig.IfMTU with unsupported type: github.com/yggdrasil-network/yggdrasil-go/src/types.MTU
// skipped field NodeConfig.SessionFirewall with unsupported type: github.com/yggdrasil-network/yggdrasil-go/src/config.SessionFirewall
// skipped field NodeConfig.TunnelRouting with unsupported type: github.com/yggdrasil-network/yggdrasil-go/src/config.TunnelRouting
// skipped field NodeConfig.SwitchOptions with unsupported type: github.com/yggdrasil-network/yggdrasil-go/src/config.SwitchOptions
public final native boolean getNodeInfoPrivacy();
public final native void setNodeInfoPrivacy(boolean v);
// skipped field NodeConfig.NodeInfo with unsupported type: map[string]interface{}
/**
* NewEncryptionKeys replaces the encryption keypair in the NodeConfig with a
new encryption keypair. The encryption keys are used by the router to encrypt
traffic and to derive the node ID and IPv6 address/subnet of the node, so
this is equivalent to discarding the node's identity on the network.
*/
public native void newEncryptionKeys();
/**
* NewSigningKeys replaces the signing keypair in the NodeConfig with a new
signing keypair. The signing keys are used by the switch to derive the
structure of the spanning tree.
*/
public native void newSigningKeys();
@Override public boolean equals(Object o) {
if (o == null || !(o instanceof NodeConfig)) {
return false;
}
NodeConfig that = (NodeConfig)o;
// skipped field NodeConfig.Peers with unsupported type: []string
// skipped field NodeConfig.InterfacePeers with unsupported type: map[string][]string
// skipped field NodeConfig.Listen with unsupported type: []string
String thisAdminListen = getAdminListen();
String thatAdminListen = that.getAdminListen();
if (thisAdminListen == null) {
if (thatAdminListen != null) {
return false;
}
} else if (!thisAdminListen.equals(thatAdminListen)) {
return false;
}
// skipped field NodeConfig.MulticastInterfaces with unsupported type: []string
// skipped field NodeConfig.AllowedEncryptionPublicKeys with unsupported type: []string
String thisEncryptionPublicKey = getEncryptionPublicKey();
String thatEncryptionPublicKey = that.getEncryptionPublicKey();
if (thisEncryptionPublicKey == null) {
if (thatEncryptionPublicKey != null) {
return false;
}
} else if (!thisEncryptionPublicKey.equals(thatEncryptionPublicKey)) {
return false;
}
String thisEncryptionPrivateKey = getEncryptionPrivateKey();
String thatEncryptionPrivateKey = that.getEncryptionPrivateKey();
if (thisEncryptionPrivateKey == null) {
if (thatEncryptionPrivateKey != null) {
return false;
}
} else if (!thisEncryptionPrivateKey.equals(thatEncryptionPrivateKey)) {
return false;
}
String thisSigningPublicKey = getSigningPublicKey();
String thatSigningPublicKey = that.getSigningPublicKey();
if (thisSigningPublicKey == null) {
if (thatSigningPublicKey != null) {
return false;
}
} else if (!thisSigningPublicKey.equals(thatSigningPublicKey)) {
return false;
}
String thisSigningPrivateKey = getSigningPrivateKey();
String thatSigningPrivateKey = that.getSigningPrivateKey();
if (thisSigningPrivateKey == null) {
if (thatSigningPrivateKey != null) {
return false;
}
} else if (!thisSigningPrivateKey.equals(thatSigningPrivateKey)) {
return false;
}
// skipped field NodeConfig.LinkLocalTCPPort with unsupported type: uint16
String thisIfName = getIfName();
String thatIfName = that.getIfName();
if (thisIfName == null) {
if (thatIfName != null) {
return false;
}
} else if (!thisIfName.equals(thatIfName)) {
return false;
}
// skipped field NodeConfig.IfMTU with unsupported type: github.com/yggdrasil-network/yggdrasil-go/src/types.MTU
// skipped field NodeConfig.SessionFirewall with unsupported type: github.com/yggdrasil-network/yggdrasil-go/src/config.SessionFirewall
// skipped field NodeConfig.TunnelRouting with unsupported type: github.com/yggdrasil-network/yggdrasil-go/src/config.TunnelRouting
// skipped field NodeConfig.SwitchOptions with unsupported type: github.com/yggdrasil-network/yggdrasil-go/src/config.SwitchOptions
boolean thisNodeInfoPrivacy = getNodeInfoPrivacy();
boolean thatNodeInfoPrivacy = that.getNodeInfoPrivacy();
if (thisNodeInfoPrivacy != thatNodeInfoPrivacy) {
return false;
}
// skipped field NodeConfig.NodeInfo with unsupported type: map[string]interface{}
return true;
}
@Override public int hashCode() {
return java.util.Arrays.hashCode(new Object[] {getAdminListen(), getEncryptionPublicKey(), getEncryptionPrivateKey(), getSigningPublicKey(), getSigningPrivateKey(), getIfName(), getNodeInfoPrivacy()});
}
@Override public String toString() {
StringBuilder b = new StringBuilder();
b.append("NodeConfig").append("{");
b.append("AdminListen:").append(getAdminListen()).append(",");
b.append("EncryptionPublicKey:").append(getEncryptionPublicKey()).append(",");
b.append("EncryptionPrivateKey:").append(getEncryptionPrivateKey()).append(",");
b.append("SigningPublicKey:").append(getSigningPublicKey()).append(",");
b.append("SigningPrivateKey:").append(getSigningPrivateKey()).append(",");
b.append("IfName:").append(getIfName()).append(",");
b.append("NodeInfoPrivacy:").append(getNodeInfoPrivacy()).append(",");
return b.append("}").toString();
}
}
Build log:
+ cd yggdrasil
+ make
go get -u github.com/yggdrasil-network/yggdrasil-go;
package github.com/yggdrasil-network/yggdrasil-go: no Go files in /var/lib/jenkins/go/src/github.com/yggdrasil-network/yggdrasil-go
make: [Makefile:4: all] Error 1 (ignored)
cd /var/lib/jenkins/go/src/github.com/yggdrasil-network/yggdrasil-go; \
go get -v -d ./...; \
go get -u github.com/yggdrasil-network/yggdrasil-extras; \
ANDROID=true ./build;
go: downloading github.com/Arceliar/phony v0.0.0-20191006174943-d0c68492aca0
go: downloading golang.org/x/net v0.0.0-20200301022130-244492dfa37a
go: downloading github.com/hjson/hjson-go v3.0.1-0.20190209023717-9147687966d9+incompatible
go: downloading golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
go: downloading golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
go: downloading github.com/cheggaaa/pb/v3 v3.0.4
go: downloading golang.zx2c4.com/wireguard v0.0.20200320
go: downloading github.com/vishvananda/netlink v1.0.0
go: downloading github.com/fatih/color v1.7.0
go: downloading golang.zx2c4.com/wireguard/windows v0.1.0
go: downloading github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8
go: downloading github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0
go: downloading github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f
go: downloading github.com/mattn/go-colorable v0.1.2
go: downloading github.com/mattn/go-isatty v0.0.10
go: downloading github.com/mitchellh/mapstructure v1.1.2
go: downloading github.com/mattn/go-runewidth v0.0.7
go: downloading golang.org/x/text v0.3.3-0.20191230102452-929e72ca90de
go: downloading github.com/hashicorp/go-syslog v1.0.0
go: downloading github.com/VividCortex/ewma v1.1.1
go: downloading github.com/yggdrasil-network/yggdrasil-extras v0.0.0-20200525205615-6c8a4a2e8855
go: github.com/yggdrasil-network/yggdrasil-extras upgrade => v0.0.0-20200525205615-6c8a4a2e8855
Building aar for Android
mv /var/lib/jenkins/go/src/github.com/yggdrasil-network/yggdrasil-go/yggdrasil.aar yggdrasil.aar;
mv /var/lib/jenkins/go/src/github.com/yggdrasil-network/yggdrasil-go/yggdrasil-sources.jar yggdrasil-sources.jar;
[Gradle] - Launching build.
[yaggrasil-build] $ gradle clean build test
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :clean
> Task :app:clean
> Task :app:preBuild UP-TO-DATE
> Task :app:preDebugBuild UP-TO-DATE
> Task :app:compileDebugAidl NO-SOURCE
> Task :app:compileDebugRenderscript NO-SOURCE
> Task :app:generateDebugBuildConfig
> Task :app:generateDebugResValues
> Task :app:generateDebugResources
> Task :app:mergeDebugResources
> Task :app:createDebugCompatibleScreenManifests
> Task :app:extractDeepLinksDebug
> Task :app:processDebugManifest
> Task :app:processDebugResources
> Task :app:compileDebugKotlin FAILED
e: /var/lib/jenkins/workspace/yaggrasil-build/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt: (21, 18): Unresolved reference: ifMTU
e: /var/lib/jenkins/workspace/yaggrasil-build/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt: (23, 18): Unresolved reference: ifTAPMode
YggdrasilgetPeersJSON() native method returns zero peers. I have at least two 0.4 peers in the same local network.
I compiled yggdrasil with exising extras and connection was not worked for v 0.4:
I/GoLog: Build name: yggdrasil
Build version: 0.4.3.2
Starting up...
I/GoLog: Starting switch
Starting router
Startup complete
I/GoLog: Starting multicast module
I/GoLog: Started multicast module
I/GoLog: Failed to set tcp_congestion_control to bbr for socket, SetsockoptString error: no such file or directory
I/GoLog: DEBUG: starting handler for tcp://77.247.225.234:12345
I/GoLog: DEBUG: stopped handler for tcp://77.247.225.234:12345 read tcp 10.0.2.15:59062->77.247.225.234:12345: read: connection reset by peer
I/GoLog: search timeout: 89488000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1 1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.