FPAC 4.2 : routes ROSE dynamiques et sessions White Pages au repos

Spécification, version de travail du 13/10/2026. Projet en cours : le démon fpacrtd est à l'essai sur trois nœuds ; son code n'est pas encore publié. English version

1. But

Aujourd'hui, un nœud FPAC ne connaît que les routes écrites à la main dans fpac.routes. Un DNIC ou un nœud oublié dans ce fichier est injoignable, même si un voisin direct sait l'atteindre.

Le but est que chaque nœud apprenne de ses voisins directs ce qu'ils savent joindre, installe les routes qui lui manquent, et les retire quand elles ne sont plus valables. Le fichier fpac.routes garde le dernier mot.

2. Ce que le mécanisme fait, et ne fait pas

Il fait :

Il ne fait pas :

3. Architecture

Un nouveau démon, fpacrtd, lancé par myfpac.sh après les autres démons FPAC et arrêté avant eux, pour que ses routes soient retirées tant que fpad tourne encore.

Tout script local qui arrête AX.25 ou FPAC sans passer par myfpac.sh doit aussi arrêter fpacrtd, et en premier : le 11/10/2026, une relance d'AX.25 sur un nœud a laissé l'ancien démon en vie à côté du nouveau.

La même protection couvre les quatre autres démons depuis le 12/10/2026 : fpad, fpacwpd, fpacstat et fpacroute tiennent chacun un verrou sur /var/ax25/fpac/<nom>.lock et refusent de démarrer si une autre copie tourne. Ils contrôlent aussi leurs arguments avant toute action : -h ou -? affiche une aide courte, -V la version, et une option inconnue ou un argument isolé est une erreur. Jusque-là fpad et fpacroute ignoraient tout argument et démarraient : fpad -V, tapé sur un nœud en service pour lire sa version, a démarré un second fpad qui a vidé puis recréé les routes ROSE du nœud et écouté sur les mêmes adresses que le premier. Attention, fpacwpd -v reste le mode verbeux et démarre le démon.

Un fichier verrou qui ne peut pas être écrit (disque plein ou en lecture seule) est ouvert en lecture seule, ce qui suffit à tenir le verrou. S'il ne peut pas être ouvert du tout, le démon l'écrit au journal et démarre sans cette protection : un nœud qui ne remonte pas est pire qu'un verrou absent. Un démon compilé avant le verrou n'est pas vu par un nouveau ; la protection vaut une fois les nouveaux programmes en service.

Pourquoi un démon séparé et non fpacwpd : une version actuelle de fpacwpd ferme la session quand elle reçoit un type de message qu'elle ne connaît pas (wp_receive_pdu rend -1). Ajouter un message aux sessions White Pages casserait donc la synchronisation avec tout nœud non mis à jour. Un service séparé laisse les White Pages intactes.

L'indicatif de service est FPACRT, et non ROUTE : fpacroute, l'application de traceroute, écoute déjà sur ROUTE sur tous les nœuds FPAC (constaté au premier essai, le 08/10/2026).

Un nœud sans fpacrtd ne refuse PAS un appel vers FPACRT : son fpad le prend pour un appel d'utilisateur, inscrit l'appelant dans les White Pages et tente une connexion AX.25 vers une station nommée FPACRT. Un voisin n'est donc appelé que si son bloc Node porte Route = yes (voir 10).

4. Ce qui est annoncé

Deux sortes de destinations seulement :

Sorte Masque Exemple
Adresse de nœud 10 2080 175526
DNIC entier 4 5050

Les préfixes intermédiaires (masques 5 à 9, par exemple 2080 44) ne sont ni annoncés ni appris. C'est avec eux que les boucles sont apparues ; ils restent du ressort de fpac.routes.

Origine d'une annonce :

Tout le reste est du relais : un nœud réannonce une destination apprise au coût reçu plus 1, et rien d'autre. Une route de fpac.routes ne donne jamais lieu à une annonce par elle-même : une ligne fausse ou périmée reste donc sans effet hors du nœud.

Un nœud ne relaie que ce que son propre RouteLearn lui fait retenir : avec RouteLearn = no il ne relaie rien, et avec RouteLearn = nodes il ne relaie aucun DNIC.

Un nœud qui déclare RouteOrigin = 5050 doit avoir lui-même une route vers ce DNIC dans fpac.routes. Sinon, fpacrtd le signale dans le journal et n'annonce pas ce DNIC.

