3. Comportement du Serveur
3. Comportement du Serveur
Un serveur, à la réception d'une requête UPDATE, signalera NOTIMP au demandeur si l'opcode UPDATE n'est pas reconnu ou s'il est reconnu mais n'a pas été implémenté. Sinon, le traitement se poursuit comme suit.
3.1 Traiter la Section Zone
3.1.1. La section Zone est vérifiée pour s'assurer qu'il y a exactement un RR et que le ZTYPE du RR est SOA, sinon signaler FORMERR au demandeur. Ensuite, ZNAME et ZCLASS sont vérifiés pour voir si la zone ainsi nommée est l'une des zones d'autorité de ce serveur, sinon signaler NOTAUTH au demandeur. Si le serveur est un esclave de zone, la requête sera transférée vers le maître principal.
3.1.2 - Pseudocode pour le Traitement de la Section Zone
if (zcount != 1 || ztype != SOA)
return (FORMERR)
if (zone_type(zname, zclass) == SLAVE)
return forward()
if (zone_type(zname, zclass) == MASTER)
return update()
return (NOTAUTH)
Les sections 3.2 à 3.8 décrivent le comportement du maître principal, tandis que la section 6 décrit le comportement d'un transitaire.
3.2 Traiter la Section Prerequisite
Ensuite, la section Prerequisite est vérifiée pour s'assurer que tous les prérequis sont satisfaits par l'état actuel de la zone. En utilisant les définitions exprimées dans la section 1.2, si le NAME d'un RR ne se trouve pas dans la zone spécifiée dans la section Zone, signaler NOTZONE au demandeur.
3.2.1. Pour les RRs de cette section dont CLASS est ANY, tester pour voir que TTL et RDLENGTH sont tous deux zéro (0), sinon signaler FORMERR au demandeur. Si TYPE est ANY, tester pour voir qu'il existe au moins un RR dans la zone dont NAME est le même que celui du RR Prerequisite, sinon signaler NXDOMAIN au demandeur. Si TYPE n'est pas ANY, tester pour voir qu'il existe au moins un RR dans la zone dont NAME et TYPE sont les mêmes que ceux du RR Prerequisite, sinon signaler NXRRSET au demandeur.
3.2.2. Pour les RRs de cette section dont CLASS est NONE, tester pour voir que TTL et RDLENGTH sont tous deux zéro (0), sinon signaler FORMERR au demandeur. Si TYPE est ANY, tester pour voir qu'il n'existe aucun RR dans la zone dont NAME est le même que celui du RR Prerequisite, sinon signaler YXDOMAIN au demandeur. Si TYPE n'est pas ANY, tester pour voir qu'il n'existe aucun RR dans la zone dont NAME et TYPE sont les mêmes que ceux du RR Prerequisite, sinon signaler YXRRSET au demandeur.
3.2.3. Pour les RRs de cette section dont CLASS est la même que ZCLASS, tester pour voir que TTL est zéro (0), sinon signaler FORMERR au demandeur. Ensuite, construire un RRset pour chaque <NAME,TYPE> unique et comparer chaque RRset résultant pour l'égalité d'ensemble (mêmes membres, ni plus, ni moins) avec les RRsets dans la zone. Si un RRset Prerequisite n'est pas entièrement et exactement correspondant par un RRset de zone, signaler NXRRSET au demandeur. Si un RR de cette section a une CLASS autre que ZCLASS ou NONE ou ANY, signaler FORMERR au demandeur.
3.2.4 - Tableau des Métavaleurs Utilisées dans la Section Prerequisite
| CLASS | TYPE | RDATA | Signification |
|---|---|---|---|
| ANY | ANY | vide | Le nom est utilisé |
| ANY | rrset | vide | Le RRset existe (indépendant de la valeur) |
| NONE | ANY | vide | Le nom n'est pas utilisé |
| NONE | rrset | vide | Le RRset n'existe pas |
| zone | rrset | rr | Le RRset existe (dépendant de la valeur) |
3.2.5 - Pseudocode pour le Traitement de la Section Prerequisite
for rr in prerequisites
if (rr.ttl != 0)
return (FORMERR)
if (zone_of(rr.name) != ZNAME)
return (NOTZONE);
if (rr.class == ANY)
if (rr.rdlength != 0)
return (FORMERR)
if (rr.type == ANY)
if (!zone_name<rr.name>)
return (NXDOMAIN)
else
if (!zone_rrset<rr.name, rr.type>)
return (NXRRSET)
if (rr.class == NONE)
if (rr.rdlength != 0)
return (FORMERR)
if (rr.type == ANY)
if (zone_name<rr.name>)
return (YXDOMAIN)
else
if (zone_rrset<rr.name, rr.type>)
return (YXRRSET)
if (rr.class == zclass)
temp<rr.name, rr.type> += rr
else
return (FORMERR)
for rrset in temp
if (zone_rrset<rrset.name, rrset.type> != rrset)
return (NXRRSET)
3.3 Vérifier les Permissions du Demandeur
3.3.1. Ensuite, la permission du demandeur de mettre à jour les RRs nommés dans la section Update peut être testée de manière dépendante de l'implémentation ou en utilisant des mécanismes spécifiés dans un protocole Update DNS Sécurisé ultérieur. Si le demandeur n'a pas la permission d'effectuer ces mises à jour, le serveur peut écrire un message d'avertissement dans son journal d'opérations, et peut soit signaler REFUSED au demandeur, soit ignorer le problème de permission et poursuivre la mise à jour.
3.3.2. Bien que le traitement exact soit défini par l'implémentation, si ces activités de vérification doivent être effectuées, c'est le point dans le traitement du serveur où une telle performance devrait avoir lieu, car s'il rencontre une condition REFUSED après qu'une mise à jour ait été partiellement appliquée, il sera nécessaire d'annuler la mise à jour partielle et de restaurer la zone à son état d'origine avant de répondre au demandeur.
3.3.3 - Pseudocode pour la Vérification des Permissions
if (security policy exists)
if (this update is not permitted)
if (local option)
log a message about permission problem
if (local option)
return (REFUSED)
3.4 Traiter la Section Update
Ensuite, la section Update est traitée comme suit.
3.4.1 - Préanalyse
La section Update est analysée en RRs et la CLASS de chaque RR est vérifiée pour voir si elle est ANY, NONE ou la même que la Zone Class, sinon signaler FORMERR au demandeur. En utilisant les définitions de la section 1.2, le NAME de chaque RR doit être dans la zone spécifiée par la section Zone, sinon signaler NOTZONE au demandeur.
3.4.1.2. Pour les RRs dont CLASS n'est pas ANY, vérifier TYPE et s'il est ANY, AXFR, MAILA, MAILB ou tout autre métatype QUERY, ou tout type non reconnu, alors signaler FORMERR au demandeur. Pour les RRs dont CLASS est ANY ou NONE, vérifier TTL pour voir qu'il est zéro (0), sinon signaler FORMERR au demandeur. Pour tout RR dont CLASS est ANY, vérifier RDLENGTH pour s'assurer qu'il est zéro (0) (c'est-à-dire que le champ RDATA est vide), et que TYPE n'est pas AXFR, MAILA, MAILB ou tout autre métatype QUERY en plus de ANY, ou tout type non reconnu, sinon signaler FORMERR au demandeur.
3.4.1.3 - Pseudocode pour la Préanalyse de la Section Update
[rr] for rr in updates
if (zone_of(rr.name) != ZNAME)
return (NOTZONE);
if (rr.class == zclass)
if (rr.type & ANY|AXFR|MAILA|MAILB)
return (FORMERR)
elsif (rr.class == ANY)
if (rr.ttl != 0 || rr.rdlength != 0
|| rr.type & AXFR|MAILA|MAILB)
return (FORMERR)
elsif (rr.class == NONE)
if (rr.ttl != 0 || rr.type & ANY|AXFR|MAILA|MAILB)
return (FORMERR)
else
return (FORMERR)
3.4.2 - Mise à Jour
La section Update est analysée en RRs et ces RRs sont traités dans l'ordre.
3.4.2.1. Si une défaillance système (telle qu'une condition de manque de mémoire ou une erreur matérielle dans le stockage persistant) se produit pendant le traitement de cette section, signaler SERVFAIL au demandeur et annuler toutes les mises à jour appliquées à la zone pendant cette transaction.
3.4.2.2. Tout RR Update dont CLASS est la même que ZCLASS est ajouté à la zone. En cas de RDATAs en double (ce qui est toujours le cas pour les RRs SOA, et pour les RRs WKS si les champs ADDRESS et PROTOCOL correspondent tous deux), le RR Zone est remplacé par le RR Update. Si TYPE est SOA et qu'il n'y a pas de RR SOA Zone, ou que le nouveau SOA.SERIAL est inférieur (selon [RFC1982]) ou égal au SOA.SERIAL du RR SOA Zone actuel, le RR Update est ignoré. Dans le cas d'un RR Update CNAME et d'un RRset Zone non-CNAME ou vice versa, ignorer le RR Update CNAME, sinon remplacer le RR Zone CNAME par le RR Update CNAME.
3.4.2.3. Pour tout RR Update dont CLASS est ANY et dont TYPE est ANY, tous les RRs Zone avec le même NAME sont supprimés, sauf si NAME est le même que ZNAME auquel cas seuls les RRs dont TYPE est autre que SOA ou NS sont supprimés. Pour tout RR Update dont CLASS est ANY et dont TYPE n'est pas ANY, tous les RRs Zone avec le même NAME et TYPE sont supprimés, sauf si NAME est le même que ZNAME auquel cas ni les RRs SOA ni NS ne seront supprimés.
3.4.2.4. Pour tout RR Update dont la classe est NONE, tout RR Zone dont NAME, TYPE, RDATA et RDLENGTH sont égaux au RR Update est supprimé, sauf si NAME est le même que ZNAME et soit TYPE est SOA, soit TYPE est NS et le RR Zone correspondant est le seul NS restant dans le RRset, auquel cas ce RR Update est ignoré.
3.4.2.5. Signaler NOERROR au demandeur.
3.4.2.6 - Tableau des Métavaleurs Utilisées dans la Section Update
| CLASS | TYPE | RDATA | Signification |
|---|---|---|---|
| ANY | ANY | vide | Supprimer tous les RRsets d'un nom |
| ANY | rrset | vide | Supprimer un RRset |
| NONE | rrset | rr | Supprimer un RR d'un RRset |
| zone | rrset | rr | Ajouter à un RRset |
3.4.2.7 - Pseudocode pour le Traitement de la Section Update
[rr] for rr in updates
if (rr.class == zclass)
if (rr.type == CNAME)
if (zone_rrset<rr.name, ~CNAME>)
next [rr]
elsif (zone_rrset<rr.name, CNAME>)
next [rr]
if (rr.type == SOA)
if (!zone_rrset<rr.name, SOA> ||
zone_rr<rr.name, SOA>.serial > rr.soa.serial)
zone_rr<rr.name, SOA> = rr
elsif (rr.type == WKS)
if (zone_rrset<rr.name, WKS, rr.proto, rr.address>)
zone_rr<rr.name, WKS, rr.proto, rr.address> = rr
else
zone_rrset<rr.name, WKS> += rr
else
zone_rrset<rr.name, rr.type> += rr
elsif (rr.class == ANY)
if (rr.type == ANY)
if (rr.name == zname)
zone_rrset<rr.name, ~(SOA|NS)> = Nil
else
zone_rrset<rr.name, *> = Nil
elsif (rr.name == zname &&
(rr.type == SOA || rr.type == NS))
next [rr]
else
zone_rrset<rr.name, rr.type> = Nil
elsif (rr.class == NONE)
if (rr.type == SOA)
next [rr]
if (rr.type == NS && zone_rrset<rr.name, NS> == rr)
next [rr]
zone_rr<rr.name, rr.type, rr.data> = Nil
return (NOERROR)
3.5 Traiter la Section Additional Data
Le traitement des Additional Data n'est pas décrit dans ce mémo. Un serveur devrait silencieusement ignorer les RRs dans la section Additional Data qui sont liés au traitement UPDATE. Cependant, si la section Additional Data contient des RRs dont un serveur aura besoin pour rendre la mise à jour utile (tels que les RRs A de glue pour la cible d'un nouveau RR NS), alors cette section devrait être traitée.
3.6 Ajouter les Modifications au Journal des Transactions
Si la zone a un journal des transactions, les modifications apportées à la zone PEUVENT y être ajoutées, peut-être sous la forme d'un message UPDATE minimal. Notez que le SOA SERIAL ne sera mis à jour que si un RR SOA faisait partie du message UPDATE, ou si la politique du serveur dicte que le SOA SERIAL soit auto-incrémenté.
3.7 Envoyer la Réponse au Demandeur
À ce stade, le message de réponse doit être assemblé et renvoyé au demandeur. L'en-tête ne contient aucune option spéciale et la section Zone (section Question dans Query) est copiée de la section correspondante de la requête. PRCOUNT, UPCOUNT et ADCOUNT sont tous mis à zéro (0). Le code de réponse est NOERROR, sauf si une erreur de traitement ou de permission s'est produite, auquel cas le RCODE approprié est envoyé. Une copie du RR SOA actuel de la zone devrait être envoyée dans la section Answer de la réponse (même en cas d'erreur), pour le bénéfice des demandeurs qui utilisent UPDATE pour modifier les paramètres SOA et qui nécessitent des commentaires concernant le statut réel.
3.8 Signaler aux Esclaves
Le maître principal devrait utiliser un mécanisme tel que DNS NOTIFY (voir [RFC1996]) pour signaler aux esclaves connus que la zone a été mise à jour. Notez que cette notification devrait être envoyée même si le SOA SERIAL n'a pas été incrémenté en raison de la politique ou du contenu UPDATE.