L'interface socket

From Livre IPv6

Revision as of 11:42, 27 February 2006 by Bruno Deniaud (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
L'interface de programmation "socket" IPv6 Table des matières Les primitives de conversion entre noms et adresses

La création d'une socket se fait comme auparavant en appelant la primitive socket. La distinction entre les protocoles IPv4 et IPv6 se fait sur la valeur du premier argument passé à socket, à savoir la famille d'adresses (ou de protocoles), c'est-à-dire ici PF_INET ou PF_INET6. Par exemple, si on veut créer un socket IPv4/UDP, on écrira :

sock = socket(PF_INET, SOCK_DGRAM, 0);

tandis qu'une création de socket IPv6/UDP se fera ainsi :

sock = socket(PF_INET6, SOCK_DGRAM, 0);

Une erreur de programmation classique consiste à utiliser AF_INET à la place de PF_INET. Cela n'a pas d'effet en général car rares sont les systèmes pour lesquels ces deux constantes diffèrent. Pour éviter en IPv6 des problèmes liés à cette erreur, il est demandé que les deux constantes PF_INET6 et AF_INET6 soient identiques.

Quant aux autres primitives constituant l'interface socket, leur syntaxe reste inchangée. Il faut simplement leur fournir des adresses IPv6, en l'occurrence des pointeurs vers des structures de type struct sockaddr_in6 au préalable convertis en des pointeurs vers des structures génériques de type struct sockaddr.

Donnons pour mémoire une liste des primitives les plus importantes :

bind()    connect()     sendmsg()
sendto()  accept()      recvfrom()
recvmsg() getsockname() getpeername()

L'adresse "wildcard"

Lors du nommage d'une socket via la primitive bind, il arrive fréquemment qu'une application (par exemple un serveur TCP) laisse au système la détermination de l'adresse source pour elle. En IPv4, pour ce faire, elle passe à bind une structure sockaddr_in avec le champ sin_addr.s_addr ayant pour valeur la constante INADDR_ANY, constante définie dans le fichier netinet/in.h.

En IPv6, il y a deux manières de faire cela, à cause des règles du langage C sur les initialisations et affectations de structures. La première est d'initialiser une structure de type struct in6_addr par la constante IN6ADDR_ANY_INIT :

struct in6_addr any_addr = IN6ADDR_ANY_INIT;

Attention, ceci ne peut se faire qu'au moment de la déclaration. Par exemple le code qui suit est incorrect (en C il est interdit d'affecter une constante complexe à une structure) :

struct sockaddr_in6 sin6;
 
sin6.sin6_addr = IN6ADDR_ANY_INIT; /* erreur de syntaxe !! */

La seconde manière utilise une variable globale :

extern const struct in6_addr in6addr_any;
struct sockaddr_in6 sin6;
 
sin6.sin6_addr = in6addr_any;

Cette méthode n'est pas possible dans une déclaration de variable globale ou statique.

La constante IN6ADDR_ANY_INIT et la variable in6addr_any sont toutes deux définies dans le fichier netinet/in.h.

L'adresse de bouclage

En IPv4, c'est la constante INADDR_LOOPBACK. En IPv6, de manière tout à fait similaire à l'adresse "wildcard", il y a deux façons d'affecter cette adresse. Ceci peut se faire au moment de la déclaration avec la constante IN6ADDR_LOOPBACK_INIT :

struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;

ou via la variable globale in6addr_loopback :

extern const struct in6_addr in6addr_loopback;
struct sockaddr_in6 sin6;
sin6.sin6_addr = in6addr_loopback;

Cette constante et cette variable sont définies dans le fichier netinet/in.h.

L'interface de programmation "socket" IPv6 Table des matières Les primitives de conversion entre noms et adresses
Personal tools