Giter Site home page Giter Site logo

pacien / tincapp Goto Github PK

View Code? Open in Web Editor NEW
157.0 15.0 30.0 1.56 MB

Android binding and user interface for the tinc mesh VPN daemon.

Home Page: https://tincapp.pacien.org

License: GNU General Public License v3.0

CMake 2.30% C 0.03% Kotlin 97.68%
android vpn tinc

tincapp's Introduction

Tinc App

Android binding and user interface for the tinc mesh VPN daemon which does not require root privilege.

Help and documentation

The complete list of features, the quickstart guides and the user manual can be found on the project's website: https://tincapp.pacien.org.

Community support is mainly provided through the dedicated Matrix Room and IRC channel: #tincapp:pacien.net and #tincapp on irc.libera.chat.

Download

Compiled Android packages are available from:

Build

The project can be built using the Gradle build task, on Linux.

Requirements:

  • Android SDK Platform 33
  • Android NDK r22
  • Android Platform-Tools 34
  • Android SDK Tools 26
  • CMake
  • automake
  • autoconf

License

Copyright (C) 2017-2024 Pacien TRAN-GIRARD and contributors (listed in contributors.md).

Tinc App is distributed under the terms of GNU General Public License v3.0, as detailed in the provided license.md file.

Builds of this software embed and make use of the following libraries:

  • Kotlin Standard Library, licensed under the Apache v2.0 License
  • streamsupport-cfuture, licensed under the GNU General Public License v2.0
  • Material Components for Android, licensed under the Apache v2.0 License
  • ZXing Android Embedded, licensed under the Apache v2.0 License
  • Bouncy Castle PKIX, licensed under the Bouncy Castle License
  • SLF4J, licensed under the MIT License
  • logback-android, licensed under the GNU Lesser General Public License v2.1
  • Apache Commons Configuration, licensed under the Apache v2.0 License
  • Apache Commons BeanUtils, licensed under the Apache v2.0 License
  • LZO, licensed under the GNU General Public License v2.0
  • LibreSSL libcrypto, licensed under the OpenSSL License, ISC License, public domain
  • tinc, licensed under the GNU General Public License v2.0

tincapp's People

Contributors

comradekingu avatar exclued avatar naofum avatar pacien avatar sebastien46 avatar yangfl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tincapp's Issues

Log reports

  • Disable class member obfuscation
  • Add a pop-up on crash, asking the user to report the problem, providing the generated log file.

SDCard: Error: Could not create directory. Permission denied.

Tap 'Generate node configuration and keys'->{Enter Tinc network name "lalanet" & nodename "lalaname"&Tap 'Create'}->Error: Could not create directory /storage/sdcard1/Andrpoid/data/org.pacien.tincapp/files/lalanet: Permission denied.
The same problem is for 'Join network via invitation URL'

P.S.Manual setup is ok. It seems there is something wrong with the app write permission in the directory only.

Android Lollipop 5.1.1 Huawei Honor 6 (H60-L04)
EMUI 3.1

NullPointerException in ViewLogActivity

Happens when the activity is oppened at the exact same moment the service is stopped.

Reported via Google Play.

  • Version: v0.13
  • Android versions: 7.1
  • Reports: 1
Caused by: kotlin.KotlinNullPointerException: 
  at org.pacien.tincapp.activities.ViewLogActivity.startLogging (ViewLogActivity.kt:81)
  at org.pacien.tincapp.activities.ViewLogActivity.startLogging$default (ViewLogActivity.kt:78)
  at org.pacien.tincapp.activities.ViewLogActivity.toggleLogging (ViewLogActivity.kt:59)

ViewLogActivity.kt:81

Check for "external" storage availability

Check whether the "external" storage directory is available (not busy while mounted as an USB flash drive) and display a clear error message insead of crashing.

Stacktrace reported by the Google Play Console:

java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2316)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2376)
  at android.app.ActivityThread.access$800 (ActivityThread.java:147)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1281)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:135)
  at android.app.ActivityThread.main (ActivityThread.java:5253)
  at java.lang.reflect.Method.invoke (Method.java)
  at java.lang.reflect.Method.invoke (Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:899)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:694)

Caused by: java.lang.NullPointerException:
  at android.os.Parcel.readException(Parcel.java:1546)
  at android.os.Parcel.readException (Parcel.java:1493)
  at android.os.storage.IMountService$Stub$Proxy.mkdirs (IMountService.java:830)
  at android.app.ContextImpl.ensureDirsExistOrFilter (ContextImpl.java:2455)
  at android.app.ContextImpl.getExternalFilesDirs (ContextImpl.java:1092)
  at android.app.ContextImpl.getExternalFilesDir (ContextImpl.java:1066)
  at android.content.ContextWrapper.getExternalFilesDir (ContextWrapper.java:218)
  at org.pacien.tincapp.context.AppPaths.confDir (AppPaths.java)
  or                     .hostsDir (AppPaths.java)
  at org.pacien.tincapp.activities.StartActivity.onCreate (StartActivity.java)
  at android.app.Activity.performCreate (Activity.java:5975)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1105)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2269)

