1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-20 05:09:02 +00:00

incompleteHosts and completedHosts are now sets, matching a packet to a target is done faster

This commit is contained in:
tudor
2016-08-09 06:07:22 +00:00
parent 5d942ab1bd
commit 7c0280382e
3 changed files with 69 additions and 41 deletions

View File

@@ -152,6 +152,18 @@ extern NmapOps o;
extern "C" int g_has_npcap_loopback;
#endif
int HssPredicate::operator() (HostScanStats *lhs, HostScanStats *rhs) {
return 0 > sockaddr_storage_cmp(lhs->target->TargetSockAddr(), rhs->target->TargetSockAddr());
}
int SockAddrPredicate::operator() (HostScanStats *lhs, HostScanStats *rhs) {
const struct sockaddr_storage *lss, *rss;
lss = (lhs) ? lhs->target->TargetSockAddr() : ss;
rss = (rhs) ? rhs->target->TargetSockAddr() : ss;
return 0 > sockaddr_storage_cmp(lss, rss);
}
void UltraScanInfo::log_overall_rates(int logt) {
log_write(logt, "Overall sending rates: %.2f packets / s", send_rate_meter.getOverallPacketRate(&now));
if (send_rate_meter.getNumBytes() > 0)
@@ -751,14 +763,19 @@ UltraScanInfo::UltraScanInfo() {
}
UltraScanInfo::~UltraScanInfo() {
while (!incompleteHosts.empty()) {
delete incompleteHosts.front();
incompleteHosts.pop_front();
std::set<HostScanStats *>::iterator hostI;
for (hostI = incompleteHosts.begin(); hostI != incompleteHosts.end(); hostI++) {
delete *hostI;
}
while (!completedHosts.empty()) {
delete completedHosts.front();
completedHosts.pop_front();
for (hostI = completedHosts.begin(); hostI != completedHosts.end(); hostI++) {
delete *hostI;
}
incompleteHosts.clear();
completedHosts.clear();
delete gstats;
delete SPM;
if (rawsd >= 0) {
@@ -805,7 +822,7 @@ HostScanStats *UltraScanInfo::nextIncompleteHost() {
/* Return a number between 0.0 and 1.0 inclusive indicating how much of the scan
is done. */
double UltraScanInfo::getCompletionFraction() {
std::list<HostScanStats *>::iterator hostI;
std::set<HostScanStats *>::iterator hostI;
double total;
/* Add 1 for each completed host. */
@@ -958,7 +975,7 @@ void UltraScanInfo::Init(std::vector<Target *> &Targets, struct scan_lists *pts,
}
hss = new HostScanStats(Targets[targetno], this);
incompleteHosts.push_back(hss);
incompleteHosts.insert(hss);
}
numInitialTargets = Targets.size();
nextI = incompleteHosts.begin();
@@ -1062,7 +1079,7 @@ unsigned int UltraScanInfo::numProbesPerHost() {
bool UltraScanInfo::sendOK(struct timeval *when) {
struct timeval lowhtime = {0};
struct timeval tmptv;
std::list<HostScanStats *>::iterator host;
std::set<HostScanStats *>::iterator host;
bool ggood = false;
bool thisHostGood = false;
bool foundgood = false;
@@ -1120,27 +1137,23 @@ bool UltraScanInfo::sendOK(struct timeval *when) {
/* Find a HostScanStats by its IP address in the incomplete and completed lists.
Returns NULL if none are found. */
HostScanStats *UltraScanInfo::findHost(struct sockaddr_storage *ss) {
std::list<HostScanStats *>::iterator hss;
struct sockaddr_storage target_addr;
size_t target_addr_len;
std::set<HostScanStats *>::iterator hss;
for (hss = incompleteHosts.begin(); hss != incompleteHosts.end(); hss++) {
target_addr_len = sizeof(target_addr);
(*hss)->target->TargetSockAddr(&target_addr, &target_addr_len);
if (sockaddr_storage_cmp(&target_addr, ss) == 0) {
if (o.debugging > 2)
log_write(LOG_STDOUT, "Found %s in incomplete hosts list.\n", (*hss)->target->targetipstr());
return *hss;
}
SockAddrPredicate p(ss);
HostScanStats *fakeHss = NULL;
hss = std::lower_bound(incompleteHosts.begin(), incompleteHosts.end(), fakeHss, p);
if (hss != incompleteHosts.end()) {
if (o.debugging > 2)
log_write(LOG_STDOUT, "Found %s in incomplete hosts list.\n", (*hss)->target->targetipstr());
return *hss;
}
for (hss = completedHosts.begin(); hss != completedHosts.end(); hss++) {
target_addr_len = sizeof(target_addr);
(*hss)->target->TargetSockAddr(&target_addr, &target_addr_len);
if (sockaddr_storage_cmp(&target_addr, ss) == 0) {
if (o.debugging > 2)
log_write(LOG_STDOUT, "Found %s in completed hosts list.\n", (*hss)->target->targetipstr());
return *hss;
}
hss = std::lower_bound(completedHosts.begin(), completedHosts.end(), fakeHss, p);
if (hss != completedHosts.end()) {
if (o.debugging > 2)
log_write(LOG_STDOUT, "Found %s in completed hosts list.\n", (*hss)->target->targetipstr());
return *hss;
}
return NULL;
@@ -1150,7 +1163,7 @@ HostScanStats *UltraScanInfo::findHost(struct sockaddr_storage *ss) {
is here to replace numIncompleteHosts() < n, which would have to walk
through the entire list. */
bool UltraScanInfo::numIncompleteHostsLessThan(unsigned int n) {
std::list<HostScanStats *>::iterator hostI;
std::set<HostScanStats *>::iterator hostI;
unsigned int count;
count = 0;
@@ -1170,7 +1183,7 @@ static bool pingprobe_is_better(const probespec *new_probe, int new_state,
list, and remove any hosts from completedHosts which have exceeded their
lifetime. Returns the number of hosts removed. */
int UltraScanInfo::removeCompletedHosts() {
std::list<HostScanStats *>::iterator hostI, nxt;
std::set<HostScanStats *>::iterator hostI, nxt;
HostScanStats *hss = NULL;
int hostsRemoved = 0;
bool timedout = false;
@@ -1236,7 +1249,7 @@ int UltraScanInfo::removeCompletedHosts() {
}
}
hss->completiontime = now;
completedHosts.push_front(hss);
completedHosts.insert(hss);
incompleteHosts.erase(hostI);
hostsRemoved++;
/* Consider making this host the new global ping host during its
@@ -2280,7 +2293,7 @@ static void sendGlobalPingProbe(UltraScanInfo *USI) {
}
static void doAnyPings(UltraScanInfo *USI) {
std::list<HostScanStats *>::iterator hostI;
std::set<HostScanStats *>::iterator hostI;
HostScanStats *hss = NULL;
gettimeofday(&USI->now, NULL);
@@ -2355,7 +2368,7 @@ static void retransmitProbe(UltraScanInfo *USI, HostScanStats *hss,
/* Go through the ProbeQueue of each host, identify any
timed out probes, then try to retransmit them as appropriate */
static void doAnyOutstandingRetransmits(UltraScanInfo *USI) {
std::list<HostScanStats *>::iterator hostI;
std::set<HostScanStats *>::iterator hostI;
std::list<UltraProbe *>::iterator probeI;
/* A cache of the last processed probe from each host, to avoid re-examining a
bunch of probes to find the next one that needs to be retransmitted. */
@@ -2435,8 +2448,7 @@ static void doAnyOutstandingRetransmits(UltraScanInfo *USI) {
/* Print occasional remaining time estimates, as well as
debugging information */
static void printAnyStats(UltraScanInfo *USI) {
std::list<HostScanStats *>::iterator hostI;
std::set<HostScanStats *>::iterator hostI;
HostScanStats *hss;
struct ultra_timing_vals hosttm;
@@ -2506,7 +2518,7 @@ static void waitForResponses(UltraScanInfo *USI) {
/* Go through the data structures, making appropriate changes (such as expiring
probes, noting when hosts are complete, etc. */
static void processData(UltraScanInfo *USI) {
std::list<HostScanStats *>::iterator hostI;
std::set<HostScanStats *>::iterator hostI;
std::list<UltraProbe *>::iterator probeI, nextProbeI;
HostScanStats *host = NULL;
UltraProbe *probe = NULL;

View File

@@ -135,6 +135,8 @@
#include "tcpip.h"
#include <list>
#include <vector>
#include <set>
#include <algorithm>
struct probespec_tcpdata {
u16 dport;
@@ -649,6 +651,20 @@ struct ultra_scan_performance_vars : public scan_performance_vars {
void init();
};
struct HssPredicate {
public:
int operator() (HostScanStats *lhs, HostScanStats *rhs);
};
struct SockAddrPredicate {
public:
SockAddrPredicate(struct sockaddr_storage *ss) {
this->ss = ss;
}
int operator() (HostScanStats *lhs, HostScanStats *rhs);
struct sockaddr_storage *ss;
};
class UltraScanInfo {
public:
UltraScanInfo();
@@ -730,11 +746,11 @@ public:
/* Any function which messes with (removes elements from)
incompleteHosts may have to manipulate nextI */
std::list<HostScanStats *> incompleteHosts;
std::set<HostScanStats *, HssPredicate> incompleteHosts;
/* Hosts are moved from incompleteHosts to completedHosts as they are
completed. We keep them around because sometimes responses come back very
late, after we consider a host completed. */
std::list<HostScanStats *> completedHosts;
std::set<HostScanStats *, HssPredicate> completedHosts;
/* How long (in msecs) we keep a host in completedHosts */
unsigned int completedHostLifetime;
/* The last time we went through completedHosts to remove hosts */
@@ -751,7 +767,7 @@ public:
private:
unsigned int numInitialTargets;
std::list<HostScanStats *>::iterator nextI;
std::set<HostScanStats *>::iterator nextI;
};

View File

@@ -479,7 +479,7 @@ bool do_one_select_round(UltraScanInfo *USI, struct timeval *stime) {
int timeleft;
ConnectScanInfo *CSI = USI->gstats->CSI;
int sd;
std::list<HostScanStats *>::iterator hostI;
std::set<HostScanStats *>::iterator hostI;
HostScanStats *host;
UltraProbe *probe = NULL;
int optval;
@@ -520,7 +520,7 @@ bool do_one_select_round(UltraScanInfo *USI, struct timeval *stime) {
and find the relevant ones. Note the peculiar structure of the loop--we
iterate through both incompleteHosts and completedHosts, because global
timing pings are sent to hosts in completedHosts. */
std::list<HostScanStats *>::iterator incompleteHostI, completedHostI;
std::set<HostScanStats *>::iterator incompleteHostI, completedHostI;
incompleteHostI = USI->incompleteHosts.begin();
completedHostI = USI->completedHosts.begin();
while ((incompleteHostI != USI->incompleteHosts.end()