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

Reply via email to