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
63 lines
2.2 KiB
C
63 lines
2.2 KiB
C
#ifndef RAMPART_VARINT_H
|
|
#define RAMPART_VARINT_H
|
|
|
|
#include "common.h"
|
|
|
|
// ── VarInt reader with dual-bounds check ──
|
|
// Returns {value, bytes_consumed} on success, goto error on failure
|
|
// Fixed: no sign extension UB (shift in u32, cast to s32)
|
|
// Fixed: max 5 bytes per Minecraft protocol spec
|
|
|
|
#define VARINT_BYTE(ptr, pend, dend, max, idx, shift, result) \
|
|
do { \
|
|
if ((max) < (idx)) \
|
|
goto error; \
|
|
if ((void *)(ptr) + 1 > (void *)(dend)) \
|
|
goto error; \
|
|
if ((void *)(ptr) + 1 > (void *)(pend)) \
|
|
goto error; \
|
|
__u8 _b = *(ptr)++; \
|
|
(result) |= ((__u32)(_b & 0x7F) << (shift)); \
|
|
if (!(_b & 0x80)) \
|
|
return varint((__s32)(result), (idx)); \
|
|
} while (0)
|
|
|
|
struct varint_value {
|
|
__s32 value;
|
|
__u8 bytes;
|
|
};
|
|
|
|
static __always_inline struct varint_value varint(__s32 value, __u8 bytes)
|
|
{
|
|
struct varint_value v = { .value = value, .bytes = bytes };
|
|
return v;
|
|
}
|
|
|
|
static __always_inline struct varint_value read_varint_sized(
|
|
__u8 *ptr, __u8 *pend, __u8 max, void *dend)
|
|
{
|
|
__u32 result = 0;
|
|
|
|
VARINT_BYTE(ptr, pend, dend, max, 1, 0, result);
|
|
VARINT_BYTE(ptr, pend, dend, max, 2, 7, result);
|
|
VARINT_BYTE(ptr, pend, dend, max, 3, 14, result);
|
|
VARINT_BYTE(ptr, pend, dend, max, 4, 21, result);
|
|
if (max < 5) goto error;
|
|
if ((void *)(ptr) + 1 > (void *)(dend)) goto error;
|
|
if ((void *)(ptr) + 1 > (void *)(pend)) goto error;
|
|
__u8 b5 = *(ptr)++;
|
|
result |= ((__u32)(b5 & 0x7F) << 28);
|
|
result &= 0x7FFFFFFF;
|
|
return varint((__s32)result, 5);
|
|
|
|
error:
|
|
return varint(0, 0);
|
|
}
|
|
|
|
// Convenience: read varint with max=5 (full Minecraft varint)
|
|
static __always_inline struct varint_value read_varint(__u8 *ptr, __u8 *pend, void *dend)
|
|
{
|
|
return read_varint_sized(ptr, pend, 5, dend);
|
|
}
|
|
|
|
#endif /* RAMPART_VARINT_H */
|