mirror of
https://github.com/nmap/nmap.git
synced 2025-12-18 05:29:02 +00:00
Merge from /nmap-exp/david/nmap-perf. A summary of changes:
Don't make a host the global ping host until it moves to the completed hosts list, and only change the global ping probe if the new probe is no worse than the old (according to pingprobe_is_better). Restore the ping magnifier for host congestion window updates. Ignore the timing of certain ICMP errors that are likely to be rate limited and don't change the port or host state. Avoid making timing pings out of probes that elicit such errors. This used to be done only for port scans and only at -T4 and above (and didn't prohibit the creation of timing pings). Now it is done for host discovery too, and at all timing levels. Gracefully handle updates from the recent past in RateMeter. Doesn't affect performance, but avoids a rare assertion failure.
This commit is contained in:
197
scan_engine.cc
197
scan_engine.cc
@@ -367,8 +367,8 @@ public:
|
|||||||
|
|
||||||
struct send_delay_nfo {
|
struct send_delay_nfo {
|
||||||
unsigned int delayms; /* Milliseconds to delay between probes */
|
unsigned int delayms; /* Milliseconds to delay between probes */
|
||||||
/* The number of successful and dropped probes since the last time delayms
|
/* The number of successful and dropped probes since the last time the delay
|
||||||
was changed */
|
was changed. The ratio controls when the rate drops. */
|
||||||
unsigned int goodRespSinceDelayChanged;
|
unsigned int goodRespSinceDelayChanged;
|
||||||
unsigned int droppedRespSinceDelayChanged;
|
unsigned int droppedRespSinceDelayChanged;
|
||||||
struct timeval last_boost; /* Most recent time of increase to delayms. Init to creation time. */
|
struct timeval last_boost; /* Most recent time of increase to delayms. Init to creation time. */
|
||||||
@@ -1166,7 +1166,6 @@ unsigned long HostScanStats::probeExpireTime(const UltraProbe *probe) {
|
|||||||
true. */
|
true. */
|
||||||
bool HostScanStats::sendOK(struct timeval *when) {
|
bool HostScanStats::sendOK(struct timeval *when) {
|
||||||
struct ultra_timing_vals tmng;
|
struct ultra_timing_vals tmng;
|
||||||
int packTime;
|
|
||||||
list<UltraProbe *>::iterator probeI;
|
list<UltraProbe *>::iterator probeI;
|
||||||
struct timeval probe_to, earliest_to, sendTime;
|
struct timeval probe_to, earliest_to, sendTime;
|
||||||
long tdiff;
|
long tdiff;
|
||||||
@@ -1187,18 +1186,19 @@ bool HostScanStats::sendOK(struct timeval *when) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rld.rld_waiting) {
|
if (rld.rld_waiting) {
|
||||||
packTime = TIMEVAL_MSEC_SUBTRACT(rld.rld_waittime, USI->now);
|
if (TIMEVAL_AFTER(rld.rld_waittime, USI->now)) {
|
||||||
if (packTime <= 0) {
|
if (when)
|
||||||
if (when) *when = USI->now;
|
*when = rld.rld_waittime;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (when)
|
||||||
|
*when = USI->now;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (when) *when = rld.rld_waittime;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdn.delayms) {
|
if (sdn.delayms) {
|
||||||
packTime = TIMEVAL_MSEC_SUBTRACT(USI->now, lastprobe_sent);
|
if (TIMEVAL_MSEC_SUBTRACT(USI->now, lastprobe_sent) < (int) sdn.delayms) {
|
||||||
if (packTime < (int) sdn.delayms) {
|
|
||||||
if (when) { TIMEVAL_MSEC_ADD(*when, lastprobe_sent, sdn.delayms); }
|
if (when) { TIMEVAL_MSEC_ADD(*when, lastprobe_sent, sdn.delayms); }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1230,7 +1230,7 @@ bool HostScanStats::sendOK(struct timeval *when) {
|
|||||||
// Will any scan delay affect this?
|
// Will any scan delay affect this?
|
||||||
if (sdn.delayms) {
|
if (sdn.delayms) {
|
||||||
TIMEVAL_MSEC_ADD(sendTime, lastprobe_sent, sdn.delayms);
|
TIMEVAL_MSEC_ADD(sendTime, lastprobe_sent, sdn.delayms);
|
||||||
if (TIMEVAL_MSEC_SUBTRACT(sendTime, USI->now) < 0)
|
if (TIMEVAL_BEFORE(sendTime, USI->now))
|
||||||
sendTime = USI->now;
|
sendTime = USI->now;
|
||||||
tdiff = TIMEVAL_MSEC_SUBTRACT(earliest_to, sendTime);
|
tdiff = TIMEVAL_MSEC_SUBTRACT(earliest_to, sendTime);
|
||||||
|
|
||||||
@@ -1701,6 +1701,9 @@ bool UltraScanInfo::numIncompleteHostsLessThan(unsigned int n) {
|
|||||||
return count < n;
|
return count < n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pingprobe_is_better(const probespec *new_probe, int new_state,
|
||||||
|
const probespec *old_probe, int old_state);
|
||||||
|
|
||||||
/* Removes any hosts that have completed their scans from the incompleteHosts
|
/* Removes any hosts that have completed their scans from the incompleteHosts
|
||||||
list, and remove any hosts from completedHosts which have exceeded their
|
list, and remove any hosts from completedHosts which have exceeded their
|
||||||
lifetime. Returns the number of hosts removed. */
|
lifetime. Returns the number of hosts removed. */
|
||||||
@@ -1771,6 +1774,16 @@ int UltraScanInfo::removeCompletedHosts() {
|
|||||||
completedHosts.push_front(hss);
|
completedHosts.push_front(hss);
|
||||||
incompleteHosts.erase(hostI);
|
incompleteHosts.erase(hostI);
|
||||||
hostsRemoved++;
|
hostsRemoved++;
|
||||||
|
/* Consider making this host the new global ping host during its
|
||||||
|
retirement in the completed hosts list. */
|
||||||
|
HostScanStats *pinghost = gstats->pinghost;
|
||||||
|
if ((pinghost == NULL && hss->target->pingprobe.type != PS_NONE)
|
||||||
|
|| (pinghost != NULL && pinghost->num_probes_active == 0
|
||||||
|
&& !pingprobe_is_better(&pinghost->target->pingprobe, pinghost->target->pingprobe_state, &hss->target->pingprobe, hss->target->pingprobe_state))) {
|
||||||
|
if (o.debugging > 1)
|
||||||
|
log_write(LOG_PLAIN, "Changing global ping host to %s.\n", hss->target->targetipstr());
|
||||||
|
gstats->pinghost = hss;
|
||||||
|
}
|
||||||
if (timedout) gstats->num_hosts_timedout++;
|
if (timedout) gstats->num_hosts_timedout++;
|
||||||
hss->target->stopTimeOutClock(&now);
|
hss->target->stopTimeOutClock(&now);
|
||||||
}
|
}
|
||||||
@@ -2072,12 +2085,12 @@ static void ultrascan_adjust_timing(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
if (o.debugging > 1)
|
if (o.debugging > 1)
|
||||||
log_write(LOG_PLAIN, "Ultrascan DROPPED %sprobe packet to %s detected\n", probe->isPing()? "PING " : "", hss->target->targetipstr());
|
log_write(LOG_PLAIN, "Ultrascan DROPPED %sprobe packet to %s detected\n", probe->isPing()? "PING " : "", hss->target->targetipstr());
|
||||||
// Drops often come in big batches, but we only want one decrease per batch.
|
// Drops often come in big batches, but we only want one decrease per batch.
|
||||||
if (TIMEVAL_SUBTRACT(probe->sent, hss->timing.last_drop) > 0) {
|
if (TIMEVAL_AFTER(probe->sent, hss->timing.last_drop)) {
|
||||||
hss->timing.cwnd = USI->perf.low_cwnd;
|
hss->timing.cwnd = USI->perf.low_cwnd;
|
||||||
hss->timing.ssthresh = (int) MAX(hss->num_probes_active / USI->perf.host_drop_ssthresh_divisor, 2);
|
hss->timing.ssthresh = (int) MAX(hss->num_probes_active / USI->perf.host_drop_ssthresh_divisor, 2);
|
||||||
hss->timing.last_drop = USI->now;
|
hss->timing.last_drop = USI->now;
|
||||||
}
|
}
|
||||||
if (TIMEVAL_SUBTRACT(probe->sent, USI->gstats->timing.last_drop) > 0) {
|
if (TIMEVAL_AFTER(probe->sent, USI->gstats->timing.last_drop)) {
|
||||||
USI->gstats->timing.cwnd = MAX(USI->perf.low_cwnd, USI->gstats->timing.cwnd / USI->perf.group_drop_cwnd_divisor);
|
USI->gstats->timing.cwnd = MAX(USI->perf.low_cwnd, USI->gstats->timing.cwnd / USI->perf.group_drop_cwnd_divisor);
|
||||||
USI->gstats->timing.ssthresh = (int) MAX(USI->gstats->num_probes_active / USI->perf.group_drop_ssthresh_divisor, 2);
|
USI->gstats->timing.ssthresh = (int) MAX(USI->gstats->num_probes_active / USI->perf.group_drop_ssthresh_divisor, 2);
|
||||||
USI->gstats->timing.last_drop = USI->now;
|
USI->gstats->timing.last_drop = USI->now;
|
||||||
@@ -2102,12 +2115,12 @@ static void ultrascan_adjust_timing(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
|
|
||||||
if (hss->timing.cwnd < hss->timing.ssthresh) {
|
if (hss->timing.cwnd < hss->timing.ssthresh) {
|
||||||
/* In slow start mode */
|
/* In slow start mode */
|
||||||
hss->timing.cwnd += 1.0 * hss->cc_scale();
|
hss->timing.cwnd += ping_magnifier * hss->cc_scale();
|
||||||
if (hss->timing.cwnd > hss->timing.ssthresh)
|
if (hss->timing.cwnd > hss->timing.ssthresh)
|
||||||
hss->timing.cwnd = hss->timing.ssthresh;
|
hss->timing.cwnd = hss->timing.ssthresh;
|
||||||
} else {
|
} else {
|
||||||
/* Congestion avoidance mode */
|
/* Congestion avoidance mode */
|
||||||
hss->timing.cwnd += 1.0 / hss->timing.cwnd * hss->cc_scale();
|
hss->timing.cwnd += ping_magnifier / hss->timing.cwnd * hss->cc_scale();
|
||||||
}
|
}
|
||||||
if (hss->timing.cwnd > USI->perf.max_cwnd)
|
if (hss->timing.cwnd > USI->perf.max_cwnd)
|
||||||
hss->timing.cwnd = USI->perf.max_cwnd;
|
hss->timing.cwnd = USI->perf.max_cwnd;
|
||||||
@@ -2380,7 +2393,7 @@ static bool pingprobe_is_better(const probespec *new_probe, int new_state,
|
|||||||
return pingprobe_score(new_probe, new_state) > pingprobe_score(old_probe, old_state);
|
return pingprobe_score(new_probe, new_state) > pingprobe_score(old_probe, old_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ultrascan_host_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
|
static bool ultrascan_host_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
|
||||||
const probespec *pspec, int newstate);
|
const probespec *pspec, int newstate);
|
||||||
|
|
||||||
/* Like ultrascan_port_probe_update(), except it is called with just a
|
/* Like ultrascan_port_probe_update(), except it is called with just a
|
||||||
@@ -2566,25 +2579,28 @@ static const char *readhoststate(int state) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update state of the host in hss based on its current state and newstate. */
|
/* Update state of the host in hss based on its current state and newstate.
|
||||||
static void ultrascan_host_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
|
Returns true if the state was changed. */
|
||||||
|
static bool ultrascan_host_pspec_update(UltraScanInfo *USI, HostScanStats *hss,
|
||||||
const probespec *pspec, int newstate) {
|
const probespec *pspec, int newstate) {
|
||||||
|
unsigned int oldstate = hss->target->flags;
|
||||||
/* If the host is already up, ignore any further updates. */
|
/* If the host is already up, ignore any further updates. */
|
||||||
if (hss->target->flags != HOST_UP) {
|
if (hss->target->flags != HOST_UP) {
|
||||||
assert(newstate == HOST_UP || newstate == HOST_DOWN);
|
assert(newstate == HOST_UP || newstate == HOST_DOWN);
|
||||||
hss->target->flags = newstate;
|
hss->target->flags = newstate;
|
||||||
}
|
}
|
||||||
|
return hss->target->flags != oldstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when a new status is determined for host in hss (eg. it is
|
/* Called when a new status is determined for host in hss (eg. it is
|
||||||
found to be up or down by a ping/ping_arp scan. The probe that led
|
found to be up or down by a ping/ping_arp scan. The probe that led
|
||||||
to this new decision is in probeI. This function needs to update
|
to this new decision is in probeI. This function needs to update
|
||||||
timing information and other stats as appropriate. If rcvdtime is
|
timing information and other stats as appropriate. If
|
||||||
NULL or adjust_timing is false, packet stats are not updated. */
|
adjust_timing_hint is false, packet stats are not updated. */
|
||||||
static void ultrascan_host_probe_update(UltraScanInfo *USI, HostScanStats *hss,
|
static void ultrascan_host_probe_update(UltraScanInfo *USI, HostScanStats *hss,
|
||||||
list<UltraProbe *>::iterator probeI,
|
list<UltraProbe *>::iterator probeI,
|
||||||
int newstate, struct timeval *rcvdtime,
|
int newstate, struct timeval *rcvdtime,
|
||||||
bool adjust_timing = true) {
|
bool adjust_timing_hint = true) {
|
||||||
UltraProbe *probe = *probeI;
|
UltraProbe *probe = *probeI;
|
||||||
|
|
||||||
if (o.debugging > 1) {
|
if (o.debugging > 1) {
|
||||||
@@ -2594,32 +2610,43 @@ static void ultrascan_host_probe_update(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
log_write(LOG_STDOUT, "%s called for machine %s state %s -> %s (trynum %d time: %ld)\n", __func__, hss->target->targetipstr(), readhoststate(hss->target->flags), readhoststate(newstate), probe->tryno, (long) TIMEVAL_SUBTRACT(tv, probe->sent));
|
log_write(LOG_STDOUT, "%s called for machine %s state %s -> %s (trynum %d time: %ld)\n", __func__, hss->target->targetipstr(), readhoststate(hss->target->flags), readhoststate(newstate), probe->tryno, (long) TIMEVAL_SUBTRACT(tv, probe->sent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ultrascan_host_pspec_update(USI, hss, probe->pspec(), newstate);
|
||||||
|
|
||||||
ultrascan_adjust_timeouts(USI, hss, probe, rcvdtime);
|
ultrascan_adjust_timeouts(USI, hss, probe, rcvdtime);
|
||||||
|
|
||||||
|
/* Decide whether to adjust timing. We and together a bunch of conditions.
|
||||||
|
First, don't adjust timing if adjust_timing_hint is false. */
|
||||||
|
bool adjust_timing = adjust_timing_hint;
|
||||||
|
bool adjust_ping = adjust_timing_hint;
|
||||||
|
|
||||||
|
/* If we got a response that meant "down", then it was an ICMP error. These
|
||||||
|
are often rate-limited (RFC 1812) or generated by a different host. We only
|
||||||
|
allow such responses to increase, not decrease, scanning speed by
|
||||||
|
disallowing drops (probe->tryno > 0), and we don't allow changing the ping
|
||||||
|
probe to something that's likely to get dropped. */
|
||||||
|
if (rcvdtime != NULL && newstate == HOST_DOWN) {
|
||||||
|
if (probe->tryno > 0) {
|
||||||
|
if (adjust_timing && o.debugging > 1)
|
||||||
|
log_write(LOG_PLAIN, "Response for %s means new state is down; not adjusting timing.\n", hss->target->targetipstr());
|
||||||
|
adjust_timing = false;
|
||||||
|
}
|
||||||
|
adjust_ping = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (adjust_timing)
|
if (adjust_timing)
|
||||||
ultrascan_adjust_timing(USI, hss, probe, rcvdtime);
|
ultrascan_adjust_timing(USI, hss, probe, rcvdtime);
|
||||||
|
|
||||||
ultrascan_host_pspec_update(USI, hss, probe->pspec(), newstate);
|
/* If this probe received a positive response, consider making it the new
|
||||||
|
timing ping probe. */
|
||||||
if (rcvdtime != NULL && adjust_timing) {
|
if (rcvdtime != NULL && adjust_ping
|
||||||
/* This probe received a positive response. Consider making it the new
|
&& pingprobe_is_better(probe->pspec(), PORT_UNKNOWN, &hss->target->pingprobe, hss->target->pingprobe_state)) {
|
||||||
timing ping probe. */
|
if (o.debugging > 1) {
|
||||||
if (pingprobe_is_better(probe->pspec(), PORT_UNKNOWN, &hss->target->pingprobe, hss->target->pingprobe_state)) {
|
char buf[32];
|
||||||
if (o.debugging > 1) {
|
probespec2ascii(probe->pspec(), buf, sizeof(buf));
|
||||||
char buf[32];
|
log_write(LOG_PLAIN, "Changing ping technique for %s to %s\n", hss->target->targetipstr(), buf);
|
||||||
probespec2ascii(probe->pspec(), buf, sizeof(buf));
|
|
||||||
log_write(LOG_PLAIN, "Changing ping technique for %s to %s\n", hss->target->targetipstr(), buf);
|
|
||||||
}
|
|
||||||
hss->target->pingprobe = *probe->pspec();
|
|
||||||
hss->target->pingprobe_state = PORT_UNKNOWN;
|
|
||||||
/* Make this the new global ping host, but only if the old one is not
|
|
||||||
waiting for any probes. */
|
|
||||||
if (USI->gstats->pinghost == NULL
|
|
||||||
|| USI->gstats->pinghost->num_probes_active == 0) {
|
|
||||||
if (o.debugging > 1)
|
|
||||||
log_write(LOG_PLAIN, "Changing global ping host to %s.\n", hss->target->targetipstr());
|
|
||||||
USI->gstats->pinghost = hss;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
hss->target->pingprobe = *probe->pspec();
|
||||||
|
hss->target->pingprobe_state = PORT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
hss->destroyOutstandingProbe(probeI);
|
hss->destroyOutstandingProbe(probeI);
|
||||||
@@ -2631,59 +2658,61 @@ static void ultrascan_host_probe_update(UltraScanInfo *USI, HostScanStats *hss,
|
|||||||
Nmap port state table as appropriate. If rcvdtime is NULL or we got
|
Nmap port state table as appropriate. If rcvdtime is NULL or we got
|
||||||
unimportant packet, packet stats are not updated. If you don't have an
|
unimportant packet, packet stats are not updated. If you don't have an
|
||||||
UltraProbe list iterator, you may need to call ultrascan_port_psec_update()
|
UltraProbe list iterator, you may need to call ultrascan_port_psec_update()
|
||||||
instead. If rcvdtime is NULL or adjust_timing is false, packet stats are not
|
instead. If adjust_timing_hint is false, packet stats are not
|
||||||
updated. */
|
updated. */
|
||||||
static void ultrascan_port_probe_update(UltraScanInfo *USI, HostScanStats *hss,
|
static void ultrascan_port_probe_update(UltraScanInfo *USI, HostScanStats *hss,
|
||||||
list<UltraProbe *>::iterator probeI,
|
list<UltraProbe *>::iterator probeI,
|
||||||
int newstate, struct timeval *rcvdtime,
|
int newstate, struct timeval *rcvdtime,
|
||||||
bool adjust_timing = true) {
|
bool adjust_timing_hint = true) {
|
||||||
UltraProbe *probe = *probeI;
|
UltraProbe *probe = *probeI;
|
||||||
const probespec *pspec = probe->pspec();
|
const probespec *pspec = probe->pspec();
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
changed = ultrascan_port_pspec_update(USI, hss, pspec, newstate);
|
ultrascan_port_pspec_update(USI, hss, pspec, newstate);
|
||||||
|
|
||||||
if (rcvdtime != NULL && adjust_timing) {
|
|
||||||
/* This probe received a positive response. Consider making it the new
|
|
||||||
timing ping probe. */
|
|
||||||
if (pingprobe_is_better(probe->pspec(), newstate, &hss->target->pingprobe, hss->target->pingprobe_state)) {
|
|
||||||
if (o.debugging > 1) {
|
|
||||||
char buf[32];
|
|
||||||
probespec2ascii(probe->pspec(), buf, sizeof(buf));
|
|
||||||
log_write(LOG_PLAIN, "Changing ping technique for %s to %s\n", hss->target->targetipstr(), buf);
|
|
||||||
}
|
|
||||||
hss->target->pingprobe = *probe->pspec();
|
|
||||||
hss->target->pingprobe_state = newstate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ultrascan_adjust_timeouts(USI, hss, probe, rcvdtime);
|
ultrascan_adjust_timeouts(USI, hss, probe, rcvdtime);
|
||||||
|
|
||||||
if (adjust_timing &&
|
/* Decide whether to adjust timing. We and together a bunch of conditions.
|
||||||
/* If we got a response that meant "filtered", then it was an ICMP error.
|
First, don't adjust timing if adjust_timing_hint is false. */
|
||||||
These are often rate-limited (RFC 1812) or generated by a different
|
bool adjust_timing = adjust_timing_hint;
|
||||||
host. At -T4 and above we consider only the first such response
|
bool adjust_ping = adjust_timing_hint;
|
||||||
(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 got a response that meant "filtered", then it was an ICMP error.
|
||||||
/* Do not slow down if we are in --defeat-rst-ratelimit mode and the new
|
These are often rate-limited (RFC 1812) or generated by a different host.
|
||||||
state is closed|filtered. We don't care if it's closed|filtered because
|
We only allow such responses to increase, not decrease, scanning speed by
|
||||||
of a RST or a timeout because they both mean the same thing. */
|
not considering drops (probe->tryno > 0), and we don't allow changing the
|
||||||
!(o.defeat_rst_ratelimit && newstate == PORT_CLOSEDFILTERED && probe->tryno > 0)) {
|
ping probe to something that's likely to get dropped. */
|
||||||
ultrascan_adjust_timing(USI, hss, probe, rcvdtime);
|
if (rcvdtime != NULL && newstate == PORT_FILTERED && !USI->noresp_open_scan) {
|
||||||
if (rcvdtime != NULL && probe->tryno > hss->max_successful_tryno) {
|
if (probe->tryno > 0) {
|
||||||
/* We got a positive response to a higher tryno than we've seen so far. */
|
if (adjust_timing && o.debugging > 1)
|
||||||
hss->max_successful_tryno = probe->tryno;
|
log_write(LOG_PLAIN, "Response for %s means new state is filtered; not adjusting timing.\n", hss->target->targetipstr());
|
||||||
if (o.debugging)
|
adjust_timing = false;
|
||||||
log_write(LOG_STDOUT, "Increased max_successful_tryno for %s to %d (packet drop)\n", hss->target->targetipstr(), hss->max_successful_tryno);
|
|
||||||
if (hss->max_successful_tryno > ((o.timing_level >= 4)? 4 : 3)) {
|
|
||||||
unsigned int olddelay = hss->sdn.delayms;
|
|
||||||
hss->boostScanDelay();
|
|
||||||
if (o.verbose && hss->sdn.delayms != olddelay)
|
|
||||||
log_write(LOG_STDOUT, "Increasing send delay for %s from %d to %d due to max_successful_tryno increase to %d\n",
|
|
||||||
hss->target->targetipstr(), olddelay, hss->sdn.delayms,
|
|
||||||
hss->max_successful_tryno);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
adjust_ping = false;
|
||||||
|
}
|
||||||
|
/* 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. */
|
||||||
|
if (rcvdtime != NULL
|
||||||
|
&& o.defeat_rst_ratelimit && newstate == PORT_CLOSEDFILTERED) {
|
||||||
|
if (probe->tryno > 0)
|
||||||
|
adjust_timing = false;
|
||||||
|
adjust_ping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adjust_timing)
|
||||||
|
ultrascan_adjust_timing(USI, hss, probe, rcvdtime);
|
||||||
|
|
||||||
|
/* If this probe received a positive response, consider making it the new
|
||||||
|
timing ping probe. */
|
||||||
|
if (rcvdtime != NULL && adjust_ping
|
||||||
|
&& pingprobe_is_better(probe->pspec(), newstate, &hss->target->pingprobe, hss->target->pingprobe_state)) {
|
||||||
|
if (o.debugging > 1) {
|
||||||
|
char buf[32];
|
||||||
|
probespec2ascii(probe->pspec(), buf, sizeof(buf));
|
||||||
|
log_write(LOG_PLAIN, "Changing ping technique for %s to %s\n", hss->target->targetipstr(), buf);
|
||||||
|
}
|
||||||
|
hss->target->pingprobe = *probe->pspec();
|
||||||
|
hss->target->pingprobe_state = newstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
hss->destroyOutstandingProbe(probeI);
|
hss->destroyOutstandingProbe(probeI);
|
||||||
|
|||||||
25
timing.cc
25
timing.cc
@@ -275,7 +275,6 @@ void RateMeter::stop(const struct timeval *now) {
|
|||||||
now. If now is NULL, get the current time with gettimeofday. */
|
now. If now is NULL, get the current time with gettimeofday. */
|
||||||
void RateMeter::update(double amount, const struct timeval *now) {
|
void RateMeter::update(double amount, const struct timeval *now) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
static int clockwarn = 0;
|
|
||||||
double diff;
|
double diff;
|
||||||
double interval;
|
double interval;
|
||||||
double count;
|
double count;
|
||||||
@@ -300,23 +299,17 @@ void RateMeter::update(double amount, const struct timeval *now) {
|
|||||||
/* How long since the last update? */
|
/* How long since the last update? */
|
||||||
diff = TIMEVAL_SUBTRACT(*now, last_update_tv) / 1000000.0;
|
diff = TIMEVAL_SUBTRACT(*now, last_update_tv) / 1000000.0;
|
||||||
|
|
||||||
/* On my SMP Linux 2.6.20 system, I'm getting very occasional values
|
if (diff < -current_rate_history)
|
||||||
like "now=1214173867.8027; last_update_tv=1214173867.8065".
|
/* This happened farther in the past than we care about. */
|
||||||
Unless I'm missing something, I think my gettimeofday may have
|
return;
|
||||||
decreased by 38 microseconds. Perhaps due to SMP and the old
|
|
||||||
kernel. Anyway, I think I'll just treat decreases of up to 1ms
|
if (diff < 0.0) {
|
||||||
as zero -Fyodor
|
/* If the event happened in the past, just add it into the total and don't
|
||||||
Updated to allow up to 5ms due to crash:
|
change last_update_tv, as if it had happened at the same time as the most
|
||||||
RateMeter::update: negative time delta; now=1217210189.144224; last_update_tv=1217210189.148486 */
|
recent event. */
|
||||||
if (diff < 0 && diff > -0.005) {
|
now = &last_update_tv;
|
||||||
if (!clockwarn) {
|
|
||||||
error("Warning: RateMeter::update: negative time delta; now=%lu.%lu; last_update_tv=%lu.%lu", (unsigned long) now->tv_sec, (unsigned long) now->tv_usec, (unsigned long) last_update_tv.tv_sec, (unsigned long) last_update_tv.tv_usec);
|
|
||||||
clockwarn = 1;
|
|
||||||
}
|
|
||||||
diff = 0.0;
|
diff = 0.0;
|
||||||
}
|
}
|
||||||
if (diff < 0.0)
|
|
||||||
fatal("RateMeter::update: negative time delta; now=%lu.%lu; last_update_tv=%lu.%lu", (unsigned long) now->tv_sec, (unsigned long) now->tv_usec, (unsigned long) last_update_tv.tv_sec, (unsigned long) last_update_tv.tv_usec);
|
|
||||||
|
|
||||||
/* Find out how far back in time to look. We want to look back
|
/* Find out how far back in time to look. We want to look back
|
||||||
current_rate_history seconds, or to when the last update occurred,
|
current_rate_history seconds, or to when the last update occurred,
|
||||||
|
|||||||
Reference in New Issue
Block a user