Home | History | Annotate | Line # | Download | only in util
      1 /*	$NetBSD: timed_connect.c,v 1.2 2017/02/14 01:16:49 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	timed_connect 3
      6 /* SUMMARY
      7 /*	connect operation with timeout
      8 /* SYNOPSIS
      9 /*	#include <sys/socket.h>
     10 /*	#include <timed_connect.h>
     11 /*
     12 /*	int	timed_connect(fd, buf, buf_len, timeout)
     13 /*	int	fd;
     14 /*	struct sockaddr	*buf;
     15 /*	int	buf_len;
     16 /*	int	timeout;
     17 /* DESCRIPTION
     18 /*	timed_connect() implement a BSD socket connect() operation that is
     19 /*	bounded in time.
     20 /*
     21 /*	Arguments:
     22 /* .IP fd
     23 /*	File descriptor in the range 0..FD_SETSIZE. This descriptor
     24 /*	must be set to non-blocking mode prior to calling timed_connect().
     25 /* .IP buf
     26 /*	Socket address buffer pointer.
     27 /* .IP buf_len
     28 /*	Size of socket address buffer.
     29 /* .IP timeout
     30 /*	The deadline in seconds. This must be a number > 0.
     31 /* DIAGNOSTICS
     32 /*	Panic: interface violations.
     33 /*	When the operation does not complete within the deadline, the
     34 /*	result value is -1, and errno is set to ETIMEDOUT.
     35 /*	All other returns are identical to those of a blocking connect(2)
     36 /*	operation.
     37 /* WARNINGS
     38 /* .ad
     39 /* .fi
     40 /*	A common error is to call timed_connect() without enabling
     41 /*	non-blocking I/O on the socket. In that case, the \fItimeout\fR
     42 /*	parameter takes no effect.
     43 /* LICENSE
     44 /* .ad
     45 /* .fi
     46 /*	The Secure Mailer license must be distributed with this software.
     47 /* AUTHOR(S)
     48 /*	Wietse Venema
     49 /*	IBM T.J. Watson Research
     50 /*	P.O. Box 704
     51 /*	Yorktown Heights, NY 10598, USA
     52 /*--*/
     53 
     54 /* System library. */
     55 
     56 #include <sys_defs.h>
     57 #include <sys/socket.h>
     58 #include <errno.h>
     59 
     60 /* Utility library. */
     61 
     62 #include "msg.h"
     63 #include "iostuff.h"
     64 #include "sane_connect.h"
     65 #include "timed_connect.h"
     66 
     67 /* timed_connect - connect with deadline */
     68 
     69 int     timed_connect(int sock, struct sockaddr *sa, int len, int timeout)
     70 {
     71     int     error;
     72     SOCKOPT_SIZE error_len;
     73 
     74     /*
     75      * Sanity check. Just like with timed_wait(), the timeout must be a
     76      * positive number.
     77      */
     78     if (timeout <= 0)
     79 	msg_panic("timed_connect: bad timeout: %d", timeout);
     80 
     81     /*
     82      * Start the connection, and handle all possible results.
     83      */
     84     if (sane_connect(sock, sa, len) == 0)
     85 	return (0);
     86     if (errno != EINPROGRESS)
     87 	return (-1);
     88 
     89     /*
     90      * A connection is in progress. Wait for a limited amount of time for
     91      * something to happen. If nothing happens, report an error.
     92      */
     93     if (write_wait(sock, timeout) < 0)
     94 	return (-1);
     95 
     96     /*
     97      * Something happened. Some Solaris 2 versions have getsockopt() itself
     98      * return the error, instead of returning it via the parameter list.
     99      */
    100     error = 0;
    101     error_len = sizeof(error);
    102     if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *) &error, &error_len) < 0)
    103 	return (-1);
    104     if (error) {
    105 	errno = error;
    106 	return (-1);
    107     }
    108 
    109     /*
    110      * No problems.
    111      */
    112     return (0);
    113 }
    114