diff --git a/core/client/jni/jni.go b/core/client/jni/jni.go
new file mode 100644
index 0000000..372a8a3
--- /dev/null
+++ b/core/client/jni/jni.go
@@ -0,0 +1 @@
+package jni
diff --git a/core/client/jni/jni_android.go b/core/client/jni/jni_android.go
new file mode 100644
index 0000000..24f8ed4
--- /dev/null
+++ b/core/client/jni/jni_android.go
@@ -0,0 +1,489 @@
+// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package jni implements various helper functions for communicating with the Android JVM
+// though JNI.
+package jni
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"runtime"
+	"sync"
+	"unicode/utf16"
+	"unsafe"
+)
+
+/*
+#cgo CFLAGS: -Wall
+
+#include <jni.h>
+#include <stdlib.h>
+
+static jint jni_AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args) {
+	return (*vm)->AttachCurrentThread(vm, p_env, thr_args);
+}
+
+static jint jni_DetachCurrentThread(JavaVM *vm) {
+	return (*vm)->DetachCurrentThread(vm);
+}
+
+static jint jni_GetEnv(JavaVM *vm, JNIEnv **env, jint version) {
+	return (*vm)->GetEnv(vm, (void **)env, version);
+}
+
+static jclass jni_FindClass(JNIEnv *env, const char *name) {
+	return (*env)->FindClass(env, name);
+}
+
+static jthrowable jni_ExceptionOccurred(JNIEnv *env) {
+	return (*env)->ExceptionOccurred(env);
+}
+
+static void jni_ExceptionClear(JNIEnv *env) {
+	(*env)->ExceptionClear(env);
+}
+
+static jclass jni_GetObjectClass(JNIEnv *env, jobject obj) {
+	return (*env)->GetObjectClass(env, obj);
+}
+
+static jmethodID jni_GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
+	return (*env)->GetMethodID(env, clazz, name, sig);
+}
+
+static jmethodID jni_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
+	return (*env)->GetStaticMethodID(env, clazz, name, sig);
+}
+
+static jsize jni_GetStringLength(JNIEnv *env, jstring str) {
+	return (*env)->GetStringLength(env, str);
+}
+
+static const jchar *jni_GetStringChars(JNIEnv *env, jstring str) {
+	return (*env)->GetStringChars(env, str, NULL);
+}
+
+static jstring jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len) {
+	return (*env)->NewString(env, unicodeChars, len);
+}
+
+static jboolean jni_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2) {
+	return (*env)->IsSameObject(env, ref1, ref2);
+}
+
+static jobject jni_NewGlobalRef(JNIEnv *env, jobject obj) {
+	return (*env)->NewGlobalRef(env, obj);
+}
+
+static void jni_DeleteGlobalRef(JNIEnv *env, jobject obj) {
+	(*env)->DeleteGlobalRef(env, obj);
+}
+
+static void jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID method, jvalue *args) {
+	(*env)->CallStaticVoidMethodA(env, cls, method, args);
+}
+
+static jint jni_CallStaticIntMethodA(JNIEnv *env, jclass cls, jmethodID method, jvalue *args) {
+	return (*env)->CallStaticIntMethodA(env, cls, method, args);
+}
+
+static jobject jni_CallStaticObjectMethodA(JNIEnv *env, jclass cls, jmethodID method, jvalue *args) {
+	return (*env)->CallStaticObjectMethodA(env, cls, method, args);
+}
+
+static jobject jni_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID method, jvalue *args) {
+	return (*env)->CallObjectMethodA(env, obj, method, args);
+}
+
+static jboolean jni_CallBooleanMethodA(JNIEnv *env, jobject obj, jmethodID method, jvalue *args) {
+	return (*env)->CallBooleanMethodA(env, obj, method, args);
+}
+
+static jint jni_CallIntMethodA(JNIEnv *env, jobject obj, jmethodID method, jvalue *args) {
+	return (*env)->CallIntMethodA(env, obj, method, args);
+}
+
+static void jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID method, jvalue *args) {
+	(*env)->CallVoidMethodA(env, obj, method, args);
+}
+
+static jbyteArray jni_NewByteArray(JNIEnv *env, jsize length) {
+	return (*env)->NewByteArray(env, length);
+}
+
+static jboolean *jni_GetBooleanArrayElements(JNIEnv *env, jbooleanArray arr) {
+	return (*env)->GetBooleanArrayElements(env, arr, NULL);
+}
+
+static void jni_ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray arr, jboolean *elems, jint mode) {
+	(*env)->ReleaseBooleanArrayElements(env, arr, elems, mode);
+}
+
+static jbyte *jni_GetByteArrayElements(JNIEnv *env, jbyteArray arr) {
+	return (*env)->GetByteArrayElements(env, arr, NULL);
+}
+
+static jint *jni_GetIntArrayElements(JNIEnv *env, jintArray arr) {
+	return (*env)->GetIntArrayElements(env, arr, NULL);
+}
+
+static void jni_ReleaseIntArrayElements(JNIEnv *env, jintArray arr, jint *elems, jint mode) {
+	(*env)->ReleaseIntArrayElements(env, arr, elems, mode);
+}
+
+static jlong *jni_GetLongArrayElements(JNIEnv *env, jlongArray arr) {
+	return (*env)->GetLongArrayElements(env, arr, NULL);
+}
+
+static void jni_ReleaseLongArrayElements(JNIEnv *env, jlongArray arr, jlong *elems, jint mode) {
+	(*env)->ReleaseLongArrayElements(env, arr, elems, mode);
+}
+
+static void jni_ReleaseByteArrayElements(JNIEnv *env, jbyteArray arr, jbyte *elems, jint mode) {
+	(*env)->ReleaseByteArrayElements(env, arr, elems, mode);
+}
+
+static jsize jni_GetArrayLength(JNIEnv *env, jarray arr) {
+	return (*env)->GetArrayLength(env, arr);
+}
+
+static void jni_DeleteLocalRef(JNIEnv *env, jobject localRef) {
+	return (*env)->DeleteLocalRef(env, localRef);
+}
+
+static jobject jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index) {
+	return (*env)->GetObjectArrayElement(env, array, index);
+}
+
+static jboolean jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz) {
+	return (*env)->IsInstanceOf(env, obj, clazz);
+}
+*/
+import "C"
+
+type JVM C.JavaVM
+
+type Env C.JNIEnv
+
+type (
+	Class        C.jclass
+	Object       C.jobject
+	MethodID     C.jmethodID
+	String       C.jstring
+	ByteArray    C.jbyteArray
+	ObjectArray  C.jobjectArray
+	BooleanArray C.jbooleanArray
+	LongArray    C.jlongArray
+	IntArray     C.jintArray
+	Boolean      C.jboolean
+	Value        uint64 // All JNI types fit into 64-bits.
+)
+
+// Cached class handles.
+var classes struct {
+	once                      sync.Once
+	stringClass, integerClass Class
+
+	integerIntValue MethodID
+}
+
+func env(e *Env) *C.JNIEnv {
+	return (*C.JNIEnv)(unsafe.Pointer(e))
+}
+
+func javavm(vm *JVM) *C.JavaVM {
+	return (*C.JavaVM)(unsafe.Pointer(vm))
+}
+
+// Do invokes a function with a temporary JVM environment. The
+// environment is not valid after the function returns.
+func Do(vm *JVM, f func(env *Env) error) error {
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+	var env *C.JNIEnv
+	if res := C.jni_GetEnv(javavm(vm), &env, C.JNI_VERSION_1_6); res != C.JNI_OK {
+		if res != C.JNI_EDETACHED {
+			panic(fmt.Errorf("JNI GetEnv failed with error %d", res))
+		}
+		if C.jni_AttachCurrentThread(javavm(vm), &env, nil) != C.JNI_OK {
+			panic(errors.New("runInJVM: AttachCurrentThread failed"))
+		}
+		defer C.jni_DetachCurrentThread(javavm(vm))
+	}
+
+	return f((*Env)(unsafe.Pointer(env)))
+}
+
+func Bool(b bool) Boolean {
+	if b {
+		return C.JNI_TRUE
+	}
+	return C.JNI_FALSE
+}
+
+func varArgs(args []Value) *C.jvalue {
+	if len(args) == 0 {
+		return nil
+	}
+	return (*C.jvalue)(unsafe.Pointer(&args[0]))
+}
+
+func IsSameObject(e *Env, ref1, ref2 Object) bool {
+	same := C.jni_IsSameObject(env(e), C.jobject(ref1), C.jobject(ref2))
+	return same == C.JNI_TRUE
+}
+
+func CallStaticIntMethod(e *Env, cls Class, method MethodID, args ...Value) (int, error) {
+	res := C.jni_CallStaticIntMethodA(env(e), C.jclass(cls), C.jmethodID(method), varArgs(args))
+	return int(res), exception(e)
+}
+
+func CallStaticVoidMethod(e *Env, cls Class, method MethodID, args ...Value) error {
+	C.jni_CallStaticVoidMethodA(env(e), C.jclass(cls), C.jmethodID(method), varArgs(args))
+	return exception(e)
+}
+
+func CallVoidMethod(e *Env, obj Object, method MethodID, args ...Value) error {
+	C.jni_CallVoidMethodA(env(e), C.jobject(obj), C.jmethodID(method), varArgs(args))
+	return exception(e)
+}
+
+func CallStaticObjectMethod(e *Env, cls Class, method MethodID, args ...Value) (Object, error) {
+	res := C.jni_CallStaticObjectMethodA(env(e), C.jclass(cls), C.jmethodID(method), varArgs(args))
+	return Object(res), exception(e)
+}
+
+func CallObjectMethod(e *Env, obj Object, method MethodID, args ...Value) (Object, error) {
+	res := C.jni_CallObjectMethodA(env(e), C.jobject(obj), C.jmethodID(method), varArgs(args))
+	return Object(res), exception(e)
+}
+
+func CallBooleanMethod(e *Env, obj Object, method MethodID, args ...Value) (bool, error) {
+	res := C.jni_CallBooleanMethodA(env(e), C.jobject(obj), C.jmethodID(method), varArgs(args))
+	return res == C.JNI_TRUE, exception(e)
+}
+
+func CallIntMethod(e *Env, obj Object, method MethodID, args ...Value) (int32, error) {
+	res := C.jni_CallIntMethodA(env(e), C.jobject(obj), C.jmethodID(method), varArgs(args))
+	return int32(res), exception(e)
+}
+
+// GetByteArrayElements returns the contents of the byte array.
+func GetByteArrayElements(e *Env, jarr ByteArray) []byte {
+	if jarr == 0 {
+		return nil
+	}
+	size := C.jni_GetArrayLength(env(e), C.jarray(jarr))
+	elems := C.jni_GetByteArrayElements(env(e), C.jbyteArray(jarr))
+	defer C.jni_ReleaseByteArrayElements(env(e), C.jbyteArray(jarr), elems, 0)
+	backing := (*(*[1 << 30]byte)(unsafe.Pointer(elems)))[:size:size]
+	s := make([]byte, len(backing))
+	copy(s, backing)
+	return s
+}
+
+// GetBooleanArrayElements returns the contents of the boolean array.
+func GetBooleanArrayElements(e *Env, jarr BooleanArray) []bool {
+	if jarr == 0 {
+		return nil
+	}
+	size := C.jni_GetArrayLength(env(e), C.jarray(jarr))
+	elems := C.jni_GetBooleanArrayElements(env(e), C.jbooleanArray(jarr))
+	defer C.jni_ReleaseBooleanArrayElements(env(e), C.jbooleanArray(jarr), elems, 0)
+	backing := (*(*[1 << 30]C.jboolean)(unsafe.Pointer(elems)))[:size:size]
+	r := make([]bool, len(backing))
+	for i, b := range backing {
+		r[i] = b == C.JNI_TRUE
+	}
+	return r
+}
+
+// GetStringArrayElements returns the contents of the String array.
+func GetStringArrayElements(e *Env, jarr ObjectArray) []string {
+	var strings []string
+	iterateObjectArray(e, jarr, func(e *Env, idx int, item Object) {
+		s := GoString(e, String(item))
+		strings = append(strings, s)
+	})
+	return strings
+}
+
+// GetIntArrayElements returns the contents of the int array.
+func GetIntArrayElements(e *Env, jarr IntArray) []int {
+	if jarr == 0 {
+		return nil
+	}
+	size := C.jni_GetArrayLength(env(e), C.jarray(jarr))
+	elems := C.jni_GetIntArrayElements(env(e), C.jintArray(jarr))
+	defer C.jni_ReleaseIntArrayElements(env(e), C.jintArray(jarr), elems, 0)
+	backing := (*(*[1 << 27]C.jint)(unsafe.Pointer(elems)))[:size:size]
+	r := make([]int, len(backing))
+	for i, l := range backing {
+		r[i] = int(l)
+	}
+	return r
+}
+
+// GetLongArrayElements returns the contents of the long array.
+func GetLongArrayElements(e *Env, jarr LongArray) []int64 {
+	if jarr == 0 {
+		return nil
+	}
+	size := C.jni_GetArrayLength(env(e), C.jarray(jarr))
+	elems := C.jni_GetLongArrayElements(env(e), C.jlongArray(jarr))
+	defer C.jni_ReleaseLongArrayElements(env(e), C.jlongArray(jarr), elems, 0)
+	backing := (*(*[1 << 27]C.jlong)(unsafe.Pointer(elems)))[:size:size]
+	r := make([]int64, len(backing))
+	for i, l := range backing {
+		r[i] = int64(l)
+	}
+	return r
+}
+
+func iterateObjectArray(e *Env, jarr ObjectArray, f func(e *Env, idx int, item Object)) {
+	if jarr == 0 {
+		return
+	}
+	size := C.jni_GetArrayLength(env(e), C.jarray(jarr))
+	for i := 0; i < int(size); i++ {
+		item := C.jni_GetObjectArrayElement(env(e), C.jobjectArray(jarr), C.jint(i))
+		f(e, i, Object(item))
+		C.jni_DeleteLocalRef(env(e), item)
+	}
+}
+
+// NewByteArray allocates a Java byte array with the content. It
+// panics if the allocation fails.
+func NewByteArray(e *Env, content []byte) ByteArray {
+	jarr := C.jni_NewByteArray(env(e), C.jsize(len(content)))
+	if jarr == 0 {
+		panic(fmt.Errorf("jni: NewByteArray(%d) failed", len(content)))
+	}
+	elems := C.jni_GetByteArrayElements(env(e), jarr)
+	defer C.jni_ReleaseByteArrayElements(env(e), jarr, elems, 0)
+	backing := (*(*[1 << 30]byte)(unsafe.Pointer(elems)))[:len(content):len(content)]
+	copy(backing, content)
+	return ByteArray(jarr)
+}
+
+// ClassLoader returns a reference to the Java ClassLoader associated
+// with obj.
+func ClassLoaderFor(e *Env, obj Object) Object {
+	cls := GetObjectClass(e, obj)
+	getClassLoader := GetMethodID(e, cls, "getClassLoader", "()Ljava/lang/ClassLoader;")
+	clsLoader, err := CallObjectMethod(e, Object(obj), getClassLoader)
+	if err != nil {
+		// Class.getClassLoader should never fail.
+		panic(err)
+	}
+	return Object(clsLoader)
+}
+
+// LoadClass invokes the underlying ClassLoader's loadClass method and
+// returns the class.
+func LoadClass(e *Env, loader Object, class string) (Class, error) {
+	cls := GetObjectClass(e, loader)
+	loadClass := GetMethodID(e, cls, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;")
+	name := JavaString(e, class)
+	loaded, err := CallObjectMethod(e, loader, loadClass, Value(name))
+	if err != nil {
+		return 0, err
+	}
+	return Class(loaded), exception(e)
+}
+
+// exception returns an error corresponding to the pending
+// exception, and clears it. exceptionError returns nil if no
+// exception is pending.
+func exception(e *Env) error {
+	thr := C.jni_ExceptionOccurred(env(e))
+	if thr == 0 {
+		return nil
+	}
+	C.jni_ExceptionClear(env(e))
+	cls := GetObjectClass(e, Object(thr))
+	toString := GetMethodID(e, cls, "toString", "()Ljava/lang/String;")
+	msg, err := CallObjectMethod(e, Object(thr), toString)
+	if err != nil {
+		return err
+	}
+	return errors.New(GoString(e, String(msg)))
+}
+
+// GetObjectClass returns the Java Class for an Object.
+func GetObjectClass(e *Env, obj Object) Class {
+	if obj == 0 {
+		panic("null object")
+	}
+	cls := C.jni_GetObjectClass(env(e), C.jobject(obj))
+	if err := exception(e); err != nil {
+		// GetObjectClass should never fail.
+		panic(err)
+	}
+	return Class(cls)
+}
+
+// GetStaticMethodID returns the id for a static method. It panics if the method
+// wasn't found.
+func GetStaticMethodID(e *Env, cls Class, name, signature string) MethodID {
+	mname := C.CString(name)
+	defer C.free(unsafe.Pointer(mname))
+	msig := C.CString(signature)
+	defer C.free(unsafe.Pointer(msig))
+	m := C.jni_GetStaticMethodID(env(e), C.jclass(cls), mname, msig)
+	if err := exception(e); err != nil {
+		panic(err)
+	}
+	return MethodID(m)
+}
+
+// GetMethodID returns the id for a method. It panics if the method
+// wasn't found.
+func GetMethodID(e *Env, cls Class, name, signature string) MethodID {
+	mname := C.CString(name)
+	defer C.free(unsafe.Pointer(mname))
+	msig := C.CString(signature)
+	defer C.free(unsafe.Pointer(msig))
+	m := C.jni_GetMethodID(env(e), C.jclass(cls), mname, msig)
+	if err := exception(e); err != nil {
+		panic(err)
+	}
+	return MethodID(m)
+}
+
+func NewGlobalRef(e *Env, obj Object) Object {
+	return Object(C.jni_NewGlobalRef(env(e), C.jobject(obj)))
+}
+
+func DeleteGlobalRef(e *Env, obj Object) {
+	C.jni_DeleteGlobalRef(env(e), C.jobject(obj))
+}
+
+// JavaString converts the string to a JVM jstring.
+func JavaString(e *Env, str string) String {
+	if str == "" {
+		return 0
+	}
+	utf16Chars := utf16.Encode([]rune(str))
+	res := C.jni_NewString(env(e), (*C.jchar)(unsafe.Pointer(&utf16Chars[0])), C.int(len(utf16Chars)))
+	return String(res)
+}
+
+// GoString converts the JVM jstring to a Go string.
+func GoString(e *Env, str String) string {
+	if str == 0 {
+		return ""
+	}
+	strlen := C.jni_GetStringLength(env(e), C.jstring(str))
+	chars := C.jni_GetStringChars(env(e), C.jstring(str))
+	var utf16Chars []uint16
+	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&utf16Chars))
+	hdr.Data = uintptr(unsafe.Pointer(chars))
+	hdr.Cap = int(strlen)
+	hdr.Len = int(strlen)
+	utf8 := utf16.Decode(utf16Chars)
+	return string(utf8)
+}
