Loading packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java +32 −22 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.vpn; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.net.vpn.VpnManager; import android.os.SystemProperties; import android.util.Log; Loading Loading @@ -48,6 +49,9 @@ public class AndroidServiceProxy extends ProcessProxy { private static final int END_OF_ARGUMENTS = 255; private static final int STOP_SERVICE = -1; private static final int AUTH_ERROR_CODE = 51; private String mServiceName; private String mSocketName; private LocalSocket mKeepaliveSocket; Loading @@ -72,14 +76,21 @@ public class AndroidServiceProxy extends ProcessProxy { @Override public synchronized void stop() { if (isRunning()) setResultAndCloseControlSocket(-1); if (isRunning()) { try { setResultAndCloseControlSocket(STOP_SERVICE); } catch (IOException e) { // should not occur throw new RuntimeException(e); } } SystemProperties.set(SVC_STOP_CMD, mServiceName); } /** * Sends a command with arguments to the service through the control socket. */ public void sendCommand(String ...args) throws IOException { public synchronized void sendCommand(String ...args) throws IOException { OutputStream out = getControlSocketOutput(); for (String arg : args) outputString(out, arg); out.write(END_OF_ARGUMENTS); Loading Loading @@ -114,30 +125,22 @@ public class AndroidServiceProxy extends ProcessProxy { InputStream in = s.getInputStream(); int data = in.read(); if (data >= 0) { Log.d(mTag, "got data from keepalive socket: " + data); Log.d(mTag, "got data from control socket: " + data); if (data == 0) { // re-establish the connection: // synchronized here so that checkSocketResult() // returns when new mKeepaliveSocket is available for // next cmd synchronized (this) { setResultAndCloseControlSocket((byte) data); s = mKeepaliveSocket = createServiceSocket(); } } else { // keep the socket setSocketResult(data); } } else { // service is gone if (mControlSocketInUse) setSocketResult(-1); break; } } Log.d(mTag, "keepalive connection closed"); Log.d(mTag, "control connection closed"); } catch (IOException e) { Log.d(mTag, "keepalive socket broken: " + e.getMessage()); if (e instanceof VpnConnectingError) { throw e; } else { Log.d(mTag, "control socket broken: " + e.getMessage()); } } // Wait 5 seconds for the service to exit Loading Loading @@ -179,7 +182,7 @@ public class AndroidServiceProxy extends ProcessProxy { } } private synchronized void checkSocketResult() throws IOException { private void checkSocketResult() throws IOException { try { // will be notified when the result comes back from service if (mSocketResult == null) wait(); Loading @@ -194,14 +197,21 @@ public class AndroidServiceProxy extends ProcessProxy { } } private synchronized void setSocketResult(int result) { private synchronized void setSocketResult(int result) throws VpnConnectingError { if (mControlSocketInUse) { mSocketResult = result; notifyAll(); } else if (result > 0) { // error from daemon throw new VpnConnectingError((result == AUTH_ERROR_CODE) ? VpnManager.VPN_ERROR_AUTH : VpnManager.VPN_ERROR_CONNECTION_FAILED); } } private void setResultAndCloseControlSocket(int result) { private void setResultAndCloseControlSocket(int result) throws VpnConnectingError { setSocketResult(result); try { mKeepaliveSocket.shutdownInput(); Loading packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * 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 java.io.IOException; /** * Exception thrown when a connecting attempt fails. */ class VpnConnectingError extends IOException { private int mErrorCode; VpnConnectingError(int errorCode) { super("Connecting error: " + errorCode); mErrorCode = errorCode; } int getErrorCode() { return mErrorCode; } } packages/VpnServices/src/com/android/server/vpn/VpnService.java +40 −15 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; Loading @@ -46,9 +47,9 @@ abstract class VpnService<E extends VpnProfile> { 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 VPN_STATUS = "vpn.status"; private static final String VPN_IS_UP = "ok"; private static final String VPN_IS_DOWN = "down"; private static final String REMOTE_IP = "net.ipremote"; private static final String DNS_DOMAIN_SUFFICES = "net.dns.search"; Loading @@ -60,6 +61,7 @@ abstract class VpnService<E extends VpnProfile> { private VpnState mState = VpnState.IDLE; private boolean mInError; private VpnConnectingError mError; // connection settings private String mOriginalDns1; Loading Loading @@ -166,8 +168,8 @@ abstract class VpnService<E extends VpnProfile> { return mState; } synchronized void onConnect(String username, String password) throws IOException { synchronized boolean onConnect(String username, String password) { try { mState = VpnState.CONNECTING; broadcastConnectivity(VpnState.CONNECTING); Loading @@ -176,6 +178,13 @@ abstract class VpnService<E extends VpnProfile> { onBeforeConnect(); connect(serverIp, username, password); waitUntilConnectedOrTimedout(); return true; } catch (Throwable e) { Log.e(TAG, "onConnect()", e); mError = newConnectingError(e); onError(); return false; } } synchronized void onDisconnect(boolean cleanUpServices) { Loading Loading @@ -214,8 +223,8 @@ abstract class VpnService<E extends VpnProfile> { SystemProperties.set(VPN_DNS1, "-"); SystemProperties.set(VPN_DNS2, "-"); SystemProperties.set(VPN_UP, VPN_IS_DOWN); Log.d(TAG, " VPN UP: " + SystemProperties.get(VPN_UP)); SystemProperties.set(VPN_STATUS, VPN_IS_DOWN); Log.d(TAG, " VPN UP: " + SystemProperties.get(VPN_STATUS)); } private void waitUntilConnectedOrTimedout() { Loading @@ -224,7 +233,7 @@ abstract class VpnService<E extends VpnProfile> { public void run() { sleep(2000); // 2 seconds for (int i = 0; i < 60; i++) { if (VPN_IS_UP.equals(SystemProperties.get(VPN_UP))) { if (VPN_IS_UP.equals(SystemProperties.get(VPN_STATUS))) { onConnected(); return; } else if (mState != VpnState.CONNECTING) { Loading Loading @@ -271,6 +280,13 @@ abstract class VpnService<E extends VpnProfile> { mContext.stopSelf(); } private VpnConnectingError newConnectingError(Throwable e) { return new VpnConnectingError( (e instanceof UnknownHostException) ? VpnManager.VPN_ERROR_UNKNOWN_SERVER : VpnManager.VPN_ERROR_CONNECTION_FAILED); } private synchronized void onOneServiceGone() { switch (mState) { case IDLE: Loading Loading @@ -347,7 +363,13 @@ abstract class VpnService<E extends VpnProfile> { } private void broadcastConnectivity(VpnState s) { new VpnManager(mContext).broadcastConnectivity(mProfile.getName(), s); VpnManager m = new VpnManager(mContext); if ((s == VpnState.IDLE) && (mError != null)) { m.broadcastConnectivity(mProfile.getName(), s, mError.getErrorCode()); } else { m.broadcastConnectivity(mProfile.getName(), s); } } private void startConnectivityMonitor() { Loading Loading @@ -447,6 +469,9 @@ abstract class VpnService<E extends VpnProfile> { //@Override public void error(ProcessProxy p, Throwable e) { Log.e(TAG, "service error: " + p.getName(), e); if (e instanceof VpnConnectingError) { mError = (VpnConnectingError) e; } commonCallback((AndroidServiceProxy) p); } Loading packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java +7 −10 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.net.vpn.VpnManager; import android.net.vpn.VpnProfile; import android.net.vpn.VpnState; import android.os.IBinder; import android.util.Log; import java.io.IOException; Loading Loading @@ -55,6 +54,11 @@ public class VpnServiceBinder extends Service { } }; public void onStart (Intent intent, int startId) { super.onStart(intent, startId); setForeground(true); } public IBinder onBind(Intent intent) { return mBinder; } Loading @@ -62,15 +66,8 @@ public class VpnServiceBinder extends Service { private synchronized boolean connect( VpnProfile p, String username, String password) { if (mService != null) return false; try { mService = createService(p); mService.onConnect(username, password); return true; } catch (Throwable e) { Log.e(TAG, "connect()", e); if (mService != null) mService.onError(); return false; } return mService.onConnect(username, password); } private synchronized void checkStatus(VpnProfile p) { Loading vpn/java/android/net/vpn/VpnManager.java +20 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,15 @@ public class VpnManager { public static final String BROADCAST_PROFILE_NAME = "profile_name"; /** Key to the connectivity state of a connectivity broadcast event. */ public static final String BROADCAST_CONNECTION_STATE = "connection_state"; /** Key to the error code of a connectivity broadcast event. */ public static final String BROADCAST_ERROR_CODE = "err"; /** Error code to indicate an error from authentication. */ public static final int VPN_ERROR_AUTH = 1; /** Error code to indicate the connection attempt failed. */ public static final int VPN_ERROR_CONNECTION_FAILED = 2; /** Error code to indicate the server is not known. */ public static final int VPN_ERROR_UNKNOWN_SERVER = 3; private static final int VPN_ERROR_NO_ERROR = 0; public static final String PROFILES_PATH = "/data/misc/vpn/profiles"; Loading @@ -52,7 +61,8 @@ public class VpnManager { private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE"; // Action to start VPN settings private static final String ACTION_VPN_SETTINGS = PACKAGE_PREFIX + "SETTINGS"; private static final String ACTION_VPN_SETTINGS = PACKAGE_PREFIX + "SETTINGS"; private static final String TAG = VpnManager.class.getSimpleName(); Loading Loading @@ -130,9 +140,18 @@ public class VpnManager { /** Broadcasts the connectivity state of the specified profile. */ public void broadcastConnectivity(String profileName, VpnState s) { broadcastConnectivity(profileName, s, VPN_ERROR_NO_ERROR); } /** Broadcasts the connectivity state with an error code. */ public void broadcastConnectivity(String profileName, VpnState s, int error) { Intent intent = new Intent(ACTION_VPN_CONNECTIVITY); intent.putExtra(BROADCAST_PROFILE_NAME, profileName); intent.putExtra(BROADCAST_CONNECTION_STATE, s); if (error != VPN_ERROR_NO_ERROR) { intent.putExtra(BROADCAST_ERROR_CODE, error); } mContext.sendBroadcast(intent); } Loading Loading
packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java +32 −22 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.vpn; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.net.vpn.VpnManager; import android.os.SystemProperties; import android.util.Log; Loading Loading @@ -48,6 +49,9 @@ public class AndroidServiceProxy extends ProcessProxy { private static final int END_OF_ARGUMENTS = 255; private static final int STOP_SERVICE = -1; private static final int AUTH_ERROR_CODE = 51; private String mServiceName; private String mSocketName; private LocalSocket mKeepaliveSocket; Loading @@ -72,14 +76,21 @@ public class AndroidServiceProxy extends ProcessProxy { @Override public synchronized void stop() { if (isRunning()) setResultAndCloseControlSocket(-1); if (isRunning()) { try { setResultAndCloseControlSocket(STOP_SERVICE); } catch (IOException e) { // should not occur throw new RuntimeException(e); } } SystemProperties.set(SVC_STOP_CMD, mServiceName); } /** * Sends a command with arguments to the service through the control socket. */ public void sendCommand(String ...args) throws IOException { public synchronized void sendCommand(String ...args) throws IOException { OutputStream out = getControlSocketOutput(); for (String arg : args) outputString(out, arg); out.write(END_OF_ARGUMENTS); Loading Loading @@ -114,30 +125,22 @@ public class AndroidServiceProxy extends ProcessProxy { InputStream in = s.getInputStream(); int data = in.read(); if (data >= 0) { Log.d(mTag, "got data from keepalive socket: " + data); Log.d(mTag, "got data from control socket: " + data); if (data == 0) { // re-establish the connection: // synchronized here so that checkSocketResult() // returns when new mKeepaliveSocket is available for // next cmd synchronized (this) { setResultAndCloseControlSocket((byte) data); s = mKeepaliveSocket = createServiceSocket(); } } else { // keep the socket setSocketResult(data); } } else { // service is gone if (mControlSocketInUse) setSocketResult(-1); break; } } Log.d(mTag, "keepalive connection closed"); Log.d(mTag, "control connection closed"); } catch (IOException e) { Log.d(mTag, "keepalive socket broken: " + e.getMessage()); if (e instanceof VpnConnectingError) { throw e; } else { Log.d(mTag, "control socket broken: " + e.getMessage()); } } // Wait 5 seconds for the service to exit Loading Loading @@ -179,7 +182,7 @@ public class AndroidServiceProxy extends ProcessProxy { } } private synchronized void checkSocketResult() throws IOException { private void checkSocketResult() throws IOException { try { // will be notified when the result comes back from service if (mSocketResult == null) wait(); Loading @@ -194,14 +197,21 @@ public class AndroidServiceProxy extends ProcessProxy { } } private synchronized void setSocketResult(int result) { private synchronized void setSocketResult(int result) throws VpnConnectingError { if (mControlSocketInUse) { mSocketResult = result; notifyAll(); } else if (result > 0) { // error from daemon throw new VpnConnectingError((result == AUTH_ERROR_CODE) ? VpnManager.VPN_ERROR_AUTH : VpnManager.VPN_ERROR_CONNECTION_FAILED); } } private void setResultAndCloseControlSocket(int result) { private void setResultAndCloseControlSocket(int result) throws VpnConnectingError { setSocketResult(result); try { mKeepaliveSocket.shutdownInput(); Loading
packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * 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 java.io.IOException; /** * Exception thrown when a connecting attempt fails. */ class VpnConnectingError extends IOException { private int mErrorCode; VpnConnectingError(int errorCode) { super("Connecting error: " + errorCode); mErrorCode = errorCode; } int getErrorCode() { return mErrorCode; } }
packages/VpnServices/src/com/android/server/vpn/VpnService.java +40 −15 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; Loading @@ -46,9 +47,9 @@ abstract class VpnService<E extends VpnProfile> { 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 VPN_STATUS = "vpn.status"; private static final String VPN_IS_UP = "ok"; private static final String VPN_IS_DOWN = "down"; private static final String REMOTE_IP = "net.ipremote"; private static final String DNS_DOMAIN_SUFFICES = "net.dns.search"; Loading @@ -60,6 +61,7 @@ abstract class VpnService<E extends VpnProfile> { private VpnState mState = VpnState.IDLE; private boolean mInError; private VpnConnectingError mError; // connection settings private String mOriginalDns1; Loading Loading @@ -166,8 +168,8 @@ abstract class VpnService<E extends VpnProfile> { return mState; } synchronized void onConnect(String username, String password) throws IOException { synchronized boolean onConnect(String username, String password) { try { mState = VpnState.CONNECTING; broadcastConnectivity(VpnState.CONNECTING); Loading @@ -176,6 +178,13 @@ abstract class VpnService<E extends VpnProfile> { onBeforeConnect(); connect(serverIp, username, password); waitUntilConnectedOrTimedout(); return true; } catch (Throwable e) { Log.e(TAG, "onConnect()", e); mError = newConnectingError(e); onError(); return false; } } synchronized void onDisconnect(boolean cleanUpServices) { Loading Loading @@ -214,8 +223,8 @@ abstract class VpnService<E extends VpnProfile> { SystemProperties.set(VPN_DNS1, "-"); SystemProperties.set(VPN_DNS2, "-"); SystemProperties.set(VPN_UP, VPN_IS_DOWN); Log.d(TAG, " VPN UP: " + SystemProperties.get(VPN_UP)); SystemProperties.set(VPN_STATUS, VPN_IS_DOWN); Log.d(TAG, " VPN UP: " + SystemProperties.get(VPN_STATUS)); } private void waitUntilConnectedOrTimedout() { Loading @@ -224,7 +233,7 @@ abstract class VpnService<E extends VpnProfile> { public void run() { sleep(2000); // 2 seconds for (int i = 0; i < 60; i++) { if (VPN_IS_UP.equals(SystemProperties.get(VPN_UP))) { if (VPN_IS_UP.equals(SystemProperties.get(VPN_STATUS))) { onConnected(); return; } else if (mState != VpnState.CONNECTING) { Loading Loading @@ -271,6 +280,13 @@ abstract class VpnService<E extends VpnProfile> { mContext.stopSelf(); } private VpnConnectingError newConnectingError(Throwable e) { return new VpnConnectingError( (e instanceof UnknownHostException) ? VpnManager.VPN_ERROR_UNKNOWN_SERVER : VpnManager.VPN_ERROR_CONNECTION_FAILED); } private synchronized void onOneServiceGone() { switch (mState) { case IDLE: Loading Loading @@ -347,7 +363,13 @@ abstract class VpnService<E extends VpnProfile> { } private void broadcastConnectivity(VpnState s) { new VpnManager(mContext).broadcastConnectivity(mProfile.getName(), s); VpnManager m = new VpnManager(mContext); if ((s == VpnState.IDLE) && (mError != null)) { m.broadcastConnectivity(mProfile.getName(), s, mError.getErrorCode()); } else { m.broadcastConnectivity(mProfile.getName(), s); } } private void startConnectivityMonitor() { Loading Loading @@ -447,6 +469,9 @@ abstract class VpnService<E extends VpnProfile> { //@Override public void error(ProcessProxy p, Throwable e) { Log.e(TAG, "service error: " + p.getName(), e); if (e instanceof VpnConnectingError) { mError = (VpnConnectingError) e; } commonCallback((AndroidServiceProxy) p); } Loading
packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java +7 −10 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.net.vpn.VpnManager; import android.net.vpn.VpnProfile; import android.net.vpn.VpnState; import android.os.IBinder; import android.util.Log; import java.io.IOException; Loading Loading @@ -55,6 +54,11 @@ public class VpnServiceBinder extends Service { } }; public void onStart (Intent intent, int startId) { super.onStart(intent, startId); setForeground(true); } public IBinder onBind(Intent intent) { return mBinder; } Loading @@ -62,15 +66,8 @@ public class VpnServiceBinder extends Service { private synchronized boolean connect( VpnProfile p, String username, String password) { if (mService != null) return false; try { mService = createService(p); mService.onConnect(username, password); return true; } catch (Throwable e) { Log.e(TAG, "connect()", e); if (mService != null) mService.onError(); return false; } return mService.onConnect(username, password); } private synchronized void checkStatus(VpnProfile p) { Loading
vpn/java/android/net/vpn/VpnManager.java +20 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,15 @@ public class VpnManager { public static final String BROADCAST_PROFILE_NAME = "profile_name"; /** Key to the connectivity state of a connectivity broadcast event. */ public static final String BROADCAST_CONNECTION_STATE = "connection_state"; /** Key to the error code of a connectivity broadcast event. */ public static final String BROADCAST_ERROR_CODE = "err"; /** Error code to indicate an error from authentication. */ public static final int VPN_ERROR_AUTH = 1; /** Error code to indicate the connection attempt failed. */ public static final int VPN_ERROR_CONNECTION_FAILED = 2; /** Error code to indicate the server is not known. */ public static final int VPN_ERROR_UNKNOWN_SERVER = 3; private static final int VPN_ERROR_NO_ERROR = 0; public static final String PROFILES_PATH = "/data/misc/vpn/profiles"; Loading @@ -52,7 +61,8 @@ public class VpnManager { private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE"; // Action to start VPN settings private static final String ACTION_VPN_SETTINGS = PACKAGE_PREFIX + "SETTINGS"; private static final String ACTION_VPN_SETTINGS = PACKAGE_PREFIX + "SETTINGS"; private static final String TAG = VpnManager.class.getSimpleName(); Loading Loading @@ -130,9 +140,18 @@ public class VpnManager { /** Broadcasts the connectivity state of the specified profile. */ public void broadcastConnectivity(String profileName, VpnState s) { broadcastConnectivity(profileName, s, VPN_ERROR_NO_ERROR); } /** Broadcasts the connectivity state with an error code. */ public void broadcastConnectivity(String profileName, VpnState s, int error) { Intent intent = new Intent(ACTION_VPN_CONNECTIVITY); intent.putExtra(BROADCAST_PROFILE_NAME, profileName); intent.putExtra(BROADCAST_CONNECTION_STATE, s); if (error != VPN_ERROR_NO_ERROR) { intent.putExtra(BROADCAST_ERROR_CODE, error); } mContext.sendBroadcast(intent); } Loading