xref: /csrg-svn/sys/netinet/tcp_input.c (revision 5244)
1 /*	tcp_input.c	1.39	81/12/12	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/mbuf.h"
6 #include "../h/protosw.h"
7 #include "../h/socket.h"
8 #include "../h/socketvar.h"
9 #include "../net/in.h"
10 #include "../net/in_pcb.h"
11 #include "../net/in_systm.h"
12 #include "../net/if.h"
13 #include "../net/ip.h"
14 #include "../net/ip_var.h"
15 #include "../net/tcp.h"
16 #define TCPSTATES
17 #include "../net/tcp_fsm.h"
18 #include "../net/tcp_seq.h"
19 #include "../net/tcp_timer.h"
20 #include "../net/tcp_var.h"
21 #include "../net/tcpip.h"
22 #include "../errno.h"
23 
24 int	tcpcksum = 1;
25 struct	sockaddr_in tcp_in = { AF_INET };
26 
27 /*
28  * TCP input routine, follows pages 65-76 of the
29  * protocol specification dated September, 1981 very closely.
30  */
31 tcp_input(m0)
32 	struct mbuf *m0;
33 {
34 	register struct tcpiphdr *ti;
35 	struct inpcb *inp;
36 	register struct mbuf *m;
37 	int len, tlen, off;
38 	register struct tcpcb *tp;
39 	register int tiflags;
40 	struct socket *so;
41 	int todrop, acked;
42 
43 COUNT(TCP_INPUT);
44 	/*
45 	 * Get IP and TCP header together in first mbuf.
46 	 * Note: IP leaves IP header in first mbuf.
47 	 */
48 	m = m0;
49 	ti = mtod(m, struct tcpiphdr *);
50 	if (((struct ip *)ti)->ip_hl > (sizeof (struct ip) >> 2))
51 		ip_stripoptions((struct ip *)ti, (struct mbuf *)0);
52 	if (m->m_len < sizeof (struct tcpiphdr)) {
53 printf("m->m_len %d\n", m->m_len);
54 		if (m_pullup(m, sizeof (struct tcpiphdr)) == 0) {
55 printf("tcp_input: header drop\n");
56 			tcpstat.tcps_hdrops++;
57 			goto drop;
58 		}
59 		ti = mtod(m, struct tcpiphdr *);
60 	}
61 
62 	/*
63 	 * Checksum extended TCP header and data.
64 	 */
65 	tlen = ((struct ip *)ti)->ip_len;
66 	len = sizeof (struct ip) + tlen;
67 	if (tcpcksum) {
68 		ti->ti_next = ti->ti_prev = 0;
69 		ti->ti_x1 = 0;
70 		ti->ti_len = (u_short)tlen;
71 #if vax
72 		ti->ti_len = htons(ti->ti_len);
73 #endif
74 		if (ti->ti_sum = in_cksum(m, len)) {
75 			tcpstat.tcps_badsum++;
76 			printf("tcp cksum %x\n", ti->ti_sum);
77 			goto drop;
78 		}
79 	}
80 
81 	/*
82 	 * Check that TCP offset makes sense,
83 	 * process TCP options and adjust length.
84 	 */
85 	off = ti->ti_off << 2;
86 	if (off < sizeof (struct tcphdr) || off > tlen) {
87 printf("tcp_input: bad offset\n");
88 		tcpstat.tcps_badoff++;
89 		goto drop;
90 	}
91 	ti->ti_len = tlen - off;
92 #if 0
93 	if (off > sizeof (struct tcphdr))
94 		tcp_options(ti);
95 #endif
96 	tiflags = ti->ti_flags;
97 
98 #if vax
99 	/*
100 	 * Convert TCP protocol specific fields to host format.
101 	 */
102 	ti->ti_seq = ntohl(ti->ti_seq);
103 	ti->ti_ack = ntohl(ti->ti_ack);
104 	ti->ti_win = ntohs(ti->ti_win);
105 	ti->ti_urp = ntohs(ti->ti_urp);
106 #endif
107 
108 	/*
109 	 * Locate pcb for segment.
110 	 */
111 	inp = in_pcblookup
112 		(&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport);
113 
114 	/*
115 	 * If the state is CLOSED (i.e., TCB does not exist) then
116 	 * all data in the incoming segment is discarded.
117 	 */
118 	if (inp == 0)
119 		goto dropwithreset;
120 	tp = intotcpcb(inp);
121 	if (tp == 0)
122 		goto dropwithreset;
123 printf("tcp_input: segment seq %x ack %x win %x inp %x flags",
124 ti->ti_seq, ti->ti_ack, ti->ti_win, inp);
125 if (ti->ti_flags & TH_FIN) printf(" FIN");
126 if (ti->ti_flags & TH_SYN) printf(" SYN");
127 if (ti->ti_flags & TH_RST) printf(" RST");
128 if (ti->ti_flags & TH_PUSH) printf(" PUSH");
129 if (ti->ti_flags & TH_ACK) printf(" ACK");
130 if (ti->ti_flags & TH_URG) printf(" URG");
131 printf("\n");
132 printf("tcp_input: "); pseqno(tp);
133 	so = inp->inp_socket;
134 
135 	/*
136 	 * Segment received on connection.
137 	 * Reset idle time and keep-alive timer.
138 	 */
139 	tp->t_idle = 0;
140 	tp->t_timer[TCPT_KEEP] = TCPTV_KEEP;
141 
142 	/*
143 	 * Calculate amount of space in receive window,
144 	 * and then do TCP input processing.
145 	 */
146 	tp->rcv_wnd = sbspace(&so->so_rcv);
147 	if (tp->rcv_wnd < 0)
148 		tp->rcv_wnd = 0;
149 
150 	switch (tp->t_state) {
151 
152 	/*
153 	 * If the state is LISTEN then ignore segment if it contains an RST.
154 	 * If the segment contains an ACK then it is bad and send a RST.
155 	 * If it does not contain a SYN then it is not interesting; drop it.
156 	 * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
157 	 * tp->iss, and send a segment:
158 	 *     <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
159 	 * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
160 	 * Fill in remote peer address fields if not previously specified.
161 	 * Enter SYN_RECEIVED state, and process any other fields of this
162 	 * segment in this state.
163 	 */
164 	case TCPS_LISTEN:
165 		if (tiflags & TH_RST)
166 			goto drop;
167 		if (tiflags & TH_ACK)
168 			goto dropwithreset;
169 		if ((tiflags & TH_SYN) == 0)
170 			goto drop;
171 		tcp_in.sin_addr = ti->ti_src;
172 		tcp_in.sin_port = ti->ti_sport;
173 		if (in_pcbconnect(inp, (struct sockaddr *)&tcp_in))
174 			goto drop;
175 		tp->t_template = tcp_template(tp);
176 		if (tp->t_template == 0) {
177 			in_pcbdisconnect(inp);
178 			goto drop;
179 		}
180 		tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2;
181 		tp->irs = ti->ti_seq;
182 		tcp_sendseqinit(tp);
183 		tcp_rcvseqinit(tp);
184 		tp->t_state = TCPS_SYN_RECEIVED;
185 		tp->t_timer[TCPT_KEEP] = TCPTV_KEEP;
186 printf("tcp_input: out of LISTEN: ");
187 		goto trimthenstep6;
188 
189 	/*
190 	 * If the state is SYN_SENT:
191 	 *	if seg contains an ACK, but not for our SYN, drop the input.
192 	 *	if seg contains a RST, then drop the connection.
193 	 *	if seg does not contain SYN, then drop it.
194 	 * Otherwise this is an acceptable SYN segment
195 	 *	initialize tp->rcv_nxt and tp->irs
196 	 *	if seg contains ack then advance tp->snd_una
197 	 *	if SYN has been acked change to ESTABLISHED else SYN_RCVD state
198 	 *	arrange for segment to be acked (eventually)
199 	 *	continue processing rest of data/controls, beginning with URG
200 	 */
201 	case TCPS_SYN_SENT:
202 		if ((tiflags & TH_ACK) &&
203 		    (SEQ_LEQ(ti->ti_ack, tp->iss) ||
204 		     SEQ_GT(ti->ti_ack, tp->snd_max)))
205 			goto dropwithreset;
206 		if (tiflags & TH_RST) {
207 			if (tiflags & TH_ACK)
208 				tcp_drop(tp, ECONNRESET);
209 			goto drop;
210 		}
211 		if ((tiflags & TH_SYN) == 0)
212 			goto drop;
213 		tp->snd_una = ti->ti_ack;
214 		tp->t_timer[TCPT_REXMT] = 0;
215 		tp->irs = ti->ti_seq;
216 		tcp_rcvseqinit(tp);
217 		tp->t_flags |= TF_ACKNOW;
218 		if (SEQ_GT(tp->snd_una, tp->iss)) {
219 			soisconnected(so);
220 			tp->t_state = TCPS_ESTABLISHED;
221 			(void) tcp_reass(tp, (struct tcpiphdr *)0);
222 			tp->snd_wl1 = ti->ti_seq;
223 		} else
224 			tp->t_state = TCPS_SYN_RECEIVED;
225 printf("tcp_input: out of SYN_SENT: ");
226 		goto trimthenstep6;
227 
228 trimthenstep6:
229 		/*
230 		 * Advance ti->ti_seq to correspond to first data byte.
231 		 * If data, trim to stay within window,
232 		 * dropping FIN if necessary.
233 		 */
234 		ti->ti_seq++;
235 		if (ti->ti_len > tp->rcv_wnd) {
236 			todrop = ti->ti_len - tp->rcv_wnd;
237 			m_adj(m, -todrop);
238 			ti->ti_len = tp->rcv_wnd;
239 			ti->ti_flags &= ~TH_FIN;
240 		}
241 printf("ti->ti_len %d\n", ti->ti_len);
242 pseqno(tp);
243 		goto step6;
244 	}
245 
246 	/*
247 	 * States other than LISTEN or SYN_SENT.
248 	 * First check that at least some bytes of segment are within
249 	 * receive window.
250 	 */
251 	if (tp->rcv_wnd == 0) {
252 		/*
253 		 * If window is closed can only take segments at
254 		 * window edge, and have to drop data and PUSH from
255 		 * incoming segments.
256 		 */
257 		if (tp->rcv_nxt != ti->ti_seq)
258 			goto dropafterack;
259 		if (ti->ti_len > 0) {
260 			ti->ti_len = 0;
261 			ti->ti_flags &= ~(TH_PUSH|TH_FIN);
262 		}
263 printf("tcp_input %x: window 0, drop text and FIN\n", tp);
264 	} else {
265 		/*
266 		 * If segment begins before rcv_nxt, drop leading
267 		 * data (and SYN); if nothing left, just ack.
268 		 */
269 		if (SEQ_GT(tp->rcv_nxt, ti->ti_seq)) {
270 			todrop = tp->rcv_nxt - ti->ti_seq;
271 printf("tcp_input %x: drop %d dup bytes\n", tp, todrop);
272 			if (tiflags & TH_SYN) {
273 				ti->ti_seq++;
274 				if (ti->ti_urp > 1)
275 					ti->ti_urp--;
276 				else
277 					tiflags &= ~TH_URG;
278 				todrop--;
279 			}
280 			if (todrop > ti->ti_len)
281 				goto dropafterack;
282 			m_adj(m, todrop);
283 			ti->ti_seq += todrop;
284 			ti->ti_len -= todrop;
285 			if (ti->ti_urp > todrop)
286 				ti->ti_urp -= todrop;
287 			else {
288 				tiflags &= ~TH_URG;
289 				/* ti->ti_flags &= ~TH_URG; */
290 				/* ti->ti_urp = 0; */
291 			}
292 			/* tiflags &= ~TH_SYN; */
293 			/* ti->ti_flags &= ~TH_SYN; */
294 		}
295 		/*
296 		 * If segment ends after window, drop trailing data
297 		 * (and PUSH and FIN); if nothing left, just ACK.
298 		 */
299 		if (SEQ_GT(ti->ti_seq+ti->ti_len, tp->rcv_nxt+tp->rcv_wnd)) {
300 			todrop =
301 			     ti->ti_seq+ti->ti_len - (tp->rcv_nxt+tp->rcv_wnd);
302 			if (todrop > ti->ti_len)
303 				goto dropafterack;
304 			m_adj(m, -todrop);
305 			ti->ti_len -= todrop;
306 			ti->ti_flags &= ~(TH_PUSH|TH_FIN);
307 		}
308 	}
309 
310 	/*
311 	 * If the RST bit is set examine the state:
312 	 *    SYN_RECEIVED STATE:
313 	 *	If passive open, return to LISTEN state.
314 	 *	If active open, inform user that connection was refused.
315 	 *    ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
316 	 *	Inform user that connection was reset, and close tcb.
317 	 *    CLOSING, LAST_ACK, TIME_WAIT STATES
318 	 *	Close the tcb.
319 	 */
320 	if (tiflags&TH_RST) switch (tp->t_state) {
321 
322 	case TCPS_SYN_RECEIVED:
323 		if (inp->inp_socket->so_options & SO_ACCEPTCONN) {
324 			tp->t_state = TCPS_LISTEN;
325 			tp->t_timer[TCPT_KEEP] = 0;
326 			(void) m_free(dtom(tp->t_template));
327 			tp->t_template = 0;
328 			in_pcbdisconnect(inp);
329 			goto drop;
330 		}
331 		tcp_drop(tp, ECONNREFUSED);
332 		goto drop;
333 
334 	case TCPS_ESTABLISHED:
335 	case TCPS_FIN_WAIT_1:
336 	case TCPS_FIN_WAIT_2:
337 	case TCPS_CLOSE_WAIT:
338 		tcp_drop(tp, ECONNRESET);
339 		goto drop;
340 
341 	case TCPS_CLOSING:
342 	case TCPS_LAST_ACK:
343 	case TCPS_TIME_WAIT:
344 		tcp_close(tp);
345 		goto drop;
346 	}
347 
348 	/*
349 	 * If a SYN is in the window, then this is an
350 	 * error and we send an RST and drop the connection.
351 	 */
352 	if (tiflags & TH_SYN) {
353 		tcp_drop(tp, ECONNRESET);
354 		goto dropwithreset;
355 	}
356 
357 	/*
358 	 * If the ACK bit is off we drop the segment and return.
359 	 */
360 	if ((tiflags & TH_ACK) == 0)
361 		goto drop;
362 
363 	/*
364 	 * Ack processing.
365 	 */
366 	switch (tp->t_state) {
367 
368 	/*
369 	 * In SYN_RECEIVED state if the ack ACKs our SYN then enter
370 	 * ESTABLISHED state and continue processing, othewise
371 	 * send an RST.
372 	 */
373 	case TCPS_SYN_RECEIVED:
374 		if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
375 		    SEQ_GT(ti->ti_ack, tp->snd_max))
376 			goto dropwithreset;
377 		tp->snd_una++;			/* SYN acked */
378 		tp->t_timer[TCPT_REXMT] = 0;
379 		soisconnected(so);
380 		tp->t_state = TCPS_ESTABLISHED;
381 		(void) tcp_reass(tp, (struct tcpiphdr *)0);
382 		tp->snd_wl1 = ti->ti_seq - 1;
383 printf("tcp_input: to ESTAB:\n"); pseqno(tp);
384 		/* fall into ... */
385 
386 	/*
387 	 * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
388 	 * ACKs.  If the ack is in the range
389 	 *	tp->snd_una < ti->ti_ack <= tp->snd_max
390 	 * then advance tp->snd_una to ti->ti_ack and drop
391 	 * data from the retransmission queue.  If this ACK reflects
392 	 * more up to date window information we update our window information.
393 	 */
394 	case TCPS_ESTABLISHED:
395 	case TCPS_FIN_WAIT_1:
396 	case TCPS_FIN_WAIT_2:
397 	case TCPS_CLOSE_WAIT:
398 	case TCPS_CLOSING:
399 	case TCPS_LAST_ACK:
400 	case TCPS_TIME_WAIT:
401 #define	ourfinisacked	(acked > 0)
402 
403 		if (SEQ_LEQ(ti->ti_ack, tp->snd_una))
404 			break;
405 		if (SEQ_GT(ti->ti_ack, tp->snd_max))
406 			goto dropafterack;
407 		acked = ti->ti_ack - tp->snd_una;
408 printf("tcp_input: got ack of %d bytes\n", acked);
409 		if (acked >= so->so_snd.sb_cc) {
410 			acked -= so->so_snd.sb_cc;
411 			/* if acked > 0 our FIN is acked */
412 			sbdrop(&so->so_snd, so->so_snd.sb_cc);
413 			tp->t_timer[TCPT_REXMT] = 0;
414 		} else {
415 			sbdrop(&so->so_snd, acked);
416 			acked = 0;
417 			TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
418 			    tcp_beta * tp->t_srtt, TCPTV_MIN, TCPTV_MAX);
419 		}
420 		tp->snd_una = ti->ti_ack;
421 
422 		/*
423 		 * If transmit timer is running and timed sequence
424 		 * number was acked, update smoothed round trip time.
425 		 */
426 		if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) {
427 			if (tp->t_srtt == 0)
428 				tp->t_srtt = tp->t_rtt;
429 			else
430 				tp->t_srtt =
431 				    tcp_alpha * tp->t_srtt +
432 				    (1 - tcp_alpha) * tp->t_rtt;
433 printf("tcp_input: rtt sampled %d, srtt now %d\n", tp->t_rtt, (int)(100* tp->t_srtt));
434 			tp->t_rtt = 0;
435 		}
436 
437 		switch (tp->t_state) {
438 
439 		/*
440 		 * In FIN_WAIT_1 STATE in addition to the processing
441 		 * for the ESTABLISHED state if our FIN is now acknowledged
442 		 * then enter FIN_WAIT_2.
443 		 */
444 		case TCPS_FIN_WAIT_1:
445 			if (ourfinisacked)
446 				tp->t_state = TCPS_FIN_WAIT_2;
447 			break;
448 
449 	 	/*
450 		 * In CLOSING STATE in addition to the processing for
451 		 * the ESTABLISHED state if the ACK acknowledges our FIN
452 		 * then enter the TIME-WAIT state, otherwise ignore
453 		 * the segment.
454 		 */
455 		case TCPS_CLOSING:
456 			if (ourfinisacked) {
457 				tp->t_state = TCPS_TIME_WAIT;
458 				tcp_canceltimers(tp);
459 				tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
460 				soisdisconnected(so);
461 			}
462 			break;
463 
464 		/*
465 		 * The only thing that can arrive in  LAST_ACK state
466 		 * is an acknowledgment of our FIN.  If our FIN is now
467 		 * acknowledged, delete the TCB, enter the closed state
468 		 * and return.
469 		 */
470 		case TCPS_LAST_ACK:
471 			if (ourfinisacked) {
472 printf("tcp_input: LAST ACK close\n");
473 				tcp_close(tp);
474 			}
475 			goto drop;
476 
477 		/*
478 		 * In TIME_WAIT state the only thing that should arrive
479 		 * is a retransmission of the remote FIN.  Acknowledge
480 		 * it and restart the finack timer.
481 		 */
482 		case TCPS_TIME_WAIT:
483 printf("tcp_input: TIME_WAIT restart timer\n");
484 			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
485 			goto dropafterack;
486 		}
487 #undef ourfinisacked
488 	}
489 
490 step6:
491 	/*
492 	 * Update window information.
493 	 */
494 printf("update win wl1 %x ti->ti_seq %x wl2 %x?", tp->snd_wl1, ti->ti_seq, tp->snd_wl2);
495 	if (SEQ_LT(tp->snd_wl1, ti->ti_seq) ||
496 	    tp->snd_wl1==ti->ti_seq && SEQ_LEQ(tp->snd_wl2,ti->ti_seq)) {
497 printf("yes\n");
498 		tp->snd_wnd = ti->ti_win;
499 		tp->snd_wl1 = ti->ti_seq;
500 		tp->snd_wl2 = ti->ti_ack;
501 		if (tp->snd_wnd > 0)
502 			tp->t_timer[TCPT_PERSIST] = 0;
503 	}
504 else printf("no\n");
505 
506 	/*
507 	 * If an URG bit is set in the segment and is greater than the
508 	 * current known urgent pointer, then signal the user that the
509 	 * remote side has out of band data.  This should not happen
510 	 * in CLOSE_WAIT, CLOSING, LAST-ACK or TIME_WAIT STATES since
511 	 * a FIN has been received from the remote side.  In these states
512 	 * we ignore the URG.
513 	 */
514 	if ((tiflags & TH_URG) == 0 && TCPS_HAVERCVDFIN(tp->t_state) == 0)
515 		if (SEQ_GT(ti->ti_urp, tp->rcv_up)) {
516 			tp->rcv_up = ti->ti_urp;
517 #if 0
518 			sohasoutofband(so);		/* XXX */
519 #endif
520 		}
521 
522 	/*
523 	 * Process the segment text, merging it into the TCP sequencing queue,
524 	 * and arranging for acknowledgment of receipt if necessary.
525 	 * This process logically involves adjusting tp->rcv_wnd as data
526 	 * is presented to the user (this happens in tcp_usrreq.c,
527 	 * case PRU_RCVD).  If a FIN has already been received on this
528 	 * connection then we just ignore the text.
529 	 */
530 	if (ti->ti_len && TCPS_HAVERCVDFIN(tp->t_state) == 0) {
531 		off += sizeof (struct ip);		/* drop IP header */
532 		m->m_off += off;
533 		m->m_len -= off;
534 		tiflags = tcp_reass(tp, ti);
535 		tp->t_flags |= TF_ACKNOW;		/* XXX TF_DELACK */
536 	} else {
537 		m_freem(m);
538 	}
539 
540 	/*
541 	 * If FIN is received then if we haven't received SYN and
542 	 * therefore can't validate drop the segment.  Otherwise ACK
543 	 * the FIN and let the user know that the connection is closing.
544 	 */
545 	if ((tiflags & TH_FIN)) {
546 		if (TCPS_HAVERCVDSYN(tp->t_state) == 0)
547 			goto drop;
548 		if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
549 			socantrcvmore(so);
550 			tp->t_flags |= TF_ACKNOW;
551 			tp->rcv_nxt++;
552 		}
553 printf("tcp_input: %x got FIN\n", tp);
554 		switch (tp->t_state) {
555 
556 	 	/*
557 		 * In SYN_RECEIVED and ESTABLISHED STATES
558 		 * enter the CLOSE_WAIT state.
559 		 */
560 		case TCPS_SYN_RECEIVED:
561 		case TCPS_ESTABLISHED:
562 			tp->t_state = TCPS_CLOSE_WAIT;
563 			break;
564 
565 	 	/*
566 		 * If still in FIN_WAIT_1 STATE FIN has not been acked so
567 		 * enter the CLOSING state.
568 		 */
569 		case TCPS_FIN_WAIT_1:
570 			tp->t_state = TCPS_CLOSING;
571 			break;
572 
573 	 	/*
574 		 * In FIN_WAIT_2 state enter the TIME_WAIT state,
575 		 * starting the time-wait timer, turning off the other
576 		 * standard timers.
577 		 */
578 		case TCPS_FIN_WAIT_2:
579 			tp->t_state = TCPS_TIME_WAIT;
580 			tcp_canceltimers(tp);
581 			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
582 			soisdisconnected(so);
583 			break;
584 
585 		/*
586 		 * In TIME_WAIT state restart the 2 MSL time_wait timer.
587 		 */
588 		case TCPS_TIME_WAIT:
589 			tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
590 			break;
591 		}
592 	}
593 
594 	/*
595 	 * Return any desired output.
596 	 */
597 	tcp_output(tp);
598 	return;
599 
600 dropafterack:
601 	/*
602 	 * Generate an ACK dropping incoming segment.
603 	 * Make ACK reflect our state.
604 	 */
605 printf("tcp_input: dropafterack\n");
606 	if (tiflags & TH_RST)
607 		goto drop;
608 	tcp_respond(ti, tp->rcv_nxt, tp->snd_nxt, TH_ACK);
609 	return;
610 
611 dropwithreset:
612 printf("tcp_input: dropwithreset\n");
613 	/*
614 	 * Generate a RST, dropping incoming segment.
615 	 * Make ACK acceptable to originator of segment.
616 	 */
617 	if (tiflags & TH_RST)
618 		goto drop;
619 	if (tiflags & TH_ACK)
620 		tcp_respond(ti, (tcp_seq)0, ti->ti_ack, TH_RST);
621 	else {
622 		if (tiflags & TH_SYN)
623 			ti->ti_len++;
624 		tcp_respond(ti, ti->ti_seq+ti->ti_len, (tcp_seq)0, TH_RST|TH_ACK);
625 	}
626 	return;
627 
628 drop:
629 printf("tcp_input: drop\n");
630 	/*
631 	 * Drop space held by incoming segment and return.
632 	 */
633 	m_freem(m);
634 }
635 
636 /*
637  * Insert segment ti into reassembly queue of tcp with
638  * control block tp.  Return TH_FIN if reassembly now includes
639  * a segment with FIN.
640  */
641 tcp_reass(tp, ti)
642 	register struct tcpcb *tp;
643 	register struct tcpiphdr *ti;
644 {
645 	register struct tcpiphdr *q;
646 	struct socket *so = tp->t_inpcb->inp_socket;
647 	int flags = 0;		/* no FIN */
648 COUNT(TCP_REASS);
649 
650 	/*
651 	 * Call with ti==0 after become established to
652 	 * force pre-ESTABLISHED data up to user socket.
653 	 */
654 	if (ti == 0)
655 		goto present;
656 
657 	/*
658 	 * Find a segment which begins after this one does.
659 	 */
660 	for (q = tp->seg_next; q != (struct tcpiphdr *)tp;
661 	    q = (struct tcpiphdr *)q->ti_next)
662 		if (SEQ_GT(q->ti_seq, ti->ti_seq))
663 			break;
664 
665 	/*
666 	 * If there is a preceding segment, it may provide some of
667 	 * our data already.  If so, drop the data from the incoming
668 	 * segment.  If it provides all of our data, drop us.
669 	 */
670 	if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {
671 		register int i;
672 		q = (struct tcpiphdr *)(q->ti_prev);
673 		/* conversion to int (in i) handles seq wraparound */
674 		i = q->ti_seq + q->ti_len - ti->ti_seq;
675 		if (i > 0) {
676 			if (i >= ti->ti_len)
677 				goto drop;
678 			m_adj(dtom(tp), i);
679 			ti->ti_len -= i;
680 			ti->ti_seq += i;
681 		}
682 		q = (struct tcpiphdr *)(q->ti_next);
683 	}
684 
685 	/*
686 	 * While we overlap succeeding segments trim them or,
687 	 * if they are completely covered, dequeue them.
688 	 */
689 	while (q != (struct tcpiphdr *)tp &&
690 	    SEQ_GT(ti->ti_seq + ti->ti_len, q->ti_seq)) {
691 		register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
692 		if (i < q->ti_len) {
693 			q->ti_len -= i;
694 			m_adj(dtom(q), i);
695 			break;
696 		}
697 		q = (struct tcpiphdr *)q->ti_next;
698 		m_freem(dtom(q->ti_prev));
699 		remque(q->ti_prev);
700 	}
701 
702 	/*
703 	 * Stick new segment in its place.
704 	 */
705 	insque(ti, q->ti_prev);
706 
707 present:
708 	/*
709 	 * Present data to user, advancing rcv_nxt through
710 	 * completed sequence space.
711 	 */
712 	if (tp->t_state < TCPS_ESTABLISHED)
713 		return (0);
714 	ti = tp->seg_next;
715 	while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt) {
716 		tp->rcv_nxt += ti->ti_len;
717 		flags = ti->ti_flags & TH_FIN;
718 printf("move %d bytes to user; rcv_nxt now %x\n", ti->ti_len, tp->rcv_nxt);
719 		remque(ti);
720 		sbappend(&so->so_rcv, dtom(ti));
721 		ti = (struct tcpiphdr *)ti->ti_next;
722 	}
723 	if (so->so_state & SS_CANTRCVMORE)
724 		sbflush(&so->so_rcv);
725 	else
726 		sorwakeup(so);
727 	return (flags);
728 drop:
729 printf("tcp_reass drop\n");
730 	m_freem(dtom(ti));
731 	return (flags);
732 }
733