From 7ad69e645000fc66951a79104b0ce5ac3478b9f3 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 18 May 2012 00:06:49 +0200 Subject: - Make Ipv6 support complete (minus tun-ipv6 warning) - Implement byte counter support in the log window - Fix spelling of secret (closes issue #22) - Replace "quot; with ", no idea what went wrong there (closes issue #21) --- src/de/blinkt/openvpn/FileSelectionFragment.java | 3 - src/de/blinkt/openvpn/LogWindow.java | 36 ++++++++++- src/de/blinkt/openvpn/OpenVPN.java | 20 ++++++ src/de/blinkt/openvpn/OpenVpnManagementThread.java | 40 +++++++++++- src/de/blinkt/openvpn/Settings_IP.java | 19 +----- src/de/blinkt/openvpn/Settings_Routing.java | 73 ++++++++++++++++++++++ src/de/blinkt/openvpn/VpnProfile.java | 35 ++++++++++- 7 files changed, 198 insertions(+), 28 deletions(-) create mode 100644 src/de/blinkt/openvpn/Settings_Routing.java (limited to 'src/de') diff --git a/src/de/blinkt/openvpn/FileSelectionFragment.java b/src/de/blinkt/openvpn/FileSelectionFragment.java index 41c7a1eb..c030bba0 100644 --- a/src/de/blinkt/openvpn/FileSelectionFragment.java +++ b/src/de/blinkt/openvpn/FileSelectionFragment.java @@ -29,9 +29,6 @@ public class FileSelectionFragment extends ListFragment { private static final String ITEM_KEY = "key"; private static final String ITEM_IMAGE = "image"; private static final String ROOT = "/"; - - - private List path = null; diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java index 3455e385..2e2612d3 100644 --- a/src/de/blinkt/openvpn/LogWindow.java +++ b/src/de/blinkt/openvpn/LogWindow.java @@ -28,8 +28,9 @@ import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import de.blinkt.openvpn.OpenVPN.LogListener; +import de.blinkt.openvpn.OpenVPN.SpeedListener; -public class LogWindow extends ListActivity { +public class LogWindow extends ListActivity implements SpeedListener { private String[] mBconfig=null; @@ -190,6 +191,7 @@ public class LogWindow extends ListActivity { private LogWindowListAdapter ladapter; + private TextView mSpeedView; @Override public boolean onOptionsItemSelected(MenuItem item) { @@ -228,12 +230,23 @@ public class LogWindow extends ListActivity { return true; } + @Override + protected void onResume() { + super.onResume(); + OpenVPN.addSpeedListener(this); + } + @Override + protected void onStop() { + super.onStop(); + OpenVPN.removeSpeedListener(this); + } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.logwindow); ListView lv = getListView(); lv.setOnItemLongClickListener(new OnItemLongClickListener() { @@ -249,12 +262,29 @@ public class LogWindow extends ListActivity { return true; } }); - //lv.setTextFilterEnabled(true); + ladapter = new LogWindowListAdapter(); lv.setAdapter(ladapter); + mSpeedView = (TextView) findViewById(R.id.speed); } - + @Override + public void updateSpeed(final String logmessage) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mSpeedView.setText(logmessage); + } + }); + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + OpenVPN.removeLogListener(ladapter); + } } diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index 24281d13..1d9eb6e0 100644 --- a/src/de/blinkt/openvpn/OpenVPN.java +++ b/src/de/blinkt/openvpn/OpenVPN.java @@ -10,12 +10,16 @@ public class OpenVPN { public static LinkedList logbuffer = new LinkedList(); private static Vector logListener=new Vector(); + private static Vector speedListener=new Vector(); private static String[] mBconfig; public interface LogListener { void newLog(String logmessage); } + public interface SpeedListener { + void updateSpeed(String logmessage); + } synchronized static void logMessage(int level,String prefix, String message) { @@ -41,6 +45,16 @@ public class OpenVPN { logListener.remove(ll); } + + synchronized static void addSpeedListener(SpeedListener sl){ + speedListener.add(sl); + } + + synchronized static void removeSpeedListener(SpeedListener sl) { + speedListener.remove(sl); + } + + synchronized public static String[] getlogbuffer() { @@ -62,4 +76,10 @@ public class OpenVPN { } } + + public static void updateSpeedString(String msg) { + for (SpeedListener sl : speedListener) { + sl.updateSpeed(msg); + } + } } diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java index 753cd98a..b568bd60 100644 --- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java @@ -18,7 +18,10 @@ public class OpenVpnManagementThread implements Runnable { private LocalSocket mSocket; private VpnProfile mProfile; private OpenVpnService mOpenVPNService; - private LinkedList mFDList=new LinkedList(); + private LinkedList mFDList=new LinkedList(); + private int mBytecountinterval=2; + private long mLastIn=0; + private long mLastOut=0; private static Vector active=new Vector(); @@ -157,9 +160,11 @@ public class OpenVpnManagementThread implements Runnable { processPWCommand(argument); } else if (cmd.equals("HOLD")) { managmentCommand("hold release\n"); - //managmentCommand("log on\n"); + managmentCommand("bytecount " + mBytecountinterval + "\n"); } else if (cmd.equals("NEED-OK")) { processNeedCommand(argument); + } else if (cmd.equals("BYTECOUNT")){ + processByteCount(argument); } else if (cmd.equals("LOG")) { String[] args = argument.split(",",3); // 0 unix time stamp @@ -178,6 +183,37 @@ public class OpenVpnManagementThread implements Runnable { } } + private void processByteCount(String argument) { + // >BYTECOUNT:{BYTES_IN},{BYTES_OUT} + int comma = argument.indexOf(','); + long in = Long.parseLong(argument.substring(0, comma)); + long out = Long.parseLong(argument.substring(comma+1)); + + long diffin = in - mLastIn; + long diffout = out - mLastOut; + + mLastIn=in; + mLastOut=out; + + String netstat = String.format("In: %8s, %8s/s Out %8s, %8s/s ", + humanReadableByteCount(in, false), + humanReadableByteCount(diffin, false), + humanReadableByteCount(out, false), + humanReadableByteCount(diffout, false)); + OpenVPN.updateSpeedString(netstat); + + + } + + // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java + public static String humanReadableByteCount(long bytes, boolean si) { + int unit = si ? 1000 : 1024; + if (bytes < unit) return bytes + " B"; + int exp = (int) (Math.log(bytes) / Math.log(unit)); + String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i"); + return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); + } + private void processNeedCommand(String argument) { int p1 =argument.indexOf('\''); int p2 = argument.indexOf('\'',p1+1); diff --git a/src/de/blinkt/openvpn/Settings_IP.java b/src/de/blinkt/openvpn/Settings_IP.java index dcdc10c0..f1e495c8 100644 --- a/src/de/blinkt/openvpn/Settings_IP.java +++ b/src/de/blinkt/openvpn/Settings_IP.java @@ -16,9 +16,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere private EditTextPreference mSearchdomain; private EditTextPreference mDNS1; private EditTextPreference mDNS2; - private EditTextPreference mCustomRoutes; - private CheckBoxPreference mUseDefaultRoute; - private CheckBoxPreference mRouteNoPull; private CheckBoxPreference mNobind; @Override @@ -41,9 +38,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere mSearchdomain =(EditTextPreference) findPreference("searchdomain"); mDNS1 = (EditTextPreference) findPreference("dns1"); mDNS2 = (EditTextPreference) findPreference("dns2"); - mCustomRoutes = (EditTextPreference) findPreference("customRoutes"); - mUseDefaultRoute = (CheckBoxPreference) findPreference("useDefaultRoute"); - mRouteNoPull = (CheckBoxPreference) findPreference("routenopull"); mNobind = (CheckBoxPreference) findPreference("nobind"); mIPv4.setOnPreferenceChangeListener(this); @@ -53,7 +47,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere mUsePull.setOnPreferenceChangeListener(this); mOverrideDNS.setOnPreferenceChangeListener(this); mSearchdomain.setOnPreferenceChangeListener(this); - mCustomRoutes.setOnPreferenceChangeListener(this); loadSettings(); } @@ -68,9 +61,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere mDNS2.setText(mProfile.mDNS2); mOverrideDNS.setChecked(mProfile.mOverrideDNS); mSearchdomain.setText(mProfile.mSearchDomain); - mUseDefaultRoute.setChecked(mProfile.mUseDefaultRoute); - mCustomRoutes.setText(mProfile.mCustomRoutes); - mRouteNoPull.setChecked(mProfile.mRoutenopull); mNobind.setChecked(mProfile.mNobind); // Sets Summary @@ -79,8 +69,7 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere onPreferenceChange(mDNS1, mDNS1.getText()); onPreferenceChange(mDNS2, mDNS2.getText()); onPreferenceChange(mSearchdomain, mSearchdomain.getText()); - onPreferenceChange(mCustomRoutes, mCustomRoutes.getText()); - + setDNSState(); } @@ -94,9 +83,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere mProfile.mDNS2 = mDNS2.getText(); mProfile.mOverrideDNS = mOverrideDNS.isChecked(); mProfile.mSearchDomain = mSearchdomain.getText(); - mProfile.mUseDefaultRoute = mUseDefaultRoute.isChecked(); - mProfile.mCustomRoutes = mCustomRoutes.getText(); - mProfile.mRoutenopull = mRouteNoPull.isChecked(); mProfile.mNobind = mNobind.isChecked(); } @@ -106,7 +92,7 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere Object newValue) { if(preference==mIPv4 || preference == mIPv6 || preference==mDNS1 || preference == mDNS2 - || preference == mSearchdomain || preference == mCustomRoutes + || preference == mSearchdomain ) preference.setSummary((String)newValue); @@ -125,7 +111,6 @@ public class Settings_IP extends OpenVpnPreferencesFragment implements OnPrefere private void setDNSState() { boolean enabled; mOverrideDNS.setEnabled(mUsePull.isChecked()); - mRouteNoPull.setEnabled(mUsePull.isChecked()); if(!mUsePull.isChecked()) enabled =true; else if (mOverrideDNS.isChecked()) diff --git a/src/de/blinkt/openvpn/Settings_Routing.java b/src/de/blinkt/openvpn/Settings_Routing.java new file mode 100644 index 00000000..8305f4db --- /dev/null +++ b/src/de/blinkt/openvpn/Settings_Routing.java @@ -0,0 +1,73 @@ +package de.blinkt.openvpn; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.PreferenceManager; + + +public class Settings_Routing extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { + private EditTextPreference mCustomRoutes; + private CheckBoxPreference mUseDefaultRoute; + private EditTextPreference mCustomRoutesv6; + private CheckBoxPreference mUseDefaultRoutev6; + private CheckBoxPreference mRouteNoPull; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.vpn_routing); + mCustomRoutes = (EditTextPreference) findPreference("customRoutes"); + mUseDefaultRoute = (CheckBoxPreference) findPreference("useDefaultRoute"); + mCustomRoutesv6 = (EditTextPreference) findPreference("customRoutesv6"); + mUseDefaultRoutev6 = (CheckBoxPreference) findPreference("useDefaultRoutev6"); + mRouteNoPull = (CheckBoxPreference) findPreference("routenopull"); + + mCustomRoutes.setOnPreferenceChangeListener(this); + mCustomRoutesv6.setOnPreferenceChangeListener(this); + + loadSettings(); + } + + @Override + protected void loadSettings() { + + mUseDefaultRoute.setChecked(mProfile.mUseDefaultRoute); + mUseDefaultRoutev6.setChecked(mProfile.mUseDefaultRoutev6); + + mCustomRoutes.setText(mProfile.mCustomRoutes); + mCustomRoutesv6.setText(mProfile.mCustomRoutesv6); + + mRouteNoPull.setChecked(mProfile.mRoutenopull); + + // Sets Summary + onPreferenceChange(mCustomRoutes, mCustomRoutes.getText()); + onPreferenceChange(mCustomRoutesv6, mCustomRoutesv6.getText()); + mRouteNoPull.setEnabled(mProfile.mUsePull); + } + + + @Override + protected void saveSettings() { + mProfile.mUseDefaultRoute = mUseDefaultRoute.isChecked(); + mProfile.mUseDefaultRoutev6 = mUseDefaultRoutev6.isChecked(); + mProfile.mCustomRoutes = mCustomRoutes.getText(); + mProfile.mCustomRoutesv6 = mCustomRoutesv6.getText(); + mProfile.mRoutenopull = mRouteNoPull.isChecked(); + } + + @Override + public boolean onPreferenceChange(Preference preference, + Object newValue) { + if( preference == mCustomRoutes || preference == mCustomRoutesv6 ) + preference.setSummary((String)newValue); + + saveSettings(); + return true; + } + + +} \ No newline at end of file diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index a0f6db76..5cdff43d 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -91,6 +91,8 @@ public class VpnProfile implements Serializable{ public String mVerb="1"; public String mCipher=""; public boolean mNobind=false; + public boolean mUseDefaultRoutev6=true; + public String mCustomRoutesv6=""; public void clearDefaults() { @@ -231,7 +233,7 @@ public class VpnProfile implements Serializable{ if(mUseTLSAuth) { if(mAuthenticationType==TYPE_STATICKEYS) - cfg+=insertFileData("scecret",mTLSAuthFilename); + cfg+=insertFileData("secret",mTLSAuthFilename); else cfg+=insertFileData("tls-auth",mTLSAuthFilename); cfg+=" "; @@ -243,9 +245,12 @@ public class VpnProfile implements Serializable{ cfg+="\n"; } - // Basic Settings if(!mUsePull ) { - cfg +="ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n"; + if(nonNull(mIPv4Address)) + cfg +="ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n"; + + if(nonNull(mIPv6Address)) + cfg +="ifconfig-ipv6 " + mIPv6Address + "\n"; } if(mUsePull && mRoutenopull) @@ -258,6 +263,13 @@ public class VpnProfile implements Serializable{ cfg += "route " + route + "\n"; } + + if(mUseDefaultRoutev6) + cfg += "route-ipv6 ::/0\n"; + else + for(String route:getCustomRoutesv6()) { + cfg += "route-ipv6 " + route + "\n"; + } if(mOverrideDNS || !mUsePull) { if(!mDNS1.equals("") && mDNS1!=null) @@ -346,6 +358,23 @@ public class VpnProfile implements Serializable{ return cidrRoutes; } + private Collection getCustomRoutesv6() { + Vector cidrRoutes=new Vector(); + if(mCustomRoutesv6==null) { + // No routes set, return empty vector + return cidrRoutes; + } + for(String route:mCustomRoutesv6.split("[\n \t]")) { + if(!route.equals("")) { + cidrRoutes.add(route); + } + } + + return cidrRoutes; + } + + + private String cidrToIPAndNetmask(String route) { String[] parts = route.split("/"); -- cgit v1.2.3