start method

Starts the scanning task and returns a PortScannerTaskReport with the results.

Implementation

Future<PortScannerTaskReport> start() async {
  if (_isRunning) {
    throw PortScannerTaskException('Scanning is already in progress');
  }
  _isRunning = true;

  await _resolveHost();

  // Split ports into sublists based on parallelism
  var portsPerScanner = (ports.length / parallelism).ceil();
  var sublists = <List<int>>[];
  for (int i = 0; i < ports.length; i += portsPerScanner) {
    sublists.add(ports.sublist(i, min(i + portsPerScanner, ports.length)));
  }

  // Create ScannerIsolateInteractor for each sublist
  _scanners.clear();
  for (var sublist in sublists) {
    _scanners.add(
      ScannerIsolateInteractor(
        host,
        sublist,
        shuffle: shuffle,
        parallelism: 1, // Assuming one isolate per sublist
        socketTimeout: socketTimeout,
        useUdp: true, // Indicate that this is a UDP scan
      ),
    );
  }

  // Start scanning concurrently
  try {
    var reports =
        await Future.wait(_scanners.map((scanner) => scanner.scan()));

    // Aggregate results
    var scanReport = Report(host, ports, status: ReportStatus.finished);
    for (var report in reports) {
      scanReport.addOpen(ports: report.openPorts);
      scanReport.addClosed(ports: report.closedPorts);
      scanReport.addFiltered(ports: report.filteredPorts);
    }

    _isRunning = false;
    return _reportToPortScannerTaskReport(scanReport);
  } catch (e) {
    _isRunning = false;
    rethrow;
  }
}