← Journal technique
Ferry·distribué & temps réel·2026-09-06

Trois bugs qu'un réseau simulé ne pouvait pas voir

The first real two-daemon run found an mDNS advert with no A-record: discovery reported success while the peer resolved to a .local name with zero addresses.

Le filet avait un trou

Le test, le journal d'audit, le scanner, la CI — couvrant moins que je ne le supposais.

Le harnais en mémoire à deux nœuds était vert depuis des semaines quand la première vraie exécution à deux démons a eu lieu. Cette exécution a trouvé trois bugs d'un coup, tous le même jour :

L'annonce mDNS n'avait pas d'enregistrement A. discovery_ok=true des deux côtés, les deux annonçaient, mais un pair qui parcourait résolvait l'autre vers un nom d'hôte .local avec zéro adresse — donc TcpStream::connect n'avait rien à quoi se connecter. Corrigé avec enable_addr_auto() sur les infos du service, plus l'essai de chaque IP résolue avant de retomber sur le nom d'hôte.

Un élément mis en file vers un pair déjà connu restait simplement là. mdns-sd ne réémet pas ServiceResolved pour un service inchangé, donc le redéclenchement ponctuel à la première résolution ne se déclenchait plus jamais. Corrigé avec une revérification périodique de 5s pour tout pair connu ayant du travail en attente dans l'outbox.

Le canal IPC réutilisait la limite de trame de 64 Kio du câble P2P pour une réponse Open de fichier entier. Correct pour un chunk, faux pour une charge utile — tout ce qui dépassait ~48 Kio échouait avec « frame length exceeds maximum ». Corrigé avec une limite IPC séparée de 64 Mio, en laissant intacte la limite de 64 Kio du câble P2P.

Aucun de ces bugs n'est un bug de machine à états — la machine à états était correcte. Ce sont tous des bugs dans la frontière que le mock remplace : vraie résolution DNS, vrai timing de livraison d'événements, vraies tailles de trame. Un harnais qui simule le réseau vous dira que la logique est correcte et rien sur si la logique arrive un jour à s'exécuter.