예제 #1
0
 @Override
 protected void onHandleIntent(Intent intent) {
   LogUtils.i("ver: " + getMyVersion(this));
   LogUtils.i("rooted: " + ShellUtils.checkRooted());
   if (isVpnRunning()) {
     LogUtils.i("manager is already running in vpn mode");
     sendBroadcast(new LaunchedIntent(true));
     return;
   }
   if (ping(false)) {
     LogUtils.i("manager is already running in root mode");
     sendBroadcast(new LaunchedIntent(false));
     return;
   }
   if (ping(true)) {
     LogUtils.i("Restart manager");
     try {
       ManagerProcess.kill();
       Thread.sleep(1000);
       if (ManagerProcess.exists()) {
         LogUtils.e("failed to restart manager", null);
       } else {
         LaunchService.execute(this);
       }
     } catch (Exception e) {
       handleFatalError(LogUtils.e("failed to stop exiting process", e));
     }
     return;
   }
   deployAndLaunch();
 }
예제 #2
0
 private void passFileDescriptor(LocalSocket fdSocket, FileDescriptor tunFD) throws Exception {
   OutputStream outputStream = fdSocket.getOutputStream();
   InputStream inputStream = fdSocket.getInputStream();
   try {
     BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream), 1);
     String request = reader.readLine();
     String[] parts = request.split(",");
     LogUtils.i("current open tcp sockets: " + tcpSockets.size());
     LogUtils.i("current open udp sockets: " + udpSockets.size());
     if ("TUN".equals(parts[0])) {
       fdSocket.setFileDescriptorsForSend(new FileDescriptor[] {tunFD});
       outputStream.write('*');
     } else if ("OPEN UDP".equals(parts[0])) {
       String socketId = parts[1];
       passUdpFileDescriptor(fdSocket, outputStream, socketId);
     } else if ("OPEN TCP".equals(parts[0])) {
       String socketId = parts[1];
       String dstIp = parts[2];
       int dstPort = Integer.parseInt(parts[3]);
       int connectTimeout = Integer.parseInt(parts[4]);
       passTcpFileDescriptor(fdSocket, outputStream, socketId, dstIp, dstPort, connectTimeout);
     } else if ("CLOSE UDP".equals(parts[0])) {
       String socketId = parts[1];
       DatagramSocket sock = udpSockets.get(socketId);
       if (sock != null) {
         udpSockets.remove(socketId);
         sock.close();
       }
     } else if ("CLOSE TCP".equals(parts[0])) {
       String socketId = parts[1];
       Socket sock = tcpSockets.get(socketId);
       if (sock != null) {
         tcpSockets.remove(socketId);
         sock.close();
       }
     } else {
       throw new UnsupportedOperationException("fdsock unable to handle: " + request);
     }
   } finally {
     try {
       inputStream.close();
     } catch (Exception e) {
       LogUtils.e("failed to close input stream", e);
     }
     try {
       outputStream.close();
     } catch (Exception e) {
       LogUtils.e("failed to close output stream", e);
     }
     fdSocket.close();
   }
 }
예제 #3
0
 private Process executeManager(boolean isVpnMode) throws Exception {
   Map<String, String> env =
       new HashMap<String, String>() {
         {
           put("FQROUTER_VERSION", getMyVersion(LaunchService.this));
         }
       };
   env.putAll(ShellUtils.pythonEnv());
   if (isVpnMode) {
     Process process =
         ShellUtils.executeNoWait(env, ShellUtils.BUSYBOX_FILE.getCanonicalPath(), "sh");
     OutputStreamWriter stdin = new OutputStreamWriter(process.getOutputStream());
     try {
       String command =
           Deployer.PYTHON_LAUNCHER
               + " "
               + Deployer.MANAGER_VPN_PY.getAbsolutePath()
               + " > /data/data/fq.router/log/current-python.log 2>&1";
       LogUtils.i("write to stdin: " + command);
       stdin.write(command);
       stdin.write("\nexit\n");
     } finally {
       stdin.close();
     }
     return process;
   } else {
     try {
       LogUtils.i(
           ShellUtils.sudo(
                   env,
                   Deployer.PYTHON_LAUNCHER
                       + " -c \"import os; print 'current user id: %s' % os.getuid()\"")
               .trim());
     } catch (Exception e) {
       LogUtils.e("log current user id failed", e);
     }
     return ShellUtils.sudoNoWait(
         env,
         Deployer.PYTHON_LAUNCHER
             + " "
             + Deployer.MANAGER_MAIN_PY.getAbsolutePath()
             + " > /data/data/fq.router/log/current-python.log 2>&1");
   }
 }
예제 #4
0
 private void deployAndLaunch() {
   try {
     LogUtils.i("Kill existing manager process");
     LogUtils.i("try to kill manager process before launch");
     ManagerProcess.kill();
   } catch (Exception e) {
     LogUtils.e("failed to kill manager process before launch", e);
     LogUtils.i("failed to kill manager process before launch");
   }
   Deployer deployer = new Deployer(this);
   String fatalError = deployer.deploy();
   if (!fatalError.isEmpty()) {
     handleFatalError(fatalError);
     return;
   }
   updateConfigFile(this);
   LogUtils.i("Launching...");
   if (ShellUtils.checkRooted()) {
     fatalError = launch(false);
     if (fatalError.isEmpty()) {
       sendBroadcast(new LaunchedIntent(false));
     } else {
       handleFatalError(fatalError);
     }
   } else {
     if (Build.VERSION.SDK_INT < 14) {
       handleFatalError("[ROOT] is required");
       return;
     }
     fatalError = launch(true);
     if (fatalError.isEmpty()) {
       sendBroadcast(new LaunchedIntent(true));
     } else {
       handleFatalError(fatalError);
     }
   }
 }
예제 #5
0
 private void startVpn() {
   try {
     if (tunPFD != null) {
       throw new RuntimeException("another VPN is still running");
     }
     tunPFD =
         new Builder()
             .setSession("fqrouter")
             .addAddress("10.25.1.1", 24)
             .addRoute("0.0.0.0", 0)
             .addDnsServer("8.8.8.8")
             .establish();
     if (tunPFD == null) {
       stopSelf();
       return;
     }
     final int tunFD = tunPFD.getFd();
     LogUtils.i("tunFD is " + tunFD);
     new Thread(
             new Runnable() {
               @Override
               public void run() {
                 try {
                   listenFdServerSocket(tunPFD);
                 } catch (Exception e) {
                   LogUtils.e("fdsock failed " + e, e);
                 }
               }
             })
         .start();
     updateStatus("Started in VPN mode");
     sendBroadcast(new LaunchedIntent(true));
   } catch (Exception e) {
     LogUtils.e("establish failed", e);
   }
 }
예제 #6
0
 @Override
 public void onStart(Intent intent, int startId) {
   startVpn();
   LogUtils.i("on start");
 }