Désolé pour ce billet très incohérent, qui a dérivé de deux lignes de code pour récupérer le nom de la machine à contacter pour se connecter à un serveur Jabber à des réflexions un peu plus générales.

Au commencement était le DNS qui permettait de faire le lien entre un nom de domaine et une (ou plusieurs) adresses IP.

Petit rappel

Chaque enregistrement DNS est composé d'un nom, le nom de domaine, d'un type, d'une classe, d'une durée de vie et d'une valeur.

Les types les plus courant sont:

  • A : adresse IPv4;
  • AAAA : adresse IPv6;
  • NS : nom du serveur DNS gérant le domaine;
  • CNAME : pour les alias. Par exemple www.clochix.net CNAME blogs.vip.gandi.net signifie que le nom www.clochix.net est un simple synonyme de blogs.vip.gandi.net et que pour avoir ses caractéristiques il faut donc requérir celles du domaine initial;

La classe sera toujours 'IN' pour internet (je doute que les gens qui utilisent d'autres valeurs lisent ce billet).

La durée de vie (TTL) indique le nombre de secondes pendant lequel un client peut garder l'information en cache au lieu de la re-demander au serveur (c'est ce qui explique les durées de propagation des modifications d'enregistrement DNS : un client n'est censé interroger le serveur qui gère le domaine que toutes les TTL secondes)

MX

Au commencement donc était le DNS. Un peu plus tard, on s'est dit que ça serait bien de pouvoir indiquer dans le DNS que les mails adressés à un domaine sont traités par un autre serveur. Ainsi le site web clochix.net pourrait être hébergé sur une machine, et les mails traités par une autre. Ainsi est né le MX. C'est un type d'enregistrement indiquant les serveurs qui traitent les mails pour un domaine. Ses données se composent d'une liste de priorités et de noms de serveurs. Par exemple pour clochix.net:

clochix.net. 10800 IN MX 10 spool.mail.gandi.net.
clochix.net. 10800 IN MX 50 fb.mail.gandi.net.

Les mails devront être envoyés au serveur spool.mail.gandi.net ou, s'il est indisponible, à fb.mail.gandi.net.

SRV

L'idée était bonne, on a donc décidé de la généraliser en créant un nouveau type d'enregistrement, SRV, défini par la RFC 2782 pour associer des serveurs à des services pour un domaine.

Pour découvrir le serveur associé à un service, il faut demander l'enregistrement SRV pour le nom _Service._Protocole.Domain. Les noms de service et de protocole sont préfixés par le caractère '_' pour éviter toute confusion avec des noms existant.

La liste des noms de services est en cours de normalisation, on pourra en trouver une version ici.

Le protocole sera généralement _tcp ou _udp.

Le protocole XMPP est un des premiers à utiliser les enregistrements SRV. Concrètement, si vous voulez connaître l'adresse du serveur auquel vous connecter pour accéder à votre compte GTalk[1] à partir d'un client Jabber, il suffit de rechercher le SRV de _xmpp-client._tcp.gmail.com. La réponse devrait ressembler à ça:

_xmpp-client._tcp.google.com. 900 IN SRV 20 0 5222 talk1.l.google.com.
_xmpp-client._tcp.google.com. 900 IN SRV 20 0 5222 talk2.l.google.com.
_xmpp-client._tcp.google.com. 900 IN SRV 5 0 5222 talk.l.google.com.

Les données d'un enregistrement SRV sont:

  • la priorité, comme pour les MX, la plus petite étant le serveur prioritaire;
  • un poids servant à choisir entre les serveurs de même priorité. Cette fois, ce sont les poids les plus lourds qui sont prioritaires;
  • le port : cela permet de définir un port inhabituel pour un service;
  • le nom de domaine du serveur;

Pour utiliser le serveur Jabber de Google, un client devra donc se connecter au port 5222 de la machine talk.l.google.com.

En PHP

Accéder au DNS en PHP est très simple, c'est disponible nativement grâce à la fonction dns_get_record. On pourra utiliser un code de ce genre pour récupérer l'hôte hébergeant le serveur XMPP d'un domaine:

function getServer($domain) {
  $rec = dns_get_record("_xmpp-client._tcp.$domain", DNS_SRV);
  usort($rec, create_function('$a,$b', 'if($a["pri"]==$b["pri"]){if ($a["weight"]==$b["weight"])return 0;return($a["weight"]>$b["weight"]?-1:1);}return($a["pri"]<$b["pri"]?-1:1);'));
  return $rec[0];
}
$rec    = getServer('gmail.com');
$server = $rec['target'];
$port   = $rec['port'];

(je trie les réponses en fonction de leur priorité et de leur poids avec une fonction anonyme dont le code n'a aucun intérêt).

Pour aller plus loin

Outre mes travaux en cours sur XMPP, je me suis aussi intéressé aux enregistrements SRV suite à un billet d'Eric Daspet, "Ouvert et décentralisé, est-ce suffisant ?" dans lequel il se demandait où centraliser son profil public, comment avoir à un seul endroit les liens vers son blog, son micro-blog, sa galerie de photos, son CV, etc. Selon Saint TBL, tout doit avoir une URL. Je suis donc assez partisan que chaque être possède un nom de domaine, histoire de maîtriser la base de ses URL[2][3]. Posséder un nom de domaine est le minimum nécessaire, mais c'est peut-être aussi suffisant pour stocker sa carte de visite. A partir du moment où on dispose d'un nom de domaine, est-il besoin d'autres choses pour pointer vers ses données ?. Le DNS devrait pour moi suffire. Il contient un type d'enregistrement, TXT, susceptible de contenir n'importe quelle donnée textuelle (je ne connais pas les contraintes de taille). De nouvelles propositions d'utilisation en sont régulièrement faites, qui débouchent parfois sur la création de nouveaux type d'enregistrements. Ainsi la RFC 1464 propose d'utiliser les champs TXT pour stocker des données sous la simple forme clé = valeur. La RFC 4408 utilise elle les enregistrements TXT pour implémenter un mécanisme de lutte contre le spam, le Sender Policy Framework[4]. Pourquoi ne pas utiliser ce champ pour stocker sa carte de visite, sous forme par exemple d'un document XML avec tous les vocabulaires qui vont bien ? Ou inventer un équivalent aux enregistrements SRV, non plus pour des services au sens Internet, mais pour des bouts de notre présence en ligne... Idéalement, le protocole whois aurait pu également servir à stocker ce type d'information. Il sert à interroger les bases de données des registres où sont enregistrés les noms de domaine, et contient de nombreuses informations. Malheureusement, malgré l'existence de quelques RFC, il n'est absolument pas standardisé, et il est difficile d'imaginer des applications inter-opérables s'appuyant dessus. Le DNS lui-même semble donc le meilleur endroit où stocker sa carte de visite.

Mouais, vous en pensez quoi ?

Ajout du 7 septembre l'idée n'est évidemment pas neuve, et j'ai trouvé plusieurs propositions similaires d'implémentations. Mais j'ai surtout découvert les enregistrements NAPTR définis dans la RFC 2915 et qui permettent très schématiquement de renvoyer une réponse en appliquant une expression régulière à la question. Je n'ai pas le temps de creuser mais si ça vous intéresse allez donc faire un tour par là.

Notes

[1] c'est mal

[2] non je n'ai pas d'actions chez Gandi

[3] le gTLD .name a d'ailleurs été créé dans cette optique

[4] grosso-modo cela consiste à lister une série d'IP seules autorisées à envoyer des mails pour un domaine. Cette liste était initialement stockée dans les champs TXT avant qu'un type spécifique d'enregistrement, SPF, ne soit créé