Le DNIC n'est annoncé que tant que son lien de sortie est ouvert, c'est-à-dire tant qu'un voisin de cette route est « ouvert » dans rose_neigh. Quand le lien se ferme le DNIC est retiré (W), puis annoncé de nouveau quand il se rouvre ; l'état est contrôlé chaque minute et chaque changement est écrit au journal. Le lien avec le voisin à qui l'annonce est destinée ne compte pas : un DNIC n'est jamais annoncé à un nœud sur la foi du lien avec ce même nœud.

5. Échanges

Le dialogue est en texte, une ligne par message, pour rester lisible avec listen.

Message Sens
FPACRT 1 <appel> ouverture : version, indicatif L3
R <adr> <m> <c> route : adresse, masque, coût
W <adr> <m> retrait de cette route
E <n> fin de table, n routes envoyées

Rythme :

6. Règles de réception

Pour chaque route reçue d'un voisin V, de coût c :

  1. coût retenu = c + 1 ; au-delà de 6, la route est ignorée ;
  2. si la destination est l'une des adresses du nœud : ignorée ;
  3. si fpac.routes contient déjà cette adresse avec ce masque : la route n'est pas installée, la route manuelle reste en place ; la destination est quand même relayée aux autres voisins ;
  4. si V n'est pas « ouvert » dans rose_neigh : pas installée ;
  5. sinon, elle est installée si aucune route apprise n'existe pour cette destination, ou si son coût est strictement meilleur.

Une route que RouteLearn n'admet pas n'est pas retenue du tout : elle n'est ni installée ni relayée (voir 4).

Une seule route apprise par destination : la meilleure. Pas de voisin de secours en version 1.

7. Règles d'émission

8. Durée de vie

Une route apprise est retirée du noyau quand :

Au démarrage, fpacrtd retire d'abord les routes restées de sa dernière exécution, d'après fpacrt.dat. Chaque minute, il contrôle aussi que ses routes sont toujours dans le noyau et remet celles qui auraient disparu.

Un voisin qui se tait est traité lui aussi : quand un nœud détient des routes apprises d'un voisin et n'a reçu de lui aucune table complète depuis 90 minutes, il ferme le circuit. Les routes apprises de ce voisin sont retirées, et il est rappelé 30 minutes plus tard. Un voisin qui n'a jamais rien annoncé (RouteAnnounce = no) se tait par construction et n'est pas concerné.

9. Routes manuelles et routes apprises

10. Configuration

Dans fpac.conf et fpac.nodes, quatre réglages, tous inactifs par défaut :

Mot-clé Valeurs Effet
RouteAnnounce no, yes envoie sa table
RouteLearn no, nodes, n'apprend rien, apprend
all les nœuds, ou nœuds et
DNIC
RouteOrigin un DNIC par ligne porte de sortie du DNIC
Route yes, dans un ce voisin participe
bloc Node

Sans ces lignes, un nœud en 4.2 se comporte comme en 4.1. Un voisin sans Route = yes n'est jamais appelé, et ses appels sont refusés.

Exemple pour f6bvp-8, qui a les liens réels vers l'étranger :

RouteAnnounce = yes
RouteLearn    = all
RouteOrigin   = 2020
RouteOrigin   = 2400
RouteOrigin   = 3020
RouteOrigin   = 3100
RouteOrigin   = 5050

et, dans fpac.nodes, une ligne de plus dans le bloc de chaque voisin qui fait tourner fpacrtd (ici f6bvp-12). Sans elle, rien n'est échangé :

Node = F6BVP-13
 ...
 Route = yes
End

11. Affichage

Prévu, pas encore codé. La commande Routes de fpacnode marquera les routes apprises (dyn), et une commande routes dyn listera les seules routes apprises, avec le voisin qui les annonce.

Aujourd'hui, les routes apprises se lisent dans le journal de fpacrtd (lignes « add route » et « del route ») et dans fpacrt.dat.

12. Compatibilité

13. Plan d'essai

  1. Paire f6bvp-12 / f6bvp-8 (f6bvp-8 est le nœud le plus connecté) : f6bvp-8 en RouteAnnounce = yes avec ses RouteOrigin, f6bvp-12 en RouteLearn = all. Retirer d'abord de fpac.routes de f6bvp-12 un DNIC lointain, par exemple 5050 : il doit revenir seul. Vérifier aussi le retrait à la fermeture du voisin et la purge au redémarrage.
  2. Activer l'annonce dans les deux sens sur la paire, puis ajouter f6bvp-10 en RouteLearn = all : il doit recevoir 5050, qui lui manque aujourd'hui.
  3. Essai de boucle provoquée : couper le lien de sortie d'un DNIC et vérifier que la route disparaît partout en moins de 2 minutes, sans trame qui tourne (rose-controle.py).
  4. Une semaine d'observation avant d'étendre aux autres nœuds.

