[ds6-devel] nc6/src connection.c,1.7,1.8 connection.h,1.3,1.4 io_stream.c,1.6,1.7 misc.c,1.9,1.10 misc.h,1.10,1.11 network.c,1.19,1.20 parser.c,1.14,1.15

chris@deepspace6.net chris@deepspace6.net
Sat Dec 28 20:54:24 2002


Update of /cvs/nc6/src

Modified Files:
	connection.c connection.h io_stream.c misc.c misc.h network.c 
	parser.c 
Log Message:
Added timeout support for connects/accepts (only simple testing done).
Added a "-t sec" option to enable it.


Index: connection.c
===================================================================
RCS file: /cvs/nc6/src/connection.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- connection.c	24 Dec 2002 21:05:37 -0000	1.7
+++ connection.c	28 Dec 2002 20:54:22 -0000	1.8
@@ -47,6 +47,9 @@
 
 	/* the local stream has an infinite hold timeout by default */
 	ios_set_hold_timeout(&(attrs->local_stream), -1);
+
+	/* no connect timeout */
+	attrs->connect_timeout = -1;
 }
 
 
Index: connection.h
===================================================================
RCS file: /cvs/nc6/src/connection.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- connection.h	24 Dec 2002 19:50:56 -0000	1.3
+++ connection.h	28 Dec 2002 20:54:22 -0000	1.4
@@ -23,6 +23,7 @@
 
 #include "io_stream.h"
 #include <netdb.h>
+#include <sys/time.h>
 
 typedef enum sock_type_t {
 	TCP_SOCKET,
@@ -49,6 +50,7 @@
 	address local_address;
 	io_stream remote_stream;
 	io_stream local_stream;
+	time_t connect_timeout;
 } connection_attributes;
 
 
Index: io_stream.c
===================================================================
RCS file: /cvs/nc6/src/io_stream.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- io_stream.c	24 Dec 2002 21:05:37 -0000	1.6
+++ io_stream.c	28 Dec 2002 20:54:22 -0000	1.7
@@ -28,13 +28,10 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <unistd.h>
-#include <fcntl.h>
 
 RCSID("@(#) $Header$");
 
 
-/* static void nonblock(int fd); */
-
 
 void io_stream_init(io_stream *ios)
 {
@@ -163,21 +160,3 @@
 
 	return tv;
 }
-
-
-
-/*
-static void nonblock(int fd)
-{
-	int arg;
-	if ((arg = fcntl(fd, F_GETFL, 0)) < 0)
-		fatal("error reading file descriptor flags: %s",
-		      strerror(errno));
-
-	arg |= O_NONBLOCK;
-
-	if (fcntl(fd, F_SETFL, arg) < 0)
-		fatal("error setting flag O_NONBLOCK on file descriptor",
-		      strerror(errno));
-}
-*/
Index: misc.c
===================================================================
RCS file: /cvs/nc6/src/misc.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- misc.c	24 Dec 2002 20:20:31 -0000	1.9
+++ misc.c	28 Dec 2002 20:54:22 -0000	1.10
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#include <fcntl.h>
 #ifdef HAVE_STRTOL
 #include <errno.h>
 #include <limits.h>
@@ -89,6 +90,22 @@
 	/* we should use srtlcpy here instead of strcpy */
 	strcpy(nstr, str);
 	return nstr;
+}
+
+
+
+void nonblock(int fd)
+{
+	int arg;
+	if ((arg = fcntl(fd, F_GETFL, 0)) < 0)
+		fatal("error reading file descriptor flags: %s",
+		      strerror(errno));
+
+	arg |= O_NONBLOCK;
+
+	if (fcntl(fd, F_SETFL, arg) < 0)
+		fatal("error setting flag O_NONBLOCK on file descriptor",
+		      strerror(errno));
 }
 
 
Index: misc.h
===================================================================
RCS file: /cvs/nc6/src/misc.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- misc.h	24 Dec 2002 20:20:31 -0000	1.10
+++ misc.h	28 Dec 2002 20:54:22 -0000	1.11
@@ -41,6 +41,8 @@
 void *xmalloc(size_t size);
 char *xstrdup(const char* str);
 
+void nonblock(int fd);
+
 #ifdef HAVE_STRTOL
 int safe_atoi(const char *str);
 #else
