[Spice-devel] [PATCH 2/2] spice client: add ipv6 support.

Uri Lublin uril at redhat.com
Sun Feb 21 04:44:56 PST 2010


On 02/19/2010 01:21 PM, Gerd Hoffmann wrote:
>
> Signed-off-by: Gerd Hoffmann<kraxel at redhat.com>
> ---
>   client/red_peer.cpp |   89 +++++++++++++++++++++++---------------------------
>   1 files changed, 41 insertions(+), 48 deletions(-)
>
> diff --git a/client/red_peer.cpp b/client/red_peer.cpp
> index f252ef2..a6afcc2 100644
> --- a/client/red_peer.cpp
> +++ b/client/red_peer.cpp
> @@ -69,60 +69,53 @@ void RedPeer::cleanup()
>       }
>   }
>
> -uint32_t RedPeer::host_by_name(const char* host)
> +void RedPeer::connect_unsecure(const char* host, int portnr)
>   {
> -    struct addrinfo *result = NULL;
> -    struct sockaddr_in *addr;
> -    uint32_t return_value;
> -    int rc;
> -
> -    rc = getaddrinfo(host, NULL, NULL,&result);
> -    while (result != NULL&&  result->ai_family != PF_INET)
> -        result = result->ai_next;
> -    if (rc != 0 || result == NULL) {
> -        THROW_ERR(SPICEC_ERROR_CODE_GETHOSTBYNAME_FAILED, "cannot resolve host address %s", host);
> -    }
> -
> -    addr = (sockaddr_in *)result->ai_addr;
> -    return_value = addr->sin_addr.s_addr;
> -
> -    freeaddrinfo(result);
> -
> -    DBG(0, "%s = %u", host, return_value);
> -    return ntohl(return_value);
> -}
> -
> -void RedPeer::connect_unsecure(const char* host, int port)
> -{
> -    struct sockaddr_in addr;
> -    int no_delay;
> -    uint32_t ip;
> +    struct addrinfo ai, *result = NULL, *e;
> +    char uaddr[INET6_ADDRSTRLEN+1];
> +    char uport[33], port[33];
> +    int err = 0, rc, no_delay = 1;
>       ASSERT(_ctx == NULL&&  _ssl == NULL&&  _peer == INVALID_SOCKET);
>       try {
> -        ip = host_by_name(host);
> -
> -        addr.sin_port = htons(port);
> -        addr.sin_family = AF_INET;
> -        addr.sin_addr.s_addr = htonl(ip);
> -
> -        Lock lock(_lock);
> -        if ((_peer = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
> -            int err = sock_error();
> -            THROW_ERR(SPICEC_ERROR_CODE_SOCKET_FAILED, "failed to create socket: %s (%d)",
> -                      sock_err_message(err), err);
> +        memset(&ai,0, sizeof(ai));
> +        ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
> +        ai.ai_family = PF_UNSPEC;
> +        ai.ai_socktype = SOCK_STREAM;
> +        snprintf(port, sizeof(port), "%d", portnr);
> +        rc = getaddrinfo(host, port,&ai,&result);
> +        if (rc != 0) {
> +            THROW_ERR(SPICEC_ERROR_CODE_GETHOSTBYNAME_FAILED, "cannot resolve host address %s", host);
>           }
> +        Lock lock(_lock);
> +        _peer = -1;
> +        for (e = result; e != NULL; e = e->ai_next) {
> +            if ((_peer = socket(e->ai_family, e->ai_socktype, e->ai_protocol)) == INVALID_SOCKET) {
> +                int err = sock_error();
> +                THROW_ERR(SPICEC_ERROR_CODE_SOCKET_FAILED, "failed to create socket: %s (%d)",
> +                          sock_err_message(err), err);
> +            }
> +            if (setsockopt(_peer, IPPROTO_TCP, TCP_NODELAY, (const char*)&no_delay, sizeof(no_delay)) ==
> +                SOCKET_ERROR) {
> +                LOG_WARN("set TCP_NODELAY failed");
> +            }
>
> -        no_delay = 1;
> -        if (setsockopt(_peer, IPPROTO_TCP, TCP_NODELAY, (const char*)&no_delay, sizeof(no_delay)) ==
> -                                                                                     SOCKET_ERROR) {
> -            LOG_WARN("set TCP_NODELAY failed");
> +            getnameinfo((struct sockaddr*)e->ai_addr, e->ai_addrlen,
> +                        uaddr,INET6_ADDRSTRLEN, uport,32,
> +                        NI_NUMERICHOST | NI_NUMERICSERV);
> +            LOG_INFO("Trying %s %s", uaddr, uport);
> +            if (::connect(_peer, e->ai_addr, e->ai_addrlen) == SOCKET_ERROR) {
> +                err = sock_error();
> +                LOG_INFO("Connect failed: %s (%d)",
> +                         sock_err_message(err), err);
> +                closesocket(_peer);
> +                _peer = -1;
> +                continue;
> +            }
> +            LOG_INFO("Connected to %s %s", uaddr, uport);

I think there is a missing "break" here.
If connection was established successfully, we should not continue trying.
(even worse if first trial succeeds but second trial fails, maybe because the 
server is already connected and is not listening anymore).

>           }
> -
> -        LOG_INFO("Connecting %s %d", inet_ntoa(addr.sin_addr), port);
>           lock.unlock();
> -        if (::connect(_peer, (struct sockaddr *)&addr, sizeof(sockaddr_in)) == SOCKET_ERROR) {
> -            int err = sock_error();
> -            closesocket(_peer);
> +        freeaddrinfo(result);
> +        if (_peer == -1) {
>               THROW_ERR(SPICEC_ERROR_CODE_CONNECT_FAILED, "failed to connect: %s (%d)",
>                         sock_err_message(err), err);
>           }



More information about the Spice-devel mailing list