From 670dd1be40e94873543319fd57b33d4911c71d98 Mon Sep 17 00:00:00 2001 From: Yuheng Zhang Date: Wed, 1 Jul 2026 18:38:16 +0000 Subject: [PATCH 1/3] Fix UDPInput thread death, TCPOutput double-free, and compile warnings --- .idea/AndroidProjectSystem.xml | 6 + .idea/caches/deviceStreaming.xml | 1990 +++++++++++++++++ .idea/deploymentTargetSelector.xml | 11 + .idea/markdown.xml | 8 + .idea/runConfigurations.xml | 17 + .../java/xyz/hexene/localvpn/LRUCache.java | 9 +- .../main/java/xyz/hexene/localvpn/Packet.java | 2 +- .../java/xyz/hexene/localvpn/TCPOutput.java | 7 +- .../java/xyz/hexene/localvpn/UDPInput.java | 12 +- .../java/xyz/hexene/localvpn/UDPOutput.java | 5 +- 10 files changed, 2050 insertions(+), 17 deletions(-) create mode 100644 .idea/AndroidProjectSystem.xml create mode 100644 .idea/caches/deviceStreaming.xml create mode 100644 .idea/deploymentTargetSelector.xml create mode 100644 .idea/markdown.xml create mode 100644 .idea/runConfigurations.xml diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml new file mode 100644 index 0000000..a4536a2 --- /dev/null +++ b/.idea/caches/deviceStreaming.xml @@ -0,0 +1,1990 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..ca16a99 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/markdown.xml b/.idea/markdown.xml new file mode 100644 index 0000000..c61ea33 --- /dev/null +++ b/.idea/markdown.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/xyz/hexene/localvpn/LRUCache.java b/app/src/main/java/xyz/hexene/localvpn/LRUCache.java index d3be080..a42da6f 100644 --- a/app/src/main/java/xyz/hexene/localvpn/LRUCache.java +++ b/app/src/main/java/xyz/hexene/localvpn/LRUCache.java @@ -18,15 +18,12 @@ import java.util.LinkedHashMap; -public class LRUCache extends LinkedHashMap -{ +public class LRUCache extends LinkedHashMap { private int maxSize; - private CleanupCallback callback; + private CleanupCallback callback; - public LRUCache(int maxSize, CleanupCallback callback) - { + public LRUCache(int maxSize, CleanupCallback callback) { super(maxSize + 1, 1, true); - this.maxSize = maxSize; this.callback = callback; } diff --git a/app/src/main/java/xyz/hexene/localvpn/Packet.java b/app/src/main/java/xyz/hexene/localvpn/Packet.java index cfd38eb..33b57ba 100644 --- a/app/src/main/java/xyz/hexene/localvpn/Packet.java +++ b/app/src/main/java/xyz/hexene/localvpn/Packet.java @@ -236,7 +236,7 @@ private enum TransportProtocol UDP(17), Other(0xFF); - private int protocolNumber; + private final int protocolNumber; TransportProtocol(int protocolNumber) { diff --git a/app/src/main/java/xyz/hexene/localvpn/TCPOutput.java b/app/src/main/java/xyz/hexene/localvpn/TCPOutput.java index 5e8615c..3293ca7 100644 --- a/app/src/main/java/xyz/hexene/localvpn/TCPOutput.java +++ b/app/src/main/java/xyz/hexene/localvpn/TCPOutput.java @@ -35,14 +35,13 @@ public class TCPOutput implements Runnable { private static final String TAG = TCPOutput.class.getSimpleName(); - private LocalVPNService vpnService; + private android.net.VpnService vpnService; private ConcurrentLinkedQueue inputQueue; private ConcurrentLinkedQueue outputQueue; private Selector selector; private Random random = new Random(); - public TCPOutput(ConcurrentLinkedQueue inputQueue, ConcurrentLinkedQueue outputQueue, - Selector selector, LocalVPNService vpnService) + public TCPOutput(ConcurrentLinkedQueue inputQueue, Selector selector, android.net.VpnService vpnService) { this.inputQueue = inputQueue; this.outputQueue = outputQueue; @@ -266,7 +265,7 @@ private void sendRST(TCB tcb, int prevPayloadSize, ByteBuffer buffer) private void closeCleanly(TCB tcb, ByteBuffer buffer) { - ByteBufferPool.release(buffer); + // ByteBufferPool.release(buffer); // Commented out to prevent double-free corruption TCB.closeTCB(tcb); } } diff --git a/app/src/main/java/xyz/hexene/localvpn/UDPInput.java b/app/src/main/java/xyz/hexene/localvpn/UDPInput.java index 7108030..a4dfaca 100644 --- a/app/src/main/java/xyz/hexene/localvpn/UDPInput.java +++ b/app/src/main/java/xyz/hexene/localvpn/UDPInput.java @@ -71,9 +71,15 @@ public void run() receiveBuffer.position(HEADER_SIZE); DatagramChannel inputChannel = (DatagramChannel) key.channel(); - // XXX: We should handle any IOExceptions here immediately, - // but that probably won't happen with UDP - int readBytes = inputChannel.read(receiveBuffer); + int readBytes; + try { + readBytes = inputChannel.read(receiveBuffer); + } catch (IOException e) { + Log.e(TAG, "UDP read error", e); + key.cancel(); + ByteBufferPool.release(receiveBuffer); + continue; // Prevent thread death, skip to next packet + } Packet referencePacket = (Packet) key.attachment(); referencePacket.updateUDPBuffer(receiveBuffer, readBytes); diff --git a/app/src/main/java/xyz/hexene/localvpn/UDPOutput.java b/app/src/main/java/xyz/hexene/localvpn/UDPOutput.java index 0a48273..fbe7236 100644 --- a/app/src/main/java/xyz/hexene/localvpn/UDPOutput.java +++ b/app/src/main/java/xyz/hexene/localvpn/UDPOutput.java @@ -33,7 +33,7 @@ public class UDPOutput implements Runnable { private static final String TAG = UDPOutput.class.getSimpleName(); - private LocalVPNService vpnService; + private android.net.VpnService vpnService; private ConcurrentLinkedQueue inputQueue; private Selector selector; @@ -48,8 +48,7 @@ public void cleanup(Map.Entry eldest) } }); - public UDPOutput(ConcurrentLinkedQueue inputQueue, Selector selector, LocalVPNService vpnService) - { + public UDPOutput(ConcurrentLinkedQueue inputQueue, Selector selector, android.net.VpnService vpnService) { this.inputQueue = inputQueue; this.selector = selector; this.vpnService = vpnService; From 7a92a3dc7e9245f25dec770f13a1964859b1f9ac Mon Sep 17 00:00:00 2001 From: Yuheng Zhang Date: Wed, 1 Jul 2026 20:01:01 +0000 Subject: [PATCH 2/3] Remove only the specific local Android Studio cache files --- .idea/AndroidProjectSystem.xml | 6 - .idea/caches/deviceStreaming.xml | 1990 ---------------------------- .idea/deploymentTargetSelector.xml | 11 - .idea/markdown.xml | 8 - .idea/runConfigurations.xml | 17 - 5 files changed, 2032 deletions(-) delete mode 100644 .idea/AndroidProjectSystem.xml delete mode 100644 .idea/caches/deviceStreaming.xml delete mode 100644 .idea/deploymentTargetSelector.xml delete mode 100644 .idea/markdown.xml delete mode 100644 .idea/runConfigurations.xml diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml deleted file mode 100644 index 4a53bee..0000000 --- a/.idea/AndroidProjectSystem.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/caches/deviceStreaming.xml b/.idea/caches/deviceStreaming.xml deleted file mode 100644 index a4536a2..0000000 --- a/.idea/caches/deviceStreaming.xml +++ /dev/null @@ -1,1990 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml deleted file mode 100644 index ca16a99..0000000 --- a/.idea/deploymentTargetSelector.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/markdown.xml b/.idea/markdown.xml deleted file mode 100644 index c61ea33..0000000 --- a/.idea/markdown.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 16660f1..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - \ No newline at end of file From 9e987b86d03a654219be05fc052d2b44ac920d96 Mon Sep 17 00:00:00 2001 From: Yuheng Zhang Date: Wed, 1 Jul 2026 20:11:56 +0000 Subject: [PATCH 3/3] revert deletion of outputQueue in constructor --- app/src/main/java/xyz/hexene/localvpn/TCPOutput.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/xyz/hexene/localvpn/TCPOutput.java b/app/src/main/java/xyz/hexene/localvpn/TCPOutput.java index 3293ca7..6f48ede 100644 --- a/app/src/main/java/xyz/hexene/localvpn/TCPOutput.java +++ b/app/src/main/java/xyz/hexene/localvpn/TCPOutput.java @@ -41,8 +41,11 @@ public class TCPOutput implements Runnable private Selector selector; private Random random = new Random(); - public TCPOutput(ConcurrentLinkedQueue inputQueue, Selector selector, android.net.VpnService vpnService) - { + public TCPOutput( + ConcurrentLinkedQueue inputQueue, + ConcurrentLinkedQueue outputQueue, + Selector selector, + android.net.VpnService vpnService) { this.inputQueue = inputQueue; this.outputQueue = outputQueue; this.selector = selector;