Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculate estimated time of completion (ETC) based on slowest host #1890

Open
djcater opened this issue Jan 12, 2020 · 0 comments
Open

Calculate estimated time of completion (ETC) based on slowest host #1890

djcater opened this issue Jan 12, 2020 · 0 comments

Comments

@djcater
Copy link

@djcater djcater commented Jan 12, 2020

Nmap appears to calculate the estimated time of completion (ETC) using this code in timing.cc:

/* Return an estimate of the time remaining if a process was started at begin
   and is perc_done of the way finished. Returns inf if perc_done == 0.0. */
static double estimate_time_left(double perc_done,
                                 const struct timeval *begin,
                                 const struct timeval *now) {
  double time_used_s;
  double time_needed_s;

  time_used_s = difftime(now->tv_sec, begin->tv_sec);
  time_needed_s = time_used_s / perc_done;

  return time_needed_s - time_used_s;
}

This is basically looking at the percentage completed so far since the start time, and extrapolating to an end time based on that, which makes sense, and is a simple calculation.

However, the assumptions it makes break down when some hosts are being scanned much more slowly than others (which happens a lot in practice).

Obviously this estimate is never going to be perfect, and scan conditions can change all the time, but I think a much more reliable algorithm would be:

  1. Calculate ETC as above but per host (use per-host start time, and per-host percentage completed)
  2. Take the latest ETC of all hosts, and print that instead

This seems to me to make more sense, because no-one is really interested in the average rate of progress across all hosts, as Nmap doesn't produce useful output files for a hostgroup until every host in the group has finished. Therefore, calculating when the slowest host is going to finish will give a better estimate of when the whole scan (or hostgroup) will finish.

As an example, if you scan 1000 ports on 100 hosts, there are 100,000 ports in total. If 9 of the hosts finish within 1 minute, but the 10th host has slowed right down to a scan delay of 1000 (maybe due to TCP RST rate-limiting or something) and has only done 60 ports, then Nmap will tell you that there are 7 seconds left, because you are 90% of the way through the whole scan in 1 minute, but actually, there are over 15 minutes left. This effect gets amplified the more ports you are scanning on the slowest host.

Typically I have verbose output on, and notice the messages about scan delay increasing, and kill the scan and restart it without the slow hosts, or cap the scan delay, or use the "defeat" flags, but having a more realistic ETC might help people realise that certain scans are in effect never going to finish within the timeframe that they have, so they can cut their losses and change tactics.

I'm not sure how much effort that is to factor into the code.

Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.