1*4924Swnj /* tcp_input.c 1.25 81/11/18 */ 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/inet_host.h" 134803Swnj #include "../net/ip.h" 144899Swnj #include "../net/ip_var.h" 154803Swnj #include "../net/tcp.h" 164803Swnj #include "../net/tcp_fsm.h" 174803Swnj #include "../net/tcp_var.h" 184803Swnj #include "/usr/include/errno.h" 194601Swnj 204679Swnj int tcpcksum = 1; 214601Swnj 224884Swnj tcp_drain() 234803Swnj { 244884Swnj register struct inpcb *ip; 254803Swnj 264884Swnj for (ip = tcb.inp_next; ip != &tcb; ip = ip->inp_next) 274884Swnj tcp_drainunack(intotcpcb(ip)); 284803Swnj } 294803Swnj 304884Swnj tcp_drainunack(tp) 314884Swnj register struct tcpcb *tp; 324884Swnj { 334884Swnj register struct mbuf *m; 344884Swnj 354884Swnj for (m = tp->seg_unack; m; m = m->m_act) 364884Swnj m_freem(m); 374884Swnj tp->seg_unack = 0; 384884Swnj } 394884Swnj 404884Swnj tcp_ctlinput(m) 414884Swnj struct mbuf *m; 424884Swnj { 434884Swnj 444884Swnj m_freem(m); 454884Swnj } 464884Swnj 47*4924Swnj tcp_input(m0) 48*4924Swnj struct mbuf *m0; 494601Swnj { 50*4924Swnj register struct tcpiphdr *ti; 51*4924Swnj struct inpcb *inp; 52*4924Swnj register struct mbuf *m; 53*4924Swnj int len, tlen, off; 54*4924Swnj 55*4924Swnj register struct tcpcb *tp; 564697Swnj register int j; 57*4924Swnj register int tiflags; 584601Swnj int nstate; 594803Swnj struct socket *so; 604601Swnj #ifdef TCPDEBUG 614601Swnj struct tcp_debug tdb; 624601Swnj #endif 63*4924Swnj 644601Swnj COUNT(TCP_INPUT); 65*4924Swnj /* 66*4924Swnj * Get ip and tcp header together in first mbuf. 67*4924Swnj */ 68*4924Swnj m = m0; 69*4924Swnj ti = mtod(m, struct tcpiphdr *); 70*4924Swnj if (ti->ti_len > sizeof (struct ip)) 71*4924Swnj ip_stripoptions((struct ip *)ti); 72*4924Swnj if (m->m_len < sizeof (struct tcpiphdr) && 73*4924Swnj m_pullup(m, sizeof (struct tcpiphdr)) == 0) { 74*4924Swnj tcpstat.tcps_hdrops++; 75*4924Swnj goto bad; 76*4924Swnj } 774601Swnj 784601Swnj /* 79*4924Swnj * Checksum extended tcp header and data. 804601Swnj */ 81*4924Swnj tlen = ((struct ip *)ti)->ip_len; 82*4924Swnj len = sizeof (struct ip) + tlen; 834679Swnj if (tcpcksum) { 84*4924Swnj ti->ti_next = ti->ti_prev = 0; 85*4924Swnj ti->ti_x1 = 0; 86*4924Swnj ti->ti_len = htons(tlen); 87*4924Swnj if (ti->ti_sum = inet_cksum(m, len)) { 88*4924Swnj tcpstat.tcps_badsum++; 89*4924Swnj printf("tcp cksum %x\ti", ti->ti_sum); 90*4924Swnj goto bad; 914601Swnj } 924601Swnj } 934601Swnj 944601Swnj /* 95*4924Swnj * Check that tcp offset makes sense, 96*4924Swnj * process tcp options and adjust length. 974601Swnj */ 98*4924Swnj off = ti->ti_off << 2; 99*4924Swnj if (off < sizeof (struct tcphdr) || off > ti->ti_len) { 100*4924Swnj tcpstat.tcps_badoff++; 101*4924Swnj goto bad; 102*4924Swnj } 103*4924Swnj ti->ti_len = tlen - off; 104*4924Swnj /* PROCESS OPTIONS */ 105*4924Swnj 106*4924Swnj /* 107*4924Swnj * Convert addresses and ports to host format. 108*4924Swnj * Locate pcb for segment. 109*4924Swnj */ 110*4924Swnj ti->ti_src.s_addr = ntohl(ti->ti_src.s_addr); 111*4924Swnj ti->ti_dst.s_addr = ntohl(ti->ti_dst.s_addr); 112*4924Swnj ti->ti_sport = ntohs(ti->ti_sport); 113*4924Swnj ti->ti_dport = ntohs(ti->ti_dport); 114*4924Swnj inp = in_pcblookup(&tcb, &ti->ti_src, ti->ti_sport, &ti->ti_dst, ti->ti_dport); 1154884Swnj if (inp == 0) 1164884Swnj goto notwanted; 117*4924Swnj tp = intotcpcb(inp); /* ??? */ 118*4924Swnj if (tp == 0) /* ??? */ 119*4924Swnj goto notwanted; /* ??? */ 1204601Swnj 1214601Swnj /* 122*4924Swnj * Convert tcp protocol specific fields to host format. 1234601Swnj */ 124*4924Swnj ti->ti_seq = ntohl(ti->ti_seq); 125*4924Swnj ti->ti_ackno = ntohl((n_long)ti->ti_ackno); 126*4924Swnj ti->ti_win = ntohs(ti->ti_win); 127*4924Swnj ti->ti_urp = ntohs(ti->ti_urp); 1284601Swnj 1294601Swnj /* 1304601Swnj * Check segment seq # and do rst processing 1314601Swnj */ 132*4924Swnj tiflags = ti->ti_flags; 1334601Swnj switch (tp->t_state) { 1344601Swnj 1354601Swnj case LISTEN: 136*4924Swnj if ((tiflags&TH_ACK) || (tiflags&TH_SYN) == 0) { 137*4924Swnj tcp_sndrst(tp, ti); 138*4924Swnj goto bad; 1394601Swnj } 140*4924Swnj if (tiflags&TH_RST) 141*4924Swnj goto bad; 142*4924Swnj goto good; 1434601Swnj 1444601Swnj case SYN_SENT: 145*4924Swnj if (!ack_ok(tp, ti) || (tiflags&TH_SYN) == 0) { 146*4924Swnj tcp_sndrst(tp, ti); /* 71,72,75 */ 147*4924Swnj goto bad; 1484601Swnj } 149*4924Swnj if (tiflags&TH_RST) { 1504803Swnj tcp_error(tp, ENETRESET); 1514803Swnj tcp_detach(tp); /* 70 */ 1524601Swnj tp->t_state = CLOSED; 153*4924Swnj goto bad; 1544601Swnj } 155*4924Swnj goto good; 1564601Swnj 1574601Swnj default: 158*4924Swnj if ((tiflags&TH_RST) == 0) 1594601Swnj goto common; 160*4924Swnj if (ti->ti_seq < tp->rcv_nxt) /* bad rst */ 161*4924Swnj goto bad; /* 69 */ 1624601Swnj switch (tp->t_state) { 1634601Swnj 1644601Swnj case L_SYN_RCVD: 165*4924Swnj if (ack_ok(tp, ti) == 0) 166*4924Swnj goto bad; /* 69 */ 1674601Swnj tp->t_rexmt = 0; 1684601Swnj tp->t_rexmttl = 0; 1694601Swnj tp->t_persist = 0; 1704909Swnj in_hostfree(inp->inp_fhost); 1714884Swnj inp->inp_fhost = 0; 1724601Swnj tp->t_state = LISTEN; 173*4924Swnj goto bad; 1744601Swnj 1754601Swnj default: 1764803Swnj tcp_error(tp, ENETRESET); 1774803Swnj tcp_detach(tp); /* 66 */ 1784601Swnj tp->t_state = CLOSED; 179*4924Swnj goto bad; 1804601Swnj } 1814601Swnj /*NOTREACHED*/ 1824601Swnj 1834601Swnj case SYN_RCVD: 1844601Swnj common: 185*4924Swnj if (ack_ok(tp, ti) == 0) { 186*4924Swnj tcp_sndrst(tp, ti); /* 74 */ 187*4924Swnj goto bad; 1884601Swnj } 189*4924Swnj if ((tiflags&TH_SYN) == 0 && ti->ti_seq != tp->irs) { 1904679Swnj tcp_sndnull(tp); /* 74 */ 191*4924Swnj goto bad; 1924601Swnj } 193*4924Swnj goto good; 1944601Swnj } 195*4924Swnj bad: 196*4924Swnj m_freem(m); 1974601Swnj return; 1984601Swnj 199*4924Swnj good: 2004601Swnj /* 2014601Swnj * Defer processing if no buffer space for this connection. 2024601Swnj */ 2034884Swnj so = inp->inp_socket; 2044803Swnj if (so->so_rcv.sb_cc >= so->so_rcv.sb_hiwat && 205*4924Swnj ti->ti_len != 0 && mbstat.m_bufs < mbstat.m_lowat) { 2064803Swnj /* 207*4924Swnj m->m_act = (struct mbuf *)0; 2084803Swnj if ((m = tp->seg_unack) != NULL) { 2094601Swnj while (m->m_act != NULL) 2104601Swnj m = m->m_act; 211*4924Swnj m->m_act = m0; 2124601Swnj } else 213*4924Swnj tp->seg_unack = m0; 2144803Swnj */ 215*4924Swnj m_freem(m0); 2164601Swnj return; 2174601Swnj } 2184601Swnj 2194601Swnj /* 2204601Swnj * Discard ip header, and do tcp input processing. 2214601Swnj */ 222*4924Swnj off += sizeof (struct ip); 223*4924Swnj m->m_off += off; 224*4924Swnj m->m_len -= off; 2254601Swnj nstate = tp->t_state; 2264601Swnj tp->tc_flags &= ~TC_NET_KEEP; 2274770Swnj #ifdef KPROF 2284601Swnj acounts[tp->t_state][INRECV]++; 2294770Swnj #endif 2304601Swnj #ifdef TCPDEBUG 2314803Swnj if ((tp->t_socket->so_options & SO_DEBUG) || tcpconsdebug) { 232*4924Swnj tdb_setup(tp, ti, INRECV, &tdb); 2334601Swnj } else 2344601Swnj tdb.td_tod = 0; 2354601Swnj #endif 2364601Swnj switch (tp->t_state) { 2374601Swnj 2384601Swnj case LISTEN: 239*4924Swnj if ((tiflags&TH_SYN) == 0 || 240*4924Swnj ((inp->inp_lhost = in_hostalloc(&ti->ti_src)) == 0)) { 2414601Swnj nstate = EFAILEC; 2424601Swnj goto done; 2434601Swnj } 244*4924Swnj inp->inp_fport = ti->ti_sport; 2454733Swnj tp->t_template = tcp_template(tp); 246*4924Swnj tcp_ctldat(tp, ti, 1); 2474601Swnj if (tp->tc_flags&TC_FIN_RCVD) { 2484601Swnj tp->t_finack = T_2ML; /* 3 */ 2494601Swnj tp->tc_flags &= ~TC_WAITED_2_ML; 2504601Swnj nstate = CLOSE_WAIT; 2514601Swnj } else { 2524884Swnj tp->t_init = T_INIT / 2; /* 4 */ 2534601Swnj nstate = L_SYN_RCVD; 2544601Swnj } 2554601Swnj goto done; 2564601Swnj 2574601Swnj case SYN_SENT: 258*4924Swnj if (!syn_ok(tp, ti)) { 2594601Swnj nstate = EFAILEC; 2604601Swnj goto done; 2614601Swnj } 262*4924Swnj tcp_ctldat(tp, ti, 1); 2634601Swnj if (tp->tc_flags&TC_FIN_RCVD) { 264*4924Swnj if ((tiflags&TH_ACK) == 0) { 2654601Swnj tp->t_finack = T_2ML; /* 9 */ 2664601Swnj tp->tc_flags &= ~TC_WAITED_2_ML; 2674601Swnj } 2684601Swnj nstate = CLOSE_WAIT; 2694601Swnj goto done; 2704601Swnj } 271*4924Swnj nstate = (tiflags&TH_ACK) ? ESTAB : SYN_RCVD; /* 11:8 */ 2724601Swnj goto done; 2734601Swnj 2744601Swnj case SYN_RCVD: 2754601Swnj case L_SYN_RCVD: 276*4924Swnj if ((tiflags&TH_ACK) == 0 || 277*4924Swnj (tiflags&TH_ACK) && ti->ti_ackno <= tp->iss) { 2784601Swnj nstate = EFAILEC; 2794601Swnj goto done; 2804601Swnj } 2814601Swnj goto input; 2824601Swnj 2834601Swnj case ESTAB: 2844601Swnj case FIN_W1: 2854601Swnj case FIN_W2: 2864601Swnj case TIME_WAIT: 2874601Swnj input: 288*4924Swnj tcp_ctldat(tp, ti, 1); /* 39 */ 2894601Swnj switch (tp->t_state) { 2904601Swnj 2914601Swnj case ESTAB: 2924601Swnj if (tp->tc_flags&TC_FIN_RCVD) 2934601Swnj nstate = CLOSE_WAIT; 2944601Swnj break; 2954601Swnj 2964601Swnj case SYN_RCVD: 2974601Swnj case L_SYN_RCVD: 2984601Swnj nstate = (tp->tc_flags&TC_FIN_RCVD) ? 2994601Swnj CLOSE_WAIT : ESTAB; /* 33:5 */ 3004601Swnj break; 3014601Swnj 3024601Swnj case FIN_W1: 303*4924Swnj j = ack_fin(tp, ti); 3044601Swnj if ((tp->tc_flags & TC_FIN_RCVD) == 0) { 3054601Swnj if (j) 3064601Swnj nstate = FIN_W2; /* 27 */ 3074601Swnj break; 3084601Swnj } 3094601Swnj tp->t_finack = T_2ML; 3104601Swnj tp->tc_flags &= ~TC_WAITED_2_ML; 3114730Swnj nstate = j ? TIME_WAIT : CLOSING; /* 28:26 */ 3124601Swnj break; 3134601Swnj 3144601Swnj case FIN_W2: 3154601Swnj if (tp->tc_flags&TC_FIN_RCVD) { 3164601Swnj tp->t_finack = T_2ML; /* 29 */ 3174601Swnj tp->tc_flags &= ~TC_WAITED_2_ML; 3184601Swnj nstate = TIME_WAIT; 3194601Swnj break; 3204601Swnj } 3214601Swnj break; 3224601Swnj } 3234601Swnj goto done; 3244601Swnj 3254601Swnj case CLOSE_WAIT: 326*4924Swnj if (tiflags&TH_FIN) { 327*4924Swnj if ((tiflags&TH_ACK) && 328*4924Swnj ti->ti_ackno <= tp->seq_fin) { 329*4924Swnj tcp_ctldat(tp, ti, 0); /* 30 */ 3304601Swnj tp->t_finack = T_2ML; 3314601Swnj tp->tc_flags &= ~TC_WAITED_2_ML; 3324601Swnj } else 3334909Swnj (void) tcp_sndctl(tp); /* 31 */ 3344601Swnj goto done; 3354601Swnj } 3364601Swnj goto input; 3374601Swnj 3384730Swnj case CLOSING: 339*4924Swnj j = ack_fin(tp, ti); 340*4924Swnj if (tiflags&TH_FIN) { 341*4924Swnj tcp_ctldat(tp, ti, 0); 3424601Swnj tp->t_finack = T_2ML; 3434601Swnj tp->tc_flags &= ~TC_WAITED_2_ML; 3444601Swnj if (j) 3454601Swnj nstate = TIME_WAIT; /* 23 */ 3464601Swnj goto done; 3474601Swnj } 3484601Swnj if (j) { 3494601Swnj if (tp->tc_flags&TC_WAITED_2_ML) 3504601Swnj if (rcv_empty(tp)) { 3514884Swnj sorwakeup(inp->inp_socket); 3524803Swnj nstate = CLOSED; /* 15 */ 3534601Swnj } else 3544601Swnj nstate = RCV_WAIT; /* 18 */ 3554601Swnj else 3564601Swnj nstate = TIME_WAIT; 3574601Swnj goto done; 3584601Swnj } 3594601Swnj goto input; 3604601Swnj 3614730Swnj case LAST_ACK: 362*4924Swnj if (ack_fin(tp, ti)) { 3634884Swnj if (rcv_empty(tp)) { /* 16 */ 3644884Swnj sorwakeup(inp->inp_socket); 3654601Swnj nstate = CLOSED; 3664601Swnj } else 3674601Swnj nstate = RCV_WAIT; /* 19 */ 3684601Swnj goto done; 3694601Swnj } 370*4924Swnj if (tiflags&TH_FIN) { 3714909Swnj (void) tcp_sndctl(tp); /* 31 */ 3724601Swnj goto done; 3734601Swnj } 3744601Swnj goto input; 3754601Swnj 3764601Swnj case RCV_WAIT: 377*4924Swnj if ((tiflags&TH_FIN) && (tiflags&TH_ACK) && 378*4924Swnj ti->ti_ackno <= tp->seq_fin) { 379*4924Swnj tcp_ctldat(tp, ti, 0); 3804601Swnj tp->t_finack = T_2ML; 3814601Swnj tp->tc_flags &= ~TC_WAITED_2_ML; /* 30 */ 3824601Swnj } 3834601Swnj goto done; 3844601Swnj } 3854601Swnj panic("tcp_input"); 3864601Swnj done: 3874601Swnj 3884601Swnj /* 3894601Swnj * Done with state*input specific processing. 3904601Swnj * Form trace records, free input if not needed, 3914601Swnj * and enter new state. 3924601Swnj */ 3934601Swnj #ifdef TCPDEBUG 3944604Swnj if (tdb.td_tod) 3954604Swnj tdb_stuff(&tdb, nstate); 3964601Swnj #endif 3974601Swnj switch (nstate) { 3984601Swnj 3994601Swnj case EFAILEC: 400*4924Swnj m_freem(m); 4014601Swnj return; 4024601Swnj 4034601Swnj default: 4044601Swnj tp->t_state = nstate; 4054601Swnj /* fall into ... */ 4064601Swnj 4074601Swnj case CLOSED: 4084601Swnj /* IF CLOSED CANT LOOK AT tc_flags */ 409*4924Swnj if ((tp->tc_flags&TC_NET_KEEP) == 0) { 410*4924Swnj register struct mbuf *n; 4114690Swnj /* inline expansion of m_freem */ 412*4924Swnj while (m) { 413*4924Swnj MFREE(n, m); 414*4924Swnj m = n; 4154690Swnj } 416*4924Swnj } 4174601Swnj return; 4184601Swnj } 4194601Swnj /* NOTREACHED */ 4204601Swnj 4214601Swnj /* 4224601Swnj * Unwanted packed; free everything 4234601Swnj * but the header and return an rst. 4244601Swnj */ 4254601Swnj notwanted: 426*4924Swnj m_freem(m->m_next); 427*4924Swnj m->m_next = NULL; 428*4924Swnj m->m_len = sizeof(struct tcpiphdr); 4294601Swnj #define xchg(a,b) j=a; a=b; b=j 430*4924Swnj xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr); 431*4924Swnj xchg(ti->ti_dport, ti->ti_sport); 4324601Swnj #undef xchg 433*4924Swnj if (tiflags&TH_ACK) 434*4924Swnj ti->ti_seq = ti->ti_ackno; 4354601Swnj else { 436*4924Swnj ti->ti_ackno = htonl(ntohl(ti->ti_seq) + ti->ti_len); 437*4924Swnj ti->ti_seq = 0; 4384601Swnj } 439*4924Swnj ti->ti_flags = ((tiflags & TH_ACK) ? 0 : TH_ACK) | TH_RST; 440*4924Swnj ti->ti_len = htons(TCPSIZE); 441*4924Swnj ti->ti_off = 5; 442*4924Swnj ti->ti_sum = inet_cksum(m, sizeof(struct tcpiphdr)); 443*4924Swnj ((struct ip *)ti)->ip_len = sizeof(struct tcpiphdr); 444*4924Swnj ip_output(m); 445*4924Swnj tcpstat.tcps_badsegs++; 4464601Swnj } 4474601Swnj 4484884Swnj tcp_ctldat(tp, n0, dataok) 4494884Swnj register struct tcpcb *tp; 4504884Swnj struct tcpiphdr *n0; 4514884Swnj int dataok; 4524601Swnj { 453*4924Swnj register struct tcpiphdr *ti = n0; 454*4924Swnj register int tiflags = ti->ti_flags; 4554884Swnj struct socket *so = tp->t_inpcb->inp_socket; 456*4924Swnj seq_t past = ti->ti_seq + ti->ti_len; 4574884Swnj seq_t urgent; 4584679Swnj int sent; 4594679Swnj COUNT(TCP_CTLDAT); 4604601Swnj 461*4924Swnj if (tiflags & TH_URG) 462*4924Swnj urgent = ti->ti_seq + ti->ti_urp; 4634884Swnj tp->tc_flags &= ~(TC_ACK_DUE|TC_NEW_WINDOW); 4644601Swnj /* syn */ 465*4924Swnj if ((tp->tc_flags&TC_SYN_RCVD) == 0 && (tiflags&TH_SYN)) { 466*4924Swnj tp->irs = ti->ti_seq; 467*4924Swnj tp->rcv_nxt = ti->ti_seq + 1; 4684601Swnj tp->snd_wl = tp->rcv_urp = tp->irs; 4694601Swnj tp->tc_flags |= (TC_SYN_RCVD|TC_ACK_DUE); 4704601Swnj } 4714601Swnj /* ack */ 472*4924Swnj if ((tiflags&TH_ACK) && (tp->tc_flags&TC_SYN_RCVD) && 473*4924Swnj ti->ti_ackno > tp->snd_una) { 4744884Swnj /* 4754884Swnj * Reflect newly acknowledged data. 4764884Swnj */ 477*4924Swnj tp->snd_una = ti->ti_ackno; 4784601Swnj if (tp->snd_una > tp->snd_nxt) 4794601Swnj tp->snd_nxt = tp->snd_una; 4804884Swnj 4814884Swnj /* 4824884Swnj * If timed msg acked, update retransmit time value. 4834884Swnj */ 4844601Swnj if ((tp->tc_flags&TC_SYN_ACKED) && 4854601Swnj tp->snd_una > tp->t_xmt_val) { 4864884Swnj /* NEED SMOOTHING HERE */ 4874601Swnj tp->t_xmtime = (tp->t_xmt != 0 ? tp->t_xmt : T_REXMT); 4884601Swnj if (tp->t_xmtime > T_REMAX) 4894601Swnj tp->t_xmtime = T_REMAX; 4904601Swnj } 4914601Swnj 4924884Swnj /* 4934884Swnj * Remove acked data from send buf 4944884Swnj */ 4954909Swnj sbdrop(&so->so_snd, (int)(tp->snd_una - tp->snd_off)); 4964601Swnj tp->snd_off = tp->snd_una; 4974601Swnj if ((tp->tc_flags&TC_SYN_ACKED) == 0 && 4984601Swnj (tp->snd_una > tp->iss)) { 4994601Swnj tp->tc_flags |= TC_SYN_ACKED; 5004601Swnj tp->t_init = 0; 5014601Swnj } 5024601Swnj if (tp->seq_fin != tp->iss && tp->snd_una > tp->seq_fin) 5034601Swnj tp->tc_flags &= ~TC_SND_FIN; 5044601Swnj tp->t_rexmt = 0; 5054601Swnj tp->t_rexmttl = 0; 5064601Swnj tp->tc_flags |= TC_CANCELLED; 5074884Swnj sowwakeup(tp->t_inpcb->inp_socket); 5084601Swnj } 5094601Swnj /* win */ 510*4924Swnj if ((tp->tc_flags & TC_SYN_RCVD) && ti->ti_seq >= tp->snd_wl) { 511*4924Swnj tp->snd_wl = ti->ti_seq; 512*4924Swnj tp->snd_wnd = ti->ti_win; 5134601Swnj tp->tc_flags |= TC_NEW_WINDOW; 5144601Swnj tp->t_persist = 0; 5154601Swnj } 5164601Swnj /* text */ 517*4924Swnj if (dataok && ti->ti_len) { 5184909Swnj register struct tcpiphdr *q; 5194884Swnj int overage; 5204601Swnj 5214884Swnj /* eol */ 522*4924Swnj if ((tiflags&TH_EOL)) { 5234884Swnj register struct mbuf *m; 524*4924Swnj for (m = dtom(ti); m->m_next; m = m->m_next) 5254884Swnj ; 5264884Swnj m->m_act = (struct mbuf *)(mtod(m, caddr_t) - 1); 5274884Swnj } 5284601Swnj 5294884Swnj /* text */ 5304884Swnj /* 5314884Swnj * Discard duplicate data already passed to user. 5324884Swnj */ 533*4924Swnj if (SEQ_LT(ti->ti_seq, tp->rcv_nxt)) { 534*4924Swnj register int i = tp->rcv_nxt - ti->ti_seq; 535*4924Swnj if (i >= ti->ti_len) 5364884Swnj goto notext; 537*4924Swnj ti->ti_seq += i; 538*4924Swnj ti->ti_len -= i; 539*4924Swnj m_adj(dtom(ti), i); 5404601Swnj } 5414601Swnj 5424884Swnj /* 5434884Swnj * Find a segment which begins after this one does. 5444884Swnj */ 5454884Swnj for (q = tp->seg_next; q != (struct tcpiphdr *)tp; 5464899Swnj q = (struct tcpiphdr *)q->ti_next) 547*4924Swnj if (SEQ_GT(q->ti_seq, ti->ti_seq)) 5484884Swnj break; 5494884Swnj 5504884Swnj /* 5514884Swnj * If there is a preceding segment, it may provide some of 5524884Swnj * our data already. If so, drop the data from the incoming 5534884Swnj * segment. If it provides all of our data, drop us. 5544884Swnj */ 5554899Swnj if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { 5564899Swnj register int i; 5574899Swnj q = (struct tcpiphdr *)(q->ti_prev); 5584884Swnj /* conversion to int (in i) handles seq wraparound */ 559*4924Swnj i = q->ti_seq + q->ti_len - ti->ti_seq; 5604884Swnj if (i > 0) { 561*4924Swnj if (i >= ti->ti_len) 5624884Swnj goto notext; 5634884Swnj /* w/o setting TC_NET_KEEP */ 5644884Swnj m_adj(dtom(tp), i); 565*4924Swnj ti->ti_len -= i; 566*4924Swnj ti->ti_seq += i; 5674884Swnj } 5684899Swnj q = (struct tcpiphdr *)(q->ti_next); 5694601Swnj } 5704601Swnj 5714884Swnj /* 5724884Swnj * While we overlap succeeding segments trim them or, 5734884Swnj * if they are completely covered, dequeue them. 5744884Swnj */ 5754884Swnj while (q != (struct tcpiphdr *)tp && 576*4924Swnj SEQ_GT(ti->ti_seq + ti->ti_len, q->ti_seq)) { 577*4924Swnj register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; 5784899Swnj if (i < q->ti_len) { 5794899Swnj q->ti_len -= i; 5804884Swnj m_adj(dtom(q), i); 5814884Swnj break; 5824884Swnj } 5834899Swnj q = (struct tcpiphdr *)q->ti_next; 5844899Swnj m_freem(dtom(q->ti_prev)); 5854899Swnj remque(q->ti_prev); 5864884Swnj } 5874601Swnj 5884884Swnj /* 5894884Swnj * Stick new segment in its place. 5904884Swnj */ 591*4924Swnj insque(ti, q->ti_prev); 592*4924Swnj tp->seqcnt += ti->ti_len; 5934884Swnj 5944884Swnj /* 5954884Swnj * Calculate available space and discard segments for 5964884Swnj * which there is too much. 5974884Swnj */ 5984884Swnj overage = 5994884Swnj (so->so_rcv.sb_cc /*XXX+tp->rcv_seqcnt*/) - so->so_rcv.sb_hiwat; 6004884Swnj if (overage > 0) { 6014884Swnj q = tp->seg_prev; 6024884Swnj for (;;) { 6034899Swnj register int i = MIN(q->ti_len, overage); 6044884Swnj overage -= i; 6054899Swnj q->ti_len -= i; 6064909Swnj m_adj(dtom(q), -i); 6074899Swnj if (q->ti_len) 6084884Swnj break; 609*4924Swnj if (q == ti) 6104884Swnj panic("tcp_text dropall"); 6114899Swnj q = (struct tcpiphdr *)q->ti_prev; 6124899Swnj remque(q->ti_next); 6134884Swnj } 6144884Swnj } 6154884Swnj 6164884Swnj /* 6174884Swnj * Advance rcv_next through newly completed sequence space. 6184884Swnj */ 619*4924Swnj while (ti->ti_seq == tp->rcv_nxt) { 620*4924Swnj tp->rcv_nxt += ti->ti_len; 621*4924Swnj ti = (struct tcpiphdr *)ti->ti_next; 622*4924Swnj if (ti == (struct tcpiphdr *)tp) 6234645Swnj break; 6244645Swnj } 6254679Swnj /* urg */ 626*4924Swnj if (tiflags&TH_URG) { 6274884Swnj /* ... */ 6284884Swnj if (SEQ_GT(urgent, tp->rcv_urp)) 6294803Swnj tp->rcv_urp = urgent; 6304679Swnj } 6314884Swnj tp->tc_flags |= (TC_ACK_DUE|TC_NET_KEEP); 6324884Swnj } 6334884Swnj notext: 6344679Swnj /* fin */ 635*4924Swnj if ((tiflags&TH_FIN) && past == tp->rcv_nxt) { 6364884Swnj if ((tp->tc_flags&TC_FIN_RCVD) == 0) { 6374884Swnj tp->tc_flags |= TC_FIN_RCVD; 6384884Swnj sorwakeup(so); 6394884Swnj tp->rcv_nxt++; 6404803Swnj } 6414884Swnj tp->tc_flags |= TC_ACK_DUE; 6424679Swnj } 6434679Swnj /* respond */ 6444679Swnj sent = 0; 6454679Swnj if (tp->tc_flags&TC_ACK_DUE) 6464679Swnj sent = tcp_sndctl(tp); 6474803Swnj else if ((tp->tc_flags&TC_NEW_WINDOW)) 6484884Swnj if (tp->snd_nxt <= tp->snd_off + so->so_snd.sb_cc || 6494803Swnj (tp->tc_flags&TC_SND_FIN)) 6504679Swnj sent = tcp_send(tp); 6514679Swnj 6524679Swnj /* set for retrans */ 6534679Swnj if (!sent && tp->snd_una < tp->snd_nxt && 6544679Swnj (tp->tc_flags&TC_CANCELLED)) { 6554679Swnj tp->t_rexmt = tp->t_xmtime; 6564679Swnj tp->t_rexmttl = T_REXMTTL; 6574679Swnj tp->t_rexmt_val = tp->t_rtl_val = tp->snd_lst; 6584679Swnj tp->tc_flags &= ~TC_CANCELLED; 6594679Swnj } 6604690Swnj /* present data to user */ 6614656Swnj if ((tp->tc_flags&TC_SYN_ACKED) == 0) 6624601Swnj return; 663*4924Swnj ti = tp->seg_next; 664*4924Swnj while (ti != (struct tcpiphdr *)tp && ti->ti_seq < tp->rcv_nxt) { 665*4924Swnj remque(ti); 666*4924Swnj sbappend(&so->so_rcv, dtom(ti)); 667*4924Swnj tp->seqcnt -= ti->ti_len; 6684884Swnj if (tp->seqcnt < 0) 6694884Swnj panic("tcp_input present"); 670*4924Swnj ti = (struct tcpiphdr *)ti->ti_next; 6714601Swnj } 6724884Swnj sorwakeup(so); 6734601Swnj } 674