summaryrefslogtreecommitdiff
path: root/src/main/java/com/it_jaros/network_scanner/Scanner.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/it_jaros/network_scanner/Scanner.java')
-rw-r--r--src/main/java/com/it_jaros/network_scanner/Scanner.java61
1 files changed, 29 insertions, 32 deletions
diff --git a/src/main/java/com/it_jaros/network_scanner/Scanner.java b/src/main/java/com/it_jaros/network_scanner/Scanner.java
index 7ee0276..2153fe6 100644
--- a/src/main/java/com/it_jaros/network_scanner/Scanner.java
+++ b/src/main/java/com/it_jaros/network_scanner/Scanner.java
@@ -1,19 +1,11 @@
package com.it_jaros.network_scanner;
import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
+import java.net.*;
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.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;
@@ -69,7 +61,11 @@ public class Scanner {
}
progressBar.stop();
+ System.out.println("--------------------");
+ System.out.println("Finished scan!");
+ System.out.println("Stats:");
System.out.println("Peak concurrent connects: " + counter.max());
+ System.out.println("--------------------");
return results;
}
@@ -78,23 +74,26 @@ public class Scanner {
AtomicLong portSlotFactory = new AtomicLong(System.nanoTime());
Semaphore maxWorkers = new Semaphore(maxWorkersPerHost);
BitSet openPorts = new BitSet(PortRange.MAX_PORT);
+ BitSet blockedPorts = new BitSet(PortRange.MAX_PORT);
- Progress progress = new Progress(target, portRange.getTotal(), new AtomicInteger(), new AtomicInteger());
+ Progress progress = new Progress(target, portRange.getTotal(), new AtomicInteger(), new AtomicInteger(), new AtomicInteger() );
progressBar.submit(progress);
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
- List<Future<Integer>> futures = new ArrayList<>();
+ List<Future<PortResult>> 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) {
+ PortState state = getPortState(target, currentPort);
+ if (state.equals(PortState.OPEN)) {
progress.open().incrementAndGet();
+ } else if (state.equals(PortState.BLOCKED)) {
+ progress.blocked().incrementAndGet();
}
- return port;
+ return new PortResult(currentPort, state);
} finally {
maxWorkers.release();
progress.done().incrementAndGet();
@@ -103,12 +102,12 @@ public class Scanner {
}
List<Throwable> errors = new ArrayList<>();
- for (Future<Integer> f : futures) {
+ for (Future<PortResult> 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);
+ PortResult portResult = f.get();
+ switch (portResult.state()) {
+ case OPEN -> openPorts.set(portResult.port());
+ case BLOCKED -> blockedPorts.set(portResult.port());
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
@@ -122,11 +121,7 @@ public class Scanner {
}
}
- return new ScanResult(target, openPorts);
- }
-
- private int scanPort(String target, final int currentPort) {
- return isTargetPortOpen(target, currentPort) ? currentPort : -1;
+ return new ScanResult(target, openPorts, blockedPorts);
}
private void waitForSlot(AtomicLong scanSlotFactory) {
@@ -138,21 +133,23 @@ public class Scanner {
}
}
- private boolean isTargetPortOpen(String target, int port) {
+ private PortState getPortState(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) {
+ return PortState.OPEN;
+ } catch (NoRouteToHostException ignored) {
+ // this can be safely ignored because the port is closed if a host is unreachable
+ } catch (ConnectException ignored) {
+ return PortState.BLOCKED;
+ } catch (IOException 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 {
+ } finally {
counter.dec();
socketLimit.release();
}
- return false;
+ return PortState.CLOSED;
}
}