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 /doc | |
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 'doc')
-rw-r--r-- | doc/configuration_parameters.md | 1 | ||||
-rw-r--r-- | doc/library_initialization.md | 84 |
2 files changed, 85 insertions, 0 deletions
diff --git a/doc/configuration_parameters.md b/doc/configuration_parameters.md index 7c8e78ac2..5b7ca257e 100644 --- a/doc/configuration_parameters.md +++ b/doc/configuration_parameters.md @@ -20,6 +20,7 @@ TODO | NULL | "log.level" | 0 | 0 | 3 | Configure the log/debug level. Possible values: 0 = error, 1 = trace, 2 = debug, 3 = extra debug | | NULL | "lru.$CACHE_NAME.size" | See description | 0 | 16777215 | Set the size (in number of elements) of the specified LRU cache (0 = the cache is disabled). The keyword "$CACHE_NAME" is a placeholder for the cache name and the possible values are: ookla, bittorrent, zoom, stun, tls_cert, mining, msteams, stun_zoom. The default value is "32768" for the bittorrent cache, "512" for the zoom cache and "1024" for all the other caches | | NULL | "lru.$CACHE_NAME.ttl" | See description | 0 | 16777215 | Set the TTL (in seconds) for the elements of the specified LRU cache (0 = the elements never explicitly expire). The keyword "$CACHE_NAME" is a placeholder for the cache name and the possible values are: ookla, bittorrent, zoom, stun, tls_cert, mining, msteams, stun_zoom. The default value is "120" for the ookla cache, "60" for the msteams and stun_zoom caches and "0" for all the other caches | +| NULL | "lru.$CACHE_NAME.scope" | 0 | 0 | 1 | Set the scope of the specified LRU cache (0 = the cache is local, 1 = the cache is global). The keyword "$CACHE_NAME" is a placeholder for the cache name and the possible values are: ookla, bittorrent, zoom, stun, tls_cert, mining, msteams, stun_zoom. The global scope con be set only if a global context has been initialized | | "tls" | "certificate_expiration_threshold" | 30 | 0 | 365 | The threshold (in days) used to trigger the `NDPI_TLS_CERTIFICATE_ABOUT_TO_EXPIRE` flow risk | | "tls" | "application_blocks_tracking" | disable | NULL | NULL | Enable/disable processing of TLS Application Blocks (post handshake) to extract statistical information about the flow | | "tls" | "metadata.sha1_fingerprint" | enable | NULL | NULL | Enable/disable computation and export of SHA1 fingerprint for TLS flows. Note that if it is disable, the flow risk `NDPI_MALICIOUS_SHA1_CERTIFICATE` is not checked | diff --git a/doc/library_initialization.md b/doc/library_initialization.md new file mode 100644 index 000000000..f70051aa9 --- /dev/null +++ b/doc/library_initialization.md @@ -0,0 +1,84 @@ + + + +A simple, common example + +``` + +struct ndpi_detection_module_struct *ndpi_struct; +ndpi_cfg_error rc; +int ret; + +ndpi_struct = ndpi_init_detection_module(NULL); +if(!ndpi_struct) { + ERROR; +} + +/* Configuration */ + +rc = ndpi_set_config(ndpi_struct, "tls", "certificate_expiration_threshold", "10"); +if(rc != NDPI_CFG_OK) { + ERROR; +} + +/* Finalization */ +ret = ndpi_finalize_initialization(ndpi_struct); +if(ret != 0) { + ERROR; +} + + +/* Initialization done, now you can feed packets to the library */ + + + +/* Cleanup */ + +ndpi_exit_detection_module(ndpi_struct); + + +``` + +A more complex example, with global context and a shared Oookla LRU cache (all the others caches are local) + +``` + +struct ndpi_global_context *g_ctx; +struct ndpi_detection_module_struct *ndpi_structs[num_local_contexts]; +ndpi_cfg_error rc; +int i, ret; + +g_ctx = ndpi_global_init(); +if(!g_ctx) { + ERROR; +} + +for(i = 0; i < num_local_contexts; i++) { + ndpi_structs[i] = ndpi_init_detection_module(g_ctx); + if(!ndpi_struct[i]) { + ERROR; + } + + rc = ndpi_set_config(ndpi_structs[i], NULL, "lru.ookla.scope", "1"); + if(rc != NDPI_CFG_OK) { + ERROR; + } + + ret = ndpi_finalize_initialization(ndpi_structs[i]); + if(ret != 0) { + ERROR; + } +} + +/* Initialization done */ + +/* Cleanup */ + +for(i = 0; i < num_local_contexts; i++) { + ndpi_exit_detection_module(ndpi_structs[i]); +} + +ndpi_global_deinit(g_ctx); + + +``` |