2010-10-25 9 views
0

J'essaie de remplacer une API pour qu'elle soit compatible avec IPv4. Fondamentalement, l'API à un stade crée un socket, puis appelle bind() pour ouvrir un port d'écoute. Le port est spécifié en passant un sockaddr retourné par getaddrinfo(), en spécifiant le port dans le paramètre de service. Plus tard, l'appelant a le choix d'assigner un groupe de multidiffusion, en appelant une fonction API qui définit IP_ADD_MEMBERSHIP sur le socket. Le problème est qu'avec IPv6 (c'est-à-dire que l'indice de famille pour getaddrinfo est AF_UNSPEC au lieu de AF_INET comme c'était le cas auparavant), IP_ADD_MEMBERSHIP échoue lorsque l'utilisateur demande un groupe de multidiffusion IPv4. Cela est dû au fait que le système fournit par défaut une adresse IPv6 lorsqu'aucune indication n'est fournie.est-il un moyen de changer la famille d'une socket après lier? (Problème lié à IPv6)

La solution est évidemment de savoir à l'avance si l'utilisateur voudra spécifier un groupe de multidiffusion IPv4 ou IPv6. Cependant, puisque j'essaie de ne pas modifier l'API elle-même, cette information est simplement considérée comme inconnue.

Est-ce que j'ai d'autres options?

J'ai essayé de fermer, de recréer et de relier de nouveau le socket avant IP_ADD_MEMBERSHIP, mais mon second bind() échoue pour une raison quelconque. (J'ai essayé de spécifier SO_REUSEADDR mais cela n'a pas aidé.)

Y at-il un moyen de simplement "délier" un socket et de le relier à une nouvelle famille? Ou juste changer la famille, période?

Répondre

1

Impossible. La solution kludgey habituelle est de garder deux sockets, un pour AF_INET, un pour AF_INET6.