diff --git a/include/NetworkInterface.h b/include/NetworkInterface.h index 7c1fe15a42..22e7b7d5f4 100644 --- a/include/NetworkInterface.h +++ b/include/NetworkInterface.h @@ -528,9 +528,9 @@ class NetworkInterface : public AlertableEntity { const char *groupColumn); int dropFlowsTraffic(AddressTree *allowed_hosts, Paginator *p); - virtual void purgeIdle(time_t when); - u_int purgeIdleFlows(); - u_int purgeIdleHostsMacsASesVlans(); + virtual void purgeIdle(time_t when, bool force_idle = false); + u_int purgeIdleFlows(bool force_idle); + u_int purgeIdleHostsMacsASesVlans(bool force_idle); virtual u_int64_t getNumPackets(); virtual u_int64_t getNumBytes(); diff --git a/src/GenericHash.cpp b/src/GenericHash.cpp index 6422111020..60df631c3c 100644 --- a/src/GenericHash.cpp +++ b/src/GenericHash.cpp @@ -250,13 +250,18 @@ u_int GenericHash::purgeIdle(bool force_idle) { case hash_entry_state_allocated: /* TCP flows with 3WH not yet completed fall here */ + if(force_idle) head->set_hash_entry_state_idle(); break; case hash_entry_state_flow_notyetdetected: head->housekeep(now); + if(force_idle) head->set_hash_entry_state_idle(); break; case hash_entry_state_flow_protocoldetected: + if(force_idle) head->set_hash_entry_state_idle(); + break; + case hash_entry_state_idle: /* Skip as this is handled by periodic activities thread */ break; diff --git a/src/Host.cpp b/src/Host.cpp index 9124a35717..6d8df09b62 100644 --- a/src/Host.cpp +++ b/src/Host.cpp @@ -1126,14 +1126,14 @@ bool Host::statsResetRequested() { /* *************************************** */ void Host::updateStats(update_stats_user_data_t *update_hosts_stats_user_data) { + char buf[64]; struct timeval *tv = update_hosts_stats_user_data->tv; Mac *cur_mac = getMac(); if(get_state() == hash_entry_state_idle) { - if((getUses() > 0) - /* View hosts are not in sync with viewed flows so during shutdown it can be normal */ - && (!iface->isView() || !ntop->getGlobals()->isShutdownRequested())) - ntop->getTrace()->traceEvent(TRACE_WARNING, "Internal error: num_uses=%u", getUses()); + if(getUses() > 0 && !ntop->getGlobals()->isShutdownRequested()) + /* During shutdown it is acceptable to have a getUses() > 0 as all the hosts are forced as idle */ + ntop->getTrace()->traceEvent(TRACE_WARNING, "Internal error: num_uses=%u [%s]", getUses(), get_ip()->print(buf, sizeof(buf))); set_hash_entry_state_ready_to_be_purged(); diff --git a/src/NetworkInterface.cpp b/src/NetworkInterface.cpp index 84386f44d5..7f5b49c529 100644 --- a/src/NetworkInterface.cpp +++ b/src/NetworkInterface.cpp @@ -1733,17 +1733,17 @@ bool NetworkInterface::processPacket(u_int32_t bridge_iface_idx, /* **************************************************** */ -void NetworkInterface::purgeIdle(time_t when) { +void NetworkInterface::purgeIdle(time_t when, bool force_idle) { if(purge_idle_flows_hosts) { u_int n, m; last_pkt_rcvd = when; - if((n = purgeIdleFlows()) > 0) + if((n = purgeIdleFlows(force_idle)) > 0) ntop->getTrace()->traceEvent(TRACE_DEBUG, "Purged %u/%u idle flows on %s", n, getNumFlows(), ifname); - if((m = purgeIdleHostsMacsASesVlans()) > 0) + if((m = purgeIdleHostsMacsASesVlans(force_idle)) > 0) ntop->getTrace()->traceEvent(TRACE_DEBUG, "Purged %u/%u idle hosts/macs on %s", m, getNumHosts()+getNumMacs(), ifname); } @@ -1753,7 +1753,7 @@ void NetworkInterface::purgeIdle(time_t when) { HASH_ITER(hh, flowHashing, current, tmp) { if(current->iface) - current->iface->purgeIdle(when); + current->iface->purgeIdle(when, force_idle); } } } @@ -2494,7 +2494,7 @@ void NetworkInterface::shutdown() { running = false; pthread_join(pollLoop, &res); /* purgeIdle one last time to make sure all entries will be marked as idle */ - purgeIdle(time(NULL)); + purgeIdle(time(NULL), true); } } @@ -4961,10 +4961,9 @@ void NetworkInterface::getNetworksStats(lua_State* vm) const { /* **************************************************** */ -u_int NetworkInterface::purgeIdleFlows() { +u_int NetworkInterface::purgeIdleFlows(bool force_idle) { u_int n = 0; time_t last_packet_time = getTimeLastPktRcvd(); - bool force_idle = !isRunning(); pollQueuedeCompanionEvents(); reloadCustomCategories(); @@ -4978,7 +4977,7 @@ u_int NetworkInterface::purgeIdleFlows() { /* Time to purge flows */ #if 0 - ntop->getTrace()->traceEvent(TRACE_INFO, + ntop->getTrace()->traceEvent(TRACE_NORMAL, "Purging idle flows [ifname: %s] [ifid: %i] [current size: %i]", ifname, id, flows_hash->getCurrentSize()); #endif @@ -5051,9 +5050,8 @@ u_int NetworkInterface::getNumArpStatsMatrixElements() { /* **************************************************** */ -u_int NetworkInterface::purgeIdleHostsMacsASesVlans() { +u_int NetworkInterface::purgeIdleHostsMacsASesVlans(bool force_idle) { time_t last_packet_time = getTimeLastPktRcvd(); - bool force_idle = !isRunning(); if(!purge_idle_flows_hosts) return(0); @@ -5064,6 +5062,12 @@ u_int NetworkInterface::purgeIdleHostsMacsASesVlans() { u_int n; /* If the interface is no longer running it is safe to force all entries as idle */ +#if 0 + ntop->getTrace()->traceEvent(TRACE_NORMAL, + "Purging idle hosts [ifname: %s] [ifid: %i] [current size: %i]", + ifname, id, hosts_hash->getCurrentSize()); +#endif + // ntop->getTrace()->traceEvent(TRACE_INFO, "Purging idle hosts"); n = (hosts_hash ? hosts_hash->purgeIdle(force_idle) : 0) + (macs_hash ? macs_hash->purgeIdle(force_idle) : 0)