From: Tobias Brunner Date: Tue, 3 Jul 2018 13:03:51 +0000 (+0200) Subject: android: Poll dropper TUN device for data on older Android systems X-Git-Tag: 5.7.0dr5~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e905b96dd59c74198c03013ce5b20621cdd6f5a;p=thirdparty%2Fstrongswan.git android: Poll dropper TUN device for data on older Android systems It seems that even the NIO version of read() is uninterruptible on platforms < Android 7 (24). --- diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java index ac22cf5ff2..2777202b59 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java @@ -1012,20 +1012,42 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe FileInputStream plain = new FileInputStream(mFd.getFileDescriptor()); ByteBuffer packet = ByteBuffer.allocate(mCache.mMtu); while (true) - { /* just read and ignore all data, regular read() is not properly interruptible */ - int len = plain.getChannel().read(packet); - packet.clear(); - if (len < 0) - { - break; + { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + { /* just read and ignore all data, regular read() is not interruptible */ + int len = plain.getChannel().read(packet); + packet.clear(); + if (len < 0) + { + break; + } + } + else + { /* this is rather ugly but on older platforms not even the NIO version of read() is interruptible */ + boolean wait = true; + if (plain.available() > 0) + { + int len = plain.read(packet.array()); + packet.clear(); + if (len < 0 || Thread.interrupted()) + { + break; + } + /* check again right away, there may be another packet */ + wait = false; + } + if (wait) + { + Thread.sleep(250); + } } } } - catch (ClosedByInterruptException e) + catch (ClosedByInterruptException|InterruptedException e) { /* regular interruption */ } - catch (Exception e) + catch (IOException e) { e.printStackTrace(); }