source:
npl/overig/netcat_openbsd/patches/0002-connect-timeout.patch
@
072d3d5
Last change on this file since 072d3d5 was c5c522c, checked in by , 8 years ago | |
---|---|
|
|
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 106 106 #define PORT_MAX_LEN 6 107 107 #define UNIX_DG_TMP_SOCKET_SIZE 19 108 108 109 #define CONNECTION_SUCCESS 0 110 #define CONNECTION_FAILED 1 111 #define CONNECTION_TIMEOUT 2 112 109 113 /* Command Line Options */ 110 114 int dflag; /* detached, no stdin */ 111 115 unsigned int iflag; /* Interval Flag */ … … void set_common_sockopts(int); 151 155 int map_tos(char *, int *); 152 156 void usage(int); 153 157 158 static int connect_with_timeout(int fd, const struct sockaddr *sa, 159 socklen_t salen, int ctimeout); 160 154 161 int 155 162 main(int argc, char *argv[]) 156 163 { … … remote_connect(const char *host, const char *port, struct addrinfo hints) 651 658 652 659 set_common_sockopts(s); 653 660 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) 655 662 break; 656 else if (vflag )663 else if (vflag && error == CONNECTION_FAILED) 657 664 warn("connect to %s port %s (%s) failed", host, port, 658 665 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"); 659 669 660 670 close(s); 661 671 s = -1; … … timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) 703 713 return (ret); 704 714 } 705 715 716 static 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 706 779 /* 707 780 * local_listen() 708 781 * Returns a socket listening on a local port, binds to specified source
Note: See TracBrowser
for help on using the repository browser.