+ the actual list. Please reply-all to the list on these, thanks.
::begin / ::set are only used at configure time, not during packet processing. We use static THREAD_LOCAL decoration (there is some macro-magic to determine its behavior) for simplicity in storing per-instance data, though you can reference the current thread number with snort::get_instance_number() if you need to go that route.
For that type of usage, it almost sounds like an inspector would be more appropriate, given that an IpsOption would be instantiated for each unique option set. You could then define your realms within the Module paradigm for the inspector. If you wanted to act on that data, FlowData to communicate to a new IpsOption or a builtin rule for the condition you want would be appropriate.
Truly global data manipulated across threads isn’t really a supported use case at the time, as critical sections would be needed and those can be serious performance hits. The aim for us is to ensure any load balancing directs all correlated data to the same thread (sip control + call data for instance).
Also, a note on the separate interface set remark, that is a rough definition. Defining –daq afpacket -Ieth0:eth1 -Ieth2:eth3 would keep each pair on separate threads, however defining afpacket fanout could mean a single interface pair being load-balanced per 5-tuple to however many threads you run, which is why it’s considered “mostly” effective. The fanout mechanism happens at the kernel level and doesn’t have the context to intelligently direct correlated traffic.
From within option ::eval or module ::begin/::set - am I able to recognize which thread particular option instance belongs to? Or at any other step during option object creation / execution? Or is single option object executed in multiple threads?
I'd like to keep semi "global" stats regarding accumulated entropy, length, n-grams etc of already processed DNS packets in recent history. That could allow to detect long-term anomaly patterns like DNS tunneling. Of course since in real world scenarios interface sets probably represent independent zones in network there's no need to share such stats between them. However since I planned to keep stats structures in global Module object, in order to avoid race conditions I need to be able to distinguish threads so that each one accesses only own structure (providing we want to avoid unnecessary critical sections) or alternatively put stats access into critical section.
Simple implementation could just keep 1 stats object per option instance but it could be suboptimal if user wanted to describe logically the same "realm" of DNS traffic in multiple rules. For example if we have 2 DNS servers used in LAN user could create rules:
drop udp $HOME_NET any -> xyz 53 (dns_tun: realm 1)
drop udp $HOME_NET any -> abc 53 (dns_tun: realm 1)
It's obviously simplified example but the point is that we'd like to process those 2 rules in correlated manner since it's technically the same traffic. If some particular machine for whatever reason started to use second server, while everyone else uses first one - it could easily trigger false positives since there would be a lot of requests to "rare domains that nobody else asks about" since it'd improperly be classified as isolated case. Thus I'd like to keep stats in module instance, globally.
So can I in any way detect which thread does object instance belong to?
On Mon, 11 Mar 2019, 14:07 Carter Waxman (cwaxman), <email@example.com> wrote:
We currently do not support internal load balancing; however the general assumption should be a given flow will always be handed to the same thread. There is some support for external load balancing with afpacket, but it still holds to that same assumption.
One Module and one Plugin is created globally. From there, pinit/pterm (called once) and tinit/tterm (called per thread, not at reload at the moment) can be used to set up data structures as needed. Calls to ::configure should be used to read in new Module data, especially if it interacts with other plugins as at that point, they have all been instantiated.
I thought individual packets/tracked connections are balanced between threads. If that's not the case then indeed there's probably no need.
Is there new Module instance created per each thread? Or do Option objects in all threads share single "parent" Module object?
On Mon, 11 Mar 2019, 13:38 Carter Waxman (cwaxman), <firstname.lastname@example.org> wrote:
There shouldn’t be any critical sections in an ips options. The current threading model places 1 interface set / pcap per thread, so threads shouldn’t need to share any data with each other. What global data are you trying to share?
How does multi threading work in Snort 3? I mean - i made IPS Option and I want it to be stateful (as in use global data shared amongst all ips option instances). However from what I saw in manual Snort 3 support multi threading. So how do I handle critical sections in IPS Option module code? Can I just use pthread mutexes? Or is there some other recommended way?