瀏覽代碼

- tcp sigio_rt workarround for undocumented event 0x08 (which seems to be set
on some errors, like receiving a RST)

Andrei Pelinescu-Onciul 20 年之前
父節點
當前提交
8d7f99dd0f
共有 3 個文件被更改,包括 42 次插入7 次删除
  1. 1 1
      Makefile.defs
  2. 25 2
      io_wait.h
  3. 16 4
      test/udp_flood.c

+ 1 - 1
Makefile.defs

@@ -59,7 +59,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev16-tcp
+EXTRAVERSION = -dev17-tcp
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")

+ 25 - 2
io_wait.h

@@ -714,9 +714,23 @@ again:
 				goto error;
 			}
 		}
+#if 0
+		if (n>1){
+			for(r=0; r<n; r++){
+				LOG(L_ERR, "WARNING: ep_array[%d]= %x, %p\n",
+						r, h->ep_array[r].events, h->ep_array[r].data.ptr);
+			}
+		}
+#endif
 		for (r=0; r<n; r++){
-			while((handle_io((struct fd_map*)h->ep_array[r].data.ptr, -1)>0)
+			if (h->ep_array[r].events & (EPOLLIN|EPOLLERR|EPOLLHUP)){
+				while((handle_io((struct fd_map*)h->ep_array[r].data.ptr,-1)>0)
 					&& repeat);
+			}else{
+				LOG(L_ERR, "ERROR:io_wait_loop_epoll: unexpected event %x"
+							" on %d/%d, data=%p\n", h->ep_array[r].events,
+							r+1, n, h->ep_array[r].data.ptr);
+			}
 		}
 error:
 	return n;
@@ -842,13 +856,22 @@ again:
 					(unsigned)sigio_band,
 					sigio_fd);
 #endif
-			if (sigio_band&(POLL_IN|POLL_ERR)){
+			/* on some errors (e.g. when receving TCP RST), sigio_band will
+			 * be set to 0x08 (undocumented, no corresp. POLL_xx), so better
+			 * catch all events --andrei */
+			if (sigio_band/*&(POLL_IN|POLL_ERR|POLL_HUP)*/){
 				fm=get_fd_map(h, sigio_fd);
 				/* we can have queued signals generated by fds not watched
 			 	 * any more, or by fds in transition, to a child 
 				 * => ignore them */
 				if (fm->type)
 					handle_io(fm, -1);
+				else
+					LOG(L_ERR, "WARNING: io_wait_loop_sigio_rt: ignoring event"
+							"%x on fd %d\n", sigio_band, sigio_fd);
+			}else{
+				LOG(L_ERR, "ERROR: io_wait_loop_sigio_rt: unexpected event"
+							" on fd %d: %x\n", sigio_fd, sigio_band);
 			}
 		}
 	}else{

+ 16 - 4
test/udp_flood.c

@@ -44,6 +44,7 @@
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
+#include <signal.h>
 
 
 static char *id="$Id$";
@@ -94,6 +95,7 @@ int main (int argc, char** argv)
 	int t;
 	struct linger t_linger;
 	int k;
+	int err;
 	
 	/* init */
 	count=0;
@@ -107,6 +109,7 @@ int main (int argc, char** argv)
 	tcp=0;
 	tcp_rst=0;
 	con_no=1;
+	err=0;
 
 	opterr=0;
 	while ((c=getopt(argc,argv, "f:c:d:p:s:t:n:rTRvhV"))!=-1){
@@ -215,6 +218,12 @@ int main (int argc, char** argv)
 	}
 	if (!tcp) con_no=1;
 	
+	/* ignore sigpipe */
+	if (signal(SIGPIPE, SIG_IGN)==SIG_ERR){
+		fprintf(stderr, "failed to ignore SIGPIPE: %s\n", strerror(errno));
+		exit(-1);
+	}
+	
 	/* open packet file */
 	fd=open(fname, O_RDONLY);
 	if (fd<0){
@@ -277,8 +286,8 @@ int main (int argc, char** argv)
 		for (r=0; r<count; r++){
 			if ((verbose>1)&&((r%1000)==999)){  putchar('.'); fflush(stdout); }
 			if (send(sock, buf, n, 0)==-1) {
-				fprintf(stderr, "Error: send: %s\n",  strerror(errno));
-				exit(1);
+				fprintf(stderr, "Error(%d): send: %s\n", err, strerror(errno));
+				err++;;
 			}
 			if (usec){
 				t--;
@@ -296,13 +305,16 @@ int main (int argc, char** argv)
 	if (tcp){
 		printf("\n%d packets sent on %d tcp connections (%d on each of them),"
 				" %d bytes each => total %d bytes\n",
-				count*con_no, con_no, count, n, con_no*n*count);
+				count*con_no-err, con_no, count, n,
+				(con_no*count-err)*n);
 	}else{
 		printf("\n%d packets sent, %d bytes each => total %d bytes\n",
-				count, n, n*count);
+				count-err, n, n*(count-err));
 	}
+	if (err) printf("%d errors\n", err);
 	exit(0);
 
 error:
+	fprintf(stderr, "exiting due to error (%s)\n", strerror(errno));
 	exit(-1);
 }