On 02/19/2010 01:21 PM, Gerd Hoffmann wrote:
>
> Signed-off-by: Gerd Hoffmann<kra...@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);
>           }

_______________________________________________
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel

Reply via email to