Connect returns EINPROGRESS

Cathy Almond cathya at isc.org
Wed Aug 19 14:36:31 UTC 2009


Hi Kalpesh,

Isn't the explanation already clear in the code comments?

* HP-UX "fails" to connect a UDP socket and sets errno to
* EINPROGRESS if it's non-blocking.  We'd rather regard this as
* a success and let the user detect it if it's really an error
* at the time of sending a packet on the socket.
*/

A non-blocking connect() call on a UDP socket doesn't have anything to
do except to put the destination address and port into the socket
structure (unlike TCP which is going to try to establish the connection
by starting the 3-way handshake).

So why would a UDP non-blocking connect() return EINPROGRESS at all?  It
should either succeed or fail?  Per the comments, EINPROGRESS is treated
as 'success' here for the special case that the HP-UX connect() call was
seen to be returning that status instead of 'success' directly.

The comments also explain that no additional code path has been added to
cover the situation where EINPROGRESS might actually mean 'fail' (this
is unexpected anyway), but in that case the failure to send (this will
return EDESTADDRREQ) is where any connect() problem is eventually trapped.

Cathy

kalpesh varyani wrote:
> Hi all,
> 
>  I am using HPUX 11.23 and looking into the socket.c code of bind-9.4.3-P3.
> 
>  Following is the code for isc_socket_connect() in the file:
> 
> isc_result_t
> isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
>                   isc_task_t *task, isc_taskaction_t action, const void
> *arg)
> {
> 
> ::
>        /*
>         * Try to do the connect right away, as there can be only one
>         * outstanding, and it might happen to complete.
>         */
>        sock->address = *addr;
>        cc = connect(sock->fd, &addr->type.sa, addr->length);
>        if (cc < 0) {
> 
> *               /*
>                 * HP-UX "fails" to connect a UDP socket and sets errno to
>                 * EINPROGRESS if it's non-blocking.  We'd rather regard this
> as
>                 * a success and let the user detect it if it's really an
> error
>                 * at the time of sending a packet on the socket.
>                 */
>                if (sock->type == isc_sockettype_udp && errno == EINPROGRESS)
> {
>                        cc = 0;
>                        goto success;
>                }*
> 
>                if (SOFT_ERROR(errno) || errno == EINPROGRESS)
>                        goto queue;
> ::
>        /*
>         * If connect completed, fire off the done event.
>         */
> success:
>        if (cc == 0) {
>                sock->connected = 1;
>                sock->bound = 1;
>                dev->result = ISC_R_SUCCESS;
>                isc_task_send(task, (isc_event_t **)&dev);
> 
>                UNLOCK(&sock->lock);
>                return (ISC_R_SUCCESS);
>        }
> 
>  queue:
>  ....
>  ....
>        /*
>         * Poke watcher here.  We still have the socket locked, so there
>         * is no race condition.  We will keep the lock for such a short
>         * bit of time waking it up now or later won't matter all that much.
>         */
>        if (sock->connect_ev == NULL)
>                select_poke(manager, sock->fd, SELECT_POKE_CONNECT);
> 
>        sock->connect_ev = dev;
> 
>        UNLOCK(&sock->lock);
>        return (ISC_R_SUCCESS);
> 
> 
> 
> I am noticing a strange code path here (marked in blue).My question here is,
> why does the
> success path being executed when errno is EINPROGRESS ?
> 
> Probably the answer is already given in the comments(/*HPUX "fails" ....*/),
> but I am not able to
> understand the implications. Could someone please explain why EINPROGRESS is
> treated as a success
> case.
> I see the query failing initially when errno is EINPROGRESS and after
> retrying after 2 sec
> it succeeds somehow. Could someone explain this behavior.
> 
> Thanks in advance,
> Kalpesh.
> 



More information about the bind-users mailing list