diff options
Diffstat (limited to 'src/main/java/com/it_jaros/jscanner/scan/Scan.java')
| -rw-r--r-- | src/main/java/com/it_jaros/jscanner/scan/Scan.java | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/main/java/com/it_jaros/jscanner/scan/Scan.java b/src/main/java/com/it_jaros/jscanner/scan/Scan.java new file mode 100644 index 0000000..0820abc --- /dev/null +++ b/src/main/java/com/it_jaros/jscanner/scan/Scan.java @@ -0,0 +1,173 @@ +package com.it_jaros.jscanner.scan; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.stream.Stream; + +/** + * Object holder for stateful volatile data during scan + */ +public class Scan { + private final Stream<String> hosts; + private final String ports; + private final Runnable onDone; + private final Counter hostCounter; + private final Counter portCounter; + private final Counter socketCounter; + private final Counter threadCounter; + private long start = 0; + private long stop = 0; + + private Scan(Stream<String> hosts, String ports) { + this(hosts, ports, () -> {}); + } + + private Scan(Stream<String> hosts, String ports, Runnable onDone) { + this.hosts = hosts; + this.ports = ports; + this.onDone = onDone; + this.hostCounter = new Counter(); + this.portCounter = new Counter(); + this.socketCounter = new Counter(); + this.threadCounter = new Counter(); + } + + public static Scan create(ScanOptions options) throws IOException { + if (options.hostsFile() != null) { + return create(options.hostsFile(), options.ports()); + } + return create(options.hostsArgv(), options.ports()); + } + + /** + * Create Scan based on either a source file or stdin + * + * @param sourceFile + * @param ports + * @return + * @throws IOException + */ + public static Scan create(String sourceFile, String ports) { + Stream<String> hosts; + if (sourceFile == null || sourceFile.isEmpty()) { + throw new IllegalArgumentException("Source file is null or empty"); + } + + if ("-".equals(sourceFile)) { + BufferedReader stdinReader = new BufferedReader(new InputStreamReader(System.in)); + hosts = stdinReader.lines(); + return new Scan(hosts, ports); + } + + try { + BufferedReader reader = Files.newBufferedReader(Path.of(sourceFile)); + return new Scan(reader.lines(), ports, () -> { + try { + reader.close(); + } catch (IOException ignore) { + // we ignore it because at this moment the program is shutting down anyway + } + }); + } catch (IOException e) { + throw new ScanException("Error while trying to open source File", e); + } + } + + public static Scan create(List<String> hostsArgv, String ports) { + return new Scan(hostsArgv.stream(), ports); + } + + public Stream<String> getHosts() { + return hosts; + } + + public String getPorts() { + return ports; + } + + public void stop() { + stop = System.currentTimeMillis(); + onDone.run(); + } + + public void start() { + start = System.currentTimeMillis(); + } + + private long getDurationMillis() { + if (stop == 0) { + if (start == 0) { + return 0; + } + return System.currentTimeMillis() - start; + } + return stop - start; + } + + public void portStart() { + this.portCounter.inc(); + this.threadCounter.inc(); + this.socketCounter.inc(); + } + + public void portFinish() { + this.portCounter.dec(); + this.threadCounter.dec(); + this.socketCounter.dec(); + } + + public void hostStart() { + this.hostCounter.inc(); + this.threadCounter.inc(); + } + + public void hostFinish() { + this.threadCounter.dec(); + this.hostCounter.dec(); + } + + public void producerStart() { + this.threadCounter.inc(); + } + + public void producerStop() { + this.threadCounter.dec(); + } + + /** + * This is not an atomic 100% correct snapshot but + * more a relative snapshot optimized more for performance + * than exactness + */ + public Statistics getStatistics() { + return new Statistics( + this.getDurationMillis(), + this.hostCounter.total(), + this.hostCounter.current(), + this.hostCounter.max(), + this.portCounter.total(), + this.portCounter.current(), + this.threadCounter.current(), + this.threadCounter.max(), + this.socketCounter.current(), + this.socketCounter.max() + ); + } + + public record Statistics( + long durationInMillis, + int hostTotal, + int hostCurrent, + int hostMaxConcurrent, + int portTotal, + int portCurrent, + int threadCurrent, + int threadMaxConcurrent, + int socketCurrent, + int socketMaxConcurrent + ) {} +} |
