summaryrefslogtreecommitdiff
path: root/src/main/java/com/it_jaros/jscanner/Scanner.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/it_jaros/jscanner/Scanner.java')
-rw-r--r--src/main/java/com/it_jaros/jscanner/Scanner.java51
1 files changed, 29 insertions, 22 deletions
diff --git a/src/main/java/com/it_jaros/jscanner/Scanner.java b/src/main/java/com/it_jaros/jscanner/Scanner.java
index 3e655a5..55b42fc 100644
--- a/src/main/java/com/it_jaros/jscanner/Scanner.java
+++ b/src/main/java/com/it_jaros/jscanner/Scanner.java
@@ -67,16 +67,23 @@ public class Scanner implements AutoCloseable {
final ProducerState<ScanResult> state = startProducer(
scan.getHosts().iterator(),
maxHostsLimit,
- host -> () -> scanHostPorts(host, scan)
+ host -> () -> {
+ try {
+ scan.getHostCounter().inc();
+ return scanHostPorts(host, scan);
+ } finally {
+ scan.getHostCounter().dec();
+ }
+ },
+ scan.getThreadCounter()
);
// the main thread is the consumer
- // Let the consumer run as long as
- // as the producer runs
+ // Let the consumer run as long as the producer runs
// or if still tasks are pending in pipeline
// we do not listen to canceled here because we want
- // because we want all results (also partial) ones collected here to print
- // whatever is already there
+ // all results (also partial) collected for the consumer
+ // with whatever is there already
while (state.running().get() || state.inPipeline().get() > 0) {
try {
// let's check for results and give add them to our scan data holder object
@@ -92,6 +99,8 @@ public class Scanner implements AutoCloseable {
consumer.accept(result);
}
} finally {
+ scan.getHostTotalCounter().inc();
+ scan.getThreadCounter().dec();
state.activeWorkers().release();
state.inPipeline().decrementAndGet();
}
@@ -118,13 +127,8 @@ public class Scanner implements AutoCloseable {
BitSet filteredPorts = new BitSet(PortRange.MAX_PORT);
HashMap<Integer, ServiceType> serviceTypes = new HashMap<>();
- // 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());
- scan.addHostProgress(progress);
-
if (!disableOnlineCheck && !checkHostOnline(host)) {
- // Visually show that this host is basically done
- progress.done().set(progress.total());
+ // Unreachable host
return new ScanResult(host, openPorts, filteredPorts, serviceTypes);
}
@@ -138,7 +142,8 @@ public class Scanner implements AutoCloseable {
waitForSlot(portSlotFactory);
if (cancelled) return null;
return checkPort(host, port, scan);
- }
+ },
+ scan.getThreadCounter()
);
// consumer is the main thread
@@ -159,21 +164,19 @@ public class Scanner implements AutoCloseable {
// bitset is not thread-safe, so it is set
// outside the other virtual threads that update progress
openPorts.set(portResult.getPort());
- progress.open().incrementAndGet();
serviceTypes.put(portResult.getPort(), ServiceDetector.detect(portResult.getBanner()));
}
case FILTERED -> {
filteredPorts.set(portResult.getPort());
- progress.filtered().incrementAndGet();
}
default -> {
// sonarcube glücklich machen
}
}
} finally {
+ scan.getThreadCounter().dec();
state.activeWorkers().release();
state.inPipeline().decrementAndGet();
- progress.done().incrementAndGet();
}
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
@@ -201,13 +204,14 @@ public class Scanner implements AutoCloseable {
* @param <OUTPUT>
* @return
*/
- private <INPUT, OUTPUT> ProducerState<OUTPUT> startProducer(Iterator<INPUT> queue, int maxWorkers, Function<INPUT, Callable<OUTPUT>> taskFactory) {
+ private <INPUT, OUTPUT> ProducerState<OUTPUT> startProducer(Iterator<INPUT> queue, int maxWorkers, Function<INPUT, Callable<OUTPUT>> taskFactory, Counter threadCounter) {
final AtomicInteger inPipeline = new AtomicInteger(0);
final AtomicBoolean running = new AtomicBoolean(true);
final Semaphore activeWorkers = new Semaphore(maxWorkers);
CompletionService<OUTPUT> completionService = new ExecutorCompletionService<>(executor);
executor.submit(() -> {
try {
+ threadCounter.inc();
while (queue.hasNext() && !cancelled) {
activeWorkers.acquire();
@@ -226,6 +230,7 @@ public class Scanner implements AutoCloseable {
final INPUT item = queue.next();
Callable<OUTPUT> task = taskFactory.apply(item);
inPipeline.incrementAndGet();
+ threadCounter.inc();
try {
// here we are filling the completion service
// host <-> virtual thread
@@ -233,6 +238,7 @@ public class Scanner implements AutoCloseable {
submitted = true;
} catch (Throwable e) {
inPipeline.decrementAndGet();
+ threadCounter.dec();
throw e;
}
} finally {
@@ -244,6 +250,7 @@ public class Scanner implements AutoCloseable {
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
+ threadCounter.dec();
running.set(false);
}
});
@@ -277,7 +284,7 @@ public class Scanner implements AutoCloseable {
// don't allow more sockets then specified
socketLimit.acquire();
// count how many ports are concurrently checked
- scan.incSocketCounter();
+ scan.getSocketCounter().inc();
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), timeoutInMillis);
result.setState(PortState.OPEN);
@@ -292,7 +299,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 {
- scan.decSocketCounter();
+ scan.getSocketCounter().dec();
socketLimit.release();
}
@@ -314,6 +321,10 @@ public class Scanner implements AutoCloseable {
return null;
}
+ public boolean awaitTermination(Duration duration) throws InterruptedException {
+ return executor.awaitTermination(duration.toMillis(), TimeUnit.MILLISECONDS);
+ }
+
public void cancel() {
if (!cancelled) {
cancelled = true;
@@ -332,8 +343,4 @@ public class Scanner implements AutoCloseable {
public void close() throws Exception {
cancel();
}
-
- public boolean awaitTermination(Duration duration) throws InterruptedException {
- return executor.awaitTermination(duration.toMillis(), TimeUnit.MILLISECONDS);
- }
}