jscanner

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit c7e87c2e43a569e7a4fb72178ac3c5b5c7d13216
parent cedba0f485d95cca854ab1b3b83d020a4aa10181
Author: Matthias Jaros <jaros@mailbox.org>
Date:   Thu,  2 Jul 2026 12:45:18 +0200

Changed scanstate to class that now owns completetly the Result List and
does not allow modifications outside of defined methods. -> thread safe

Diffstat:
Msrc/main/java/com/it_jaros/jscanner/ScanState.java | 34+++++++++++++++++++++++++++++++++-
Msrc/main/java/com/it_jaros/jscanner/Scanner.java | 18+++++++++---------
2 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/it_jaros/jscanner/ScanState.java b/src/main/java/com/it_jaros/jscanner/ScanState.java @@ -1,5 +1,37 @@ package com.it_jaros.jscanner; +import java.util.ArrayList; import java.util.List; -public record ScanState(Counter counter, ProgressBar progressBar, List<ScanResult> scanResult) {} +public class ScanState { + private final Counter counter; + private final ProgressBar progressBar; + private final List<ScanResult> scanResult; + + public ScanState(Counter counter, ProgressBar progressBar) { + this.counter = counter; + this.progressBar = progressBar; + // scanResult can not be given from outside because this class controls full access to it + this.scanResult = new ArrayList<>(); + } + + public Counter getCounter() { + return counter; + } + + public ProgressBar getProgressBar() { + return progressBar; + } + + public void addScanResult(ScanResult newResult) { + synchronized (this.scanResult) { + this.scanResult.add(newResult); + } + } + + public List<ScanResult> getSnapshotOfScanResults() { + synchronized (scanResult) { + return List.copyOf(scanResult); + } + } +} diff --git a/src/main/java/com/it_jaros/jscanner/Scanner.java b/src/main/java/com/it_jaros/jscanner/Scanner.java @@ -86,8 +86,8 @@ public class Scanner implements AutoCloseable { } public List<ScanResult> scanHosts(Stream<String> hosts, String ports) throws IOException { - ScanState scanState = new ScanState(new Counter(), new ProgressBar(quiet), new ArrayList<>()); - scanState.progressBar().start(); + ScanState scanState = new ScanState(new Counter(), new ProgressBar(quiet)); + scanState.getProgressBar().start(); try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) { CompletionService<ScanResult> completionService = new ExecutorCompletionService<>(executor); Queue<String> hostsInQueue = hosts.collect(Collectors.toCollection(ArrayDeque::new)); @@ -109,7 +109,7 @@ public class Scanner implements AutoCloseable { } activeHostWorkers--; hostsToProcess--; - scanState.scanResult().add(finishedHost.get()); + scanState.addScanResult(finishedHost.get()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } catch (ExecutionException e) { @@ -122,13 +122,13 @@ public class Scanner implements AutoCloseable { } } - scanState.progressBar().stop(); + scanState.getProgressBar().stop(); System.out.println("--------------------"); System.out.println("Finished scan!"); System.out.println("Stats:"); - System.out.println("Peak concurrent connects: " + scanState.counter().max()); + System.out.println("Peak concurrent connects: " + scanState.getCounter().max()); System.out.println("--------------------"); - return scanState.scanResult(); + return scanState.getSnapshotOfScanResults(); } private ScanResult scanHost(String host, String ports, ScanState scanState) { @@ -140,7 +140,7 @@ public class Scanner implements AutoCloseable { // Give progressbar the current progress object which is then updated in the sub virtual threads Progress progress = new Progress(host, portRange.getTotal(), new AtomicInteger(), new AtomicInteger(), new AtomicInteger()); - scanState.progressBar().submit(progress); + scanState.getProgressBar().submit(progress); if (!disableOnlineCheck && !checkHostOnline(host)) { // Visually show that this host is basically done @@ -228,7 +228,7 @@ public class Scanner implements AutoCloseable { // don't allow more sockets then specified socketLimit.acquireUninterruptibly(); // count how many ports are concurrently checked - scanState.counter().inc(); + scanState.getCounter().inc(); try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port), timeoutInMillis); @@ -244,7 +244,7 @@ public class Scanner implements AutoCloseable { // NoRouteToHostException: this can be safely ignored because the port is closed if a host is unreachable // Will happen a lot when scanning for open ports, so not needed } finally { - scanState.counter().dec(); + scanState.getCounter().dec(); socketLimit.release(); }