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