État au 12/10/2026 : l'étape 1 est passée le 08/10/2026, y compris le retrait à l'arrêt du démon du voisin et la purge au redémarrage. Depuis le 09/10/2026, trois nœuds participent : f6bvp-8 annonce, f6bvp-12 et f6bvp-10 apprennent, chacun directement de f6bvp-8. Après chacun des quatre redémarrages nocturnes de FPAC, les sessions et les routes apprises sont revenues seules en moins de 50 secondes, et la table de 6 routes est reçue toutes les 30 minutes sans manque. L'annonce dans les deux sens (étape 2) n'est pas encore activée. Pas encore éprouvés en réel : le vieillissement, la règle des 90 minutes, le relais par un troisième nœud et un appel réel par une route apprise.

Les démons munis du verrou d'instance unique (voir 3) sont en service sur sept nœuds depuis le 12/10/2026, compilés à partir des sources de la 4.1.6-rc7 et de ce seul changement. Sur chaque nœud les verrous sont tenus et un second lancement de chaque démon est refusé.

14. Décisions prises et points ouverts

Décidé (F6BVP, 08/10/2026) :

Encore ouvert :

Décidé (F6BVP, 13/10/2026) :

15. Numérotation

Cette nouveauté ajoute un démon, un protocole entre nœuds et des mots-clés de configuration : elle justifie FPAC 4.2. Ordre proposé :

  1. sortir la 4.1.6 stable avec les correctifs de la rc7 ;
  2. ouvrir la 4.2-rc1 avec fpacrtd et WpIdle (voir 16), tous deux inactifs par défaut, le changement des vecteurs (voir 17) et la commande QSl (voir 18).

Le code à l'essai est public : branche fpac-4.2 de https://github.com/f6bvp/fpac. Il est expérimental, ce n'est pas une version publiée.

16. Second chantier : sessions White Pages fermées au repos

Décidé par F6BVP le 08/10/2026. Rien n'est encore codé.

Aujourd'hui, fpacwpd garde ouvert en permanence un circuit ROSE avec chaque voisin (de WP-0 à WP-0), alors qu'il ne transporte qu'une fiche de temps en temps et un échange de vecteurs par heure.

Nouveau mot-clé dans fpac.conf :

Mot-clé Valeur Effet
WpIdle minutes, 0 = jamais ferme une session WP au repos

Sans ce mot-clé, ou avec 0, rien ne change : la session reste ouverte comme en 4.1. Valeur recommandée : WpIdle = 10.

Comportement avec WpIdle = 10 :

Ce que le code demande :

Avec un voisin resté en 4.1, qui rouvre sa session toutes les 30 minutes et la garde, le circuit est refermé 10 minutes plus tard. C'est sans gravité, mais cela se voit dans les journaux.

Le noyau sait fermer seul un circuit ROSE au repos (option de socket ROSE_IDLE). Une fermeture décidée par fpacwpd est préférée, parce qu'il sait si un échange est en cours ; à trancher au moment du code.

Essai : sur une paire, vérifier qu'une session au repos se ferme, qu'une fiche modifiée par wpedit la rouvre et arrive chez le voisin, et que l'échange horaire de vecteurs a toujours lieu.

17. Troisième chantier : fiches supprimées obsolètes sorties des vecteurs

Constaté le 11/10/2026. Deux nœuds écrivaient Vectors still differ chaque heure alors qu'ils avaient la même version.

Une fiche supprimée de plus de 14 jours (WP_OBSOLETE) n'est ni envoyée ni acceptée entre nœuds, et une fiche supprimée d'un indicatif inconnu est refusée. Ces fiches comptent pourtant dans les vecteurs, dont la somme de contrôle couvre la date et l'adresse de chaque fiche. Quand deux nœuds marquent une fiche supprimée, ou l'effacent, à des jours différents, leurs vecteurs diffèrent et l'échange ne peut pas le réparer : les fiches qui régleraient l'écart sont justement celles qui ne s'échangent pas. Cela dure jusqu'à ce que les deux nœuds les aient effacées.

