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