diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2024-02-01 15:33:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-01 15:33:11 +0100 |
commit | 400cd516b5fbc6137feb73c377a944e3dc64f53b (patch) | |
tree | cd86a570dbde39fb286a5521f3c165ef4e68cf60 /src/include/ndpi_api.h | |
parent | 44c2e59661b34f7b9004a98ddd31e7b3e514e6ec (diff) |
Allow multiple `struct ndpi_detection_module_struct` to share some state (#2271)
Add the concept of "global context".
Right now every instance of `struct ndpi_detection_module_struct` (we
will call it "local context" in this description) is completely
independent from each other. This provide optimal performances in
multithreaded environment, where we pin each local context to a thread,
and each thread to a specific CPU core: we don't have any data shared
across the cores.
Each local context has, internally, also some information correlating
**different** flows; something like:
```
if flow1 (PeerA <-> Peer B) is PROTOCOL_X; then
flow2 (PeerC <-> PeerD) will be PROTOCOL_Y
```
To get optimal classification results, both flow1 and flow2 must be
processed by the same local context. This is not an issue at all in the far
most common scenario where there is only one local context, but it might
be impractical in some more complex scenarios.
Create the concept of "global context": multiple local contexts can use
the same global context and share some data (structures) using it.
This way the data correlating multiple flows can be read/write from
different local contexts.
This is an optional feature, disabled by default.
Obviously data structures shared in a global context must be thread safe.
This PR updates the code of the LRU implementation to be, optionally,
thread safe.
Right now, only the LRU caches can be shared; the other main structures
(trees and automas) are basically read-only: there is little sense in
sharing them. Furthermore, these structures don't have any information
correlating multiple flows.
Every LRU cache can be shared, independently from the others, via
`ndpi_set_config(ndpi_struct, NULL, "lru.$CACHE_NAME.scope", "1")`.
It's up to the user to find the right trade-off between performances
(i.e. without shared data) and classification results (i.e. with some
shared data among the local contexts), depending on the specific traffic
patterns and on the algorithms used to balance the flows across the
threads/cores/local contexts.
Add some basic examples of library initialization in
`doc/library_initialization.md`.
This code needs libpthread as external dependency. It shouldn't be a big
issue; however a configure flag has been added to disable global context
support. A new CI job has been added to test it.
TODO: we should need to find a proper way to add some tests on
multithreaded enviroment... not an easy task...
*** API changes ***
If you are not interested in this feature, simply add a NULL parameter to
any `ndpi_init_detection_module()` calls.
Diffstat (limited to 'src/include/ndpi_api.h')
-rw-r--r-- | src/include/ndpi_api.h | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index abef7ad34..ea40927bf 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -202,6 +202,22 @@ extern "C" { ndpi_protocol_match const * const match); /** + * Returns a new initialized global context. + * + * @return the initialized global context + * + */ + struct ndpi_global_context *ndpi_global_init(void); + + /** + * Deinit a properly initialized global context. + * + * @par g_ctx = global context to free/deinit + * + */ + void ndpi_global_deinit(struct ndpi_global_context *g_ctx); + + /** * Returns a new initialized detection module * Note that before you can use it you can still load * hosts and do other things. As soon as you are ready to use @@ -211,10 +227,11 @@ extern "C" { * indipendent detection contexts) but all these calls MUST NOT run * in parallel * + * @g_ctx = global context associated to the new detection module; NULL if no global context is needed * @return the initialized detection module * */ - struct ndpi_detection_module_struct *ndpi_init_detection_module(void); + struct ndpi_detection_module_struct *ndpi_init_detection_module(struct ndpi_global_context *g_ctx); /** * Completes the initialization (2nd step) @@ -1038,14 +1055,15 @@ extern "C" { u_int32_t ndpi_get_current_time(struct ndpi_flow_struct *flow); /* LRU cache */ - struct ndpi_lru_cache* ndpi_lru_cache_init(u_int32_t num_entries, u_int32_t ttl); + struct ndpi_lru_cache* ndpi_lru_cache_init(u_int32_t num_entries, u_int32_t ttl, int shared); void ndpi_lru_free_cache(struct ndpi_lru_cache *c); u_int8_t ndpi_lru_find_cache(struct ndpi_lru_cache *c, u_int32_t key, u_int16_t *value, u_int8_t clean_key_when_found, u_int32_t now_sec); void ndpi_lru_add_to_cache(struct ndpi_lru_cache *c, u_int32_t key, u_int16_t value, u_int32_t now_sec); void ndpi_lru_get_stats(struct ndpi_lru_cache *c, struct ndpi_lru_cache_stats *stats); - int ndpi_get_lru_cache_stats(struct ndpi_detection_module_struct *ndpi_struct, + int ndpi_get_lru_cache_stats(struct ndpi_global_context *g_ctx, + struct ndpi_detection_module_struct *ndpi_struct, lru_cache_type cache_type, struct ndpi_lru_cache_stats *stats); |