A short-circuit evaluation rule matching method and system based on a binary expression tree pre-compilation
By converting infix expressions into binary expression trees at compile time and employing a three-level adaptive path method, the problems of high parsing overhead and invalid computation in network traffic detection are solved, achieving efficient rule matching and hot update guarantee.
Patent Information
- Application Number
- CN202611519836.1
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2026-09-29
- Publication Date
- 2026-11-06
AI Technical Summary
Existing technologies suffer from high parsing overhead and unnecessary computational overhead in network traffic detection at speeds of millions of packets per second. In particular, under the infix regular expression evaluation method, they cannot effectively support logical short circuits, resulting in limited system performance.
A short-circuit evaluation rule matching method based on binary expression tree pre-compilation is adopted. By converting the infix expression into a postfix expression array and constructing a binary expression tree at compile time, combined with a three-level adaptive evaluation path, logical short-circuiting and efficient matching are achieved.
It significantly reduces invalid computation, improves CPU cache locality, supports high-concurrency, low-latency network deep packet inspection, and the matching throughput can be linearly scaled. The matching continuity is good during the rule hot update transition period.
Smart Images

Figure CN123049160A_ABST
Abstract
Description
Technical Field
[0001] This invention belongs to the fields of computer software, network security and traffic analysis technology, and specifically provides a rule matching method and system for detecting network traffic anomalies. Background Technology
[0002] With the continuous growth in demand for network security monitoring and traffic analysis, Deep Packet Inspection (DPI) systems need to perform real-time rule matching on the metadata fields of each packet, such as IP address, port number, protocol type, HTTP URL, TLS (Transport Layer Security) certificate fields, and DNS query domain name, at extremely high packet processing rates, typically millions of packets per second, to determine whether the packet matches predefined detection rules and trigger corresponding actions, such as alarms, dropping, and reporting.
[0003] Rules are typically given in the form of Boolean expressions containing multiple layers of logical combinations, covering relational operations, arithmetic operations, string matching, regular expression matching, and logical AND / OR combinations, for example:
[0004]
[0005] In the example above, the first line detects the URL path of the HTTP request, triggered when a link starting with / login (login page) or / admin (administration page) is accessed; the second line checks if the HTTP response status code is 200; the third line contains two logical OR conditions: the IP packet's Time-to-Live (TTL) is greater than 64, or the source IP address is 192.168.1.100. At a processing rate of millions of packets per second, the time available for rule matching for each packet is only on the order of microseconds. How to efficiently evaluate rule expressions containing multiple layers of logical combinations is the core bottleneck of rule engine performance.
[0006] Existing technologies include runtime parsing-based rule engines that store infix rule expression strings along with the rules. Each time a packet arrives, the infix string undergoes real-time lexical and syntactic analysis to dynamically generate an evaluation plan before execution. However, this approach has the following drawbacks: the time complexity of lexical and syntactic analysis is directly proportional to the length of the expression string; the entire parsing process must be repeated for each packet match, resulting in extremely high accumulated parsing overhead at a processing rate of millions of packets per second; when the rule matching throughput reaches millions of packets per second, the parsing overhead accounts for more than 50% of the total processing time, severely limiting system performance.
[0007] Existing technologies also include engines based on the sequential evaluation of traditional postfix expressions. These engines pre-convert infix expressions to postfix expressions (Reverse Polish notation) and perform calculations by sequentially traversing each element of the postfix expression using an operand stack during matching. While this approach eliminates runtime parsing overhead, it suffers from the following core drawback: the sequential evaluation model of postfix expressions requires a complete calculation of each operand, which does not support logical short-circuiting. For example, in the rule "A && B && C && D && E", when sub-condition A is not satisfied, according to the logical short-circuiting principle, the evaluation of sub-conditions B, C, D, and E has no impact on the overall result. However, this approach still performs the complete calculation of B, C, D, and E, resulting in significant unnecessary computational overhead. Summary of the Invention
[0008] Existing technologies for real-time rule matching security detection of millions of network packets per second suffer from high parsing overhead when using infix rule expression evaluation, and significant unnecessary computational overhead when using postfix expression sequential evaluation. The purpose of this invention is to provide a short-circuit evaluation rule matching method and system based on binary expression tree pre-compilation, to solve the problems of high runtime construction overhead, lack of support for logical short-circuiting, poor CPU cache locality, multi-threaded lock contention, and lack of adaptive path selection and hot update transition guarantees in existing real-time network traffic rule matching technologies.
[0009] This invention provides a short-circuit evaluation rule matching system based on binary expression tree pre-compilation, including an operator registration module, an infix-to-postfix compiler, a string pre-compiler, a validity verification module, a tree pre-construction module, and a three-level adaptive evaluation engine. The system loads rules for network traffic detection, where each rule is a string using infix regular expressions. The compiler creates a rule object for each rule and stores it in a preset storage area. The rule object includes a logical operator flag `has_logic_ops`, a postfix expression array `item`, a string pool `mpool`, and a binary expression tree. The binary expression tree includes a fixed-byte array `expr_heap` for storing nodes in the tree, and a field `expr_root` that caches pointers to the root nodes of the tree. The `has_logic_ops` flag is initially set to false.
[0010] During compilation, the operator registration module registers the operators in the rules to the operator mapping table of the device operating system; the infix-to-postfix compiler converts the infix expression of the rule into a postfix expression array and stores it in the rule object; during the conversion of the infix expression to the postfix expression array, the infix-to-postfix compiler stores the detected strings into the string pool mpool, and synchronously sets the flag has_logic_ops to true when writing the logical operators AND or OR into the postfix expression array; the string pre-compiler performs pre-compilation on the string constant operands in the rules; the validity verification module performs validity verification on the protocol element operands in the rules; the tree pre-construction module performs binary tree pre-construction, including: if the flag has_logic_ops is true in an execution path, restoring the postfix expression array into a binary expression tree through the node stack, storing all nodes of the tree contiguously in the fixed byte array expr_heap of the rule object, and caching the root node pointer in the expr_root field; the nodes in the tree reference the operands or operators in the postfix expression array using the range index (start, end).
[0011] During runtime, the three-level adaptive evaluation engine reads the postfix expression array, string pool, and binary expression tree of the rule objects stored by the compiler, performs real-time matching of messages, adaptively selects the evaluation path, and outputs the matching result. The adaptive selection of the evaluation path includes: checking expr_root and has_logic_ops; if expr_root is not empty, execute path 1; if expr_root is empty and has_logic_ops is true, execute path 2; if has_logic_ops is false, execute path 3. Among them, path 1 performs short-circuit evaluation by recursively traversing the binary expression tree, immediately truncating if the left subtree of the AND node is false, and immediately truncating if the left subtree of the OR node is true; path 2 performs short-circuit evaluation after dynamically constructing a temporary tree through the thread-local heap during the hot update transition period; path 3 directly performs evaluation by linearly traversing the postfix expression array.
[0012] Accordingly, the present invention provides a short-circuit evaluation rule matching method based on binary expression tree pre-compilation, which executes steps 1-5 during compilation and step 6 during runtime, including:
[0013] Step 1: The compiler creates a rule object for the loaded infix expression rules and stores it in a preset storage area. It then performs operator registration on the rule, registering the operators in the rule to the operator mapping table of the device operating system. The rule object includes a logical operator flag `has_logic_ops`, a postfix expression array `item`, a string pool `mpool`, and a binary expression tree. The binary expression tree includes a fixed-byte array `expr_heap` for storing nodes in the tree, and a field `expr_root` that caches the root node pointer of the tree. The flag `has_logic_ops` is initially set to false.
[0014] Step 2: Convert the infix expression of the rule into a postfix expression array and store it in the rule object; during the conversion of the infix expression into a postfix expression array, store the detected string into the string pool mpool; when writing the logical operator AND or OR into the postfix expression array, synchronously set the flag has_logic_ops to true.
[0015] Step 3: Perform pre-compilation on the string constant operands in the rules; the string constant operands are read from the string pool mpool;
[0016] Step 4: Perform validity verification on the operands of the protocol elements in the rules;
[0017] Step 5 involves pre-constructing the binary tree, including: if the flag has_logic_ops is true in an execution path, restoring the postfix expression array into a binary expression tree through the node stack, storing all nodes of the tree contiguously in the fixed byte array expr_heap of the rule object, and caching the root node pointer in the expr_root field; the nodes in the tree use the range index (start, end) to reference the operands or operators in the postfix expression array to calculate the range.
[0018] Step 6: When matching messages in real time, read the postfix expression array, string pool, and binary expression tree of the rule object stored by the compiler, adaptively select the evaluation path, and output the matching result;
[0019] The adaptive selection of the evaluation path includes: checking expr_root and has_logic_ops; if expr_root is not empty, execute path 1; if expr_root is empty and has_logic_ops is true, execute path 2; if has_logic_ops is false, execute path 3. Path 1 performs short-circuit evaluation by recursively traversing the binary expression tree. If the left subtree of an AND node is false, the right subtree is immediately truncated for evaluation; if the left subtree of an OR node is true, the right subtree is immediately truncated for evaluation. Path 2 performs short-circuit evaluation after dynamically constructing a temporary tree using the thread-local heap during the hot update transition period. Path 3 directly performs evaluation by linearly traversing the postfix expression array.
[0020] The advantages and positive effects of this invention are as follows:
[0021] (1) The method and system of this invention first convert the infix expression of the network traffic detection rule into a postfix expression array through a scheduling field algorithm. During the rule loading stage, the postfix expression is restored to a binary short-circuit evaluation expression tree and cached in a fixed storage area inside the rule object. Then, during the real-time packet matching stage, logical short-circuiting is achieved through a three-level adaptive path to complete the rule matching. The method and system of this invention significantly reduce invalid calculations through short-circuit evaluation and can be applied to high-concurrency, low-latency network deep packet inspection scenarios.
[0022] (2) The method and system of the present invention eliminate runtime construction overhead by pre-constructing the tree, improve CPU cache locality, and store all tree nodes in a fixed byte array with contiguous physical addresses, thereby improving L1 / L2 cache hit rate. Tree nodes do not copy operand / operator data, but only store the range index shared suffix array, which significantly reduces memory usage.
[0023] (3) When selecting three-level adaptive paths, the method and system of this invention only need to check two fields, with a time complexity of O(1). Furthermore, the three paths take into account various rules, ensuring the continuity of matching during the rule hot update transition period. Multiple concurrent matching threads are set up, each thread uses an independent heap space, without any mutex locks or atomic operations, and the matching throughput can be linearly expanded with the number of CPU cores. Attached Figure Description
[0024] Figure 1 This is the overall flowchart of the short-circuit evaluation rule matching system based on binary expression tree pre-compilation of the present invention;
[0025] Figure 2 This is a flowchart of the scheduling field algorithm for converting infix expressions to postfix expressions according to an embodiment of the present invention;
[0026] Figure 3 This is a flowchart of the binary expression tree construction process according to an embodiment of the present invention;
[0027] Figure 4 This is a flowchart of the three-level adaptive evaluation path selection in an embodiment of the present invention, showing the selection conditions and execution branches of paths ①②③;
[0028] Figure 5 This is a schematic diagram comparing the traditional full evaluation and the short-circuit evaluation of this invention.
[0029] Figure 6 This is a detailed flowchart of the short-circuit evaluation of the AND node according to an embodiment of the present invention;
[0030] Figure 7 This is a detailed flowchart of the OR node short-circuit evaluation according to an embodiment of the present invention;
[0031] Figure 8 This is a schematic diagram of the thread-local heap allocation mechanism according to an embodiment of the present invention, illustrating the lock-free heap design for each thread;
[0032] Figure 9 This is a flowchart of the rule hot update process according to an embodiment of the present invention, illustrating the collaborative process of lock-free update and pre-compiled binary expression tree;
[0033] Figure 10 This is the core data structure relationship diagram of the embodiments of the present invention. Detailed Implementation
[0034] The present invention will now be described in further detail with reference to the accompanying drawings and embodiments.
[0035] This invention is a short-circuit evaluation rule matching method and system based on binary expression tree pre-compilation. The core design principle is to advance all calculations that can be completed during rule loading to the compilation stage, minimize the runtime (path matching per message) work, and ensure the robustness of the rule matching system in various scenarios through a three-level adaptive strategy.
[0036] This invention discloses a short-circuit evaluation rule matching method and system based on a pre-compiled binary expression tree of postfix expressions. During the rule loading phase, the invention employs a scheduling field algorithm to convert infix expressions into postfix expression arrays, synchronously sets the `has_logic_ops` logical operator flag, and restores the postfix expressions to a binary expression tree. All nodes are continuously stored in a fixed byte array `expr_heap
[2048] ` within the rule object, and the root node pointer is cached in the `expr_root` field. During the real-time message matching phase, three-level adaptive path selection is completed in O(1) time complexity: Path 1 recursively short-circuit evaluates the pre-constructed tree, truncating left false AND nodes and left true OR nodes; Path 2 performs short-circuit evaluation after dynamically constructing a temporary tree using a thread-local heap during the hot update transition period; Path 3 directly performs linear postfix evaluation for simple rules without logical AND / OR. The thread-local heap is allocated using pointer collision, has no global lock, and the matching throughput expands linearly with the number of CPU cores. Compared to traditional solutions, this invention eliminates runtime construction overhead and achieves logic short-circuit optimization. When the sub-condition hit rate p approaches 0, the performance improvement is close to N times, where N is the number of sub-conditions.
[0037] The specific functions involved in the embodiments of this invention are described below:
[0038]
[0039] like Figure 1 As shown, the short-circuit evaluation rule matching system based on binary expression tree pre-compilation of the present invention includes functional modules one through six. Modules one through five are called during compilation, and module six is called during runtime. The system of the present invention first loads rules for traffic detection, which are strings using infix rule expressions. Module one is an operator registration module, module two is an infix-to-postfix compiler, module three is a string pre-compiler, module four is a validity verification module, module five is a tree pre-construction module, and module six is a three-level adaptive evaluation engine. Figure 1This section demonstrates the functionality of each module and the three-level adaptive path selection process. The specific implementation of each module is the same as steps 1-6 below. The system loads rules for network traffic detection, and the compiler creates a rule object for each rule and stores it in a preset storage area. The operator registration module registers the operators in the rules to the operator mapping table of the device operating system. The infix-to-postfix compiler converts the infix expression of the rule into a postfix expression array and stores it in the rule object. During the conversion, the infix-to-postfix compiler stores detected strings in a string pool and simultaneously sets the has_logic_ops flag to true when writing logical operators AND or OR into the postfix expression array. The string pre-compiler performs pre-compilation on the string constant operands in the rules. The validity verification module performs validity verification on the protocol element operands in the rules. The tree pre-construction module performs binary tree pre-construction. At runtime, the three-level adaptive evaluation engine reads the postfix expression array, string pool, and binary expression tree of the rule object stored by the compiler, performs real-time matching of packets, adaptively selects the evaluation path, and outputs the matching results.
[0040] Correspondingly, the short-circuit evaluation rule matching method based on binary expression tree pre-compilation implemented in this embodiment of the invention executes the following steps 1-5 at once during compilation and rule loading to achieve complete decoupling from message processing. During runtime, step 6 is executed to perform real-time matching of messages and rules, which requires extremely high efficiency.
[0041] Step 1: Call module one to perform operator registration. In this embodiment, a system operator loading function `system_op_load()` and a custom operator loading function `customize_op_load()` are predefined. These two functions are used to register the operators in the loaded rules to the system's operator mapping table. Operators are registered according to priority hierarchy, with logical AND and logical OR designed as the lowest priority.
[0042] During compilation, a rule object is generated for each loaded rule and stored in a pre-defined storage area. The rule object `postfix_t` includes the control field `has_logic_ops`, the suffix array `item`, the string pool `mpool`, and the binary expression tree `expr_root` + `expr_heap`. At the rule loading stage, different functional modules—the operator registration module, the infix-to-postfix compiler, the string pre-compiler, and the tree pre-construction module—populate the corresponding fields of the rule object `postfix_t`.
[0043] Step 2: Module 2 is called to use the Shunting-Yard algorithm to convert the infix expression of the rule into a postfix expression array and store it in the postfix array item
[64] of the rule object; the has_logic_ops flag is set in real time in the same code execution path where the logical operators AND / OR are written into the postfix array. In this embodiment, the has_logic_ops flag is set in the same execution path where the function try_store_op() writes the logical AND or logical OR operators into the postfix expression array, so there is no need to perform an additional linear scan after the postfix conversion is completed.
[0044] Step 3: Call module 3 to perform pre-compilation on string constant operands. For example, for fixed string matching, the KMP prefix function table (LPS table) is used for pre-compilation, and for regular expression matching, the Hyperscan engine is used for pre-compilation. The string pool mpool refers to the rule object postfix_t.mpool.addr
[1024] , which stores the original byte data of all strings in the rule expression. During the matching process, the pointer pstr of the operand points to the corresponding offset position in mpool, ensuring that the pointer remains valid throughout the rule's lifetime. mpool itself is not the KMP LPS table, nor is it the Hyperscan compilation database; it is simply the position of the string that can be quickly located through the pointer pstr.
[0045] Step 4: Call module four to perform legality verification on the operands of the protocol elements and preload the external function plugin.
[0046] Protocol element operands, or protocol element strings, refer to network packet fields referenced in the rule expression, such as ip.ttl and http.url. These fields are pre-registered in step 1. Validity verification primarily verifies whether these fields are valid fields for the registered operators, and whether the format of the configuration items corresponding to the configuration rules, whether integers or strings, meets the requirements. The system supports calling the call_plugin to configure rules. This rule allows calling externally implemented custom function plugins. These plugins exist as dynamic libraries and need to be dynamically loaded into memory.
[0047] Step 5: Call module 5 to preconstruct the binary tree.
[0048] If the flag `has_logic_ops` is true (i.e., 1) in an execution path, the postfix expression array is restored to a binary expression tree via the node stack. All nodes of the binary expression tree are linearly allocated in the fixed-byte array `expr_heap
[2048] ` within the regular object structure using `dyn_alloc()`, and the root node pointer is cached in the `expr_root` field. Tree nodes reference operands or operators in the postfix expression array using range indices (start, end), without data copying; each node is approximately 24 bytes in size. The above operations do not trigger any additional heap memory allocation.
[0049] Step 6: Call module six to adaptively select the evaluation path and output the matching result.
[0050] During the real-time message matching phase, the rule object stored by the compiler is read, including the postfix expression array, string pool, and binary expression tree, and then the following is executed:
[0051] Step 61, complete the evaluation path selection in O(1) time complexity: check only the two fields of expr_root pointer and has_logic_ops flag; determine whether expr_root pointer is null and whether has_logic_ops flag is true.
[0052] Step 62: Based on the results of step 61, adaptively select the evaluation path and perform rule matching:
[0053] Level ①, i.e. path 1, if expr_root is not empty, then recursively traverse the pre-built tree to perform short-circuit evaluation. If the left subtree of the AND node is false, it is immediately truncated. If the left subtree of the OR node is true, it is immediately truncated.
[0054] Level ②, i.e. path 2, if expr_root is empty and has_logic_ops is true, it indicates that it is in the hot update transition period. Then, short-circuit evaluation is performed after the temporary tree is dynamically built in the thread-local heap.
[0055] Level ③, i.e. path 3, if has_logic_ops is false, then the suffix array is directly linearly traversed to perform the evaluation.
[0056] Level ②'s mechanism implements automatic degradation processing during the hot update transition period. When a rule hot update causes the expr_root pointer to be temporarily null while the has_logic_ops flag is set, the system automatically selects path ② to dynamically build a temporary tree in the thread-local heap for short-circuit evaluation, ensuring the continuity of rule matching and preventing interruptions or matching errors.
[0057] Step 63: All runtime dynamic memory allocation is performed on a thread-independent fixed heap (per-thread heap) in a sequential collision manner, without global locks or memory fragmentation. After the function returns, the offset is reset and reused as a whole.
[0058] Assume that the thread-local heap heap_space[thrdx] allocates a fixed-size memory region independently for each matching thread. The allocation operation is implemented through pointer bumping, dyn_alloc[thrdx]+=sizeof(expr_node_t). There is no mutex lock, no atomic operation, and the heap space is reused as a whole by resetting the dyn_alloc offset when the function returns.
[0059] like Figure 2 As shown, the infix-to-postfix compiler is implemented by executing the function `postfix_generate()`. The function takes the infix expression string `infix`, its length `length`, and the rule ID `rid` as inputs and stores the parsed postfix expression result in `out_postfix`. When `postfix_generate()` executes, it first initializes the function by setting the operator stack pointer `op_stack.top` to -1 (indicating the operator stack is empty), setting the parenthesis nesting level counter `brkt_stack.level` to -1, setting the postfix expression output counter `postfix.total` to 0, and setting the logical operator presence flag `postfix.has_logic_ops` to 0 (indicating no logical operators have been detected in the current postfix expression). After initialization, the function scans the infix string `infix[idx]` character by character, starting from index `idx`, identifying the current lexical type and performing the corresponding operations based on the type: letter lexical, number lexical, left parenthesis, logical or relational operators, right parenthesis, etc. `idx` increments by one after each character processed. The function `try_store_opd` stores non-operator alphanumeric strings into the suffix array `item`, and the detected string content is stored into `mpool`. The number of parameters is counted using `nb_operand`. When `idx` equals `length`, the scan ends. All remaining operators are popped from the operator stack sequentially and written into the suffix expression using `try_store_op`. Finally, the complete suffix expression is written into `out_postfix`, and the function returns. In this embodiment, the function `postfix_generate()` is implemented based on the scheduling field algorithm; the specific implementation process for processing various lexical items is not described further. Improvements to this invention include... Figure 2As shown in the dashed box, in the function try_store_op() that pops operators from the operator stack and writes them to the suffix array, the judgment of whether the logical operators AND or OR are included is incorporated into the write-out action of the conversion. When AND or OR is detected, the has_logic_ops flag is set to 1 in real time, eliminating the need for a separate second scan.
[0060] like Figure 3 As shown, the example suffix array is [A(0),B(1),&&(2),C(1),||(4)]. For example, A(0) means that the operand at position 0 in the array is A. In the process of constructing a binary expression tree from the suffix array, the dyn_alloc function dynamically allocates memory space for each node, sets left and right child nodes for each node, sets the calculation range of the operand or operator in the corresponding suffix expression array using the interval index (start, end), and marks whether the node is a logical operator. For example... Figure 3 In this method, `idx` represents the position index of the suffix array, `is_logic` indicates whether it is a logical operator, `nb_operand` indicates the number of operands required, `stack[top]` is used for pushing and popping operands, and `op_type` indicates the type of operator. When a node is an operand, such as `idx=0 A`, it is dynamically assigned to a leaf node A, with the leaf node's range index `start=0`, `end=0`, and `is_logic=0`, and leaf node A is pushed onto the node stack. When a node is an operator, such as `idx=2 &&`, an AND node `node_AND` is dynamically allocated, and the left and right subtrees of this node are set, with the node's range index `start=0`, `end=2`, and `is_logic=1`. In the process of constructing a binary expression tree from the suffix array in this invention, nodes only store the (start, end) range index subscripts and do not need to copy any operand / operator data. After generating the binary expression tree from the suffix array, the pointer of the root node `node_OR` is cached in the `expr_root` field, and the nodes in the tree are stored in the fixed-byte array `expr_heap` in sequence.
[0061] like Figure 4As shown, this embodiment of the invention implements three-level adaptive path matching by calling the meta_compute_lanuch() function. First, the thread-local heap descriptor is initialized, and the fixed heap is reused by resetting the offset. The execution path is quickly selected by reading the expr_root field and the has_logic_ops flag. If the expr_root field is not empty, the constructed binary expression tree is recursively traversed. If a node is encountered that is a logical operation AND or OR, the calculation of the right subtree is skipped based on the result of the left subtree. If it is determined that it is in the hot update transition period, a temporary tree is dynamically constructed in the thread-local heap for short-circuit evaluation to ensure the continuity of matching.
[0062] like Figure 5 As shown, the traditional suffix order full evaluation scheme is labeled as Scheme 2. Compared with the short-circuit evaluation method of this invention, the rule (A&&B)||C is matched in the current scenario. In the current scenario, A=0, B=1, C=1, and the matching result of this rule is 1. The binary tree of this rule is shown below. Figure 3 As shown. Scheme 2 does not support logical short-circuiting. Even if B has no impact on the final result, it still requires evaluating the sub-conditions A+B+C a total of 3 times. However, the method of this invention executes explicit path ①, evaluating the sub-conditions A+C a total of 2 times, skipping the evaluation of B, saving 1 HTTP access. The left false truncation of the AND node plays a key role. Compared with Scheme 2, the performance advantage of this invention's AND short-circuit evaluation becomes more significant as the hit rate p decreases and the number of rules N increases. The performance improvement multiplier is greater. For example, when N=10 and p=0.01, the improvement is 9.9 times.
[0063] like Figure 6 As shown, the `eval_expr_tree()` function recursively traverses the binary expression tree to perform short-circuit evaluation of the AND logical operation. It takes the current AND node and determines whether it's a logical AND node based on the node's `is_logic` attribute and operator type. The first step is to recursively evaluate the left subtree. The second step checks if the calculated value of the left subtree is 0, indicating a short-circuit AND. If so, the third step directly performs AND short-circuit truncation, skipping the evaluation of the right subtree. At this point, it doesn't need to perform the protocol element memory reads, string / regular expression matching, KMP / Hyperscan pre-compilation, or custom function calls involved in the right subtree; it directly returns the AND evaluation result of 0. Only when the AND is not short-circuited does it need to recursively evaluate the value of the right subtree, returning the AND result of the left and right subtrees. Taking the A&&B&&C rule as an example, the matching in three scenarios is calculated. It is found that for rules with AND logical operations, the further to the left the first false condition is, the lower the hit rate; the earlier the short-circuit truncation is triggered, the more significant the performance improvement.
[0064] like Figure 7As shown, the `eval_expr_tree()` function performs short-circuit evaluation of OR nodes. Based on the node's attributes, it determines if the current node is a logical OR node. The first step recursively calculates the left subtree. The second step checks if the left subtree is true; if so, it skips the calculation of the right subtree and directly returns the OR result of 1. Otherwise, it continues recursively calculating the right subtree and then the OR result of the left and right subtrees. For OR rules A||B||C, it calculates matching in three scenarios. It is found that for AND logical operations, the further to the left the first true condition is, the lower the hit rate, and the earlier the short-circuit truncation is triggered, resulting in a more significant performance improvement.
[0065] For rules with mixed nested OR and AND operations, such as (A||B)&&(C||D), the method of this invention can skip evaluating B when A=1, C=0, and D=0, saving one string matching calculation.
[0066] like Figure 8 As shown, in the initial stage of this embodiment, the local heap space of each thread is initialized according to the number of threads using the function `meta_compute_load()`. The addresses of the thread heap spaces do not overlap, and the operations executed by different threads are independent of each other, with no data contention. During the hot update transition period, the thread allocates temporary tree nodes in the thread's local heap space by calling the function `dyn_alloc()`, and then performs short-circuit evaluation. The function `dyn_alloc()` implements lock-free space allocation with O(1) time complexity. Each thread is designed with a lock-free heap, without mutexes, CAS, or atomic operations; space is allocated sequentially for tree nodes, with 100% space utilization and no fragmentation; the entire heap is reused, and there is no need to release memory for each object.
[0067] like Figure 9The diagram shows the sequence diagram of the rule hot update transition period degradation strategy, describing the complete process of smoothly switching from old rules to new rules without interrupting online traffic matching. The diagram includes the following modules: rule control thread, rule object, and different parsing threads. Hot updates are divided into four stages: Stage A: Old rules run normally. Each parsing thread initiates a matching request by calling `meta_compute_launch(old_rule, thrdx)`, and each thread executes path 1. Stage B: New rule compilation period. After receiving the rule update instruction, the rule control thread executes `postfix_generate()` to complete the compilation of infix expressions to postfix expressions and string preprocessing. This compilation process is performed in parallel with the online matching calculations of each parsing thread. After compilation, the rule control thread writes the new rule object `new_rule` to `postfix_t`. At this point, `has_logic_ops=1` is ready, but `expr_root=NULL`, and the expression tree has not yet been built. When the parsing thread initiates matching with the new rule, it detects that `expr_root` = NULL and `has_logic_ops` = 1, triggering fallback path 2: The thread dynamically calls the function `build_expr_tree_from_postfix()` to temporarily build the expression tree, then calls `eval_expr_tree(dynamic_root)` to complete short-circuit evaluation and returns the matching result. Path 2 is slightly less performant than path 1 because it requires online tree construction, but it ensures the correctness of the matching result within the transition window, achieving a smooth fallback without downtime. Stage C: After completing the expression tree construction, the `expr_root` pointer is updated to the root node address through atomic assignment and written to `postfix_t`. Afterwards, when the parsing thread calls `meta_compute_launch(new_rule, thrdx)` again, it detects that `expr_root` ≠ NULL and automatically switches back to path 1: calling `eval_expr_tree(expr_root)` to perform optimal short-circuit evaluation, with zero memory allocation, restoring performance to optimal levels. Since the assignment of `expr_root` is an atomic operation, different threads may take path 1 or path 2 respectively within a short window, but the evaluation semantics of the two paths are equivalent and do not affect the correctness of the result. Phase D: Safe release of old rules. After confirming that all parsing threads no longer hold references to the old rule object, the old rule object is safely released, and the `postfix_t` instance along with its associated expression node heap memory `expr_heap` is reclaimed.
[0068] like Figure 10As shown, the core data structure postfix_t of this invention consists of four consecutive areas. (1) Control field area, which stores two fields: the field total records the number of valid elements in the postfix expression array, and the field has_logic_ops marks whether the rule contains AND / OR logical operators. This flag is written synchronously in try_store_op() of postfix_generate() in real time. If the flag is 0, path 3 is executed; if it is 1, path 1 or 2 is executed. (2) Postfix array area, which stores a fixed-length postfix expression array item
[64] . The elements in the array are divided into two categories: the operand item type=0, which includes the field name opd_express, the type flag and the value function pointer (get_u32val / get_u64val / get_fltval); the operator item type=1, which includes the operator expression op_express, the operator type op_type, the priority op_prior and the number of operands nb_operand. (3) String constant memory pool area, which stores string literals and LPS mismatch table pre-calculation results required by KMP algorithm in sequential allocation, managed by offset mpool.pos to avoid repeated calculation during runtime. (4) Expression tree area, which contains root node pointer expr_root and fixed byte array expr_heap
[2048] ; if expr_root=NULL, it means that the tree is not ready and is in the hot update transition period, triggering path 2 to execute; if expr_root≠NULL, it means that the pre-construction is completed, triggering path 1 to evaluate the optimal value; tree nodes are allocated sequentially in expr_heap through dyn_alloc. Figure 10It also provides a data structure for the nodes in the tree, with each node containing the following fields: `is_logic` (identifying whether it is an AND or OR logical node); `op_type` (identifying whether it is an AND or OR operator); `start` (the smallest index of the suffix array covered by the current node's subtree); `end` (the largest index of the suffix array covered by the current node's subtree; (start, end) only records the range and does not copy operand data); `left` (a pointer to the left child node, pointing to the internal address of the `expr_heap` array); `right` (a pointer to the right child node, pointing to the internal address of the `expr_heap` array); if `left` and `right` are NULL, it means there are no left or right child nodes. The object memory organization designed by this invention is statically determined at compile time and requires no additional heap allocation at runtime. The design advantages are: using a fixed byte array instead of dynamic memory allocation eliminates heap fragmentation and improves CPU L1 / L2 cache hit rate (due to contiguous physical addresses); range indexes do not copy data, and tree nodes only store two uint16_ts (start, end), reducing memory usage and copying overhead; the expr_heap of the rule object is allocated and released together with the postfix_t, eliminating the risk of dangling pointers.
[0069] The following lists some types of rules to illustrate the technical effects of using the method of this invention.
[0070] Example 1: Pure arithmetic / relational rules, for example, the rule is ip.ttl > 64.
[0071] This rule does not contain logical AND / OR, has_logic_ops=0, and expr_root=NULL. The method of this invention uses path 3 linear postfix evaluation for decision-making. During rule matching, the linear postfix evaluation function eval_postfix_linear() is directly called, resulting in a time complexity of O(N). It eliminates the need for tree construction and minimizes overhead.
[0072] Example 2: AND short-circuit rule, for example, the rule is A && B && C.
[0073] This rule contains logical AND operations, with `has_logic_ops=1`. At compile time, it generates a suffix array `[A,B,&&,C,&&]`, which is used to construct a binary tree in `expr_heap[]`. The root node is `AND(AND(A,B),C)`, and `expr_root` points to the root node. During runtime matching: A is evaluated first; if A = false, the AND node immediately returns false, skipping the evaluation of B and C (short-circuiting); if A = true, the right subtree B of `AND(A,B)` is evaluated; and so on. Compared to full evaluation, when A = false, 2 / 3 of the computation is saved.
[0074] Example 3: OR short-circuit rule, for example, the rule is X || Y || Z.
[0075] This rule includes a logical OR, with left-true truncation in the OR node: First, evaluate X; if X = true, the OR node immediately returns true, skipping the evaluation of Y and Z. If X = false, then evaluate Y; if Y = true, skip Z.
[0076] Example 4: During the hot update transition period, perform dynamic tree short-circuit evaluation for path 2.
[0077] During a hot rule update: the new rule has set has_logic_ops=1, but expr_root has not yet been built and is NULL. At this point, matching follows path 2: a temporary tree is dynamically built on the thread-local heap, and the offset is reset after short-circuit evaluation to reuse heap space, ensuring matching continuity and preventing interruptions or errors.
[0078] Example 5: String precompilation.
[0079] For example, if the rule is a floating match of `http.url ^ " / admin"`, in step 2, the string " / admin" is submitted to the Hyperscan regular expression engine for pre-compilation. The runtime function `hs_scan()`, which scans the data at runtime, directly uses the pre-compiled database without needing to recompile. For example, if the rule is a fixed match of `http.url == " / login"`, the KMP LPS table for the string " / login" is calculated during compilation and stored in the `array_sz` field of the operand structure, which is then used directly at runtime.
[0080] Example 6: String pre-compilation (KMP + Hyperscan).
[0081] For example, in the case of a floating match for the rule `http.url ^ " / admin"`, in step S2, the string " / admin" is submitted to the Hyperscan regular expression engine for pre-compilation. The runtime function `hs_scan()` directly uses the pre-compiled database without needing to compile again. Similarly, in the case of a fixed match for the rule `http.url == " / login"`, the KMP LPS table for the string " / login" is calculated during compilation and stored in the `array_sz` field of the operand structure, which is then used directly at runtime.
[0082] The above example demonstrates that the short-circuit evaluation method of this invention significantly reduces unnecessary computations. For instance, a rule contains N sub-conditions connected by AND, each sub-condition having an individual hit rate (probability of being true) of p, and the expected evaluation time for each sub-condition being T. Traditional postfix order evaluation (Scheme 2) always takes N·T in total time, regardless of the hit rate p; the expected time for short-circuit evaluation in this invention is E[cost] = T(1-p). N ) / (1-p). For example... Figure 5 As shown in the table, the smaller p is (the lower the sub-condition hit rate) and the larger N is (the more sub-conditions), the higher the optimization factor of E[cost] of the present invention compared with the traditional scheme. For example, when p=0.01 and N=10, the expected time of the method of the present invention is only 1 / 9.90 of the traditional scheme, which is nearly 10 times the optimization. The more significant the optimization effect, the better. This shows that the method of the present invention is perfectly adapted to the network traffic detection scenario with multiple sub-conditions and low hit rate.
[0083] This invention eliminates runtime construction overhead by pre-constructing the tree, improving CPU cache locality. The binary expression tree is constructed all at once during rule loading, and all tree nodes are stored contiguously in the expr_heap
[2048] fixed byte array, with contiguous physical addresses, improving L1 / L2 cache hit rate. There are no malloc() calls in the execution path of eval_expr_tree() at runtime. During the three-level adaptive path selection, only two fields need to be checked, with a time complexity of O(1). Furthermore, the three paths take into account various types of rules: simple rules follow path 3 with no tree traversal overhead, complex rules follow path 1 to maximize short-circuit benefits, and path 2 is used during the hot update transition period to ensure matching continuity.
[0084] The method of this invention sets up multiple concurrent matching threads, each using an independent heap space heap_space[thrdx]. The allocation operation is O(1) pointer collision, without any mutex locks or atomic operations, and the matching throughput scales linearly with the number of CPU cores. When constructing the binary expression tree, the tree nodes do not copy operand / operator data, but only store the interval index shared suffix array. For example, each interval index is 2 bytes, and the tree node is about 24 bytes. expr_heap
[2048] can hold up to about 85 nodes, which is sufficient to cover complex rules with up to 64 suffix elements, significantly reducing memory usage.
[0085] Except for the technical features described in the specification, all other technologies are known to those skilled in the art. Descriptions of well-known components and technologies are omitted in this invention to avoid redundancy and unnecessary limitation. The embodiments described above do not represent all embodiments consistent with this application. Various modifications or variations that can be made by those skilled in the art without creative effort based on the technical solutions of this invention are still within the protection scope of this invention.
[0086] In general, the various exemplary embodiments of this disclosure can be implemented in hardware or dedicated circuitry, software, firmware, logic, or any combination thereof. Some aspects can be implemented in hardware, while others can be implemented in firmware or software executed by a controller, microprocessor, or other computing device. When aspects of embodiments of this disclosure are illustrated or described as block diagrams, flowcharts, or using some other graphical representation, it will be understood that the blocks, apparatuses, systems, techniques, or methods described herein can be implemented as non-limiting examples in hardware, software, firmware, dedicated circuitry or logic, general-purpose hardware or controllers or other computing devices, or some combination thereof.
Claims
1. A short-circuit evaluation rule matching method based on binary expression tree pre-compilation, characterized in that, Load rules for network traffic detection, wherein the rules are strings using infix expressions. The method executes steps 1-5 at compile time and step 6 at runtime, including: Step 1: The compiler creates a rule object for each rule and stores it in a preset storage area. It then performs operator registration for the rule, registering the operators in the rule to the operator mapping table of the device operating system. The rule object includes a logical operator flag `has_logic_ops`, a postfix expression array `item`, a string pool `mpool`, and a binary expression tree. The binary expression tree includes a fixed-byte array `expr_heap` for storing nodes in the tree, and a field `expr_root` that caches the root node pointer of the tree. The flag `has_logic_ops` is initially set to false. Step 2: Convert the infix expression of the rule into a postfix expression array and store it in the rule object; during the conversion of the infix expression into a postfix expression array, store the detected string into the string pool mpool; when writing the logical operator AND or OR into the postfix expression array, synchronously set the flag has_logic_ops to true. Step 3: Perform pre-compilation on the string constant operands in the rules; the string constant operands are read from the string pool mpool; Step 4: Perform validity verification on the operands of the protocol elements in the rules; Step 5 involves pre-constructing the binary tree, including: if the flag has_logic_ops is true in an execution path, restoring the postfix expression array into a binary expression tree through the node stack, storing all nodes of the tree contiguously in the fixed byte array expr_heap of the rule object, and caching the root node pointer in the expr_root field; the nodes in the tree use the range index (start, end) to reference the operands or operators in the postfix expression array to calculate the range. Step 6: When matching messages in real time, read the postfix expression array, string pool, and binary expression tree of the rule object stored by the compiler, adaptively select the evaluation path, and output the matching result; The adaptive selection of the evaluation path includes: checking expr_root and has_logic_ops; if expr_root is not empty, execute path 1; if expr_root is empty and has_logic_ops is true, execute path 2; if has_logic_ops is false, execute path 3. Path 1 performs short-circuit evaluation by recursively traversing the binary expression tree. If the left subtree of an AND node is false, the right subtree is immediately truncated for evaluation; if the left subtree of an OR node is true, the right subtree is immediately truncated for evaluation. Path 2 performs short-circuit evaluation after dynamically constructing a temporary tree using the thread-local heap during the hot update transition period. Path 3 directly performs evaluation by linearly traversing the postfix expression array.
2. The method according to claim 1, characterized in that, Step 1 includes: predefining a system operator loading function and a custom operator loading function; registering system built-in operators through the system operator loading function, including arithmetic operators, relational operators, string matching operators, and logical operators; and registering protocol element string operators and custom function operators through the custom operator loading function; the protocol element string refers to the network packet field referenced in the rule.
3. The method according to claim 1, characterized in that, Step 2 includes: using a scheduling field algorithm to convert the infix expression of the rule into a postfix expression array; defining a function try_store_op() in the scheduling field algorithm to pop operators from the operator stack and write them into the postfix expression array; and setting the flag has_logic_ops of the same execution path to true when the function try_store_op() writes logical AND or logical OR operators into the postfix expression array.
4. The method according to claim 1, characterized in that, Step 4 includes: the protocol element operand refers to the network packet field referenced in the rule; validating the protocol element operand means verifying whether the network packet field is a valid field of the protocol element string operator that has been registered; and determining whether the format of the field meets the requirements according to the configuration rules.
5. The method according to claim 1, characterized in that, Step 6 includes: all dynamic memory allocations during runtime are performed sequentially on thread-independent fixed heaps in a collision-based manner, and the offsets are reset and the entire heap space is reused after the function returns.
6. The method according to claim 1 or 5, characterized in that, Step 6 includes: initially initializing the local heap space for each thread, ensuring that the addresses of the thread heap spaces do not overlap and that each thread heap space is lock-free; during the hot update transition period, the compiler performs infix expression to postfix expression array conversion on the loaded new rules. If has_logic_ops is true and the postfix expression array has not yet been constructed into a binary expression tree, a temporary tree is dynamically constructed in the local heap of each thread, space is allocated sequentially for the tree nodes, and then short-circuit evaluation is performed.
7. The method according to claim 1, characterized in that, In step 1, the data structure of the rule object consists of four contiguous areas: a control field area, which stores the fields `total` and `has_logic_ops`. `total` records the number of valid elements in the postfix expression array, and `has_logic_ops` indicates whether the rule contains AND / OR logical operators; a postfix array area, which stores a fixed-length postfix expression array. The elements in the array are divided into operands and operators. The operand fields include the field name, type flag, and value retrieval function pointer, while the operator fields include the operator expression, operator type, priority, and number of operands; a string constant memory pool area, which stores the string pool `mpool` and the precompiled KMP prefix function table in a sequential allocation manner; and a binary expression tree area, which stores the array `expr_heap` and the field `expr_root`.
8. The method according to claim 1, characterized in that, In step 5, the data structure of the nodes in the binary expression tree includes the following fields: is_logic, indicating whether it is an AND or OR logical node; op_type, indicating whether it is an AND operator or an OR operator; start, the minimum index of the postfix expression array covered by the subtree of this node; end, the maximum index of the postfix expression array covered by the subtree of this node; left, left child node pointer; right, right child node pointer, the pointer points to the internal address of the expr_heap array.
9. A short-circuit evaluation rule matching system based on binary expression tree pre-compilation, characterized in that, It includes an operator registration module, an infix to postfix compiler, a string pre-compiler, a validity verification module, a tree pre-construction module, and a three-level adaptive evaluation engine; The system loads rules for network traffic detection, which are strings using infix regular expressions. The compiler creates a rule object for each rule and stores it in a preset storage area. The rule object includes a logical operator flag has_logic_ops, a postfix expression array item, a string pool mpool, and a binary expression tree. The binary expression tree includes a fixed-byte array expr_heap for storing nodes in the tree, and a field expr_root for caching the root node pointer of the tree. The flag has_logic_ops is initially set to false. During compilation, the operator registration module registers the operators in the rules into the operator mapping table of the device operating system; The infix-to-postfix compiler converts the infix expression of a rule into an array of postfix expressions and stores them in the rule object; The infix-to-postfix compiler stores the detected strings into the string pool `mpool` during the process of converting infix expressions to postfix expression arrays. When writing logical operators AND or OR into the postfix expression array, it synchronously sets the flag `has_logic_ops` to true. The string pre-compiler performs pre-compilation on the string constant operands in the rules. The validity verification module performs validity verification on the protocol element operands in the rules. Tree The pre-construction module performs binary tree pre-construction, including: if the flag bit has_logic_ops is true in an execution path, restoring the postfix expression array into a binary expression tree through the node stack, storing all nodes of the tree contiguously in the fixed byte array expr_heap of the rule object, and caching the root node pointer in the expr_root field; the nodes in the tree reference operands or operators in the postfix expression array using the range index (start, end); During runtime, the three-level adaptive evaluation engine reads the postfix expression array, string pool, and binary expression tree of the rule objects stored by the compiler, performs real-time matching of messages, adaptively selects the evaluation path, and outputs the matching result. The adaptive selection of the evaluation path includes: checking expr_root and has_logic_ops; if expr_root is not empty, execute path 1; if expr_root is empty and has_logic_ops is true, execute path 2; if has_logic_ops is false, execute path 3. Among them, path 1 performs short-circuit evaluation by recursively traversing the binary expression tree, immediately truncating if the left subtree of the AND node is false, and immediately truncating if the left subtree of the OR node is true; path 2 performs short-circuit evaluation after dynamically constructing a temporary tree through the thread-local heap during the hot update transition period; path 3 directly performs evaluation by linearly traversing the postfix expression array.
