Robert E. Gilligan (FreeGate Corporation)Susan Thomson (Bell Communications Research)Jim Bound (Compaq Computer Corporation)W. Richard StevensMarch19992008-02-19
A priori, l'IETF ne normalise pas
d'API (et c'est pour cela que ce
RFC n'a que le statut de « pour
information »), se limitant aux « bits qu'on voit passer sur le câble ». Mais le monde de la
normalisation n'est pas toujours si simple et,
à l'époque, il était important de publier rapidement une documentation
sur la nouvelle API nécessaire aux applications pour faire de
l'IPv6.
Les APIUnix
et réseaux sont typiquement gérées par l'IEEE,
via sa norme POSIX. Mais POSIX n'est pas
librement téléchargeable sur le réseau, ce qui limite son
utilité. Pour cette raison et pour d'autres,
l'IETF a donc publié ce RFC, dont on notera
qu'un des auteurs est W. Richard Stevens,
auteur de Unix network
programming, le livre de
référence sur le sujet. Il succède à un premier RFC sur la question,
le et a lui-même été remplacé par le .
Depuis leur apparition, les prises
(socket dans la langue de Stevens) sont le
principal mécanisme d'accès au réseau pour les
programmes. Les programmes qui les utilisent sont relativement
portables, bien au delà du système BSD où elles
sont nées. Traditionnellement multi-protocoles, les prises ne
permettaient néanmoins pas d'accéder à
IPv6. C'est désormais le cas et l'interface
décrite dans ce RFC est désormais largement présente (MacOS X a été le dernier système d'exploitation à la
proposer).
Elle ne concerne que le langage C. Les
autres langages disposent souvent de mécanismes de plus haut niveau que les
prises comme les Streams
de Java.
Idéalement, la plupart des applications ne devrait pas avoir besoin de savoir si
elles utilisent IPv4 ou IPv6. Concentrée dans la
couche Réseau, le protocole utilisé ne devrait
pas concerner l'application. Mais C est un langage de bas niveau, et
expose donc le protocole de couche 3 utilisé (même si la section 2 du
RFC explique que l'API cherche à être la plus générale possible).
La section 2.1 résume les principaux changements qui ont été faits
pour permettre l'utilisation d'IPv6. Ils incluent une nouvelle
constante (section 3.1) pour indiquer les adresses IPv6
(AF_INET6, puisque AF_INET, comme
son nom ne l'indique pas clairement, étant spécifique à IPv4) et une
pour le protocole IPv6 (PF_INET6). Notons que le
RFC documente aussi PF_UNSPEC, qui permet à
l'application de dire qu'elle se moque du protocole utilisé (ce qui
devrait être le cas le plus courant). Il y a bien sûr une nouvelle
structure de données (section 3.3) pour placer les adresses IPv6,
quatre fois plus grandes. Les sockaddr sont
désormais des représentations de la prise, indépendantes de la famille
d'adresses, les sockaddr_in6 étant spécifiques à
IPv6. Elles contiennent :
struct sockaddr_in6 {
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* transport layer port # */
uint32_t sin6_flowinfo; /* IPv6 traffic class & flow info */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* set of interfaces for a scope */
};
Les appels système sur les prises, décrits dans la section 3.5,
eux, ont peu changés, socket, connect,
bind, continuent comme avant.
Les sections 3.6. et 3.7 concernent l'interopérabilité avec
IPv4. Le monde des applications a une forte inertie. Les développeurs,
déjà très occupés, ne portent pas leurs applications vers la nouvelle
interface instantanément. Ces deux sections expliquent donc comment
assurer le recouvrement des deux protocoles. On notera qu'avec cette
interface, pour faire un serveur qui écoute en
IPv4 et IPv6, il faut créer une prise IPv6, les
clients IPv4 recevront alors des adresses
IPv4-mapped comme
::FFFF:192.0.2.24. Ce n'est pas très
intuitif... (Heureusement, c'est plus simple pour un client.)
La section 6 du RFC parle des fonctions de bibliothèque pour
effectuer les traductions de noms en adresses et
réciproquement. L'ancienne gethostbyname, très spécifique
à IPv4 et souffrant d'autres limitations, ne devrait plus être
utilisée depuis des années (le nombre de programmes qui l'utilisent
encore ou de tutoriels qui l'expliquent donne une idée de l'extrême
inertie d'un secteur qui se prétend novateur et réactif). Les
« nouvelles » fonctions getaddrinfo et
getnameinfo (section 6.4) la remplacent. Le RFC propose
également en sections 6.1 et 6.2 getipnodebyname et
getipnodebyaddr, qui seront supprimées dans le
RFC suivant, le . Un programme
typique désormais fait :
ai_addr, pour les
suivantes, il faudra suivre result->ai_next */
mysocket = socket(...);
error = connect(mysocket, result->ai_addr, result->ai_addrlen);
...
]]>
Un des rares cas où un client réseau a besoin de manipuler des
adresses IP (pas seulement de les stocker et de les passer d'une
fonction à une autre) est lors de l'affichage, par exemple en mode
bavard. Pour éviter que le programme ne doive connaitre les détails de
syntaxe des adresses (celle d'IPv4 n'a jamais été normalisée, celle
d'IPv6 est décrite dans le ), notre RFC décrit en
section 6.6 des fonctions de conversion de et vers un format texte, inet_ntop et inet_pton.
L'inertie des programmeurs étant très forte, et celle des
enseignants également, on peut parier, bien que ce RFC soit vieux de
neuf ans, que beaucoup de cours de programmation réseaux sont encore
donnés avec la vieille interface, qui ne marche qu'en IPv4...