Protocole et Formats

Messages DNS et codage

Le Protocole DNS utilise un format de messages commun pour tous les échanges entre serveurs ou entre client et serveur. Les messages DNS sont acheminés soit au dessus de UDP, soit au dessus de TCP. Dans les 2 cas, on utilise le numéro de port prédéfini 53. Au dessus de UDP, le protocole DNS ne gère pas la segmentation et impose une taille maximum de message DNS de 512 octets. UDP sera utilisé par défaut, TCP servira dans le cas de messages dépassant 512 octets (transfert de zone en particulier).

Messages DNS

IdentificationContrôle
Nombre de QuestionsNombre de Réponses
Nombre de "Authority"Nombre de "Additional"
Question
...
Réponse
...
"Authority"
...
"Additional"
...

Les 6 premiers champs sont chacun sur 16 bits, les autres champs sont de tailles variables sans contraintes d'alignement autres que les octets. Les limites de tailles sont de 255 octets pour un Nom-DNS et de 65535 octets pour un RDATA.

L'existence et le contenu des différentes sections peuvent être requis ou optionnels suivant les cas. Cela dépendra aussi fortement de la nature itérative ou récursive de la réponse.

Pour une réponse itérative (RD=0 ou RA=0), la section Réponse sera le plus souvent vide (sauf si le serveur connaît par chance la réponse). La section Authority contiendra alors un Nom de domaine qui est un Nom de zone et les Serveurs de Noms associés. Il s'agit de la "meilleure information" connue par le serveur courant pour résoudre la requête. C'est à dire le plus long suffixe du nom de la question, dont le serveur courant connaît les Serveurs de Noms. Dans le pire des cas, c'est la zone Racine. La section Additional contient alors si possible (obligatoire pour la GLUE), des adresses de ces serveurs vers qui on va immédiatement itérer la requête.

Pour une réponse récursive positive (RD=RA=1, Rcode=NOERROR, Nombre de Réponses>0), la section Réponse contiendra toutes les réponses souhaitées. La section Authority contiendra le nom de la zone et la liste des serveurs Authoritative pour la réponse. Ceci permet éventuellement d'aller vérifier la réponse à la source si l'on ne fait pas confiance au cache, ou de mémoriser utilement les serveurs dans le cache pour répondre plus rapidement à des requêtes voisines ultérieurement (ou à la même requête après expiration du TTL).

La notion de réponse négative va en pratique couvrir deux cas différents :

  1. NXDOMAIN le nom dans la requête n'existe pas dans la base DNS. Cela est identifié dans le message DNS par Rcode=NXDOMAIN.
  2. NODATA le nom dans la requête existe mais il n'y a pas de RR du TYPE demandé. Le message contient alors Rcode=NOERROR et Nombre de Réponses=0.
Le mécanisme de cache négatif s'appliquera dans les 2 cas.

Pour une réponse récursive négative (RD=RA=1, NXDOMAIN ou NODATA), la section Réponse sera vide. La section Authority contiendra le SOA de la zone afin de donner la valeur du parametre Negative Cache TTL à utiliser pour cette réponse.

On se reportera à la section exemples dig pour des exemples.

Codage des Noms de Domaine

Le codage des Noms-DNS prend la forme :
N1label1N2label2...Nnlabeln0
N1, N2, ..., Nn sont sur 1 octet la taille des labels successifs. La taille maximum d'un label est 63 octets à cause de la compression à venir. La taille maximum d'un nom est arbitrairement de 255 octets pour "simplifier l'implémentation". Le label vide (N=0) est uniquement la racine. Les labels sont constitués d'octets quelconques.

On a par exemple :
3www8int-evry2fr0

où les chiffres en gras sont les valeurs décimales des octets, le reste est en ASCII.

Compression des Noms de Domaines

Pour économiser la place dans les messages DNS, on peut, et l'on doit, partager des parties de noms communes dans un même message. Les 2 bits de poids fort dans le champs longueur d'un label sont utilisés pour cela : Cet offset sur 14 bits, indique la position en octet de la suite du nom de domaine par rapport au début du message DNS. Offset=0 correspond au premier octet du champs Identification.

Exemple :
On considère une requête sur le nom zeratul.ipv6.int-evry.fr. (cf. exemple dig n.7). Dans la réponse, le premier nom qui apparaît est celui de la question, il commencera au 12ième octet du message DNS.
On trouve donc avec OFFSET=12, le codage :
7zeratul4ipv68int-evry2fr0

Le même nom apparaît naturellement dans la section Réponse, il sera alors codé sur seulement 2 octets par :
19212
NB: 192="11000000"

Le nom ipv6.int-evry.fr. apparaît ensuite comme nom de zone dans la section Authority, il sera alors codé sur 2 octets :
19220

Le nom hugo.int-evry.fr. apparaît aussi comme serveur de zone, il sera alors codé :
4hugo19225

Precisions : La compression des noms s'applique aussi bien sur le Nom de domaine des RRs que sur les noms DNS qui apparaissent dans les RDATAs. Cela pose un problème d'extensibilité au niveau du DNS car les RDATAs contenants des noms ne peuvent être traités de manière opaque comme une chaîne d'octets. En effet, le codage des RDATAs dépend alors du message qui les a véhiculé. Ainsi l'introduction d'un nouveau type de RR avec des noms dans les RDATAs nécessite la mise à jour de tout les serveurs DNS (car ils peuvent servir de cache), ou l'interdiction de la compression des noms pour les nouveaux RDATAs (cf. RFC3597).