source: npl/overig/netcat_openbsd/patches/0002-connect-timeout.patch @ 072d3d5

gcc484perl-5.22
Last change on this file since 072d3d5 was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 3.4 KB
  • netcat.c

    From: Aron Xu <aron@debian.org>
    Date: Mon, 13 Feb 2012 14:43:56 +0800
    Subject: connect timeout
    
    ---
     netcat.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
     1 file changed, 75 insertions(+), 2 deletions(-)
    
    diff --git a/netcat.c b/netcat.c
    index 9b2def2..f3cc8c1 100644
    a b  
    106106#define PORT_MAX_LEN    6
    107107#define UNIX_DG_TMP_SOCKET_SIZE 19
    108108
     109#define CONNECTION_SUCCESS 0
     110#define CONNECTION_FAILED 1
     111#define CONNECTION_TIMEOUT 2
     112
    109113/* Command Line Options */
    110114int     dflag;                                  /* detached, no stdin */
    111115unsigned int iflag;                             /* Interval Flag */
    void set_common_sockopts(int); 
    151155int     map_tos(char *, int *);
    152156void    usage(int);
    153157
     158static int connect_with_timeout(int fd, const struct sockaddr *sa,
     159        socklen_t salen, int ctimeout);
     160
    154161int
    155162main(int argc, char *argv[])
    156163{
    remote_connect(const char *host, const char *port, struct addrinfo hints) 
    651658
    652659                set_common_sockopts(s);
    653660
    654                 if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
     661                if ((error = connect_with_timeout(s, res0->ai_addr, res0->ai_addrlen, timeout))== CONNECTION_SUCCESS)
    655662                        break;
    656                 else if (vflag)
     663                else if (vflag && error == CONNECTION_FAILED)
    657664                        warn("connect to %s port %s (%s) failed", host, port,
    658665                            uflag ? "udp" : "tcp");
     666                else if (vflag && error == CONNECTION_TIMEOUT)
     667                    warn("connect to %s port %s (%s) timed out", host, port,
     668                            uflag ? "udp" : "tcp");
    659669
    660670                close(s);
    661671                s = -1;
    timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) 
    703713        return (ret);
    704714}
    705715
     716static int connect_with_timeout(int fd, const struct sockaddr *sa,
     717                                socklen_t salen, int ctimeout)
     718{
     719        int err;
     720        struct timeval tv, *tvp = NULL;
     721        fd_set connect_fdset;
     722        socklen_t len;
     723        int orig_flags;
     724
     725        orig_flags = fcntl(fd, F_GETFL, 0);
     726        if (fcntl(fd, F_SETFL, orig_flags | O_NONBLOCK) < 0 ) {
     727                warn("can't set O_NONBLOCK - timeout not available");
     728                if (connect(fd, sa, salen) == 0)
     729                        return CONNECTION_SUCCESS;
     730                else
     731                        return CONNECTION_FAILED;
     732        }
     733
     734        /* set connect timeout */
     735        if (ctimeout > 0) {
     736                tv.tv_sec = (time_t)ctimeout/1000;
     737                tv.tv_usec = 0;
     738                tvp = &tv;
     739        }
     740
     741        /* attempt the connection */
     742        err = connect(fd, sa, salen);
     743        if (err != 0 && errno == EINPROGRESS) {
     744                /* connection is proceeding
     745                 * it is complete (or failed) when select returns */
     746
     747                /* initialize connect_fdset */
     748                FD_ZERO(&connect_fdset);
     749                FD_SET(fd, &connect_fdset);
     750
     751                /* call select */
     752                do {
     753                        err = select(fd + 1, NULL, &connect_fdset,
     754                                     NULL, tvp);
     755                } while (err < 0 && errno == EINTR);
     756
     757                /* select error */
     758                if (err < 0)
     759                        errx(1,"select error: %s", strerror(errno));
     760                /* we have reached a timeout */
     761                if (err == 0)
     762                        return CONNECTION_TIMEOUT;
     763                /* select returned successfully, but we must test socket
     764                 * error for result */
     765                len = sizeof(err);
     766                if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
     767                        errx(1, "getsockopt error: %s", strerror(errno));
     768                /* setup errno according to the result returned by
     769                 * getsockopt */
     770                if (err != 0)
     771                        errno = err;
     772        }
     773
     774        /* return aborted if an error occured, and valid otherwise */
     775        fcntl(fd, F_SETFL, orig_flags);
     776        return (err != 0)? CONNECTION_FAILED : CONNECTION_SUCCESS;
     777}
     778
    706779/*
    707780 * local_listen()
    708781 * Returns a socket listening on a local port, binds to specified source
Note: See TracBrowser for help on using the repository browser.