From c9fe92826d8deb35b3413acfec2182a579ad3b51 Mon Sep 17 00:00:00 2001 From: Matteo Baccan Date: Thu, 30 Nov 2023 15:30:42 +0100 Subject: [PATCH] Some optimization and randomKill feature --- .vscode/settings.json | 6 + README.md | 1 + nb-configuration.xml | 20 +-- pom.xml | 5 +- renovate.json | 8 +- src/main/config/sockRedirector.ini | 9 +- .../it/baccan/sockredirector/AdminThread.java | 147 +++++++----------- .../it/baccan/sockredirector/FlowThread.java | 74 ++++++--- .../baccan/sockredirector/PortRedirect.java | 27 ++-- .../sockredirector/ServerSocketThread.java | 128 ++++++++------- .../baccan/sockredirector/SockRedirector.java | 47 +++--- .../sockredirector/pojo/ServerPojo.java | 10 +- .../sockredirector/util/SocketFlow.java | 16 +- 13 files changed, 257 insertions(+), 241 deletions(-) create mode 100644 .vscode/settings.json 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 @@ - 127.0.0.1 - 8080 - www.comune.novara.it - 80 + 0.0.0.0 + 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 }