1 /* $NetBSD: tcp_usrreq.c,v 1.92 2004/05/25 04:34:00 atatat Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 34 * All rights reserved. 35 * 36 * This code is derived from software contributed to The NetBSD Foundation 37 * by Jason R. Thorpe and Kevin M. Lahey of the Numerical Aerospace Simulation 38 * Facility, NASA Ames Research Center. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. All advertising materials mentioning features or use of this software 49 * must display the following acknowledgement: 50 * This product includes software developed by the NetBSD 51 * Foundation, Inc. and its contributors. 52 * 4. Neither the name of The NetBSD Foundation nor the names of its 53 * contributors may be used to endorse or promote products derived 54 * from this software without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 57 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 58 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 59 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 60 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 61 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 62 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 64 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 * POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69 /* 70 * Copyright (c) 1982, 1986, 1988, 1993, 1995 71 * The Regents of the University of California. All rights reserved. 72 * 73 * Redistribution and use in source and binary forms, with or without 74 * modification, are permitted provided that the following conditions 75 * are met: 76 * 1. Redistributions of source code must retain the above copyright 77 * notice, this list of conditions and the following disclaimer. 78 * 2. Redistributions in binary form must reproduce the above copyright 79 * notice, this list of conditions and the following disclaimer in the 80 * documentation and/or other materials provided with the distribution. 81 * 3. Neither the name of the University nor the names of its contributors 82 * may be used to endorse or promote products derived from this software 83 * without specific prior written permission. 84 * 85 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 86 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 87 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 88 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 89 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 90 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 91 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 92 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 93 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 94 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 95 * SUCH DAMAGE. 96 * 97 * @(#)tcp_usrreq.c 8.5 (Berkeley) 6/21/95 98 */ 99 100 #include <sys/cdefs.h> 101 __KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.92 2004/05/25 04:34:00 atatat Exp $"); 102 103 #include "opt_inet.h" 104 #include "opt_ipsec.h" 105 #include "opt_tcp_debug.h" 106 #include "opt_mbuftrace.h" 107 108 #include <sys/param.h> 109 #include <sys/systm.h> 110 #include <sys/kernel.h> 111 #include <sys/malloc.h> 112 #include <sys/mbuf.h> 113 #include <sys/socket.h> 114 #include <sys/socketvar.h> 115 #include <sys/protosw.h> 116 #include <sys/errno.h> 117 #include <sys/stat.h> 118 #include <sys/proc.h> 119 #include <sys/domain.h> 120 #include <sys/sysctl.h> 121 122 #include <net/if.h> 123 #include <net/route.h> 124 125 #include <netinet/in.h> 126 #include <netinet/in_systm.h> 127 #include <netinet/in_var.h> 128 #include <netinet/ip.h> 129 #include <netinet/in_pcb.h> 130 #include <netinet/ip_var.h> 131 132 #ifdef INET6 133 #ifndef INET 134 #include <netinet/in.h> 135 #endif 136 #include <netinet/ip6.h> 137 #include <netinet6/in6_pcb.h> 138 #include <netinet6/ip6_var.h> 139 #endif 140 141 #include <netinet/tcp.h> 142 #include <netinet/tcp_fsm.h> 143 #include <netinet/tcp_seq.h> 144 #include <netinet/tcp_timer.h> 145 #include <netinet/tcp_var.h> 146 #include <netinet/tcpip.h> 147 #include <netinet/tcp_debug.h> 148 149 #include "opt_tcp_space.h" 150 151 #ifdef IPSEC 152 #include <netinet6/ipsec.h> 153 #endif /*IPSEC*/ 154 155 /* 156 * TCP protocol interface to socket abstraction. 157 */ 158 159 /* 160 * Process a TCP user request for TCP tb. If this is a send request 161 * then m is the mbuf chain of send data. If this is a timer expiration 162 * (called from the software clock routine), then timertype tells which timer. 163 */ 164 /*ARGSUSED*/ 165 int 166 tcp_usrreq(so, req, m, nam, control, p) 167 struct socket *so; 168 int req; 169 struct mbuf *m, *nam, *control; 170 struct proc *p; 171 { 172 struct inpcb *inp; 173 #ifdef INET6 174 struct in6pcb *in6p; 175 #endif 176 struct tcpcb *tp = NULL; 177 int s; 178 int error = 0; 179 #ifdef TCP_DEBUG 180 int ostate = 0; 181 #endif 182 int family; /* family of the socket */ 183 184 family = so->so_proto->pr_domain->dom_family; 185 186 if (req == PRU_CONTROL) { 187 switch (family) { 188 #ifdef INET 189 case PF_INET: 190 return (in_control(so, (long)m, (caddr_t)nam, 191 (struct ifnet *)control, p)); 192 #endif 193 #ifdef INET6 194 case PF_INET6: 195 return (in6_control(so, (long)m, (caddr_t)nam, 196 (struct ifnet *)control, p)); 197 #endif 198 default: 199 return EAFNOSUPPORT; 200 } 201 } 202 203 if (req == PRU_PURGEIF) { 204 switch (family) { 205 #ifdef INET 206 case PF_INET: 207 in_pcbpurgeif0(&tcbtable, (struct ifnet *)control); 208 in_purgeif((struct ifnet *)control); 209 in_pcbpurgeif(&tcbtable, (struct ifnet *)control); 210 break; 211 #endif 212 #ifdef INET6 213 case PF_INET6: 214 in6_pcbpurgeif0(&tcbtable, (struct ifnet *)control); 215 in6_purgeif((struct ifnet *)control); 216 in6_pcbpurgeif(&tcbtable, (struct ifnet *)control); 217 break; 218 #endif 219 default: 220 return (EAFNOSUPPORT); 221 } 222 return (0); 223 } 224 225 s = splsoftnet(); 226 switch (family) { 227 #ifdef INET 228 case PF_INET: 229 inp = sotoinpcb(so); 230 #ifdef INET6 231 in6p = NULL; 232 #endif 233 break; 234 #endif 235 #ifdef INET6 236 case PF_INET6: 237 inp = NULL; 238 in6p = sotoin6pcb(so); 239 break; 240 #endif 241 default: 242 splx(s); 243 return EAFNOSUPPORT; 244 } 245 246 #ifdef DIAGNOSTIC 247 #ifdef INET6 248 if (inp && in6p) 249 panic("tcp_usrreq: both inp and in6p set to non-NULL"); 250 #endif 251 if (req != PRU_SEND && req != PRU_SENDOOB && control) 252 panic("tcp_usrreq: unexpected control mbuf"); 253 #endif 254 /* 255 * When a TCP is attached to a socket, then there will be 256 * a (struct inpcb) pointed at by the socket, and this 257 * structure will point at a subsidary (struct tcpcb). 258 */ 259 #ifndef INET6 260 if (inp == 0 && req != PRU_ATTACH) 261 #else 262 if ((inp == 0 && in6p == 0) && req != PRU_ATTACH) 263 #endif 264 { 265 error = EINVAL; 266 goto release; 267 } 268 #ifdef INET 269 if (inp) { 270 tp = intotcpcb(inp); 271 /* WHAT IF TP IS 0? */ 272 #ifdef KPROF 273 tcp_acounts[tp->t_state][req]++; 274 #endif 275 #ifdef TCP_DEBUG 276 ostate = tp->t_state; 277 #endif 278 } 279 #endif 280 #ifdef INET6 281 if (in6p) { 282 tp = in6totcpcb(in6p); 283 /* WHAT IF TP IS 0? */ 284 #ifdef KPROF 285 tcp_acounts[tp->t_state][req]++; 286 #endif 287 #ifdef TCP_DEBUG 288 ostate = tp->t_state; 289 #endif 290 } 291 #endif 292 293 switch (req) { 294 295 /* 296 * TCP attaches to socket via PRU_ATTACH, reserving space, 297 * and an internet control block. 298 */ 299 case PRU_ATTACH: 300 #ifndef INET6 301 if (inp != 0) 302 #else 303 if (inp != 0 || in6p != 0) 304 #endif 305 { 306 error = EISCONN; 307 break; 308 } 309 error = tcp_attach(so); 310 if (error) 311 break; 312 if ((so->so_options & SO_LINGER) && so->so_linger == 0) 313 so->so_linger = TCP_LINGERTIME; 314 tp = sototcpcb(so); 315 break; 316 317 /* 318 * PRU_DETACH detaches the TCP protocol from the socket. 319 */ 320 case PRU_DETACH: 321 tp = tcp_disconnect(tp); 322 break; 323 324 /* 325 * Give the socket an address. 326 */ 327 case PRU_BIND: 328 switch (family) { 329 #ifdef INET 330 case PF_INET: 331 error = in_pcbbind(inp, nam, p); 332 break; 333 #endif 334 #ifdef INET6 335 case PF_INET6: 336 error = in6_pcbbind(in6p, nam, p); 337 if (!error) { 338 /* mapped addr case */ 339 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)) 340 tp->t_family = AF_INET; 341 else 342 tp->t_family = AF_INET6; 343 } 344 break; 345 #endif 346 } 347 break; 348 349 /* 350 * Prepare to accept connections. 351 */ 352 case PRU_LISTEN: 353 #ifdef INET 354 if (inp && inp->inp_lport == 0) { 355 error = in_pcbbind(inp, (struct mbuf *)0, 356 (struct proc *)0); 357 if (error) 358 break; 359 } 360 #endif 361 #ifdef INET6 362 if (in6p && in6p->in6p_lport == 0) { 363 error = in6_pcbbind(in6p, (struct mbuf *)0, 364 (struct proc *)0); 365 if (error) 366 break; 367 } 368 #endif 369 tp->t_state = TCPS_LISTEN; 370 break; 371 372 /* 373 * Initiate connection to peer. 374 * Create a template for use in transmissions on this connection. 375 * Enter SYN_SENT state, and mark socket as connecting. 376 * Start keep-alive timer, and seed output sequence space. 377 * Send initial segment on connection. 378 */ 379 case PRU_CONNECT: 380 #ifdef INET 381 if (inp) { 382 if (inp->inp_lport == 0) { 383 error = in_pcbbind(inp, (struct mbuf *)0, 384 (struct proc *)0); 385 if (error) 386 break; 387 } 388 error = in_pcbconnect(inp, nam); 389 } 390 #endif 391 #ifdef INET6 392 if (in6p) { 393 if (in6p->in6p_lport == 0) { 394 error = in6_pcbbind(in6p, (struct mbuf *)0, 395 (struct proc *)0); 396 if (error) 397 break; 398 } 399 error = in6_pcbconnect(in6p, nam); 400 if (!error) { 401 /* mapped addr case */ 402 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr)) 403 tp->t_family = AF_INET; 404 else 405 tp->t_family = AF_INET6; 406 } 407 } 408 #endif 409 if (error) 410 break; 411 tp->t_template = tcp_template(tp); 412 if (tp->t_template == 0) { 413 #ifdef INET 414 if (inp) 415 in_pcbdisconnect(inp); 416 #endif 417 #ifdef INET6 418 if (in6p) 419 in6_pcbdisconnect(in6p); 420 #endif 421 error = ENOBUFS; 422 break; 423 } 424 /* Compute window scaling to request. */ 425 while (tp->request_r_scale < TCP_MAX_WINSHIFT && 426 (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 427 tp->request_r_scale++; 428 soisconnecting(so); 429 tcpstat.tcps_connattempt++; 430 tp->t_state = TCPS_SYN_SENT; 431 TCP_TIMER_ARM(tp, TCPT_KEEP, TCPTV_KEEP_INIT); 432 tp->iss = tcp_new_iss(tp, 0); 433 tcp_sendseqinit(tp); 434 error = tcp_output(tp); 435 break; 436 437 /* 438 * Create a TCP connection between two sockets. 439 */ 440 case PRU_CONNECT2: 441 error = EOPNOTSUPP; 442 break; 443 444 /* 445 * Initiate disconnect from peer. 446 * If connection never passed embryonic stage, just drop; 447 * else if don't need to let data drain, then can just drop anyways, 448 * else have to begin TCP shutdown process: mark socket disconnecting, 449 * drain unread data, state switch to reflect user close, and 450 * send segment (e.g. FIN) to peer. Socket will be really disconnected 451 * when peer sends FIN and acks ours. 452 * 453 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB. 454 */ 455 case PRU_DISCONNECT: 456 tp = tcp_disconnect(tp); 457 break; 458 459 /* 460 * Accept a connection. Essentially all the work is 461 * done at higher levels; just return the address 462 * of the peer, storing through addr. 463 */ 464 case PRU_ACCEPT: 465 #ifdef INET 466 if (inp) 467 in_setpeeraddr(inp, nam); 468 #endif 469 #ifdef INET6 470 if (in6p) 471 in6_setpeeraddr(in6p, nam); 472 #endif 473 break; 474 475 /* 476 * Mark the connection as being incapable of further output. 477 */ 478 case PRU_SHUTDOWN: 479 socantsendmore(so); 480 tp = tcp_usrclosed(tp); 481 if (tp) 482 error = tcp_output(tp); 483 break; 484 485 /* 486 * After a receive, possibly send window update to peer. 487 */ 488 case PRU_RCVD: 489 /* 490 * soreceive() calls this function when a user receives 491 * ancillary data on a listening socket. We don't call 492 * tcp_output in such a case, since there is no header 493 * template for a listening socket and hence the kernel 494 * will panic. 495 */ 496 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) != 0) 497 (void) tcp_output(tp); 498 break; 499 500 /* 501 * Do a send by putting data in output queue and updating urgent 502 * marker if URG set. Possibly send more data. 503 */ 504 case PRU_SEND: 505 if (control && control->m_len) { 506 m_freem(control); 507 m_freem(m); 508 error = EINVAL; 509 break; 510 } 511 sbappendstream(&so->so_snd, m); 512 error = tcp_output(tp); 513 break; 514 515 /* 516 * Abort the TCP. 517 */ 518 case PRU_ABORT: 519 tp = tcp_drop(tp, ECONNABORTED); 520 break; 521 522 case PRU_SENSE: 523 /* 524 * stat: don't bother with a blocksize. 525 */ 526 splx(s); 527 return (0); 528 529 case PRU_RCVOOB: 530 if (control && control->m_len) { 531 m_freem(control); 532 m_freem(m); 533 error = EINVAL; 534 break; 535 } 536 if ((so->so_oobmark == 0 && 537 (so->so_state & SS_RCVATMARK) == 0) || 538 so->so_options & SO_OOBINLINE || 539 tp->t_oobflags & TCPOOB_HADDATA) { 540 error = EINVAL; 541 break; 542 } 543 if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) { 544 error = EWOULDBLOCK; 545 break; 546 } 547 m->m_len = 1; 548 *mtod(m, caddr_t) = tp->t_iobc; 549 if (((long)nam & MSG_PEEK) == 0) 550 tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA); 551 break; 552 553 case PRU_SENDOOB: 554 if (sbspace(&so->so_snd) < -512) { 555 m_freem(m); 556 error = ENOBUFS; 557 break; 558 } 559 /* 560 * According to RFC961 (Assigned Protocols), 561 * the urgent pointer points to the last octet 562 * of urgent data. We continue, however, 563 * to consider it to indicate the first octet 564 * of data past the urgent section. 565 * Otherwise, snd_up should be one lower. 566 */ 567 sbappendstream(&so->so_snd, m); 568 tp->snd_up = tp->snd_una + so->so_snd.sb_cc; 569 tp->t_force = 1; 570 error = tcp_output(tp); 571 tp->t_force = 0; 572 break; 573 574 case PRU_SOCKADDR: 575 #ifdef INET 576 if (inp) 577 in_setsockaddr(inp, nam); 578 #endif 579 #ifdef INET6 580 if (in6p) 581 in6_setsockaddr(in6p, nam); 582 #endif 583 break; 584 585 case PRU_PEERADDR: 586 #ifdef INET 587 if (inp) 588 in_setpeeraddr(inp, nam); 589 #endif 590 #ifdef INET6 591 if (in6p) 592 in6_setpeeraddr(in6p, nam); 593 #endif 594 break; 595 596 default: 597 panic("tcp_usrreq"); 598 } 599 #ifdef TCP_DEBUG 600 if (tp && (so->so_options & SO_DEBUG)) 601 tcp_trace(TA_USER, ostate, tp, NULL, req); 602 #endif 603 604 release: 605 splx(s); 606 return (error); 607 } 608 609 int 610 tcp_ctloutput(op, so, level, optname, mp) 611 int op; 612 struct socket *so; 613 int level, optname; 614 struct mbuf **mp; 615 { 616 int error = 0, s; 617 struct inpcb *inp; 618 #ifdef INET6 619 struct in6pcb *in6p; 620 #endif 621 struct tcpcb *tp; 622 struct mbuf *m; 623 int i; 624 int family; /* family of the socket */ 625 626 family = so->so_proto->pr_domain->dom_family; 627 628 s = splsoftnet(); 629 switch (family) { 630 #ifdef INET 631 case PF_INET: 632 inp = sotoinpcb(so); 633 #ifdef INET6 634 in6p = NULL; 635 #endif 636 break; 637 #endif 638 #ifdef INET6 639 case PF_INET6: 640 inp = NULL; 641 in6p = sotoin6pcb(so); 642 break; 643 #endif 644 default: 645 splx(s); 646 return EAFNOSUPPORT; 647 } 648 #ifndef INET6 649 if (inp == NULL) 650 #else 651 if (inp == NULL && in6p == NULL) 652 #endif 653 { 654 splx(s); 655 if (op == PRCO_SETOPT && *mp) 656 (void) m_free(*mp); 657 return (ECONNRESET); 658 } 659 if (level != IPPROTO_TCP) { 660 switch (family) { 661 #ifdef INET 662 case PF_INET: 663 error = ip_ctloutput(op, so, level, optname, mp); 664 break; 665 #endif 666 #ifdef INET6 667 case PF_INET6: 668 error = ip6_ctloutput(op, so, level, optname, mp); 669 break; 670 #endif 671 } 672 splx(s); 673 return (error); 674 } 675 if (inp) 676 tp = intotcpcb(inp); 677 #ifdef INET6 678 else if (in6p) 679 tp = in6totcpcb(in6p); 680 #endif 681 else 682 tp = NULL; 683 684 switch (op) { 685 686 case PRCO_SETOPT: 687 m = *mp; 688 switch (optname) { 689 690 #ifdef TCP_SIGNATURE 691 case TCP_MD5SIG: 692 if (m == NULL || m->m_len < sizeof (int)) 693 error = EINVAL; 694 if (error) 695 break; 696 if (*mtod(m, int *) > 0) 697 tp->t_flags |= TF_SIGNATURE; 698 else 699 tp->t_flags &= ~TF_SIGNATURE; 700 break; 701 #endif /* TCP_SIGNATURE */ 702 703 case TCP_NODELAY: 704 if (m == NULL || m->m_len < sizeof (int)) 705 error = EINVAL; 706 else if (*mtod(m, int *)) 707 tp->t_flags |= TF_NODELAY; 708 else 709 tp->t_flags &= ~TF_NODELAY; 710 break; 711 712 case TCP_MAXSEG: 713 if (m && (i = *mtod(m, int *)) > 0 && 714 i <= tp->t_peermss) 715 tp->t_peermss = i; /* limit on send size */ 716 else 717 error = EINVAL; 718 break; 719 720 default: 721 error = ENOPROTOOPT; 722 break; 723 } 724 if (m) 725 (void) m_free(m); 726 break; 727 728 case PRCO_GETOPT: 729 *mp = m = m_get(M_WAIT, MT_SOOPTS); 730 m->m_len = sizeof(int); 731 MCLAIM(m, so->so_mowner); 732 733 switch (optname) { 734 #ifdef TCP_SIGNATURE 735 case TCP_MD5SIG: 736 *mtod(m, int *) = (tp->t_flags & TF_SIGNATURE) ? 1 : 0; 737 break; 738 #endif 739 case TCP_NODELAY: 740 *mtod(m, int *) = tp->t_flags & TF_NODELAY; 741 break; 742 case TCP_MAXSEG: 743 *mtod(m, int *) = tp->t_peermss; 744 break; 745 default: 746 error = ENOPROTOOPT; 747 break; 748 } 749 break; 750 } 751 splx(s); 752 return (error); 753 } 754 755 #ifndef TCP_SENDSPACE 756 #define TCP_SENDSPACE 1024*32 757 #endif 758 int tcp_sendspace = TCP_SENDSPACE; 759 #ifndef TCP_RECVSPACE 760 #define TCP_RECVSPACE 1024*32 761 #endif 762 int tcp_recvspace = TCP_RECVSPACE; 763 764 /* 765 * Attach TCP protocol to socket, allocating 766 * internet protocol control block, tcp control block, 767 * bufer space, and entering LISTEN state if to accept connections. 768 */ 769 int 770 tcp_attach(so) 771 struct socket *so; 772 { 773 struct tcpcb *tp; 774 struct inpcb *inp; 775 #ifdef INET6 776 struct in6pcb *in6p; 777 #endif 778 int error; 779 int family; /* family of the socket */ 780 781 family = so->so_proto->pr_domain->dom_family; 782 783 #ifdef MBUFTRACE 784 so->so_mowner = &tcp_mowner; 785 so->so_rcv.sb_mowner = &tcp_rx_mowner; 786 so->so_snd.sb_mowner = &tcp_tx_mowner; 787 #endif 788 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 789 error = soreserve(so, tcp_sendspace, tcp_recvspace); 790 if (error) 791 return (error); 792 } 793 switch (family) { 794 #ifdef INET 795 case PF_INET: 796 error = in_pcballoc(so, &tcbtable); 797 if (error) 798 return (error); 799 inp = sotoinpcb(so); 800 #ifdef INET6 801 in6p = NULL; 802 #endif 803 break; 804 #endif 805 #ifdef INET6 806 case PF_INET6: 807 error = in6_pcballoc(so, &tcbtable); 808 if (error) 809 return (error); 810 inp = NULL; 811 in6p = sotoin6pcb(so); 812 break; 813 #endif 814 default: 815 return EAFNOSUPPORT; 816 } 817 if (inp) 818 tp = tcp_newtcpcb(family, (void *)inp); 819 #ifdef INET6 820 else if (in6p) 821 tp = tcp_newtcpcb(family, (void *)in6p); 822 #endif 823 else 824 tp = NULL; 825 826 if (tp == 0) { 827 int nofd = so->so_state & SS_NOFDREF; /* XXX */ 828 829 so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */ 830 #ifdef INET 831 if (inp) 832 in_pcbdetach(inp); 833 #endif 834 #ifdef INET6 835 if (in6p) 836 in6_pcbdetach(in6p); 837 #endif 838 so->so_state |= nofd; 839 return (ENOBUFS); 840 } 841 tp->t_state = TCPS_CLOSED; 842 return (0); 843 } 844 845 /* 846 * Initiate (or continue) disconnect. 847 * If embryonic state, just send reset (once). 848 * If in ``let data drain'' option and linger null, just drop. 849 * Otherwise (hard), mark socket disconnecting and drop 850 * current input data; switch states based on user close, and 851 * send segment to peer (with FIN). 852 */ 853 struct tcpcb * 854 tcp_disconnect(tp) 855 struct tcpcb *tp; 856 { 857 struct socket *so; 858 859 if (tp->t_inpcb) 860 so = tp->t_inpcb->inp_socket; 861 #ifdef INET6 862 else if (tp->t_in6pcb) 863 so = tp->t_in6pcb->in6p_socket; 864 #endif 865 else 866 so = NULL; 867 868 if (TCPS_HAVEESTABLISHED(tp->t_state) == 0) 869 tp = tcp_close(tp); 870 else if ((so->so_options & SO_LINGER) && so->so_linger == 0) 871 tp = tcp_drop(tp, 0); 872 else { 873 soisdisconnecting(so); 874 sbflush(&so->so_rcv); 875 tp = tcp_usrclosed(tp); 876 if (tp) 877 (void) tcp_output(tp); 878 } 879 return (tp); 880 } 881 882 /* 883 * User issued close, and wish to trail through shutdown states: 884 * if never received SYN, just forget it. If got a SYN from peer, 885 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 886 * If already got a FIN from peer, then almost done; go to LAST_ACK 887 * state. In all other cases, have already sent FIN to peer (e.g. 888 * after PRU_SHUTDOWN), and just have to play tedious game waiting 889 * for peer to send FIN or not respond to keep-alives, etc. 890 * We can let the user exit from the close as soon as the FIN is acked. 891 */ 892 struct tcpcb * 893 tcp_usrclosed(tp) 894 struct tcpcb *tp; 895 { 896 897 switch (tp->t_state) { 898 899 case TCPS_CLOSED: 900 case TCPS_LISTEN: 901 case TCPS_SYN_SENT: 902 tp->t_state = TCPS_CLOSED; 903 tp = tcp_close(tp); 904 break; 905 906 case TCPS_SYN_RECEIVED: 907 case TCPS_ESTABLISHED: 908 tp->t_state = TCPS_FIN_WAIT_1; 909 break; 910 911 case TCPS_CLOSE_WAIT: 912 tp->t_state = TCPS_LAST_ACK; 913 break; 914 } 915 if (tp && tp->t_state >= TCPS_FIN_WAIT_2) { 916 struct socket *so; 917 if (tp->t_inpcb) 918 so = tp->t_inpcb->inp_socket; 919 #ifdef INET6 920 else if (tp->t_in6pcb) 921 so = tp->t_in6pcb->in6p_socket; 922 #endif 923 else 924 so = NULL; 925 soisdisconnected(so); 926 /* 927 * If we are in FIN_WAIT_2, we arrived here because the 928 * application did a shutdown of the send side. Like the 929 * case of a transition from FIN_WAIT_1 to FIN_WAIT_2 after 930 * a full close, we start a timer to make sure sockets are 931 * not left in FIN_WAIT_2 forever. 932 */ 933 if ((tp->t_state == TCPS_FIN_WAIT_2) && (tcp_maxidle > 0)) 934 TCP_TIMER_ARM(tp, TCPT_2MSL, tcp_maxidle); 935 } 936 return (tp); 937 } 938 939 /* 940 * sysctl helper routine for net.inet.ip.mssdflt. it can't be less 941 * than 32. 942 */ 943 static int 944 sysctl_net_inet_tcp_mssdflt(SYSCTLFN_ARGS) 945 { 946 int error, mssdflt; 947 struct sysctlnode node; 948 949 mssdflt = tcp_mssdflt; 950 node = *rnode; 951 node.sysctl_data = &mssdflt; 952 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 953 if (error || newp == NULL) 954 return (error); 955 956 if (mssdflt < 32) 957 return (EINVAL); 958 tcp_mssdflt = mssdflt; 959 960 return (0); 961 } 962 963 /* 964 * sysctl helper routine for setting port related values under 965 * net.inet.ip and net.inet6.ip6. does basic range checking and does 966 * additional checks for each type. this code has placed in 967 * tcp_input.c since INET and INET6 both use the same tcp code. 968 * 969 * this helper is not static so that both inet and inet6 can use it. 970 */ 971 int 972 sysctl_net_inet_ip_ports(SYSCTLFN_ARGS) 973 { 974 int error, tmp; 975 int apmin, apmax; 976 #ifndef IPNOPRIVPORTS 977 int lpmin, lpmax; 978 #endif /* IPNOPRIVPORTS */ 979 struct sysctlnode node; 980 981 if (namelen != 0) 982 return (EINVAL); 983 984 switch (name[-3]) { 985 #ifdef INET 986 case PF_INET: 987 apmin = anonportmin; 988 apmax = anonportmax; 989 #ifndef IPNOPRIVPORTS 990 lpmin = lowportmin; 991 lpmax = lowportmax; 992 #endif /* IPNOPRIVPORTS */ 993 break; 994 #endif /* INET */ 995 #ifdef INET6 996 case PF_INET6: 997 apmin = ip6_anonportmin; 998 apmax = ip6_anonportmax; 999 #ifndef IPNOPRIVPORTS 1000 lpmin = ip6_lowportmin; 1001 lpmax = ip6_lowportmax; 1002 #endif /* IPNOPRIVPORTS */ 1003 break; 1004 #endif /* INET6 */ 1005 default: 1006 return (EINVAL); 1007 } 1008 1009 /* 1010 * insert temporary copy into node, perform lookup on 1011 * temporary, then restore pointer 1012 */ 1013 node = *rnode; 1014 tmp = *(int*)rnode->sysctl_data; 1015 node.sysctl_data = &tmp; 1016 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1017 if (error || newp == NULL) 1018 return (error); 1019 1020 /* 1021 * simple port range check 1022 */ 1023 if (tmp < 0 || tmp > 65535) 1024 return (EINVAL); 1025 1026 /* 1027 * per-node range checks 1028 */ 1029 switch (rnode->sysctl_num) { 1030 case IPCTL_ANONPORTMIN: 1031 if (tmp >= apmax) 1032 return (EINVAL); 1033 #ifndef IPNOPRIVPORTS 1034 if (tmp < IPPORT_RESERVED) 1035 return (EINVAL); 1036 #endif /* IPNOPRIVPORTS */ 1037 break; 1038 1039 case IPCTL_ANONPORTMAX: 1040 if (apmin >= tmp) 1041 return (EINVAL); 1042 #ifndef IPNOPRIVPORTS 1043 if (tmp < IPPORT_RESERVED) 1044 return (EINVAL); 1045 #endif /* IPNOPRIVPORTS */ 1046 break; 1047 1048 #ifndef IPNOPRIVPORTS 1049 case IPCTL_LOWPORTMIN: 1050 if (tmp >= lpmax || 1051 tmp > IPPORT_RESERVEDMAX || 1052 tmp < IPPORT_RESERVEDMIN) 1053 return (EINVAL); 1054 break; 1055 1056 case IPCTL_LOWPORTMAX: 1057 if (lpmin >= tmp || 1058 tmp > IPPORT_RESERVEDMAX || 1059 tmp < IPPORT_RESERVEDMIN) 1060 return (EINVAL); 1061 break; 1062 #endif /* IPNOPRIVPORTS */ 1063 1064 default: 1065 return (EINVAL); 1066 } 1067 1068 *(int*)rnode->sysctl_data = tmp; 1069 1070 return (0); 1071 } 1072 1073 /* 1074 * sysctl helper routine for the net.inet.tcp.ident and 1075 * net.inet6.tcp6.ident nodes. contains backwards compat code for the 1076 * old way of looking up the ident information for ipv4 which involves 1077 * stuffing the port/addr pairs into the mib lookup. 1078 */ 1079 static int 1080 sysctl_net_inet_tcp_ident(SYSCTLFN_ARGS) 1081 { 1082 #ifdef INET 1083 struct inpcb *inb; 1084 struct sockaddr_in *si4[2]; 1085 #endif /* INET */ 1086 #ifdef INET6 1087 struct in6pcb *in6b; 1088 struct sockaddr_in6 *si6[2]; 1089 #endif /* INET6 */ 1090 struct sockaddr_storage sa[2]; 1091 struct socket *sockp; 1092 size_t sz; 1093 uid_t uid; 1094 int error, pf; 1095 1096 if (namelen != 4 && namelen != 0) 1097 return (EINVAL); 1098 if (name[-2] != IPPROTO_TCP) 1099 return (EINVAL); 1100 pf = name[-3]; 1101 1102 /* old style lookup, ipv4 only */ 1103 if (namelen == 4) { 1104 #ifdef INET 1105 struct in_addr laddr, raddr; 1106 u_int lport, rport; 1107 1108 if (pf != PF_INET) 1109 return (EPROTONOSUPPORT); 1110 raddr.s_addr = (uint32_t)name[0]; 1111 rport = (u_int)name[1]; 1112 laddr.s_addr = (uint32_t)name[2]; 1113 lport = (u_int)name[3]; 1114 inb = in_pcblookup_connect(&tcbtable, raddr, rport, 1115 laddr, lport); 1116 if (inb == NULL || (sockp = inb->inp_socket) == NULL) 1117 return (ESRCH); 1118 uid = sockp->so_uid; 1119 if (oldp) { 1120 sz = MIN(sizeof(uid), *oldlenp); 1121 error = copyout(&uid, oldp, sz); 1122 if (error) 1123 return (error); 1124 } 1125 *oldlenp = sizeof(uid); 1126 return (0); 1127 #else /* INET */ 1128 return (EINVAL); 1129 #endif /* INET */ 1130 } 1131 1132 if (newp == NULL || newlen != sizeof(sa)) 1133 return (EINVAL); 1134 error = copyin(newp, &sa, newlen); 1135 if (error) 1136 return (error); 1137 1138 /* 1139 * requested families must match 1140 */ 1141 if (pf != sa[0].ss_family || sa[0].ss_family != sa[1].ss_family) 1142 return (EINVAL); 1143 1144 switch (pf) { 1145 #ifdef INET 1146 case PF_INET: 1147 si4[0] = (struct sockaddr_in*)&sa[0]; 1148 si4[1] = (struct sockaddr_in*)&sa[1]; 1149 if (si4[0]->sin_len != sizeof(*si4[0]) || 1150 si4[0]->sin_len != si4[1]->sin_len) 1151 return (EINVAL); 1152 inb = in_pcblookup_connect(&tcbtable, 1153 si4[0]->sin_addr, si4[0]->sin_port, 1154 si4[1]->sin_addr, si4[1]->sin_port); 1155 if (inb == NULL || (sockp = inb->inp_socket) == NULL) 1156 return (ESRCH); 1157 break; 1158 #endif /* INET */ 1159 #ifdef INET6 1160 case PF_INET6: 1161 si6[0] = (struct sockaddr_in6*)&sa[0]; 1162 si6[1] = (struct sockaddr_in6*)&sa[1]; 1163 if (si6[0]->sin6_len != sizeof(*si6[0]) || 1164 si6[0]->sin6_len != si6[1]->sin6_len) 1165 return (EINVAL); 1166 in6b = in6_pcblookup_connect(&tcbtable, 1167 &si6[0]->sin6_addr, si6[0]->sin6_port, 1168 &si6[1]->sin6_addr, si6[1]->sin6_port, 0); 1169 if (in6b == NULL || (sockp = in6b->in6p_socket) == NULL) 1170 return (ESRCH); 1171 break; 1172 #endif /* INET6 */ 1173 default: 1174 return (EPROTONOSUPPORT); 1175 } 1176 1177 uid = sockp->so_uid; 1178 if (oldp) { 1179 sz = MIN(sizeof(uid), *oldlenp); 1180 error = copyout(&uid, oldp, sz); 1181 if (error) 1182 return (error); 1183 } 1184 *oldlenp = sizeof(uid); 1185 1186 return (0); 1187 } 1188 1189 /* 1190 * this (second stage) setup routine is a replacement for tcp_sysctl() 1191 * (which is currently used for ipv4 and ipv6) 1192 */ 1193 static void 1194 sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname, 1195 const char *tcpname) 1196 { 1197 1198 sysctl_createv(clog, 0, NULL, NULL, 1199 CTLFLAG_PERMANENT, 1200 CTLTYPE_NODE, "net", NULL, 1201 NULL, 0, NULL, 0, 1202 CTL_NET, CTL_EOL); 1203 sysctl_createv(clog, 0, NULL, NULL, 1204 CTLFLAG_PERMANENT, 1205 CTLTYPE_NODE, pfname, NULL, 1206 NULL, 0, NULL, 0, 1207 CTL_NET, pf, CTL_EOL); 1208 sysctl_createv(clog, 0, NULL, NULL, 1209 CTLFLAG_PERMANENT, 1210 CTLTYPE_NODE, tcpname, 1211 SYSCTL_DESCR("TCP related settings"), 1212 NULL, 0, NULL, 0, 1213 CTL_NET, pf, IPPROTO_TCP, CTL_EOL); 1214 1215 sysctl_createv(clog, 0, NULL, NULL, 1216 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1217 CTLTYPE_INT, "rfc1323", 1218 SYSCTL_DESCR("Enable RFC1323 TCP extensions"), 1219 NULL, 0, &tcp_do_rfc1323, 0, 1220 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RFC1323, CTL_EOL); 1221 sysctl_createv(clog, 0, NULL, NULL, 1222 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1223 CTLTYPE_INT, "sendspace", 1224 SYSCTL_DESCR("Default TCP send buffer size"), 1225 NULL, 0, &tcp_sendspace, 0, 1226 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SENDSPACE, CTL_EOL); 1227 sysctl_createv(clog, 0, NULL, NULL, 1228 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1229 CTLTYPE_INT, "recvspace", 1230 SYSCTL_DESCR("Default TCP receive buffer size"), 1231 NULL, 0, &tcp_recvspace, 0, 1232 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RECVSPACE, CTL_EOL); 1233 sysctl_createv(clog, 0, NULL, NULL, 1234 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1235 CTLTYPE_INT, "mssdflt", 1236 SYSCTL_DESCR("Default maximum segment size"), 1237 sysctl_net_inet_tcp_mssdflt, 0, &tcp_mssdflt, 0, 1238 CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSSDFLT, CTL_EOL); 1239 sysctl_createv(clog, 0, NULL, NULL, 1240 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1241 CTLTYPE_INT, "syn_cache_limit", 1242 SYSCTL_DESCR("Maximum number of entries in the TCP " 1243 "compressed state engine"), 1244 NULL, 0, &tcp_syn_cache_limit, 0, 1245 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_LIMIT, 1246 CTL_EOL); 1247 sysctl_createv(clog, 0, NULL, NULL, 1248 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1249 CTLTYPE_INT, "syn_bucket_limit", 1250 SYSCTL_DESCR("Maximum number of entries per hash " 1251 "bucket in the TCP compressed state " 1252 "engine"), 1253 NULL, 0, &tcp_syn_bucket_limit, 0, 1254 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_BUCKET_LIMIT, 1255 CTL_EOL); 1256 #if 0 /* obsoleted */ 1257 sysctl_createv(clog, 0, NULL, NULL, 1258 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1259 CTLTYPE_INT, "syn_cache_interval", 1260 SYSCTL_DESCR("TCP compressed state engine's timer interval"), 1261 NULL, 0, &tcp_syn_cache_interval, 0, 1262 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_INTER, 1263 CTL_EOL); 1264 #endif 1265 sysctl_createv(clog, 0, NULL, NULL, 1266 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1267 CTLTYPE_INT, "init_win", 1268 SYSCTL_DESCR("Initial TCP congestion window"), 1269 NULL, 0, &tcp_init_win, 0, 1270 CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN, CTL_EOL); 1271 sysctl_createv(clog, 0, NULL, NULL, 1272 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1273 CTLTYPE_INT, "mss_ifmtu", 1274 SYSCTL_DESCR("Use interface MTU for calculating MSS"), 1275 NULL, 0, &tcp_mss_ifmtu, 0, 1276 CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSS_IFMTU, CTL_EOL); 1277 sysctl_createv(clog, 0, NULL, NULL, 1278 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1279 CTLTYPE_INT, "sack", 1280 SYSCTL_DESCR("Enable RFC2018 Selection ACKnowledgement " 1281 "(not implemented)"), 1282 NULL, 0, &tcp_do_sack, 0, 1283 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_EOL); 1284 sysctl_createv(clog, 0, NULL, NULL, 1285 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1286 CTLTYPE_INT, "win_scale", 1287 SYSCTL_DESCR("Use RFC1323 window scale options"), 1288 NULL, 0, &tcp_do_win_scale, 0, 1289 CTL_NET, pf, IPPROTO_TCP, TCPCTL_WSCALE, CTL_EOL); 1290 sysctl_createv(clog, 0, NULL, NULL, 1291 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1292 CTLTYPE_INT, "timestamps", 1293 SYSCTL_DESCR("Use RFC1323 time stamp options"), 1294 NULL, 0, &tcp_do_timestamps, 0, 1295 CTL_NET, pf, IPPROTO_TCP, TCPCTL_TSTAMP, CTL_EOL); 1296 sysctl_createv(clog, 0, NULL, NULL, 1297 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1298 CTLTYPE_INT, "compat_42", 1299 SYSCTL_DESCR("Enable workarounds for 4.2BSD TCP bugs"), 1300 NULL, 0, &tcp_compat_42, 0, 1301 CTL_NET, pf, IPPROTO_TCP, TCPCTL_COMPAT_42, CTL_EOL); 1302 sysctl_createv(clog, 0, NULL, NULL, 1303 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1304 CTLTYPE_INT, "cwm", 1305 SYSCTL_DESCR("Hughes/Touch/Heidemann Congestion Window " 1306 "Monitoring"), 1307 NULL, 0, &tcp_cwm, 0, 1308 CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM, CTL_EOL); 1309 sysctl_createv(clog, 0, NULL, NULL, 1310 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1311 CTLTYPE_INT, "cwm_burstsize", 1312 SYSCTL_DESCR("Congestion Window Monitoring allowed " 1313 "burst count in packets"), 1314 NULL, 0, &tcp_cwm_burstsize, 0, 1315 CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM_BURSTSIZE, 1316 CTL_EOL); 1317 sysctl_createv(clog, 0, NULL, NULL, 1318 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1319 CTLTYPE_INT, "ack_on_push", 1320 SYSCTL_DESCR("Immediately return ACK when PSH is " 1321 "received"), 1322 NULL, 0, &tcp_ack_on_push, 0, 1323 CTL_NET, pf, IPPROTO_TCP, TCPCTL_ACK_ON_PUSH, CTL_EOL); 1324 sysctl_createv(clog, 0, NULL, NULL, 1325 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1326 CTLTYPE_INT, "keepidle", 1327 SYSCTL_DESCR("Allowed connection idle ticks before a " 1328 "keepalive probe is sent"), 1329 NULL, 0, &tcp_keepidle, 0, 1330 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPIDLE, CTL_EOL); 1331 sysctl_createv(clog, 0, NULL, NULL, 1332 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1333 CTLTYPE_INT, "keepintvl", 1334 SYSCTL_DESCR("Ticks before next keepalive probe is sent"), 1335 NULL, 0, &tcp_keepintvl, 0, 1336 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPINTVL, CTL_EOL); 1337 sysctl_createv(clog, 0, NULL, NULL, 1338 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1339 CTLTYPE_INT, "keepcnt", 1340 SYSCTL_DESCR("Number of keepalive probes to send"), 1341 NULL, 0, &tcp_keepcnt, 0, 1342 CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPCNT, CTL_EOL); 1343 sysctl_createv(clog, 0, NULL, NULL, 1344 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 1345 CTLTYPE_INT, "slowhz", 1346 SYSCTL_DESCR("Keepalive ticks per second"), 1347 NULL, PR_SLOWHZ, NULL, 0, 1348 CTL_NET, pf, IPPROTO_TCP, TCPCTL_SLOWHZ, CTL_EOL); 1349 sysctl_createv(clog, 0, NULL, NULL, 1350 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1351 CTLTYPE_INT, "newreno", 1352 SYSCTL_DESCR("NewReno congestion control algorithm"), 1353 NULL, 0, &tcp_do_newreno, 0, 1354 CTL_NET, pf, IPPROTO_TCP, TCPCTL_NEWRENO, CTL_EOL); 1355 sysctl_createv(clog, 0, NULL, NULL, 1356 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1357 CTLTYPE_INT, "log_refused", 1358 SYSCTL_DESCR("Log refused TCP connections"), 1359 NULL, 0, &tcp_log_refused, 0, 1360 CTL_NET, pf, IPPROTO_TCP, TCPCTL_LOG_REFUSED, CTL_EOL); 1361 #if 0 /* obsoleted */ 1362 sysctl_createv(clog, 0, NULL, NULL, 1363 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1364 CTLTYPE_INT, "rstratelimit", NULL, 1365 NULL, 0, &tcp_rst_ratelim, 0, 1366 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTRATELIMIT, CTL_EOL); 1367 #endif 1368 sysctl_createv(clog, 0, NULL, NULL, 1369 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1370 CTLTYPE_INT, "rstppslimit", 1371 SYSCTL_DESCR("Maximum number of RST packets to send " 1372 "per second"), 1373 NULL, 0, &tcp_rst_ppslim, 0, 1374 CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTPPSLIMIT, CTL_EOL); 1375 sysctl_createv(clog, 0, NULL, NULL, 1376 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1377 CTLTYPE_INT, "delack_ticks", 1378 SYSCTL_DESCR("Number of ticks to delay sending an ACK"), 1379 NULL, 0, &tcp_delack_ticks, 0, 1380 CTL_NET, pf, IPPROTO_TCP, TCPCTL_DELACK_TICKS, CTL_EOL); 1381 sysctl_createv(clog, 0, NULL, NULL, 1382 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1383 CTLTYPE_INT, "init_win_local", 1384 SYSCTL_DESCR("Initial TCP window size (in segments)"), 1385 NULL, 0, &tcp_init_win_local, 0, 1386 CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN_LOCAL, 1387 CTL_EOL); 1388 sysctl_createv(clog, 0, NULL, NULL, 1389 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1390 CTLTYPE_STRUCT, "ident", 1391 SYSCTL_DESCR("RFC1413 Identification Protocol lookups"), 1392 sysctl_net_inet_tcp_ident, 0, NULL, sizeof(uid_t), 1393 CTL_NET, pf, IPPROTO_TCP, TCPCTL_IDENT, CTL_EOL); 1394 } 1395 1396 /* 1397 * Sysctl for tcp variables. 1398 */ 1399 #ifdef INET 1400 SYSCTL_SETUP(sysctl_net_inet_tcp_setup, "sysctl net.inet.tcp subtree setup") 1401 { 1402 1403 sysctl_net_inet_tcp_setup2(clog, PF_INET, "inet", "tcp"); 1404 } 1405 #endif /* INET */ 1406 1407 #ifdef INET6 1408 SYSCTL_SETUP(sysctl_net_inet6_tcp6_setup, "sysctl net.inet6.tcp6 subtree setup") 1409 { 1410 1411 sysctl_net_inet_tcp_setup2(clog, PF_INET6, "inet6", "tcp6"); 1412 } 1413 #endif /* INET6 */ 1414 1415