Paramètre IPv4/IPv6, l'adresse et le port d'un sockaddr_storage structure

Je suis le portage d'une IPv4 application à un AF-indépendant de la base de code(il devrait travailler avec les protocoles IPv4 et IPv6). Maintenant, je suis en utilisant sockaddr_storage partout où je peux, cependant maintenant, je dois mettre(remplir) une sockaddr_storage. Mais je ne sais pas quelle est la manière correcte est. Le code précédent a été de:

//defined in data_socket.h
struct sockaddr_in laddr;

Maintenant il y a cette fonction qui définit sin_addr et sin_port:

void DataSocket::SetLocalAddr(const char *addr, const int port)
{
    this->laddr.sin_port = htons(port);
    if(addr != NULL)
        this->laddr.sin_addr.s_addr = inet_addr(addr);
    else
        this->laddr.sin_addr.s_addr = inet_addr("0.0.0.0");
}

Comme vous le voyez c'est le style ancien(utilise IPv4).

Maintenant, mes modifications sont ci-dessous. Tout d'abord j'ai changé sockaddr_in à sockaddr_storage

//defined in data_socket.h
struct sockaddr_storage laddr;

Puis j'ai changé le code ci-dessus à l'appui de IPv4 et IPv6:

void DataSocket::SetLocalAddr(const char *addr, const int port)
{ 
switch (this->GetAddrFamily(addr)) {
    case AF_INET:
        (struct sockaddr_in *) this->laddr.sin_port = htons(port);
        if(addr != NULL)
            inet_pton(AF_INET, addr, (struct sockaddr_in *) this->laddr.sin_addr);
        else
            inet_pton(AF_INET, "0.0.0.0", (struct sockaddr_in *) this->laddr.sin_addr);
        break;

    case AF_INET6:
        (struct sockaddr_in6 *) this->laddr.sin6_port = htons(port);
        if(addr != NULL)
            inet_pton(AF_INET6, addr, (struct sockaddr_in6 *) this->laddr.sin6_addr);
        else
            inet_pton(AF_INET6, "0:0:0:0:0:0:0:0", (struct sockaddr_in6 *) this->laddr.sin6_addr);
        break;

    default:
        return NULL;

}

}

GetAddrFamily() est:

int DataSocket::GetAddrFamily(const char *addr)
{
    struct addrinfo hints, *res;
    int status, result;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((status = getaddrinfo(addr, 0, &hints, &res)) != 0)
    {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
        return false;
    }

    result = res->ai_family; //This might be AF_INET, AF_INET6,etc..
    freeaddrinfo(res); //We're done with res, free it up

    return result;
}

Il semble que mon chemin est complexe. Est-ce la bonne façon de le faire? Parce que j'ai changé sockaddr_in à sockaddr_storage, en fait je veux juste l'inverse de cette question: Obtenir de l'adresse IPV4 à partir d'une structure sockaddr

J'essaie de trouver la meilleure solution, par exemple ici: http://www.kame.net/newsletter/19980604/ il déclare ne jamais utiliser inet_ntop() et inet_pton(), cependant, certains d'autres(comme le Beej du réseau tutoriel) dit que inet_ntop() et inet_pton() doit être utilisé pour IPv6 en fonction de l'application.

Est ma façon de la mise en œuvre correcte ou dois-je le changer?

C'est une des raisons pourquoi j'aime boost::asio::ip::address, il les résumés loin boost::asio::ip::address_v4 et boost::asio::ip::address_v6.
Laissez-moi savoir lors de la C des gains de fonctions membres.
oups désolé pour le c tag

OriginalL'auteur Fatih Arslan | 2012-07-12