Zond: убийство процесса через системный вызов
This commit is contained in:
@@ -45,4 +45,6 @@ dependencies {
|
|||||||
includedEx group: 'org.apache.commons', name: 'commons-exec', version: '1.3'
|
includedEx group: 'org.apache.commons', name: 'commons-exec', version: '1.3'
|
||||||
included group: 'io.netty', name: 'netty-codec', version: nettyVersion
|
included group: 'io.netty', name: 'netty-codec', version: nettyVersion
|
||||||
included group: 'com.google.guava', name: 'guava', version: '21.0'
|
included group: 'com.google.guava', name: 'guava', version: '21.0'
|
||||||
|
included group: 'com.sun.jna', name: 'jna', version: '3.0.9'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package asys.zond;
|
package asys.zond;
|
||||||
|
|
||||||
|
import asys.zond.shell.Shell;
|
||||||
|
|
||||||
public class PingMonitor {
|
public class PingMonitor {
|
||||||
private static final long STEP_PING = 5000;
|
private static final long STEP_PING = 5000;
|
||||||
private final long delayStart;
|
private final long delayStart;
|
||||||
@@ -22,10 +24,17 @@ public class PingMonitor {
|
|||||||
|
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
long currentTimeMillis = System.currentTimeMillis();
|
long currentTimeMillis = System.currentTimeMillis();
|
||||||
if ((currentTimeMillis - lastPingTime) >= (2*STEP_PING)) { // если пропущено два пинга
|
if ((currentTimeMillis - lastPingTime) >= (1*STEP_PING)) {
|
||||||
|
Shell.getInstance().getOutput().println("[D] lost one ping....");
|
||||||
|
}
|
||||||
|
else if ((currentTimeMillis - lastPingTime) >= (2*STEP_PING)) { // если пропущено два пинга
|
||||||
|
Shell.getInstance().getOutput().println("[D] lost two ping....");
|
||||||
callback.run(); // запускаем код завершения процесса
|
callback.run(); // запускаем код завершения процесса
|
||||||
return; // завершаем поток
|
return; // завершаем поток
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Shell.getInstance().getOutput().println("[D] check ping");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(STEP_PING);
|
Thread.sleep(STEP_PING);
|
||||||
|
|||||||
@@ -74,7 +74,12 @@ public class ZondCommandHandler implements CommandHandler {
|
|||||||
private void startProcess() {
|
private void startProcess() {
|
||||||
if (watchdog == null || !watchdog.isWatching()) {
|
if (watchdog == null || !watchdog.isWatching()) {
|
||||||
if (watchdog == null) {
|
if (watchdog == null) {
|
||||||
watchdog = new ZondExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT, proxyStdIn);
|
watchdog = new ZondExecuteWatchdog(
|
||||||
|
ExecuteWatchdog.INFINITE_TIMEOUT,
|
||||||
|
proxyStdIn,
|
||||||
|
Config.getInstance().getString("cmdkiller")
|
||||||
|
);
|
||||||
|
|
||||||
executor.setWatchdog(watchdog);
|
executor.setWatchdog(watchdog);
|
||||||
}
|
}
|
||||||
final long delay = Config.getInstance().getLong("pingmonitor.delay");
|
final long delay = Config.getInstance().getLong("pingmonitor.delay");
|
||||||
|
|||||||
@@ -4,19 +4,56 @@
|
|||||||
*/
|
*/
|
||||||
package asys.zond;
|
package asys.zond;
|
||||||
|
|
||||||
|
import asys.zond.shell.Shell;
|
||||||
|
import asys.zond.win32.Kernel32;
|
||||||
|
import asys.zond.win32.W32API;
|
||||||
|
import com.sun.jna.Pointer;
|
||||||
import org.apache.commons.exec.ExecuteWatchdog;
|
import org.apache.commons.exec.ExecuteWatchdog;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
public class ZondExecuteWatchdog extends ExecuteWatchdog {
|
public class ZondExecuteWatchdog extends ExecuteWatchdog {
|
||||||
private final PipeInputStream inputStream;
|
private final PipeInputStream inputStream;
|
||||||
|
private long pid;
|
||||||
|
private String cmdkiller;
|
||||||
|
|
||||||
public ZondExecuteWatchdog(long timeout, PipeInputStream inputStream) {
|
public ZondExecuteWatchdog(long timeout, PipeInputStream inputStream, String cmdkiller) {
|
||||||
super(timeout);
|
super(timeout);
|
||||||
this.inputStream = inputStream;
|
this.inputStream = inputStream;
|
||||||
|
this.cmdkiller = cmdkiller.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long get_pid(Process process) {
|
||||||
|
if (process.getClass().getName().equals("java.lang.Win32Process") ||
|
||||||
|
process.getClass().getName().equals("java.lang.ProcessImpl")) {
|
||||||
|
try {
|
||||||
|
Field f = process.getClass().getDeclaredField("handle");
|
||||||
|
f.setAccessible(true);
|
||||||
|
long handl = f.getLong(process);
|
||||||
|
|
||||||
|
Kernel32 kernel32 = Kernel32.INSTANCE;
|
||||||
|
W32API.HANDLE handle = new W32API.HANDLE();
|
||||||
|
handle.setPointer(Pointer.createConstant(handl));
|
||||||
|
return kernel32.GetProcessId(handle); //pid
|
||||||
|
} catch (Throwable ignore) {
|
||||||
|
}
|
||||||
|
} else if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
|
||||||
|
try {
|
||||||
|
Field f = process.getClass().getDeclaredField("pid");
|
||||||
|
f.setAccessible(true);
|
||||||
|
return f.getLong(process); //pid
|
||||||
|
} catch (Throwable ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void start(Process processToMonitor) {
|
public synchronized void start(Process processToMonitor) {
|
||||||
super.start(processToMonitor);
|
super.start(processToMonitor);
|
||||||
|
pid = get_pid(processToMonitor);
|
||||||
inputStream.open();
|
inputStream.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,4 +62,19 @@ public class ZondExecuteWatchdog extends ExecuteWatchdog {
|
|||||||
super.stop();
|
super.stop();
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void destroyProcess() {
|
||||||
|
super.destroyProcess();
|
||||||
|
if (pid != -1 && cmdkiller != null && !cmdkiller.isEmpty()) {
|
||||||
|
try {
|
||||||
|
String cmd = cmdkiller.replace("%PID", String.valueOf(pid));
|
||||||
|
Shell.getInstance().getOutput().println("CMDKILL: '" + cmd + "'");
|
||||||
|
Runtime.getRuntime().exec(cmd);
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Shell.getInstance().getOutput().println("PID = -1");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
zond/src/main/java/asys/zond/win32/Kernel32.java
Normal file
15
zond/src/main/java/asys/zond/win32/Kernel32.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* DmitriyMX <dimon550@gmail.com>
|
||||||
|
* 2017-07-24
|
||||||
|
*/
|
||||||
|
package asys.zond.win32;
|
||||||
|
|
||||||
|
import com.sun.jna.Native;
|
||||||
|
/* https://jna.dev.java.net/ */
|
||||||
|
public interface Kernel32 extends W32API {
|
||||||
|
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, DEFAULT_OPTIONS);
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/ms683179(VS.85).aspx */
|
||||||
|
HANDLE GetCurrentProcess();
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/ms683215.aspx */
|
||||||
|
int GetProcessId(HANDLE Process);
|
||||||
|
}
|
||||||
65
zond/src/main/java/asys/zond/win32/W32API.java
Normal file
65
zond/src/main/java/asys/zond/win32/W32API.java
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*/
|
||||||
|
package asys.zond.win32;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.sun.jna.*;
|
||||||
|
import com.sun.jna.win32.StdCallLibrary;
|
||||||
|
import com.sun.jna.win32.W32APIFunctionMapper;
|
||||||
|
import com.sun.jna.win32.W32APITypeMapper;
|
||||||
|
|
||||||
|
/** Base type for most W32 API libraries. Provides standard options
|
||||||
|
* for unicode/ASCII mappings. Set the system property w32.ascii
|
||||||
|
* to true to default to the ASCII mappings.
|
||||||
|
*/
|
||||||
|
public interface W32API extends StdCallLibrary, W32Errors {
|
||||||
|
|
||||||
|
/** Standard options to use the unicode version of a w32 API. */
|
||||||
|
Map UNICODE_OPTIONS = new HashMap<String, Object>() {
|
||||||
|
{
|
||||||
|
put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
|
||||||
|
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Standard options to use the ASCII/MBCS version of a w32 API. */
|
||||||
|
Map ASCII_OPTIONS = new HashMap<String, Object>() {
|
||||||
|
{
|
||||||
|
put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);
|
||||||
|
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS;
|
||||||
|
|
||||||
|
class HANDLE extends PointerType {
|
||||||
|
@Override
|
||||||
|
public Object fromNative(Object nativeValue, FromNativeContext context) {
|
||||||
|
Object o = super.fromNative(nativeValue, context);
|
||||||
|
if (INVALID_HANDLE_VALUE.equals(o))
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constant value representing an invalid HANDLE. */
|
||||||
|
HANDLE INVALID_HANDLE_VALUE = new HANDLE() {
|
||||||
|
{ super.setPointer(Pointer.createConstant(-1)); }
|
||||||
|
@Override
|
||||||
|
public void setPointer(Pointer p) {
|
||||||
|
throw new UnsupportedOperationException("Immutable reference");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
23
zond/src/main/java/asys/zond/win32/W32Errors.java
Normal file
23
zond/src/main/java/asys/zond/win32/W32Errors.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*/
|
||||||
|
package asys.zond.win32;
|
||||||
|
|
||||||
|
public interface W32Errors {
|
||||||
|
|
||||||
|
int NO_ERROR = 0;
|
||||||
|
int ERROR_INVALID_FUNCTION = 1;
|
||||||
|
int ERROR_FILE_NOT_FOUND = 2;
|
||||||
|
int ERROR_PATH_NOT_FOUND = 3;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,3 +4,5 @@ port = 8779
|
|||||||
passcode = testpassphrase
|
passcode = testpassphrase
|
||||||
bridge.port = 8710
|
bridge.port = 8710
|
||||||
pingmonitor.delay = 2100
|
pingmonitor.delay = 2100
|
||||||
|
#cmdkiller = taskkill /F /PID %PID
|
||||||
|
cmdkiller = kill -KILL %PID
|
||||||
Reference in New Issue
Block a user