Ici, un nœud lançait chaque nuit wpmaint -d 100 quand les autres lançaient wpmaint -d 30 : il gardait 12 fiches supprimées que les autres avaient effacées, et deux fiches encore valides, supprimées ailleurs.

Décidé (F6BVP, 11/10/2026) : sortir de la somme de contrôle des vecteurs les fiches supprimées trop anciennes pour être échangées. Codé le 13/10/2026, pas encore en service.

Un nœud modifié et un nœud non modifié calculent des vecteurs différents et divergeraient sans fin. Décidé (F6BVP, 13/10/2026) : le numéro de version des vecteurs change avec la nouvelle somme de contrôle ; c'est son rôle.

fpacwpd jusqu'à la 4.1.6 ferme la session White Pages quand il reçoit un vecteur d'une autre version, et rappelle 30 minutes plus tard. Sans rien de plus, un nœud 4.2 et un nœud 4.1.6 ne garderaient plus de session. Décidé (F6BVP, 13/10/2026) : la 4.2 continue de parler l'ancienne version, avec l'ancienne somme de contrôle, à un voisin resté plus ancien ; la nouvelle version ne sert qu'entre nœuds 4.2. Un réseau peut ainsi être mis à jour nœud par nœud.

Tel que codé le 13/10/2026 : la nouvelle version des vecteurs est 0x112, l'ancienne 0x111. Un nœud répond à une demande de vecteur dans la version où elle est arrivée. Pour ses propres demandes, il prend d'abord chaque voisin pour un nœud 4.2 ; si le voisin raccroche avant de répondre, il lui parle ensuite dans l'ancienne version, avec une ligne au journal. Un vecteur en nouvelle version reçu de ce voisin prouve qu'il a été mis à jour. Comme une session peut aussi tomber pour une autre raison à ce moment précis, la nouvelle version est réessayée une fois par semaine. Le prix avec un voisin 4.1 : une session fermée au premier échange, puis une fois par semaine ; elle se rouvre dans les 30 minutes.

Non couvert : une fiche supprimée récemment, que l'autre nœud n'a jamais connue, y est refusée et compte encore dans les vecteurs, jusqu'à ce qu'elle devienne obsolète à son tour.

D'ici là : régler les mêmes délais de wpmaint sur tous les nœuds d'un réseau. L'écart est sans gravité - trois tours de vecteurs par heure au plus depuis la 4.1.6-rc7 - mais il remplit le journal.

18. Quatrième chantier : la commande QSl du nœud

Demandée le 13/10/2026 : une carte QSL qui confirme une connexion au nœud, à la manière de la carte envoyée après un contact radio.

Un utilisateur tape QSl (QS suffit). Le nœud affiche la carte en texte dans la session : le titre « FPAC node confirming connection with », l'indicatif de l'utilisateur, la date et l'heure en UTC, l'heure de début de la session, puis ce que montre la commande Status jusqu'à la version de FPAC.

Une session ne transporte que du texte : l'image de la carte ne peut pas y passer. Décidé (F6BVP, 13/10/2026) : le nœud fabrique l'image et donne un lien pour la télécharger avec un navigateur ; pas de courriel. L'image est un seul fichier JPEG, l'image du nœud au-dessus (recto) et le texte en dessous (verso).

Il faut pour cela un serveur web sur le nœud ; c'est donc facultatif :

Mot-clé Valeur Effet
QslDir dossier où les cartes sont écrites
QslUrl adresse web le même dossier vu du web
QslImage fichier image du recto
QslKeep jours, 30 par défaut durée de conservation

Ils s'écrivent dans fpac.conf, ou dans un fichier fpacqsl.conf placé à côté. Sans QslDir et QslUrl, le nœud ne donne que la carte en texte. L'image du recto est par défaut le fichier QSL_fpac.jpg déposé par le sysop à côté de fpac.conf ; sans lui la carte n'a que sa face de texte.

L'image est dessinée par un programme à part, fpacqsl, écrit en Python : le nœud lui-même ne gagne aucune dépendance. Il lui faut le paquet python3-pil.

Limites : les cartes de plus de QslKeep jours sont effacées ; un utilisateur qui redemande dans les 10 minutes reçoit la carte déjà fabriquée ; aucune image n'est fabriquée tant que le dossier contient 500 cartes. Chaque demande est inscrite dans fpac/qsl.log.

État au 13/10/2026 : codé, et à l'essai sur un nœud, qui sert les cartes sous http://f6bvp.org/qsl/. Le mode d'emploi est le fichier doc/qsl.txt des sources.