xref: /csrg-svn/sys/netinet/tcp_input.c (revision 4663)
1 /* tcp_input.c 1.7 81/10/29 */
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/mbuf.h"
6 #include "../h/socket.h"
7 #include "../inet/inet.h"
8 #include "../inet/inet_systm.h"
9 #include "../inet/imp.h"
10 #include "../inet/inet_host.h"
11 #include "../inet/ip.h"
12 #include "../inet/tcp.h"
13 #include "../inet/tcp_fsm.h"
14 
15 extern int nosum;
16 
17 tcp_input(mp)
18 	register struct mbuf *mp;
19 {
20 	register struct tcb *tp;
21 	register struct th *n;
22 	int nstate;
23 	struct mbuf *m;
24 	struct ucb *up;
25 	int hlen, tlen, j;
26 	u_short lport, fport;
27 #ifdef TCPDEBUG
28 	struct tcp_debug tdb;
29 #endif
30 COUNT(TCP_INPUT);
31 
32 	/*
33 	 * Build extended tcp header
34 	 */
35 	n = (struct th *)((int)mp + mp->m_off);
36 	tlen = ((struct ip *)n)->ip_len;
37 	n->t_len = htons(tlen);
38 	n->t_next = NULL;
39 	n->t_prev = NULL;
40 	n->t_x1 = 0;
41 	lport = ntohs(n->t_dst);
42 	fport = ntohs(n->t_src);
43 
44 	/* WONT BE POSSIBLE WHEN MBUFS ARE 256 BYTES */
45 	if ((hlen = n->t_off << 2) > mp->m_len)
46 		{ printf("tcp header overflow\n"); m_freem(mp); return; }
47 
48 	/*
49 	 * Checksum extended header and data
50 	 */
51 	j = n->t_sum; n->t_sum = 0;
52 	if (j != cksum(mp, sizeof (struct ip) + tlen)) {
53 		netstat.t_badsum++;
54 		if (nosum == 0) {
55 			m_freem(mp);
56 			return;
57 		}
58 	}
59 
60 	/*
61 	 * Find tcb for message (SHOULDN'T USE LINEAR SEARCH!)
62 	 */
63 	for (tp = tcb_head; tp != 0; tp = tp->t_tcb_next)
64 		if (tp->t_lport == lport && tp->t_fport == fport &&
65 		    tp->t_ucb->uc_host->h_addr.s_addr == n->t_s.s_addr)
66 			goto found;
67 	for (tp = tcb_head; tp != 0; tp = tp->t_tcb_next)
68 		if (tp->t_lport == lport &&
69 		    (tp->t_fport==fport || tp->t_fport==0) &&
70 		    (tp->t_ucb->uc_host->h_addr.s_addr == n->t_s.s_addr ||
71 		     tp->t_ucb->uc_host->h_addr.s_addr == 0))
72 			goto found;
73 	goto notwanted;
74 found:
75 
76 	/*
77 	 * Byte swap header
78 	 */
79 	n->t_len = tlen - hlen;
80 	n->t_src = fport;
81 	n->t_dst = lport;
82 	n->t_seq = ntohl(n->t_seq);
83 	n->t_ackno = ntohl(n->t_ackno);
84 	n->t_win = ntohs(n->t_win);
85 	n->t_urp = ntohs(n->t_urp);
86 
87 	/*
88 	 * Check segment seq # and do rst processing
89 	 */
90 	switch (tp->t_state) {
91 
92 	case LISTEN:
93 		if ((n->th_flags&TH_ACK) || !syn_ok(tp, n)) {
94 			send_rst(tp, n);
95 			goto badseg;
96 		}
97 		if (n->th_flags&TH_RST)
98 			goto badseg;
99 		goto goodseg;
100 
101 	case SYN_SENT:
102 		if (!ack_ok(tp, n) || !syn_ok(tp, n)) {
103 			send_rst(tp, n);			/* 71,72,75 */
104 			goto badseg;
105 		}
106 		if (n->th_flags&TH_RST) {
107 			t_close(tp, URESET);			/* 70 */
108 			tp->t_state = CLOSED;
109 			goto badseg;
110 		}
111 		goto goodseg;
112 
113 	default:
114         	if ((n->th_flags&TH_RST) == 0)
115 			goto common;
116 		if (n->t_seq < tp->rcv_nxt)		/* bad rst */
117 			goto badseg;				/* 69 */
118 		switch (tp->t_state) {
119 
120 		case L_SYN_RCVD:
121 			if (ack_ok(tp, n) == 0)
122 				goto badseg;			/* 69 */
123 			tp->t_rexmt = 0;
124 			tp->t_rexmttl = 0;
125 			tp->t_persist = 0;
126 			h_free(tp->t_ucb->uc_host);
127 			tp->t_state = LISTEN;
128 			goto badseg;
129 
130 		default:
131 			t_close(tp, URESET);			/* 66 */
132 			tp->t_state = CLOSED;
133 			goto badseg;
134 		}
135 		/*NOTREACHED*/
136 
137 	case SYN_RCVD:
138 common:
139 		if (ack_ok(tp, n) == 0) {
140 			send_rst(tp, n);			/* 74 */
141 			goto badseg;
142 		}
143 		if (syn_ok(tp, n) && n->t_seq != tp->irs) {
144 			send_null(tp);				/* 74 */
145 			goto badseg;
146 		}
147 		goto goodseg;
148 	}
149 badseg:
150 	m_freem(mp);
151 	return;
152 
153 goodseg:
154 #ifdef notdef
155 	/*
156 	 * Defer processing if no buffer space for this connection.
157 	 */
158 	up = tp->t_ucb;
159 	if (up->uc_rcc > up->uc_rhiwat &&
160 	     && n->t_len != 0 && mbstat.m_bufs < mbstat.m_lowat) {
161 		mp->m_act = (struct mbuf *)0;
162 		if ((m = tp->t_rcv_unack) != NULL) {
163 			while (m->m_act != NULL)
164 				m = m->m_act;
165 			m->m_act = mp;
166 		} else
167 			tp->t_rcv_unack = mp;
168 		return;
169 	}
170 #endif
171 
172 	/*
173 	 * Discard ip header, and do tcp input processing.
174 	 */
175 	hlen += sizeof(struct ip);
176 	mp->m_off += hlen;
177 	mp->m_len -= hlen;
178 	nstate = tp->t_state;
179 	tp->tc_flags &= ~TC_NET_KEEP;
180 	acounts[tp->t_state][INRECV]++;
181 #ifdef TCPDEBUG
182 	if ((tp->t_ucb->uc_flags & UDEBUG) || tcpconsdebug) {
183 		tdb_setup(tp, n, INRECV, &tdb);
184 	} else
185 		tdb.td_tod = 0;
186 #endif
187 	switch (tp->t_state) {
188 
189 	case LISTEN:
190 		if (!syn_ok(tp, n) ||
191 		    ((tp->t_ucb->uc_host = h_make(&n->t_s)) == 0)) {
192 			nstate = EFAILEC;
193 			goto done;
194 		}
195 		tp->t_fport = n->t_src;
196 		tp->t_ucb->uc_template = tcp_template(tp);
197 		rcv_ctldat(tp, n, 1);
198 		if (tp->tc_flags&TC_FIN_RCVD) {
199 			tp->t_finack = T_2ML;			/* 3 */
200 			tp->tc_flags &= ~TC_WAITED_2_ML;
201 			nstate = CLOSE_WAIT;
202 		} else {
203 			tp->t_init = T_INIT / 2;		/* 4 */
204 			nstate = L_SYN_RCVD;
205 		}
206 		goto done;
207 
208 	case SYN_SENT:
209 		if (!syn_ok(tp, n)) {
210 			nstate = EFAILEC;
211 			goto done;
212 		}
213 		rcv_ctldat(tp, n, 1);
214 		if (tp->tc_flags&TC_FIN_RCVD) {
215 			if (n->th_flags&TH_ACK) {
216 				if (n->t_ackno > tp->iss)
217 					present_data(tp);	/* 32 */
218 			} else {
219 				tp->t_finack = T_2ML;		/* 9 */
220 				tp->tc_flags &= ~TC_WAITED_2_ML;
221 			}
222 			nstate = CLOSE_WAIT;
223 			goto done;
224 		}
225 		if (n->th_flags&TH_ACK) {
226 			present_data(tp);			/* 11 */
227 			nstate = ESTAB;
228 		} else
229 			nstate = SYN_RCVD;			/* 8 */
230 		goto done;
231 
232 	case SYN_RCVD:
233 	case L_SYN_RCVD:
234 		if ((n->th_flags&TH_ACK) == 0 ||
235 		    (n->th_flags&TH_ACK) && n->t_ackno <= tp->iss) {
236 			nstate = EFAILEC;
237 			goto done;
238 		}
239 		goto input;
240 
241 	case ESTAB:
242 	case FIN_W1:
243 	case FIN_W2:
244 	case TIME_WAIT:
245 input:
246 		rcv_ctldat(tp, n, 1);				/* 39 */
247 		present_data(tp);
248 		switch (tp->t_state) {
249 
250 		case ESTAB:
251 			if (tp->tc_flags&TC_FIN_RCVD)
252 				nstate = CLOSE_WAIT;
253 			break;
254 
255 		case SYN_RCVD:
256 		case L_SYN_RCVD:
257 			nstate = (tp->tc_flags&TC_FIN_RCVD) ?
258 			    CLOSE_WAIT : ESTAB;			 /* 33:5 */
259 			break;
260 
261 		case FIN_W1:
262 			j = ack_fin(tp, n);
263 			if ((tp->tc_flags & TC_FIN_RCVD) == 0) {
264 				if (j)
265 					nstate = FIN_W2;	/* 27 */
266 				break;
267 			}
268 			tp->t_finack = T_2ML;
269 			tp->tc_flags &= ~TC_WAITED_2_ML;
270 			nstate = j ? TIME_WAIT : CLOSING1;	/* 28:26 */
271 			break;
272 
273 		case FIN_W2:
274 			if (tp->tc_flags&TC_FIN_RCVD) {
275 				tp->t_finack = T_2ML;		/* 29 */
276 				tp->tc_flags &= ~TC_WAITED_2_ML;
277 				nstate = TIME_WAIT;
278 				break;
279 			}
280 			break;
281 		}
282 		goto done;
283 
284 	case CLOSE_WAIT:
285 		if (n->th_flags&TH_FIN) {
286 			if ((n->th_flags&TH_ACK) &&
287 			    n->t_ackno <= tp->seq_fin) {
288 				rcv_ctldat(tp, n, 0);		/* 30 */
289 				tp->t_finack = T_2ML;
290 				tp->tc_flags &= ~TC_WAITED_2_ML;
291 			} else
292 				send_ctl(tp);			/* 31 */
293 			goto done;
294 		}
295 		goto input;
296 
297 	case CLOSING1:
298 		j = ack_fin(tp, n);
299 		if (n->th_flags&TH_FIN) {
300 			rcv_ctldat(tp, n, 0);
301 			tp->t_finack = T_2ML;
302 			tp->tc_flags &= ~TC_WAITED_2_ML;
303 			if (j)
304 				nstate = TIME_WAIT;		/* 23 */
305 			goto done;
306 		}
307 		if (j) {
308 			if (tp->tc_flags&TC_WAITED_2_ML)
309 				if (rcv_empty(tp)) {
310 					t_close(tp, UCLOSED);	/* 15 */
311 					nstate = CLOSED;
312 				} else
313 					nstate = RCV_WAIT;	/* 18 */
314 			else
315 				nstate = TIME_WAIT;
316 			goto done;
317 		}
318 		goto input;
319 
320 	case CLOSING2:
321 		if (ack_fin(tp, n)) {
322 			if (rcv_empty(tp)) {			/* 16 */
323 				t_close(tp, UCLOSED);
324 				nstate = CLOSED;
325 			} else
326 				nstate = RCV_WAIT;		/* 19 */
327 			goto done;
328 		}
329 		if (n->th_flags&TH_FIN) {
330 			send_ctl(tp);				/* 31 */
331 			goto done;
332 		}
333 		goto input;
334 
335 	case RCV_WAIT:
336 		if ((n->th_flags&TH_FIN) && (n->th_flags&TH_ACK) &&
337 		    n->t_ackno <= tp->seq_fin) {
338 			rcv_ctldat(tp, n, 0);
339 			tp->t_finack = T_2ML;
340 			tp->tc_flags &= ~TC_WAITED_2_ML;	/* 30 */
341 		}
342 		goto done;
343 	}
344 	panic("tcp_input");
345 done:
346 
347 	/*
348 	 * Done with state*input specific processing.
349 	 * Form trace records, free input if not needed,
350 	 * and enter new state.
351 	 */
352 #ifdef TCPDEBUG
353 	if (tdb.td_tod)
354 		tdb_stuff(&tdb, nstate);
355 #endif
356 	switch (nstate) {
357 
358 	case EFAILEC:
359 		m_freem(mp);
360 		return;
361 
362 	default:
363 		tp->t_state = nstate;
364 		/* fall into ... */
365 
366 	case CLOSED:
367 		/* IF CLOSED CANT LOOK AT tc_flags */
368 		if ((tp->tc_flags&TC_NET_KEEP) == 0)
369 			m_freem(mp);
370 		return;
371 	}
372 	/* NOTREACHED */
373 
374 	/*
375 	 * Unwanted packed; free everything
376 	 * but the header and return an rst.
377 	 */
378 notwanted:
379 	m_freem(mp->m_next);
380 	mp->m_next = NULL;
381 	mp->m_len = sizeof(struct th);
382 #define xchg(a,b) j=a; a=b; b=j
383 	xchg(n->t_d.s_addr, n->t_s.s_addr); xchg(n->t_dst, n->t_src);
384 #undef xchg
385 	if (n->th_flags&TH_ACK)
386 		n->t_seq = n->t_ackno;
387 	else {
388 		n->t_ackno = htonl(ntohl(n->t_seq) + tlen - hlen);
389 		n->t_seq = 0;
390 	}
391 	n->th_flags = TH_RST; /* not TH_FIN, TH_SYN */
392 	n->th_flags ^= TH_ACK;
393 	n->t_len = htons(TCPSIZE);
394 	n->t_off = 5;
395 	n->t_sum = cksum(mp, sizeof(struct th));
396 	((struct ip *)n)->ip_len = sizeof(struct th);
397 	ip_output(mp);
398 	netstat.t_badsegs++;
399 }
400 
401 rcv_ctldat(tp, n, dataok)
402 	register struct tcb *tp;
403 	register struct th *n;
404 {
405 	register sent;
406 	register struct ucb *up;
407 	register struct mbuf *m, *mn;
408 	register len;
409 COUNT(RCV_CTLDAT);
410 
411 	tp->tc_flags &= ~(TC_DROPPED_TXT|TC_ACK_DUE|TC_NEW_WINDOW);
412 /* syn */
413 	if ((tp->tc_flags&TC_SYN_RCVD) == 0 && (n->th_flags&TH_SYN)) {
414 		tp->irs = n->t_seq;
415 		tp->rcv_nxt = n->t_seq + 1;
416 		tp->snd_wl = tp->rcv_urp = tp->irs;
417 		tp->tc_flags |= (TC_SYN_RCVD|TC_ACK_DUE);
418 	}
419 /* ack */
420 	if ((n->th_flags&TH_ACK) && (tp->tc_flags&TC_SYN_RCVD) &&
421 	    n->t_ackno > tp->snd_una) {
422 		up = tp->t_ucb;
423 
424 		/* update snd_una and snd_nxt */
425 		tp->snd_una = n->t_ackno;
426 		if (tp->snd_una > tp->snd_nxt)
427 			tp->snd_nxt = tp->snd_una;
428 
429 		/* if timed msg acked, set retrans time value */
430 		if ((tp->tc_flags&TC_SYN_ACKED) &&
431 		    tp->snd_una > tp->t_xmt_val) {
432 			tp->t_xmtime = (tp->t_xmt != 0 ? tp->t_xmt : T_REXMT);
433 			if (tp->t_xmtime > T_REMAX)
434 				tp->t_xmtime = T_REMAX;
435 		}
436 
437 		/* remove acked data from send buf */
438 		len = tp->snd_una - tp->snd_off;
439 		m = up->uc_sbuf;
440 		while (len > 0 && m != NULL)
441 			if (m->m_len <= len) {
442 				len -= m->m_len;
443 				if (m->m_off > MMAXOFF)
444 					up->uc_ssize -= NMBPG;
445 				MFREE(m, mn);
446 				m = mn;
447 				up->uc_ssize--;
448 			} else {
449 				m->m_len -= len;
450 				m->m_off += len;
451 				break;
452 			}
453 		up->uc_sbuf = m;
454 		tp->snd_off = tp->snd_una;
455 		if ((tp->tc_flags&TC_SYN_ACKED) == 0 &&
456 		    (tp->snd_una > tp->iss)) {
457 			tp->tc_flags |= TC_SYN_ACKED;
458 			tp->t_init = 0;
459 		}
460 		if (tp->seq_fin != tp->iss && tp->snd_una > tp->seq_fin)
461 			tp->tc_flags &= ~TC_SND_FIN;
462 		tp->t_rexmt = 0;
463 		tp->t_rexmttl = 0;
464 		tp->tc_flags |= TC_CANCELLED;
465 		netwakeup(tp->t_ucb);		/* wasteful */
466 	}
467 /* win */
468 	if ((tp->tc_flags & TC_SYN_RCVD) && n->t_seq >= tp->snd_wl) {
469 		tp->snd_wl = n->t_seq;
470 		tp->snd_wnd = n->t_win;
471 		tp->tc_flags |= TC_NEW_WINDOW;
472 		tp->t_persist = 0;
473 	}
474 	if (dataok) {
475 /* text */
476 		if (n->t_len != 0)
477 			rcv_text(tp, n);
478 /* urg */
479 		if (n->th_flags&TH_URG) {
480 			unsigned urgent;
481 
482 			urgent = n->t_urp + n->t_seq;
483 			if (tp->rcv_nxt < urgent) {
484 				if (tp->rcv_urp <= tp->rcv_nxt)
485 					to_user(tp->t_ucb, UURGENT);
486 				tp->rcv_urp = urgent;
487 			}
488 		}
489 /* eol */
490 		if ((n->th_flags&TH_EOL) &&
491 		    (tp->tc_flags&TC_DROPPED_TXT) == 0 &&
492 		    tp->t_rcv_prev != (struct th *)tp) {
493 			/* mark last mbuf */
494 			m = dtom(tp->t_rcv_prev);
495 			if (m != NULL) {
496 				while (m->m_next != NULL)
497 					m = m->m_next;
498 				m->m_act =
499 				    (struct mbuf *)(m->m_off + m->m_len - 1);
500 			}
501 		}
502 	}
503 /* fin */
504 	if ((n->th_flags&TH_FIN) && (tp->tc_flags&TC_DROPPED_TXT) == 0) {
505 		int last;
506 
507 		if ((tp->tc_flags&TC_FIN_RCVD) == 0) {
508 			/* do we really have fin ? */
509 			last = firstempty(tp);
510 			if (tp->t_rcv_prev == (struct th *)tp ||
511 			    last == t_end(tp->t_rcv_prev)) {
512 				tp->tc_flags |= TC_FIN_RCVD;
513 				netwakeup(tp->t_ucb);		/* poke */
514 			}
515 			if ((tp->tc_flags&TC_FIN_RCVD) &&
516 			    tp->rcv_nxt >= last) {
517 				tp->rcv_nxt = last + 1;		/* fin seq */
518 				tp->tc_flags |= TC_ACK_DUE;
519 			}
520 		} else
521 			tp->tc_flags |= TC_ACK_DUE;
522 	}
523 
524 /* respond */
525 	if (tp->tc_flags&TC_ACK_DUE)
526 		sent = send_ctl(tp);
527 	else if (tp->tc_flags&TC_NEW_WINDOW)
528 		sent = send(tp);
529 	else
530 		sent = 0;
531 
532 /* set for retrans */
533 	if (!sent && tp->snd_una < tp->snd_nxt &&
534 	    (tp->tc_flags&TC_CANCELLED)) {
535 		tp->t_rexmt = tp->t_xmtime;
536 		tp->t_rexmttl = T_REXMTTL;
537 		tp->t_rexmt_val = tp->t_rtl_val = tp->snd_lst;
538 		tp->tc_flags &= ~TC_CANCELLED;
539 	}
540 }
541 
542 rcv_text(tp, n)
543 	register struct tcb *tp;
544 	register struct th *n;
545 {
546 	register int i;
547 	register struct th *p, *q;
548 	register struct mbuf *m;
549 	int overage;
550 COUNT(RCV_TEXT);
551 
552 	/*
553 	 * Discard duplicate data already passed to user.
554 	 */
555 	if (SEQ_LT(n->t_seq, tp->rcv_nxt)) {
556 		i = tp->rcv_nxt - n->t_seq;
557 		if (i >= n->t_len)
558 			goto dropseg;
559 		n->t_seq += i;
560 		n->t_len -= i;
561 		m_adj(dtom(n), i);
562 	}
563 
564 	/*
565 	 * Find a segment which begins after this one does.
566 	 */
567 	for (q = tp->t_rcv_next; q != (struct th *)tp; q = q->t_next)
568 		if (SEQ_GT(q->t_seq, n->t_seq))
569 			break;
570 
571 	/*
572 	 * If there is a preceding segment, it may provide some of
573 	 * our data already.  If so, drop the data from the incoming
574 	 * segment.  If it provides all of our data, drop us.
575 	 */
576 	if (q->t_prev != (struct th *)tp) {
577 		/* conversion to int (in i) handles seq wraparound */
578 		i = q->t_prev->t_seq + q->t_prev->t_len - n->t_seq;
579 		if (i > 0) {
580 			if (i >= n->t_len)
581 				goto dropseg;
582 			m_adj(dtom(tp), i);
583 			n->t_len -= i;
584 			n->t_seq += i;
585 		}
586 	}
587 
588 	/*
589 	 * While we overlap succeeding segments trim them or,
590 	 * if they are completely covered, dequeue them.
591 	 */
592 	while (q != (struct th *)tp && SEQ_GT(n->t_seq + n->t_len, q->t_seq)) {
593 		i = (n->t_seq + n->t_len) - q->t_seq;
594 		if (i < q->t_len) {
595 			q->t_len -= i;
596 			m_adj(dtom(q), i);
597 			break;
598 		}
599 		q = q->t_next;
600 		m_freem(dtom(q->t_prev));
601 		remque(q->t_prev);
602 	}
603 
604 	/*
605 	 * Stick new segment in its place.
606 	 */
607 	insque(n, q->t_prev);
608 	tp->seqcnt += n->t_len;
609 
610 #ifdef notdef
611 	/*
612 	 * Calculate available space and discard segments for
613 	 * which there is too much.
614 	 */
615 	q = tp->t_rcv_prev;
616 	overage =
617 	    (tp->t_socket->uc_rcc + tp->rcv_seqcnt) - tp->t_socket->uc_rhiwat;
618 	if (overage > 0)
619 		for (;;) {
620 			i = MIN(q->t_len, overage);
621 			overage -= i;
622 			q->t_len -= i;
623 			m_adj(q, -i);
624 			if (q == n)
625 				tp->tc_flags |= TC_DROPPED_TXT;
626 			if (q->t_len)
627 				break;
628 			if (q == n)
629 				panic("tcp_text dropall");
630 			q = q->t_prev;
631 			remque(q->t_next);
632 		}
633 #endif
634 
635 	/*
636 	 * Advance rcv_next through
637 	 * newly completed sequence space
638 	 * and return forcing an ack.
639 	 */
640 	while (n->t_seq == tp->rcv_nxt) {
641 		/* present data belongs here */
642 		tp->rcv_nxt += n->t_len;
643 		n = n->t_next;
644 		if (n == (struct th *)tp)
645 			break;
646 	}
647 	tp->tc_flags |= (TC_ACK_DUE|TC_NET_KEEP);
648 	return;
649 
650 dropseg:
651 	/* don't set TC_NET_KEEP, so that mbuf's will get dropped */
652 	return;
653 }
654 
655 #define	socket		ucb			/* ### */
656 #define	t_socket	t_ucb			/* ### */
657 
658 present_data(tp)
659 	register struct tcb *tp;
660 {
661 	register struct th *t;
662 	register struct socket *up;
663 	register struct mbuf *m, **mp;
664 	seq_t ready;
665 COUNT(PRESENT_DATA);
666 
667 	/* connection must be synced and data available for user */
668 	if ((tp->tc_flags&TC_SYN_ACKED) == 0)
669 		return;
670 	up = tp->t_socket;
671 	mp = &up->uc_rbuf;
672 	while (*mp)
673 		mp = &(*mp)->m_next;
674 	t = tp->t_rcv_next;
675 	/* SHOULD PACK DATA IN HERE */
676 	while (t != (struct th *)tp && t->t_seq < tp->rcv_nxt) {
677 		remque(t);
678 		m = dtom(t);
679 		up->uc_rcc += t->t_len;
680 		tp->seqcnt -= t->t_len;
681 		if (tp->seqcnt < 0) panic("present_data");
682 		t = t->t_next;
683 		while (m) {
684 			if (m->m_len == 0) {
685 				m = m_free(m);
686 				continue;
687 			}
688 			*mp = m;
689 			mp = &m->m_next;
690 			m = *mp;
691 		}
692 	}
693 	if (up->uc_rcc != 0)
694 		netwakeup(up);
695 	if ((tp->tc_flags&TC_FIN_RCVD) &&			/* ### */
696 	    (tp->tc_flags&TC_USR_CLOSED) == 0 &&		/* ### */
697 	    rcv_empty(tp))					/* ### */
698 		to_user(up, UCLOSED);				/* ### */
699 }
700