Question

Je travaille actuellement sur une application de socket UDP et je dois intégrer un support permettant aux connexions IPV4 et IPV6 d'envoyer des paquets à un serveur.

J'espérais que quelqu'un pourrait m'aider et me diriger dans la bonne direction; la majorité de la documentation que j'ai trouvée n'était pas complète. Il serait également utile de signaler toute différence entre les sockets Winsock et BSD.

Merci d'avance!

Était-ce utile?

La solution

La meilleure approche consiste à créer un socket de serveur IPv6 pouvant également accepter les connexions IPv4. Pour ce faire, créez un socket IPv6 normal, désactivez l'option de socket IPV6_V6ONLY , associez-la à l'option " any " adresse et commencer à recevoir. Les adresses IPv4 seront présentées sous forme d'adresses IPv6, au format IPv4-mapped .

La principale différence entre les systèmes est de savoir si IPV6_V6ONLY est a) disponible et b) activé ou désactivé par défaut. Il est désactivé par défaut sous Linux (c'est-à-dire, autorise les sockets à double pile sans setsockopt) et est activé sur la plupart des autres systèmes.

De plus, la pile IPv6 sous Windows XP ne prend pas en charge cette option. Dans ce cas, vous devrez créer deux sockets serveur distincts et les placer dans select ou dans plusieurs threads.

Autres conseils

L'API de socket est régie par les RFC IETF et doit être identique sur toutes les plates-formes, y compris Windows WRT IPv6.

Pour les applications IPv4 / IPv6, ALL concerne getaddrinfo () et getnameinfo () . getaddrinfo est un génie - examine le DNS, les noms de port et les capacités du client pour résoudre l'éternelle question de "# 8220; puis-je utiliser IPv4, IPv6 ou les deux pour atteindre une destination particulière?" ; Ou bien, si vous voulez emprunter la route à double pile et renvoyer les adresses IPv6 mappées IPv4, cela se produira également.

Il fournit une structure directe sockaddr * pouvant être insérée dans bind () , recvfrom () , sendto () et la famille d'adresses pour socket () & # 8230; Dans de nombreux cas, cela signifie qu’il n’ya pas de structures sockaddr_in (6) en désordre à compléter et à traiter.

Pour les implémentations UDP, je ferais attention à la définition de sockets à double pile ou, plus généralement, à la liaison à toutes les interfaces ( INADDR_ANY ). Le problème classique est que, lorsque les adresses ne sont pas verrouillées (voir bind () ) et que le système a plusieurs demandes d’interface, les réponses peuvent transiter d’adresses différentes pour des ordinateurs avec plusieurs adresses caprices de la table de routage du système d’exploitation, confusion des protocoles d’application, en particulier des systèmes avec authentification requise.

Pour les implémentations UDP où ce n'est pas un problème, ou TCP, les sockets à double pile peuvent gagner beaucoup de temps lorsque vous activez IPv * sur votre système. Il faut faire attention à ne pas se fier entièrement à la double pile où cela n’est pas absolument nécessaire, car il ne manque pas de plates-formes raisonnables (Old Linux, BSD, Windows 2003) déployées avec des piles IPv6 ne pouvant pas utiliser de sockets à double pile.

Je joue avec cela sous Windows et cela semble effectivement poser un problème de sécurité. Si vous vous liez à l'adresse de bouclage, le socket IPv6 est correctement lié à [:: 1] mais le socket mappé IPv4 est lié à INADDR_ANY, de sorte que votre application (supposément) locale uniquement en toute sécurité est réellement exposée au monde.

Les RFC ne précisent pas vraiment l'existence de l'option de socket IPV6_V6ONLY, mais si elle est absente, les RFC indiquent clairement que l'implémentation doit être comme si cette option était FALSE.

Là où l'option est présente, je dirais qu'elle devrait avoir la valeur FALSE par défaut, mais que, pour des raisons qui ont fait comprendre, les implémentations BSD et Windows ont la valeur TRUE. Il est bizarre d’affirmer qu’il s’agit d’un problème de sécurité puisqu’un programmeur IPv6 non averti pourrait se lier en pensant qu’il se liait uniquement à IN6ADDR_ANY pour IPv6 uniquement et accepter accidentellement une connexion IPv4, posant un problème de sécurité. Je pense que cette idée est à la fois absurde et absurde, en plus de surprendre quiconque s'attend à une implémentation conforme à RFC.

Dans le cas de Windows, la non-conformité ne sera généralement pas une surprise. Dans le cas de BSD, c'est au mieux regrettable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top