Index: network.c
===================================================================
RCS file: /cvs/nc6/src/network.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- network.c	28 Dec 2002 19:01:41 -0000	1.19
+++ network.c	28 Dec 2002 20:54:22 -0000	1.20
@@ -142,6 +142,9 @@
 
 	/* try connecting to any of the addresses returned by getaddrinfo */
 	for (ptr = res; ptr != NULL; ptr = ptr->ai_next) {
+		struct timeval tv, *tvp = NULL;
+		fd_set connect_fdset;
+		socklen_t len;
 
 		/* only accept socktypes we can handle */
 		if (ptr->ai_socktype != SOCK_STREAM &&
@@ -228,7 +231,8 @@
 			err = getaddrinfo(local->address, local->service,
 			                  &hints, &src_res);
 			if (err != 0)
-				fatal("forward host lookup failed for source address %s: %s",
+				fatal("forward host lookup failed "
+				      "for source address %s: %s",
 				      local->address, gai_strerror(err));
 
 			/* check the results of getaddrinfo */
@@ -252,7 +256,8 @@
 				
 				if (is_flag_set(VERBOSE_MODE) == TRUE) {
 					warn("bind to source addr/port failed "
-					     "when connecting %s [%s] %s (%s): %s",
+					     "when connecting "
+					     "%s [%s] %s (%s): %s",
 					      hbuf_rev, hbuf_num,
 					      sbuf_num, sbuf_rev,
 					      strerror(errno));
@@ -265,14 +270,62 @@
 
 			freeaddrinfo(src_res);
 		}
+
+		/* set connect timeout */
+		if (attrs->connect_timeout > 0) {
+			tv.tv_sec = attrs->connect_timeout;
+			tv.tv_usec = 0;
+			tvp = &tv;
+		}
+
+		/* set fd to nonblocking */
+		nonblock(fd);
 		
-		/* perform the connection */
+		/* attempt the connection */
 		err = connect(fd, ptr->ai_addr, ptr->ai_addrlen);
+		if (err != 0 && errno == EINPROGRESS) {
+			/* connection is proceeding
+			 * it is complete (or failed) when select returns */
+
+			/* initialize connect_fdset */
+			FD_ZERO(&connect_fdset);
+			FD_SET(fd, &connect_fdset);
+
+			/* call select */
+			do {
+				err = select(
+					fd+1, NULL, &connect_fdset, NULL, tvp);
+			} while (err < 0 && errno == EINTR);
+
+			if (err < 0)
+				fatal("select error: %s", strerror(errno));
+			if (err == 0) {
+				/* connection timed out */
+				if (is_flag_set(VERBOSE_MODE) == TRUE) {
+					warn("%s [%s] %s (%s): "
+					     "connect timed out",
+					     hbuf_rev, hbuf_num,
+					     sbuf_num, sbuf_rev);
+				}
+				close(fd);
+				fd = -1;
+				continue;
+			}
+			
+			/* select returned - test socket error for result */
+			len = sizeof(err);
+			if (getsockopt(fd, SOL_SOCKET,SO_ERROR, &err, &len) < 0)
+				fatal("getsockopt error: %s", strerror(errno));
+			if (err != 0)
+				errno = err;
+		}
 		if (err != 0) {
+			/* connection failed */
 			if (is_flag_set(VERBOSE_MODE) == TRUE) {
 				warn("%s [%s] %s (%s): %s",
 				     hbuf_rev, hbuf_num,
-				     sbuf_num, sbuf_rev, strerror(errno));
+				     sbuf_num, sbuf_rev,
+				     strerror(errno));
[...30 lines suppressed...]
Index: parser.c
===================================================================
RCS file: /cvs/nc6/src/parser.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- parser.c	24 Dec 2002 21:05:37 -0000	1.14
+++ parser.c	28 Dec 2002 20:54:22 -0000	1.15
@@ -56,7 +56,7 @@
 	opterr = 0;
 
 	/* option recognition loop */
-	while ((c = getopt(argc, argv, "46hlnp:q:s:uvx")) >= 0) {
+	while ((c = getopt(argc, argv, "46hlnp:q:s:t:uvx")) >= 0) {
  		switch(c) {
 		case '4':
 			if (attrs->proto != PROTO_UNSPECIFIED) 
@@ -95,6 +95,9 @@
 		case 's':	
 			attrs->local_address.address = xstrdup(optarg);
 			break;	
+		case 't':
+			attrs->connect_timeout = safe_atoi(optarg);
+			break;
 		case 'u':	
 			attrs->type = UDP_SOCKET;
 			break;
@@ -198,6 +201,7 @@
 "    -p port    Local source port\n"
 "    -q n1[:n2] Hold timeouts\n"
 "    -s addr    Local source address\n"
+"    -t sec     Timeout for connects/accepts\n"
 "    -u         Require use of UDP\n"
 "    -v         Increase program verbosity (call twice for max verbosity)\n"
 "    -x         File transfer mode\n\n");



More information about the ds6-devel mailing list