Avant d'aborder le codage des applications supportant les deux protocoles de couche réseau, il convient de poser les termes du débat. Deux lignes de conduite s'affrontent depuis des années sans que l'une ait réussi à prendre l'ascendant sur l'autre. L'objectif du présent document n'est pas d'affirmer une position mais d'exposer les arguments des uns et des autres. Ensuite, on étudiera dans les sections suivantes le même programme écrit suivant les deux modes de fonctionnement possibles.
Codage basé sur un socket simple
On pourrait qualifier cette ligne de conduite comme étant la plus académique. En effet, en reprenant les principes énoncés dans le cours sur la modélisation (voir Modélisations réseau), on postule que les traitements réalisés au niveau de chaque couche doivent être indépendants les uns des autres. Dans notre contexte, un programme de la couche application ne doit pas dépendre des protocoles de la couche réseau. Le principal argument en faveur de cette position est la pérennité du modèle. Si les traitements entre couches introduisent des relations de dépendance multiples, nous allons très vite être confronté à un écheveau inextricable. Plus il y aura de dépendances, moins le modèle sera évolutif et pérenne dans le temps.
On peut représenter cette solution comme suit.
Pour satisfaire le critère sur l'unicité du canal de communication entre la couche réseau et la couche transport, il est nécessaire d'établir une correspondance automatique entre les adresses IPv4 et les adresses IPv6. On parle de IPv4-mapped IPv6 addresses. Par exemple, l'adresse IPv4 192.0.2.10 devient ::ffff:192.0.2.10 après correspondance.
Codage basé sur deux sockets non bloquants
La seconde ligne de conduite s'appuie sur le fait que le support de l'option bindv6only n'est pas uniforme entre les différents systèmes d'exploitation. On observe des comportements différents entre les distributions BSD, Linux et les systèmes propriétaires. Cette option, que l'on applique à l'échelle du système ou dans une application, sert à définir si une prise réseau (socket) doit exclusivement être associée au seul protocole réseau IPv6 ou non.
Les partisans de cette position souhaitent que tous les programmes de la couche application gèrent deux sockets distincts. Cette solution a un impact important sur le codage des applications en langage C dans les domaines voisins de l'espace mémoire noyau comme les systèmes embarqués. Pour les langages «bien encrés» dans l'espace utilisateur, le recours à des bibliothèques de haut niveau permet de rendre l'opération transparente.
On peut représenter cette solution comme suit.
Pour qu'un unique processus puisse exploiter deux canaux de communication entre les couches application et transport, il est nécessaire d'utiliser des appels système non bloquants et de scruter les deux canaux en attente d'évènements. On a alors recours à la fonction select() qui permet de mettre en place une boucle de scrutation (polling).
Programmes et infrastructure de test
Voici un tableau de synthèse des tests effectués avec les différents codes proposés dans ce document.
Tableau 2. Protocole de couche réseau utilisé suivant les conditions de tests
|
client ou talker |
Serveur ou listener socket unique
|
Serveur ou listener socket double
|
|---|---|---|
|
Client dual stack
|
IPv6 |
IPv6 |
|
Client single stack
|
IPv6 IPv4-mapped IPv6 addresses |
IPv4 |


