diff --git a/scan_engine.cc b/scan_engine.cc index 846583c0e..43a51e495 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -2653,18 +2653,18 @@ static void ultrascan_port_probe_update(UltraScanInfo *USI, HostScanStats *hss, ultrascan_adjust_timeouts(USI, hss, probe, rcvdtime); if (adjust_timing && - /* If we are not in "noresp_open_scan" and got something back and the - * newstate is PORT_FILTERED then we got ICMP error response. - * ICMP errors are often rate-limited (RFC1812) and/or generated by - * middle-box. No reason to slow down the scan. */ - /* We try to defeat ratelimit only when -T4 or -T5 is used */ - /* We only care ICMP errors timing when we get them during first probe to a port */ + /* If we got a response that meant "filtered", then it was an ICMP error. + These are often rate-limited (RFC 1812) or generated by a different + host. At -T4 and above we consider only the first such response + (probe->tryno == 0) for timing purposes and ignore the rest. */ ((changed && newstate != PORT_FILTERED) || USI->noresp_open_scan || probe->tryno == 0 || o.timing_level < 4) && - /* If we are in --defeat-rst-ratelimit mode, we do not care whether we got RST back or not - * because RST and "no response" both mean PORT_CLOSEDFILTERED. Do not slow down */ - !(o.defeat_rst_ratelimit && newstate == PORT_CLOSEDFILTERED && probe->tryno > 0)) { /* rcvdtime is interesting */ + /* Do not slow down if we are in --defeat-rst-ratelimit mode and the new + state is closed|filtered. We don't care if it's closed|filtered because + of a RST or a timeout because they both mean the same thing. */ + !(o.defeat_rst_ratelimit && newstate == PORT_CLOSEDFILTERED && probe->tryno > 0)) { ultrascan_adjust_timing(USI, hss, probe, rcvdtime); - if (probe->tryno > hss->max_successful_tryno) { + if (rcvdtime != NULL && probe->tryno > hss->max_successful_tryno) { + /* We got a positive response to a higher tryno than we've seen so far. */ hss->max_successful_tryno = probe->tryno; if (o.debugging) log_write(LOG_STDOUT, "Increased max_successful_tryno for %s to %d (packet drop)\n", hss->target->targetipstr(), hss->max_successful_tryno);