/sec/zero-delay

ANALYSE EVDEV STROOM 2026-06-17

• Het Vraagstuk

Linux is CC. CC is analoog vertaald naar code. Analoog stroomt. Net als bij elke wisselmotor kun je frequentie aanpassen. Vrije custom toetsen = je kunt engineeren hoe de stroom loopt. Het doel: stroom zonder delay.
ConceptStatusImpact
evdev als analoog veldbevestigdHardware interrupt → kernel buffer
CC = code circuitbevestigdCode = vertaalde stroom
Polling = stolselbottleneck1ms sleep = gestolde stroom
epoll = interruptte bouwenZero-delay mogelijk via libuv
Custom event freqtheoretischEigen frequentie = eigen taal

• De Stroom

Huidige Stroom (met delay)

hardware → kernel → user space → actie

Hardware
  `/dev/input/eventX`

Kernel Ringbuffer
  24 bytes × 64 slots

evdev-reader.js
  readSync → EAGAIN → sleep(1ms) → herhaal
[DELAY: ~1-10ms]
slot-router.js
  keycode → slot → IPv6

payload-executor.js
  payload → actie

Resultaat
Hardware IRQ Ringbuffer poll(1ms) slot-router executor

• De Bottleneck

// evdev-reader.js — HUIDIGE IMPLEMENTATIE
async function* readEvents(devicePath) {
  while (true) {
    try {
      const { bytesRead } = fs.readSync(fd, buf, 0, 24);
      if (bytesRead === 24) yield parseEvent(buf);
    } catch (err) {
      // ← HIER STOLT DE STROOM
      if (err.code === 'EAGAIN') {
        await new Promise(r => setTimeout(r, 1));
      }
    }
  }
}
ProbleemOorzaakEffect
readSync blokkeertGeen native epoll in JSThread blokkeert tot read complete
setTimeout(1ms)Event loop granularityMinimaal 1ms vertraging per cycle
EAGAIN loopNon-blocking fd leegPolling: vraag continu "is er data?"
Buffer parseJSON + object createExtra 0.1-0.5ms per event

Analogie: Je hebt een kraan (hardware interrupt). In plaats van direct water te laten lopen (epoll), draai je elke milliseconde even de kraan open om te kijken of er water komt (polling). Het water stolt tussen de polles door.

• Zero-Delay Architectuur

De oplossing: libuv doet epoll al

hardware → kernel → libuv epoll → stream → actie

Hardware
  `/dev/input/eventX`

Kernel Ringbuffer
  24 bytes × 64 slots

libuv / epoll
  Automatisch — geen JS code nodig
[DELAY: ~0μs]
ReadableStream
  `data` event = direct

slot-router.js
  keycode → slot → IPv6

payload-executor.js

Resultaat
Hardware IRQ Ringbuffer libuv epoll ReadableStream slot-router executor
MethodeDelayStatus
Huidig: polling1-10msactief
libuv stream~0μste bouwen
C addon epoll~0μscomplexer
Direct fd pipe~0μssnelste route

• Frequentie Engineeren

Custom evdev events = eigen frequentie. Net als een wisselmotor kun je de snelheid aanpassen:

FrequentieGebruikEvent Type
StandardsnelheidNormale toetsaanslagenEV_KEY (1)
SnelReal-time controlEV_ABS (3) + custom code
Ultra-snelDirecte interruptEV_MSC (4) + eigen code
CustomEigen taalEigen event type + code
// Custom event = eigen frequentie
// EV_MSC (Miscellaneous) — voor eigen data

const EV_MSC = 0x04;
const MSC_CUSTOM = 0x100; // eigen code

// Payload = onbeperkt in value veld
const event = Buffer.alloc(24);
event.writeUInt16LE(EV_MSC, 16);
event.writeUInt16LE(MSC_CUSTOM, 18);
event.writeUInt32LE(payload, 20);
fs.writeSync(fd, event);
// → Direct naar kernel → epoll → 0ms

• Veiligheidslagen

Vrije events = vrijheid in de stroom. Maar vrijheid zonder authenticatie = kwetsbaar.

LaagVerdedigingStatus
Whitelistslots.json — alleen bekende slotsactief
Device-naamFilter op /sys/class/input/eventX/device/namespoofbaar
Event signatuurHMAC op event payloadte bouwen
Hardware-boundSleutel gebonden aan fysiek devicetheoretisch
Rate limitMax events per secondete bouwen

Rubber Ducky Scenario

USB stick → /dev/input/event22 → "USB Keyboard"
→ stuurt SYN + EV_KEY sequentie
→ evdev-reader leest events
→ slot-router matcht → commando uitgevoerd

Verdediging: slots.json whitelist
→ Ongekende events → genegeerd
→ Bekende slot → kan geïmitieerd worden

• Live Status

evdev-reader actief polling: ~1ms delay
ComponentStatusDelay
evdev-readerpolling~1-10ms
slot-routerstreaming~0ms
payload-executorstreaming~0ms
libuv streamniet actief