113 lines
3.5 KiB
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])
|