diff --git a/include/NetworkInterface.h b/include/NetworkInterface.h index 9f69101459..96f776fffb 100644 --- a/include/NetworkInterface.h +++ b/include/NetworkInterface.h @@ -668,7 +668,7 @@ class NetworkInterface : public AlertableEntity { void reloadHideFromTop(bool refreshHosts=true); void updateLbdIdentifier(); inline bool serializeLbdHostsAsMacs() { return(lbd_serialize_by_mac); } - void startCustomCategoriesReload(); + bool startCustomCategoriesReload(); void cleanShadownDPI(); void checkReloadHostsBroadcastDomain(); inline bool reloadHostsBroadcastDomain() { return reload_hosts_bcast_domain; } diff --git a/include/Ntop.h b/include/Ntop.h index bea2767ba5..75c6513b93 100644 --- a/include/Ntop.h +++ b/include/Ntop.h @@ -430,7 +430,7 @@ class Ntop { DeviceProtoStatus getDeviceAllowedProtocolStatus(DeviceType dev_type, ndpi_protocol proto, u_int16_t pool_id, bool as_client); void refreshCpuLoad(); bool getCpuLoad(float *out); - inline bool canSafelyReloadnDPI(time_t now) { return((now - last_ndpi_reload) >= MIN_NDPI_RELOAD_INTERVAL); } + bool canSafelyReloadnDPI(time_t now); inline void setLastInterfacenDPIReload(time_t now) { last_ndpi_reload = now; } inline bool needsnDPICleanup(time_t now) { return(ndpi_cleanup_needed && canSafelyReloadnDPI(now)); } inline void setnDPICleanupNeeded(bool needed) { ndpi_cleanup_needed = needed; } diff --git a/include/ntop_defines.h b/include/ntop_defines.h index e1b0a5579d..cb92991b22 100644 --- a/include/ntop_defines.h +++ b/include/ntop_defines.h @@ -619,7 +619,7 @@ #endif #define CONST_RUNTIME_PREFS_HOSTMASK NTOPNG_PREFS_PREFIX".host_mask" #define CONST_RUNTIME_PREFS_AUTO_ASSIGNED_POOL_ID NTOPNG_PREFS_PREFIX".auto_assigned_pool_id" -#define MIN_NDPI_RELOAD_INTERVAL 120 /* sec, needed to avoid freeing the shadow pointer too early */ +#define MIN_NDPI_RELOAD_INTERVAL 10 /* sec, needed to avoid freeing the shadow pointer too early */ #define CONST_MAX_ALERT_MSG_QUEUE_LEN 8192 #define CONST_MAX_ES_MSG_QUEUE_LEN 8192 diff --git a/src/LuaEngine.cpp b/src/LuaEngine.cpp index 7a70b3a47d..ff19b11323 100644 --- a/src/LuaEngine.cpp +++ b/src/LuaEngine.cpp @@ -1803,13 +1803,16 @@ static int ntop_startCustomCategoriesReload(lua_State* vm) { return(CONST_LUA_OK); } - ntop->setLastInterfacenDPIReload(time(NULL)); - for(int i=0; iget_num_interfaces(); i++) { NetworkInterface *iface; - if((iface = ntop->getInterface(i)) != NULL) - iface->startCustomCategoriesReload(); + if((iface = ntop->getInterface(i)) != NULL) { + if(!iface->startCustomCategoriesReload()) { + /* startCustomCategoriesReload, abort */ + lua_pushboolean(vm, false); + return(CONST_LUA_OK); + } + } } lua_pushboolean(vm, true /* can now start reloading */); @@ -1899,6 +1902,7 @@ static int ntop_reloadCustomCategories(lua_State* vm) { } ntop->getTrace()->traceEvent(TRACE_DEBUG, "Category lists reload done"); + ntop->setLastInterfacenDPIReload(time(NULL)); ntop->setnDPICleanupNeeded(true); lua_pushboolean(vm, true /* reload performed */); diff --git a/src/NetworkInterface.cpp b/src/NetworkInterface.cpp index 2d3ae5674c..8e26c1092f 100644 --- a/src/NetworkInterface.cpp +++ b/src/NetworkInterface.cpp @@ -355,7 +355,7 @@ struct ndpi_detection_module_struct* NetworkInterface::initnDPIStruct() { void NetworkInterface::cleanShadownDPI() { ntop->getTrace()->traceEvent(TRACE_NORMAL, "%s(%p)", __FUNCTION__, ndpi_struct_shadow); - if(ndpi_struct_shadow) { + if(ndpi_struct_shadow && !ndpiReloadInProgress) { ndpi_exit_detection_module(ndpi_struct_shadow); ndpi_struct_shadow = NULL; } @@ -370,21 +370,22 @@ void NetworkInterface::cleanShadownDPI() { * 3. reloadCustomCategories() * 4. cleanShadownDPI() */ -void NetworkInterface::startCustomCategoriesReload() { +bool NetworkInterface::startCustomCategoriesReload() { ntop->getTrace()->traceEvent(TRACE_NORMAL, "Started nDPI reload on %s [%p][%s]", get_name(), ndpi_struct_shadow, ndpiReloadInProgress ? "IN PROGRESS" : ""); if(ndpiReloadInProgress) { ntop->getTrace()->traceEvent(TRACE_ERROR, "Internal error: nested nDPI category reload"); - return; - } else - ndpiReloadInProgress = true; - + return(false); + } + cleanShadownDPI(); + ndpiReloadInProgress = true; /* No need to dedicate another variable for the reload, we can use the shadow itself */ ndpi_struct_shadow = initnDPIStruct(); - ntop->getTrace()->traceEvent(TRACE_NORMAL, "Completed nDPI reload on %s [%p]", + ntop->getTrace()->traceEvent(TRACE_NORMAL, "nDPI reload is now ready on %s [%p]", get_name(), ndpi_struct_shadow); + return(true); } /* **************************************************** */ diff --git a/src/Ntop.cpp b/src/Ntop.cpp index fd5f1fcfef..5a55cf3b7a 100644 --- a/src/Ntop.cpp +++ b/src/Ntop.cpp @@ -2317,3 +2317,12 @@ void Ntop::reloadJA3Hashes() { malicious_ja3 = new_malicious_ja3; new_malicious_ja3 = new std::set(); } + +/* ******************************************* */ + +/* This ensures that a network interface is not still using the old ndpi struct + * (stored in ndpi_struct_shadow) while a reload is in progress. + */ +bool Ntop::canSafelyReloadnDPI(time_t now) { + return((now - last_ndpi_reload) >= MIN_NDPI_RELOAD_INTERVAL); +}