Comment écouter sur toutes les adresses IPV6 à l'aide de C API sockets
Je maintiens DSGP, largement déployée à l'open-source, service de démon qui surveille GPSes et d'autres géodésique de capteurs. Il est à l'écoute pour le client, de l'application des connexions sur le port 2947 à la fois IPv4 et IPv6. Pour la sécurité et la confidentialité normalement, il n'écoute que sur l'adresse de bouclage, mais il y a une option-G pour le démon qui est prévu pour l'obliger à l'écouter sur n'importe quelle adresse.
Le problème: l'option-G travaille en IPv4, mais je ne peux pas comprendre comment le faire fonctionner avec le protocole IPv6. La méthode de travail basée sur divers tutoriel, exemples à ne pas, au lieu de produire une erreur ce qui suggère que l'adresse est déjà en cours d'utilisation. Je suis à la recherche de l'aide pour résoudre ce de personnes ayant de l'expérience avec le protocole IPv6 de la programmation réseau.
Code correspondant est à http://git.berlios.de/cgi-bin/gitweb.cgi?p=gpsd;a=blob;f=gpsd.c;h=ee2156caf03ca23405f57f3e04e9ef306a75686f;hb=HEAD
Ce code fonctionne correctement dans les deux -G et non G cas sous IPv4, comme c'est facile à vérifier avec la commande netstat -l.
Maintenant, regardez autour ligne 398 après "cas AF_INET6:". Le listen_global option est définie par G; si la valeur est false, le code de la réussite. Il y a présentement un commentaire suivant, hérité d'un inconnu contributeur, qui se lit comme suit:
/* else */
/* BAD: sat.sa_in6.sin6_addr = in6addr_any;
* the simple assignment will not work (except as an initializer)
* because sin6_addr is an array not a simple type
* we could do something like this:
* memcpy(sat.sa_in6.sin6_addr, in6addr_any, sizeof(sin6_addr));
* BUT, all zeros is IPv6 wildcard, and we just zeroed the array
* so really nothing to do here
*/
Selon diverses tutoriel exemples que j'ai regardé, l'affectation "sat.sa_in6.sin6_addr = in6addr_any;" est (malgré le commentaire) correct, et il n'a compiler. Toutefois, le démarrage avec -G échoue revendication de l'écouter adresse est déjà en cours d'utilisation.
Est l'affectation "sat.sa_in6.sin6_addr = in6addr_any;" théoriquement correct ici? Quoi d'autre, si quelque chose, qui me manque?
OriginalL'auteur ESR | 2011-09-19
Vous devez vous connecter pour publier un commentaire.
La raison pour laquelle l'adresse est déjà en cours d'utilisation est parce que sur de nombreux réseaux IPv6 piles, par défaut, une socket IPv6 va écouter à la fois IPv4 et IPv6 en même temps. Des connexions IPv4 seront traitées de manière transparente et mappé à un sous-ensemble de l'IPv6 de l'espace. Toutefois, cela signifie que vous ne peut pas se lier à une socket IPv6 sur le même port que l'IPv4 socket sans changer les paramètres sur le socket IPv6. Un sens?
Viens de le faire avant votre appel à
bind
(ceci est pris à partir d'un de mes projets):Malheureusement, il n'existe pas de valeur par défaut sur les plates-formes pour
IPV6_V6ONLY
-- ce qui signifie essentiellement que vous avez toujours besoin de l'activer ou de désactiver explicitement si vous les aimez, à moins que vous ne vous souciez pas des autres plates-formes. Linux laisse par défaut, Windows le laisse activé par défaut...Votre réponse est correcte et mon bug est corrigé. Je vous remercie.
OriginalL'auteur Dietrich Epp
D'un coup d'oeil au hasard Linux système de fichiers à inclure,
in6addr_any
est déclarée comme suit:Alors, peut-être la proximité de la
INIT
tableau de confondre celui qui la gauche que le commentaire de la DSGP sources. Le type réel est clairementstruct in6_addr
, qui est cessible.Je n'ai regardez autour de vous, et a constaté que certains indices donnent à penser que si l'IPv4 est déjà à l'écoute de "tout" adresse IPv6 ne peuvent pas également. Peut-être que c'est ce qui est à vous mordre.
OriginalL'auteur unwind