Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe8e48cd authored by Hung-ying Tyan's avatar Hung-ying Tyan
Browse files

Add state saving mechanism to support proc restart

Also...
+ stop daemons before getting server IP;
+ remove setForeground();
+ add the DBG flag for Log.d calls.

PatchSet 3:
+ add CHALLENGE_ERROR and REMOTE_HUNG_UP to VpnManager
+ broadcast new error codes in VpnService
+ check local IP change instead of dns change
+ move removeStates() to VpnService.onFinalCleanUp()

PatchSet 7:
+ add encryption flag to PptpProfile
+ PptpService and MtpdHelper are revised accordingly
parent b91e2b02
Loading
Loading
Loading
Loading
+16 −16
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;

/**
 * Proxy to start, stop and interact with a VPN daemon.
@@ -33,7 +34,10 @@ import java.io.OutputStream;
 * connection with the daemon, to both send commands to the daemon and receive
 * response and connecting error code from the daemon.
 */
class DaemonProxy {
class DaemonProxy implements Serializable {
    private static final long serialVersionUID = 1L;
    private static final boolean DBG = true;

    private static final int WAITING_TIME = 15; // sec

    private static final String SVC_STATE_CMD_PREFIX = "init.svc.";
@@ -45,8 +49,8 @@ class DaemonProxy {
    private static final int END_OF_ARGUMENTS = 255;

    private String mName;
    private LocalSocket mControlSocket;
    private String mTag;
    private transient LocalSocket mControlSocket;

    /**
     * Creates a proxy of the specified daemon.
@@ -63,14 +67,8 @@ class DaemonProxy {

    void start() throws IOException {
        String svc = mName;
        Log.d(mTag, "-----  Stop the daemon just in case: " + mName);
        SystemProperties.set(SVC_STOP_CMD, mName);
        if (!blockUntil(SVC_STATE_STOPPED, 5)) {
            throw new IOException("cannot start service anew: " + svc
                    + ", it is still running");
        }

        Log.d(mTag, "+++++  Start: " + svc);
        Log.i(mTag, "Start VPN daemon: " + svc);
        SystemProperties.set(SVC_START_CMD, svc);

        if (!blockUntil(SVC_STATE_RUNNING, WAITING_TIME)) {
@@ -103,7 +101,7 @@ class DaemonProxy {
        try {
            mControlSocket.close();
        } catch (IOException e) {
            Log.e(mTag, "close control socket", e);
            Log.w(mTag, "close control socket", e);
        } finally {
            mControlSocket = null;
        }
@@ -111,10 +109,10 @@ class DaemonProxy {

    void stop() {
        String svc = mName;
        Log.d(mTag, "-----  Stop: " + svc);
        Log.i(mTag, "Stop VPN daemon: " + svc);
        SystemProperties.set(SVC_STOP_CMD, svc);
        boolean success = blockUntil(SVC_STATE_STOPPED, 5);
        Log.d(mTag, "stopping " + svc + ", success? " + success);
        if (DBG) Log.d(mTag, "stopping " + svc + ", success? " + success);
    }

    boolean isStopped() {
@@ -129,7 +127,7 @@ class DaemonProxy {
        if (!blocking && in.available() == 0) return 0;

        int data = in.read();
        Log.d(mTag, "got data from control socket: " + data);
        Log.i(mTag, "got data from control socket: " + data);

        return data;
    }
@@ -146,7 +144,7 @@ class DaemonProxy {
                s.connect(a);
                return s;
            } catch (IOException e) {
                Log.d(mTag, "service not yet listen()ing; try again");
                if (DBG) Log.d(mTag, "service not yet listen()ing; try again");
                excp = e;
                sleep(500);
            }
@@ -173,8 +171,10 @@ class DaemonProxy {
        int n = waitTime * 1000 / sleepTime;
        for (int i = 0; i < n; i++) {
            if (expectedState.equals(SystemProperties.get(cmd))) {
                if (DBG) {
                    Log.d(mTag, mName + " is " + expectedState + " after "
                            + (i * sleepTime) + " msec");
                }
                break;
            }
            sleep(sleepTime);
+6 −0
Original line number Diff line number Diff line
@@ -45,4 +45,10 @@ class L2tpIpsecPskService extends VpnService<L2tpIpsecPskProfile> {
                (p.isSecretEnabled() ? p.getSecretString() : null),
                username, password);
    }

    @Override
    protected void stopPreviouslyRunDaemons() {
        stopDaemon(IPSEC);
        stopDaemon(MtpdHelper.MTPD);
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -46,6 +46,12 @@ class L2tpIpsecService extends VpnService<L2tpIpsecProfile> {
                username, password);
    }

    @Override
    protected void stopPreviouslyRunDaemons() {
        stopDaemon(IPSEC);
        stopDaemon(MtpdHelper.MTPD);
    }

    private String getCaCertPath() {
        return CertTool.getInstance().getCaCertificate(
                getProfile().getCaCertificate());
+5 −0
Original line number Diff line number Diff line
@@ -35,4 +35,9 @@ class L2tpService extends VpnService<L2tpProfile> {
                (p.isSecretEnabled() ? p.getSecretString() : null),
                username, password);
    }

    @Override
    protected void stopPreviouslyRunDaemons() {
        stopDaemon(MtpdHelper.MTPD);
    }
}
+15 −5
Original line number Diff line number Diff line
@@ -24,26 +24,33 @@ import java.util.Arrays;
 * A helper class for sending commands to the MTP daemon (mtpd).
 */
class MtpdHelper {
    private static final String MTPD = "mtpd";
    static final String MTPD = "mtpd";
    private static final String VPN_LINKNAME = "vpn";
    private static final String PPP_ARGS_SEPARATOR = "";

    static void sendCommand(VpnService<?> vpnService, String protocol,
            String serverIp, String port, String secret, String username,
            String password) throws IOException {
        sendCommand(vpnService, protocol, serverIp, port, secret, username,
                password, false);
    }

    static void sendCommand(VpnService<?> vpnService, String protocol,
            String serverIp, String port, String secret, String username,
            String password, boolean encryption) throws IOException {
        ArrayList<String> args = new ArrayList<String>();
        args.addAll(Arrays.asList(protocol, serverIp, port));
        if (secret != null) args.add(secret);
        args.add(PPP_ARGS_SEPARATOR);
        addPppArguments(vpnService, args, serverIp, username, password);
        addPppArguments(args, serverIp, username, password, encryption);

        DaemonProxy mtpd = vpnService.startDaemon(MTPD);
        mtpd.sendCommand(args.toArray(new String[args.size()]));
    }

    private static void addPppArguments(VpnService<?> vpnService,
            ArrayList<String> args, String serverIp, String username,
            String password) throws IOException {
    private static void addPppArguments(ArrayList<String> args, String serverIp,
            String username, String password, boolean encryption)
            throws IOException {
        args.addAll(Arrays.asList(
                "linkname", VPN_LINKNAME,
                "name", username,
@@ -52,6 +59,9 @@ class MtpdHelper {
                "idle", "1800",
                "mtu", "1400",
                "mru", "1400"));
        if (encryption) {
            args.add("+mppe");
        }
    }

    private MtpdHelper() {
Loading