xref: /csrg-svn/sys/netinet/tcp_input.c (revision 4671)
1 /* tcp_input.c 1.8 81/10/30 */
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 	sent = 0;
526 	if (tp->tc_flags&TC_ACK_DUE)
527 		sent = send_ctl(tp);
528 	else if (tp->tc_flags&TC_NEW_WINDOW) {
529 		seq_t last = tp->snd_off;
530 		up = tp->t_ucb;
531 		for (m = up->uc_sbuf; m != NULL; m = m->m_next)
532 			last += m->m_len;
533 		if (tp->snd_nxt <= last || (tp->tc_flags&TC_SND_FIN))
534 			sent = send(tp);
535 	}
536 
537 /* set for retrans */
538 	if (!sent && tp->snd_una < tp->snd_nxt &&
539 	    (tp->tc_flags&TC_CANCELLED)) {
540 		tp->t_rexmt = tp->t_xmtime;
541 		tp->t_rexmttl = T_REXMTTL;
542 		tp->t_rexmt_val = tp->t_rtl_val = tp->snd_lst;
543 		tp->tc_flags &= ~TC_CANCELLED;
544 	}
545 }
546 
547 rcv_text(tp, n)
548 	register struct tcb *tp;
549 	register struct th *n;
550 {
551 	register int i;
552 	register struct th *p, *q;
553 	register struct mbuf *m;
554 	int overage;
555 COUNT(RCV_TEXT);
556 
557 	/*
558 	 * Discard duplicate data already passed to user.
559 	 */
560 	if (SEQ_LT(n->t_seq, tp->rcv_nxt)) {
561 		i = tp->rcv_nxt - n->t_seq;
562 		if (i >= n->t_len)
563 			goto dropseg;
564 		n->t_seq += i;
565 		n->t_len -= i;
566 		m_adj(dtom(n), i);
567 	}
568 
569 	/*
570 	 * Find a segment which begins after this one does.
571 	 */
572 	for (q = tp->t_rcv_next; q != (struct th *)tp; q = q->t_next)
573 		if (SEQ_GT(q->t_seq, n->t_seq))
574 			break;
575 
576 	/*
577 	 * If there is a preceding segment, it may provide some of
578 	 * our data already.  If so, drop the data from the incoming
579 	 * segment.  If it provides all of our data, drop us.
580 	 */
581 	if (q->t_prev != (struct th *)tp) {
582 		/* conversion to int (in i) handles seq wraparound */
583 		i = q->t_prev->t_seq + q->t_prev->t_len - n->t_seq;
584 		if (i > 0) {
585 			if (i >= n->t_len)
586 				goto dropseg;
587 			m_adj(dtom(tp), i);
588 			n->t_len -= i;
589 			n->t_seq += i;
590 		}
591 	}
592 
593 	/*
594 	 * While we overlap succeeding segments trim them or,
595 	 * if they are completely covered, dequeue them.
596 	 */
597 	while (q != (struct th *)tp && SEQ_GT(n->t_seq + n->t_len, q->t_seq)) {
598 		i = (n->t_seq + n->t_len) - q->t_seq;
599 		if (i < q->t_len) {
600 			q->t_len -= i;
601 			m_adj(dtom(q), i);
602 			break;
603 		}
604 		q = q->t_next;
605 		m_freem(dtom(q->t_prev));
606 		remque(q->t_prev);
607 	}
608 
609 	/*
610 	 * Stick new segment in its place.
611 	 */
612 	insque(n, q->t_prev);
613 	tp->seqcnt += n->t_len;
614 
615 #ifdef notdef
616 	/*
617 	 * Calculate available space and discard segments for
618 	 * which there is too much.
619 	 */
620 	q = tp->t_rcv_prev;
621 	overage =
622 	    (tp->t_socket->uc_rcc + tp->rcv_seqcnt) - tp->t_socket->uc_rhiwat;
623 	if (overage > 0)
624 		for (;;) {
625 			i = MIN(q->t_len, overage);
626 			overage -= i;
627 			q->t_len -= i;
628 			m_adj(q, -i);
629 			if (q == n)
630 				tp->tc_flags |= TC_DROPPED_TXT;
631 			if (q->t_len)
632 				break;
633 			if (q == n)
634 				panic("tcp_text dropall");
635 			q = q->t_prev;
636 			remque(q->t_next);
637 		}
638 #endif
639 
640 	/*
641 	 * Advance rcv_next through
642 	 * newly completed sequence space
643 	 * and return forcing an ack.
644 	 */
645 	while (n->t_seq == tp->rcv_nxt) {
646 		/* present data belongs here */
647 		tp->rcv_nxt += n->t_len;
648 		n = n->t_next;
649 		if (n == (struct th *)tp)
650 			break;
651 	}
652 	tp->tc_flags |= (TC_ACK_DUE|TC_NET_KEEP);
653 	return;
654 
655 dropseg:
656 	/* don't set TC_NET_KEEP, so that mbuf's will get dropped */
657 	return;
658 }
659 
660 #define	socket		ucb			/* ### */
661 #define	t_socket	t_ucb			/* ### */
662 
663 present_data(tp)
664 	register struct tcb *tp;
665 {
666 	register struct th *t;
667 	register struct socket *up;
668 	register struct mbuf *m, **mp;
669 	seq_t ready;
670 COUNT(PRESENT_DATA);
671 
672 	/* connection must be synced and data available for user */
673 	if ((tp->tc_flags&TC_SYN_ACKED) == 0)
674 		return;
675 	up = tp->t_socket;
676 	mp = &up->uc_rbuf;
677 	while (*mp)
678 		mp = &(*mp)->m_next;
679 	t = tp->t_rcv_next;
680 	/* SHOULD PACK DATA IN HERE */
681 	while (t != (struct th *)tp && t->t_seq < tp->rcv_nxt) {
682 		remque(t);
683 		m = dtom(t);
684 		up->uc_rcc += t->t_len;
685 		tp->seqcnt -= t->t_len;
686 		if (tp->seqcnt < 0) panic("present_data");
687 		t = t->t_next;
688 		while (m) {
689 			if (m->m_len == 0) {
690 				m = m_free(m);
691 				continue;
692 			}
693 			*mp = m;
694 			mp = &m->m_next;
695 			m = *mp;
696 		}
697 	}
698 	if (up->uc_rcc != 0)
699 		netwakeup(up);
700 	if ((tp->tc_flags&TC_FIN_RCVD) &&			/* ### */
701 	    (tp->tc_flags&TC_USR_CLOSED) == 0 &&		/* ### */
702 	    rcv_empty(tp))					/* ### */
703 		to_user(up, UCLOSED);				/* ### */
704 }
705