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