summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorHung-ying Tyan <tyanh@google.com>2009-06-27 15:59:44 +0800
committerHung-ying Tyan <tyanh@google.com>2009-06-27 16:08:01 +0800
commit2b04d2980aca13c47211e857fc95787122c0fe91 (patch)
tree2786efe89f966303fadb0a063f540ca9bdbd67d7 /packages
parent5c7d9e8194900a2b1699cd57f95b22ca5f7b9be2 (diff)
downloadframeworks_base-2b04d2980aca13c47211e857fc95787122c0fe91.zip
frameworks_base-2b04d2980aca13c47211e857fc95787122c0fe91.tar.gz
frameworks_base-2b04d2980aca13c47211e857fc95787122c0fe91.tar.bz2
Revise VpnService to use new vpn.* properties.
* Changes + Make VpnService get dns info from vpn.dns1/dns2 and set net.dns1/dns2. + Make VpnService wait on vpn.up instead of monitoring on ip-up-vpn. + Change commands sent to racoon. + Remove original sendCommand() from AndroidServiceProxy and rename sendCommand2() to sendCommand(). + Add L2tpIpsecPskService.java. + Add short stop after sending ipsec command.
Diffstat (limited to 'packages')
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java21
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java49
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java11
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java2
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/VpnService.java218
5 files changed, 103 insertions, 198 deletions
diff --git a/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java b/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
index 2ad218f..7dd9d9e 100644
--- a/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
+++ b/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
@@ -78,20 +78,10 @@ public class AndroidServiceProxy extends ProcessProxy {
/**
* 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 {
OutputStream out = getControlSocketOutput();
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.flush();
checkSocketResult();
@@ -128,8 +118,9 @@ public class AndroidServiceProxy extends ProcessProxy {
if (data == 0) {
// re-establish the connection:
- // synchronized here so that checkSocketResult() returns
- // when new mKeepaliveSocket is available for next cmd
+ // synchronized here so that checkSocketResult()
+ // returns when new mKeepaliveSocket is available for
+ // next cmd
synchronized (this) {
setResultAndCloseControlSocket((byte) data);
s = mKeepaliveSocket = createServiceSocket();
@@ -244,12 +235,6 @@ public class AndroidServiceProxy extends ProcessProxy {
}
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();
out.write(bytes.length);
out.write(bytes);
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java
new file mode 100644
index 0000000..6abf81c
--- /dev/null
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java
@@ -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);
+ }
+}
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
index 877fa6b..bd14110 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
@@ -22,7 +22,7 @@ import android.security.Keystore;
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> {
private static final String IPSEC_DAEMON = "racoon";
@@ -34,11 +34,10 @@ class L2tpIpsecService extends VpnService<L2tpIpsecProfile> {
// IPSEC
AndroidServiceProxy ipsecService = startService(IPSEC_DAEMON);
- ipsecService.sendCommand(
- String.format("SETKEY %s %s", hostIp, serverIp));
- ipsecService.sendCommand(String.format("SET_CERTS %s %s %s %s",
- serverIp, getCaCertPath(), getUserCertPath(),
- getUserkeyPath()));
+ ipsecService.sendCommand(hostIp, serverIp, L2tpService.L2TP_PORT,
+ getUserkeyPath(), getUserCertPath(), getCaCertPath());
+
+ sleep(2000); // 2 seconds
// L2TP
L2tpIpsecProfile p = getProfile();
diff --git a/packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java b/packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java
index 6160900..16d253a 100644
--- a/packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java
+++ b/packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java
@@ -38,7 +38,7 @@ class MtpdHelper {
addPppArguments(vpnService, args, serverIp, username, password);
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,
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
index 44127ff..6e5d46b 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
@@ -24,14 +24,12 @@ import android.net.NetworkUtils;
import android.net.vpn.VpnManager;
import android.net.vpn.VpnProfile;
import android.net.vpn.VpnState;
-import android.os.FileObserver;
import android.os.SystemProperties;
+import android.text.TextUtils;
import android.util.Log;
-import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
-import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.util.ArrayList;
@@ -43,21 +41,18 @@ import java.util.List;
*/
abstract class VpnService<E extends VpnProfile> {
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 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 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();
E mProfile;
@@ -76,13 +71,6 @@ abstract class VpnService<E extends VpnProfile> {
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
private ServiceHelper mServiceHelper = new ServiceHelper();
@@ -110,19 +98,6 @@ abstract class VpnService<E extends VpnProfile> {
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.
*/
@@ -131,23 +106,6 @@ abstract class VpnService<E extends VpnProfile> {
}
/**
- * 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.
*/
protected String getHostIp() throws IOException {
@@ -178,14 +136,6 @@ abstract class VpnService<E extends VpnProfile> {
}
/**
- * 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
* settled in.
* @param name the name of the property
@@ -222,10 +172,10 @@ abstract class VpnService<E extends VpnProfile> {
broadcastConnectivity(VpnState.CONNECTING);
String serverIp = getIp(getProfile().getServerName());
- setSystemProperty(SERVER_IP, serverIp);
- onBeforeConnect();
+ onBeforeConnect();
connect(serverIp, username, password);
+ waitUntilConnectedOrTimedout();
}
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() {
mNotification.disableNotification();
- createConnectMonitor();
- mConnectMonitor.startWatching();
- saveOriginalDnsProperties();
+ SystemProperties.set(VPN_DNS1, "-");
+ SystemProperties.set(VPN_DNS2, "-");
+ 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 void waitUntilConnectedOrTimedout() {
+ 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 onConnectMonitorTriggered() {
- Log.d(TAG, "onConnectMonitorTriggered()");
+ private synchronized void onConnected() {
+ Log.d(TAG, "onConnected()");
- stopTimer(mWatchdog);
- mConnectMonitor.stopWatching();
saveVpnDnsProperties();
saveAndSetDomainSuffices();
startConnectivityMonitor();
@@ -310,8 +257,6 @@ abstract class VpnService<E extends VpnProfile> {
restoreOriginalDnsProperties();
restoreOriginalDomainSuffices();
- if (mConnectMonitor != null) mConnectMonitor.stopWatching();
- if (mWatchdog != null) stopTimer(mWatchdog);
mState = 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() {
// restore only if they are not overridden
if (mVpnDns1.equals(SystemProperties.get(DNS1))) {
@@ -365,15 +303,21 @@ abstract class VpnService<E extends VpnProfile> {
}
private void saveVpnDnsProperties() {
- mVpnDns1 = mVpnDns2 = "";
+ mOriginalDns1 = mOriginalDns2 = "";
for (int i = 0; i < 10; i++) {
- mVpnDns1 = SystemProperties.get(DNS1);
- mVpnDns2 = SystemProperties.get(DNS2);
- if (mVpnDns1.equals(mOriginalDns1)) {
+ mVpnDns1 = SystemProperties.get(VPN_DNS1);
+ mVpnDns2 = SystemProperties.get(VPN_DNS2);
+ if (mOriginalDns1.equals(mVpnDns1)) {
Log.d(TAG, "wait for vpn dns to settle in..." + i);
sleep(500);
} 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));
return;
}
@@ -381,23 +325,11 @@ abstract class VpnService<E extends VpnProfile> {
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() {
mOriginalDomainSuffices = SystemProperties.get(DNS_DOMAIN_SUFFICES);
Log.d(TAG, "save original dns search: " + mOriginalDomainSuffices);
String list = mProfile.getDomainSuffices();
- if (!isNullOrEmpty(list)) {
+ if (!TextUtils.isEmpty(list)) {
SystemProperties.set(DNS_DOMAIN_SUFFICES, list);
}
}
@@ -423,7 +355,7 @@ abstract class VpnService<E extends VpnProfile> {
if (mState != VpnState.CONNECTED) break;
mNotification.update();
checkConnectivity();
- VpnService.this.wait(ONE_SECOND);
+ VpnService.this.wait(1000); // 1 second
}
}
} 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 {
Enumeration<NetworkInterface> ifces =
NetworkInterface.getNetworkInterfaces();
@@ -487,33 +393,13 @@ abstract class VpnService<E extends VpnProfile> {
throw new IOException("Host IP is not available");
}
- private String getProfileSubpath(String subpath) throws IOException {
- 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) {
+ protected void sleep(int ms) {
try {
Thread.currentThread().sleep(ms);
} catch (InterruptedException e) {
}
}
- private static boolean isNullOrEmpty(String message) {
- return ((message == null) || (message.length() == 0));
- }
-
private InetAddress toInetAddress(int addr) throws IOException {
byte[] aa = new byte[4];
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.
private class NotificationHelper {
void update() {