summaryrefslogtreecommitdiff
path: root/src/main/java/com/it_jaros/networkScanner/Scanner.java
diff options
context:
space:
mode:
authorGravatar Matthias Jaros <jarlucmat@mailbox.org>2026-03-16 16:41:25 +0100
committerGravatar Matthias Jaros <jarlucmat@mailbox.org>2026-07-09 09:59:28 +0200
commit7946b8aae3427b180d28441f8a02ae6665ac215c (patch)
treef10deda6e765715a68d37981a5ab0a6c73744dc6 /src/main/java/com/it_jaros/networkScanner/Scanner.java
parent98a62828f7305fc3a2a36a9b19f0ae98ce78904b (diff)
Renamed package
Diffstat (limited to 'src/main/java/com/it_jaros/networkScanner/Scanner.java')
-rw-r--r--src/main/java/com/it_jaros/networkScanner/Scanner.java148
1 files changed, 0 insertions, 148 deletions
diff --git a/src/main/java/com/it_jaros/networkScanner/Scanner.java b/src/main/java/com/it_jaros/networkScanner/Scanner.java
deleted file mode 100644
index e3f90f1..0000000
--- a/src/main/java/com/it_jaros/networkScanner/Scanner.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package com.it_jaros.networkScanner;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.LockSupport;
-
-public class Scanner {
-
- private final Counter counter = new Counter();
- private final ProgressBar progressBar = new ProgressBar();
- private final Semaphore socketLimit;
- private final int timeoutInMillis;
- private final long delayInNanos;
- private final int maxWorkersPerHost;
-
- public Scanner(int socketLimit, int timeoutInMillis, int delayInMillis, int maxWorkersPerHost) {
- this.timeoutInMillis = timeoutInMillis;
- this.delayInNanos = TimeUnit.MILLISECONDS.toNanos(Math.max(0, delayInMillis));
- this.socketLimit = new Semaphore(socketLimit);
- this.maxWorkersPerHost = maxWorkersPerHost;
- }
-
- public List<ScanResult> scan(ScanOptions target) {
- return scanTargets(target.targets(), target.ports());
- }
-
- public List<ScanResult> scanTargets(List<String> targets, String ports) {
- List<ScanResult> results = new ArrayList<>();
- progressBar.start();
- try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
- List<Future<ScanResult>> futures = new ArrayList<>();
- for (String target : targets) {
- futures.add(executor.submit(() -> scanTarget(target, ports)));
- }
-
- futures.forEach((Future<ScanResult> f) -> {
- try {
- results.add(f.get());
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- } catch (ExecutionException e) {
- System.out.printf("%s -> %s%n", e.getClass().getSimpleName(), e.getMessage());
- }
- });
- }
-
- progressBar.stop();
- System.out.println("Peak concurrent connects: " + counter.max());
- return results;
- }
-
- private ScanResult scanTarget(String target, String ports) {
- PortRange portRange = new PortRange(ports);
- AtomicLong portSlotFactory = new AtomicLong(System.nanoTime());
- Semaphore maxWorkers = new Semaphore(maxWorkersPerHost);
- BitSet openPorts = new BitSet(PortRange.MAX_PORT);
-
- Progress progress = new Progress(target, portRange.getTotal(), new AtomicInteger(), new AtomicInteger());
- progressBar.submit(progress);
-
- try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
- List<Future<Integer>> futures = new ArrayList<>();
- while (portRange.hasNext()) {
- maxWorkers.acquireUninterruptibly();
- final int currentPort = portRange.next();
- futures.add(executor.submit(() -> {
- try {
- waitForSlot(portSlotFactory);
- int port = scanPort(target, currentPort);
- if (port != -1) {
- progress.open().incrementAndGet();
- }
- return port;
- } finally {
- maxWorkers.release();
- progress.done().incrementAndGet();
- }
- }));
- }
-
- List<Throwable> errors = new ArrayList<>();
- for (Future<Integer> f : futures) {
- try {
- int port = f.get();
- if (port != -1) {
- // openPorts is not threadsafe, so we do not update it outside the worker threads
- openPorts.set(port);
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- } catch (ExecutionException e) {
- errors.add(e);
- }
- }
-
- if (!errors.isEmpty()) {
- System.out.printf("Errors happened during scan of target %s%nErrors:%s -> %s", target, errors.size(), errors);
- }
- }
-
- return new ScanResult(target, openPorts);
- }
-
- private int scanPort(String target, final int currentPort) {
- return isTargetPortOpen(target, currentPort) ? currentPort : -1;
- }
-
- private void waitForSlot(AtomicLong scanSlotFactory) {
- if (delayInNanos > 0) {
- long slot = scanSlotFactory.getAndAdd(delayInNanos);
- long wait = slot - System.nanoTime();
- if (wait > 0)
- LockSupport.parkNanos(wait);
- }
- }
-
- private boolean isTargetPortOpen(String target, int port) {
- socketLimit.acquireUninterruptibly();
- counter.inc();
- try (Socket socket = new Socket()) {
- socket.connect(new InetSocketAddress(target, port), timeoutInMillis);
- return true;
- } catch (SocketException | SocketTimeoutException ignored) {
- // Will happen a lot when scanning for open ports, so not needed
- } catch (IOException e) {
- System.out.printf("%s -> %s", e.getClass().getSimpleName(), e.getMessage());
- } finally {
- counter.dec();
- socketLimit.release();
- }
-
- return false;
- }
-}