Aller au contenu principal

3. Protocole de Temps Réseau

Cette section consiste en une définition formelle du Protocole de Temps Réseau, y compris ses formats de données, entités, variables d'état, événements et procédures de traitement des événements. La spécification est basée sur le modèle d'implémentation illustré dans la Figure 1, mais il n'est pas prévu que ce modèle soit le seul sur lequel une spécification peut être basée. En particulier, la spécification est destinée à illustrer et clarifier les opérations intrinsèques de NTP, ainsi qu'à servir de fondement pour une spécification plus rigoureuse, complète et vérifiable.

3.1. Formats de Données

Toutes les opérations mathématiques exprimées ou implicites ici sont en arithmétique à virgule fixe en complément à deux. Les données sont spécifiées comme des quantités entières ou à virgule fixe, avec des bits numérotés en mode big-endian à partir de zéro en commençant à la position gauche ou de poids fort. Étant donné que diverses implémentations peuvent mettre à l'échelle des quantités dérivées en externe pour un usage interne, ni la précision ni le placement de la virgule décimale pour les quantités à virgule fixe ne sont spécifiés. Sauf indication contraire, toutes les quantités sont non signées et peuvent occuper toute la largeur du champ avec un zéro implicite précédant le bit zéro. Les packages matériels et logiciels conçus pour fonctionner avec des quantités signées donneront ainsi des résultats surprenants lorsque le bit le plus significatif (signe) est défini. Il est suggéré que les quantités à virgule fixe non signées dérivées en externe telles que les horodatages soient décalées d'un bit vers la droite pour un usage interne, car la précision représentée par la largeur complète du champ est rarement justifiée.

Étant donné que les horodatages NTP sont des données précieuses et, en fait, représentent le principal produit du protocole, un format d'horodatage spécial a été établi. Les horodatages NTP sont représentés comme un nombre à virgule fixe non signé de 64 bits, en secondes par rapport à 0h le 1er janvier 1900. La partie entière est dans les 32 premiers bits et la partie fractionnaire dans les 32 derniers bits. Ce format permet une arithmétique de précision multiple pratique et une conversion en représentation de Protocole de Temps (secondes), mais complique la conversion en représentation de message d'horodatage ICMP (millisecondes). La précision de cette représentation est d'environ 200 picosecondes, ce qui devrait être adéquat même pour les exigences les plus exotiques.

Les horodatages sont déterminés en copiant la valeur actuelle de l'horloge locale vers un horodatage lorsqu'un événement significatif, tel que l'arrivée d'un message, se produit. Afin de maintenir la plus haute précision, il est important que cela soit fait aussi près que possible du pilote matériel ou logiciel associé à l'événement. En particulier, les horodatages de départ doivent être redéterminés pour chaque retransmission au niveau de la liaison. Dans certains cas, un horodatage particulier peut ne pas être disponible, par exemple lorsque l'hôte est redémarré ou que le protocole démarre pour la première fois. Dans ces cas, le champ de 64 bits est défini sur zéro, indiquant que la valeur est invalide ou indéfinie.

