Browse code

- tcp eof handling backported from unstable (should fix WM tcp problems)

Andrei Pelinescu-Onciul authored on 30/07/2003 16:33:37
Showing 4 changed files
... ...
@@ -40,7 +40,7 @@ export makefile_defs
40 40
 VERSION = 0
41 41
 PATCHLEVEL = 8
42 42
 SUBLEVEL =   11
43
-EXTRAVERSION = rc1
43
+EXTRAVERSION = rc2
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]")
... ...
@@ -25,9 +25,10 @@
25 25
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 26
  *
27 27
  *
28
- * history:
28
+ * History:
29 29
  * --------
30
- * 2003-01-29 tcp buffer size ++-ed to allow for 0-terminator
30
+ *  2003-01-29 tcp buffer size ++-ed to allow for 0-terminator
31
+ *  2003-07-30 tcpconn->state and tcp_conn_states added (andrei)
31 32
  */
32 33
 
33 34
 
... ...
@@ -57,6 +58,8 @@ enum tcp_req_states {	H_SKIP_EMPTY, H_SKIP, H_LF, H_LFCR,  H_BODY, H_STARTWS,
57 58
 		H_CONT_LEN_BODY, H_CONT_LEN_BODY_PARSE 
58 59
 	};
59 60
 
61
+enum tcp_conn_states { S_CONN_OK=0, S_CONN_EOF };
62
+
60 63
 /* fd communication commands */
61 64
 enum conn_cmds { CONN_DESTROY=-3, CONN_ERROR=-2, CONN_EOF=-1, CONN_RELEASE, 
62 65
 					CONN_GET_FD, CONN_NEW };
... ...
@@ -96,6 +99,7 @@ struct tcp_connection{
96 99
 #endif
97 100
 	struct tcp_req req; /* request data */
98 101
 	volatile int refcnt;
102
+	int state; /* connection state, only EOF and OK for now */
99 103
 	int bad; /* if set this is a "bad" connection */
100 104
 	int timeout; /* connection timeout, after this it will be removed*/
101 105
 	unsigned addr_hash; /* hash indexes in the 2 tables */
... ...
@@ -39,6 +39,7 @@
39 39
  *               a temp. socket and store in in *->bind_address: added
40 40
  *               find_tcp_si, modified tcpconn_connect (andrei)
41 41
  *  2003-04-14  set sockopts to TOS low delay (andrei)
42
+ *  2003-07-30  tcpconn->state added (andrei)
42 43
  */
43 44
 
44 45
 
... ...
@@ -135,6 +136,7 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
135 136
 	
136 137
 	c->refcnt=0;
137 138
 	c->bad=0;
139
+	c->state=S_CONN_OK;
138 140
 	su2ip_addr(&c->rcv.src_ip, su);
139 141
 	c->rcv.src_port=su_getport(su);
140 142
 	c->rcv.proto=PROTO_TCP;
... ...
@@ -32,6 +32,9 @@
32 32
  * 2003-05-13  l: (short form of Content-Length) is now recognized (andrei)
33 33
  * 2003-07-04  fixed eof for tcp_read_req  (andrei)
34 34
  * 2003-07-09  fix a possible bug in tcp_receive_loop (andrei)
35
+ * 2003-07-30  tcp_read* updated to use tcp_connection and tcpconn->state --
36
+ *              fixes false EOF on multiple reqs/packet; 
37
+ *              backported from unstable (andrei)
35 38
  */
36 39
 
37 40
 #ifdef USE_TCP
... ...
@@ -63,9 +66,14 @@
63 66
 /* reads next available bytes
64 67
  * return number of bytes read, 0 on EOF or -1 on error,
65 68
  * sets also r->error */
66
-int tcp_read(struct tcp_req *r, int fd)
69
+int tcp_read(struct tcp_connection *c)
67 70
 {
68 71
 	int bytes_free, bytes_read;
72
+	struct tcp_req* r;
73
+	int fd;
74
+	
75
+	r=&c->req;
76
+	fd=c->fd;
69 77
 	
70 78
 	bytes_free=TCP_BUF_SIZE- (int)(r->pos - r->buf);
71 79
 	
... ...
@@ -86,6 +94,9 @@ again:
86 94
 			r->error=TCP_READ_ERROR;
87 95
 			return -1;
88 96
 		}
97
+	}else if (bytes_read==0){
98
+		c->state=S_CONN_EOF;
99
+		DBG("tcp_read: EOF on %p, FD %d\n", c, fd);
89 100
 	}
90 101
 #ifdef EXTRA_DEBUG
91 102
 	DBG("tcp_read: read %d bytes:\n%.*s\n", bytes_read, bytes_read, r->pos);
... ...
@@ -105,10 +116,11 @@ again:
105 116
  * when either r->body!=0 or r->state==H_BODY =>
106 117
  * all headers have been read. It should be called in a while loop.
107 118
  * returns < 0 if error or 0 if EOF */
108
-int tcp_read_headers(struct tcp_req *r, int fd)
119
+int tcp_read_headers(struct tcp_connection *c)
109 120
 {
110 121
 	int bytes, remaining;
111 122
 	char *p;
123
+	struct tcp_req* r;
112 124
 	
113 125
 	#define crlf_default_skip_case \
114 126
 					case '\n': \
... ...
@@ -151,11 +163,12 @@ int tcp_read_headers(struct tcp_req *r, int fd)
151 163
 							  break
152 164
 
153 165
 
166
+	r=&c->req; 
154 167
 	/* if we still have some unparsed part, parse it first, don't do the read*/
155 168
 	if (r->parsed<r->pos){
156 169
 		bytes=0;
157 170
 	}else{
158
-		bytes=tcp_read(r, fd);
171
+		bytes=tcp_read(c);
159 172
 		if (bytes<=0) return bytes;
160 173
 	}
161 174
 	p=r->parsed;
... ...
@@ -379,7 +392,7 @@ int tcp_read_req(struct tcp_connection* con)
379 392
 		req=&con->req;
380 393
 again:
381 394
 		if(req->error==TCP_REQ_OK){
382
-			bytes=tcp_read_headers(req, s);
395
+			bytes=tcp_read_headers(con);
383 396
 #ifdef EXTRA_DEBUG
384 397
 						/* if timeout state=0; goto end__req; */
385 398
 			DBG("read= %d bytes, parsed=%d, state=%d, error=%d\n",
... ...
@@ -394,7 +407,12 @@ again:
394 407
 				resp=CONN_ERROR;
395 408
 				goto end_req;
396 409
 			}
397
-			if ((req->complete==0) && (bytes==0)){
410
+			/* eof check:
411
+			 * is EOF if eof on fd and req.  not complete yet,
412
+			 * if req. is complete we might have a second unparsed
413
+			 * request after it, so postpone release_with_eof
414
+			 */
415
+			if ((con->state==S_CONN_EOF) && (req->complete==0)){
398 416
 				DBG( "tcp_read_req: EOF\n");
399 417
 				resp=CONN_EOF;
400 418
 				goto end_req;
... ...
@@ -476,8 +494,10 @@ again:
476 494
 			req->bytes_to_go=0;
477 495
 			/* if we still have some unparsed bytes, try to  parse them too*/
478 496
 			if (size) goto again;
479
-			else if (bytes==0) resp=CONN_EOF;/* 0 bytes read, this is an EOF*/
480
-			
497
+			else if (con->state==S_CONN_EOF){
498
+				DBG( "tcp_read_req: EOF after reading complete request\n");
499
+				resp=CONN_EOF;
500
+			}
481 501
 		}
482 502
 		
483 503