Add PortChecker

* This helps troubleshooting in case the proxy port is already being used by another program.
This commit is contained in:
Eduardo Alonso 2021-07-31 00:15:19 +02:00 committed by Eduardo Alonso
parent 85c933cf7c
commit e9c7996a2f
6 changed files with 116 additions and 1 deletions

View File

@ -80,6 +80,8 @@ public class HConnection {
}
} catch (IOException e) {
e.printStackTrace();
setState(HState.ABORTING);
setState(HState.NOT_CONNECTED);
}
}

View File

@ -7,6 +7,11 @@ import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.SocksConfiguration;
import gearth.protocol.hostreplacer.hostsfile.HostReplacer;
import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory;
import gearth.protocol.portchecker.PortChecker;
import gearth.protocol.portchecker.PortCheckerFactory;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import java.io.IOException;
import java.net.*;
@ -92,7 +97,19 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
for (int c = 0; c < potentialProxies.size(); c++) {
HProxy potentialProxy = potentialProxies.get(c);
ServerSocket proxy_server = new ServerSocket(potentialProxy.getIntercept_port(), 10, InetAddress.getByName(potentialProxy.getIntercept_host()));
ServerSocket proxy_server;
try {
proxy_server = new ServerSocket(potentialProxy.getIntercept_port(), 10, InetAddress.getByName(potentialProxy.getIntercept_host()));
} catch (BindException e) {
PortChecker portChecker = PortCheckerFactory.getPortChecker();
String processName = portChecker.getProcessUsingPort(potentialProxy.getIntercept_port());
Platform.runLater(() -> {
Alert a = new Alert(Alert.AlertType.ERROR, "The port is in use by " + processName,
ButtonType.OK);
a.showAndWait();
});
throw new IOException(e);
}
potentialProxy.initProxy(proxy_server);
new Thread(() -> {

View File

@ -0,0 +1,38 @@
package gearth.protocol.portchecker;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* This interface wraps the OS-dependant operation of checking if a specific port is used by any program.
* Some programs like McAfee TrueKey run on port 30000. This will hopefully save the user some time troubleshooting.
*/
public interface PortChecker {
/**
* @param port port to check
* @return process name or null if none
*/
String getProcessUsingPort(int port) throws IOException;
/** Runs a command and reads the first line of output
* @param command Command to run
* @return {@link String} containing the output
* @throws IOException If an I/O error occurs
*/
default String getCommandOutput(String[] command) throws IOException {
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
return stdInput.readLine();
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
}

View File

@ -0,0 +1,20 @@
package gearth.protocol.portchecker;
import gearth.misc.OSValidator;
import org.apache.commons.lang3.NotImplementedException;
public final class PortCheckerFactory {
private PortCheckerFactory() {}
public static PortChecker getPortChecker() {
if (OSValidator.isWindows()) {
return new WindowsPortChecker();
}
if (OSValidator.isUnix()) {
return new UnixPortChecker();
}
throw new NotImplementedException("macOS port checker not implemented yet");
}
}

View File

@ -0,0 +1,13 @@
package gearth.protocol.portchecker;
import java.io.IOException;
public class UnixPortChecker implements PortChecker {
@Override
public String getProcessUsingPort(int port) throws IOException {
String netstatOut = getCommandOutput(new String[] {"/bin/sh", "-c", " netstat -nlp | grep :" + port});
int index = netstatOut.lastIndexOf("LISTEN ");
return netstatOut.substring(index + 12);
}
}

View File

@ -0,0 +1,25 @@
package gearth.protocol.portchecker;
import java.io.IOException;
public class WindowsPortChecker implements PortChecker{
@Override
public String getProcessUsingPort(int port) throws IOException {
try {
String s = getCommandOutput(new String[] {"cmd", "/c", " netstat -ano | findstr LISTENING | findstr " + port});
int index = s.lastIndexOf(" ");
String pid = s.substring(index);
return getProcessNameFromPid(pid);
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
private String getProcessNameFromPid(String pid) throws IOException {
String task = getCommandOutput(new String[] {"tasklist /fi \"pid eq " + pid + "\" /nh /fo:CSV"});
int index = task.indexOf(',');
return task.substring(0, index);
}
}