Provided by: manpages-fr-dev_4.21.0-2_all bug

NOM

       getaddrinfo, freeaddrinfo, gai_strerror - Traduction d'adresses et de services réseau

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

       #include <sys/types.h>
       #include <sys/socket.h>
       #include <netdb.h>

       int getaddrinfo(const char *restrict node,
                       const char *restrict service,
                       const struct addrinfo *restrict hints,
                       struct addrinfo **restrict res);

       void freeaddrinfo(struct addrinfo *res);

       const char *gai_strerror(int errcode);

   Exigences de macros de test de fonctionnalités pour la glibc (consulter feature_test_macros(7)) :

       getaddrinfo(), freeaddrinfo(), gai_strerror() :
           Avant la glibc 2.22 :
               _POSIX_C_SOURCE >= 200112L
           glibc 2.21 et antérieures :
               _POSIX_C_SOURCE

DESCRIPTION

       Étant  donnés  node et service, qui identifient un hôte Internet et un service, getaddrinfo() renvoie une
       ou plusieurs structure addrinfo, chacune d'entre elles contenant une adresse  Internet  qui  puisse  être
       indiquée  dans  un  appel  à  bind(2)  ou connect(2). La fonction getaddrinfo() combine la fonctionnalité
       fournie par les fonctions gethostbyname(3) et getservbyname(3) en une interface unique, mais à  l'inverse
       de  ces  fonctions, getaddrinfo() est réentrante et permet aux programmes d'éliminer la dépendance envers
       IPv4 ou IPv6.

       La structure addrinfo utilisée par getaddrinfo() contient les membres suivants :

           struct addrinfo {
               int              ai_flags;
               int              ai_family;
               int              ai_socktype;
               int              ai_protocol;
               socklen_t        ai_addrlen;
               struct sockaddr *ai_addr;
               char            *ai_canonname;
               struct addrinfo *ai_next;
           };

       Le paramètre hints pointe sur une structure addrinfo qui indique les critères de sélection des structures
       d'adresses  de  sockets renvoyées dans la liste pointée par res. Si hints n'est pas NULL, il doit pointer
       sur une structure addrinfo dont les membres ai_family, ai_socktype, et ai_protocol indiquent les critères
       limitant l'ensemble d'adresses de sockets renvoyées par getaddrinfo(), de la façon suivante :

       ai_family
              Ce  champ  indique  la  famille d'adresse désirée des adresses renvoyées. AF_INET et AF_INET6 font
              partie des valeurs valables pour ce champ. La valeur  AF_UNSPEC  indique  que  getaddrinfo()  doit
              renvoyer les adresses de socket de n'importe quelle famille d'adresses (par exemple, IPv4 ou IPv6)
              pouvant être utilisées avec node et service.

       ai_socktype
              Ce champ indique le type préféré de socket, par exemple SOCK_STREAM ou SOCK_DGRAM. Mettre  0  dans
              ce champ indique que getaddrinfo() peut renvoyer n'importe quel type d'adresse de socket.

       ai_protocol
              Ce champ indique le protocole des adresses de socket renvoyées. Mettre 0 dans ce champ indique que
              getaddrinfo() peut renvoyer des adresses de socket de n'importe quel type.

       ai_flags
              Ce champ indique des options supplémentaires, décrites  ci-dessous.  Plusieurs  attributs  peuvent
              être indiqués en les groupant par un OU binaire.

       Tous les autres membres de la structure pointée par hints doivent contenir 0 ou être des pointeurs NULL.

       Spécifier  hints à NULL est équivalent à définir ai_socktype et ai_protocol à 0, ai_family à AF_UNSPEC et
       ai_flags à (AI_V4MAPPED | AI_ADDRCONFIG). (POSIX spécifie d'autres valeurs  par  défaut  pour  ai_flags ;
       consultez  les  NOTES.)  node  indique  soit  une adresse réseau en format numérique (décimal pointé pour
       l'IPv4, comme prise en charge par inet_aton(3) ; hexadécimal pour  l'IPv6,  comme  prise  en  charge  par
       inet_pton(3)),  soit  un nom d'hôte, dont l'adresse réseau est alors résolue. Si le membre hints.ai_flags
       contient l'attribut AI_NUMERICHOST alors  node  devra  être  une  adresse  réseau  numérique.  L'attribut
       AI_NUMERICHOST empêche toute tentative, éventuellement longue, de résolution de nom d'hôte.

       Si  l'attribut  AI_PASSIVE  est  indiqué dans hints.ai_flags, et si node est NULL, les adresses de socket
       renvoyées seront pertinentes pour lier (bind(2)) un socket qui acceptera (accept(2)) les connexions.  Les
       adresses  de  socket  renvoyées  contiendront  l'« adresse joker » (wildcard adress) (INADDR_ANY pour les
       adresses IPv4, IN6ADDR_ANY_INIT pour les  adresses  IPv6).  L'« adresse  joker »  est  utilisée  par  des
       applications  (typiquement  des serveurs) qui ont l'intention d'accepter des connexions de n'importe quel
       hôte. Si node n'est pas NULL, l'attribut AI_PASSIVE est ignoré.

       Si l'attribut AI_PASSIVE n'est pas positionné dans  hints.ai_flags,  les  adresses  de  socket  renvoyées
       seront  pertinentes  pour  être  utilisées  avec  connect(2),  sendto(2) ou sendmsg(2). Si node est NULL,
       l'adresse réseau sera définie avec l'adresse de l'interface de boucle  (loopback)  (INADDR_LOOPBACK  pour
       les  adresses IPv4, IN6ADDR_LOOPBACK_INIT pour les adresses IPv6) ; cela est utilisé par les applications
       qui doivent communiquer avec des correspondants s'exécutant sur la même machine.

       service définit le port dans chacune des structures d'adresses renvoyées. Si cet argument est un  nom  de
       service  (consultez services(5)), il est convertit en son numéro de port correspondant. Cet argument peut
       également être indiqué sous forme décimale, qui est simplement converti en binaire. Si service est  NULL,
       le  numéro  de  port des adresses de socket renvoyées n'est pas initialisé. Si AI_NUMERICSERV est indiqué
       dans hints.ai_flags et si service n'est pas NULL, service doit pointer  vers  une  chaîne  contenant  une
       valeur numérique de port. Cet attribut est utilisé pour inhiber l'invocation du service de résolution des
       noms dans les cas où l'on sait qu'il n'est pas nécessaire.

       node ou service peuvent être NULL, mais pas les deux à la fois.

       La fonction getaddrinfo() alloue et initialise une liste chaînée de structures addrinfo, une pour  chaque
       adresse  réseau  correspondant à node et service, soumise aux restrictions imposées par l'argument hints,
       et renvoie dans res un pointeur sur le début de la liste. Les éléments de la liste sont  chaînés  par  le
       champ ai_next.

       Il  y  a  plusieurs  raisons  pour lesquelles la liste chaînée peut avoir plus d'une structure addrinfo :
       l'hôte réseau est « multihomed » ; le même  service  est  accessible  depuis  plusieurs  protocoles  (par
       exemple  AF_INET  et AF_INET6) ou accessible depuis plusieurs types de socket (par exemple une adresse de
       type SOCK_STREAM et une autre de type  SOCK_DGRAM).  Normalement,  l'application  essaie  d'utiliser  les
       adresses dans l'ordre où elles sont renvoyées. La fonction de tri utilisée dans getaddrinfo() est définie
       dans la RFC 3484 ; le tri peut être configuré pour un système particulier avec le  fichier  /etc/gai.conf
       (disponible depuis la glibc 2.5).

       Si  hints.ai_flags  contient  l'attribut  AI_CANONNAME,  le  champ  ai_canonname de la première structure
       addrinfo de la liste renvoyée est défini pour pointer vers le nom officiel de l'hôte.

       Les champs restants de chaque structure addrinfo renvoyée sont initialisés de la façon suivante :

       -  Les champs ai_family, ai_socktype et ai_protocol renvoient les paramètres de  création  de  la  socket
          (c'est-à-dire  que  ces  champs  ont  la  même  signification  que  les  paramètres  correspondants de
          socket(2)). Par exemple, ai_family  pourrait  renvoyer  AF_INET  ou  AF_INET6 ;  ai_socktype  pourrait
          renvoyer SOCK_DGRAM ou SOCK_STREAM ; et ai_protocol renvoie le protocole de la socket.

       -  Un  pointeur  vers l'adresse de la socket est placé dans le champ ai_addr, et la longueur de l'adresse
          de la socket, en octets, est inscrite dans le champ ai_addrlen de la structure.

       Si hints.ai_flags inclut l'attribut AI_ADDRCONFIG, alors des adresses IPv4 sont renvoyées dans  la  liste
       pointée  par res seulement si le système local possède au moins une adresse IPv4 configurée. Des adresses
       IPv6 sont seulement renvoyées si le système local possède au moins une adresse IPv6 configurée.  Dans  ce
       cas,  l'adresse de boucle n'est pas considérée comme une adresse configurée valable. Cet attribut est par
       exemple utile sur les systèmes uniquement en IPv4,  pour  s’assurer  que  getaddrinfo()  ne  renvoie  pas
       d’adresse de socket IPv6 qui échouerait toujours dans connect(2) ou bind(2).

       Si  hints.ai_flags  indique  le drapeau AI_V4MAPPED, et si hints.ai_family a été indiqué avec AF_INET6 et
       qu'aucune adresse IPv6 correspondante n'a pu être trouvée, alors des adresses IPv4 au  format  IPv6  sont
       renvoyées  dans la liste pointée par res. Si AI_V4MAPPED et AI_ALL sont indiqués dans hints.ai_flags, des
       adresses IPv6 et des adresses IPv4 au format IPv6 sont renvoyées dans la liste pointée  par  res.  AI_ALL
       est ignoré si AI_V4MAPPED n'est pas aussi indiqué.

       La fonction freeaddrinfo() libère la mémoire qui a été allouée dynamiquement pour la liste chaînée res.

   Extensions de getaddrinfo() pour les noms de domaines internationalisés
       Depuis  la  glibc 2.3.4,  getaddrinfo()  a  été modifié pour sélectivement permettre que les noms d'hôtes
       entrant et sortant soient convertis vers ou depuis le  format  des  noms  de  domaines  internationalisés
       (IDN).  Consultez  la  RFC 3490,  Internationalizing Domain Names in Applications (IDNA). Quatre nouveaux
       attributs ont été ajoutés :

       AI_IDN Si cet attribut est défini, alors le nom du nœud contenu dans node est converti dans le format IDN
              si nécessaire. Le format d'encodage choisi est celui de la locale du système.

              Si  le nom du nœud contient des caractères non ASCII, alors le format IDN est utilisé. Ces parties
              du nom du nœud (séparées par des points) qui contiennent des caractères  non  ASCI  sont  encodées
              avec  « ASCII  Compatible Encoding (ACE) » avant d'être transférées aux fonctions de résolution de
              noms.

       AI_CANONIDN
              À la suite d'une résolution de nom  réussie  et  si  AI_CANONNAME  a  été  indiqué,  getaddrinfo()
              retournera  le nom canonique du nœud correspondant à la valeur de la structure addrinfo passée. La
              valeur renvoyée est une copie exacte de la valeur retournée par la fonction de résolution de noms.

              Si le nom est encodé avec ACE, alors une ou plusieurs composantes de son nom  sont  préfixées  par
              xn--.  Pour  convertir  ces  composantes  dans un format lisible, l'attribut AI_CANONIDN peut être
              utilisé en plus de AI_CANONNAME. La chaîne résultante est encodée selon la locale du système.

       AI_IDN_ALLOW_UNASSIGNED, AI_IDN_USE_STD3_ASCII_RULES
              Utiliser ces attributs permet d'activer  respectivement  les  attributs  « IDNA_ALLOW_UNASSIGNED »
              (permettre  des  caractères  Unicode  non  assignés) et « IDNA_USE_STD3_ASCII_RULES » (vérifier la
              sortie pour être sûr que le nom d'hôte est conforme à STD3) utilisés dans la gestion de l'IDNA.

VALEUR RENVOYÉE

       getaddrinfo() renvoie 0 si elle réussit, ou l'un des codes d'erreur non nuls suivants :

       EAI_ADDRFAMILY
              L'hôte indiqué n'a pas d'adresse dans la famille réseau demandée.

       EAI_AGAIN
              Le serveur de noms a renvoyé une erreur temporaire. Réessayez plus tard.

       EAI_BADFLAGS
              hints.ai_flags contient des drapeaux incorrects ; ou hints.ai_flags inclut  AI_CANONNAME  et  name
              est NULL.

       EAI_FAIL
              Le serveur de noms a renvoyé une erreur définitive.

       EAI_FAMILY
              La famille d'adresse réclamée n'est pas supportée.

       EAI_MEMORY
              Plus assez de mémoire.

       EAI_NODATA
              L'hôte existe mais n'a pas d'adresse réseau définie.

       EAI_NONAME
              node  ou  service  sont  inconnus ou ils sont tous les deux NULL ; ou AI_NUMERICSERV a été indiqué
              dans hints.ai_flags mais service n'est pas un numéro de port.

       EAI_SERVICE
              Le service demandé n'est pas disponible pour le  type  de  socket  demandé.  Il  est  probablement
              disponible avec un autre type de socket. Par exemple, cette erreur peut se produire si service est
              « shell » (un  service  uniquement  disponible  avec  les  sockets  de  type  flux),  et  soit  si
              hints.ai_protocol  est  égal  à  IPPROTO_UDP  ou  soit si hints.ai_socktype est égal à SOCK_DGRAM.
              L'erreur peut aussi se produire si service est non NULL et hints.ai_socktype est égal  à  SOCK_RAW
              (un type de socket qui ne gère pas le concept de service).

       EAI_SOCKTYPE
              Le  type de socket demandé n'est pas géré. Cela peut se produire, par exemple si hints.ai_socktype
              et hints.ai_protocol sont inconsistants (par exemple, SOCK_DGRAM et IPPROTO_TCP, respectivement).

       EAI_SYSTEM
              Autre erreur système, la valeur de retour est -1 et errno est défini pour indiquer l'erreur.

       La fonction gai_strerror() traduit ces  codes  d'erreur  en  une  chaîne  de  caractères  compréhensible,
       utilisable pour rendre compte du problème.

FICHIERS

       /etc/gai.conf

ATTRIBUTS

       Pour une explication des termes utilisés dans cette section, consulter attributes(7).

       ┌────────────────────────────────────────────────────────────┬──────────────────────┬────────────────────┐
       │InterfaceAttributValeur             │
       ├────────────────────────────────────────────────────────────┼──────────────────────┼────────────────────┤
       │getaddrinfo()                                               │ Sécurité des threads │ MT-Safe env locale │
       ├────────────────────────────────────────────────────────────┼──────────────────────┼────────────────────┤
       │freeaddrinfo(), gai_strerror()                              │ Sécurité des threads │ MT-Safe            │
       └────────────────────────────────────────────────────────────┴──────────────────────┴────────────────────┘

STANDARDS

       POSIX.1-2001, POSIX.1-2008. La fonction getaddrinfo() est documentée dans la RFC 2553.

NOTES

       getaddrinfo() gère la notation address%scope-id pour indiquer l'identifiant scope de IPv6.

       AI_ADDRCONFIG,  AI_ALL  et  AI_V4MAPPED  sont  disponibles  depuis  la  glibc 2.3.3.  AI_NUMERICSERV  est
       disponible depuis la glibc 2.3.4.

       Selon POSIX.1, définir hints comme NULL devrait supposer que ai_flags soit égal à 0. La bibliothèque C de
       GNU  suppose  à la place que ai_flags est égal à (AI_V4MAPPED | AI_ADDRCONFIG) dans ce cas, puisque cette
       valeur est considérée comme une amélioration de la spécification.

EXEMPLES

       Le  programme  suivant  explique  l'utilisation  de  getaddrinfo(),  gai_strerror(),  freeaddrinfo(),  et
       getnameinfo(3). Les programmes sont des clients et serveurs

   Programme du serveur

       #include <netdb.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/socket.h>
       #include <sys/types.h>
       #include <unistd.h>

       #define BUF_SIZE 500

       int
       main(int argc, char *argv[])
       {
           int                      sfd, s;
           char                     buf[BUF_SIZE];
           ssize_t                  nread;
           socklen_t                peer_addrlen;
           struct addrinfo          hints;
           struct addrinfo          *result, *rp;
           struct sockaddr_storage  peer_addr;

           if (argc != 2) {
               fprintf(stderr, "Usage: %s port\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           memset(&hints, 0, sizeof(hints));
           hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
           hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
           hints.ai_flags = AI_PASSIVE;    /* For wildcard IP address */
           hints.ai_protocol = 0;          /* Any protocol */
           hints.ai_canonname = NULL;
           hints.ai_addr = NULL;
           hints.ai_next = NULL;

           s = getaddrinfo(NULL, argv[1], &hints, &result);
           if (s != 0) {
               fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
               exit(EXIT_FAILURE);
           }

           /* getaddrinfo() returns a list of address structures.
              Try each address until we successfully bind(2).
              If socket(2) (or bind(2)) fails, we (close the socket
              and) try the next address. */

           for (rp = result; rp != NULL; rp = rp->ai_next) {
               sfd = socket(rp->ai_family, rp->ai_socktype,
                            rp->ai_protocol);
               if (sfd == -1)
                   continue;

               if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
                   break;                  /* Success */

               close(sfd);
           }

           freeaddrinfo(result);           /* No longer needed */

           if (rp == NULL) {               /* No address succeeded */
               fprintf(stderr, "Could not bind\n");
               exit(EXIT_FAILURE);
           }

           /* Read datagrams and echo them back to sender. */

           for (;;) {
               char host[NI_MAXHOST], service[NI_MAXSERV];

               peer_addrlen = sizeof(peer_addr);
               nread = recvfrom(sfd, buf, BUF_SIZE, 0,
                                (struct sockaddr *) &peer_addr, &peer_addrlen);
               if (nread == -1)
                   continue;               /* Ignore failed request */

               s = getnameinfo((struct sockaddr *) &peer_addr,
                               peer_addrlen, host, NI_MAXHOST,
                               service, NI_MAXSERV, NI_NUMERICSERV);
               if (s == 0)
                   printf("Received %zd bytes from %s:%s\n",
                          nread, host, service);
               else
                   fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));

               if (sendto(sfd, buf, nread, 0, (struct sockaddr *) &peer_addr,
                          peer_addrlen) != nread)
               {
                   fprintf(stderr, "Error sending response\n");
               }
           }
       }

   Programme du client

       #include <netdb.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/socket.h>
       #include <sys/types.h>
       #include <unistd.h>

       #define BUF_SIZE 500

       int
       main(int argc, char *argv[])
       {
           int              sfd, s;
           char             buf[BUF_SIZE];
           size_t           len;
           ssize_t          nread;
           struct addrinfo  hints;
           struct addrinfo  *result, *rp;

           if (argc < 3) {
               fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           /* Obtain address(es) matching host/port. */

           memset(&hints, 0, sizeof(hints));
           hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
           hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
           hints.ai_flags = 0;
           hints.ai_protocol = 0;          /* Any protocol */

           s = getaddrinfo(argv[1], argv[2], &hints, &result);
           if (s != 0) {
               fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
               exit(EXIT_FAILURE);
           }

           /* getaddrinfo() returns a list of address structures.
              Try each address until we successfully connect(2).
              If socket(2) (or connect(2)) fails, we (close the socket
              and) try the next address. */

           for (rp = result; rp != NULL; rp = rp->ai_next) {
               sfd = socket(rp->ai_family, rp->ai_socktype,
                            rp->ai_protocol);
               if (sfd == -1)
                   continue;

               if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
                   break;                  /* Success */

               close(sfd);
           }

           freeaddrinfo(result);           /* No longer needed */

           if (rp == NULL) {               /* No address succeeded */
               fprintf(stderr, "Could not connect\n");
               exit(EXIT_FAILURE);
           }

           /* Send remaining command-line arguments as separate
              datagrams, and read responses from server. */

           for (size_t j = 3; j < argc; j++) {
               len = strlen(argv[j]) + 1;
                       /* +1 for terminating null byte */

               if (len > BUF_SIZE) {
                   fprintf(stderr,
                           "Ignoring long message in argument %zu\n", j);
                   continue;
               }

               if (write(sfd, argv[j], len) != len) {
                   fprintf(stderr, "partial/failed write\n");
                   exit(EXIT_FAILURE);
               }

               nread = read(sfd, buf, BUF_SIZE);
               if (nread == -1) {
                   perror("read");
                   exit(EXIT_FAILURE);
               }

               printf("Received %zd bytes: %s\n", nread, buf);
           }

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       getaddrinfo_a(3), gethostbyname(3), getnameinfo(3), inet(3), gai.conf(5), hostname(7), ip(7)

TRADUCTION

       La   traduction   française   de   cette   page   de   manuel   a   été   créée   par  Christophe  Blaess
       <https://www.blaess.fr/christophe/>,   Stéphan   Rafin   <stephan.rafin@laposte.net>,   Thierry   Vignaud
       <tvignaud@mandriva.com>,  François  Micaux,  Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard
       <fevrier@tigreraye.org>,   Jean-Luc   Coulon   (f5ibh)   <jean-luc.coulon@wanadoo.fr>,   Julien   Cristau
       <jcristau@debian.org>,      Thomas      Huriaux      <thomas.huriaux@gmail.com>,     Nicolas     François
       <nicolas.francois@centraliens.net>,    Florentin    Duneau    <fduneau@gmail.com>,     Simon     Paillard
       <simon.paillard@resel.enst-bretagne.fr>,     Denis    Barbier    <barbier@debian.org>,    David    Prévot
       <david@tilapin.org> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>

       Cette traduction est une documentation libre ; veuillez vous reporter à la  GNU  General  Public  License
       version 3   ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   concernant   les  conditions  de  copie  et  de
       distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel,  veuillez  envoyer  un  message  à
       ⟨debian-l10n-french@lists.debian.org⟩.