01 · Problem
Wofür braucht man das?
Peers müssen sich finden, eine stabile Identität aushandeln, Nachrichten begrenzen und Vertraulichkeit sowie Authentizität über eine Session sicherstellen.
02 · Denkmodell
Das mentale Modell
Discovery verrät nur eine Adresse. Ein Handshake bestätigt Identität und Fähigkeiten; danach transportieren längengerahmte, sequenzierte Nachrichten über eine etablierte sichere Session.
P2P soll mDNS, TCP und RSA verbinden, kompiliert aber nicht. Signaturen werden nicht übertragen, Framing fehlt, Peer-IDs sind inkonsistent und das selbstgebaute Kryptoprotokoll ist unvollständig.
03 · Kontrollfluss
Was passiert in welcher Reihenfolge?
- Per mDNS nur nodeId, Host, Port und öffentlichen Fingerprint ankündigen.
- Transport verbinden und Peer über TLS oder ein geprüftes Handshake-Protokoll authentifizieren.
- Stabile Node-IDs und Protokollversionen austauschen; Self- und Duplicate-Verbindungen ablehnen.
- Nachrichten mit Länge, Typ und Sequenz framen und harte Maximalgrößen erzwingen.
- Backpressure, Heartbeat, Reconnect und vollständigen Shutdown implementieren.
04 · Bauteile
Die entscheidenden Verträge
P2P
Beabsichtigter Coordinator für Server, mDNS-Discovery und Peer-Lifecycle.
Peer
EventEmitter um einen TCP-Socket mit send und Datenverarbeitung.
KeyPairEncryption
Soll RSA signieren und verschlüsseln, ist aber unvollständig und nicht importfähig.
PeerInfo
Adress- und Identitätsdaten eines entdeckten Peers.
05 · Build it yourself
Selbst implementieren
Baue kein eigenes Kryptoprotokoll. Beginne mit klarem Framing und verwende eine etablierte sichere Transportschicht.
- Trenne Discovery, Transport, Session und Peer-Registry in eigene Ports.
- Nutze TLS oder Noise und binde den erwarteten Fingerprint an einen Trust Store.
- Erzwinge Frame-Limits, Sequenzen, Timeouts und idempotenten Lifecycle.
type Frame = { type: number; sequence: number; payload: Uint8Array };
function encodeFrame(frame: Frame) {
const body = encodeBody(frame);
if (body.length > 1_048_576) throw new RangeError("Frame too large");
const output = new Uint8Array(4 + body.length);
new DataView(output.buffer).setUint32(0, body.length);
output.set(body, 4);
return output;
}
function acceptSequence(last: number, next: number) {
if (next !== last + 1) throw new Error("Invalid sequence");
}06 · Verifizieren
Was du testen solltest
- TCP-Chunks mit halbem, genau einem und mehreren Frames werden korrekt reassembliert.
- Zu große Frames, Replay-Sequenzen und falsche Peer-Fingerprints werden vor Payload-Verarbeitung abgelehnt.
- Disconnect, Timeout und destroy räumen Server, Sockets, Timer und Discovery vollständig auf.
07 · Grenzen
Kompromisse und Stolperfallen
- mDNS entdeckt nur Peers im lokalen Netz; Internet-P2P braucht Rendezvous, NAT-Traversal oder Relay.
- Direct RSA encryption eignet sich nicht für beliebige Payloads; Sessions verwenden symmetrische AEAD-Keys.
- Discovery-Metadaten sind ohne nachfolgenden Trust-Check nicht vertrauenswürdig.
Kryptografie, Framing und Lifecycle sind Sicherheitsgrenzen. Der aktuelle Source ist eine unvollständige Idee und darf nicht als sicheres Protokoll eingesetzt werden.
08 · Weiterdenken