diff --git a/core/src/main/java/com/github/shadowsocks/JniHelper.java b/core/src/main/java/com/github/shadowsocks/JniHelper.java index 14a8e914..2cc41a34 100755 --- a/core/src/main/java/com/github/shadowsocks/JniHelper.java +++ b/core/src/main/java/com/github/shadowsocks/JniHelper.java @@ -70,5 +70,4 @@ public class JniHelper { private static native Object getExitValueMutex(Process process); public static native int sendFd(int fd, String path); public static native void close(int fd); - public static native void unlink(String path); } diff --git a/core/src/main/jni/jni-helper.cpp b/core/src/main/jni/jni-helper.cpp index 9730879a..6c56cb52 100644 --- a/core/src/main/jni/jni-helper.cpp +++ b/core/src/main/jni/jni-helper.cpp @@ -72,12 +72,6 @@ JNIEXPORT void JNICALL Java_com_github_shadowsocks_JniHelper_close(JNIEnv *env, close(fd); } -JNIEXPORT void JNICALL Java_com_github_shadowsocks_JniHelper_unlink(JNIEnv *env, jobject thiz, jstring path) { - const char *sock_str = env->GetStringUTFChars(path, 0); - unlink(sock_str); - env->ReleaseStringUTFChars(path, sock_str); -} - JNIEXPORT jint JNICALL Java_com_github_shadowsocks_JniHelper_sendFd(JNIEnv *env, jobject thiz, jint tun_fd, jstring path) { int fd; diff --git a/mobile/proguard-rules.pro b/mobile/proguard-rules.pro index 24587743..7639281b 100644 --- a/mobile/proguard-rules.pro +++ b/mobile/proguard-rules.pro @@ -23,8 +23,6 @@ -keepattributes *DatabaseField* -keepattributes *DatabaseTable* -keepattributes *SerializedName* --keepattributes Exceptions, InnerClasses - -keep class com.j256.** -keepclassmembers class com.j256.** { *; } -keep enum com.j256.** diff --git a/mobile/src/main/java/com/github/shadowsocks/bg/LocalSocketListener.kt b/mobile/src/main/java/com/github/shadowsocks/bg/LocalSocketListener.kt index 753d2065..13a60ea9 100644 --- a/mobile/src/main/java/com/github/shadowsocks/bg/LocalSocketListener.kt +++ b/mobile/src/main/java/com/github/shadowsocks/bg/LocalSocketListener.kt @@ -25,75 +25,46 @@ import android.net.LocalSocket import android.net.LocalSocketAddress import android.util.Log import com.github.shadowsocks.App.Companion.app -import com.github.shadowsocks.JniHelper import java.io.File import java.io.IOException import java.util.concurrent.atomic.AtomicReference -abstract class LocalSocketListener(private val tag: String) : Thread() { +abstract class LocalSocketListener(protected val tag: String) : Thread() { init { setUncaughtExceptionHandler(app::track) } protected abstract val socketFile: File - private val localSocket = AtomicReference() + private val serverSocket = AtomicReference() /** * Inherited class do not need to close input/output streams as they will be closed automatically. */ protected abstract fun accept(socket: LocalSocket) override fun run() { - - JniHelper.unlink(socketFile.absolutePath) - Thread.sleep(1000) // trick to close the previous local socket safely - - val serverSocket: LocalServerSocket? = try { - val ls = LocalSocket() - localSocket.set(ls) - ls.bind(LocalSocketAddress(socketFile.absolutePath, LocalSocketAddress.Namespace.FILESYSTEM)) - LocalServerSocket(ls.fileDescriptor) + socketFile.delete() + try { + val localSocket = LocalSocket() + localSocket.bind(LocalSocketAddress(socketFile.absolutePath, LocalSocketAddress.Namespace.FILESYSTEM)) + serverSocket.set(LocalServerSocket(localSocket.fileDescriptor)) } catch (e: IOException) { Log.e(tag, "unable to bind", e) - null + return } - while (true) { + val serverSocket = serverSocket.get() ?: return try { - val socket = serverSocket?.accept() ?: break - - try { - accept(socket) - } catch (e: Exception) { - Log.e(tag, "Error when recv traffic stat", e) - app.track(e) - } - - try { - socket.close() - } catch (e: IOException) { - Log.e(tag, "Error when closing the local socket", e) - app.track(e) - } - + serverSocket.accept() } catch (e: IOException) { Log.e(tag, "Error when accept socket", e) app.track(e) - break - } + null + }?.use(this::accept) } - - try { - serverSocket?.close() - } catch (e: IOException) { - Log.e(tag, "Error when closing socket", e) - app.track(e) - } - - Log.d(tag, "thread exit") } fun stopThread() { - val old = localSocket.getAndSet(null) ?: return + val old = serverSocket.getAndSet(null) ?: return try { old.close() } catch (_: Exception) { } // ignore diff --git a/mobile/src/main/java/com/github/shadowsocks/bg/TrafficMonitorThread.kt b/mobile/src/main/java/com/github/shadowsocks/bg/TrafficMonitorThread.kt index c2dbe42a..b0b1eae4 100644 --- a/mobile/src/main/java/com/github/shadowsocks/bg/TrafficMonitorThread.kt +++ b/mobile/src/main/java/com/github/shadowsocks/bg/TrafficMonitorThread.kt @@ -21,6 +21,7 @@ package com.github.shadowsocks.bg import android.net.LocalSocket +import android.util.Log import com.github.shadowsocks.App.Companion.app import java.io.File import java.io.IOException @@ -31,10 +32,15 @@ class TrafficMonitorThread : LocalSocketListener("TrafficMonitorThread") { override val socketFile = File(app.filesDir, "/stat_path") override fun accept(socket: LocalSocket) { - val buffer = ByteArray(16) - if (socket.inputStream.read(buffer) != 16) throw IOException("Unexpected traffic stat length") - val stat = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN) - TrafficMonitor.update(stat.getLong(0), stat.getLong(8)) - socket.outputStream.write(0) + try { + val buffer = ByteArray(16) + if (socket.inputStream.read(buffer) != 16) throw IOException("Unexpected traffic stat length") + val stat = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN) + TrafficMonitor.update(stat.getLong(0), stat.getLong(8)) + socket.outputStream.write(0) + } catch (e: Exception) { + Log.e(tag, "Error when recv traffic stat", e) + app.track(e) + } } } diff --git a/mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt b/mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt index 93582949..f4381774 100644 --- a/mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt +++ b/mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt @@ -55,13 +55,18 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface { override val socketFile: File = File(filesDir, "protect_path") override fun accept(socket: LocalSocket) { - socket.inputStream.read() - val fds = socket.ancillaryFileDescriptors - if (fds.isEmpty()) return - val fd = getInt.invoke(fds.first()) as Int - val ret = protect(fd) - JniHelper.close(fd) // Trick to close file decriptor - socket.outputStream.write(if (ret) 0 else 1) + try { + socket.inputStream.read() + val fds = socket.ancillaryFileDescriptors + if (fds.isEmpty()) return + val fd = getInt.invoke(fds.first()) as Int + val ret = protect(fd) + JniHelper.close(fd) // Trick to close file decriptor + socket.outputStream.write(if (ret) 0 else 1) + } catch (e: Exception) { + Log.e(tag, "Error when protect socket", e) + app.track(e) + } } } class NullConnectionException : NullPointerException()