1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-12 10:49:02 +00:00

Undo r7283 (doAnyOutstandingRestransmits performance improvements) pending

further testing on Windows.
This commit is contained in:
david
2008-05-03 05:42:16 +00:00
parent 2b35d4d1c5
commit 7b9cc11e1e

View File

@@ -485,22 +485,13 @@ public:
maximum tryno and expired) are not counted in maximum tryno and expired) are not counted in
probes_outstanding. */ probes_outstanding. */
list<UltraProbe *> probes_outstanding; list<UltraProbe *> probes_outstanding;
/* A list of iterators that point into probes_outstanding. The iterators point
to those probes that can be retransmitted immediately, i.e., those that are
timed out but not expired, with a tryno less than the maximum. */
list<list<UltraProbe *>::iterator> probes_waiting_retransmit;
/* The number of probes in probes_outstanding, minus the inactive (timed out) ones */ /* The number of probes in probes_outstanding, minus the inactive (timed out) ones */
unsigned int num_probes_active; unsigned int num_probes_active;
/* Probes timed out but not yet retransmitted because of congestion
/* Probes timed out but still in probes_outstanding because of congestion control limits or because more retransmits may not be
control limits or because more retransmits may not be necessary. This neccessary. Note that probes on probe_bench are not included
number may exceed probes_waiting_retransmit, because not all timed-out in this value. */
probes are eligible for immediate retransmission (it depends on the tryno unsigned int num_probes_waiting_retransmit;
and other factors). Note that probes on probe_bench are not included in
this value. */
unsigned int num_probes_timed_out;
unsigned int num_probes_outstanding() { return probes_outstanding.size(); } unsigned int num_probes_outstanding() { return probes_outstanding.size(); }
/* Call this instead of checking for num_probes_outstanding() == 0 because it /* Call this instead of checking for num_probes_outstanding() == 0 because it
avoids a potential traversal of the list to find the size. */ avoids a potential traversal of the list to find the size. */
@@ -525,7 +516,7 @@ public:
vector<u8> retry_stack_tries; vector<u8> retry_stack_tries;
/* tryno of probes on the retry queue */ /* tryno of probes on the retry queue */
/* Moves the given probe from the probes_outstanding list, to /* Moves the given probe from the probes_outstanding list, to
probe_bench, and decrements num_probes_timed_out accordingly */ probe_bench, and decrements num_probes_waiting_retransmit accordingly */
void moveProbeToBench(list<UltraProbe *>::iterator probeI); void moveProbeToBench(list<UltraProbe *>::iterator probeI);
/* Dismiss all probe attempts on bench -- the ports are marked /* Dismiss all probe attempts on bench -- the ports are marked
'filtered' or whatever is appropriate for having no response */ 'filtered' or whatever is appropriate for having no response */
@@ -1038,7 +1029,7 @@ HostScanStats::HostScanStats(Target *t, UltraScanInfo *UltraSI) {
sent_icmp_mask = false; sent_icmp_mask = false;
sent_icmp_ts = false; sent_icmp_ts = false;
num_probes_active = 0; num_probes_active = 0;
num_probes_timed_out = 0; num_probes_waiting_retransmit = 0;
lastping_sent = lastprobe_sent = lastrcvd = USI->now; lastping_sent = lastprobe_sent = lastrcvd = USI->now;
lastping_sent_numprobes = 0; lastping_sent_numprobes = 0;
memset(&pingprobe, 0, sizeof(pingprobe)); memset(&pingprobe, 0, sizeof(pingprobe));
@@ -1150,7 +1141,7 @@ bool HostScanStats::sendOK(struct timeval *when) {
getTiming(&tmng); getTiming(&tmng);
if (tmng.cwnd >= num_probes_active + .5 && if (tmng.cwnd >= num_probes_active + .5 &&
(freshPortsLeft() || !probes_waiting_retransmit.empty() || !retry_stack.empty())) { (freshPortsLeft() || num_probes_waiting_retransmit || !retry_stack.empty())) {
if (when) *when = USI->now; if (when) *when = USI->now;
return true; return true;
} }
@@ -1888,8 +1879,8 @@ void HostScanStats::destroyOutstandingProbe(list<UltraProbe *>::iterator probeI)
} }
if (!probe->isPing() && probe->timedout && !probe->retransmitted) { if (!probe->isPing() && probe->timedout && !probe->retransmitted) {
assert(num_probes_timed_out > 0); assert(num_probes_waiting_retransmit > 0);
num_probes_timed_out--; num_probes_waiting_retransmit--;
} }
/* Remove it from scan watch lists, if it exists on them. */ /* Remove it from scan watch lists, if it exists on them. */
@@ -1897,8 +1888,6 @@ void HostScanStats::destroyOutstandingProbe(list<UltraProbe *>::iterator probeI)
USI->gstats->CSI->clearSD(probe->CP()->sd); USI->gstats->CSI->clearSD(probe->CP()->sd);
probes_outstanding.erase(probeI); probes_outstanding.erase(probeI);
probes_waiting_retransmit.remove(probeI);
delete probe; delete probe;
} }
@@ -2033,13 +2022,7 @@ void HostScanStats::markProbeTimedout(list<UltraProbe *>::iterator probeI) {
ultrascan_adjust_timing(USI, this, probe, NULL); ultrascan_adjust_timing(USI, this, probe, NULL);
/* I'll leave it in the queue in case some response ever does /* I'll leave it in the queue in case some response ever does
come */ come */
} else { } else num_probes_waiting_retransmit++;
num_probes_timed_out++;
int maxtries = allowedTryno(NULL, NULL);
if (probe->tryno < maxtries)
/* Get ready to send it back out right away. */
probes_waiting_retransmit.push_back(probeI);
}
if (probe->type == UltraProbe::UP_CONNECT && probe->CP()->sd >= 0 ) { if (probe->type == UltraProbe::UP_CONNECT && probe->CP()->sd >= 0 ) {
/* Free the socket as that is a valuable resource, though it is a shame /* Free the socket as that is a valuable resource, though it is a shame
@@ -2052,7 +2035,7 @@ void HostScanStats::markProbeTimedout(list<UltraProbe *>::iterator probeI) {
bool HostScanStats::completed() { bool HostScanStats::completed() {
/* If there are probes active or awaiting retransmission, we are not done. */ /* If there are probes active or awaiting retransmission, we are not done. */
if (num_probes_active != 0 || num_probes_timed_out != 0 if (num_probes_active != 0 || num_probes_waiting_retransmit != 0
|| !probe_bench.empty() || !retry_stack.empty()) { || !probe_bench.empty() || !retry_stack.empty()) {
return false; return false;
} }
@@ -2372,7 +2355,7 @@ void HostScanStats::retransmitBench() {
} }
/* Moves the given probe from the probes_outstanding list, to /* Moves the given probe from the probes_outstanding list, to
probe_bench, and decrements num_probes_timed_out probe_bench, and decrements num_probes_waiting_retransmit
accordingly */ accordingly */
void HostScanStats::moveProbeToBench(list<UltraProbe *>::iterator probeI) { void HostScanStats::moveProbeToBench(list<UltraProbe *>::iterator probeI) {
UltraProbe *probe = *probeI; UltraProbe *probe = *probeI;
@@ -2384,8 +2367,7 @@ void HostScanStats::moveProbeToBench(list<UltraProbe *>::iterator probeI) {
} }
probe_bench.push_back(*probe->pspec()); probe_bench.push_back(*probe->pspec());
probes_outstanding.erase(probeI); probes_outstanding.erase(probeI);
probes_waiting_retransmit.remove(probeI); num_probes_waiting_retransmit--;
num_probes_timed_out--;
delete probe; delete probe;
} }
@@ -3055,8 +3037,8 @@ static void retransmitProbe(UltraScanInfo *USI, HostScanStats *hss,
if (newProbe) if (newProbe)
newProbe->prevSent = probe->sent; newProbe->prevSent = probe->sent;
probe->retransmitted = true; probe->retransmitted = true;
assert(hss->num_probes_timed_out > 0); assert(hss->num_probes_waiting_retransmit > 0);
hss->num_probes_timed_out--; hss->num_probes_waiting_retransmit--;
hss->numprobes_sent++; hss->numprobes_sent++;
USI->gstats->probes_sent++; USI->gstats->probes_sent++;
} }
@@ -3065,7 +3047,7 @@ static void retransmitProbe(UltraScanInfo *USI, HostScanStats *hss,
timed out probes, then try to retransmit them as appropriate */ timed out probes, then try to retransmit them as appropriate */
static void doAnyOutstandingRetransmits(UltraScanInfo *USI) { static void doAnyOutstandingRetransmits(UltraScanInfo *USI) {
list<HostScanStats *>::iterator hostI; list<HostScanStats *>::iterator hostI;
list<list<UltraProbe *>::iterator>::iterator probeII; list<UltraProbe *>::iterator probeI;
HostScanStats *host = NULL; HostScanStats *host = NULL;
UltraProbe *probe = NULL; UltraProbe *probe = NULL;
int retrans = 0; /* Number of retransmissions during a loop */ int retrans = 0; /* Number of retransmissions during a loop */
@@ -3088,29 +3070,34 @@ static void doAnyOutstandingRetransmits(UltraScanInfo *USI) {
hostI++) { hostI++) {
host = *hostI; host = *hostI;
/* Skip this host if it has nothing to send. */ /* Skip this host if it has nothing to send. */
if (host->probes_waiting_retransmit.empty()) if ((host->num_probes_active == 0
&& host->num_probes_waiting_retransmit == 0))
continue; continue;
if (!host->sendOK(NULL)) if (!host->sendOK(NULL))
continue; continue;
assert(!host->probes_outstanding.empty());
probeI = host->probes_outstanding.end();
maxtries = host->allowedTryno(NULL, NULL); maxtries = host->allowedTryno(NULL, NULL);
probeII = host->probes_waiting_retransmit.begin(); do {
probe = **probeII; probeI--;
assert(probe->timedout && !probe->retransmitted && probe = *probeI;
maxtries > probe->tryno && !probe->isPing()); if (probe->timedout && !probe->retransmitted &&
/* For rate limit detection, we delay the first time a new tryno maxtries > probe->tryno && !probe->isPing()) {
is seen, as long as we are scanning at least 2 ports */ /* For rate limit detection, we delay the first time a new tryno
if (probe->tryno + 1 > (int) host->rld.max_tryno_sent && is seen, as long as we are scanning at least 2 ports */
USI->gstats->numprobes > 1) { if (probe->tryno + 1 > (int) host->rld.max_tryno_sent &&
host->rld.max_tryno_sent = probe->tryno + 1; USI->gstats->numprobes > 1) {
host->rld.rld_waiting = true; host->rld.max_tryno_sent = probe->tryno + 1;
TIMEVAL_MSEC_ADD(host->rld.rld_waittime, USI->now, 1000); host->rld.rld_waiting = true;
} else { TIMEVAL_MSEC_ADD(host->rld.rld_waittime, USI->now, 1000);
host->rld.rld_waiting = false; } else {
host->probes_waiting_retransmit.erase(probeII); host->rld.rld_waiting = false;
retransmitProbe(USI, host, probe); retransmitProbe(USI, host, probe);
retrans++; retrans++;
} }
/* Only do one probe per host to spread load */ break; /* I only do one probe per host for now to spread load */
}
} while (probeI != host->probes_outstanding.begin());
} }
} while (USI->gstats->sendOK(NULL) && retrans != 0); } while (USI->gstats->sendOK(NULL) && retrans != 0);
@@ -3132,7 +3119,7 @@ static void printAnyStats(UltraScanInfo *USI) {
/* Print debugging states for each host being scanned */ /* Print debugging states for each host being scanned */
if (o.debugging > 2) { if (o.debugging > 2) {
log_write(LOG_PLAIN, "**TIMING STATS** (%.4fs): IP, probes active/freshportsleft/retry_stack/outstanding/timedout/onbench, cwnd/ccthresh/delay, timeout/srtt/rttvar/\n", o.TimeSinceStartMS() / 1000.0); log_write(LOG_PLAIN, "**TIMING STATS** (%.4fs): IP, probes active/freshportsleft/retry_stack/outstanding/retranwait/onbench, cwnd/ccthresh/delay, timeout/srtt/rttvar/\n", o.TimeSinceStartMS() / 1000.0);
log_write(LOG_PLAIN, " Groupstats (%d/%d incomplete): %d/*/*/*/*/* %.2f/%d/* %d/%d/%d\n", log_write(LOG_PLAIN, " Groupstats (%d/%d incomplete): %d/*/*/*/*/* %.2f/%d/* %d/%d/%d\n",
USI->numIncompleteHosts(), USI->numInitialHosts(), USI->numIncompleteHosts(), USI->numInitialHosts(),
USI->gstats->num_probes_active, USI->gstats->timing.cwnd, USI->gstats->num_probes_active, USI->gstats->timing.cwnd,
@@ -3148,7 +3135,7 @@ static void printAnyStats(UltraScanInfo *USI) {
hss->num_probes_active, hss->freshPortsLeft(), hss->num_probes_active, hss->freshPortsLeft(),
(int) hss->retry_stack.size(), (int) hss->retry_stack.size(),
hss->num_probes_outstanding(), hss->num_probes_outstanding(),
hss->num_probes_timed_out, (int) hss->probe_bench.size(), hss->num_probes_waiting_retransmit, (int) hss->probe_bench.size(),
hosttm.cwnd, hosttm.ccthresh, hss->sdn.delayms, hosttm.cwnd, hosttm.ccthresh, hss->sdn.delayms,
hss->probeTimeout(), hss->target->to.srtt, hss->probeTimeout(), hss->target->to.srtt,
hss->target->to.rttvar); hss->target->to.rttvar);