1 /* tcp_input.c 1.25 81/11/18 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mbuf.h" 6 #include "../h/socket.h" 7 #include "../h/socketvar.h" 8 #include "../net/inet.h" 9 #include "../net/inet_pcb.h" 10 #include "../net/inet_systm.h" 11 #include "../net/imp.h" 12 #include "../net/inet_host.h" 13 #include "../net/ip.h" 14 #include "../net/ip_var.h" 15 #include "../net/tcp.h" 16 #include "../net/tcp_fsm.h" 17 #include "../net/tcp_var.h" 18 #include "/usr/include/errno.h" 19 20 int tcpcksum = 1; 21 22 tcp_drain() 23 { 24 register struct inpcb *ip; 25 26 for (ip = tcb.inp_next; ip != &tcb; ip = ip->inp_next) 27 tcp_drainunack(intotcpcb(ip)); 28 } 29 30 tcp_drainunack(tp) 31 register struct tcpcb *tp; 32 { 33 register struct mbuf *m; 34 35 for (m = tp->seg_unack; m; m = m->m_act) 36 m_freem(m); 37 tp->seg_unack = 0; 38 } 39 40 tcp_ctlinput(m) 41 struct mbuf *m; 42 { 43 44 m_freem(m); 45 } 46 47 tcp_input(m0) 48 struct mbuf *m0; 49 { 50 register struct tcpiphdr *ti; 51 struct inpcb *inp; 52 register struct mbuf *m; 53 int len, tlen, off; 54 55 register struct tcpcb *tp; 56 register int j; 57 register int tiflags; 58 int nstate; 59 struct socket *so; 60 #ifdef TCPDEBUG 61 struct tcp_debug tdb; 62 #endif 63 64 COUNT(TCP_INPUT); 65 /* 66 * Get ip and tcp header together in first mbuf. 67 */ 68 m = m0; 69 ti = mtod(m, struct tcpiphdr *); 70 if (ti->ti_len > sizeof (struct ip)) 71 ip_stripoptions((struct ip *)ti); 72 if (m->m_len < sizeof (struct tcpiphdr) && 73 m_pullup(m, sizeof (struct tcpiphdr)) == 0) { 74 tcpstat.tcps_hdrops++; 75 goto bad; 76 } 77 78 /* 79 * Checksum extended tcp header and data. 80 */ 81 tlen = ((struct ip *)ti)->ip_len; 82 len = sizeof (struct ip) + tlen; 83 if (tcpcksum) { 84 ti->ti_next = ti->ti_prev = 0; 85 ti->ti_x1 = 0; 86 ti->ti_len = htons(tlen); 87 if (ti->ti_sum = inet_cksum(m, len)) { 88 tcpstat.tcps_badsum++; 89 printf("tcp cksum %x\ti", ti->ti_sum); 90 goto bad; 91 } 92 } 93 94 /* 95 * Check that tcp offset makes sense, 96 * process tcp options and adjust length. 97 */ 98 off = ti->ti_off << 2; 99 if (off < sizeof (struct tcphdr) || off > ti->ti_len) { 100 tcpstat.tcps_badoff++; 101 goto bad; 102 } 103 ti->ti_len = tlen - off; 104 /* PROCESS OPTIONS */ 105 106 /* 107 * Convert addresses and ports to host format. 108 * Locate pcb for segment. 109 */ 110 ti->ti_src.s_addr = ntohl(ti->ti_src.s_addr); 111 ti->ti_dst.s_addr = ntohl(ti->ti_dst.s_addr); 112 ti->ti_sport = ntohs(ti->ti_sport); 113 ti->ti_dport = ntohs(ti->ti_dport); 114 inp = in_pcblookup(&tcb, &ti->ti_src, ti->ti_sport, &ti->ti_dst, ti->ti_dport); 115 if (inp == 0) 116 goto notwanted; 117 tp = intotcpcb(inp); /* ??? */ 118 if (tp == 0) /* ??? */ 119 goto notwanted; /* ??? */ 120 121 /* 122 * Convert tcp protocol specific fields to host format. 123 */ 124 ti->ti_seq = ntohl(ti->ti_seq); 125 ti->ti_ackno = ntohl((n_long)ti->ti_ackno); 126 ti->ti_win = ntohs(ti->ti_win); 127 ti->ti_urp = ntohs(ti->ti_urp); 128 129 /* 130 * Check segment seq # and do rst processing 131 */ 132 tiflags = ti->ti_flags; 133 switch (tp->t_state) { 134 135 case LISTEN: 136 if ((tiflags&TH_ACK) || (tiflags&TH_SYN) == 0) { 137 tcp_sndrst(tp, ti); 138 goto bad; 139 } 140 if (tiflags&TH_RST) 141 goto bad; 142 goto good; 143 144 case SYN_SENT: 145 if (!ack_ok(tp, ti) || (tiflags&TH_SYN) == 0) { 146 tcp_sndrst(tp, ti); /* 71,72,75 */ 147 goto bad; 148 } 149 if (tiflags&TH_RST) { 150 tcp_error(tp, ENETRESET); 151 tcp_detach(tp); /* 70 */ 152 tp->t_state = CLOSED; 153 goto bad; 154 } 155 goto good; 156 157 default: 158 if ((tiflags&TH_RST) == 0) 159 goto common; 160 if (ti->ti_seq < tp->rcv_nxt) /* bad rst */ 161 goto bad; /* 69 */ 162 switch (tp->t_state) { 163 164 case L_SYN_RCVD: 165 if (ack_ok(tp, ti) == 0) 166 goto bad; /* 69 */ 167 tp->t_rexmt = 0; 168 tp->t_rexmttl = 0; 169 tp->t_persist = 0; 170 in_hostfree(inp->inp_fhost); 171 inp->inp_fhost = 0; 172 tp->t_state = LISTEN; 173 goto bad; 174 175 default: 176 tcp_error(tp, ENETRESET); 177 tcp_detach(tp); /* 66 */ 178 tp->t_state = CLOSED; 179 goto bad; 180 } 181 /*NOTREACHED*/ 182 183 case SYN_RCVD: 184 common: 185 if (ack_ok(tp, ti) == 0) { 186 tcp_sndrst(tp, ti); /* 74 */ 187 goto bad; 188 } 189 if ((tiflags&TH_SYN) == 0 && ti->ti_seq != tp->irs) { 190 tcp_sndnull(tp); /* 74 */ 191 goto bad; 192 } 193 goto good; 194 } 195 bad: 196 m_freem(m); 197 return; 198 199 good: 200 /* 201 * Defer processing if no buffer space for this connection. 202 */ 203 so = inp->inp_socket; 204 if (so->so_rcv.sb_cc >= so->so_rcv.sb_hiwat && 205 ti->ti_len != 0 && mbstat.m_bufs < mbstat.m_lowat) { 206 /* 207 m->m_act = (struct mbuf *)0; 208 if ((m = tp->seg_unack) != NULL) { 209 while (m->m_act != NULL) 210 m = m->m_act; 211 m->m_act = m0; 212 } else 213 tp->seg_unack = m0; 214 */ 215 m_freem(m0); 216 return; 217 } 218 219 /* 220 * Discard ip header, and do tcp input processing. 221 */ 222 off += sizeof (struct ip); 223 m->m_off += off; 224 m->m_len -= off; 225 nstate = tp->t_state; 226 tp->tc_flags &= ~TC_NET_KEEP; 227 #ifdef KPROF 228 acounts[tp->t_state][INRECV]++; 229 #endif 230 #ifdef TCPDEBUG 231 if ((tp->t_socket->so_options & SO_DEBUG) || tcpconsdebug) { 232 tdb_setup(tp, ti, INRECV, &tdb); 233 } else 234 tdb.td_tod = 0; 235 #endif 236 switch (tp->t_state) { 237 238 case LISTEN: 239 if ((tiflags&TH_SYN) == 0 || 240 ((inp->inp_lhost = in_hostalloc(&ti->ti_src)) == 0)) { 241 nstate = EFAILEC; 242 goto done; 243 } 244 inp->inp_fport = ti->ti_sport; 245 tp->t_template = tcp_template(tp); 246 tcp_ctldat(tp, ti, 1); 247 if (tp->tc_flags&TC_FIN_RCVD) { 248 tp->t_finack = T_2ML; /* 3 */ 249 tp->tc_flags &= ~TC_WAITED_2_ML; 250 nstate = CLOSE_WAIT; 251 } else { 252 tp->t_init = T_INIT / 2; /* 4 */ 253 nstate = L_SYN_RCVD; 254 } 255 goto done; 256 257 case SYN_SENT: 258 if (!syn_ok(tp, ti)) { 259 nstate = EFAILEC; 260 goto done; 261 } 262 tcp_ctldat(tp, ti, 1); 263 if (tp->tc_flags&TC_FIN_RCVD) { 264 if ((tiflags&TH_ACK) == 0) { 265 tp->t_finack = T_2ML; /* 9 */ 266 tp->tc_flags &= ~TC_WAITED_2_ML; 267 } 268 nstate = CLOSE_WAIT; 269 goto done; 270 } 271 nstate = (tiflags&TH_ACK) ? ESTAB : SYN_RCVD; /* 11:8 */ 272 goto done; 273 274 case SYN_RCVD: 275 case L_SYN_RCVD: 276 if ((tiflags&TH_ACK) == 0 || 277 (tiflags&TH_ACK) && ti->ti_ackno <= tp->iss) { 278 nstate = EFAILEC; 279 goto done; 280 } 281 goto input; 282 283 case ESTAB: 284 case FIN_W1: 285 case FIN_W2: 286 case TIME_WAIT: 287 input: 288 tcp_ctldat(tp, ti, 1); /* 39 */ 289 switch (tp->t_state) { 290 291 case ESTAB: 292 if (tp->tc_flags&TC_FIN_RCVD) 293 nstate = CLOSE_WAIT; 294 break; 295 296 case SYN_RCVD: 297 case L_SYN_RCVD: 298 nstate = (tp->tc_flags&TC_FIN_RCVD) ? 299 CLOSE_WAIT : ESTAB; /* 33:5 */ 300 break; 301 302 case FIN_W1: 303 j = ack_fin(tp, ti); 304 if ((tp->tc_flags & TC_FIN_RCVD) == 0) { 305 if (j) 306 nstate = FIN_W2; /* 27 */ 307 break; 308 } 309 tp->t_finack = T_2ML; 310 tp->tc_flags &= ~TC_WAITED_2_ML; 311 nstate = j ? TIME_WAIT : CLOSING; /* 28:26 */ 312 break; 313 314 case FIN_W2: 315 if (tp->tc_flags&TC_FIN_RCVD) { 316 tp->t_finack = T_2ML; /* 29 */ 317 tp->tc_flags &= ~TC_WAITED_2_ML; 318 nstate = TIME_WAIT; 319 break; 320 } 321 break; 322 } 323 goto done; 324 325 case CLOSE_WAIT: 326 if (tiflags&TH_FIN) { 327 if ((tiflags&TH_ACK) && 328 ti->ti_ackno <= tp->seq_fin) { 329 tcp_ctldat(tp, ti, 0); /* 30 */ 330 tp->t_finack = T_2ML; 331 tp->tc_flags &= ~TC_WAITED_2_ML; 332 } else 333 (void) tcp_sndctl(tp); /* 31 */ 334 goto done; 335 } 336 goto input; 337 338 case CLOSING: 339 j = ack_fin(tp, ti); 340 if (tiflags&TH_FIN) { 341 tcp_ctldat(tp, ti, 0); 342 tp->t_finack = T_2ML; 343 tp->tc_flags &= ~TC_WAITED_2_ML; 344 if (j) 345 nstate = TIME_WAIT; /* 23 */ 346 goto done; 347 } 348 if (j) { 349 if (tp->tc_flags&TC_WAITED_2_ML) 350 if (rcv_empty(tp)) { 351 sorwakeup(inp->inp_socket); 352 nstate = CLOSED; /* 15 */ 353 } else 354 nstate = RCV_WAIT; /* 18 */ 355 else 356 nstate = TIME_WAIT; 357 goto done; 358 } 359 goto input; 360 361 case LAST_ACK: 362 if (ack_fin(tp, ti)) { 363 if (rcv_empty(tp)) { /* 16 */ 364 sorwakeup(inp->inp_socket); 365 nstate = CLOSED; 366 } else 367 nstate = RCV_WAIT; /* 19 */ 368 goto done; 369 } 370 if (tiflags&TH_FIN) { 371 (void) tcp_sndctl(tp); /* 31 */ 372 goto done; 373 } 374 goto input; 375 376 case RCV_WAIT: 377 if ((tiflags&TH_FIN) && (tiflags&TH_ACK) && 378 ti->ti_ackno <= tp->seq_fin) { 379 tcp_ctldat(tp, ti, 0); 380 tp->t_finack = T_2ML; 381 tp->tc_flags &= ~TC_WAITED_2_ML; /* 30 */ 382 } 383 goto done; 384 } 385 panic("tcp_input"); 386 done: 387 388 /* 389 * Done with state*input specific processing. 390 * Form trace records, free input if not needed, 391 * and enter new state. 392 */ 393 #ifdef TCPDEBUG 394 if (tdb.td_tod) 395 tdb_stuff(&tdb, nstate); 396 #endif 397 switch (nstate) { 398 399 case EFAILEC: 400 m_freem(m); 401 return; 402 403 default: 404 tp->t_state = nstate; 405 /* fall into ... */ 406 407 case CLOSED: 408 /* IF CLOSED CANT LOOK AT tc_flags */ 409 if ((tp->tc_flags&TC_NET_KEEP) == 0) { 410 register struct mbuf *n; 411 /* inline expansion of m_freem */ 412 while (m) { 413 MFREE(n, m); 414 m = n; 415 } 416 } 417 return; 418 } 419 /* NOTREACHED */ 420 421 /* 422 * Unwanted packed; free everything 423 * but the header and return an rst. 424 */ 425 notwanted: 426 m_freem(m->m_next); 427 m->m_next = NULL; 428 m->m_len = sizeof(struct tcpiphdr); 429 #define xchg(a,b) j=a; a=b; b=j 430 xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr); 431 xchg(ti->ti_dport, ti->ti_sport); 432 #undef xchg 433 if (tiflags&TH_ACK) 434 ti->ti_seq = ti->ti_ackno; 435 else { 436 ti->ti_ackno = htonl(ntohl(ti->ti_seq) + ti->ti_len); 437 ti->ti_seq = 0; 438 } 439 ti->ti_flags = ((tiflags & TH_ACK) ? 0 : TH_ACK) | TH_RST; 440 ti->ti_len = htons(TCPSIZE); 441 ti->ti_off = 5; 442 ti->ti_sum = inet_cksum(m, sizeof(struct tcpiphdr)); 443 ((struct ip *)ti)->ip_len = sizeof(struct tcpiphdr); 444 ip_output(m); 445 tcpstat.tcps_badsegs++; 446 } 447 448 tcp_ctldat(tp, n0, dataok) 449 register struct tcpcb *tp; 450 struct tcpiphdr *n0; 451 int dataok; 452 { 453 register struct tcpiphdr *ti = n0; 454 register int tiflags = ti->ti_flags; 455 struct socket *so = tp->t_inpcb->inp_socket; 456 seq_t past = ti->ti_seq + ti->ti_len; 457 seq_t urgent; 458 int sent; 459 COUNT(TCP_CTLDAT); 460 461 if (tiflags & TH_URG) 462 urgent = ti->ti_seq + ti->ti_urp; 463 tp->tc_flags &= ~(TC_ACK_DUE|TC_NEW_WINDOW); 464 /* syn */ 465 if ((tp->tc_flags&TC_SYN_RCVD) == 0 && (tiflags&TH_SYN)) { 466 tp->irs = ti->ti_seq; 467 tp->rcv_nxt = ti->ti_seq + 1; 468 tp->snd_wl = tp->rcv_urp = tp->irs; 469 tp->tc_flags |= (TC_SYN_RCVD|TC_ACK_DUE); 470 } 471 /* ack */ 472 if ((tiflags&TH_ACK) && (tp->tc_flags&TC_SYN_RCVD) && 473 ti->ti_ackno > tp->snd_una) { 474 /* 475 * Reflect newly acknowledged data. 476 */ 477 tp->snd_una = ti->ti_ackno; 478 if (tp->snd_una > tp->snd_nxt) 479 tp->snd_nxt = tp->snd_una; 480 481 /* 482 * If timed msg acked, update retransmit time value. 483 */ 484 if ((tp->tc_flags&TC_SYN_ACKED) && 485 tp->snd_una > tp->t_xmt_val) { 486 /* NEED SMOOTHING HERE */ 487 tp->t_xmtime = (tp->t_xmt != 0 ? tp->t_xmt : T_REXMT); 488 if (tp->t_xmtime > T_REMAX) 489 tp->t_xmtime = T_REMAX; 490 } 491 492 /* 493 * Remove acked data from send buf 494 */ 495 sbdrop(&so->so_snd, (int)(tp->snd_una - tp->snd_off)); 496 tp->snd_off = tp->snd_una; 497 if ((tp->tc_flags&TC_SYN_ACKED) == 0 && 498 (tp->snd_una > tp->iss)) { 499 tp->tc_flags |= TC_SYN_ACKED; 500 tp->t_init = 0; 501 } 502 if (tp->seq_fin != tp->iss && tp->snd_una > tp->seq_fin) 503 tp->tc_flags &= ~TC_SND_FIN; 504 tp->t_rexmt = 0; 505 tp->t_rexmttl = 0; 506 tp->tc_flags |= TC_CANCELLED; 507 sowwakeup(tp->t_inpcb->inp_socket); 508 } 509 /* win */ 510 if ((tp->tc_flags & TC_SYN_RCVD) && ti->ti_seq >= tp->snd_wl) { 511 tp->snd_wl = ti->ti_seq; 512 tp->snd_wnd = ti->ti_win; 513 tp->tc_flags |= TC_NEW_WINDOW; 514 tp->t_persist = 0; 515 } 516 /* text */ 517 if (dataok && ti->ti_len) { 518 register struct tcpiphdr *q; 519 int overage; 520 521 /* eol */ 522 if ((tiflags&TH_EOL)) { 523 register struct mbuf *m; 524 for (m = dtom(ti); m->m_next; m = m->m_next) 525 ; 526 m->m_act = (struct mbuf *)(mtod(m, caddr_t) - 1); 527 } 528 529 /* text */ 530 /* 531 * Discard duplicate data already passed to user. 532 */ 533 if (SEQ_LT(ti->ti_seq, tp->rcv_nxt)) { 534 register int i = tp->rcv_nxt - ti->ti_seq; 535 if (i >= ti->ti_len) 536 goto notext; 537 ti->ti_seq += i; 538 ti->ti_len -= i; 539 m_adj(dtom(ti), i); 540 } 541 542 /* 543 * Find a segment which begins after this one does. 544 */ 545 for (q = tp->seg_next; q != (struct tcpiphdr *)tp; 546 q = (struct tcpiphdr *)q->ti_next) 547 if (SEQ_GT(q->ti_seq, ti->ti_seq)) 548 break; 549 550 /* 551 * If there is a preceding segment, it may provide some of 552 * our data already. If so, drop the data from the incoming 553 * segment. If it provides all of our data, drop us. 554 */ 555 if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { 556 register int i; 557 q = (struct tcpiphdr *)(q->ti_prev); 558 /* conversion to int (in i) handles seq wraparound */ 559 i = q->ti_seq + q->ti_len - ti->ti_seq; 560 if (i > 0) { 561 if (i >= ti->ti_len) 562 goto notext; 563 /* w/o setting TC_NET_KEEP */ 564 m_adj(dtom(tp), i); 565 ti->ti_len -= i; 566 ti->ti_seq += i; 567 } 568 q = (struct tcpiphdr *)(q->ti_next); 569 } 570 571 /* 572 * While we overlap succeeding segments trim them or, 573 * if they are completely covered, dequeue them. 574 */ 575 while (q != (struct tcpiphdr *)tp && 576 SEQ_GT(ti->ti_seq + ti->ti_len, q->ti_seq)) { 577 register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; 578 if (i < q->ti_len) { 579 q->ti_len -= i; 580 m_adj(dtom(q), i); 581 break; 582 } 583 q = (struct tcpiphdr *)q->ti_next; 584 m_freem(dtom(q->ti_prev)); 585 remque(q->ti_prev); 586 } 587 588 /* 589 * Stick new segment in its place. 590 */ 591 insque(ti, q->ti_prev); 592 tp->seqcnt += ti->ti_len; 593 594 /* 595 * Calculate available space and discard segments for 596 * which there is too much. 597 */ 598 overage = 599 (so->so_rcv.sb_cc /*XXX+tp->rcv_seqcnt*/) - so->so_rcv.sb_hiwat; 600 if (overage > 0) { 601 q = tp->seg_prev; 602 for (;;) { 603 register int i = MIN(q->ti_len, overage); 604 overage -= i; 605 q->ti_len -= i; 606 m_adj(dtom(q), -i); 607 if (q->ti_len) 608 break; 609 if (q == ti) 610 panic("tcp_text dropall"); 611 q = (struct tcpiphdr *)q->ti_prev; 612 remque(q->ti_next); 613 } 614 } 615 616 /* 617 * Advance rcv_next through newly completed sequence space. 618 */ 619 while (ti->ti_seq == tp->rcv_nxt) { 620 tp->rcv_nxt += ti->ti_len; 621 ti = (struct tcpiphdr *)ti->ti_next; 622 if (ti == (struct tcpiphdr *)tp) 623 break; 624 } 625 /* urg */ 626 if (tiflags&TH_URG) { 627 /* ... */ 628 if (SEQ_GT(urgent, tp->rcv_urp)) 629 tp->rcv_urp = urgent; 630 } 631 tp->tc_flags |= (TC_ACK_DUE|TC_NET_KEEP); 632 } 633 notext: 634 /* fin */ 635 if ((tiflags&TH_FIN) && past == tp->rcv_nxt) { 636 if ((tp->tc_flags&TC_FIN_RCVD) == 0) { 637 tp->tc_flags |= TC_FIN_RCVD; 638 sorwakeup(so); 639 tp->rcv_nxt++; 640 } 641 tp->tc_flags |= TC_ACK_DUE; 642 } 643 /* respond */ 644 sent = 0; 645 if (tp->tc_flags&TC_ACK_DUE) 646 sent = tcp_sndctl(tp); 647 else if ((tp->tc_flags&TC_NEW_WINDOW)) 648 if (tp->snd_nxt <= tp->snd_off + so->so_snd.sb_cc || 649 (tp->tc_flags&TC_SND_FIN)) 650 sent = tcp_send(tp); 651 652 /* set for retrans */ 653 if (!sent && tp->snd_una < tp->snd_nxt && 654 (tp->tc_flags&TC_CANCELLED)) { 655 tp->t_rexmt = tp->t_xmtime; 656 tp->t_rexmttl = T_REXMTTL; 657 tp->t_rexmt_val = tp->t_rtl_val = tp->snd_lst; 658 tp->tc_flags &= ~TC_CANCELLED; 659 } 660 /* present data to user */ 661 if ((tp->tc_flags&TC_SYN_ACKED) == 0) 662 return; 663 ti = tp->seg_next; 664 while (ti != (struct tcpiphdr *)tp && ti->ti_seq < tp->rcv_nxt) { 665 remque(ti); 666 sbappend(&so->so_rcv, dtom(ti)); 667 tp->seqcnt -= ti->ti_len; 668 if (tp->seqcnt < 0) 669 panic("tcp_input present"); 670 ti = (struct tcpiphdr *)ti->ti_next; 671 } 672 sorwakeup(so); 673 } 674