cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: a non-blocking IPv6 connect problem

From: Bjorn Reese <breese_at_mail1.stofanet.dk>
Date: Tue, 02 Oct 2001 16:29:52 +0000

Forgot to cc: the mailinglist (why isn't reply-to set?)

-------- Original Message --------
Subject: Re: a non-blocking IPv6 connect problem
Date: Tue, 02 Oct 2001 16:28:40 +0000
From: Bjorn Reese <breese_at_mail1.stofanet.dk>
Organization: Hyperspace Academy
To: Daniel Stenberg <daniel_at_haxx.se>
References: <Pine.GSO.4.33.0110021319110.17209-100000_at_pm1.contactor.se>

Daniel Stenberg wrote:

> However, I'm experiencing some problems with my IPv6 support for non-blocking
> connects. The problem is that when I attempt a connect() to a non-listening
> (IPv4-) port and get -1 returned, I would assume that I'd get ECONNREFUSED in
> errno, but I don't!
>
> Instead, I get EINPROGRESS which serves as an indication that a connection is
> being made (asynchronously). I even get a positive return from select()
> afterwards (it indicates that the socket becomes writable) as an indication
> of a successful connection...!

IIRC (and I am a little rusty on this) this is expected behaviour. If
a connection cannot be established or rejected instanteniously then
EINPROGRESS is returned. It seems that the IPv6 supports is causing a
delay in your test setup, which means that it cannot determine the
state of the connection immediately.

What you must do is to keep track of whether or not the connection has
been established (or rejected). If select() says that the socket is
readable, and you have not established the connection yet, then you must
retrieve the error code from the socket. If it is 0 (zero) or EISCONN
then the connection has been successfully established, otherwise it has
been rejected and the error code will tell you why.

Retrieving the error code from the socket is done with getsockopt(), but
requires a little workaround like this:

  int GetSocketError(int handle) {
    int error_code = 0;
    int error_code_size = sizeof(error_code);
    /*
     * Some platforms will return 0 and error_code set to the pending error,
     * others will return -1 and errno set to the pending error.
     */
    if (getsockopt(handle, SOL_SOCKET, SO_ERROR, (char *)error_code,
&error_code_size) == -1)
      error_code = errno;
    return error_code;
  }

I believe this does the trick. For a full example see the Triacle code
(socket.c / SocketCallbackConnecting & SocketGetError)
Received on 2001-10-02