Skip to main content

trojan_rules/
rule.rs

1//! Rule and action type definitions.
2
3use std::net::IpAddr;
4
5use ipnet::IpNet;
6use serde::{Deserialize, Serialize};
7
8/// A parsed rule from a rule-set file.
9#[derive(Debug, Clone)]
10pub enum ParsedRule {
11    Domain(String),
12    DomainSuffix(String),
13    DomainKeyword(String),
14    IpCidr(IpNet),
15    /// Match on destination port.
16    DstPort(u16),
17    /// Match on source IP CIDR.
18    SrcIpCidr(IpNet),
19    // GEOIP and FINAL are handled at the engine level, not in rule-sets.
20}
21
22/// Action to take when a rule matches.
23#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
24#[serde(rename_all = "UPPERCASE")]
25pub enum Action {
26    /// Connect directly to the target.
27    Direct,
28    /// Reject the connection.
29    Reject,
30    /// Route through a named outbound.
31    #[serde(untagged)]
32    Outbound(String),
33}
34
35impl Action {
36    /// Check if this is the DIRECT action.
37    pub fn is_direct(&self) -> bool {
38        matches!(self, Action::Direct)
39    }
40
41    /// Check if this is the REJECT action.
42    pub fn is_reject(&self) -> bool {
43        matches!(self, Action::Reject)
44    }
45}
46
47/// A compiled rule in the engine's rule list.
48#[derive(Debug)]
49pub(crate) enum EngineRule {
50    /// Match against a named rule-set.
51    RuleSet { name: String, action: Action },
52    /// Match against a GEOIP country code.
53    GeoIp { code: String, action: Action },
54    /// Inline single rule (type + value).
55    Inline { rule: ParsedRule, action: Action },
56    /// Final catch-all rule.
57    Final { action: Action },
58}
59
60/// Context for matching a request against rules.
61#[derive(Debug)]
62pub struct MatchContext<'a> {
63    /// Target domain name (when the target is a domain).
64    pub domain: Option<&'a str>,
65    /// Target IP address (when the target is an IP or after DNS resolution).
66    pub dest_ip: Option<IpAddr>,
67    /// Target port.
68    pub dest_port: u16,
69    /// Source (client) IP address.
70    pub src_ip: IpAddr,
71}