diff options
Diffstat (limited to 'src/main/java/com/it_jaros/jscanner/Scanner.java')
| -rw-r--r-- | src/main/java/com/it_jaros/jscanner/Scanner.java | 51 |
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); - } } |
