1 /* tcp_usrreq.c 1.27 81/11/14 */ 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 "../h/protosw.h" 9 #include "../net/inet.h" 10 #include "../net/inet_host.h" 11 #include "../net/inet_pcb.h" 12 #include "../net/inet_systm.h" 13 #include "../net/imp.h" 14 #include "../net/ip.h" 15 #include "../net/tcp.h" 16 #define TCPFSTAB 17 #ifdef TCPDEBUG 18 #define TCPSTATES 19 #endif 20 #include "../net/tcp_fsm.h" 21 #include "../net/tcp_var.h" 22 #include "/usr/include/errno.h" 23 24 /* 25 * Tcp initialization 26 */ 27 tcp_init() 28 { 29 30 tcp_iss = 1; /* wrong */ 31 tcb.inp_next = tcb.inp_prev = &tcb; 32 } 33 34 /* 35 * Tcp finite state machine entries for timer and user generated 36 * requests. These routines raise the ipl to that of the network 37 * to prevent reentry. In particluar, this requires that the software 38 * clock interrupt have lower priority than the network so that 39 * we can enter the network from timeout routines without improperly 40 * nesting the interrupt stack. 41 */ 42 43 /* 44 * Tcp protocol timeout routine called every 500 ms. 45 * Updates the timers in all active tcb's and 46 * causes finite state machine actions if timers expire. 47 */ 48 tcp_slowtimo() 49 { 50 register struct inpcb *ip; 51 register struct tcpcb *tp; 52 int s = splnet(); 53 register short *tmp; 54 register int i; 55 COUNT(TCP_TIMEO); 56 57 /* 58 * Search through tcb's and update active timers. 59 */ 60 for (ip = tcb.inp_next; ip != &tcb; ip = ip->inp_next) { 61 tp = intotcpcb(ip); 62 tmp = &tp->t_init; 63 for (i = 0; i < TNTIMERS; i++) { 64 if (*tmp && --*tmp == 0) 65 tcp_usrreq(tp->t_inpcb->inp_socket, 66 PRU_SLOWTIMO, 0, i); 67 tmp++; 68 } 69 tp->t_xmt++; 70 } 71 tcp_iss += ISSINCR/2; /* increment iss */ 72 splx(s); 73 } 74 75 /* 76 * Cancel all timers for tcp tp. 77 */ 78 tcp_tcancel(tp) 79 struct tcpcb *tp; 80 { 81 register short *tmp = &tp->t_init; 82 register int i; 83 84 for (i = 0; i < TNTIMERS; i++) 85 *tmp++ = 0; 86 } 87 88 /* 89 * Process a TCP user request for tcp tb. If this is a send request 90 * then m is the mbuf chain of send data. If this is a timer expiration 91 * (called from the software clock routine), then timertype tells which timer. 92 */ 93 tcp_usrreq(so, req, m, addr) 94 struct socket *so; 95 int req; 96 struct mbuf *m; 97 caddr_t addr; 98 { 99 register struct inpcb *inp = sotoinpcb(so); 100 register struct tcpcb *tp = intotcpcb(inp); 101 int s = splnet(); 102 register int nstate; 103 #ifdef TCPDEBUG 104 struct tcp_debug tdb; 105 #endif 106 int error = 0; 107 COUNT(TCP_USRREQ); 108 109 /* 110 * Make sure attached. If not, 111 * only PRU_ATTACH is valid. 112 */ 113 if (tp) { 114 nstate = tp->t_state; 115 tp->tc_flags &= ~TC_NET_KEEP; 116 } else 117 if (req != PRU_ATTACH) { 118 splx(s); 119 return (EINVAL); 120 } 121 122 /* 123 * Do tracing and accounting. 124 */ 125 #ifdef KPROF 126 acounts[nstate][req]++; 127 #endif 128 #ifdef TCPDEBUG 129 if (tp && ((tp->t_socket->so_options & SO_DEBUG) || tcpconsdebug)) { 130 tdb_setup(tp, (struct tcpiphdr *)0, req, &tdb); 131 tdb.td_tim = timertype; 132 } else 133 tdb.td_tod = 0; 134 #endif 135 switch (req) { 136 137 case PRU_ATTACH: 138 if (tp) 139 error = EISCONN; 140 else { 141 tcp_attach(so); 142 tp = sototcpcb(so); 143 } 144 if (so->so_options & SO_ACCEPTCONN) { 145 inp->inp_lhost = h_make(&n_lhost); 146 in_pcbgenport(&tcb, inp); 147 nstate = LISTEN; 148 } else 149 nstate = CLOSED; 150 break; 151 152 case PRU_DETACH: 153 tcp_detach(so); 154 break; 155 156 case PRU_CONNECT: 157 if (tp->t_state != 0 && tp->t_state != CLOSED) 158 goto bad; 159 inp->inp_fhost = in_hmake((struct in_addr *)addr, &error); 160 if (inp->inp_fhost == 0) 161 break; 162 tcp_sndctl(tp); 163 nstate = SYN_SENT; 164 soisconnecting(so); 165 break; 166 167 case PRU_DISCONNECT: 168 if ((tp->tc_flags & TC_FIN_RCVD) == 0) 169 goto abort; 170 if (nstate < ESTAB) 171 tcp_disconnect(so); 172 else { 173 tp->tc_flags |= TC_SND_FIN; 174 tcp_sendctl(tp); 175 tp->tc_flags |= TC_USR_CLOSED; 176 soisdisconnecting(so); 177 } 178 break; 179 180 case PRU_SHUTDOWN: 181 switch (nstate) { 182 183 case LISTEN: 184 case SYN_SENT: 185 nstate = CLOSED; 186 break; 187 188 case SYN_RCVD: 189 case L_SYN_RCVD: 190 case ESTAB: 191 case CLOSE_WAIT: 192 tp->tc_flags |= TC_SND_FIN; 193 tcp_sndctl(tp); 194 tp->tc_flags |= TC_USR_CLOSED; 195 nstate = nstate != CLOSE_WAIT ? FIN_W1 : LAST_ACK; 196 break; 197 198 case FIN_W1: 199 case FIN_W2: 200 case TIME_WAIT: 201 case CLOSING: 202 case LAST_ACK: 203 case RCV_WAIT: 204 break; 205 206 default: 207 goto bad; 208 } 209 break; 210 211 case PRU_RCVD: 212 if (nstate < ESTAB || nstate == CLOSED) 213 goto bad; 214 tcp_sndwin(tp); 215 if ((tp->tc_flags&TC_FIN_RCVD) && 216 (tp->tc_flags&TC_USR_CLOSED) == 0 && 217 rcv_empty(tp)) 218 error = ESHUTDOWN; 219 if (nstate == RCV_WAIT && rcv_empty(tp)) 220 nstate = CLOSED; 221 break; 222 223 case PRU_SEND: 224 switch (nstate) { 225 226 case ESTAB: 227 case CLOSE_WAIT: 228 tcp_usrsend(tp, m); 229 break; 230 231 default: 232 if (nstate < ESTAB) 233 goto bad; 234 m_freem(m); 235 error = ENOTCONN; 236 break; 237 } 238 break; 239 240 abort: 241 case PRU_ABORT: 242 tcp_abort(tp); 243 nstate = CLOSED; 244 break; 245 246 case PRU_CONTROL: 247 error = EOPNOTSUPP; 248 break; 249 250 case PRU_SLOWTIMO: 251 switch (nstate) { 252 253 case 0: 254 case CLOSED: 255 case LISTEN: 256 goto bad; 257 258 default: 259 nstate = tcp_timers(tp, (int)addr); 260 } 261 break; 262 263 default: 264 panic("tcp_usrreq"); 265 bad: 266 printf("tcp: bad state: tcb=%x state=%d input=%d\n", 267 tp, tp->t_state, req); 268 nstate = EFAILEC; 269 break; 270 } 271 #ifdef TCPDEBUG 272 if (tdb.td_tod) 273 tdb_stuff(&tdb, nstate); 274 #endif 275 switch (nstate) { 276 277 case CLOSED: 278 case SAME: 279 break; 280 281 case EFAILEC: 282 if (m) 283 m_freem(dtom(m)); 284 break; 285 286 default: 287 tp->t_state = nstate; 288 break; 289 } 290 splx(s); 291 return (error); 292 } 293 294 tcp_attach(so) 295 register struct socket *so; 296 { 297 register struct tcpcb *tp; 298 COUNT(TCP_ATTACH); 299 300 /* 301 * Make empty reassembly queue. 302 */ 303 tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp; 304 305 /* 306 * Initialize sequence numbers and round trip retransmit timer. 307 */ 308 tp->t_xmtime = T_REXMT; 309 tp->snd_end = tp->seq_fin = tp->snd_nxt = tp->snd_hi = tp->snd_una = 310 tp->iss = tcp_iss; 311 tp->snd_off = tp->iss + 1; 312 tcp_iss += (ISSINCR >> 1) + 1; 313 } 314 315 tcp_detach(so) 316 register struct socket *so; 317 { 318 register struct tcpcb *tp = (struct tcpcb *)so->so_pcb; 319 register struct tcpiphdr *t; 320 register struct mbuf *m; 321 COUNT(TCP_DETACH); 322 323 wmemfree((caddr_t)tp, 1024); 324 m_release(so->so_rcv.sb_hiwat + so->so_snd.sb_hiwat + 2 * MSIZE); 325 } 326 327 tcp_disconnect(tp) 328 register struct tcpcb *tp; 329 { 330 register struct tcpiphdr *t; 331 register struct mbuf *m; 332 register struct socket *so; 333 334 tcp_tcancel(tp); 335 t = tp->seg_next; 336 for (; t != (struct tcpiphdr *)tp; t = t->t_next) 337 m_freem(dtom(t)); 338 tcp_drainunack(tp); 339 if (tp->t_template) { 340 m_free(dtom(tp->t_template)); 341 tp->t_template = 0; 342 } 343 in_pcbfree(tp->t_inpcb); 344 } 345 346 tcp_abort(so) 347 register struct socket *so; 348 { 349 register struct tcpcb *tp = sototcpcb(so); 350 351 switch (tp->t_state) { 352 353 case SYN_RCVD: 354 case ESTAB: 355 case FIN_W1: 356 case FIN_W2: 357 case CLOSE_WAIT: 358 tp->tc_flags |= TC_SND_RST; 359 tcp_sndnull(tp); 360 } 361 if (so) 362 soisdisconnected(so); 363 } 364 365 /* 366 * Send data queue headed by m0 into the protocol. 367 */ 368 tcp_usrsend(tp, m0) 369 register struct tcpcb *tp; 370 struct mbuf *m0; 371 { 372 register struct mbuf *m, *n; 373 register struct socket *so = tp->t_inpcb->inp_socket; 374 register off; 375 seq_t last; 376 COUNT(TCP_USRSEND); 377 378 sbappend(&so->so_snd, m0); 379 if (tp->t_options & TO_EOL) 380 tp->snd_end = tp->snd_off + so->so_snd.sb_cc; 381 if (tp->t_options & TO_URG) { 382 tp->snd_urp = tp->snd_off + so->so_snd.sb_cc + 1; 383 tp->tc_flags |= TC_SND_URG; 384 } 385 tcp_send(tp); 386 } 387 388 /* 389 * TCP timer went off processing. 390 */ 391 tcp_timers(tp, timertype) 392 register struct tcpcb *tp; 393 int timertype; 394 { 395 396 COUNT(TCP_TIMERS); 397 switch (timertype) { 398 399 case TFINACK: /* fin-ack timer */ 400 switch (tp->t_state) { 401 402 case TIME_WAIT: 403 /* 404 * We can be sure our ACK of foreign FIN was rcvd, 405 * and can close if no data left for user. 406 */ 407 if (rcv_empty(tp)) { 408 tcp_disconnect(tp); 409 return (CLOSED); 410 } 411 return (RCV_WAIT); /* 17 */ 412 413 case CLOSING: 414 tp->tc_flags |= TC_WAITED_2_ML; 415 return (SAME); 416 417 default: 418 return (SAME); 419 } 420 421 case TREXMT: /* retransmission timer */ 422 if (tp->t_rexmt_val > tp->snd_una) { /* 34 */ 423 /* 424 * Set so for a retransmission, increase rexmt time 425 * in case of multiple retransmissions. 426 */ 427 tp->snd_nxt = tp->snd_una; 428 tp->tc_flags |= TC_REXMT; 429 tp->t_xmtime = tp->t_xmtime << 1; 430 if (tp->t_xmtime > T_REMAX) 431 tp->t_xmtime = T_REMAX; 432 tcp_send(tp); 433 } 434 return (SAME); 435 436 case TREXMTTL: /* retransmit too long */ 437 if (tp->t_rtl_val > tp->snd_una) /* 36 */ 438 tcp_error(EIO); /* URXTIMO !?! */ 439 /* 440 * If user has already closed, abort the connection. 441 */ 442 if (tp->tc_flags & TC_USR_CLOSED) { 443 tcp_abort(tp); 444 return (CLOSED); 445 } 446 return (SAME); 447 448 case TPERSIST: /* persist timer */ 449 /* 450 * Force a byte send through closed window. 451 */ 452 tp->tc_flags |= TC_FORCE_ONE; 453 tcp_send(tp); 454 return (SAME); 455 } 456 panic("tcp_timers"); 457 } 458 459 tcp_sense(m) 460 struct mbuf *m; 461 { 462 463 return (EOPNOTSUPP); 464 } 465 466 tcp_error(so, errno) 467 struct socket *so; 468 int errno; 469 { 470 COUNT(TO_USER); 471 472 so->so_error = errno; 473 sorwakeup(so); 474 sowwakeup(so); 475 } 476 477 #ifdef TCPDEBUG 478 /* 479 * TCP debugging utility subroutines. 480 * THE NAMES OF THE FIELDS USED BY THESE ROUTINES ARE STUPID. 481 */ 482 tdb_setup(tp, n, input, tdp) 483 struct tcpcb *tp; 484 register struct tcpiphdr *n; 485 int input; 486 register struct tcp_debug *tdp; 487 { 488 489 COUNT(TDB_SETUP); 490 tdp->td_tod = time; 491 tdp->td_tcb = tp; 492 tdp->td_old = tp->t_state; 493 tdp->td_inp = input; 494 tdp->td_tim = 0; 495 tdp->td_new = -1; 496 if (n) { 497 tdp->td_sno = n->t_seq; 498 tdp->td_ano = n->t_ackno; 499 tdp->td_wno = n->t_win; 500 tdp->td_lno = n->t_len; 501 tdp->td_flg = n->th_flags; 502 } else 503 tdp->td_sno = tdp->td_ano = tdp->td_wno = tdp->td_lno = 504 tdp->td_flg = 0; 505 } 506 507 tdb_stuff(tdp, nstate) 508 struct tcp_debug *tdp; 509 int nstate; 510 { 511 COUNT(TDB_STUFF); 512 513 tdp->td_new = nstate; 514 tcp_debug[tdbx++ % TDBSIZE] = *tdp; 515 if (tcpconsdebug & 2) 516 tcp_prt(tdp); 517 } 518 519 tcp_prt(tdp) 520 register struct tcp_debug *tdp; 521 { 522 COUNT(TCP_PRT); 523 524 printf("%x ", ((int)tdp->td_tcb)&0xffffff); 525 if (tdp->td_inp == INSEND) { 526 printf("SEND #%x", tdp->td_sno); 527 tdp->td_lno = ntohs(tdp->td_lno); 528 tdp->td_wno = ntohs(tdp->td_wno); 529 } else { 530 if (tdp->td_inp == INRECV) 531 printf("RCV #%x ", tdp->td_sno); 532 printf("%s.%s", 533 tcpstates[tdp->td_old], tcpinputs[tdp->td_inp]); 534 if (tdp->td_inp == ISTIMER) 535 printf("(%s)", tcptimers[tdp->td_tim]); 536 printf(" -> %s", 537 tcpstates[(tdp->td_new > 0) ? tdp->td_new : tdp->td_old]); 538 if (tdp->td_new == -1) 539 printf(" (FAILED)"); 540 } 541 /* GROSS... DEPENDS ON SIGN EXTENSION OF CHARACTERS */ 542 if (tdp->td_lno) 543 printf(" len=%d", tdp->td_lno); 544 if (tdp->td_wno) 545 printf(" win=%d", tdp->td_wno); 546 if (tdp->td_flg & TH_FIN) printf(" FIN"); 547 if (tdp->td_flg & TH_SYN) printf(" SYN"); 548 if (tdp->td_flg & TH_RST) printf(" RST"); 549 if (tdp->td_flg & TH_EOL) printf(" EOL"); 550 if (tdp->td_flg & TH_ACK) printf(" ACK %x", tdp->td_ano); 551 if (tdp->td_flg & TH_URG) printf(" URG"); 552 printf("\n"); 553 } 554 #endif 555