Notez que depuis un certain temps en 1968, le bit le plus significatif (bit 0 de la partie entière) a été défini et que le champ de 64 bits débordera à un certain moment en 2036. Si NTP est utilisé en 2036, des moyens externes seront nécessaires pour qualifier le temps par rapport à 1900 et le temps par rapport à 2036 (et d'autres multiples de 136 ans). Les données horodatées nécessitant une telle qualification seront si précieuses que des moyens appropriés devraient être facilement disponibles. Il existera un intervalle de 200 picosecondes, désormais ignoré, tous les 136 ans lorsque le champ de 64 bits sera zéro et donc considéré comme invalide.

3.2. Variables d'État et Paramètres

Ce qui suit est un résumé des diverses variables d'état et paramètres utilisés par le protocole. Ils sont séparés en classes de variables système, qui se rapportent à l'environnement du système d'exploitation et au mécanisme d'horloge locale; variables de pair, qui représentent l'état de la machine de protocole spécifique à chaque pair; variables de paquet, qui représentent le contenu du message NTP; et paramètres, qui représentent des constantes de configuration fixes pour toutes les implémentations de la version actuelle. Pour chaque classe, la description de la variable est suivie de son nom et de la procédure ou valeur qui la contrôle. Notez que les variables sont en minuscules, tandis que les paramètres sont en majuscules. Des détails supplémentaires sur les formats et l'utilisation sont présentés dans les sections et annexes ultérieures.

3.2.1. Variables Communes

Les variables suivantes sont communes à deux ou plusieurs des classes système, pair et paquet. Des variables supplémentaires sont spécifiques au mécanisme d'authentification optionnel décrit dans l'Annexe C. Lorsqu'il est nécessaire de distinguer entre les variables communes du même nom, l'identifiant de variable sera utilisé.

Adresse du Pair (Peer Address,peer.peeraddr, pkt.peeraddr), Port du Pair (Peer Port,peer.peerport, pkt.peerport): Ce sont l'adresse Internet 32 bits et le numéro de port 16 bits du pair.

Adresse de l'Hôte (Host Address,peer.hostaddr, pkt.hostaddr), Port de l'Hôte (Host Port,peer.hostport, pkt.hostport): Ce sont l'adresse Internet 32 bits et le numéro de port 16 bits de l'hôte. Ils sont inclus parmi les variables d'état pour prendre en charge le multi-hébergement (multi-homing).

Indicateur de Saut (Leap Indicator,sys.leap, peer.leap, pkt.leap): Il s'agit d'un code de deux bits avertissant d'une seconde intercalaire imminente à insérer dans l'échelle de temps NTP. Les bits sont définis avant 23:59 le jour de l'insertion et réinitialisés après 00:00 le jour suivant. Cela entraîne l'augmentation ou la diminution d'un du nombre de secondes (intervalle de roulement) le jour de l'insertion. Dans le cas des serveurs primaires, les bits sont définis par intervention de l'opérateur, tandis que dans le cas des serveurs secondaires, les bits sont définis par le protocole. Les deux bits, bit 0 et bit 1, respectivement, sont codés comme suit:

ValeurSignification
00pas d'avertissement
01dernière minute a 61 secondes
10dernière minute a 59 secondes
11condition d'alarme (horloge non synchronisée)

Dans tous les cas sauf la condition d'alarme (11₂), NTP lui-même ne fait rien avec ces bits, sauf les transmettre aux routines de conversion de temps qui ne font pas partie de NTP. La condition d'alarme se produit lorsque, pour quelque raison que ce soit, l'horloge locale n'est pas synchronisée, comme lors du premier démarrage ou après une période prolongée où aucune source de référence primaire n'est disponible.

Mode (Mode,peer.mode, pkt.mode): Il s'agit d'un entier indiquant le mode d'association, avec des valeurs codées comme suit:

ValeurMode
0non spécifié
1symétrique actif
2symétrique passif
3client
4serveur
5diffusion
6réservé pour les messages de contrôle NTP
7réservé pour usage privé

Strate (Stratum,sys.stratum, peer.stratum, pkt.stratum): Il s'agit d'un entier indiquant la strate de l'horloge locale, avec des valeurs définies comme suit:

ValeurSignification
0non spécifié
1référence primaire (par ex., horloge atomique calibrée, horloge radio)
2-255référence secondaire (via NTP)

À des fins de comparaison, une valeur de zéro est considérée comme supérieure à toute autre valeur. Notez que la valeur maximale de l'entier encodé comme variable de paquet est limitée par le paramètre NTP.MAXSTRATUM.

3.2.2. Variables Système

Le Tableau 1 montre l'ensemble complet des variables système. En plus des variables communes décrites précédemment, les variables suivantes sont utilisées par le système d'exploitation afin de synchroniser l'horloge locale.

Horloge Locale (Local Clock,sys.clock): Il s'agit de l'heure locale actuelle, en format d'horodatage. L'heure locale est dérivée de l'horloge matérielle de la machine particulière et s'incrémente à des intervalles dépendant de la conception utilisée. Une conception appropriée, y compris les mécanismes d'ajustement et de compensation de biais, est décrite dans la Section 5.

Source d'Horloge (Clock Source,sys.peer): Il s'agit d'un sélecteur identifiant la source de synchronisation actuelle. Habituellement, ce sera un pointeur vers une structure contenant les variables de pair. La valeur spéciale NULL indique qu'il n'y a actuellement aucune source de synchronisation valide.

3.2.3. Variables de Pair

Le Tableau 2 montre l'ensemble complet des variables de pair. En plus des variables communes décrites précédemment, les variables suivantes sont utilisées par les fonctions de gestion et de mesure des pairs.

Bit Configuré (Configured Bit,peer.config): Il s'agit d'un bit indiquant que l'association a été créée à partir d'informations de configuration et ne doit pas être démobilisée si le pair devient inaccessible.

Horodatage de Mise à Jour (Update Timestamp,peer.update): Il s'agit de l'heure locale, en format d'horodatage, lorsque le message NTP le plus récent a été reçu. Il est utilisé pour calculer la dispersion de biais.

Registre de Disponibilité (Reachability Register,peer.reach): Il s'agit d'un registre à décalage de bits NTP.WINDOW utilisé pour déterminer l'état de disponibilité du pair, avec des bits entrant par l'extrémité la moins significative (la plus à droite). Un pair est considéré comme accessible si au moins un bit dans ce registre est défini sur un.

Minuterie de Pair (Peer Timer,peer.timer): Il s'agit d'un compteur entier utilisé pour contrôler l'intervalle entre les messages NTP transmis. Une fois défini sur une valeur non nulle, le compteur décrémente à intervalles d'une seconde jusqu'à atteindre zéro, moment auquel la procédure de transmission est appelée. Notez que le fonctionnement de cette minuterie est indépendant des mises à jour de l'horloge locale, ce qui implique que le système de chronométrage et l'architecture du système de minuterie d'intervalle doivent être indépendants l'un de l'autre.

3.3. Modes de Fonctionnement

Sauf en mode diffusion, une association NTP est formée lorsque deux pairs échangent des messages et l'un ou les deux créent et maintiennent une instanciation de la machine de protocole, appelée association. L'association peut fonctionner dans l'un des cinq modes indiqués par la variable de mode hôte (peer.mode): symétrique actif, symétrique passif, client, serveur et diffusion, qui sont définis comme suit:

Symétrique Actif (Symmetric Active,1): Un hôte fonctionnant dans ce mode envoie des messages périodiques indépendamment de l'état de disponibilité ou de la strate de son pair. En fonctionnant dans ce mode, l'hôte annonce sa volonté de synchroniser et d'être synchronisé par le pair.

Symétrique Passif (Symmetric Passive,2): Ce type d'association est normalement créé à l'arrivée d'un message d'un pair fonctionnant en mode symétrique actif et persiste seulement tant que le pair est accessible et fonctionne à un niveau de strate inférieur ou égal à l'hôte; sinon, l'association est dissoute. Cependant, l'association persistera toujours jusqu'à ce qu'au moins un message ait été envoyé en réponse. En fonctionnant dans ce mode, l'hôte annonce sa volonté de synchroniser et d'être synchronisé par le pair.

Client (Client,3): Un hôte fonctionnant dans ce mode envoie des messages périodiques indépendamment de l'état de disponibilité ou de la strate de son pair. En fonctionnant dans ce mode, l'hôte, généralement un poste de travail LAN, annonce sa volonté d'être synchronisé par, mais pas de synchroniser le pair.

Serveur (Server,4): Ce type d'association est normalement créé à l'arrivée d'un message de demande client et existe seulement afin de répondre à cette demande, après quoi l'association est dissoute. En fonctionnant dans ce mode, l'hôte, généralement un serveur de temps LAN, annonce sa volonté de synchroniser, mais pas d'être synchronisé par le pair.

Diffusion (Broadcast,5): Un hôte fonctionnant dans ce mode envoie des messages périodiques indépendamment de l'état de disponibilité ou de la strate des pairs. En fonctionnant dans ce mode, l'hôte, généralement un serveur de temps LAN fonctionnant sur un support de diffusion à haute vitesse, annonce sa volonté de synchroniser tous les pairs, mais pas d'être synchronisé par l'un d'eux.

3.4. Traitement des Événements

Les événements importants d'intérêt dans NTP se produisent lors de l'expiration d'une minuterie de pair (peer.timer), dont une est dédiée à chaque pair avec une association active, et lors de l'arrivée d'un message NTP des différents pairs. Un événement peut également se produire suite à une commande d'opérateur ou à une panne système détectée, telle qu'une défaillance de source de référence primaire. Cette section décrit les procédures invoquées lorsque ces événements se produisent.

3.5. Procédure de Distance de Synchronisation

La procédure de distance calcule la distance de synchronisation à partir des variables de pair pour le pair peer.

begin distance(peer) procedure;
DELTA <- peer.rootdelay + |peer.delay|;
EPSILON <- peer.rootdispersion + peer.dispersion + φ(sys.clock - peer.update);
LAMBDA <- EPSILON + |DELTA| / 2;
end distance procedure;

Notez que, bien que DELTA puisse être négatif dans certains cas, EPSILON et LAMBDA sont toujours positifs.

3.6. Questions de Contrôle d'Accès

La conception NTP est telle que la modification accidentelle ou malveillante de données (falsification, tampering) ou la destruction (brouillage, jamming) sur un serveur de temps ne devrait généralement pas entraîner d'erreurs de chronométrage ailleurs dans le sous-réseau de synchronisation. Cependant, le succès de cette approche dépend de serveurs de temps redondants et de chemins réseau diversifiés, ainsi que de l'hypothèse que la falsification ou le brouillage ne se produira pas sur de nombreux serveurs de temps dans tout le sous-réseau de synchronisation en même temps. En principe, la vulnérabilité du sous-réseau peut être conçue par la sélection de serveurs de temps connus pour être fiables et en permettant uniquement à ces serveurs de temps de devenir la source de synchronisation. Les procédures d'authentification décrites dans l'Annexe C représentent un mécanisme pour appliquer cela; cependant, les algorithmes de chiffrement peuvent être très intensifs en CPU et peuvent sérieusement dégrader la précision, sauf si des précautions telles que mentionnées dans la description de la procédure de transmission sont prises.

Bien qu'il ne s'agisse pas d'une fonctionnalité requise de NTP lui-même, certaines implémentations peuvent inclure une fonctionnalité de contrôle d'accès qui empêche l'accès non autorisé et contrôle quels pairs sont autorisés à mettre à jour l'horloge locale. À cette fin, il est utile de distinguer trois catégories d'accès: ceux qui sont préautorisés comme fiables, préautorisés comme amicaux et tous les autres accès (non préautorisés). Vraisemblablement, la préautorisation est accomplie par des entrées dans le fichier de configuration ou un certain type de système de gestion de tickets tel que Kerberos [STE88]. Dans ce modèle, seuls les accès fiables peuvent entraîner que le pair devienne la source de synchronisation. Bien que les accès amicaux ne puissent pas entraîner que le pair devienne la source de synchronisation, les messages NTP et les horodatages sont renvoyés comme spécifié.

Il ne semble pas utile de maintenir une horloge secrète, comme cela résulterait de la restriction des accès non préautorisés, à moins que l'intention ne soit de cacher l'existence du serveur de temps lui-même. Les hôtes Internet bien comportés sont censés renvoyer un message d'erreur ICMP service-indisponible si un service n'est pas implémenté ou si les ressources ne sont pas disponibles; cependant, dans le cas de NTP, les ressources requises sont minimes, il y a donc peu de besoin de restreindre les demandes destinées uniquement à lire l'horloge. Un mécanisme de contrôle d'accès simple mais efficace consiste alors à considérer toutes les associations préconfigurées en mode symétrique ou en mode client (modes 1, 2 et 3) comme fiables et toutes les autres associations, préconfigurées ou non, comme amicales.

Si un modèle de confiance plus complet est requis, la conception peut être basée sur une liste de contrôle d'accès avec chaque entrée composée d'une adresse Internet 32 bits, d'un masque 32 bits et d'un mode 3 bits. Si le ET logique de l'adresse source (pkt.peeraddr) et du masque dans une entrée correspond à l'adresse correspondante dans l'entrée et que le mode (pkt.mode) correspond au mode dans l'entrée, l'accès est autorisé; sinon, un message d'erreur ICMP est renvoyé au demandeur. Grâce au choix approprié du masque, il est possible de restreindre les demandes par mode à des adresses individuelles, un sous-réseau particulier ou des adresses réseau, ou de n'avoir aucune restriction du tout. La liste de contrôle d'accès servirait alors de filtre contrôlant quels pairs pourraient créer des associations.