I'm not following you. You are running multi-threaded, so
purgeIdleHosts() in hash.c IS getting invoked.
It's in ntop.c around 611, run by the thread myGlobals.scanIdleThreadId
(initialize.c @ 633).
void* scanIdleLoop(void* notUsed _UNUSED_) {
for(;;) {
int i;
sleep(60 /* do not change */);
if(!myGlobals.capturePackets) break;
myGlobals.actTime = time(NULL);
for(i=0; i<myGlobals.numDevices; i++)
if(!myGlobals.device[i].virtualDevice) {
purgeIdleHosts(i);
#ifdef HAVE_SCHED_H
sched_yield(); /* Allow other threads to run */
#endif
}
}
return(NULL);
}
This wakes up once per minute and runs purgeIdleHosts() (hash.c @ 326) on all
each device:
void purgeIdleHosts(int actDevice) {
u_int idx, numFreedBuckets=0, maxBucket = 0, theIdx, hashFull = 0, hashLen;
time_t startTime = time(NULL);
static time_t lastPurgeTime[MAX_NUM_DEVICES];
static char firstRun = 1;
static HostTraffic **theFlaggedHosts = NULL;
static u_int len;
if(myGlobals.rFileName != NULL) return;
if(firstRun) {
firstRun = 0;
memset(lastPurgeTime, 0, sizeof(lastPurgeTime));
len = sizeof(HostTraffic*)* MAX_NUM_PURGED_HOSTS;
theFlaggedHosts = (HostTraffic**)malloc(len);
}
updateDeviceThpt(actDevice);
if(startTime < (lastPurgeTime[actDevice]+PURGE_HOSTS_DELAY))
return; /* Too short */
else
lastPurgeTime[actDevice] = startTime;
accessMutex(&myGlobals.hostsHashMutex, "purgeIdleHosts");
purgeOldFragmentEntries(actDevice); /* let's do this too */
releaseMutex(&myGlobals.hostsHashMutex);
memset(theFlaggedHosts, 0, len);
/* Calculates entries to free */
hashLen = myGlobals.device[actDevice].actualHashSize;
for(theIdx = (myGlobals.actTime % hashLen) /* random start */,
hashFull = 0, idx=1; idx<hashLen; idx++) {
HostTraffic *el;
if((theIdx == myGlobals.broadcastEntryIdx) || (theIdx ==
myGlobals.otherHostEntryIdx)) {
theIdx = (theIdx+1) % hashLen;
continue;
}
if((el = myGlobals.device[actDevice].hash_hostTraffic[theIdx]) != NULL) {
if((!hashFull) && (el->numUses < MIN_NUM_USES)) {
if((!myGlobals.stickyHosts)
|| (myGlobals.borderSnifferMode)
|| (!subnetPseudoLocalHost(el))) {
accessMutex(&myGlobals.hostsHashMutex, "scanIdleLoop");
theFlaggedHosts[maxBucket++] = el;
myGlobals.device[actDevice].hash_hostTraffic[theIdx] = NULL; /* (*)
*/
releaseMutex(&myGlobals.hostsHashMutex);
if(maxBucket == (MAX_NUM_PURGED_HOSTS-1)) {
hashFull = 1;
continue;
}
}
}
/* If (*) the entry might be NULL */
if(myGlobals.device[actDevice].hash_hostTraffic[theIdx] != NULL)
myGlobals.device[actDevice].hash_hostTraffic[theIdx]->numUses = 0;
}
theIdx = (theIdx+1) % hashLen;
}
/* Now free the entries */
for(idx=0; idx<maxBucket; idx++) {
freeHostInfo(actDevice, theFlaggedHosts[idx], actDevice);
numFreedBuckets++;
#ifdef HAVE_SCHED_H
sched_yield(); /* Allow other threads to run */
#endif
}
scanTimedoutTCPSessions(actDevice); /* let's check timedout sessions too */
}
(I've deleted the ifdef MULTITHREAD and DEBUG for clarity...)
So, if the elapsed time isn't at least 300s
if(startTime < (lastPurgeTime[actDevice]+PURGE_HOSTS_DELAY))
return; /* Too short */
returns. But once every 5m it will continue and do the purge...
scanTimedoutTCPSessions(actDevice); /* let's check timedout sessions too */
Are you saying the TCPSessions scan should be moved up and use the
SESSION_SCAN_DELAY interval??? Moved into ntop.c around 611:
void* scanIdleLoop(void* notUsed _UNUSED_) {
for(;;) {
int i;
sleep(60 /* do not change */);
if(!myGlobals.capturePackets) break;
myGlobals.actTime = time(NULL);
for(i=0; i<myGlobals.numDevices; i++)
if(!myGlobals.device[i].virtualDevice) {
if(myGlobals.nextSessionTimeoutScan < myGlobals.actTime) {
/* It's time to check for timeout sessions */
scanTimedoutTCPSessions(actDevice);
#ifdef HAVE_SCHED_H
sched_yield(); /* Allow other threads to run */
#endif
}
purgeIdleHosts(i);
#ifdef HAVE_SCHED_H
sched_yield(); /* Allow other threads to run */
#endif
}
}
if(myGlobals.nextSessionTimeoutScan < myGlobals.actTime) {
myGlobals.nextSessionTimeoutScan = myGlobals.actTime+SESSION_SCAN_DELAY;
}
return(NULL);
}
(and then delete the line in purgeIdleHosts)
It should work... The only thing wrong with the current code is that it
effectively sets both SESSION_SCAN_DELAY and PURGE_HOSTS_DELAY to
300...
/signed/ Perplexed...
-----Burton
-----Original Message-----
From: Christian Hammers [mailto:[EMAIL PROTECTED]]
Sent: Thursday, May 02, 2002 4:12 PM
To: Burton M. Strauss III
Cc: [EMAIL PROTECTED]
Subject: Re: [Ntop-dev] PURGE_HOSTS_DELAY vs. SESSION_SCAN_DELAY
Hello
On Thu, May 02, 2002 at 03:51:14PM -0500, Burton M. Strauss III wrote:
> It's not the bug you think it is!
Hmm but honestly I thing I must object :)
> First off, remember that the purge doesn't free everything, just up to
"the purge" is scanTimedoutTCPSessions()? Anyway that's the function I
focus on. I desperately need it beeing called at least every 1-2 minutes
as I have asyncronous routing an _only_ incomplete tcp sessions that else
would never get exported via netflow.
The fact I was complaining about was that the variable SESSION_SCAN_DELAY is
never used in multithreading mode despite the comment above suggerates that
it is the right one. In stead the PURGE_HOSTS_DELAY is at least one of
the lower borders for the time period the scanTimedoutTCPSessions() is
called. Maybe the comments should be adjusted.
Except for the which-variable-does-what confusion the code itself works
fine!
> The code for the multithreaded version is -abstracted- this:
>
> scanIdleLoop() {
> sleep(60);
> purgeIdleHosts() {
> updateDeviceThpt(actDevice);
> if(startTime < (lastPurgeTime[actDevice]+PURGE_HOSTS_DELAY)) return;
> (else) ...do the purge...
> scanTimedoutTCPSessions();
> }
> }
> Is anyone actually running single-threaded, who can test the attached patch?
/me not, sorry.
> -----Burton
thanks,
-christian-
--
Christian Hammers WESTEND GmbH - Aachen und Dueren Tel 0241/701333-0
[EMAIL PROTECTED] Internet & Security for Professionals Fax 0241/911879
WESTEND ist CISCO Systems Partner - Authorized Reseller
_______________________________________________
Ntop mailing list
[EMAIL PROTECTED]
http://listgateway.unipi.it/mailman/listinfo/ntop