rumpk/core/fastpath.nim

113 lines
3.5 KiB
Nim

# SPDX-License-Identifier: LSL-1.0
# Copyright (c) 2026 Markus Maiwald
# Stewardship: Self Sovereign Society Foundation
#
# This file is part of the Nexus Sovereign Core.
# See legal/LICENSE_SOVEREIGN.md for license terms.
## Fast Path Bypass (SPEC-700)
##
## Intercepts UTCP tunnel traffic (UDP/9999) before LwIP processing.
## Zero-copy header stripping via pointer arithmetic.
# Constants
const
UTCP_TUNNEL_PORT* = 9999'u16
ETHERTYPE_IPV4* = 0x0800'u16
IPPROTO_UDP* = 17'u8
# Header sizes
ETH_HEADER_LEN* = 14
IP_HEADER_LEN* = 20
UDP_HEADER_LEN* = 8
TUNNEL_OVERHEAD* = ETH_HEADER_LEN + IP_HEADER_LEN + UDP_HEADER_LEN # 42 bytes
# MTU safety
MAX_UTCP_FRAME* = 1400'u16 # Safe for PPPoE/VPN
proc kprint(s: cstring) {.importc, cdecl.}
proc kprintln(s: cstring) {.importc, cdecl.}
proc kprint_hex(n: uint64) {.importc, cdecl.}
# --- Fast Path Detection ---
proc is_utcp_tunnel*(data: ptr UncheckedArray[byte], len: uint16): bool {.exportc, cdecl.} =
## Check if packet is a UTCP tunnel packet (UDP port 9999)
## Returns true if packet should bypass LwIP
# DEBUG: Print first 50 bytes
kprintln("[FastPath] Checking packet...")
kprint(" Len: "); kprint_hex(uint64(len)); kprintln("")
if len >= 42:
kprint(" EthType: "); kprint_hex(uint64((uint16(data[12]) shl 8) or uint16(data[13]))); kprintln("")
kprint(" IPProto: "); kprint_hex(uint64(data[23])); kprintln("")
if len >= 38:
let dst_port = (uint16(data[36]) shl 8) or uint16(data[37])
kprint(" DstPort: "); kprint_hex(uint64(dst_port)); kprintln("")
# Minimum size check: ETH(14) + IP(20) + UDP(8) = 42 bytes
if len < TUNNEL_OVERHEAD:
return false
# Check EtherType (big-endian at offset 12-13)
let eth_type = (uint16(data[12]) shl 8) or uint16(data[13])
if eth_type != ETHERTYPE_IPV4:
return false
# Check IP Protocol (offset 23 in frame = offset 9 in IP header)
let ip_proto = data[23]
if ip_proto != IPPROTO_UDP:
return false
# Check UDP destination port (big-endian at offset 36-37)
# ETH(14) + IP(20) + UDP dst port offset(2) = 36
let dst_port = (uint16(data[36]) shl 8) or uint16(data[37])
if dst_port == UTCP_TUNNEL_PORT:
kprintln("[FastPath] UTCP TUNNEL DETECTED!")
return dst_port == UTCP_TUNNEL_PORT
proc strip_tunnel_headers*(data: ptr UncheckedArray[byte], len: var uint16): ptr UncheckedArray[byte] {.exportc, cdecl.} =
## Strip ETH+IP+UDP headers from tunnel packet (zero-copy)
## Returns pointer to UTCP header, adjusts length
##
## SAFETY: Caller must ensure len >= TUNNEL_OVERHEAD
if len < TUNNEL_OVERHEAD:
return nil
# Zero-copy: just advance pointer
let utcp_data = cast[ptr UncheckedArray[byte]](
cast[uint64](data) + TUNNEL_OVERHEAD
)
len = len - TUNNEL_OVERHEAD
return utcp_data
proc check_mtu*(len: uint16): bool =
## Check if UTCP frame exceeds safe MTU
return len <= MAX_UTCP_FRAME
# --- Source Address Extraction (for response routing) ---
type
TunnelSource* = object
ip*: uint32 # Source IP (network byte order)
port*: uint16 # Source port
proc extract_tunnel_source*(data: ptr UncheckedArray[byte]): TunnelSource =
## Extract source IP and port from tunnel packet for response routing
# Source IP at ETH(14) + IP src offset(12) = 26
result.ip = (uint32(data[26]) shl 24) or
(uint32(data[27]) shl 16) or
(uint32(data[28]) shl 8) or
uint32(data[29])
# Source port at ETH(14) + IP(20) + UDP src offset(0) = 34
result.port = (uint16(data[34]) shl 8) or uint16(data[35])