urMQTT op een echte ARM64-VPS: geen scherm, geen hardwarematige generator voor willekeurige getallen en een handshake die te traag was
Wat er gebeurde na de tekst over v0.3.0: de eerste run op een echte aarch64-KVM-server (installatie op de schijf, een stroomuitval, schijfcijfers), een diagnose-item dat via het netwerk rapporteert omdat de console onzichtbaar is, wat het vond over de generator voor willekeurige getallen, een P-256-assembly voor ARM64 waardoor volledige handshakes ongeveer 1,5 keer vaker konden, en de fouten die we onderweg maakten.

De vorige tekst, urMQTT v0.3.0, eindigde met vier punten onder "Wat volgt": een besluit over de publieke demobroker (D1), fuzzing van de PCI- en virtio-parsers en een test voor de vergrendelde paginatabellen, een sleuteldialoog op de builderpagina, en bare metal. Geen van de vier is in deze ronde gedaan, en dat zeggen we eerst. Wat we in plaats daarvan deden, is wat al die tijd ontbrak: we draaiden urMQTT op een echte ARM64-server onder KVM, en bijna alles hieronder komt van die ene machine. Het eerste punt van de oude lijst, de CI, is opgeruimd (de eerdere tekst en de release notes die hem rood noemden zijn gecorrigeerd).
De kanttekening vooraf blijft dezelfde: het project is pre-alpha, de cijfers meten code, tests en bepaalde experimenten op één machine, niet rijpheid in productie. Waar een cijfer niet op de doelmachine is gemeten, staat dat erbij.
Hoe het eruitzag in de tijd
Sinds de vorige tekst (3 november, 02:43) tot vandaag (4 november, 03:18) telt main 29 nieuwe commits, 244 in totaal. Zoals eerder wordt het project gebouwd met Claude Code (de commits dragen Co-Authored-By: Claude). De cijfers zijn berekend met de methode van de vorige twee teksten (alle .rs-bestanden buiten vendor/ en fuzz/, #[test]-functies, ## ADR--koppen in docs/DECISIONS.md); op de oude commit geeft de methode dezelfde cijfers als toen.
| Moment | Commit | Tijd | Regels Rust | Tests | ADR's | Commits |
|---|---|---|---|---|---|---|
| vorige tekst | f1a7fbc | 3 november, 02:43 | 115.148 | 962 | 133 | 215 |
| vandaag | efddf6e | 4 november, 03:18 | 117.084 | 978 | 134 | 244 |
Groei: +1.936 regels, +16 tests, +1 ADR. Opnieuw weinig nieuwe code; de P-256-assembly zelf (1.509 regels) is vendored en zit niet in het aantal regels.
Een tweede echte machine
Tot nu toe had het project één echte server: een Contabo-VPS met een AMD EPYC (x86_64, KVM), gebruikt voor de prestatievergelijking met Mosquitto. ARM64 draaide alleen in QEMU, met hardwareversnelling op een Mac en zonder in de CI. De nieuwe machine is een netcup VPS 500 ARM G12.5: een Neoverse N1-kern op ongeveer 3 GHz, 2 vCPU's, 3,9 GiB RAM, een virtio-schijf van 64 GiB, QEMU/KVM met UEFI-firmware, een virtio-netwerkkaart. Alles werd aangestuurd via de REST-API van de aanbieder met een opdrachtregelclient: we uploaden de ISO, koppelen die als virtuele cd, wisselen het opstartapparaat en schakelen de stroom uit en weer in.
Wat we erop deden, in volgorde:
- Eerst een snapshot van het oorspronkelijke systeem. Een online snapshot kan niet met UEFI, dus de server werd uitgezet en er werd een offline snapshot gemaakt.
- Installatie. Het installatieprogramma van de ISO schreef het image naar de schijf (inclusief het aftellen van 30 seconden, samen ongeveer 40 seconden) en zette de machine zelf uit, zoals bedoeld.
- Opstarten vanaf de geïnstalleerde schijf duurde ongeveer 35 seconden tot een TLS-handshake.
- Een retained bericht overleefde een harde stroomuitval. We publiceerden het, schakelden de stroom uit via de API, startten opnieuw op en lazen het terug.
- De geïnstalleerde schijf, gemeten door het diagnose-item (alleen lezen; de schrijftest is overgeslagen omdat de geïnstalleerde indeling geen niet-toegewezen ruimte overlaat, wat de bedoeling is): sequentieel lezen 332 MiB/s, willekeurige leesacties van 4 KiB 22.147 per seconde met p50 10,4 µs, p90 28,3 µs, p99 671 µs, maximum 9,9 ms (2.000 leesacties).
Vijf punten zijn geen testsuite: dit is één machine, van elk één run, en het installatiepad is één keer op de echte schijf doorlopen. Wat het wel laat zien, is dat het eigen virtio-blk-stuurprogramma van de kernel, het installatieprogramma en het opstarten werken op een echte cloudgast en niet alleen in een laboratoriumemulator.
Geen scherm, dus de diagnose gaat via het netwerk
Het diagnose-item uit v0.3.0 tekent zijn cijfers op de framebuffer. Op deze server meldt de console van de aanbieder "Display output is not active": de virtuele machine heeft een virtio-grafische kaart waarvoor we geen stuurprogramma hebben, en de seriële poort is niet beschikbaar. De cijfers bestonden en niemand kon ze lezen.
De oplossing is een bootwoord, diag-serve: de machine voert dezelfde metingen uit, start dan als gewone live broker en publiceert het rapport als één JSON-document in het retained bericht $SYS/diag/report, dat alleen een operatorcertificaat mag lezen. Een klein hulpprogramma, urmqtt-diag-png, tekent het dashboard uit die JSON met dezelfde code die de kernel op het scherm gebruikt (dezelfde indeling en hetzelfde 8x8-lettertype), dus de afbeelding is het scherm dat de machine zou hebben getoond:

Onderweg zijn twee dingen aan het scherm toegevoegd, omdat we ze misten: de CPU-klok (de PMU-cyclusteller tegen de tijdbasis: hier 2,95 tot 2,98 GHz; waar alleen een timer met vaste frequentie leesbaar is, staat er "niet meetbaar" in plaats van de frequentie van de timer als die van de CPU) en een paneel voor de generator voor willekeurige getallen.
Waaruit de generator voor willekeurige getallen bestaat
Het paneel zegt waar de generator vandaan is geïnitialiseerd en test verse bytes van elke hardwarebron. Op deze machine staat er:
- virtio-rng: geen apparaat.
RNDR(de eigen instructie van de CPU): niet beschikbaar op deze CPU. - De EFI-generator voor willekeurige getallen van de bootloader: 8 van 8 waarden niet nul.
- De terugvaloptie op basis van timingjitter van de CPU (ADR-038): 1.024 samples van 64 stappen via de PMU-cyclusteller, 3 bits per sample geschat, 768 bits gecrediteerd (een kwart van de schatting, zo bedoeld), gezondheidstests geslaagd.
- De uitvoer van de generator, een redelijkheidstest over 4.096 byte: 49,6 % enen, de langste reeks 16 bits. Dat is een controle dat niets vastzit of scheef is, geen statistische certificering.
De generator op deze server rust dus op de jitter-terugval en op wat de firmware aanleverde. Dat is precies wat ADR-038 beschrijft, en het is de zwakste initialisatie die de kernel accepteert. We noemen haar niet kapot: de gecrediteerde bits liggen boven de drempel die de kernel eist (256), en de schatter is conservatief. We kunnen ook niet bewijzen dat ze even goed is als een hardwarebron. Of een productie-image moet weigeren te starten zonder hardwarebron tenzij de operator daarvoor kiest, is een open vraag voor de eigenaar (hij staat in de roadmap, hieronder). In de praktijk is het ook een vraag voor de aanbieder: een hardwarematig apparaat voor willekeurige getallen voor de virtuele machine zou het beslissen.
Een handshake die te traag was
Het diagnose-item liet ook zien wat een volledige wederzijdse TLS-handshake op de server kost: 1,08 ms. Bijna alles daarvan is rekenwerk met publieke sleutels: twee ECDSA P-256-verificaties (het clientcertificaat en het bewijs van de client), elk ongeveer 508 µs, X25519 176 µs, één ECDSA-handtekening 141 µs. Op x86_64 hadden we dit eerder opgelost (ADR-130, de OpenSSL/Intel-assembly: P-256 drie tot vier keer sneller); op ARM64 draaide nog de draagbare RustCrypto-code.
Hetzelfde deden we voor ARM64 (ADR-255). De assembly is de ARMv8-nistz256 van OpenSSL (Apache-2.0), overgenomen uit ring 0.17.14 en vendored, met de herkomst en elke mechanische wijziging opgeschreven. Wat er in de details toe deed:
- Alleen gehele getallen. De assembly gebruikt geen NEON-registers. De twee functies voor tabelselectie die upstream wel met NEON doet, hebben we weggelaten en vervangen door constant-time gemaskeerde scans in Rust (ze kosten hoogstens 1,4 µs van een handtekening van 12 µs).
- Branchbescherming. De kernel wordt gecompileerd met BTI en pointerauthenticatie. Elk van de 8 geëxporteerde ingangspunten heeft een landingspad, gecontroleerd in de disassemblage van de kernel, en de zes die het linkregister opslaan, ondertekenen het.
- Tests, want dit is cryptografie in de vertrouwde basis. De hele x86_64-suite draait nu ook op aarch64 Linux: veld- en scalarrekenkunde tegen een schoolboekreferentie, de hele generatortabel (2.368 items) tegen RustCrypto, handtekeningen bit voor bit gelijk aan die van RustCrypto, verificatieuitkomsten, ECDH met invoer buiten de kromme en nul, en de known-answer-tests die bij elke boot door de productiepaden lopen. In een virtuele machine met vier kernen onder een interruptstorm draaiden 59.526 known-answer-rondes zonder verschil (0 mismatches).
- Een timingtest met een controle, en een signaal dat onze eigen test was. Een opzettelijk lekkende vermenigvuldiging scoort |t| van 482 tot 1755, dus de test kan een lek op deze schaal zien. Op een Apple-kern in een container scoorde ECDH 0,2 tot 2,1, ondertekenen 0,5 tot 1,9, sleutelgeneratie 0,8 tot 5,5. Op de arm64-serverkern van de CI-runner scoorde ECDSA-ondertekenen |t| = 8,6, 9,1 en 8,3 in drie pogingen, boven onze grens van 7, terwijl ECDH (3,9) en sleutelgeneratie (1,9) op dezelfde machine slaagden. Een resultaat dat zich herhaalt is geen ruis, dus hebben we het vastgelegd als openstaande bevinding (A255-W1) en de grens voor dat ene geval een paar uur verhoogd naar 12, zodat de build kon slagen. Daarna vonden we de oorzaak, en die lag in de testopzet: het geval ondertekende één vast bericht, waardoor de ijle sleutel elke keer dezelfde handtekening gaf en de willekeurige sleutels elke keer een andere, en het DER-coderen van een herhaalde handtekening is sneller (|t| = 49 tot 57 voor de codering alleen). Met een willekeurig bericht per meting in beide klassen scoort het geval op de runner (een virtuele machine met Neoverse N2) 1,4 en 1,8, de nonce-generatie alleen 2,7 en 1,1, en de grens staat weer op 7. Eén ding blijft open (A255-W2): de processorvlag die de timing van de vermenigvuldiger gegevensonafhankelijk maakt op Arm-kernen (DIT) wordt nergens gezet, niet door de kernel en niet rond de aanroepen aan de hostkant. Geen enkele meting toont een verschil, maar de virtuele machine van de runner stelt de functie niet beschikbaar, dus de test kon het ook niet laten zien.
Wat het opleverde
Eerst de microbenchmark op de machine waar we het ontwikkelden, een Apple M4 Pro (niet de doel-CPU, dus de verhoudingen op de server kunnen afwijken), dezelfde code die de handshake aanroept, voor en na:
| Bewerking | voor (µs) | na (µs) | verhouding |
|---|---|---|---|
| sleutelgeneratie | 30,8 | 7,0 | 4,4x |
| ECDH P-256 | 135,2 | 25,0 | 5,4x |
| ECDSA-handtekening | 34,7 | 11,6 | 3,0x |
| ECDSA-verificatie (onbekende sleutel) | 147,4 | 29,1 | 5,1x |
| CA-verificatie (geregistreerde uitgever) | 54,2 | 9,6 | 5,6x |
| X25519 (ongewijzigde code) | 20,4 | 20,1 | 1,0x |
| schatting handshake (som van het bovenstaande) | 292 | 104 | 2,8x |
Dan het echte werk: dezelfde belastinggenerator, dezelfde methode als in de eerdere prestatietekst (volledige TLS 1.3-handshake met clientcertificaat, zonder hervatting, MQTT CONNECT, de server sluit als eerste), gedraaid vanaf een machine op 9 ms van de server, tegen dezelfde netcup-VPS, voor en na de wijziging. Het benchmark-image heeft de handshakelimieten versoepeld, zoals in de x86_64-vergelijking; drie herhalingen, het cijfer is de mediaan.
| Threads | voor (verb./s) | na (verb./s) | verhouding | fouten |
|---|---|---|---|---|
| 32 | 848 (408-855) | 1.317 (957-1.317) | 1,55x | 0 |
| 64 | 827 (815-839) | 1.398 (1.352-1.416) | 1,69x | 0 |
| 128 | 778 (714-788) | 1.316 (1.313-1.383) | 1,69x | 0 |
| TLS-deel van een verbinding, p50, 32 threads | 18,5 ms | 13 ms |
Volledige handshakes per seconde namen toe met ongeveer 1,55 tot 1,7 keer, niet met de factor drie die het rekenwerk alleen zou geven. De reden is eenvoudig en het waard om te zeggen: we hebben P-256 versneld, en X25519 (176 µs), de TCP/IP-stack, de recordlaag en MQTT zijn ongewijzigd, zodat het resterende deel zwaarder gaat wegen (de wet van Amdahl). De volgende kandidaat is X25519.
Ter oriëntatie naast de x86_64-server uit de eerdere tekst. Dit is niet vergelijkbaar als een race: verschillende CPU's, een verschillend aantal kernen (4 tegen 2), een verschillende afstand tot de generator (15 ms tegen 9 ms) en in beide gevallen een gedeelde belastinghost die tijdens de runs 5 tot 60 % van zijn eigen CPU kwijtraakte. De vergelijkbare kolom is de eigen CPU-last van de server per handshake:
| Contabo, x86_64 EPYC (asm) | netcup, ARM64 N1 voor | netcup, ARM64 N1 na | |
|---|---|---|---|
| CPU van de server per handshake | 0,26 ms (de console van de broker) | 1,08 ms (diagnose) | 0,55 ms (diagnose, één run, zie hieronder) |
| handshakes/s, 32 threads | 169 (bench) | 848 | 1.317 |
| handshakes/s, 64 threads | 278 (bench) | 827 | 1.398 |
| handshakes/s, 128 threads | 413 (bench) | 778 | 1.316 |
Dezelfde dag draaide het diagnose-item opnieuw op deze machine, met de assembly (in een build die ook het grafische stuurprogramma bevat dat in de update aan het eind wordt beschreven): de CPU-kosten van de server voor één wederzijdse TLS-handshake waren 553 µs tegen 1,08 ms ervoor, 1,95 keer minder. ECDSA-verificatie kostte 192 µs (ervoor 508 µs), ondertekenen 78 µs (141 µs) en X25519 209 µs (176 µs; die code is ongewijzigd, en de CPU-klok van deze run was 2,58 GHz tegen 2,95 tot 2,98 GHz in de eerdere, dus losse cijfers op deze gedeelde machine schommelen met tientallen procenten). Het is één run, op een gedeelde host. Dat de handshakefrequentie 1,55 tot 1,7 keer steeg terwijl de eigen kosten van de server per handshake 1,95 keer daalden, past bij elkaar: de rest van een verbinding is de stack, de generator en het netwerk. De ruis tussen runs is zichtbaar in de ruwe bestanden: elke reeks van drie heeft één uitschieter (408 voor en 957 na bij 32 threads), toen de belastinghost het grootste deel van zijn CPU aan andere virtuele machines kwijtraakte. Bij 128 threads zit op beide machines de generator, niet de server, aan zijn limiet.
De rest van de suite op deze machine
Dezelfde suite als voor de x86_64-server (doorvoer, latentie, fan-out, inactieve verbindingen) draaide volledig tegen de nieuwe build. Er is geen "voor" voor deze rijen: de run werd gestopt om de assembly te bouwen, dus dit is de toestand na de wijziging, en de assembly raakt deze paden niet, behalve de handshakes die de verbindingen openen. Eén feit verklaart het meeste van wat volgt: deze virtuele machine heeft twee vCPU's. Kern 0 doet de netwerkkaart, het verdelen en al het MQTT- en TLS-werk, kern 1 is de databasekern en was de hele tijd 2 tot 3 % bezig. De x86_64-server had vier vCPU's en twee werkkernen. Alles hieronder is dus prestatie van de broker op één kern.
| Inactieve verbindingen | 5.000 | 10.000 | 20.000 |
|---|---|---|---|
| verbonden | 5.000 van 5.000 in 4,3 s | 10.000 in 9,3 s | 20.000 in 21,2 s |
| groei van de kernelheap per verbinding | 0,34 KB | 0,41 KB | 0,43 KB |
| fouten | 0 | 0 | 0 |
(0,50 tot 0,66 KB per verbinding op de x86_64-server bij de H7-commit. Het heapcijfer is $SYS/broker/memory/used min de waarde vóór de eerste verbinding.)
| Latentie bij een bescheiden snelheid (8 paren x 100 berichten/s, 64 B) | p50 | p99 |
|---|---|---|
| QoS 0 | 4,0 ms | 6,9 ms |
| QoS 1 | 4,1 ms | 7,0 ms |
| Fan-out (1 publisher, 64 B) | afgeleverd per seconde | p50 | p99 |
|---|---|---|---|
| 100 abonnees, QoS 0, 50 ber./s | 5.000 (alle) | 5,9 ms | 8,6 ms |
| 100 abonnees, QoS 1, 50 ber./s | 5.000 (alle) | 6,3 ms | 10,0 ms |
| 1.000 abonnees, QoS 0, 10 ber./s | 8.805 van 10.000 | 207 ms | 5,4 s |
| Vloed, 16 paren, publishers zo snel als de broker aankan | gepubliceerd/s | afgeleverd/s | p50 / p99 | verbindingen verloren |
|---|---|---|---|---|
| QoS 0, 64 B | 231.317 | 85.140 | 1,36 s / 2,8 s | 0 |
| QoS 0, 1 KiB | 62.110 | 25.506 | 336 ms / 873 ms | 0 |
| QoS 1, 64 B | 107.349 | 55.965 | 21 ms / 29 ms | 0 |
| QoS 1, 1 KiB | 51.369 | 25.054 | 47 ms / 60 ms | 0 |
| QoS 1, 64 B, 64 paren | 130.462 | 69.411 | 69 ms / 87 ms | 0 |
Hoe het te lezen. De latentie bij een bescheiden snelheid is de bijdrage van de broker plus één reis naar de generator: de generator staat dichter bij deze server dan die in de x86_64-vergelijking, dus de twee latentiekolommen zijn niet vergelijkbaar. De QoS 0-vloed toont het gebruikelijke beeld van een overbelaste enkele kern: de broker accepteert 231.000 berichten per seconde en levert er 85.000 af (de rest wordt weggegooid door de backpressure-regels, daar zijn ze voor) met latenties in seconden, en er is geen verbinding verloren; op de x86_64-server kostte dezelfde soort vloed per run enkele verbindingen aan de watchdog van 20 ms (ADR-221 heeft sindsdien veranderd hoe dat budget wordt geteld). De rij met 1.000 abonnees heeft hetzelfde karakter als eerder, staarten in seconden, deels van de generator zelf. De cijfers bij de H7-commit op de x86_64-server staan in de eerdere tekst; we zetten ze niet in één tabel met deze, omdat de code tussen de twee metingen is veranderd in het datapad (ADR-221 tot en met ADR-224) en de machines in alles verschillen.
Fouten die we zelf vonden
- Het plaatje zei "geen schijven gevonden" en de schijf stond in het rapport. De eerste versie van
urmqtt-diag-pnglas het velddiskshelemaal niet. De eigenaar van het project keek naar de afbeelding, zei dat het er verkeerd uitzag, en had gelijk. Hersteld, en een test leest nu een schijf terug uit de JSON. - We verklaarden het installatieprogramma te vroeg klaar. De status van de server ging twee keer naar "uit": één keer aan het eind van de stroomcyclus en één keer toen het installatieprogramma klaar was. Ons script nam de eerste voor de tweede, koppelde de ISO los en startte het oude systeem, dat het oude versienummer meldde en ons een fout in het installatieprogramma liet zoeken die er niet was. Het script wacht nu eerst op een verse boot.
- Voortgangsgeschiedenis ging verloren. Een analyse voor de roadmap ontdekte dat de commit voor mijlpaal S6
docs/PROGRESS.md(1.763 regels, mijlpalen M0 tot en met S5) had vervangen door een eigen item van 26 regels. Het bleef dagenlang onopgemerkt, hoewel de README dit bestand "de bron van waarheid" noemt. Het is hersteld uit de geschiedenis. - De CI faalde na de assembly, op twee plekken. In drie smoke tests stond de grootte van het bootimage vastgelegd ("10 MiB"), die met de grotere kernel groeide naar 11 MiB; ze veronderstellen de grootte niet meer. De andere mislukking was de hierboven beschreven timingtest: de eerste keer leek het ruis op een gedeelde runner, dus lieten we de test drie keer herhalen; hij faalde in alle drie de pogingen, en zo leerden we dat het een signaal was, en het signaal bleek onze eigen test te zijn (hij ondertekende elke keer hetzelfde bericht). We hebben die ene grens een paar uur verhoogd, dat openlijk gezegd en hem weer verlaagd toen de oorzaak was verholpen.
- De documentatie telt drie bootwoorden en de code heeft er vier (
diag-serve), en de mijlpalentabel in de README toont het werk van de afgelopen week nog als gepland. Beide staan in de roadmap als te herstellen punten.
Een roadmap, met vragen
Voor het eerst is er een roadmap: ongeveer 40 punten in drie fasen (v0.4 verharding en beheer; protocol en netwerk; opschaling, meer clouds en bare metal), elk met een reden uit een document, een inspanning, een risico en een manier om het te verifiëren, 16 vragen die alleen de eigenaar kan beantwoorden, en een lijst van wat buiten het bereik valt. Een paar dingen zegt hij ronduit: alleen MQTT 3.1.1 wordt ondersteund, een QoS 2-publicatie sluit de verbinding, er is geen IPv6 (de aanbieder geeft een /64), geen WebSocket en geen uitgaande verbinding vanuit de broker, en er zijn geen stuurprogramma's voor de netwerk- en opslagapparaten van de grote clouds.
Wat nog niet is bewezen
- De CPU-kosten per handshake met de assembly zijn op de Neoverse-kern maar één keer gemeten (553 µs tegen 1,08 ms ervoor, bij een lagere klok, op een gedeelde host); de 1,55 tot 1,7 keer komt van de frequentie van volledige handshakes, en de 3 tot 5 keer van een Apple-kern. De x86_64-kant van de refactor (de code die naar een eigen bestand is verplaatst) is op types gecontroleerd en gebouwd, maar de unittests zijn niet gedraaid en de x86_64-kernel is er daarna niet mee gestart: de x86_64-suites zitten niet in de CI, ze worden met de hand op de Contabo VPS gedraaid, en dat is voor deze wijziging nog niet gedaan.
- Constante tijd: voor P-256-sleutelgeneratie, ECDH en ondertekenen (de sleutel en de nonce) vond de statistische test geen afhankelijkheid van een ijle geheime waarde. Hij draaide op een Apple-kern en op de CI-runner (een virtuele machine met Neoverse N2), niet op de Neoverse N1-kern bij netcup, en nooit met de DIT-vlag gezet op een serverkern (A255-W2, openstaand: de kernel zet hem niet). Hij draaide niet voor X25519 of Ed25519. Een blackboxtest begrenst alleen wat hij bij zijn steekproefgrootte kan onderscheiden.
- Eén server, één aanbieder, één installatie. Meerdere resultaten (installatie, een stroomuitval) zijn één run. Afgezien van de handshakes hebben de prestatierijen geen "voor", en een machine met twee vCPU's geeft de broker één datakern.
- De generator voor willekeurige getallen op deze server wordt geïnitialiseerd uit jitter en uit de firmware, zoals hierboven beschreven.
- De ondertekeningssleutel is nog steeds een testsleutel, de release-images zijn ontwikkelbuilds, en de vertalingen van deze tekst zijn door AI geschreven en niet door moedertaalsprekers gecontroleerd.
- Geen onafhankelijke audit, geen bare metal, geen IOMMU.
Wat volgt
- X25519 in assembly voor ARM64 (het is 176 µs van de resterende handshake), en de meting per handshake op de Neoverse-kern meer dan één keer herhalen.
- Een besluit over de standaardinstelling van de generator voor willekeurige getallen: weigeren te starten zonder hardwarebron tenzij de operator anders zegt, of de jitter-terugval houden en dat luid zeggen.
- De oude lijst: een besluit over D1, fuzzing van de PCI- en virtio-parsers, de sleuteldialoog op de builderpagina.
- Uit de roadmap, voor de volgende release: een echte ondertekeningssleutel en productie-PKI, MQTT 5.0 en QoS 2.
De code staat op github.com/zeljan-alduk/urMQTT; docs/PROGRESS.md blijft de bron van waarheid over wat werkt, docs/PERFORMANCE.md over wat is gemeten (sectie 10 heeft de cijfers van de assembly), docs/AUDIT.md over wat niet is bewezen. Pre-alpha, zoals eerder; foutmeldingen en beveiligingsmeldingen volgens de instructies in SECURITY.md zijn welkom.
Update, 4 november, later dezelfde dag. Vier dingen uit de uren nadat we deze tekst publiceerden.
- Het ontbrekende cijfer. Het diagnose-item draaide opnieuw op de netcup-server met de assembly en gaf het getal dat in de eerste tabel ontbreekt: 553 µs CPU van de server per wederzijdse TLS-handshake tegen 1,08 ms ervoor (details onder die tabel).
- Het signaal bij het ondertekenen was onze test. De oorzaak van het hierboven beschreven timingsignaal is gevonden en verholpen in de testopzet (die elke keer hetzelfde bericht ondertekende); de grens staat weer op 7. Open blijft dat de DIT-vlag nergens wordt gezet (A255-W2).
-
Het schermprobleem is opgelost, en het staat op
main. We hebben een stuurprogramma geschreven voor de virtio-grafische kaart (alleen 2D, ADR-256), geschakeld met een configuratiesleutel die in het image is ingebakken (console.virtio_gpu, standaardoff;autoenonvereisen configuratieformaat 5). Metontoont het tabblad Scherm van de provider het diagnosedashboard live op de netcup-server, hetzelfde beeld als hierboven, inclusief het laatste scherm met „press any key". Het fuzz-doelwit vond een echte bug in de eerste versie: een antwoord met weergave-informatie dat vier bytes korter was dan de specificatie werd als geldig geaccepteerd (A256-W1); een echt apparaat stuurt altijd het hele antwoord, dus de server werd niet geraakt, en de parser wijst het korte antwoord nu af. Wat we niet hebben geverifieerd: dat het donkere beeld echt kwam doordat de firmware de kaart reset bij de overdracht aan de kernel (waarschijnlijk, niet bevestigd), de wisselwerking met Secure Boot en x86_64 op een echte machine (het draaide alleen onder emulatie). Een bekende beperking (A256-W2): de instellingautokan een levende geëmuleerde framebuffer naast een virtio-kaart niet onderscheiden van een dode, dus in die ene configuratie kiest ze de virtio-kaart. Het stuurprogramma voegt een parser van de antwoorden van de hypervisor aan de kernel toe, en daarom staat het uit tenzij de configuratie erom vraagt. -
De release. Dit alles zit in v0.4.0, dezelfde avond gepubliceerd als pre-release (GitHub-release). De builderpagina op deze site biedt hem als eerste aan; hij vereist configuratieformaat 6, en de oudere sjablonen (v0.2.0 tot v0.3.0) weigeren de nieuwe sleutels met een melding die zegt dat je een nieuwere release moet gebruiken. De beperkingen van v0.3.0 blijven: de ondertekeningssleutel is nog steeds een testsleutel, en de images zijn ontwikkelbuilds met testcertificaten. CI op de release-commit was pas groen nadat één job opnieuw was gedraaid (een clienttest in een smoke-scenario liep één keer op een timeout en slaagde de tweede keer). Wat we op de gepubliceerde bestanden hebben gecontroleerd: de minisign-handtekening, de checksums, de buildattestaties van de kernel en van de SBOM, en het sjabloon met de nieuwe sleutels (v0.4.0 accepteert ze, v0.3.0 weigert ze). Het stuurprogramma voor de nieuwe virtio-apparaten (console, balloon, input, vsock) zit in de release, maar staat standaard uit en is niet op een echte server gedraaid.
Reacties
Reactieregels