1*5065Swnj /* tcp_input.c 1.30 81/11/24 */ 24601Swnj 34601Swnj #include "../h/param.h" 44601Swnj #include "../h/systm.h" 54663Swnj #include "../h/mbuf.h" 64663Swnj #include "../h/socket.h" 74803Swnj #include "../h/socketvar.h" 84803Swnj #include "../net/inet.h" 94884Swnj #include "../net/inet_pcb.h" 104803Swnj #include "../net/inet_systm.h" 114803Swnj #include "../net/imp.h" 124803Swnj #include "../net/ip.h" 134899Swnj #include "../net/ip_var.h" 144803Swnj #include "../net/tcp.h" 154803Swnj #include "../net/tcp_fsm.h" 164803Swnj #include "../net/tcp_var.h" 174803Swnj #include "/usr/include/errno.h" 184601Swnj 194679Swnj int tcpcksum = 1; 204601Swnj 214953Swnj struct sockaddr_in tcp_sockaddr = { AF_INET }; 224953Swnj 23*5065Swnj /* 24*5065Swnj * TCP input routine, follows pages 65-76 of the 25*5065Swnj * protocol specification dated September, 1981 very closely. 26*5065Swnj */ 274924Swnj tcp_input(m0) 284924Swnj struct mbuf *m0; 294601Swnj { 304924Swnj register struct tcpiphdr *ti; 314924Swnj struct inpcb *inp; 324924Swnj register struct mbuf *m; 334924Swnj int len, tlen, off; 344924Swnj register struct tcpcb *tp; 354924Swnj register int tiflags; 364803Swnj struct socket *so; 37*5065Swnj seq_t segend; 38*5065Swnj int acceptable; 394924Swnj 404601Swnj COUNT(TCP_INPUT); 414924Swnj /* 424924Swnj * Get ip and tcp header together in first mbuf. 434924Swnj */ 444924Swnj m = m0; 454924Swnj if (m->m_len < sizeof (struct tcpiphdr) && 464924Swnj m_pullup(m, sizeof (struct tcpiphdr)) == 0) { 474924Swnj tcpstat.tcps_hdrops++; 484924Swnj goto bad; 494924Swnj } 505020Sroot ti = mtod(m, struct tcpiphdr *); 515020Sroot if (ti->ti_len > sizeof (struct ip)) 525020Sroot ip_stripoptions((struct ip *)ti, (char *)0); 534601Swnj 544601Swnj /* 554924Swnj * Checksum extended tcp header and data. 564601Swnj */ 574924Swnj tlen = ((struct ip *)ti)->ip_len; 584924Swnj len = sizeof (struct ip) + tlen; 594679Swnj if (tcpcksum) { 604924Swnj ti->ti_next = ti->ti_prev = 0; 614924Swnj ti->ti_x1 = 0; 624953Swnj ti->ti_len = htons((u_short)tlen); 635048Swnj if ((ti->ti_sum = inet_cksum(m, len)) != 0xffff) { 644924Swnj tcpstat.tcps_badsum++; 65*5065Swnj printf("tcp cksum %x\n", ti->ti_sum); 664924Swnj goto bad; 674601Swnj } 684601Swnj } 694601Swnj 704601Swnj /* 714924Swnj * Check that tcp offset makes sense, 724924Swnj * process tcp options and adjust length. 734601Swnj */ 744924Swnj off = ti->ti_off << 2; 754924Swnj if (off < sizeof (struct tcphdr) || off > ti->ti_len) { 764924Swnj tcpstat.tcps_badoff++; 774924Swnj goto bad; 784924Swnj } 794924Swnj ti->ti_len = tlen - off; 804924Swnj /* PROCESS OPTIONS */ 81*5065Swnj tiflags = ti->ti_flags; 824924Swnj 834924Swnj /* 844924Swnj * Locate pcb for segment. 854924Swnj */ 86*5065Swnj inp = in_pcblookup 87*5065Swnj (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport); 88*5065Swnj 89*5065Swnj /* 90*5065Swnj * If the state is CLOSED (i.e., TCB does not exist) then 91*5065Swnj * all data in the incoming segment is discarded. (p. 65). 92*5065Swnj */ 934884Swnj if (inp == 0) 94*5065Swnj goto sendreset; 95*5065Swnj tp = intotcpcb(inp); 96*5065Swnj if (tp == 0) 97*5065Swnj goto sendreset; 984601Swnj 994601Swnj /* 1004924Swnj * Convert tcp protocol specific fields to host format. 1014601Swnj */ 1024924Swnj ti->ti_seq = ntohl(ti->ti_seq); 1034924Swnj ti->ti_ackno = ntohl((n_long)ti->ti_ackno); 1044924Swnj ti->ti_win = ntohs(ti->ti_win); 1054924Swnj ti->ti_urp = ntohs(ti->ti_urp); 1064601Swnj 1074601Swnj /* 108*5065Swnj * Discard ip header, and do tcp input processing. 1094601Swnj */ 110*5065Swnj off += sizeof (struct ip); 111*5065Swnj m->m_off += off; 112*5065Swnj m->m_len -= off; 113*5065Swnj 1144601Swnj switch (tp->t_state) { 1154601Swnj 116*5065Swnj /* 117*5065Swnj * If the state is LISTEN then ignore segment if it contains an RST. 118*5065Swnj * If the segment contains an ACK then it is bad and send a RST. 119*5065Swnj * If it does not contain a SYN then it is not interesting; drop it. 120*5065Swnj * Otherwise initialize tp->rcv_next, and tp->irs, select an initial 121*5065Swnj * tp->iss, and send a segment: 122*5065Swnj * <SEQ=ISS><ACK=RCV>NXT><CTL=SYN,ACK> 123*5065Swnj * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. 124*5065Swnj * Fill in remote peer address fields if not previously specified. 125*5065Swnj * Enter SYN_RECEIVED state, and process any other fields of this 126*5065Swnj * segment in this state. (p. 65) 127*5065Swnj */ 128*5065Swnj case TCPS_LISTEN: 129*5065Swnj if (tiflags & TH_RST) 130*5065Swnj goto drop; 131*5065Swnj if (tiflags & TH_ACK) 132*5065Swnj goto sendrst; 133*5065Swnj if ((tiflags & TH_SYN) == 0) 134*5065Swnj goto drop; 135*5065Swnj tp->rcv_nxt = ti->ti_seq + 1; 136*5065Swnj tp->irs = ti->ti_seq; 137*5065Swnj tp->iss = tcp_selectiss(); 138*5065Swnj tcp_reflect(ti, tp->iss, tp->rcv_next, TH_SYN|TH_ACK); 139*5065Swnj tp->t_state = TCPS_SYN_RECEIVED; 140*5065Swnj tiflags &= ~TH_SYN; tiflags |= TH_RST; 141*5065Swnj if (inp->inp_faddr.s_addr == 0) { 142*5065Swnj inp->inp_faddr = ti->ti_src; 143*5065Swnj inp->inp_fport = ti->ti_sport; 1444601Swnj } 145*5065Swnj break; 1464601Swnj 147*5065Swnj /* 148*5065Swnj * If the state is SYN_SENT: 149*5065Swnj * if seg contains an ACK, but not for our SYN, drop the input. 150*5065Swnj * if seg contains a RST, then drop the connection. 151*5065Swnj * if seg does not contain SYN, then drop it. 152*5065Swnj * Otherwise this is an acceptable SYN segment 153*5065Swnj * initialize tp->rcv_nxt and tp->irs 154*5065Swnj * if seg contains ack then advance tp->snd_una 155*5065Swnj * if SYN has been acked change to ESTABLISHED else SYN_RCVD state 156*5065Swnj * arrange for segment to be acked (eventually) 157*5065Swnj * continue processing rest of data/controls, beginning with URG 158*5065Swnj */ 159*5065Swnj case TCPS_SYN_SENT: 160*5065Swnj if ((tiflags & TH_ACK) && 161*5065Swnj (SEQ_LEQ(ti->ti_ack, tp->iss) || 162*5065Swnj SEQ_GT(ti->ti_ack, tp->snd.nxt))) { 163*5065Swnj tcp_reflect(ti, ti->ti_ack, 0, TH_RST); 164*5065Swnj goto drop; 1654601Swnj } 166*5065Swnj if (tiflags & TH_RST) { 167*5065Swnj if (tiflags & TH_ACK) 168*5065Swnj tcp_drop(tp, ENETRESET); 169*5065Swnj goto drop; 1704601Swnj } 171*5065Swnj if ((tiflags & TH_SYN) == 0) 172*5065Swnj goto drop; 173*5065Swnj tp->rcv_nxt = ti->ti_seq + 1; 174*5065Swnj tp->irs = ti->ti_seq; 175*5065Swnj tp->snd_una = ti->ti_seq; 176*5065Swnj if (SEQ_GT(tp->snd_una, tp->iss)) { 177*5065Swnj tp->t_state = TCPS_ESTABLISHED; 178*5065Swnj tp->t_flags |= TF_OWEACK; 179*5065Swnj goto step6; 180*5065Swnj } 181*5065Swnj tp->t_state = TCPS_SYN_RECEIVED; 182*5065Swnj tcp_reflect(ti, tp->iss, tp->rcv_nxt, TH_SYN|TH_ACK); 183*5065Swnj break; 184*5065Swnj } 1854601Swnj 186*5065Swnj /* 187*5065Swnj * States other than LISTEN or SYN_SENT. 188*5065Swnj * First check that at least some bytes of segment are within 189*5065Swnj * receive window. 190*5065Swnj */ 191*5065Swnj if (tp->rcv_wnd == 0) { 192*5065Swnj /* 193*5065Swnj * If window is closed can only take segments at 194*5065Swnj * window edge, and have to drop data and EOL from 195*5065Swnj * incoming segments. 196*5065Swnj */ 197*5065Swnj if (tp->rcv_nxt != ti->ti_seq) 198*5065Swnj goto dropafterack; 199*5065Swnj if (tp->ti_len > 0) { 200*5065Swnj tp->ti_len = 0; 201*5065Swnj tp->ti_flags &= ~(TH_EOL|TH_FIN); 202*5065Swnj } 203*5065Swnj } else { 204*5065Swnj /* 205*5065Swnj * If segment begins before rcv_next, drop leading 206*5065Swnj * data (and SYN); if nothing left, just ack. 207*5065Swnj */ 208*5065Swnj if (SEQ_GT(tp->rcv_nxt, ti->ti_seq)) { 209*5065Swnj tcpseq_t todrop = tp->rcv_nxt - ti->ti_seq; 210*5065Swnj if (todrop > ti->ti_len) 211*5065Swnj goto dropafterack; 212*5065Swnj m_adj(m, todrop); 213*5065Swnj ti->ti_seq += todrop; 214*5065Swnj ti->ti_len -= todrop; 215*5065Swnj ti->ti_flags &= ~TH_SYN; 216*5065Swnj } 217*5065Swnj /* 218*5065Swnj * If segment ends after window, drop trailing data 219*5065Swnj * (and EOL and FIN); if there would be nothing left, just ack. 220*5065Swnj */ 221*5065Swnj if (SEQ_GT(ti->ti_seq+ti->ti_len, tp->rcv_nxt+tp->rcv_wnd)) { 222*5065Swnj tcpseq_t todrop = 223*5065Swnj ti->ti_seq+ti->ti_len - (tp->rcv_nxt+tp->rcv_wnd); 224*5065Swnj if (todrop > ti->ti_len) 225*5065Swnj goto dropafterack; 226*5065Swnj m_adj(m, -todrop); 227*5065Swnj ti->ti_len -= todrop; 228*5065Swnj ti->ti_flags &= ~(TH_EOL|TH_FIN); 229*5065Swnj } 230*5065Swnj } 2314601Swnj 232*5065Swnj /* 233*5065Swnj * If the RST bit is set examine the state: 234*5065Swnj * SYN_RECEIVED STATE: 235*5065Swnj * If passive open, return to LISTEN state. 236*5065Swnj * If active open, inform user that connection was refused. 237*5065Swnj * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: 238*5065Swnj * Inform user that connection was reset, and close tcb. 239*5065Swnj * CLOSING, LAST_ACK, TIME_WAIT STATES 240*5065Swnj * Close the tcb. 241*5065Swnj */ 242*5065Swnj if (tiflags&TH_RST) switch (tp->t_state) { 243*5065Swnj 244*5065Swnj case TCPS_SYN_RECEIVED: 245*5065Swnj if (inp->inp_socket->so_options & SO_ACCEPTCONN) { 2464601Swnj tp->t_state = LISTEN; 247*5065Swnj inp->inp_fhost->s_addr = 0; 248*5065Swnj goto drop; 2494601Swnj } 250*5065Swnj tcp_drop(tp, EREFUSED); 251*5065Swnj goto drop; 2524601Swnj 253*5065Swnj case TCPS_ESTABLISHED: 254*5065Swnj case TCPS_FIN_WAIT_1: 255*5065Swnj case TCPS_FIN_WAIT_2: 256*5065Swnj case TCPS_CLOSE_WAIT: 257*5065Swnj tcp_drop(tp, ECONNRESET); 258*5065Swnj goto drop; 259*5065Swnj 260*5065Swnj case TCPS_CLOSING: 261*5065Swnj case TCPS_LAST_ACK: 262*5065Swnj case TCPS_TIME_WAIT: 263*5065Swnj tcp_close(tp); 264*5065Swnj goto drop; 2654601Swnj } 2664601Swnj 2674601Swnj /* 268*5065Swnj * If a SYN is in the window, then this is an 269*5065Swnj * error and we send an RST and drop the connection. 2704601Swnj */ 271*5065Swnj if (tiflags & TH_SYN) { 272*5065Swnj tcp_drop(tp, ECONNRESET); 273*5065Swnj goto sendreset; 2744601Swnj } 2754601Swnj 2764601Swnj /* 277*5065Swnj * If the ACK bit is off we drop the segment and return. 2784601Swnj */ 279*5065Swnj if ((tiflags & TI_ACK) == 0) 280*5065Swnj goto drop; 281*5065Swnj 282*5065Swnj /* 283*5065Swnj * Ack processing. 284*5065Swnj */ 2854601Swnj switch (tp->t_state) { 2864601Swnj 287*5065Swnj /* 288*5065Swnj * In SYN_RECEIVED state if the ack ACKs our SYN then enter 289*5065Swnj * ESTABLISHED state and continue processing, othewise 290*5065Swnj * send an RST. 291*5065Swnj */ 292*5065Swnj case TCPS_SYN_RECEIVED: 293*5065Swnj if (SEQ_LEQ(tp->snd_una, ti->ti_ack) && 294*5065Swnj SEQ_LEQ(ti->ti_ack, tp->snd_nxt)) 295*5065Swnj tp->t_state = TCPS_ESTABLISHED; 296*5065Swnj else 297*5065Swnj goto sendreset; 298*5065Swnj /* fall into next case, below... */ 2994601Swnj 300*5065Swnj /* 301*5065Swnj * In ESTABLISHED state: drop duplicate ACKs; ACK out of range 302*5065Swnj * ACKs. If the ack is in the range 303*5065Swnj * tp->snd_una < ti->ti_ack <= tp->snd_nxt 304*5065Swnj * then advance tp->snd_una to ti->ti_ack and drop 305*5065Swnj * data from the retransmission queue. If this ACK reflects 306*5065Swnj * more up to date window information we update our window information. 307*5065Swnj */ 308*5065Swnj case TCPS_ESTABLISHED: 309*5065Swnj case TCPS_FIN_WAIT_1: 310*5065Swnj case TCPS_FIN_WAIT_2: 311*5065Swnj case TCPS_CLOSE_WAIT: 312*5065Swnj case TCPS_CLOSING: 313*5065Swnj if (SEQ_LT(ti->ti_ack, tp->snd_una)) 314*5065Swnj break; 315*5065Swnj if (SEQ_GT(ti->ti_ack, tp->snd_nxt)) 316*5065Swnj goto dropafterack; 317*5065Swnj sbdrop(&so->so_snd, ti->ti_ack - tp->snd_una); 318*5065Swnj tp->snd_una = ti->ti_ack; 319*5065Swnj if (SEQ_LT(tp->snd_wl1, ti->ti_seq) || 320*5065Swnj tp->snd_wl1==ti-ti_seq && SEQ_LEQ(tp->snd_wl2,ti->ti_seq)) { 321*5065Swnj tp->snd_wnd = ti->ti_win; 322*5065Swnj tp->snd_wl1 = ti->ti_seq; 323*5065Swnj tp->snd_wl2 = ti->ti_ack; 3244601Swnj } 3254601Swnj 3264601Swnj switch (tp->t_state) { 3274601Swnj 328*5065Swnj /* 329*5065Swnj * In FIN_WAIT_1 STATE in addition to the processing 330*5065Swnj * for the ESTABLISHED state if our FIN is now acknowledged 331*5065Swnj * then enter FIN_WAIT_2 and continue processing in that state. 332*5065Swnj */ 333*5065Swnj case TCPS_FIN_WAIT_1: 334*5065Swnj if (tcp_finisacked(tp) == 0) 335*5065Swnj break; 336*5065Swnj tp->t_state = TCPS_FIN_WAIT_2; 337*5065Swnj /* fall into ... */ 3384601Swnj 339*5065Swnj /* 340*5065Swnj * In FIN_WAIT_2 STATE in addition to the processing for 341*5065Swnj * the ESTABLISHED state allow the user to close when 342*5065Swnj * the data has drained. 343*5065Swnj */ 344*5065Swnj case TCPS_FIN_WAIT_2: 345*5065Swnj tcp_usrcanclose(tp); 3464601Swnj break; 3474601Swnj 348*5065Swnj /* 349*5065Swnj * In CLOSING STATE in addition to the processing for 350*5065Swnj * the ESTABLISHED state if the ACK acknowledges our FIN 351*5065Swnj * then enter the TIME-WAIT state, otherwise ignore 352*5065Swnj * the segment. 353*5065Swnj */ 354*5065Swnj case TCPS_CLOSING: 355*5065Swnj if (tcp_finisacked(tp)) 356*5065Swnj tp->t_state = TCPS_TIME_WAIT; 3574601Swnj break; 3584601Swnj 359*5065Swnj /* 360*5065Swnj * In LAST_ACK state if our FIN is now acknowledged 361*5065Swnj * then enter the TIME_WAIT state, otherwise ignore the 362*5065Swnj * segment. 363*5065Swnj */ 364*5065Swnj case TCPS_LAST_ACK: 365*5065Swnj if (tcp_finisacked(tp)) 366*5065Swnj tcp_close(tp); 367*5065Swnj goto drop; 3684601Swnj 369*5065Swnj /* 370*5065Swnj * In TIME_WAIT state the only thing that should arrive 371*5065Swnj * is a retransmission of the remote FIN. Acknowledge 372*5065Swnj * it and restart the finack timer. 373*5065Swnj */ 374*5065Swnj case TCPS_TIME_WAIT: 375*5065Swnj tp->t_finack = 2 * TCP_MSL; 376*5065Swnj goto dropafterack; 3774601Swnj } 3784601Swnj 379*5065Swnj step6: 380*5065Swnj /* 381*5065Swnj * If an URG bit is set in the segment and is greater than the 382*5065Swnj * current known urgent pointer, then signal the user that the 383*5065Swnj * remote side has urgent data. This should not happen 384*5065Swnj * in CLOSE_WAIT, CLOSING, LAST-ACK or TIME_WAIT STATES since 385*5065Swnj * a FIN has been received from the remote side. In these states 386*5065Swnj * we ignore the URG. 387*5065Swnj */ 388*5065Swnj if ((tiflags & TH_URG) == 0 && (TCPS_RCVDFIN(tp->t_state) == 0) { 389*5065Swnj if (SEQ_GT(ti->ti_urp, tp->rcv_up) { 390*5065Swnj tp->rcv_up = ti->ti_urp; 391*5065Swnj soisurgendata(so); /* XXX */ 3924601Swnj } 3934601Swnj } 3944601Swnj 3954601Swnj /* 396*5065Swnj * Process the segment text, merging it into the TCP sequencing queue, 397*5065Swnj * and arranging for acknowledgment of receipt if necessary. 398*5065Swnj * This process logically involves adjusting tp->rcv_wnd as data 399*5065Swnj * is presented to the user (this happens in tcp_usrreq.c, 400*5065Swnj * case PRU_RCVD). If a FIN has already been received on this 401*5065Swnj * connection then we just ignore the text. 4024601Swnj */ 403*5065Swnj if (ti->ti_len) { 404*5065Swnj if (TCPS_RCVDFIN(tp->t_state)) 405*5065Swnj goto drop; 406*5065Swnj tiflags = tcp_reass(tp, ti); 407*5065Swnj else 4084924Swnj m_freem(m); 4094601Swnj 4104601Swnj /* 411*5065Swnj * If FIN is received then if we haven't received SYN and 412*5065Swnj * therefore can't validate drop the segment. Otherwise ACK 413*5065Swnj * the FIN and let the user know that the connection is closing. 4144601Swnj */ 415*5065Swnj if ((tiflags & TH_FIN) && TCPS_HAVERCVDSYN(tp->t_state)) { 416*5065Swnj tcp_usrclosing(tp); 417*5065Swnj tp->t_flags |= TF_ACKNOW; 418*5065Swnj tp->rcv_nxt++; 419*5065Swnj switch (tp->t_state) { 4204601Swnj 421*5065Swnj /* 422*5065Swnj * In SYN_RECEIVED and ESTABLISHED STATES 423*5065Swnj * enter the CLOSE_WAIT state. 4244884Swnj */ 425*5065Swnj case TCPS_SYN_RECEIVED: 426*5065Swnj case TCPS_ESTABLISHED: 427*5065Swnj tp->t_state = TCPS_CLOSE_WAIT; 428*5065Swnj break; 4294884Swnj 430*5065Swnj /* 431*5065Swnj * In FIN_WAIT_1 STATE if our FIN has been acked then 432*5065Swnj * enter TIME_WAIT state, starting the associated timer 433*5065Swnj * and turning off all other standard timers. 434*5065Swnj * If FIN has not been acked enter the CLOSING state. 4354884Swnj */ 436*5065Swnj case TCPS_FIN_WAIT_1: 437*5065Swnj if (tcp_finisacked(tp)) { 438*5065Swnj tp->t_state = TCPS_TIME_WAIT; 439*5065Swnj tcp_canceltimers(tp, 0); 440*5065Swnj tp->t_timer[TCPT_FINACK] = TCPSC_2MSL; 441*5065Swnj } else 442*5065Swnj tp->t_state = TCPS_CLOSING; 443*5065Swnj break; 4444601Swnj } 4454601Swnj 446*5065Swnj /* 447*5065Swnj * In FIN_WAIT_2 state enter the TIME_WAIT state, 448*5065Swnj * starting the time-wait timer, turning off the other 449*5065Swnj * standard timers. 450*5065Swnj */ 451*5065Swnj case TCPS_FIN_WAIT_2: 452*5065Swnj tp->t_state = TCPS_FIN_WAIT_2; 453*5065Swnj tcp_canceltimers(tp, 0); 454*5065Swnj tp->t_timer[TCPT_FINACK] = TCPSC_2MSL; 455*5065Swnj break; 456*5065Swnj 4574884Swnj /* 458*5065Swnj * In TIME_WAIT state restart the 2 MSL time_wait timer. 4594884Swnj */ 460*5065Swnj case TCPS_TIME_WAIT: 461*5065Swnj tp->t_timer[TCPT_FINACK] = TCPSC_2MSL; 462*5065Swnj break; 4634601Swnj } 464*5065Swnj return; 465*5065Swnj dropafterack: 466*5065Swnj if ((tiflags & TH_RST) == 0) 467*5065Swnj tcp_reflect(ti, tp->rcv_nxt, tp->snd_nxt, TH_ACK); 468*5065Swnj drop: 469*5065Swnj m_freem(m); 470*5065Swnj return; 471*5065Swnj } 472*5065Swnj 473*5065Swnj /* 474*5065Swnj * Insert segment ti into reassembly queue of tcp with 475*5065Swnj * control block tp. Return TH_FIN if reassembly now includes 476*5065Swnj * a segment with FIN. 477*5065Swnj */ 478*5065Swnj tcp_reass(tp, ti, endp) 479*5065Swnj register struct tcpcb *tp; 480*5065Swnj register struct tcpiphdr *ti; 481*5065Swnj int *endp; 482*5065Swnj { 483*5065Swnj register struct tcpiphdr *q; 484*5065Swnj int flags = 0; /* no FIN */ 485*5065Swnj int overage; 486*5065Swnj 487*5065Swnj /* 488*5065Swnj * If no data in this segment may want 489*5065Swnj * to move data up to socket structure (if 490*5065Swnj * connection is now established). 491*5065Swnj */ 492*5065Swnj if (ti->ti_len == 0) { 493*5065Swnj m_freem(dtom(ti)); 494*5065Swnj goto present; 4954601Swnj } 4964601Swnj 497*5065Swnj /* 498*5065Swnj * Find a segment which begins after this one does. 499*5065Swnj */ 500*5065Swnj for (q = tp->seg_next; q != (struct tcpiphdr *)tp; 501*5065Swnj q = (struct tcpiphdr *)q->ti_next) 502*5065Swnj if (SEQ_GT(q->ti_seq, ti->ti_seq)) 503*5065Swnj break; 5044601Swnj 505*5065Swnj /* 506*5065Swnj * If there is a preceding segment, it may provide some of 507*5065Swnj * our data already. If so, drop the data from the incoming 508*5065Swnj * segment. If it provides all of our data, drop us. 509*5065Swnj */ 510*5065Swnj if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { 511*5065Swnj register int i; 512*5065Swnj q = (struct tcpiphdr *)(q->ti_prev); 513*5065Swnj /* conversion to int (in i) handles seq wraparound */ 514*5065Swnj i = q->ti_seq + q->ti_len - ti->ti_seq; 515*5065Swnj if (i > 0) { 5164924Swnj if (i >= ti->ti_len) 517*5065Swnj goto drop; 518*5065Swnj m_adj(dtom(tp), i); 519*5065Swnj ti->ti_len -= i; 5204924Swnj ti->ti_seq += i; 5214601Swnj } 522*5065Swnj q = (struct tcpiphdr *)(q->ti_next); 523*5065Swnj } 5244601Swnj 525*5065Swnj /* 526*5065Swnj * While we overlap succeeding segments trim them or, 527*5065Swnj * if they are completely covered, dequeue them. 528*5065Swnj */ 529*5065Swnj while (q != (struct tcpiphdr *)tp && 530*5065Swnj SEQ_GT(ti->ti_seq + ti->ti_len, q->ti_seq)) { 531*5065Swnj register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; 532*5065Swnj if (i < q->ti_len) { 533*5065Swnj q->ti_len -= i; 534*5065Swnj m_adj(dtom(q), i); 535*5065Swnj break; 5364601Swnj } 537*5065Swnj q = (struct tcpiphdr *)q->ti_next; 538*5065Swnj m_freem(dtom(q->ti_prev)); 539*5065Swnj remque(q->ti_prev); 540*5065Swnj } 5414601Swnj 542*5065Swnj /* 543*5065Swnj * Stick new segment in its place. 544*5065Swnj */ 545*5065Swnj insque(ti, q->ti_prev); 546*5065Swnj tp->seqcnt += ti->ti_len; 5474601Swnj 548*5065Swnj /* 549*5065Swnj * Calculate available space and discard segments for 550*5065Swnj * which there is too much. 551*5065Swnj */ 552*5065Swnj overage = 553*5065Swnj (so->so_rcv.sb_cc + tp->seqcnt) - so->so_rcv.sb_hiwat; 554*5065Swnj if (overage > 0) { 555*5065Swnj q = tp->seg_prev; 556*5065Swnj for (;;) { 557*5065Swnj register int i = MIN(q->ti_len, overage); 558*5065Swnj overage -= i; 559*5065Swnj tp->seqcnt -= i; 560*5065Swnj q->ti_len -= i; 561*5065Swnj m_adj(dtom(q), -i); 562*5065Swnj if (q->ti_len) 5634645Swnj break; 564*5065Swnj if (q == ti) 565*5065Swnj panic("tcp_text dropall"); 566*5065Swnj q = (struct tcpiphdr *)q->ti_prev; 567*5065Swnj remque(q->ti_next); 5684645Swnj } 5694884Swnj } 570*5065Swnj 571*5065Swnj /* 572*5065Swnj * Advance rcv_next through newly completed sequence space. 573*5065Swnj */ 574*5065Swnj while (ti->ti_seq == tp->rcv_nxt) { 575*5065Swnj tp->rcv_nxt += ti->ti_len; 576*5065Swnj flags = ti->ti_flags & TH_FIN; 577*5065Swnj ti = (struct tcpiphdr *)ti->ti_next; 578*5065Swnj if (ti == (struct tcpiphdr *)tp) 579*5065Swnj break; 5804679Swnj } 5814679Swnj 582*5065Swnj present: 583*5065Swnj /* 584*5065Swnj * Present data to user. 585*5065Swnj */ 586*5065Swnj if (tp->t_state < ESTAB) 587*5065Swnj return (flags); 5884924Swnj ti = tp->seg_next; 5894924Swnj while (ti != (struct tcpiphdr *)tp && ti->ti_seq < tp->rcv_nxt) { 5904924Swnj remque(ti); 5914924Swnj sbappend(&so->so_rcv, dtom(ti)); 5924924Swnj tp->seqcnt -= ti->ti_len; 5934884Swnj if (tp->seqcnt < 0) 594*5065Swnj panic("tcp_reass"); 5954924Swnj ti = (struct tcpiphdr *)ti->ti_next; 5964601Swnj } 5974884Swnj sorwakeup(so); 598*5065Swnj return (flags); 599*5065Swnj drop: 600*5065Swnj m_freem(dtom(ti)); 601*5065Swnj return (flags); 6024601Swnj } 603