Browse code

- fixed tcp_read_req eof detection (specially crafted tcp connections could cause the tcp reader process to enter eat 100% cpu time, even when it should've slept)

Andrei Pelinescu-Onciul authored on 04/07/2003 14:27:33
Showing 3 changed files
... ...
@@ -40,7 +40,7 @@ export makefile_defs
40 40
 VERSION = 0
41 41
 PATCHLEVEL = 8
42 42
 SUBLEVEL =   12
43
-EXTRAVERSION = dev-t04
43
+EXTRAVERSION = dev-t05
44 44
 
45 45
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
46 46
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -96,6 +96,7 @@
96 96
 
97 97
 struct tcp_child{
98 98
 	pid_t pid;
99
+	int proc_no; /* ser proc_no, for debugging */
99 100
 	int unix_sock; /* unix sock fd, copied from pt*/
100 101
 	int busy;
101 102
 	int n_reqs; /* number of requests serviced so far */
... ...
@@ -651,7 +652,9 @@ static int send2child(struct tcp_connection* tcpconn)
651 651
 				" connection passed to the least busy one (%d)\n",
652 652
 				min_busy);
653 653
 	}
654
-	DBG("send2child: to child %d, %ld\n", idx, (long)tcpconn);
654
+	DBG("send2child: to tcp child %d %d(%d), %p\n", idx, 
655
+					tcp_children[idx].proc_no,
656
+					tcp_children[idx].pid, tcpconn);
655 657
 	send_fd(tcp_children[idx].unix_sock, &tcpconn, sizeof(tcpconn),
656 658
 			tcpconn->s);
657 659
 	
... ...
@@ -1007,6 +1010,7 @@ int tcp_init_children()
1007 1007
 			/* parent */
1008 1008
 			close(sockfd[1]);
1009 1009
 			tcp_children[r].pid=pid;
1010
+			tcp_children[r].proc_no=process_no;
1010 1011
 			tcp_children[r].busy=0;
1011 1012
 			tcp_children[r].n_reqs=0;
1012 1013
 			tcp_children[r].unix_sock=sockfd[0];
... ...
@@ -32,6 +32,7 @@
32 32
  * 2003-05-13  l: (short form of Content-Length) is now recognized (andrei)
33 33
  * 2003-07-01  tcp_read & friends take no a single tcp_connection 
34 34
  *              parameter & they set c->state to S_CONN_EOF on eof (andrei)
35
+ * 2003-07-04  fixed tcp EOF handling (possible infinite loop) (andrei)
35 36
  */
36 37
 
37 38
 #ifdef USE_TCP
... ...
@@ -96,7 +97,8 @@ again:
96 96
 			return -1;
97 97
 		}
98 98
 	}else if (bytes_read==0){
99
-		r->state=S_CONN_EOF;
99
+		c->state=S_CONN_EOF;
100
+		DBG("tcp_read: EOF on %p, FD %d\n", c, fd);
100 101
 	}
101 102
 #ifdef EXTRA_DEBUG
102 103
 	DBG("tcp_read: read %d bytes:\n%.*s\n", bytes_read, bytes_read, r->pos);
... ...
@@ -395,7 +397,6 @@ int tcp_read_req(struct tcp_connection* con)
395 395
 		resp=CONN_RELEASE;
396 396
 		s=con->fd;
397 397
 		req=&con->req;
398
-		size=0;
399 398
 #ifdef USE_TLS
400 399
 		if (con->type==PROTO_TLS){
401 400
 			if (con->state==S_CONN_ACCEPT){
... ...
@@ -416,7 +417,7 @@ int tcp_read_req(struct tcp_connection* con)
416 416
 #endif
417 417
 
418 418
 again:
419
-		if(req->complete==0 && req->error==TCP_REQ_OK){
419
+		if(req->error==TCP_REQ_OK){
420 420
 			bytes=tcp_read_headers(con);
421 421
 #ifdef EXTRA_DEBUG
422 422
 						/* if timeout state=0; goto end__req; */
... ...
@@ -432,7 +433,12 @@ again:
432 432
 				resp=CONN_ERROR;
433 433
 				goto end_req;
434 434
 			}
435
-			if ((size==0) && (bytes==0) &&(con->state==S_CONN_EOF)){
435
+			/* eof check:
436
+			 * is EOF if eof on fd and req.  not complete yet,
437
+			 * if req. is complete we might have a second unparsed
438
+			 * request after it, so postpone release_with_eof
439
+			 */
440
+			if ((con->state==S_CONN_EOF) && (req->complete==0)) {
436 441
 				DBG( "tcp_read_req: EOF\n");
437 442
 				resp=CONN_EOF;
438 443
 				goto end_req;
... ...
@@ -514,6 +520,10 @@ again:
514 514
 			req->bytes_to_go=0;
515 515
 			/* if we still have some unparsed bytes, try to  parse them too*/
516 516
 			if (size) goto again;
517
+			else if (con->state==S_CONN_EOF){
518
+				DBG( "tcp_read_req: EOF after reading complete request\n");
519
+				resp=CONN_EOF;
520
+			}
517 521
 			
518 522
 		}
519 523