1 /* tcp_usrreq.c 1.25 81/11/04 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mbuf.h" 6 #include "../h/socket.h" 7 #include "../inet/inet.h" 8 #include "../inet/inet_systm.h" 9 #include "../inet/imp.h" 10 #include "../inet/ip.h" 11 #include "../inet/tcp.h" 12 #define TCPFSTAB 13 #ifdef TCPDEBUG 14 #define TCPSTATES 15 #endif 16 #include "../inet/tcp_fsm.h" 17 18 /* 19 * Tcp finite state machine entries for timer and user generated 20 * requests. These routines raise the ipl to that of the network 21 * to prevent reentry. In particluar, this requires that the software 22 * clock interrupt have lower priority than the network so that 23 * we can enter the network from timeout routines without improperly 24 * nesting the interrupt stack. 25 */ 26 27 /* 28 * Tcp protocol timeout routine called once per second. 29 * Updates the timers in all active tcb's and 30 * causes finite state machine actions if timers expire. 31 */ 32 tcp_timeo() 33 { 34 register struct tcb *tp; 35 int s = splnet(); 36 register u_char *tmp; 37 register int i; 38 COUNT(TCP_TIMEO); 39 40 /* 41 * Search through tcb's and update active timers. 42 */ 43 for (tp = tcb.tcb_next; tp != (struct tcb *)&tcb; tp = tp->tcb_next) { 44 tmp = &tp->t_init; 45 for (i = 0; i < TNTIMERS; i++) { 46 if (*tmp && --*tmp == 0) 47 tcp_usrreq(ISTIMER, i, tp, 0); 48 tmp++; 49 } 50 tp->t_xmt++; 51 } 52 tcp_iss += ISSINCR; /* increment iss */ 53 timeout(tcp_timeo, 0, hz); /* reschedule every second */ 54 splx(s); 55 } 56 57 /* 58 * Cancel all timers for tcp tp. 59 */ 60 tcp_tcancel(tp) 61 struct tcb *tp; 62 { 63 register u_char *tmp = &tp->t_init; 64 register int i; 65 66 for (i = 0; i < TNTIMERS; i++) 67 *tmp++ = 0; 68 } 69 70 /* 71 * Process a TCP user request for tcp tb. If this is a send request 72 * then m is the mbuf chain of send data. If this is a timer expiration 73 * (called from the software clock routine), then timertype tells which timer. 74 */ 75 tcp_usrreq(input, timertype, tp, m) 76 int input, timertype; 77 register struct tcb *tp; 78 struct mbuf *m; 79 { 80 int s = splnet(); 81 register int nstate; 82 #ifdef TCPDEBUG 83 struct tcp_debug tdb; 84 #endif 85 COUNT(TCP_USRREQ); 86 87 nstate = tp->t_state; 88 tp->tc_flags &= ~TC_NET_KEEP; 89 #ifdef KPROF 90 acounts[nstate][input]++; 91 #endif 92 #ifdef TCPDEBUG 93 if ((tp->t_ucb->uc_flags & UDEBUG) || tcpconsdebug) { 94 tdb_setup(tp, (struct th *)0, input, &tdb); 95 tdb.td_tim = timertype; 96 } else 97 tdb.td_tod = 0; 98 #endif 99 switch (input) { 100 101 /* 102 * Passive open. Create a tcp control block 103 * and enter listen state. 104 */ 105 case IUOPENA: 106 if (nstate != 0 && nstate != CLOSED) 107 goto bad; 108 tcp_open(tp, PASSIVE); 109 nstate = LISTEN; 110 break; 111 112 /* 113 * Active open. Create a tcp control block, 114 * send a SYN and enter SYN_SENT state. 115 */ 116 case IUOPENR: 117 if (nstate != 0 && nstate != CLOSED) 118 goto bad; 119 tcp_open(tp, ACTIVE); 120 tcp_sndctl(tp); 121 nstate = SYN_SENT; 122 break; 123 124 /* 125 * Tcp close call. Can be generated by a user ioctl (half-close), 126 * or when higher level close occurs, if a close hasn't happened 127 * already. 128 */ 129 case IUCLOSE: 130 switch (nstate) { 131 132 /* 133 * If we are aborting out of a listener or a active 134 * connection which has not yet completed we can just 135 * delete the tcb. 136 */ 137 case LISTEN: 138 case SYN_SENT: 139 tcp_close(tp, UCLOSED); 140 nstate = CLOSED; 141 break; 142 143 /* 144 * If we have gotten as far as receiving a syn from 145 * our foreign peer, we must be sure to send a FIN. 146 * If we have gotten a FIN from the foreign peer already 147 * (CLOSE_WAIT state), then all that remains is to wait 148 * for his ack of the FIN (LAST_ACK state). If we have 149 * not gotten a FIN from the foreign peer then we need 150 * to either: 151 * 1. rcv ack of our FIN (to FIN_W2) and then 152 * send an ACK (to TIME_WAIT) and timeout at 2*MSL. 153 * or 2. receive hist FIN (to CLOSING), send an ACK 154 * (to TIME_WAIT), and then timeout. 155 * In any case this starts with a transition to FIN_W1 here. 156 */ 157 case SYN_RCVD: 158 case L_SYN_RCVD: 159 case ESTAB: 160 case CLOSE_WAIT: 161 tp->tc_flags |= TC_SND_FIN; 162 tcp_sndctl(tp); 163 tp->tc_flags |= TC_USR_CLOSED; 164 nstate = nstate != CLOSE_WAIT ? FIN_W1 : LAST_ACK; 165 break; 166 167 /* 168 * In these states the user has already closed; 169 * trying to close again is an error. 170 */ 171 case FIN_W1: 172 case FIN_W2: 173 case TIME_WAIT: 174 case CLOSING: 175 case LAST_ACK: 176 case RCV_WAIT: 177 to_user(tp->t_ucb, UCLSERR); 178 break; 179 180 default: 181 goto bad; 182 } 183 break; 184 185 /* 186 * TCP Timer processing. 187 * Timers should expire only on open connections 188 * not in LISTEN state. 189 */ 190 case ISTIMER: 191 switch (nstate) { 192 193 case 0: 194 case CLOSED: 195 case LISTEN: 196 goto bad; 197 198 default: 199 nstate = tcp_timers(tp, timertype); 200 } 201 break; 202 203 /* 204 * User notification of more window availability after 205 * reading out data. This should not happen before a connection 206 * is established or after it is closed. 207 * If the foreign peer has closed and the local entity 208 * has not, inform him of the FIN (give end of file). 209 * If the local entity is in RCV_WAIT state (draining data 210 * out of the TCP buffers after foreign close) and there 211 * is no more data, institute a close. 212 */ 213 case IURECV: 214 if (nstate < ESTAB || nstate == CLOSED) 215 goto bad; 216 tcp_sndwin(tp); 217 if ((tp->tc_flags&TC_FIN_RCVD) && 218 (tp->tc_flags&TC_USR_CLOSED) == 0 && 219 rcv_empty(tp)) 220 to_user(tp, UCLOSED); 221 if (nstate == RCV_WAIT && rcv_empty(tp)) { 222 tcp_close(tp, UCLOSED); 223 nstate = CLOSED; 224 } 225 break; 226 227 /* 228 * Send request on open connection. 229 * Should not happen if the connection is not yet established. 230 * Allowed only on ESTAB connection and after FIN from 231 * foreign peer. 232 */ 233 case IUSEND: 234 switch (nstate) { 235 236 case ESTAB: 237 case CLOSE_WAIT: 238 nstate = tcp_usrsend(tp, m); 239 break; 240 241 default: 242 if (nstate < ESTAB) 243 goto bad; 244 to_user(tp, UCLSERR); 245 break; 246 } 247 break; 248 249 /* 250 * User abort of connection. 251 * If a SYN has been received, but we have not exchanged FINs 252 * then we need to send an RST. In any case we then 253 * enter closed state. 254 */ 255 case IUABORT: 256 if (nstate == 0 || nstate == CLOSED) 257 break; 258 switch (nstate) { 259 260 case 0: 261 case CLOSED: 262 break; 263 264 case SYN_RCVD: 265 case ESTAB: 266 case FIN_W1: 267 case FIN_W2: 268 case CLOSE_WAIT: 269 tp->tc_flags |= TC_SND_RST; 270 tcp_sndnull(tp); 271 /* fall into ... */ 272 273 default: 274 tcp_close(tp, UABORT); 275 nstate = CLOSED; 276 } 277 break; 278 279 /* 280 * Network down entry. Discard the tcb and force 281 * the state to be closed, ungracefully. 282 */ 283 case INCLEAR: 284 if (nstate == 0 || nstate == CLOSED) 285 break; 286 tcp_close(tp, UNETDWN); 287 nstate = CLOSED; 288 break; 289 290 default: 291 panic("tcp_usrreq"); 292 bad: 293 printf("tcp: bad state: tcb=%x state=%d input=%d\n", 294 tp, tp->t_state, input); 295 nstate = EFAILEC; 296 break; 297 } 298 #ifdef TCPDEBUG 299 if (tdb.td_tod) 300 tdb_stuff(&tdb, nstate); 301 #endif 302 /* YECH */ 303 switch (nstate) { 304 305 case CLOSED: 306 case SAME: 307 break; 308 309 case EFAILEC: 310 if (m) 311 m_freem(dtom(m)); 312 break; 313 314 default: 315 tp->t_state = nstate; 316 break; 317 } 318 splx(s); 319 } 320 321 /* 322 * Open routine, called to initialize newly created tcb fields. 323 */ 324 tcp_open(tp, mode) 325 register struct tcb *tp; 326 int mode; 327 { 328 register struct ucb *up = tp->t_ucb; 329 COUNT(TCP_OPEN); 330 331 /* 332 * Link in tcb queue and make 333 * initialize empty reassembly queue. 334 */ 335 tp->tcb_next = tcb.tcb_next; 336 tcb.tcb_next->tcb_prev = tp; 337 tp->tcb_prev = (struct tcb *)&tcb; 338 tcb.tcb_next = tp; 339 tp->t_rcv_next = tp->t_rcv_prev = (struct th *)tp; 340 341 /* 342 * Initialize sequence numbers and 343 * round trip retransmit timer. 344 * (Other fields were init'd to zero when tcb allocated.) 345 */ 346 tp->t_xmtime = T_REXMT; 347 tp->snd_end = tp->seq_fin = tp->snd_nxt = tp->snd_hi = tp->snd_una = 348 tp->iss = tcp_iss; 349 tp->snd_off = tp->iss + 1; 350 tcp_iss += (ISSINCR >> 1) + 1; 351 352 /* 353 * Set timeout for open. 354 * SHOULD THIS BE A HIGHER LEVEL FUNCTION!?! THINK SO. 355 */ 356 if (up->uc_timeo) 357 tp->t_init = up->uc_timeo; 358 else if (mode == ACTIVE) 359 tp->t_init = T_INIT; 360 /* else 361 tp->t_init = 0; */ 362 up->uc_timeo = 0; /* ### */ 363 } 364 365 /* 366 * Internal close of a connection, shutting down the tcb. 367 */ 368 tcp_close(tp, state) 369 register struct tcb *tp; 370 short state; 371 { 372 register struct ucb *up = tp->t_ucb; 373 register struct th *t; 374 register struct mbuf *m; 375 COUNT(TCP_CLOSE); 376 377 /* 378 * Remove from tcb queue and cancel timers. 379 */ 380 tp->tcb_prev->tcb_next = tp->tcb_next; 381 tp->tcb_next->tcb_prev = tp->tcb_prev; 382 tcp_tcancel(tp); 383 384 /* 385 * Discard all buffers. 386 */ 387 for (t = tp->t_rcv_next; t != (struct th *)tp; t = t->t_next) 388 m_freem(dtom(t)); 389 if (up->uc_rbuf) { 390 m_freem(up->uc_rbuf); 391 up->uc_rbuf = NULL; 392 } 393 up->uc_rcc = 0; 394 if (up->uc_sbuf) { 395 m_freem(up->uc_sbuf); 396 up->uc_sbuf = NULL; 397 } 398 up->uc_ssize = 0; 399 for (m = tp->t_rcv_unack; m != NULL; m = m->m_act) { 400 m_freem(m); 401 tp->t_rcv_unack = NULL; 402 } 403 404 /* 405 * Free tcp send template, the tcb itself, 406 * the routing table entry, and the space we had reserved 407 * in the meory pool. 408 */ 409 if (tp->t_template) { 410 m_free(dtom(tp->t_template)); 411 tp->t_template = 0; 412 } 413 wmemfree((caddr_t)tp, 1024); 414 up->uc_pcb = 0; 415 if (up->uc_host) { 416 h_free(up->uc_host); 417 up->uc_host = 0; 418 } 419 m_release(up->uc_snd + (up->uc_rhiwat/MSIZE) + 2); 420 421 /* 422 * If user has initiated close (via close call), delete ucb 423 * entry, otherwise just wakeup so user can issue close call 424 */ 425 if (tp->tc_flags&TC_USR_ABORT) /* ### */ 426 up->uc_proc = NULL; /* ### */ 427 else /* ### */ 428 to_user(up, state); /* ### */ 429 } 430 431 /* 432 * Send data queue headed by m0 into the protocol. 433 */ 434 tcp_usrsend(tp, m0) 435 register struct tcb *tp; 436 struct mbuf *m0; 437 { 438 register struct mbuf *m, *n; 439 register struct ucb *up = tp->t_ucb; 440 register off; 441 seq_t last; 442 COUNT(TCP_USRSEND); 443 444 last = tp->snd_off; 445 for (m = n = m0; m != NULL; m = m->m_next) { 446 up->uc_ssize++; 447 if (m->m_off > MMAXOFF) 448 up->uc_ssize += NMBPG; 449 last += m->m_len; 450 } 451 if ((m = up->uc_sbuf) == NULL) 452 up->uc_sbuf = n; 453 else { 454 while (m->m_next != NULL) { 455 m = m->m_next; 456 last += m->m_len; 457 } 458 if (m->m_off <= MMAXOFF) { 459 last += m->m_len; 460 off = m->m_off + m->m_len; 461 while (n && n->m_off <= MMAXOFF && 462 (MMAXOFF - off) >= n->m_len) { 463 bcopy((caddr_t)((int)n + n->m_off), 464 (caddr_t)((int)m + off), n->m_len); 465 m->m_len += n->m_len; 466 off += n->m_len; 467 up->uc_ssize--; 468 n = m_free(n); 469 } 470 } 471 m->m_next = n; 472 } 473 if (up->uc_flags & UEOL) 474 tp->snd_end = last; 475 if (up->uc_flags & UURG) { 476 tp->snd_urp = last+1; 477 tp->tc_flags |= TC_SND_URG; 478 } 479 tcp_send(tp); 480 return (SAME); 481 } 482 483 /* 484 * TCP timer went off processing. 485 */ 486 tcp_timers(tp, timertype) 487 register struct tcb *tp; 488 int timertype; 489 { 490 491 COUNT(TCP_TIMERS); 492 switch (timertype) { 493 494 case TINIT: /* initialization timer */ 495 if ((tp->tc_flags&TC_SYN_ACKED) == 0) { /* 35 */ 496 tcp_close(tp, UINTIMO); 497 return (CLOSED); 498 } 499 return (SAME); 500 501 case TFINACK: /* fin-ack timer */ 502 switch (tp->t_state) { 503 504 case TIME_WAIT: 505 /* 506 * We can be sure our ACK of foreign FIN was rcvd, 507 * and can close if no data left for user. 508 */ 509 if (rcv_empty(tp)) { 510 tcp_close(tp, UCLOSED); /* 14 */ 511 return (CLOSED); 512 } 513 return (RCV_WAIT); /* 17 */ 514 515 case CLOSING: 516 tp->tc_flags |= TC_WAITED_2_ML; 517 return (SAME); 518 519 default: 520 return (SAME); 521 } 522 523 case TREXMT: /* retransmission timer */ 524 if (tp->t_rexmt_val > tp->snd_una) { /* 34 */ 525 /* 526 * Set up for a retransmission, increase rexmt time 527 * in case of multiple retransmissions. 528 */ 529 tp->snd_nxt = tp->snd_una; 530 tp->tc_flags |= TC_REXMT; 531 tp->t_xmtime = tp->t_xmtime << 1; 532 if (tp->t_xmtime > T_REMAX) 533 tp->t_xmtime = T_REMAX; 534 tcp_send(tp); 535 } 536 return (SAME); 537 538 case TREXMTTL: /* retransmit too long */ 539 if (tp->t_rtl_val > tp->snd_una) /* 36 */ 540 to_user(tp->t_ucb, URXTIMO); 541 /* 542 * If user has already closed, abort the connection. 543 */ 544 if (tp->tc_flags & TC_USR_CLOSED) { 545 tcp_close(tp, URXTIMO); 546 return (CLOSED); 547 } 548 return (SAME); 549 550 case TPERSIST: /* persist timer */ 551 /* 552 * Force a byte send through closed window. 553 */ 554 tp->tc_flags |= TC_FORCE_ONE; 555 tcp_send(tp); 556 return (SAME); 557 } 558 panic("tcp_timers"); 559 } 560 561 /* THIS ROUTINE IS A CROCK */ 562 to_user(up, state) 563 register struct ucb *up; 564 register short state; 565 { 566 COUNT(TO_USER); 567 568 up->uc_state |= state; 569 netwakeup(up); 570 if (state == UURGENT) 571 psignal(up->uc_proc, SIGURG); 572 } 573 574 #ifdef TCPDEBUG 575 /* 576 * TCP debugging utility subroutines. 577 * THE NAMES OF THE FIELDS USED BY THESE ROUTINES ARE STUPID. 578 */ 579 tdb_setup(tp, n, input, tdp) 580 struct tcb *tp; 581 register struct th *n; 582 int input; 583 register struct tcp_debug *tdp; 584 { 585 586 COUNT(TDB_SETUP); 587 tdp->td_tod = time; 588 tdp->td_tcb = tp; 589 tdp->td_old = tp->t_state; 590 tdp->td_inp = input; 591 tdp->td_tim = 0; 592 tdp->td_new = -1; 593 if (n) { 594 tdp->td_sno = n->t_seq; 595 tdp->td_ano = n->t_ackno; 596 tdp->td_wno = n->t_win; 597 tdp->td_lno = n->t_len; 598 tdp->td_flg = n->th_flags; 599 } else 600 tdp->td_sno = tdp->td_ano = tdp->td_wno = tdp->td_lno = 601 tdp->td_flg = 0; 602 } 603 604 tdb_stuff(tdp, nstate) 605 struct tcp_debug *tdp; 606 int nstate; 607 { 608 COUNT(TDB_STUFF); 609 610 tdp->td_new = nstate; 611 tcp_debug[tdbx++ % TDBSIZE] = *tdp; 612 if (tcpconsdebug & 2) 613 tcp_prt(tdp); 614 } 615 616 tcp_prt(tdp) 617 register struct tcp_debug *tdp; 618 { 619 COUNT(TCP_PRT); 620 621 printf("%x ", ((int)tdp->td_tcb)&0xffffff); 622 if (tdp->td_inp == INSEND) { 623 printf("SEND #%x", tdp->td_sno); 624 tdp->td_lno = ntohs(tdp->td_lno); 625 tdp->td_wno = ntohs(tdp->td_wno); 626 } else { 627 if (tdp->td_inp == INRECV) 628 printf("RCV #%x ", tdp->td_sno); 629 printf("%s.%s", 630 tcpstates[tdp->td_old], tcpinputs[tdp->td_inp]); 631 if (tdp->td_inp == ISTIMER) 632 printf("(%s)", tcptimers[tdp->td_tim]); 633 printf(" -> %s", 634 tcpstates[(tdp->td_new > 0) ? tdp->td_new : tdp->td_old]); 635 if (tdp->td_new == -1) 636 printf(" (FAILED)"); 637 } 638 /* GROSS... DEPENDS ON SIGN EXTENSION OF CHARACTERS */ 639 if (tdp->td_lno) 640 printf(" len=%d", tdp->td_lno); 641 if (tdp->td_wno) 642 printf(" win=%d", tdp->td_wno); 643 if (tdp->td_flg & TH_FIN) printf(" FIN"); 644 if (tdp->td_flg & TH_SYN) printf(" SYN"); 645 if (tdp->td_flg & TH_RST) printf(" RST"); 646 if (tdp->td_flg & TH_EOL) printf(" EOL"); 647 if (tdp->td_flg & TH_ACK) printf(" ACK %x", tdp->td_ano); 648 if (tdp->td_flg & TH_URG) printf(" URG"); 649 printf("\n"); 650 } 651 #endif 652