diff --git a/CHANGELOG b/CHANGELOG index cbf8572f1..edcf5a3e8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ #Nmap Changelog ($Id$); -*-text-*- +o [GH#1150] Start host timeout clocks when the first probe is sent to a host, + not when the hostgroup is started. Sometimes a host doesn't get probes until + late in the hostgroup, increasing the chance it will time out. [jsiembida] + o [GH#1147][GH#1108] Reduced LibPCRE resource limits so that version detection can't use as much of the stack. Previously Nmap could crash when run on low-memory systems against target services which are intentionally or diff --git a/osscan2.cc b/osscan2.cc index 7997576c0..84227f45f 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -455,19 +455,6 @@ const char *tsseqclass2ascii(int seqclass) { } -/* Start the timeout clocks of any targets that aren't already timedout */ -static void startTimeOutClocks(OsScanInfo *OSI) { - std::list::iterator hostI; - - gettimeofday(&now, NULL); - for (hostI = OSI->incompleteHosts.begin(); - hostI != OSI->incompleteHosts.end(); hostI++) { - if (!(*hostI)->target->timedOut(NULL)) - (*hostI)->target->startTimeOutClock(&now); - } -} - - /** Sets up the pcap descriptor in HOS (obtains a descriptor and sets the * appropriate BPF filter, based on the supplied list of targets). */ static void begin_sniffer(HostOsScan *HOS, std::vector &Targets) { @@ -1769,6 +1756,10 @@ void HostOsScan::sendNextProbe(HostOsScanStats *hss) { if (hss->probesToSend.empty()) return; + if (!hss->target->timeOutClockRunning() && !hss->target->timedOut(NULL)) { + hss->target->startTimeOutClock(&now); + } + probeI = hss->probesToSend.begin(); probe = *probeI; @@ -3729,7 +3720,6 @@ int OSScan::os_scan_ipv4(std::vector &Targets) { return OP_FAILURE; } OSI.starttime = o.TimeSinceStart(); - startTimeOutClocks(&OSI); HostOsScan HOS(Targets[0]); diff --git a/scan_engine.cc b/scan_engine.cc index 052ba2ac6..342f0963e 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -2035,6 +2035,15 @@ static bool ultrascan_host_pspec_update(UltraScanInfo *USI, HostScanStats *hss, return hss->target->flags != oldstate; } +static void ultrascan_host_timeout_init(UltraScanInfo *USI, HostScanStats *hss) { + if (!hss->target->timeOutClockRunning() && !hss->target->timedOut(NULL)) { + if (o.debugging > 2) { + log_write(LOG_STDOUT, "Ultrascan timeout init for %s at %.6f\n", hss->target->targetipstr(), TIMEVAL_SECS(USI->now)); + } + hss->target->startTimeOutClock(&USI->now); + } +} + /* 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 to this new decision is in probeI. This function needs to update @@ -2255,6 +2264,7 @@ static void doAnyNewProbes(UltraScanInfo *USI) { hss = USI->nextIncompleteHost(); while (hss != NULL && hss != unableToSend && USI->gstats->sendOK(NULL)) { if (hss->freshPortsLeft() && hss->sendOK(NULL)) { + ultrascan_host_timeout_init(USI, hss); sendNextScanProbe(USI, hss); unableToSend = NULL; } else if (unableToSend == NULL) { @@ -2688,18 +2698,6 @@ static void processData(UltraScanInfo *USI) { } } -/* Start the timeout clocks of any targets that aren't already timedout */ -static void startTimeOutClocks(std::vector &Targets) { - struct timeval tv; - std::vector::iterator hostI; - - gettimeofday(&tv, NULL); - for (hostI = Targets.begin(); hostI != Targets.end(); hostI++) { - if (!(*hostI)->timedOut(NULL)) - (*hostI)->startTimeOutClock(&tv); - } -} - /* 3rd generation Nmap scanning function. Handles most Nmap port scan types. The parameter to gives group timing information, and if it is not NULL, @@ -2730,7 +2728,6 @@ void ultra_scan(std::vector &Targets, struct scan_lists *ports, // Set the variable for status printing o.numhosts_scanning = Targets.size(); - startTimeOutClocks(Targets); UltraScanInfo USI(Targets, ports, scantype); /* Use the requested timeouts. */ diff --git a/service_scan.cc b/service_scan.cc index ff2ce4c38..4c4683412 100644 --- a/service_scan.cc +++ b/service_scan.cc @@ -2324,6 +2324,9 @@ static int launchSomeServiceProbes(nsock_pool nsp, ServiceGroup *SG) { end_svcprobe(nsp, PROBESTATE_INCOMPLETE, SG, svc, NULL); continue; } + else if (!svc->target->timeOutClockRunning()) { + svc->target->startTimeOutClock(nsock_gettimeofday()); + } nextprobe = svc->nextProbe(true); if (nextprobe == NULL) { @@ -2760,24 +2763,6 @@ std::list::iterator svc; } } -/* Start the timeout clocks of any targets that have probes. Assumes - that this is called before any probes have been launched (so they - are all in services_remaining */ -static void startTimeOutClocks(ServiceGroup *SG) { - std::list::iterator svcI; - Target *target = NULL; - struct timeval tv; - - gettimeofday(&tv, NULL); - for(svcI = SG->services_remaining.begin(); - svcI != SG->services_remaining.end(); svcI++) { - target = (*svcI)->target; - if (!target->timeOutClockRunning()) - target->startTimeOutClock(&tv); - } -} - - // We iterate through SG->services_remaining and remove any with port/protocol // pairs that are excluded. We use AP->isExcluded() to determine which ports @@ -2837,8 +2822,6 @@ int service_scan(std::vector &Targets) { remove_excluded_ports(AP, SG); } - startTimeOutClocks(SG); - if (SG->services_remaining.size() == 0) { delete SG; return 1;