diff --git a/osscan2.cc b/osscan2.cc index 50e132440..90ce2e579 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -939,6 +939,8 @@ HostOsScanStats::HostOsScanStats(Target * t) { /* Timing */ timing.cwnd = perf.host_initial_cwnd; timing.ssthresh = perf.initial_ssthresh; /* Will be reduced if any packets are dropped anyway */ + timing.num_replies_expected = 0; + timing.num_replies_received = 0; timing.num_updates = 0; gettimeofday(&timing.last_drop, NULL); @@ -1177,6 +1179,15 @@ double HostOsScanStats::timingRatio() { return (double) msec_taken / msec_ideal; } +double HostOsScanStats::cc_scale() { + double ratio; + + assert(timing.num_replies_received > 0); + ratio = (double) timing.num_replies_expected / timing.num_replies_received; + + return MIN(ratio, perf.cc_scale_max); +} + /****************************************************************************** * Implementation of class HostOsScan * @@ -1218,9 +1229,12 @@ void HostOsScan::adjust_times(HostOsScanStats *hss, OFProbe *probe, struct timev adjust_timeouts2(&(probe->sent), rcvdtime, &(stats->to)); } - hss->timing.num_updates++; + stats->timing.num_replies_expected++; stats->timing.num_updates++; + hss->timing.num_replies_expected++; + hss->timing.num_updates++; + /* Adjust window */ if (probe->tryno > 0 || !rcvdtime) { if (TIMEVAL_AFTER(probe->sent, hss->timing.last_drop)) { @@ -1241,24 +1255,24 @@ void HostOsScan::adjust_times(HostOsScanStats *hss, OFProbe *probe, struct timev if (stats->timing.cwnd < stats->timing.ssthresh) { /* In slow start mode */ - stats->timing.cwnd += perf.slow_incr; + stats->timing.cwnd += perf.slow_incr * stats->cc_scale(); if (stats->timing.cwnd > stats->timing.ssthresh) stats->timing.cwnd = stats->timing.ssthresh; } else { /* Congestion avoidance mode */ - stats->timing.cwnd += perf.ca_incr / stats->timing.cwnd; + stats->timing.cwnd += perf.ca_incr / stats->timing.cwnd * stats->cc_scale(); } if (stats->timing.cwnd > perf.max_cwnd) stats->timing.cwnd = perf.max_cwnd; if (hss->timing.cwnd < hss->timing.ssthresh) { /* In slow start mode */ - hss->timing.cwnd += perf.slow_incr; + hss->timing.cwnd += perf.slow_incr * hss->cc_scale(); if (hss->timing.cwnd > hss->timing.ssthresh) hss->timing.cwnd = hss->timing.ssthresh; } else { /* Congestion avoidance mode */ - hss->timing.cwnd += perf.ca_incr / hss->timing.cwnd; + hss->timing.cwnd += perf.ca_incr / hss->timing.cwnd * hss->cc_scale(); } if (hss->timing.cwnd > perf.max_cwnd) hss->timing.cwnd = perf.max_cwnd; @@ -2166,6 +2180,8 @@ ScanStats::ScanStats() { /* init timing val */ timing.cwnd = perf.group_initial_cwnd; timing.ssthresh = perf.initial_ssthresh; /* Will be reduced if any packets are dropped anyway */ + timing.num_replies_expected = 0; + timing.num_replies_received = 0; timing.num_updates = 0; gettimeofday(&timing.last_drop, NULL); @@ -2188,6 +2204,16 @@ bool ScanStats::sendOK() { } +double ScanStats::cc_scale() { + double ratio; + + assert(timing.num_replies_received > 0); + ratio = (double) timing.num_replies_expected / timing.num_replies_received; + + return MIN(ratio, perf.cc_scale_max); +} + + /****************************************************************************** * Implementation of class HostOsScan * ******************************************************************************/ diff --git a/osscan2.h b/osscan2.h index 4f5a15fab..57fd6c8d5 100644 --- a/osscan2.h +++ b/osscan2.h @@ -242,6 +242,7 @@ class HostOsScanStats { * returned if we didn't send the tseq probes because there was no * open tcp port */ double timingRatio(); + double cc_scale(); private: /* Ports of the targets used in os fingerprinting. */ @@ -306,6 +307,7 @@ class ScanStats { public: ScanStats(); bool sendOK(); /* Returns true if the system says that sending is OK. */ + double cc_scale(); struct ultra_timing_vals timing; struct timeout_info to; /* rtt/timeout info */