Merge change 5616 into donut
* changes: Revise VpnService to use new vpn.* properties.
This commit is contained in:
@@ -78,20 +78,10 @@ public class AndroidServiceProxy extends ProcessProxy {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a command with arguments to the service through the control socket.
|
* Sends a command with arguments to the service through the control socket.
|
||||||
* Each argument is sent as a C-style zero-terminated string.
|
|
||||||
*/
|
*/
|
||||||
public void sendCommand(String ...args) throws IOException {
|
public void sendCommand(String ...args) throws IOException {
|
||||||
OutputStream out = getControlSocketOutput();
|
OutputStream out = getControlSocketOutput();
|
||||||
for (String arg : args) outputString(out, arg);
|
for (String arg : args) outputString(out, arg);
|
||||||
checkSocketResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a command with arguments to the service through the control socket.
|
|
||||||
*/
|
|
||||||
public void sendCommand2(String ...args) throws IOException {
|
|
||||||
OutputStream out = getControlSocketOutput();
|
|
||||||
for (String arg : args) outputString2(out, arg);
|
|
||||||
out.write(END_OF_ARGUMENTS);
|
out.write(END_OF_ARGUMENTS);
|
||||||
out.flush();
|
out.flush();
|
||||||
checkSocketResult();
|
checkSocketResult();
|
||||||
@@ -128,8 +118,9 @@ public class AndroidServiceProxy extends ProcessProxy {
|
|||||||
|
|
||||||
if (data == 0) {
|
if (data == 0) {
|
||||||
// re-establish the connection:
|
// re-establish the connection:
|
||||||
// synchronized here so that checkSocketResult() returns
|
// synchronized here so that checkSocketResult()
|
||||||
// when new mKeepaliveSocket is available for next cmd
|
// returns when new mKeepaliveSocket is available for
|
||||||
|
// next cmd
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
setResultAndCloseControlSocket((byte) data);
|
setResultAndCloseControlSocket((byte) data);
|
||||||
s = mKeepaliveSocket = createServiceSocket();
|
s = mKeepaliveSocket = createServiceSocket();
|
||||||
@@ -244,12 +235,6 @@ public class AndroidServiceProxy extends ProcessProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void outputString(OutputStream out, String s) throws IOException {
|
private void outputString(OutputStream out, String s) throws IOException {
|
||||||
out.write(s.getBytes());
|
|
||||||
out.write(0);
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void outputString2(OutputStream out, String s) throws IOException {
|
|
||||||
byte[] bytes = s.getBytes();
|
byte[] bytes = s.getBytes();
|
||||||
out.write(bytes.length);
|
out.write(bytes.length);
|
||||||
out.write(bytes);
|
out.write(bytes);
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009, The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.server.vpn;
|
||||||
|
|
||||||
|
import android.net.vpn.L2tpIpsecPskProfile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The service that manages the preshared key based L2TP-over-IPSec VPN
|
||||||
|
* connection.
|
||||||
|
*/
|
||||||
|
class L2tpIpsecPskService extends VpnService<L2tpIpsecPskProfile> {
|
||||||
|
private static final String IPSEC_DAEMON = "racoon";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void connect(String serverIp, String username, String password)
|
||||||
|
throws IOException {
|
||||||
|
String hostIp = getHostIp();
|
||||||
|
L2tpIpsecPskProfile p = getProfile();
|
||||||
|
|
||||||
|
// IPSEC
|
||||||
|
AndroidServiceProxy ipsecService = startService(IPSEC_DAEMON);
|
||||||
|
ipsecService.sendCommand(hostIp, serverIp, L2tpService.L2TP_PORT,
|
||||||
|
p.getPresharedKey());
|
||||||
|
|
||||||
|
sleep(2000); // 2 seconds
|
||||||
|
|
||||||
|
// L2TP
|
||||||
|
MtpdHelper.sendCommand(this, L2tpService.L2TP_DAEMON, serverIp,
|
||||||
|
L2tpService.L2TP_PORT,
|
||||||
|
(p.isSecretEnabled() ? p.getSecretString() : null),
|
||||||
|
username, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ import android.security.Keystore;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The service that manages the L2TP-over-IPSec VPN connection.
|
* The service that manages the certificate based L2TP-over-IPSec VPN connection.
|
||||||
*/
|
*/
|
||||||
class L2tpIpsecService extends VpnService<L2tpIpsecProfile> {
|
class L2tpIpsecService extends VpnService<L2tpIpsecProfile> {
|
||||||
private static final String IPSEC_DAEMON = "racoon";
|
private static final String IPSEC_DAEMON = "racoon";
|
||||||
@@ -34,11 +34,10 @@ class L2tpIpsecService extends VpnService<L2tpIpsecProfile> {
|
|||||||
|
|
||||||
// IPSEC
|
// IPSEC
|
||||||
AndroidServiceProxy ipsecService = startService(IPSEC_DAEMON);
|
AndroidServiceProxy ipsecService = startService(IPSEC_DAEMON);
|
||||||
ipsecService.sendCommand(
|
ipsecService.sendCommand(hostIp, serverIp, L2tpService.L2TP_PORT,
|
||||||
String.format("SETKEY %s %s", hostIp, serverIp));
|
getUserkeyPath(), getUserCertPath(), getCaCertPath());
|
||||||
ipsecService.sendCommand(String.format("SET_CERTS %s %s %s %s",
|
|
||||||
serverIp, getCaCertPath(), getUserCertPath(),
|
sleep(2000); // 2 seconds
|
||||||
getUserkeyPath()));
|
|
||||||
|
|
||||||
// L2TP
|
// L2TP
|
||||||
L2tpIpsecProfile p = getProfile();
|
L2tpIpsecProfile p = getProfile();
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class MtpdHelper {
|
|||||||
addPppArguments(vpnService, args, serverIp, username, password);
|
addPppArguments(vpnService, args, serverIp, username, password);
|
||||||
|
|
||||||
AndroidServiceProxy mtpd = vpnService.startService(MTPD_SERVICE);
|
AndroidServiceProxy mtpd = vpnService.startService(MTPD_SERVICE);
|
||||||
mtpd.sendCommand2(args.toArray(new String[args.size()]));
|
mtpd.sendCommand(args.toArray(new String[args.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addPppArguments(VpnService<?> vpnService,
|
private static void addPppArguments(VpnService<?> vpnService,
|
||||||
|
|||||||
@@ -24,14 +24,12 @@ import android.net.NetworkUtils;
|
|||||||
import android.net.vpn.VpnManager;
|
import android.net.vpn.VpnManager;
|
||||||
import android.net.vpn.VpnProfile;
|
import android.net.vpn.VpnProfile;
|
||||||
import android.net.vpn.VpnState;
|
import android.net.vpn.VpnState;
|
||||||
import android.os.FileObserver;
|
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -43,21 +41,18 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
abstract class VpnService<E extends VpnProfile> {
|
abstract class VpnService<E extends VpnProfile> {
|
||||||
private static final int NOTIFICATION_ID = 1;
|
private static final int NOTIFICATION_ID = 1;
|
||||||
private static final String PROFILES_ROOT = VpnManager.PROFILES_PATH + "/";
|
|
||||||
public static final String DEFAULT_CONFIG_PATH = "/etc";
|
|
||||||
|
|
||||||
private static final int DNS_TIMEOUT = 3000; // ms
|
|
||||||
private static final String DNS1 = "net.dns1";
|
private static final String DNS1 = "net.dns1";
|
||||||
private static final String DNS2 = "net.dns2";
|
private static final String DNS2 = "net.dns2";
|
||||||
|
private static final String VPN_DNS1 = "vpn.dns1";
|
||||||
|
private static final String VPN_DNS2 = "vpn.dns2";
|
||||||
|
private static final String VPN_UP = "vpn.up";
|
||||||
|
private static final String VPN_IS_UP = "1";
|
||||||
|
private static final String VPN_IS_DOWN = "0";
|
||||||
|
|
||||||
private static final String REMOTE_IP = "net.ipremote";
|
private static final String REMOTE_IP = "net.ipremote";
|
||||||
private static final String DNS_DOMAIN_SUFFICES = "net.dns.search";
|
private static final String DNS_DOMAIN_SUFFICES = "net.dns.search";
|
||||||
private static final String SERVER_IP = "net.vpn.server_ip";
|
|
||||||
|
|
||||||
private static final int VPN_TIMEOUT = 30000; // milliseconds
|
|
||||||
private static final int ONE_SECOND = 1000; // milliseconds
|
|
||||||
private static final int FIVE_SECOND = 5000; // milliseconds
|
|
||||||
|
|
||||||
private static final String LOGWRAPPER = "/system/bin/logwrapper";
|
|
||||||
private final String TAG = VpnService.class.getSimpleName();
|
private final String TAG = VpnService.class.getSimpleName();
|
||||||
|
|
||||||
E mProfile;
|
E mProfile;
|
||||||
@@ -76,13 +71,6 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
|
|
||||||
private long mStartTime; // VPN connection start time
|
private long mStartTime; // VPN connection start time
|
||||||
|
|
||||||
// monitors if the VPN connection is sucessfully established
|
|
||||||
private FileMonitor mConnectMonitor;
|
|
||||||
|
|
||||||
// watch dog timer; fired up if the connection cannot be established within
|
|
||||||
// VPN_TIMEOUT
|
|
||||||
private Object mWatchdog;
|
|
||||||
|
|
||||||
// for helping managing multiple Android services
|
// for helping managing multiple Android services
|
||||||
private ServiceHelper mServiceHelper = new ServiceHelper();
|
private ServiceHelper mServiceHelper = new ServiceHelper();
|
||||||
|
|
||||||
@@ -110,19 +98,6 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
return mServiceHelper.startService(serviceName);
|
return mServiceHelper.startService(serviceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getPppOptionFilePath() throws IOException {
|
|
||||||
String subpath = getProfileSubpath("/ppp/peers");
|
|
||||||
String[] kids = new File(subpath).list();
|
|
||||||
if ((kids == null) || (kids.length == 0)) {
|
|
||||||
throw new IOException("no option file found in " + subpath);
|
|
||||||
}
|
|
||||||
if (kids.length > 1) {
|
|
||||||
Log.w(TAG, "more than one option file found in " + subpath
|
|
||||||
+ ", arbitrarily choose " + kids[0]);
|
|
||||||
}
|
|
||||||
return subpath + "/" + kids[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the VPN profile associated with the connection.
|
* Returns the VPN profile associated with the connection.
|
||||||
*/
|
*/
|
||||||
@@ -130,23 +105,6 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
return mProfile;
|
return mProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the profile path where configuration files reside.
|
|
||||||
*/
|
|
||||||
protected String getProfilePath() throws IOException {
|
|
||||||
String path = PROFILES_ROOT + mProfile.getId();
|
|
||||||
File dir = new File(path);
|
|
||||||
if (!dir.exists()) throw new IOException("Profile dir does not exist");
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the path where default configuration files reside.
|
|
||||||
*/
|
|
||||||
protected String getDefaultConfigPath() throws IOException {
|
|
||||||
return DEFAULT_CONFIG_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the host IP for establishing the VPN connection.
|
* Returns the host IP for establishing the VPN connection.
|
||||||
*/
|
*/
|
||||||
@@ -177,14 +135,6 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
throw new IOException("Default gateway is not available");
|
throw new IOException("Default gateway is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the path of the script file that is executed when the VPN
|
|
||||||
* connection is established.
|
|
||||||
*/
|
|
||||||
protected String getConnectMonitorFile() {
|
|
||||||
return "/etc/ppp/ip-up-vpn";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the system property. The method is blocked until the value is
|
* Sets the system property. The method is blocked until the value is
|
||||||
* settled in.
|
* settled in.
|
||||||
@@ -222,10 +172,10 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
broadcastConnectivity(VpnState.CONNECTING);
|
broadcastConnectivity(VpnState.CONNECTING);
|
||||||
|
|
||||||
String serverIp = getIp(getProfile().getServerName());
|
String serverIp = getIp(getProfile().getServerName());
|
||||||
setSystemProperty(SERVER_IP, serverIp);
|
|
||||||
onBeforeConnect();
|
|
||||||
|
|
||||||
|
onBeforeConnect();
|
||||||
connect(serverIp, username, password);
|
connect(serverIp, username, password);
|
||||||
|
waitUntilConnectedOrTimedout();
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void onDisconnect(boolean cleanUpServices) {
|
synchronized void onDisconnect(boolean cleanUpServices) {
|
||||||
@@ -259,39 +209,36 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createConnectMonitor() {
|
|
||||||
mConnectMonitor = new FileMonitor(getConnectMonitorFile(),
|
|
||||||
new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
onConnectMonitorTriggered();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onBeforeConnect() {
|
private void onBeforeConnect() {
|
||||||
mNotification.disableNotification();
|
mNotification.disableNotification();
|
||||||
|
|
||||||
createConnectMonitor();
|
SystemProperties.set(VPN_DNS1, "-");
|
||||||
mConnectMonitor.startWatching();
|
SystemProperties.set(VPN_DNS2, "-");
|
||||||
saveOriginalDnsProperties();
|
SystemProperties.set(VPN_UP, VPN_IS_DOWN);
|
||||||
|
Log.d(TAG, " VPN UP: " + SystemProperties.get(VPN_UP));
|
||||||
mWatchdog = startTimer(VPN_TIMEOUT, new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
synchronized (VpnService.this) {
|
|
||||||
if (mState == VpnState.CONNECTING) {
|
|
||||||
Log.d(TAG, " watchdog timer is fired !!");
|
|
||||||
onError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void onConnectMonitorTriggered() {
|
private void waitUntilConnectedOrTimedout() {
|
||||||
Log.d(TAG, "onConnectMonitorTriggered()");
|
sleep(2000); // 2 seconds
|
||||||
|
for (int i = 0; i < 60; i++) {
|
||||||
|
if (VPN_IS_UP.equals(SystemProperties.get(VPN_UP))) {
|
||||||
|
onConnected();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sleep(500); // 0.5 second
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
if (mState == VpnState.CONNECTING) {
|
||||||
|
Log.d(TAG, " connecting timed out !!");
|
||||||
|
onError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void onConnected() {
|
||||||
|
Log.d(TAG, "onConnected()");
|
||||||
|
|
||||||
stopTimer(mWatchdog);
|
|
||||||
mConnectMonitor.stopWatching();
|
|
||||||
saveVpnDnsProperties();
|
saveVpnDnsProperties();
|
||||||
saveAndSetDomainSuffices();
|
saveAndSetDomainSuffices();
|
||||||
startConnectivityMonitor();
|
startConnectivityMonitor();
|
||||||
@@ -310,8 +257,6 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
|
|
||||||
restoreOriginalDnsProperties();
|
restoreOriginalDnsProperties();
|
||||||
restoreOriginalDomainSuffices();
|
restoreOriginalDomainSuffices();
|
||||||
if (mConnectMonitor != null) mConnectMonitor.stopWatching();
|
|
||||||
if (mWatchdog != null) stopTimer(mWatchdog);
|
|
||||||
mState = VpnState.IDLE;
|
mState = VpnState.IDLE;
|
||||||
broadcastConnectivity(VpnState.IDLE);
|
broadcastConnectivity(VpnState.IDLE);
|
||||||
|
|
||||||
@@ -345,13 +290,6 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveOriginalDnsProperties() {
|
|
||||||
mOriginalDns1 = SystemProperties.get(DNS1);
|
|
||||||
mOriginalDns2 = SystemProperties.get(DNS2);
|
|
||||||
Log.d(TAG, String.format("save original dns prop: %s, %s",
|
|
||||||
mOriginalDns1, mOriginalDns2));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void restoreOriginalDnsProperties() {
|
private void restoreOriginalDnsProperties() {
|
||||||
// restore only if they are not overridden
|
// restore only if they are not overridden
|
||||||
if (mVpnDns1.equals(SystemProperties.get(DNS1))) {
|
if (mVpnDns1.equals(SystemProperties.get(DNS1))) {
|
||||||
@@ -365,15 +303,21 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void saveVpnDnsProperties() {
|
private void saveVpnDnsProperties() {
|
||||||
mVpnDns1 = mVpnDns2 = "";
|
mOriginalDns1 = mOriginalDns2 = "";
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
mVpnDns1 = SystemProperties.get(DNS1);
|
mVpnDns1 = SystemProperties.get(VPN_DNS1);
|
||||||
mVpnDns2 = SystemProperties.get(DNS2);
|
mVpnDns2 = SystemProperties.get(VPN_DNS2);
|
||||||
if (mVpnDns1.equals(mOriginalDns1)) {
|
if (mOriginalDns1.equals(mVpnDns1)) {
|
||||||
Log.d(TAG, "wait for vpn dns to settle in..." + i);
|
Log.d(TAG, "wait for vpn dns to settle in..." + i);
|
||||||
sleep(500);
|
sleep(500);
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, String.format("save vpn dns prop: %s, %s",
|
mOriginalDns1 = SystemProperties.get(DNS1);
|
||||||
|
mOriginalDns2 = SystemProperties.get(DNS2);
|
||||||
|
SystemProperties.set(DNS1, mVpnDns1);
|
||||||
|
SystemProperties.set(DNS2, mVpnDns2);
|
||||||
|
Log.d(TAG, String.format("save original dns prop: %s, %s",
|
||||||
|
mOriginalDns1, mOriginalDns2));
|
||||||
|
Log.d(TAG, String.format("set vpn dns prop: %s, %s",
|
||||||
mVpnDns1, mVpnDns2));
|
mVpnDns1, mVpnDns2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -381,23 +325,11 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
Log.e(TAG, "saveVpnDnsProperties(): DNS not updated??");
|
Log.e(TAG, "saveVpnDnsProperties(): DNS not updated??");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restoreVpnDnsProperties() {
|
|
||||||
if (isNullOrEmpty(mVpnDns1) && isNullOrEmpty(mVpnDns2)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Log.d(TAG, String.format("restore vpn dns prop: %s --> %s",
|
|
||||||
SystemProperties.get(DNS1), mVpnDns1));
|
|
||||||
Log.d(TAG, String.format("restore vpn dns prop: %s --> %s",
|
|
||||||
SystemProperties.get(DNS2), mVpnDns2));
|
|
||||||
SystemProperties.set(DNS1, mVpnDns1);
|
|
||||||
SystemProperties.set(DNS2, mVpnDns2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveAndSetDomainSuffices() {
|
private void saveAndSetDomainSuffices() {
|
||||||
mOriginalDomainSuffices = SystemProperties.get(DNS_DOMAIN_SUFFICES);
|
mOriginalDomainSuffices = SystemProperties.get(DNS_DOMAIN_SUFFICES);
|
||||||
Log.d(TAG, "save original dns search: " + mOriginalDomainSuffices);
|
Log.d(TAG, "save original dns search: " + mOriginalDomainSuffices);
|
||||||
String list = mProfile.getDomainSuffices();
|
String list = mProfile.getDomainSuffices();
|
||||||
if (!isNullOrEmpty(list)) {
|
if (!TextUtils.isEmpty(list)) {
|
||||||
SystemProperties.set(DNS_DOMAIN_SUFFICES, list);
|
SystemProperties.set(DNS_DOMAIN_SUFFICES, list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,7 +355,7 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
if (mState != VpnState.CONNECTED) break;
|
if (mState != VpnState.CONNECTED) break;
|
||||||
mNotification.update();
|
mNotification.update();
|
||||||
checkConnectivity();
|
checkConnectivity();
|
||||||
VpnService.this.wait(ONE_SECOND);
|
VpnService.this.wait(1000); // 1 second
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@@ -446,32 +378,6 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object startTimer(final int milliseconds, final Runnable task) {
|
|
||||||
Thread thread = new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
Log.d(TAG, "watchdog timer started");
|
|
||||||
Thread t = Thread.currentThread();
|
|
||||||
try {
|
|
||||||
synchronized (t) {
|
|
||||||
t.wait(milliseconds);
|
|
||||||
}
|
|
||||||
task.run();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
Log.d(TAG, "watchdog timer stopped");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
thread.start();
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopTimer(Object timer) {
|
|
||||||
synchronized (timer) {
|
|
||||||
timer.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String reallyGetHostIp() throws IOException {
|
private String reallyGetHostIp() throws IOException {
|
||||||
Enumeration<NetworkInterface> ifces =
|
Enumeration<NetworkInterface> ifces =
|
||||||
NetworkInterface.getNetworkInterfaces();
|
NetworkInterface.getNetworkInterfaces();
|
||||||
@@ -487,33 +393,13 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
throw new IOException("Host IP is not available");
|
throw new IOException("Host IP is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getProfileSubpath(String subpath) throws IOException {
|
protected void sleep(int ms) {
|
||||||
String path = getProfilePath() + subpath;
|
|
||||||
if (new File(path).exists()) {
|
|
||||||
return path;
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Profile subpath does not exist: " + path
|
|
||||||
+ ", use default one");
|
|
||||||
String path2 = getDefaultConfigPath() + subpath;
|
|
||||||
if (!new File(path2).exists()) {
|
|
||||||
throw new IOException("Profile subpath does not exist at "
|
|
||||||
+ path + " or " + path2);
|
|
||||||
}
|
|
||||||
return path2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sleep(int ms) {
|
|
||||||
try {
|
try {
|
||||||
Thread.currentThread().sleep(ms);
|
Thread.currentThread().sleep(ms);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNullOrEmpty(String message) {
|
|
||||||
return ((message == null) || (message.length() == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
private InetAddress toInetAddress(int addr) throws IOException {
|
private InetAddress toInetAddress(int addr) throws IOException {
|
||||||
byte[] aa = new byte[4];
|
byte[] aa = new byte[4];
|
||||||
for (int i= 0; i < aa.length; i++) {
|
for (int i= 0; i < aa.length; i++) {
|
||||||
@@ -564,20 +450,6 @@ abstract class VpnService<E extends VpnProfile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FileMonitor extends FileObserver {
|
|
||||||
private Runnable mCallback;
|
|
||||||
|
|
||||||
FileMonitor(String path, Runnable callback) {
|
|
||||||
super(path, CLOSE_NOWRITE);
|
|
||||||
mCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEvent(int event, String path) {
|
|
||||||
if ((event & CLOSE_NOWRITE) > 0) mCallback.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper class for showing, updating notification.
|
// Helper class for showing, updating notification.
|
||||||
private class NotificationHelper {
|
private class NotificationHelper {
|
||||||
void update() {
|
void update() {
|
||||||
|
|||||||
Reference in New Issue
Block a user