diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..551f93d
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,6 @@
+{
+ "cSpell.words": [
+ "Baccan",
+ "sockredirector"
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 8c65d3b..336ced1 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,7 @@ Ini file is divided in several section For each section you can define these par
| inWriteWait | long | 0 | writing to destination pause |
| outReadWait | long | 0 | reading from source pause |
| outWriteWait | long | 0 | write to source pause |
+| randomKill | long | 0 | random kill of thread within N seconds |
## Example
### Configuration Example (sockRedirector.ini)
diff --git a/nb-configuration.xml b/nb-configuration.xml
index 98de820..a89e8be 100644
--- a/nb-configuration.xml
+++ b/nb-configuration.xml
@@ -1,18 +1,18 @@
+ This file contains additional configuration written by modules in the NetBeans IDE.
+ The configuration is intended to be shared among all the users of project and
+ therefore it is assumed to be part of version control checkout.
+ Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+ -->
+ Properties that influence various parts of the IDE, especially code formatting and the like.
+ You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+ That way multiple projects can share the same settings (useful for formatting rules for example).
+ Any value defined here will override the pom.xml file value but is only applicable to the current project.
+ -->
${project.basedir}/licenseheader.txt
diff --git a/pom.xml b/pom.xml
index 07a2290..58bc887 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,11 @@
UTF-8
- 11
- 11
23.1.1
21.2.0
true
+ 11
@@ -163,7 +162,7 @@
anything
- 1.8.0
+ 11
%JAVA_HOME%
diff --git a/renovate.json b/renovate.json
index 204b63a..73c44d1 100644
--- a/renovate.json
+++ b/renovate.json
@@ -1,6 +1,6 @@
{
- "extends": [
- "config:base"
- ],
- "ignoreDeps": ["org.graalvm.sdk"]
+ "extends": [
+ "config:base"
+ ],
+ "ignoreDeps": ["org.graalvm.sdk"]
}
diff --git a/src/main/config/sockRedirector.ini b/src/main/config/sockRedirector.ini
index bd120d7..a7de590 100644
--- a/src/main/config/sockRedirector.ini
+++ b/src/main/config/sockRedirector.ini
@@ -1,9 +1,10 @@
-
- 8080
- www.comune.novara.it
- 80
+
+ 8081
+ 127.0.0.1
+ 8080
true
0
10
+ 10
diff --git a/src/main/java/it/baccan/sockredirector/AdminThread.java b/src/main/java/it/baccan/sockredirector/AdminThread.java
index c88d1b1..fe6e786 100644
--- a/src/main/java/it/baccan/sockredirector/AdminThread.java
+++ b/src/main/java/it/baccan/sockredirector/AdminThread.java
@@ -1,23 +1,19 @@
/*
* Copyright (c) 2019 Matteo Baccan
- * http://www.baccan.it
+ * https://www.baccan.it
*
* Distributed under the GPL v3 software license, see the accompanying
- * file LICENSE or http://www.gnu.org/licenses/gpl.html.
+ * file LICENSE or https://www.gnu.org/licenses/gpl-3.0.html.
*
*/
package it.baccan.sockredirector;
-import it.baccan.sockredirector.util.SocketFlow;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import lombok.extern.slf4j.Slf4j;
/**
* Admin thread.
@@ -25,26 +21,30 @@
* @author Matteo Baccan
* @version 1.0
*/
+@Slf4j
public class AdminThread extends Thread {
- private static final Logger LOG = LoggerFactory.getLogger(AdminThread.class);
-
- /** Admin thread constructor. */
+ /**
+ * Admin thread constructor.
+ */
public AdminThread() {
super();
setName("AdminThread");
}
+ /**
+ * Run admin thread.
+ */
@Override
public final void run() {
try {
- BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
+ var input = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String line = input.readLine();
if (!line.isEmpty()) {
- LOG.info("Admin> [{}]", line);
+ log.info("Admin> [{}]", line);
}
line = line.trim();
@@ -61,34 +61,34 @@ public final void run() {
}
if (command.equalsIgnoreCase("help")) {
- LOG.info("");
- LOG.info("help - this help");
- LOG.info("exit - exit program");
- LOG.info("thread [filter] - thread list");
- LOG.info("kill [... []] - kill nth thread");
- LOG.info("pause - set pause on nth thread");
- LOG.info("");
+ log.info("");
+ log.info("help - this help");
+ log.info("exit - exit program");
+ log.info("thread [filter] - thread list");
+ log.info("kill [... []] - kill nth thread");
+ log.info("pause - set pause on nth thread");
+ log.info("");
} else if (command.equalsIgnoreCase("exit")) {
Runtime.getRuntime().halt(0);
} else if (command.equalsIgnoreCase("thread")) {
- LOG.info("");
+ log.info("");
dumpThread(parameter);
- LOG.info("");
+ log.info("");
} else if (command.equalsIgnoreCase("pause")) {
- LOG.info("");
+ log.info("");
pauseThread(parameter);
- LOG.info("");
+ log.info("");
} else if (command.equalsIgnoreCase("kill")) {
- LOG.info("");
+ log.info("");
String[] th = parameter.split(" ");
for (String t : th) {
kill(t);
}
- LOG.info("");
+ log.info("");
}
}
} catch (IOException e) {
- LOG.error("adminThread error", e);
+ log.error("adminThread error", e);
}
}
@@ -100,10 +100,10 @@ private void dumpThread(String filter) {
String info = getThreadInfo(thread);
// If is in filter and the tread is not System
if ((filter.isEmpty() || info.contains(filter))
- && (thread.getThreadGroup() != null
- && !"system".equals(thread.getThreadGroup().getName()))
- && info.length() > 0) {
- LOG.info(info);
+ && (thread.getThreadGroup() != null
+ && !"system".equals(thread.getThreadGroup().getName()))
+ && info.length() > 0) {
+ log.info(info);
}
});
}
@@ -119,7 +119,6 @@ private void pauseThread(String parameter) {
if (thread instanceof FlowThread) {
FlowThread flowThread = (FlowThread) thread;
- String info = getThreadInfo(thread);
// If is in filter and the tread is not System
if ((th[0].isEmpty() || ("" + thread.getId()).equals(th[0]))) {
@@ -128,14 +127,14 @@ private void pauseThread(String parameter) {
flowThread.setReadPause(Long.parseLong(th[1]));
}
} catch (NumberFormatException numberFormatException) {
- LOG.error("Wrong number [{}]", th[1]);
+ log.error("Wrong number [{}]", th[1]);
}
try {
if (th.length > 2) {
flowThread.setWritePause(Long.parseLong(th[2]));
}
} catch (NumberFormatException numberFormatException) {
- LOG.error("Wrong number [{}]", th[2]);
+ log.error("Wrong number [{}]", th[2]);
}
}
}
@@ -152,83 +151,57 @@ private void kill(final String cThread) {
try {
if (cThread.equals("" + thread.getId())) {
bKill.set(true);
- LOG.info("Try to kill ID[{}]", cThread);
+ log.info("Try to kill ID[{}]", cThread);
thread.interrupt();
- LOG.info("Thread killed");
+ log.info("Thread killed");
}
} catch (ThreadDeath td) {
- LOG.error("ThreadDeath on admin kill [{}]", td.getMessage());
+ log.error("ThreadDeath on admin kill [{}]", td.getMessage());
} catch (Exception exception) {
- LOG.error("Exception on admin kill", exception);
+ log.error("Exception on admin kill", exception);
}
});
if (!bKill.get()) {
- LOG.info("Thread not found");
+ log.info("Thread not found");
}
}
private String getThreadInfo(final Thread thread) {
StringBuilder sb = new StringBuilder(128);
try {
- if (thread instanceof FlowThread) {
- FlowThread flowThread = (FlowThread) thread;
+ if (thread instanceof ServerSocketThread) {
+ ServerSocketThread serverSocketThread = (ServerSocketThread) thread;
- sb.append(
- padRight(
- flowThread.getParentSockThread().getServerPojo().getSourceAddress(),
- 15));
- sb.append("|");
- sb.append(
- padRight(
- ""
- + flowThread
- .getParentSockThread()
- .getServerPojo()
- .getSourcePort(),
- 5));
- sb.append("|");
- if (flowThread.getSocketFlow() == SocketFlow.OUTBOUND) {
- sb.append("->");
- } else {
- sb.append("<-");
- }
- sb.append("|");
- sb.append(padRight(flowThread.getSocketFlow().name(), 20));
- sb.append("|");
- sb.append(padRight("" + flowThread.getReadPause(), 5));
- sb.append("|");
- sb.append(padRight("" + flowThread.getWritePause(), 5));
- sb.append("|");
+ sb.append("|ID ");
sb.append(String.format("%1$5d", thread.getId()));
sb.append("|");
- sb.append(padRight(thread.getClass().getSimpleName(), 20));
- /*
+
+ sb.append(padRight(serverSocketThread.getServerPojo().getSourceAddress() + ":" + serverSocketThread.getServerPojo().getSourcePort(), 30));
+ sb.append("|ID ");
+ sb.append(String.format("%1$5d", serverSocketThread.getSourceOutputToDestinationInputThread().getId()));
sb.append("|");
- sb.append(padRight(thread.getState().name(), 10));
+ sb.append(serverSocketThread.getSourceOutputToDestinationInputThread().getSocketFlow().name());
+ sb.append("|R PAUSE ");
+ sb.append(padRight("" + serverSocketThread.getSourceOutputToDestinationInputThread().getReadPause(), 5));
+ sb.append("|W PAUSE ");
+ sb.append(padRight("" + serverSocketThread.getSourceOutputToDestinationInputThread().getWritePause(), 5));
sb.append("|");
- sb.append(padRight("" + thread.getPriority(), 10));
- */
- /*
- ThreadGroup threadGroup = thread.getThreadGroup();
- if (threadGroup != null) {
- sb.append(" GROUP[").append(threadGroup.getName()).append("]");
- }
- if (thread.isDaemon()) {
- sb.append(" [daemon]");
- }
- if (thread.isAlive()) {
- sb.append(" [alive]");
- }
- if (thread.isInterrupted()) {
- sb.append(" [interrupted]");
- }
- */
+ sb.append(padRight(thread.getName(), 20));
+
+ sb.append("|-|");
+ sb.append(serverSocketThread.getDestinationOutputToSourceInputThread().getSocketFlow().name());
+ sb.append("|ID ");
+ sb.append(String.format("%1$5d", serverSocketThread.getDestinationOutputToSourceInputThread().getId()));
+ sb.append("|R PAUSE ");
+ sb.append(padRight("" + serverSocketThread.getDestinationOutputToSourceInputThread().getReadPause(), 5));
+ sb.append("|W PAUSE ");
+ sb.append(padRight("" + serverSocketThread.getDestinationOutputToSourceInputThread().getWritePause(), 5));
sb.append("|");
sb.append(padRight(thread.getName(), 20));
}
} catch (Exception exception) {
- LOG.error("getThreadInfo error", exception);
+ log.error("getThreadInfo error", exception);
}
return sb.toString();
}
diff --git a/src/main/java/it/baccan/sockredirector/FlowThread.java b/src/main/java/it/baccan/sockredirector/FlowThread.java
index 721009c..58dffc5 100644
--- a/src/main/java/it/baccan/sockredirector/FlowThread.java
+++ b/src/main/java/it/baccan/sockredirector/FlowThread.java
@@ -1,31 +1,30 @@
/*
* Copyright (charRead) 2019 Matteo Baccan
- * http://www.baccan.it
+ * https://www.baccan.it
*
* Distributed under the GPL v3 software license, see the accompanying
- * file LICENSE or http://www.gnu.org/licenses/gpl.html.
+ * file LICENSE or https://www.gnu.org/licenses/gpl-3.0.html.
*
*/
package it.baccan.sockredirector;
import it.baccan.sockredirector.util.SocketFlow;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.SocketException;
+import lombok.extern.slf4j.Slf4j;
-/** @author Matteo Baccan */
+/**
+ * @author Matteo Baccan
+ */
+@Slf4j
public class FlowThread extends Thread {
- /** Logger. */
- private static final Logger LOG = LoggerFactory.getLogger(FlowThread.class);
-
+ private boolean exitThread = false;
private final OutputStream sourceOutputStream;
private final InputStream sourceInputStream;
private final ServerSocketThread parentSockThread;
@@ -71,13 +70,17 @@ public FlowThread(
setName(outputFileLog);
}
+ /**
+ * Execute socket Thread.
+ */
@Override
public void run() {
+ log.info("Ini run thread [{}]", this.getId());
// Attivo il sourceOutputToDestinationInputThread
runNormal();
// Distruggo tutti i processi
- getParentSockThread().killProcess();
+ log.info("End run thread [{}]", this.getId());
}
private void runNormal() {
@@ -94,7 +97,7 @@ private void runNormal() {
int bytesToRead = -1;
int charRead;
boolean firstPause = true;
- while (true) {
+ while (!exitThread) {
if (firstPause) {
firstPause = false;
socketPause(getReadPause());
@@ -108,12 +111,12 @@ private void runNormal() {
} catch (SocketException se) {
if ("Socket closed".equals(se.getMessage())) {
// Chiusura della connessione
- LOG.info(
+ log.info(
"[{}][{}] Socket closed",
getSocketFlow().name(),
getParentSockThread().getThreadNumber());
} else {
- LOG.error(
+ log.error(
"[{}][{}] SocketException [{}]",
getSocketFlow().name(),
getParentSockThread().getThreadNumber(),
@@ -121,7 +124,7 @@ private void runNormal() {
}
break;
} catch (IOException e) {
- LOG.error(
+ log.error(
"[{}][{}] readError [{}]",
getSocketFlow().name(),
getParentSockThread().getThreadNumber(),
@@ -150,13 +153,13 @@ private void runNormal() {
socketPause(getWritePause());
logData(logFile, buffer, bufferPosition);
} catch (ThreadDeath td) {
- LOG.error(
+ log.error(
"[{}][{}] ThreadDeath on runNormal [{}]",
getSocketFlow().name(),
getParentSockThread().getThreadNumber(),
td.getMessage());
} catch (IOException e) {
- LOG.error(
+ log.error(
"[{}][{}] Error on runNormal [{}]",
getSocketFlow().name(),
getParentSockThread().getThreadNumber(),
@@ -166,7 +169,7 @@ private void runNormal() {
try {
logFile.close();
} catch (IOException iOException) {
- LOG.error(
+ log.error(
"[{}][{}] Error on closing log file [{}]",
getSocketFlow().name(),
getParentSockThread().getThreadNumber(),
@@ -186,32 +189,44 @@ private void socketPause(long readPause) {
}
}
- /** @return the readPause */
+ /**
+ * @return the readPause
+ */
public long getReadPause() {
return readPause;
}
- /** @param readPause the readPause to set */
+ /**
+ * @param readPause the readPause to set
+ */
public void setReadPause(long readPause) {
this.readPause = readPause;
}
- /** @return the writePause */
+ /**
+ * @return the writePause
+ */
public long getWritePause() {
return writePause;
}
- /** @param writePause the writePause to set */
+ /**
+ * @param writePause the writePause to set
+ */
public void setWritePause(long writePause) {
this.writePause = writePause;
}
- /** @return the parentSockThread */
+ /**
+ * @return the parentSockThread
+ */
public ServerSocketThread getParentSockThread() {
return parentSockThread;
}
- /** @return the socketFlow */
+ /**
+ * @return the socketFlow
+ */
public SocketFlow getSocketFlow() {
return socketFlow;
}
@@ -224,4 +239,17 @@ private void logData(
logFile.write(buffer, 0, bufferPosition);
}
}
+
+ /**
+ * Stop current thread.
+ */
+ public void stopThread() {
+ log.info("Exit from thread [{}]", this.getId());
+ exitThread = true;
+ try {
+ sourceInputStream.close();
+ } catch (IOException ex) {
+ log.error("stopThread close socket [{}]", ex.getMessage());
+ }
+ }
}
diff --git a/src/main/java/it/baccan/sockredirector/PortRedirect.java b/src/main/java/it/baccan/sockredirector/PortRedirect.java
index a0f3469..9c1e085 100644
--- a/src/main/java/it/baccan/sockredirector/PortRedirect.java
+++ b/src/main/java/it/baccan/sockredirector/PortRedirect.java
@@ -1,34 +1,30 @@
/*
* Copyright (c) 2019 Matteo Baccan
- * http://www.baccan.it
+ * https://www.baccan.it
*
* Distributed under the GPL v3 software license, see the accompanying
- * file LICENSE or http://www.gnu.org/licenses/gpl.html.
+ * file LICENSE or https://www.gnu.org/licenses/gpl-3.0.html.
*
*/
package it.baccan.sockredirector;
import it.baccan.sockredirector.pojo.ServerPojo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
+import lombok.extern.slf4j.Slf4j;
/**
* PortRedirect engine.
*
* @author Matteo Baccan
*/
+@Slf4j
public class PortRedirect extends Thread {
- /** Logger. */
- private static final Logger LOG = LoggerFactory.getLogger(PortRedirect.class);
-
private final ServerPojo serverPojo;
/**
@@ -40,7 +36,7 @@ public PortRedirect(ServerPojo server) {
super();
setName("PortRedirect");
serverPojo = server;
- LOG.info(
+ log.info(
"Ready on [{}:{}] -> [{}:{}] TIMEOUT [{}]",
serverPojo.getSourceAddress(),
serverPojo.getSourcePort(),
@@ -49,10 +45,13 @@ public PortRedirect(ServerPojo server) {
serverPojo.getTimeout());
}
+ /**
+ * Execute port redirect thread.
+ */
@Override
public final void run() {
- try (ServerSocket sock =
- new ServerSocket(
+ try (ServerSocket sock
+ = new ServerSocket(
serverPojo.getSourcePort(),
serverPojo.getMaxclient(),
InetAddress.getByName(serverPojo.getSourceAddress()))) {
@@ -69,18 +68,18 @@ public final void run() {
thread.start();
}
} catch (BindException bind) {
- LOG.error(
+ log.error(
"Address [{}:{}] already in use : [{}]",
serverPojo.getSourceAddress(),
serverPojo.getSourcePort(),
bind.getMessage());
} catch (IOException e) {
- LOG.error(
+ log.error(
"Error in redirector from [{}] \t to [{}:{}]",
serverPojo.getSourcePort(),
serverPojo.getDestinationAddress(),
serverPojo.getDestinationPort());
- LOG.error("Full error", e);
+ log.error("Full error", e);
}
}
}
diff --git a/src/main/java/it/baccan/sockredirector/ServerSocketThread.java b/src/main/java/it/baccan/sockredirector/ServerSocketThread.java
index 92ca072..c108ba5 100644
--- a/src/main/java/it/baccan/sockredirector/ServerSocketThread.java
+++ b/src/main/java/it/baccan/sockredirector/ServerSocketThread.java
@@ -1,9 +1,9 @@
/*
* Copyright (c) 2019 Matteo Baccan
- * http://www.baccan.it
+ * https://www.baccan.it
*
* Distributed under the GPL v3 software license, see the accompanying
- * file LICENSE or http://www.gnu.org/licenses/gpl.html.
+ * file LICENSE or https://www.gnu.org/licenses/gpl-3.0.html.
*
*/
package it.baccan.sockredirector;
@@ -11,36 +11,31 @@
import it.baccan.sockredirector.pojo.ServerPojo;
import it.baccan.sockredirector.util.SocketFlow;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.IOException;
import java.net.Socket;
+import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
-/** @author Matteo Baccan */
+/**
+ * @author Matteo Baccan
+ */
+@Slf4j
public class ServerSocketThread extends Thread {
- /** Logger. */
- private static final Logger LOG = LoggerFactory.getLogger(ServerSocketThread.class);
- /** */
private static final AtomicLong THREADTOTAL = new AtomicLong(0);
+ @Getter
private long threadNumber = 0;
+ @Getter
private final ServerPojo serverPojo;
private final Socket socketIn;
+ @Getter
private FlowThread sourceOutputToDestinationInputThread;
+ @Getter
private FlowThread destinationOutputToSourceInputThread;
- /**
- * Current thread number.
- *
- * @return
- */
- public long getThreadNumber() {
- return threadNumber;
- }
-
/**
* @param sock
* @param server
@@ -51,56 +46,48 @@ public ServerSocketThread(Socket sock, ServerPojo server) {
threadNumber = THREADTOTAL.incrementAndGet();
setName(
"FROM:"
- + serverPojo.getSourcePort()
- + "|TO:"
- + serverPojo.getDestinationAddress()
- + ":"
- + serverPojo.getDestinationPort()
- + "|NUM:"
- + threadNumber);
+ + serverPojo.getSourcePort()
+ + "|TO:"
+ + serverPojo.getDestinationAddress()
+ + ":"
+ + serverPojo.getDestinationPort());
}
- /** Interrupt the two subthreads. */
+ /**
+ * Interrupt the two subthreads.
+ */
public synchronized void killProcess() {
- try {
- sourceOutputToDestinationInputThread.interrupt();
- } catch (ThreadDeath td) {
- LOG.error("ThreadDeath on killProcess [{}]", td.getMessage());
- } catch (Throwable e) {
- LOG.error("Throwable", e);
- }
-
- try {
- destinationOutputToSourceInputThread.interrupt();
- } catch (ThreadDeath td) {
- LOG.error("ThreadDeath on killProcess [{}]", td.getMessage());
- } catch (Throwable e) {
- LOG.error("Throwable", e);
- }
+ log.info("Kill source thread [{}] from thread [{}]", sourceOutputToDestinationInputThread.getId(), this.getId());
+ sourceOutputToDestinationInputThread.stopThread();
+ log.info("Kill destination thread [{}] from thread [{}]", destinationOutputToSourceInputThread.getId(), this.getId());
+ destinationOutputToSourceInputThread.stopThread();
}
+ /**
+ * Run socket server.
+ */
@Override
public void run() {
if (getServerPojo().isLogger()) {
- LOG.info("[{}] new user [{}]", threadNumber, socketIn);
+ log.info("new thread [{}] on connection [{}]", threadNumber, socketIn);
}
- try (Socket socketOut =
- new Socket(
+ try (Socket socketOut
+ = new Socket(
getServerPojo().getDestinationAddress(),
getServerPojo().getDestinationPort())) {
// S -> D
- sourceOutputToDestinationInputThread =
- new FlowThread(
+ sourceOutputToDestinationInputThread
+ = new FlowThread(
this,
socketIn.getOutputStream(),
socketOut.getInputStream(),
getServerPojo().getDestinationAddress()
- + "-"
- + getServerPojo().getDestinationPort()
- + ".in"
- + threadNumber,
+ + "-"
+ + getServerPojo().getDestinationPort()
+ + ".in"
+ + threadNumber,
getServerPojo().isLogger(),
getServerPojo().getBlockSize(),
SocketFlow.OUTBOUND,
@@ -108,17 +95,19 @@ public void run() {
getServerPojo().getOutWriteWait());
sourceOutputToDestinationInputThread.start();
+ log.info("Start source thread [{}] from thread [{}]", sourceOutputToDestinationInputThread.getId(), this.getId());
+
// D -> S
- destinationOutputToSourceInputThread =
- new FlowThread(
+ destinationOutputToSourceInputThread
+ = new FlowThread(
this,
socketOut.getOutputStream(),
socketIn.getInputStream(),
getServerPojo().getDestinationAddress()
- + "-"
- + getServerPojo().getDestinationPort()
- + ".out"
- + threadNumber,
+ + "-"
+ + getServerPojo().getDestinationPort()
+ + ".out"
+ + threadNumber,
getServerPojo().isLogger(),
getServerPojo().getBlockSize(),
SocketFlow.INBOUND,
@@ -126,36 +115,45 @@ public void run() {
getServerPojo().getInWriteWait());
destinationOutputToSourceInputThread.start();
+ log.info("Start destination thread [{}] from thread [{}]", destinationOutputToSourceInputThread.getId(), this.getId());
+
while (destinationOutputToSourceInputThread.isAlive()
&& sourceOutputToDestinationInputThread.isAlive()) {
sleep(1000);
+ // Proviamo a killare in modo random il thread
+ if (getServerPojo().getRandomKill() > 0) {
+ var random = new Random();
+ if (random.nextInt() % getServerPojo().getRandomKill() == 0) {
+ log.info("Kill random of thread [{}]", this.getId());
+ killProcess();
+ }
+ }
}
} catch (InterruptedException e) {
- LOG.info("InterruptedException [{}]", e.getMessage());
+ log.info("InterruptedException [{}]", e.getMessage());
Thread.currentThread().interrupt();
} catch (Exception e) {
- LOG.error(
+ log.error(
"[{}] host:port [{}:{}]",
threadNumber,
getServerPojo().getDestinationAddress(),
getServerPojo().getDestinationPort());
- LOG.error("Unknown error", e);
+ log.error("Unknown error", e);
} finally {
+ // Kill all sub process when one thread exit
+ killProcess();
+
try {
socketIn.close();
} catch (IOException e) {
- LOG.error("Error on socket.close", e);
+ log.error("Error on socket.close", e);
}
}
if (getServerPojo().isLogger()) {
- LOG.info("[{}] disconnect", threadNumber);
+ log.info("end thread [{}] on connection [{}]", threadNumber, socketIn);
}
}
- /** @return the serverPojo */
- public ServerPojo getServerPojo() {
- return serverPojo;
- }
}
diff --git a/src/main/java/it/baccan/sockredirector/SockRedirector.java b/src/main/java/it/baccan/sockredirector/SockRedirector.java
index c83552b..a434d79 100644
--- a/src/main/java/it/baccan/sockredirector/SockRedirector.java
+++ b/src/main/java/it/baccan/sockredirector/SockRedirector.java
@@ -1,53 +1,53 @@
/*
* Copyright (c) 2019 Matteo Baccan
- * http://www.baccan.it
+ * https://www.baccan.it
*
* Distributed under the GPL v3 software license, see the accompanying
- * file LICENSE or http://www.gnu.org/licenses/gpl.html.
+ * file LICENSE or https://www.gnu.org/licenses/gpl-3.0.html.
*
*/
package it.baccan.sockredirector;
import it.baccan.sockredirector.pojo.ServerPojo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import lombok.extern.slf4j.Slf4j;
/**
* Sock redirector server.
*
* @author Matteo Baccan
*/
+@Slf4j
public class SockRedirector extends Thread {
- /** Logger. */
- private static final Logger LOG = LoggerFactory.getLogger(SockRedirector.class);
-
- /** @param argv Command line parameters. */
+ /**
+ * @param argv Command line parameters.
+ */
public static void main(final String[] argv) {
SockRedirector sockRedirector = new SockRedirector();
sockRedirector.init();
}
- /** Init program. */
+ /**
+ * Init program.
+ */
public void init() {
final String initFile = "sockRedirector.ini";
System.setProperty("sun.net.spi.nameservice.nameservers", "8.8.8.8");
System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");
- LOG.info("+---------------------------------------------------------------------------+");
- LOG.info("| TCP/IP Port Redirector |");
- LOG.info("| Matteo Baccan Opensource Software http://www.baccan.it |");
- LOG.info("+---------------------------------------------------------------------------+");
- LOG.info("");
+ log.info("+---------------------------------------------------------------------------+");
+ log.info("| TCP/IP Port Redirector |");
+ log.info("| Matteo Baccan Opensource Software https://www.baccan.it |");
+ log.info("+---------------------------------------------------------------------------+");
+ log.info("");
- LOG.info("Setup environment");
+ log.info("Setup environment");
// Se non ho la directory di LOG la creo
try {
File oFile = new File("logs");
@@ -55,10 +55,10 @@ public void init() {
oFile.mkdir();
}
} catch (Throwable e) {
- LOG.error("Error creating log directory", e);
+ log.error("Error creating log directory", e);
}
- LOG.info("Opening [{}] ...", initFile);
+ log.info("Opening [{}] ...", initFile);
try {
byte[] buffer;
File config = new File(initFile);
@@ -97,6 +97,7 @@ public void init() {
serverPojo.setInWriteWait(Long.parseLong(getToken(cXML, "inWriteWait", "0")));
serverPojo.setOutReadWait(Long.parseLong(getToken(cXML, "outReadWait", "0")));
serverPojo.setOutWriteWait(Long.parseLong(getToken(cXML, "outWriteWait", "0")));
+ serverPojo.setRandomKill(Long.parseLong(getToken(cXML, "randomKill", "0")));
// Start server
PortRedirect server = new PortRedirect(serverPojo);
@@ -110,15 +111,15 @@ public void init() {
// Start admin
admin.start();
- LOG.info("");
- LOG.info("All system ready. Type \"help\" for debug info");
+ log.info("");
+ log.info("All system ready. Type \"help\" for debug info");
} else {
- LOG.error("Missing configuration file [{}]", config.getAbsolutePath());
+ log.error("Missing configuration file [{}]", config.getAbsolutePath());
}
} catch (IOException e) {
- LOG.error("Error during opening of [{}]", initFile);
- LOG.error("IOException", e);
+ log.error("Error during opening of [{}]", initFile);
+ log.error("IOException", e);
}
}
diff --git a/src/main/java/it/baccan/sockredirector/pojo/ServerPojo.java b/src/main/java/it/baccan/sockredirector/pojo/ServerPojo.java
index 3263d61..b1574b9 100644
--- a/src/main/java/it/baccan/sockredirector/pojo/ServerPojo.java
+++ b/src/main/java/it/baccan/sockredirector/pojo/ServerPojo.java
@@ -1,16 +1,18 @@
/*
* Copyright (c) 2019 Matteo Baccan
- * http://www.baccan.it
+ * https://www.baccan.it
*
* Distributed under the GPL v3 software license, see the accompanying
- * file LICENSE or http://www.gnu.org/licenses/gpl.html.
+ * file LICENSE or https://www.gnu.org/licenses/gpl-3.0.html.
*
*/
package it.baccan.sockredirector.pojo;
import lombok.Data;
-/** @author Matteo Baccan */
+/**
+ * @author Matteo Baccan
+ */
@Data
public class ServerPojo {
@@ -26,4 +28,6 @@ public class ServerPojo {
private long inWriteWait;
private long outReadWait;
private long outWriteWait;
+ private long randomKill;
+
}
diff --git a/src/main/java/it/baccan/sockredirector/util/SocketFlow.java b/src/main/java/it/baccan/sockredirector/util/SocketFlow.java
index 96cab30..7679c78 100644
--- a/src/main/java/it/baccan/sockredirector/util/SocketFlow.java
+++ b/src/main/java/it/baccan/sockredirector/util/SocketFlow.java
@@ -1,17 +1,23 @@
/*
* Copyright (c) 2019 Matteo Baccan
- * http://www.baccan.it
+ * https://www.baccan.it
*
* Distributed under the GPL v3 software license, see the accompanying
- * file LICENSE or http://www.gnu.org/licenses/gpl.html.
+ * file LICENSE or https://www.gnu.org/licenses/gpl-3.0.html.
*
*/
package it.baccan.sockredirector.util;
-/** @author Matteo Baccan */
+/**
+ * @author Matteo Baccan
+ */
public enum SocketFlow {
- /** Inbound data. */
+ /**
+ * Inbound data.
+ */
INBOUND,
- /** Outbound data. */
+ /**
+ * Outbound data.
+ */
OUTBOUND
}