v0.3: 6-layer architecture complete

Layers:
  Layer 1: XDP/eBPF — TCP state machine, SYN throttle, blacklist, ringbuf
  Layer 2: PoW Challenge — SHA-256 hashcash, dynamic difficulty, constant-time verify
  Layer 3: Rust Core — HMAC handshake, rate limit, death code (existing)
  Layer 4: Velocity — Physics check, CAPTCHA, protocol verification
  Layer 5: Paper — Heartbeat, auto-registration (existing)
  Layer 6: Traffic Intel — EWMA, 168h profiling, reputation, alerts

Infra: XDP→Prometheus metrics, ClickHouse + Grafana dashboard, Docker Compose
Testing: 100-IP DDoS simulation, MHDDoS ref analysis, load test report
Fixes: VarInt sign extension UB, pure ACK deadlock, RST/FIN cleanup
Ref: MHDDoS, Sonar, LimboFilter, AtomGuard, Infrarust, MC-XDP-eBPF, PowGo
This commit is contained in:
loki5512344 2026-07-21 15:47:36 +02:00
parent 78fc6e00c7
commit 269daa071f
Signed by: boba
GPG key ID: 253067914055423B
66 changed files with 4529 additions and 1003 deletions

183
xdp/protocol.h Normal file
View file

@ -0,0 +1,183 @@
#ifndef RAMPART_PROTOCOL_H
#define RAMPART_PROTOCOL_H
#include "common.h"
#include "varint.h"
// ── Handshake inspector ──
// Returns: pseudo-state for next action, or 0 on failure
// DIRECT_READ_LOGIN — handshake + login in same segment
// DIRECT_READ_STATUS — handshake + status in same segment
// AWAIT_LOGIN — handshake only, wait for login
// AWAIT_STATUS — handshake only, wait for status req
// RECEIVED_LEGACY_PING — 0xFE legacy ping
// 0 — parse error
#define DIRECT_READ_LOGIN 100
#define DIRECT_READ_STATUS 101
#define RECEIVED_LEGACY_PING 102
static __always_inline __s32 inspect_handshake(
__u8 **cursor, __u8 *payload_end, __s32 *protocol, void *data_end)
{
__u8 *ptr = *cursor;
// Legacy ping check (0xFE)
CHECK_BOUNDS_OR_RETURN(ptr, 1, payload_end, data_end);
if (ptr[0] == (__u8)0xFE) {
return RECEIVED_LEGACY_PING;
}
// Read total packet length
struct varint_value pkt_len = read_varint(ptr, payload_end, data_end);
if (pkt_len.bytes == 0) goto error;
ptr += pkt_len.bytes;
// Packet ID must be 0 (Handshake)
CHECK_BOUNDS_OR_RETURN(ptr, 1, payload_end, data_end);
struct varint_value pkid = read_varint(ptr, payload_end, data_end);
if (pkid.bytes == 0 || pkid.value != 0) goto error;
ptr += pkid.bytes;
// Protocol version
struct varint_value pv = read_varint(ptr, payload_end, data_end);
if (pv.bytes == 0 || pv.value < 0) goto error;
*protocol = pv.value;
ptr += pv.bytes;
// Server address (varint-length-prefixed string, max 765 bytes)
struct varint_value addr_len = read_varint(ptr, payload_end, data_end);
if (addr_len.bytes == 0 || addr_len.value < 0 || addr_len.value > 765)
goto error;
ptr += addr_len.bytes;
CHECK_BOUNDS_OR_RETURN(ptr, addr_len.value, payload_end, data_end);
ptr += addr_len.value;
// Server port (u16)
CHECK_BOUNDS_OR_RETURN(ptr, 2, payload_end, data_end);
// __u16 port = (ptr[0] << 8) | ptr[1]; — skip, not used
ptr += 2;
// Next state (1=status, 2=login, 3=transfer since 1.20.5)
struct varint_value ns = read_varint(ptr, payload_end, data_end);
if (ns.bytes == 0) goto error;
if (ns.value != 1 && ns.value != 2 && ns.value != 3) goto error;
ptr += ns.bytes;
// Verify declared length matches consumed
__u32 consumed = (__u32)(ptr - *cursor);
__u32 declared_len = (__u32)(pkt_len.value + pkt_len.bytes);
if (consumed > declared_len) goto error;
*cursor = ptr;
// Check if more data follows in same segment
if (consumed < declared_len + 2) {
// Handshake only — return expected next state
return (ns.value == 1) ? 103 /* AWAIT_STATUS */ : 104 /* AWAIT_LOGIN */;
}
// More data present — return direct-read state
return (ns.value == 1) ? DIRECT_READ_STATUS : DIRECT_READ_LOGIN;
error:
return 0;
}
// ── LoginStart inspector ──
static __always_inline __u8 inspect_login_packet(
__u8 *ptr, __u8 *payload_end, __s32 protocol, void *data_end)
{
// Packet length
struct varint_value pkt_len = read_varint(ptr, payload_end, data_end);
if (pkt_len.bytes == 0) goto error;
ptr += pkt_len.bytes;
// Packet ID must be 0 (LoginStart)
struct varint_value pkid = read_varint(ptr, payload_end, data_end);
if (pkid.bytes == 0 || pkid.value != 0) goto error;
ptr += pkid.bytes;
// Username (varint-length-prefixed string)
struct varint_value name_len = read_varint(ptr, payload_end, data_end);
if (name_len.bytes == 0 || name_len.value <= 0) goto error;
ptr += name_len.bytes;
__s32 max_name = (protocol >= 764) ? 16 : 48; // 1.20.2+ uses 16
if (name_len.value > max_name || name_len.value > 48) goto error;
CHECK_BOUNDS_OR_RETURN(ptr, name_len.value, payload_end, data_end);
// Skip username bytes
ptr += name_len.value;
// For 1.19.1+ (protocol >= 760): optional UUID
if (protocol >= 760) {
CHECK_BOUNDS_OR_RETURN(ptr, 1, payload_end, data_end);
__u8 has_uuid = ptr[0];
ptr += 1;
if (has_uuid) {
CHECK_BOUNDS_OR_RETURN(ptr, 16, payload_end, data_end);
ptr += 16; // skip UUID
}
}
// For 1.19-1.19.2 (759-760): optional public key
if (protocol >= 759 && protocol < 761) {
CHECK_BOUNDS_OR_RETURN(ptr, 1, payload_end, data_end);
__u8 has_key = ptr[0];
ptr += 1;
if (has_key) {
// Expiry (long)
CHECK_BOUNDS_OR_RETURN(ptr, 8, payload_end, data_end);
ptr += 8;
// Key length (varint)
struct varint_value key_len = read_varint(ptr, payload_end, data_end);
if (key_len.bytes == 0) goto error;
ptr += key_len.bytes;
CHECK_BOUNDS_OR_RETURN(ptr, key_len.value, payload_end, data_end);
ptr += key_len.value;
// Signature length (varint)
struct varint_value sig_len = read_varint(ptr, payload_end, data_end);
if (sig_len.bytes == 0) goto error;
ptr += sig_len.bytes;
CHECK_BOUNDS_OR_RETURN(ptr, sig_len.value, payload_end, data_end);
ptr += sig_len.value;
}
}
return 1; // success
error:
return 0;
}
// ── Status request inspector ──
// Must be: [len=0x01][id=0x00]
static __always_inline __u8 inspect_status_request(
__u8 *ptr, __u8 *payload_end, void *data_end)
{
CHECK_BOUNDS_OR_RETURN(ptr, 2, payload_end, data_end);
if (ptr[0] != 0x01 || ptr[1] != 0x00)
goto error;
return 1;
error:
return 0;
}
// ── Ping request inspector ──
// Must be: [len=0x09][id=0x01][8 byte timestamp/long]
static __always_inline __u8 inspect_ping_request(
__u8 *ptr, __u8 *payload_end, void *data_end)
{
CHECK_BOUNDS_OR_RETURN(ptr, 10, payload_end, data_end);
if (ptr[0] != 0x09 || ptr[1] != 0x01)
goto error;
return 1;
error:
return 0;
}
#endif /* RAMPART_PROTOCOL_H */