diff options
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/linux.rs | 43 | ||||
| -rw-r--r-- | src/platform/windows.rs | 4 |
2 files changed, 42 insertions, 5 deletions
diff --git a/src/platform/linux.rs b/src/platform/linux.rs index cf6e3dd..02b174b 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -36,6 +36,8 @@ const DPIBREAK_CHAIN: &str = "DPIBREAK"; pub static QUEUE_NUM: OnceLock<u16> = OnceLock::new(); pub static NFT_COMMAND: OnceLock<String> = OnceLock::new(); +const INJECT_MARK: u32 = 0xD001; + fn queue_num() -> u16 { *QUEUE_NUM.get().expect("QUEUE_NUM not initialized") } @@ -143,6 +145,15 @@ fn install_iptables_rules(ipt: &IPTables) -> Result<()> { }; ipt.new_chain("mangle", DPIBREAK_CHAIN).map_err(iptables_err)?; + + // prevent inf loop + ipt.insert( + "mangle", + DPIBREAK_CHAIN, + &format!("-m mark --mark {:#x} -j RETURN", INJECT_MARK), + 1 + ).map_err(iptables_err)?; + ipt.append("mangle", DPIBREAK_CHAIN, &rule).map_err(iptables_err)?; log_println!(LogLevel::Info, "{}: new chain {} on table mangle", ipt.cmd, DPIBREAK_CHAIN); @@ -198,6 +209,26 @@ fn install_nft_rules() -> Result<()> { } } }, + // prevent inf loop + { + "add": { + "rule": { + "family": "inet", + "table": DPIBREAK_TABLE, + "chain": DPIBREAK_CHAIN, + "expr": [ + { + "match": { + "left": { "meta": { "key": "mark" }}, + "op": "==", + "right": INJECT_MARK + } + }, + { "return": null } + ] + } + } + }, { "add": { "rule": { @@ -325,16 +356,20 @@ use socket2::{Domain, Protocol, Socket, Type}; static RAW4: LazyLock<Mutex<Socket>> = LazyLock::new(|| { let sock = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::TCP)) .expect("create raw4"); - sock.set_header_included_v4(true) - .expect("IP_HDRINCL"); + + sock.set_header_included_v4(true).expect("IP_HDRINCL"); + sock.set_mark(INJECT_MARK).expect("SO_MARK"); + Mutex::new(sock) }); static RAW6: LazyLock<Mutex<Socket>> = LazyLock::new(|| { let sock = Socket::new(Domain::IPV6, Type::RAW, Some(Protocol::TCP)) .expect("create raw6"); - sock.set_header_included_v6(true) - .expect("IP_HDRINCL"); + + sock.set_header_included_v6(true).expect("IP_HDRINCL"); + sock.set_mark(INJECT_MARK).expect("SO_MARK"); + Mutex::new(sock) }); diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 1708038..4d75e0e 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -28,7 +28,8 @@ pub static WINDIVERT_HANDLE: LazyLock<Mutex<WinDivert<NetworkLayer>>> = LazyLock const FILTER: &str = "outbound and tcp and tcp.DstPort == 443 \ and tcp.Payload[0] == 22 \ - and tcp.Payload[5] == 1"; // handshake, clienthello + and tcp.Payload[5] == 1 \ + and !impostor"; // to prevent inf loop let h = match WinDivert::network(FILTER, 0, prelude::WinDivertFlags::new()) { Ok(h) => { @@ -73,6 +74,7 @@ pub fn send_to_raw(pkt: &[u8]) -> Result<()> { p.address.set_outbound(true); p.address.set_ip_checksum(true); p.address.set_tcp_checksum(true); + p.address.set_impostor(true); // to prevent inf loop lock_handle().send(&p)?; |
