Compare commits

..

11 Commits

Author SHA1 Message Date
Jason A. Donenfeld 9245e9536a Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-27 19:00:38 +02:00
Jason A. Donenfeld 292df12175 Support always-on-vpn
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-27 18:57:52 +02:00
Jason A. Donenfeld f988306c17 libwg-go: Saner way to deal with sockets
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-27 18:17:55 +02:00
Jason A. Donenfeld 64ce6cd5a2 EditorFragment: show toast on creation too
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-27 04:08:23 +02:00
Jason A. Donenfeld 5476fc2228 Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-26 13:56:35 +02:00
Jason A. Donenfeld 7120ef9ffd libwg-go: try no stickiness and no roaming
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-26 03:03:15 +02:00
Jason A. Donenfeld 75f4478fb5 Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-24 19:26:48 +02:00
Jason A. Donenfeld 23c4174fcd libwg-go: reenable sticky sockets, just slightly less sticky
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-24 18:39:29 +02:00
Jason A. Donenfeld 5754df6b71 Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-23 17:12:18 +02:00
Jason A. Donenfeld 62dbeca732 libwg-go: use gopath
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-23 17:01:40 +02:00
Jason A. Donenfeld a533be82e8 libwg-go: No sticky sockets with VPNService.java
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-05-22 23:28:54 +02:00
14 changed files with 129 additions and 46 deletions
+2 -2
View File
@@ -20,8 +20,8 @@ android {
applicationId 'com.wireguard.android'
minSdkVersion 21
targetSdkVersion 27
versionCode 414
versionName '0.0.20180521'
versionCode 418
versionName '0.0.20180527'
}
externalNativeBuild {
cmake {
-3
View File
@@ -62,9 +62,6 @@
<intent-filter>
<action android:name="android.net.VpnService" />
</intent-filter>
<meta-data
android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON"
android:value="false" />
</service>
<service
@@ -11,6 +11,7 @@ import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.wireguard.android.backend.WgQuickBackend;
import com.wireguard.android.model.TunnelManager;
import com.wireguard.android.util.ExceptionLoggers;
@@ -19,13 +20,16 @@ public class BootShutdownReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
if (Application.getComponent().getBackendType() != WgQuickBackend.class) {
return;
}
final String action = intent.getAction();
if (action == null)
return;
final TunnelManager tunnelManager = Application.getComponent().getTunnelManager();
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Log.i(TAG, "Broadcast receiver restoring state (boot)");
tunnelManager.restoreState().whenComplete(ExceptionLoggers.D);
tunnelManager.restoreState(false).whenComplete(ExceptionLoggers.D);
} else if (Intent.ACTION_SHUTDOWN.equals(action)) {
Log.i(TAG, "Broadcast receiver saving state (shutdown)");
tunnelManager.saveState();
@@ -94,9 +94,10 @@ public class SettingsActivity extends AppCompatActivity {
public void onCreatePreferences(final Bundle savedInstanceState, final String key) {
addPreferencesFromResource(R.xml.preferences);
if (Application.getComponent().getBackendType() != WgQuickBackend.class) {
final Preference toolsInstaller =
getPreferenceManager().findPreference("tools_installer");
getPreferenceScreen().removePreference(toolsInstaller);
Preference pref = getPreferenceManager().findPreference("tools_installer");
getPreferenceScreen().removePreference(pref);
pref = getPreferenceManager().findPreference("restore_on_boot");
getPreferenceScreen().removePreference(pref);
}
}
}
@@ -6,6 +6,7 @@
package com.wireguard.android.backend;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.ParcelFileDescriptor;
@@ -13,9 +14,11 @@ import android.support.v4.util.ArraySet;
import android.util.Log;
import com.wireguard.android.Application;
import com.wireguard.android.activity.MainActivity;
import com.wireguard.android.model.Tunnel;
import com.wireguard.android.model.Tunnel.State;
import com.wireguard.android.model.Tunnel.Statistics;
import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.config.Config;
import com.wireguard.config.IPCidr;
import com.wireguard.config.Interface;
@@ -158,6 +161,10 @@ public final class GoBackend implements Backend {
final VpnService.Builder builder = service.getBuilder();
builder.setSession(tunnel.getName());
final Intent configureIntent = new Intent(context, MainActivity.class);
configureIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
builder.setConfigureIntent(PendingIntent.getActivity(context, 0, configureIntent, 0));
for (final IPCidr addr : config.getInterface().getAddresses())
builder.addAddress(addr.getAddress(), addr.getCidr());
@@ -202,6 +209,7 @@ public final class GoBackend implements Backend {
}
private void startVpnService() {
Log.d(TAG, "Requesting to start VpnService");
context.startService(new Intent(context, VpnService.class));
}
@@ -225,5 +233,15 @@ public final class GoBackend implements Backend {
vpnService = vpnService.newIncompleteFuture();
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
vpnService.complete(this);
if (intent == null || intent.getComponent() == null || !intent.getComponent().getPackageName().equals(getPackageName())) {
Log.d(TAG, "Service started by Always-on VPN feature");
Application.getComponent().getTunnelManager().restoreState(true).whenComplete(ExceptionLoggers.D);
}
return super.onStartCommand(intent, flags, startId);
}
}
}
@@ -169,6 +169,7 @@ public class TunnelEditorFragment extends BaseFragment {
tunnel = newTunnel;
message = getString(R.string.tunnel_create_success, tunnel.getName());
Log.d(TAG, message);
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
onFinished();
} else {
final String error = ExceptionLoggers.unwrapMessage(throwable);
@@ -24,6 +24,7 @@ import com.wireguard.android.util.ObservableSortedKeyedArrayList;
import com.wireguard.android.util.ObservableSortedKeyedList;
import com.wireguard.config.Config;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Set;
@@ -55,6 +56,8 @@ public final class TunnelManager extends BaseObservable {
private final ObservableSortedKeyedList<String, Tunnel> tunnels =
new ObservableSortedKeyedArrayList<>(COMPARATOR);
private Tunnel lastUsedTunnel;
private boolean haveLoaded;
private ArrayList<CompletableFuture<Void>> delayedLoadRestoreTunnels = new ArrayList<>();
@Inject
public TunnelManager(final AsyncWorker asyncWorker, final Backend backend,
@@ -140,12 +143,27 @@ public final class TunnelManager extends BaseObservable {
.whenComplete(ExceptionLoggers.E);
}
@SuppressWarnings("unchecked")
private void onTunnelsLoaded(final Iterable<String> present, final Collection<String> running) {
for (final String name : present)
addToList(name, null, running.contains(name) ? State.UP : State.DOWN);
final String lastUsedName = preferences.getString(KEY_LAST_USED_TUNNEL, null);
if (lastUsedName != null)
setLastUsedTunnel(tunnels.get(lastUsedName));
CompletableFuture<Void> toComplete[];
synchronized (delayedLoadRestoreTunnels) {
haveLoaded = true;
toComplete = delayedLoadRestoreTunnels.toArray(new CompletableFuture[delayedLoadRestoreTunnels.size()]);
delayedLoadRestoreTunnels.clear();
}
restoreState(true).whenComplete((v, t) -> {
for (final CompletableFuture<Void> f : toComplete) {
if (t == null)
f.complete(v);
else
f.completeExceptionally(t);
}
});
}
public void refreshTunnelStates() {
@@ -157,9 +175,16 @@ public final class TunnelManager extends BaseObservable {
.whenComplete(ExceptionLoggers.E);
}
public CompletionStage<Void> restoreState() {
if (!preferences.getBoolean(KEY_RESTORE_ON_BOOT, false))
public CompletionStage<Void> restoreState(boolean force) {
if (!force && !preferences.getBoolean(KEY_RESTORE_ON_BOOT, false))
return CompletableFuture.completedFuture(null);
synchronized (delayedLoadRestoreTunnels) {
if (!haveLoaded) {
CompletableFuture<Void> f = new CompletableFuture<>();
delayedLoadRestoreTunnels.add(f);
return f;
}
}
final Set<String> previouslyRunning = preferences.getStringSet(KEY_RUNNING_TUNNELS, null);
if (previouslyRunning == null)
return CompletableFuture.completedFuture(null);
@@ -236,6 +261,7 @@ public final class TunnelManager extends BaseObservable {
tunnel.onStateChanged(e == null ? newState : tunnel.getState());
if (e == null && newState == State.UP)
setLastUsedTunnel(tunnel);
saveState();
});
}
}
+1 -6
View File
@@ -1,7 +1,2 @@
go/
*.go
libwg-go.h
jni.o
gopath/
goroot/
src/
.gobuildversion
+5 -6
View File
@@ -11,7 +11,6 @@ NDK_GO_ARCH_MAP_arm64 := arm64
NDK_GO_ARCH_MAP_mips := mipsx
NDK_GO_ARCH_MAP_mips64 := mips64x
export GOPATH := $(CURDIR)/gopath
CLANG_FLAGS := --target=$(ANDROID_LLVM_TRIPLE) --gcc-toolchain=$(ANDROID_TOOLCHAIN_ROOT) --sysroot=$(ANDROID_SYSROOT)
export CGO_CFLAGS := $(CLANG_FLAGS) $(CFLAGS)
export CGO_LDFLAGS := $(CLANG_FLAGS) $(LDFLAGS)
@@ -48,12 +47,12 @@ endif
$(shell test "$$(cat .gobuildversion 2>/dev/null)" = "$(GOBUILDVERSION_CURRENT)" || rm -f "$(DESTDIR)/libwg-go.so")
$(DESTDIR)/libwg-go.so: $(FILES) api-android.go jni.c
$(DESTDIR)/libwg-go.so: $(FILES) src/git.zx2c4.com/wireguard-go/api-android.go src/git.zx2c4.com/wireguard-go/tun/api-android.go src/git.zx2c4.com/wireguard-go/jni.c
find . -name '*.go' -type l -delete
find . -type d -empty -delete
mkdir -p $(subst ../wireguard-go/,./,$(dir $(FILES)))
$(foreach FILE,$(FILES),ln -sfrt $(subst ../wireguard-go/,./,$(dir $(FILE))) $(FILE);)
mkdir -p $(subst ../wireguard-go/,./src/git.zx2c4.com/wireguard-go/,$(dir $(FILES)))
$(foreach FILE,$(FILES),ln -sfrt $(subst ../wireguard-go/,./src/git.zx2c4.com/wireguard-go/,$(dir $(FILE))) $(FILE);)
patch -p1 -f -R -s --dry-run -d"$$(go env GOROOT)" < goruntime-boottime-over-monotonic.diff
go get -v -d
go build -v -o $(DESTDIR)/libwg-go.so -buildmode c-shared
GOPATH=$(PWD) go get -v -d git.zx2c4.com/wireguard-go
GOPATH=$(PWD) go build -v -o $(DESTDIR)/libwg-go.so -buildmode c-shared git.zx2c4.com/wireguard-go
go version > .gobuildversion
@@ -10,8 +10,8 @@ package main
import "C"
import (
"./rwcancel"
"bufio"
"git.zx2c4.com/wireguard-go/tun"
"golang.org/x/sys/unix"
"io/ioutil"
"log"
@@ -36,6 +36,7 @@ func (l AndroidLogger) Write(p []byte) (int, error) {
var tunnelHandles map[int32]*Device
func init() {
roamingDisabled = true
tunnelHandles = make(map[int32]*Device)
signals := make(chan os.Signal)
signal.Notify(signals, unix.SIGUSR2)
@@ -64,28 +65,16 @@ func wgTurnOn(ifnameRef string, tun_fd int32, settings string) int32 {
logger.Debug.Println("Debug log enabled")
tun := &NativeTun{
fd: os.NewFile(uintptr(tun_fd), "/dev/tun"),
events: make(chan TUNEvent, 5),
errors: make(chan error, 5),
nopi: true,
tun, name, err := tun.CreateTUNFromFD(int(tun_fd))
if err != nil {
unix.Close(int(tun_fd))
logger.Error.Println(err)
return -1
}
var err error
tun.fdCancel, err = rwcancel.NewRWCancel(int(tun_fd))
if err != nil {
unix.Close(int(tun_fd))
logger.Error.Println(err)
return -1
}
name, err := tun.Name()
if err != nil {
unix.Close(int(tun_fd))
logger.Error.Println(err)
return -1
}
logger.Info.Println("Attaching to interface", name)
device := NewDevice(tun, logger)
logger.Debug.Println("Interface has MTU", device.tun.mtu)
bufferedSettings := bufio.NewReadWriter(bufio.NewReader(strings.NewReader(settings)), bufio.NewWriter(ioutil.Discard))
@@ -133,7 +122,18 @@ func wgGetSocketV4(tunnelHandle int32) int32 {
if !ok {
return -1
}
return int32(native.sock4)
fd := int32(-1)
conn, err := native.ipv4.SyscallConn()
if err != nil {
return -1
}
err = conn.Control(func(f uintptr) {
fd = int32(f)
})
if err != nil {
return -1
}
return fd
}
//export wgGetSocketV6
@@ -146,7 +146,18 @@ func wgGetSocketV6(tunnelHandle int32) int32 {
if !ok {
return -1
}
return int32(native.sock6)
fd := int32(-1)
conn, err := native.ipv6.SyscallConn()
if err != nil {
return -1
}
err = conn.Control(func(f uintptr) {
fd = int32(f)
})
if err != nil {
return -1
}
return fd
}
func main() {}
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/
package tun
import (
"git.zx2c4.com/wireguard-go/rwcancel"
"os"
)
func CreateTUNFromFD(tun_fd int) (TUNDevice, string, error) {
tun := &nativeTun{
fd: os.NewFile(uintptr(tun_fd), "/dev/tun"),
events: make(chan TUNEvent, 5),
errors: make(chan error, 5),
nopi: true,
}
var err error
tun.fdCancel, err = rwcancel.NewRWCancel(tun_fd)
if err != nil {
return nil, "", err
}
name, err := tun.Name()
if err != nil {
tun.fdCancel.Cancel()
return nil, "", err
}
return tun, name, nil
}