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