Only direct peer in the routing table

It appears that tincapp will not update the routing table after new indirect peers are pushed.

For example, I have 4 tinc nodes A/B/C/D, only A is on android tincapp while B/C/D are normal linux tinc build. Initially A and B are online, C&D are offline. Later on I enable node C&D, B/C/D are all inter-connected, but A is still only able to talk to B.

It defeats the purpose of tinc as a site-to-site vpn. Would you mind adding the dynamic routing table update?

Chmodding app dir fails

app_dir/app_conf is owned by the app itself and not modifiable by the shell user.
chmod app_dir/app_conf/* instead

NullPointerException on start

From the GPlay dev console:

java.lang.RuntimeException: 
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:3556)
  at android.app.ActivityThread.-wrap20 (Unknown Source)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1698)
  at android.os.Handler.dispatchMessage (Handler.java:105)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6541)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:240)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:767)
Caused by: kotlin.KotlinNullPointerException: 
  at org.pacien.tincapp.service.TincVpnService.a (TincVpnService.java:221)
  at org.pacien.tincapp.service.TincVpnService.onStartCommand (TincVpnService.java:39)
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:3539)

Crash when selecting config

My phone runs Android 7.0.

ERROR Report:

java.lang.RuntimeException: Unable to start service org.pacien.tincapp.service.TincVpnService@4cb790b with Intent { cmp=org.pacien.tincapp/.service.TincVpnService (has extras) }: org.apache.commons.c.e.a: Could not locate: org.apache.commons.c.g.l@bce80da[fileName=network.conf,basePath=/storage/emulated/0/Android/data/org.pacien.tincapp/files/mesh,sourceURL=,encoding=ISO-8859-1,fileSystem=<null>,locationStrategy=<null>]
	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3391)
	at android.app.ActivityThread.-wrap21(ActivityThread.java)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1632)
	at android.os.Handler.dispatchMessage(Handler.java:102)
	at android.os.Looper.loop(Looper.java:160)
	at android.app.ActivityThread.main(ActivityThread.java:6275)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: org.apache.commons.c.e.a: Could not locate: org.apache.commons.c.g.l@bce80da[fileName=network.conf,basePath=/storage/emulated/0/Android/data/org.pacien.tincapp/files/mesh,sourceURL=,encoding=ISO-8859-1,fileSystem=<null>,locationStrategy=<null>]
	at org.apache.commons.c.g.n.f(Unknown Source)
	at org.apache.commons.c.g.h.b(Unknown Source)
	at org.apache.commons.c.g.h.f(Unknown Source)
	at org.apache.commons.c.b.m.a(Unknown Source)
	at org.apache.commons.c.b.m.a(Unknown Source)
	at org.apache.commons.c.b.m.a(Unknown Source)
	at org.apache.commons.c.b.c.d(Unknown Source)
	at org.apache.commons.c.b.c.c(Unknown Source)
	at org.apache.commons.c.b.a.a.b(Unknown Source)
	at org.pacien.tincapp.a.b$a.a(Unknown Source)
	at org.pacien.tincapp.service.TincVpnService.b(Unknown Source)
	at org.pacien.tincapp.service.TincVpnService.onStartCommand(Unknown Source)
	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3374)
	... 8 more

Gateway/Routing support

Is there any support for changing default gateway? I can't find it in the manual.

It's extremely disappointing for an VPN software to have no support for default gateway.

I would like to suggest something like

ip route add 10.0.0.0/24 via 10.0.0.1 dev $INTERFACE -> Route = 10.0.0.0/24 10.0.0.1

IllegalStateException in StatusActivity

Reported via Google Play.

  • Version: v0.13
  • Android versions: 7.1, 8.0, 8.1
  • Reports: 3
java.lang.IllegalStateException: 
  at org.pacien.tincapp.activities.StatusActivity$updateNodeList$1$1.invoke (StatusActivity.kt:149)
  at org.pacien.tincapp.activities.StatusActivity$updateNodeList$1$1.invoke (StatusActivity.kt:34)
  at org.pacien.tincapp.activities.BaseActivityKt$sam$Runnable$57718e2c.run (Unknown Source:2)
  at android.os.Handler.handleCallback (Handler.java:790)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6494)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:440)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)

StatusActivity.kp:149

Put tinc.pid path in a world rw location

Having tinc.pid in an read/write location would allow to reload, stop, and do other nice operations such as dumping the nodes and the network graph from the console

Missing network config

HI

I am trying to use this app, so I click to generate the configs. It creates the configs then complaints about missing network.conf.

I use it on Android 5.1

thanks

ClassCastException in StatusActivity

Reported by Google Play.

  • Version: v0.13
  • Android version: 6.0
  • Reports: 1
java.lang.ClassCastException: 
  at org.pacien.tincapp.activities.StatusActivity.onItemClick (StatusActivity.kt:99)
  at android.widget.AdapterView.performItemClick (AdapterView.java:310)
  at android.widget.AbsListView.performItemClick (AbsListView.java:1145)
  at android.widget.AbsListView$PerformClick.run (AbsListView.java:3066)
  at android.widget.AbsListView$3.run (AbsListView.java:3903)
  at android.os.Handler.handleCallback (Handler.java:739)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:148)
  at android.app.ActivityThread.main (ActivityThread.java:5461)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:726)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616)

StatusActivity.kt:99

Wrapper app logging

Currently, the underlying tinc daemon takes care of its own logfiles, and tincapp uses Android's system logger.

While this is enough when developping and debugging, logcat isn't easily accessible to end users.

It would be nice to log the app's errors in a file as well to ease bug reporting.

App crashes on start when another VPN is running

I have created a tinc configuration in /storage/emulated/0/Android/data/org.pacien.tincapp/files/vpn/. tinc.conf looks like:

Name = oneplus
ConnectTo = outside

And network.conf looks like:

Address = 172.16.254.50/32
Route = 172.16.254.0/24

And hosts/outside looks like (-ish):

Address = tinc.example.com

-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

As soon as I select a network name in the UI, the tinc app crashes. There are no logs in /storage/emulated/0/Android/data/org.pacien.tincapp/cache.

I am running Android 7.1.2 (lineageos 14.1-<a recent update>).

Add Intents for integration with automation Android apps

Apps like Tasker, Automate, and Llama can call Intents on other applications - having intents for starting a tinc net and stopping tinc would be awesome, as then we can use these powerful apps to start/stop tinc on whatever conditions we want.

Even the node is connected all apps use normal Internet

I setup TincApp and was able to get a connection. ifconfig -a shows a tun0 with an IP, but all Data goes through the normal connection.
IP-Address and Route is set. DNS Server, Search domains and Allow bypass are set no

Generate initial conf via GUI

Need to generate configuration by calling tincctl, remove hook scripts, add a template for network.conf

  • generate empty conf
  • generate conf from URL (join existing net)
  • call bar-code scanner optionally to scan tinc invitation URL
  • update doc

Notes from IRC:

Notkea: what is the behaviour of the tinc --config=$confdir join $url command? does it create a directory for the configuration within $confdir, or does it consider that $confdir contains the netname?
guus: it will create $confdir and put tinc.conf inside it.
Notkea: ok, so no need for --net=$netname ?
guus: Well you can use --net=$netname, this is equal to --config=/etc/tinc/$netname.

guus: Will you make it so you can scan the invitation URL from a QR code?
Should be easy I think, I believe you just have to signal an intent?

guus: Check out the latest revision from the 1.1 branch. The data is now stored in /etc/tinc/netname/invitation-data
It's exactly the same data that was in the invitation file on the inviter.

SecurityException in TincVpnService.startVpn

Reported via Google Play Services. To investigate.
Please comment this issue if you are affected by this.

  • tincapp v0.14
  • Android 7.1.
Caused by: java.lang.SecurityException: 
  at android.os.Parcel.readException (Parcel.java:1684)
  at android.os.Parcel.readException (Parcel.java:1637)
  at android.net.IConnectivityManager$Stub$Proxy.establishVpn (IConnectivityManager.java:1966)
  at android.net.VpnService$Builder.establish (VpnService.java:769)
  at org.pacien.tincapp.service.TincVpnService.startVpn (TincVpnService.kt:87)
  at org.pacien.tincapp.service.TincVpnService.onStartCommand (TincVpnService.kt:49)
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:3351)

NullPointerException in service

From the GPlay dev console:

java.lang.RuntimeException: 
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:3344)
  at android.app.ActivityThread.-wrap21 (ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1583)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:154)
  at android.app.ActivityThread.main (ActivityThread.java:6121)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:889)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:779)
Caused by: kotlin.KotlinNullPointerException: 	at org.pacien.tincapp.service.TincVpnService.startVpn(TincVpnService.java)
  at <OR> org.pacien.tincapp.service.TincVpnService.openPrivateKey (TincVpnService.java)
  or                     .reportError (TincVpnService.java)
  or                     .reportError$default (TincVpnService.java)
  or                     .access$getTAG$cp (TincVpnService.java)
  or                     .access$setConnected$cp (TincVpnService.java)
  or                     .access$setNetName$cp (TincVpnService.java)
  or                     .access$setInterfaceCfg$cp (TincVpnService.java)
  or                     .access$setFd$cp (TincVpnService.java)
  at org.pacien.tincapp.service.TincVpnService.onStartCommand (TincVpnService.java)
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:3327)

Crash in ConfigureActivity

Reported via Google Play.

App version: 10
Android version: 5.1
Impacted users: 1

java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2335)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2397)
  at android.app.ActivityThread.access$800 (ActivityThread.java:151)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1310)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:135)
  at android.app.ActivityThread.main (ActivityThread.java:5268)
  at java.lang.reflect.Method.invoke (Method.java)
  at java.lang.reflect.Method.invoke (Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:902)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:697)
Caused by: java.lang.IllegalStateException: 
  at org.pacien.tincapp.activities.ConfigureActivity.writeContent (ConfigureActivity.java)
  at org.pacien.tincapp.activities.ConfigureActivity.onCreate (ConfigureActivity.java)
  at android.app.Activity.performCreate (Activity.java:6033)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1106)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2288)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2397)
  at android.app.ActivityThread.access$800 (ActivityThread.java:151)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1310)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:135)
  at android.app.ActivityThread.main (ActivityThread.java:5268)
  at java.lang.reflect.Method.invoke (Method.java)
  at java.lang.reflect.Method.invoke (Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:902)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:697)

bug found in tich app whento create new networks

Expected behavior

This application allows users to generate node and key configurations. this feature can be found in the settings option

Actual behavior

when i tried tu use that feature. when I want to create a new network, this application get crashed and stop itself

How to reproduce

  • download tinch app
  • laucnh the app
  • go to setting option
  • chose features generate node configurations and key
  • after that try to create new networ and a app will crashed
  • Browser: tinc app v 0. 12
  • Operating system: android 5.1 idos advan s5e nxt

Recording Of The Bug

https://www.youtube.com/watch?v=dXQTfO-EQVA



Posted on Utopian.io - Rewarding Open Source Contributors

No known node after VPN restart

The nodes list disappears after stopping and restarting the network.

Steps to reproduce:

  • Setup your Tinc network
  • Start the Tinc App
  • See the names of your network nodes in the "Nodes" section
  • Connect to your network by touching on it in the list
  • Stop the connection by pressing the "square button" in the header
  • Connect to your network by touching on it in the list

Tinc now predends to be running, but does not work. The list of nodes now only contains no known nodes.

Temporary solution:

Force stopping the Tinc App fron the Android Apps settings works to be able to re-connect to the network.

Platform:

Android 7.1.2
LineageOS 14.1 - October 16, 2017
Nexus 6P angler

编译报错

:app:externalNativeBuildDebug
Build exec arm64-v8a
[
1
/
2
0
]

P
e
r
f
o
r
m
ing configure step for 'lzo'
[2/20] No update step for 'libressl'
[3/20] No patch step for 'libressl'
FAILED: cmd.exe /C "cd /D D:\tincapp-master\app.externalNativeBuild\cmake\debug\arm64-v8a\lzo-prefix\src\lzo-build && D:\tincapp-master\app.externalNativeBuild\cmake\debug\arm64-v8a\lzo-prefix\src\lzo\configure "CC=E:/work/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe --gcc-toolchain=E:/work/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --target=aarch64-none-linux-android --sysroot=E:/work/Android/sdk/ndk-bundle/sysroot" LD=E:/work/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-ld.exe AR=E:/work/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-ar.exe RANLIB=E:/work/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-ranlib.exe "CFLAGS=-isystem E:/work/Android/sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security " "LDFLAGS=-Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot E:/work/Android/sdk/ndk-bundle/platforms/android-21/arch-arm64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now " --host=aarch64-none-linux-android --disable-shared && E:\work\Android\sdk\cmake\3.6.4111459\bin\cmake.exe -E touch D:/tincapp-master/app/.externalNativeBuild/cmake/debug/arm64-v8a/lzo-prefix/src/lzo-stamp/lzo-configure"
'D:\tincapp-master\app.externalNativeBuild\cmake\debug\arm64-v8a\lzo-prefix\src\lzo\configure' ????????????????????????е????
?????????????
ninja: build stopped: subcommand failed.
:app:externalNativeBuildDebug FAILED

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':app:externalNativeBuildDebug'.

Build command failed.
Error while executing process E:\work\Android\sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build D:\tincapp-master\app.externalNativeBuild\cmake\debug\arm64-v8a --target exec}
[1/20] Performing configure step for 'lzo'
[2/20] No update step for 'libressl'
[3/20] No patch step for 'libressl'
FAILED: cmd.exe /C "cd /D D:\tincapp-master\app.externalNativeBuild\cmake\debug\arm64-v8a\lzo-prefix\src\lzo-build && D:\tincapp-master\app.externalNativeBuild\cmake\debug\arm64-v8a\lzo-prefix\src\lzo\configure "CC=E:/work/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe --gcc-toolchain=E:/work/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --target=aarch64-none-linux-android --sysroot=E:/work/Android/sdk/ndk-bundle/sysroot" LD=E:/work/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-ld.exe AR=E:/work/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-ar.exe RANLIB=E:/work/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-ranlib.exe "CFLAGS=-isystem E:/work/Android/sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security " "LDFLAGS=-Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot E:/work/Android/sdk/ndk-bundle/platforms/android-21/arch-arm64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now " --host=aarch64-none-linux-android --disable-shared && E:\work\Android\sdk\cmake\3.6.4111459\bin\cmake.exe -E touch D:/tincapp-master/app/.externalNativeBuild/cmake/debug/arm64-v8a/lzo-prefix/src/lzo-stamp/lzo-configure"
'D:\tincapp-master\app.externalNativeBuild\cmake\debug\arm64-v8a\lzo-prefix\src\lzo\configure' ????????????????????????е????
?????????????
ninja: build stopped: subcommand failed.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

  • Get more help at https://help.gradle.org

BUILD FAILED in 3s

17 actionable tasks: 1 executed, 16 up-to-date

Encrypting the keys fails: SecretKeyFactory PBKDF-OpenSSL implementation not found

I encountered an issue with the private key encryption not working on my Android 6 phone. See the screenshot below. The error occurs when an key is about to be encrypted after entering the passphrase and confirming the dialog.

Using the app with non-encrypted keys works nicely.

encrypt-key-error-message-s

Looking at the logs I did not find anything too suspicious:

2018-02-11 22:26:18 tinc[20175]: tincd UNKNOWN (Sep 10 2017 13:01:09) starting, debug level 0
2018-02-11 22:26:18 tinc[20175]: Warning: insecure file permissions for Ed25519 private key file `/storage/emulated/0/Android/data/org.pacien.tincapp/files/test/ed25519_key.priv'!
2018-02-11 22:26:18 tinc[20175]: Warning: insecure file permissions for RSA private key file `/storage/emulated/0/Android/data/org.pacien.tincapp/files/test/rsa_key.priv'!
2018-02-11 22:26:18 tinc[20175]: fd/40 adapter set up.
2018-02-11 22:26:18 tinc[20175]: Ready
2018-02-11 22:27:05 tinc[20175]: Terminating

I wondered about the warnings regarding the file permissions on the keys being the cause for this issue. I tried to revoke the groups read and write permissions on these files using a file manager on my rooted phone, but it seems the filesystem does not support changing file permissions.

Anyways: Thanks for providing this app.

Support for older Android versions

When trying to install this app on Android 4.4.4, I get an package processing error (Un problème est survenu lors de l'analyse du package.). I downloaded the APK from your website directly (it does show greyed out in F-Droid).

I assume this is an API/SDK version problem. Could you build the app for Android 4.4 (api 19) ? Or is there any functionnality that requires API 21 ?

seeting button doest not working in tinc app

Expected behavior

when the user presses the settings button the user should be able to set the vpn settings in accordance with the wishes of the user.

Actual behavior

when I try to press the settings button to set up the vpn connection the app crashes and stops

How to reproduce

  • download tinc app
  • launch the app
  • go to setting button
  • and app will get crased and stops
  • Operating system: advan s5e nxt android lolipop 5.1 idos
  • app version; tincn app v 0.12

Recording Of The Bug

https://www.youtube.com/watch?v=1lLWJE5aQCU



Posted on Utopian.io - Rewarding Open Source Contributors

Read configuration from external storage (SD card)

Read configuration from the application directory on external storage (SD card) as a secondary option for users who can't write on the internal storage.

Log, PID and socket files will be stored along on the same storage as the active configuration. The recommended option will remain unchanged, as files on the External Storage are world readable, which is a problem for protecting private keys.

  • Handle configurations put on External Storage
  • Remove the "Fix permissions" option
  • Consider removing additional support for internal storage
  • Update documentation

Confusing error message

When I mistyped Route = 10.0.0.1/24, it just complains Bad address and nothing else. I have to check every CIDR until I realised what was wrong.

It would better if the parser could give more information, like line no.

Update documentation for Android 6+

Paths aren't the same.

  • Writable app data dir is /data/user/0 instead of /data/data
  • Native lib dir isn't symlinked to /data/data/$app/lib anymore

Those paths should be displayed in the app: #4

Crash in StatusActivity

Reported via Google Play.

App versions: 9, 10
Android versions: 7.0, 7.1
Impacted users: 3

java.lang.IllegalStateException: 
  at org.pacien.tincapp.activities.StatusActivity$updateNodeList$1$1.run (StatusActivity.java)
  at android.os.Handler.handleCallback (Handler.java:751)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:154)
  at android.app.ActivityThread.main (ActivityThread.java:6126)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:886)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:776)

Android using wrong dns server when tinc is active

I have tincapp running on two Android devices: a oneplus 3T running LineageOS 14.1 (Android 7.1.2), and a Huawei Mediapad M3 running EMUI 5.0.1 (Android 7.0). Both devices have the same configuration, which includes in network.conf:

DNSServer = 172.16.254.1

On my oneplus 3T, when tinc is active, DNS queries go, as desired, to the nameserver defined by the tinc configuration. That is, running tcpdump on the VPN server itself (172.16.254.1), I can run host hostname.only.on.vpn in Termux on my phone and see the queries coming in over the vpn interface (and the hostname resolves correctly).

On my mediapad, the same query returns an NXDOMAIN error and the query is not visible on the server side. Everything else seems to be working (that is, I can access hosts on the vpn by ip address just fine). It looks like on the mediapad, dns queries aren't going to the right server.

This smells more like an Android problem than a tinc problem, but do you have any idea what could be going on here?

UI improvements

  • Start screen listing the configured tinc networks (from internal and external storage #2), syntactically validated using tinc fsck
  • Status screen displaying connection information (IP, routes, DNS servers) and listing known nodes with their reachability
  • Display paths to configuration in internal/external storage, and path to tinc{,d} executables (done as part of commit 328ad55)

Support for encrypted private key

Support optionally passphrase-encrypted private keys. Especially useful when storing everything on the world-readable external storage. The app will show a passphrase prompt if those keys are found to be protected.

  • privkeys encryption/decryption
  • UI dialogs
  • supply decrypted keys to the underlying daemon
  • doc update

Notes from IRC:

guus: You can just do -o PrivateKeyFile=/dev/stdin, and pass a key to tincd that way. Then you have full control over it, and you don't have to write it to rsa_key.priv first.

guus: this works: cat ed25519_key.priv rsa_key.priv | tincd -o PrivateKeyFile=/dev/stdin -o Ed25519PrivateKeyFile=/dev/stdin

https://i.stack.imgur.com/5afWK.png
guus: "a RH A" is the privkey; You'll notice that there's 96 bytes worth of data in ed25519_key.priv after decoding the base64 part. So it's a concatenation of what NaCL's privkey and pubkey.

Invalid network configuration: At least one address must be specified.

I am trying to join an existing tinc network via invite url.
tinc seems to have imported the config (i can see that the files are generated in /android/sdcard/Android/data/org.pacien.tincapp/files/tincvpn), but when i try to start it, a message pops up and says:

Unable to start tinc
Invalid network configuration
At least one address must be specified
Open manual                     Close

Any idea?
Thanks.

-edit-
Just found this:
https://forums.openvpn.net/viewtopic.php?t=22215
and this, line 283
https://android.googlesource.com/platform/frameworks/base/+/d396a44/services/java/com/android/server/connectivity/Vpn.java

It points to a problem with the tun device. (?)
But "openvpn for android" and "andiodine" both work well here; my device is a zenfone 2 ze551ml, running lollipop 5.0.1

logcat says:
I/ActivityManager(  766): START u0 {act=org.pacien.tincapp.intent.action.CONNECT dat=tinc:tincvpn flg=0x10000000 cmp=org.pacien.tincapp/.activities.LaunchActivity} from uid 10286 on display 0
D/WindowManager(  766): adjustConfigurationLw, config:{0 0.85 ?mcc?mnc ?locale ?layoutDir sw360dp w360dp h615dp 480dpi nrml long port ?uimode ?night finger -keyb/v/h -nav/v} mLidState:1 mHasDockFeature:false mHasKeyboardFeature:false mHasHallSensorFeature:true config.hardKeyboardHidden:2
V/Monotype( 3431): SetAppTypeFace- try to flip, app = org.pacien.tincapp
V/Monotype( 3431):     Typeface getFontPathFlipFont - systemFont = /data/data/flipfont/app_fonts/PTSans-Regular#PT Sans
I/Vpn     (  766): Switched from [Legacy VPN] to org.pacien.tincapp
D/Vpn     (  766): setting state=IDLE, reason=prepare
I/org.pacien.tincapp.service.TincVpnService.a( 3431): Starting tinc daemon for network "tincvpn".
I/art     ( 3431): Rejecting re-init on previously-failed class java.lang.Class<org.apache.commons.a.r>
I/art     ( 3431): Rejecting re-init on previously-failed class java.lang.Class<org.apache.commons.a.r>
I/dispmgr (  318): waiting for message from kernel.
I/dispmgr (  318): message from kernel received.
I/dispmgr (  318): DpstAlgorithm_DPST4_5 
I/dispmgr (  318): DpstAlgorithm_DPST4_5 level is 3
I/art     ( 3431): Rejecting re-init on previously-failed class java.lang.Class<org.apache.commons.a.r>
D/Vpn     (  766): setting state=CONNECTING, reason=establish
E/org.pacien.tincapp.service.TincVpnService.a( 3431): Invalid network configuration:
E/org.pacien.tincapp.service.TincVpnService.a( 3431): 
E/org.pacien.tincapp.service.TincVpnService.a( 3431): At least one address must be specified
E/org.pacien.tincapp.service.TincVpnService.a( 3431): java.lang.IllegalArgumentException: At least one address must be specified
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.os.Parcel.readException(Parcel.java:1544)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.os.Parcel.readException(Parcel.java:1493)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.net.IConnectivityManager$Stub$Proxy.establishVpn(IConnectivityManager.java:1716)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.net.VpnService$Builder.establish(VpnService.java:686)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at org.pacien.tincapp.service.TincVpnService.b(Unknown Source)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at org.pacien.tincapp.service.TincVpnService.onStartCommand(Unknown Source)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2891)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.app.ActivityThread.access$2100(ActivityThread.java:147)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1379)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.os.Handler.dispatchMessage(Handler.java:102)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.os.Looper.loop(Looper.java:135)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at android.app.ActivityThread.main(ActivityThread.java:5264)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at java.lang.reflect.Method.invoke(Native Method)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at java.lang.reflect.Method.invoke(Method.java:372)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)
E/org.pacien.tincapp.service.TincVpnService.a( 3431):   at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)

Conf file edition

I would like to see that *.conf can be directly edited from UI. Especially it would be better if network.conf can be edited on the fly.

Crash when selecting a network to connect

The application is stopped after I select a network to connect, here are the logs from adb logcat:

D/hwcomposer(  239): void android::intel::DisplayAnalyzer::handleIdleExitEvent(): handling idle exit event
I/ActivityManager( 1575): START u0 {flg=0x10000000 cmp=org.pacien.tincapp/.activities.PromptActivity (has extras)} from uid 10347 on display 0
D/wpa_supplicant( 5074): wlan0: Control interface command 'SIGNAL_POLL'
D/WifiWatchdogStateMachine( 1575): RSSI current: 4 new: -44, 4
D/WindowManager( 1575): adjustConfigurationLw, config:{0 1.0 ?mcc?mnc ?locale ?layoutDir sw360dp w360dp h615dp 480dpi nrml long port ?uimode ?night finger -keyb/v/h -nav/v} mLidState:1 mHasDockFeature:false mHasKeyboardFeature:false mHasHallSensorFeature:true config.hardKeyboardHidden:2
V/Monotype(28354): SetAppTypeFace- try to flip, app = org.pacien.tincapp
V/Monotype(28354):     Typeface getFontPathFlipFont - systemFont = default#default
I/art     (28354): Rejecting re-init on previously-failed class java.lang.Class<org.apache.commons.a.r>
I/art     (28354): Rejecting re-init on previously-failed class java.lang.Class<org.apache.commons.a.r>
I/art     (28354): Rejecting re-init on previously-failed class java.lang.Class<org.apache.commons.a.r>
I/art     (28354): Rejecting re-init on previously-failed class java.lang.Class<org.apache.commons.a.r>
I/art     (28354): Rejecting re-init on previously-failed class java.lang.Class<org.apache.commons.a.r>
I/dispmgr ( 1282): waiting for message from kernel.
I/dispmgr ( 1282): message from kernel received.
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 level is 3
D/AndroidRuntime(28354): Shutting down VM
E/AndroidRuntime(28354): FATAL EXCEPTION: main
E/AndroidRuntime(28354): Process: org.pacien.tincapp, PID: 28354
E/AndroidRuntime(28354): java.lang.RuntimeException: Unable to start service org.pacien.tincapp.service.TincVpnService@299e6b9f with Intent { cmp=org.pacien.tincapp/.service.TincVpnService (has extras) }: org.apache.commons.c.e.a: Could not locate: org.apache.commons.c.g.l@2caa113e[fileName=network.conf,basePath=/storage/emulated/0/Android/data/org.pacien.tincapp/files/f2f,sourceURL=,encoding=ISO-8859-1,fileSystem=<null>,locationStrategy=<null>]
E/AndroidRuntime(28354): 	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2908)
E/AndroidRuntime(28354): 	at android.app.ActivityThread.access$2100(ActivityThread.java:147)
E/AndroidRuntime(28354): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1379)
E/AndroidRuntime(28354): 	at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(28354): 	at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime(28354): 	at android.app.ActivityThread.main(ActivityThread.java:5264)
E/AndroidRuntime(28354): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(28354): 	at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(28354): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
E/AndroidRuntime(28354): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)
E/AndroidRuntime(28354): Caused by: org.apache.commons.c.e.a: Could not locate: org.apache.commons.c.g.l@2caa113e[fileName=network.conf,basePath=/storage/emulated/0/Android/data/org.pacien.tincapp/files/f2f,sourceURL=,encoding=ISO-8859-1,fileSystem=<null>,locationStrategy=<null>]
E/AndroidRuntime(28354): 	at org.apache.commons.c.g.n.f(Unknown Source)
E/AndroidRuntime(28354): 	at org.apache.commons.c.g.h.b(Unknown Source)
E/AndroidRuntime(28354): 	at org.apache.commons.c.g.h.f(Unknown Source)
E/AndroidRuntime(28354): 	at org.apache.commons.c.b.m.a(Unknown Source)
E/AndroidRuntime(28354): 	at org.apache.commons.c.b.m.a(Unknown Source)
E/AndroidRuntime(28354): 	at org.apache.commons.c.b.m.a(Unknown Source)
E/AndroidRuntime(28354): 	at org.apache.commons.c.b.c.d(Unknown Source)
E/AndroidRuntime(28354): 	at org.apache.commons.c.b.c.c(Unknown Source)
E/AndroidRuntime(28354): 	at org.apache.commons.c.b.a.a.b(Unknown Source)
E/AndroidRuntime(28354): 	at org.pacien.tincapp.service.b.<init>(Unknown Source)
E/AndroidRuntime(28354): 	at org.pacien.tincapp.service.TincVpnService.a(Unknown Source)
E/AndroidRuntime(28354): 	at org.pacien.tincapp.service.TincVpnService.onStartCommand(Unknown Source)
E/AndroidRuntime(28354): 	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2891)
E/AndroidRuntime(28354): 	... 9 more
W/ActivityManager( 1575):   Force finishing activity org.pacien.tincapp/.activities.StartActivity
D/ForegroundUtils( 2328): Foreground changed, PID: 2058 UID: 10017 foreground: true
D/ForegroundUtils( 2328): Foreground UID/PID combinations:
D/ForegroundUtils( 2328): UID: 10017 PID: 2058
D/ForegroundUtils( 2328): UID: 10347 PID: 28354
I/OpenGLRenderer( 1575): Initialized EGL, version 1.4
I/dispmgr ( 1282): waiting for message from kernel.
I/dispmgr ( 1282): message from kernel received.
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 level is 3
I/dispmgr ( 1282): waiting for message from kernel.
I/dispmgr ( 1282): message from kernel received.
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 level is 3
I/dispmgr ( 1282): waiting for message from kernel.
I/dispmgr ( 1282): message from kernel received.
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 level is 3
I/dispmgr ( 1282): waiting for message from kernel.
I/dispmgr ( 1282): message from kernel received.
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 level is 3
W/ActivityManager( 1575): Activity pause timeout for ActivityRecord{2c8dd142 u0 org.pacien.tincapp/.activities.PromptActivity t14603 f}
D/WindowManager( 1575): adjustConfigurationLw, config:{0 1.0 ?mcc?mnc ?locale ?layoutDir sw360dp w360dp h615dp 480dpi nrml long port ?uimode ?night finger -keyb/v/h -nav/v} mLidState:1 mHasDockFeature:false mHasKeyboardFeature:false mHasHallSensorFeature:true config.hardKeyboardHidden:2
V/ActivityManager( 1575): Displayed ActivityRecord{3823b335 u0 com.asus.launcher/com.android.launcher3.Launcher t14391} Resume. Not First Launch.
I/dispmgr ( 1282): waiting for message from kernel.
I/dispmgr ( 1282): message from kernel received.
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 level is 3
V/Launcher( 2058): [onResume] called
I/Launcher( 2058): Time spent in onResume: 2ms
D/[NotificationManager]( 2058): [isQuickFindTipFinished] finished: true
I/dispmgr ( 1282): waiting for message from kernel.
I/dispmgr ( 1282): message from kernel received.
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 
I/dispmgr ( 1282): DpstAlgorithm_DPST4_5 level is 3
D/[reSortApps]( 2058): reSortApps, (mApps == null) ? false, AppsCustomizeTabHost.sAllAppMode: 0
D/Launcher.Utilities( 2058): isPhone= true
D/Launcher.Utilities( 2058): isPhone= true
D/Launcher.Utilities( 2058): isPhone= true
D/ForegroundUtils( 2328): Foreground changed, PID: 28354 UID: 10347 foreground: false
D/ForegroundUtils( 2328): Foreground UID/PID combinations:
D/ForegroundUtils( 2328): UID: 10017 PID: 2058
D/PowerSaverService( 2556): current package:com.asus.launcher;activity:com.android.launcher3.Launcher

It may have something to do with the location of the data folder, the app shows that the configuration is stored in /storage/emulated/0/Android/data/org.pacien.tincapp/files but the directory I found and in which the configuration was generated is /storage/emulated/legacy/Android/data/org.pacien.tincapp/files ("0" replaced with "legacy"). There are no tincd logs in the cache directory.

$ adb shell
shell@Z00A:/ $ ls /storage/emulated/                                           
legacy
shell@Z00A:/ $ ls /storage/emulated/0                                          
/storage/emulated/0: No such file or directory

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.