1 /*- 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. 4 * Copyright (c) 2006-2007 Robert N. M. Watson 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 * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include "opt_ddb.h" 38 #include "opt_inet.h" 39 #include "opt_inet6.h" 40 #include "opt_tcpdebug.h" 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/malloc.h> 45 #include <sys/kernel.h> 46 #include <sys/sysctl.h> 47 #include <sys/mbuf.h> 48 #ifdef INET6 49 #include <sys/domain.h> 50 #endif /* INET6 */ 51 #include <sys/socket.h> 52 #include <sys/socketvar.h> 53 #include <sys/protosw.h> 54 #include <sys/proc.h> 55 #include <sys/jail.h> 56 #include <sys/vimage.h> 57 58 #ifdef DDB 59 #include <ddb/ddb.h> 60 #endif 61 62 #include <net/if.h> 63 #include <net/route.h> 64 65 #include <netinet/in.h> 66 #include <netinet/in_systm.h> 67 #ifdef INET6 68 #include <netinet/ip6.h> 69 #endif 70 #include <netinet/in_pcb.h> 71 #ifdef INET6 72 #include <netinet6/in6_pcb.h> 73 #endif 74 #include <netinet/in_var.h> 75 #include <netinet/ip_var.h> 76 #ifdef INET6 77 #include <netinet6/ip6_var.h> 78 #include <netinet6/scope6_var.h> 79 #endif 80 #include <netinet/tcp.h> 81 #include <netinet/tcp_fsm.h> 82 #include <netinet/tcp_seq.h> 83 #include <netinet/tcp_timer.h> 84 #include <netinet/tcp_var.h> 85 #include <netinet/tcpip.h> 86 #ifdef TCPDEBUG 87 #include <netinet/tcp_debug.h> 88 #endif 89 #include <netinet/tcp_offload.h> 90 91 /* 92 * TCP protocol interface to socket abstraction. 93 */ 94 static int tcp_attach(struct socket *); 95 static int tcp_connect(struct tcpcb *, struct sockaddr *, 96 struct thread *td); 97 #ifdef INET6 98 static int tcp6_connect(struct tcpcb *, struct sockaddr *, 99 struct thread *td); 100 #endif /* INET6 */ 101 static void tcp_disconnect(struct tcpcb *); 102 static void tcp_usrclosed(struct tcpcb *); 103 static void tcp_fill_info(struct tcpcb *, struct tcp_info *); 104 105 #ifdef TCPDEBUG 106 #define TCPDEBUG0 int ostate = 0 107 #define TCPDEBUG1() ostate = tp ? tp->t_state : 0 108 #define TCPDEBUG2(req) if (tp && (so->so_options & SO_DEBUG)) \ 109 tcp_trace(TA_USER, ostate, tp, 0, 0, req) 110 #else 111 #define TCPDEBUG0 112 #define TCPDEBUG1() 113 #define TCPDEBUG2(req) 114 #endif 115 116 /* 117 * TCP attaches to socket via pru_attach(), reserving space, 118 * and an internet control block. 119 */ 120 static int 121 tcp_usr_attach(struct socket *so, int proto, struct thread *td) 122 { 123 struct inpcb *inp; 124 struct tcpcb *tp = NULL; 125 int error; 126 TCPDEBUG0; 127 128 inp = sotoinpcb(so); 129 KASSERT(inp == NULL, ("tcp_usr_attach: inp != NULL")); 130 TCPDEBUG1(); 131 132 error = tcp_attach(so); 133 if (error) 134 goto out; 135 136 if ((so->so_options & SO_LINGER) && so->so_linger == 0) 137 so->so_linger = TCP_LINGERTIME; 138 139 inp = sotoinpcb(so); 140 tp = intotcpcb(inp); 141 out: 142 TCPDEBUG2(PRU_ATTACH); 143 return error; 144 } 145 146 /* 147 * tcp_detach is called when the socket layer loses its final reference 148 * to the socket, be it a file descriptor reference, a reference from TCP, 149 * etc. At this point, there is only one case in which we will keep around 150 * inpcb state: time wait. 151 * 152 * This function can probably be re-absorbed back into tcp_usr_detach() now 153 * that there is a single detach path. 154 */ 155 static void 156 tcp_detach(struct socket *so, struct inpcb *inp) 157 { 158 struct tcpcb *tp; 159 #ifdef INET6 160 int isipv6 = INP_CHECK_SOCKAF(so, AF_INET6) != 0; 161 #endif 162 #ifdef INVARIANTS 163 INIT_VNET_INET(so->so_vnet); 164 #endif 165 166 INP_INFO_WLOCK_ASSERT(&V_tcbinfo); 167 INP_WLOCK_ASSERT(inp); 168 169 KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp")); 170 KASSERT(inp->inp_socket == so, ("tcp_detach: inp_socket != so")); 171 172 tp = intotcpcb(inp); 173 174 if (inp->inp_vflag & INP_TIMEWAIT) { 175 /* 176 * There are two cases to handle: one in which the time wait 177 * state is being discarded (INP_DROPPED), and one in which 178 * this connection will remain in timewait. In the former, 179 * it is time to discard all state (except tcptw, which has 180 * already been discarded by the timewait close code, which 181 * should be further up the call stack somewhere). In the 182 * latter case, we detach from the socket, but leave the pcb 183 * present until timewait ends. 184 * 185 * XXXRW: Would it be cleaner to free the tcptw here? 186 */ 187 if (inp->inp_vflag & INP_DROPPED) { 188 KASSERT(tp == NULL, ("tcp_detach: INP_TIMEWAIT && " 189 "INP_DROPPED && tp != NULL")); 190 #ifdef INET6 191 if (isipv6) { 192 in6_pcbdetach(inp); 193 in6_pcbfree(inp); 194 } else { 195 #endif 196 in_pcbdetach(inp); 197 in_pcbfree(inp); 198 #ifdef INET6 199 } 200 #endif 201 } else { 202 #ifdef INET6 203 if (isipv6) 204 in6_pcbdetach(inp); 205 else 206 #endif 207 in_pcbdetach(inp); 208 INP_WUNLOCK(inp); 209 } 210 } else { 211 /* 212 * If the connection is not in timewait, we consider two 213 * two conditions: one in which no further processing is 214 * necessary (dropped || embryonic), and one in which TCP is 215 * not yet done, but no longer requires the socket, so the 216 * pcb will persist for the time being. 217 * 218 * XXXRW: Does the second case still occur? 219 */ 220 if (inp->inp_vflag & INP_DROPPED || 221 tp->t_state < TCPS_SYN_SENT) { 222 tcp_discardcb(tp); 223 #ifdef INET6 224 if (isipv6) { 225 in6_pcbdetach(inp); 226 in6_pcbfree(inp); 227 } else { 228 #endif 229 in_pcbdetach(inp); 230 in_pcbfree(inp); 231 #ifdef INET6 232 } 233 #endif 234 } else { 235 #ifdef INET6 236 if (isipv6) 237 in6_pcbdetach(inp); 238 else 239 #endif 240 in_pcbdetach(inp); 241 } 242 } 243 } 244 245 /* 246 * pru_detach() detaches the TCP protocol from the socket. 247 * If the protocol state is non-embryonic, then can't 248 * do this directly: have to initiate a pru_disconnect(), 249 * which may finish later; embryonic TCB's can just 250 * be discarded here. 251 */ 252 static void 253 tcp_usr_detach(struct socket *so) 254 { 255 INIT_VNET_INET(so->so_vnet); 256 struct inpcb *inp; 257 258 inp = sotoinpcb(so); 259 KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL")); 260 INP_INFO_WLOCK(&V_tcbinfo); 261 INP_WLOCK(inp); 262 KASSERT(inp->inp_socket != NULL, 263 ("tcp_usr_detach: inp_socket == NULL")); 264 tcp_detach(so, inp); 265 INP_INFO_WUNLOCK(&V_tcbinfo); 266 } 267 268 /* 269 * Give the socket an address. 270 */ 271 static int 272 tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 273 { 274 INIT_VNET_INET(so->so_vnet); 275 int error = 0; 276 struct inpcb *inp; 277 struct tcpcb *tp = NULL; 278 struct sockaddr_in *sinp; 279 280 sinp = (struct sockaddr_in *)nam; 281 if (nam->sa_len != sizeof (*sinp)) 282 return (EINVAL); 283 /* 284 * Must check for multicast addresses and disallow binding 285 * to them. 286 */ 287 if (sinp->sin_family == AF_INET && 288 IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) 289 return (EAFNOSUPPORT); 290 291 TCPDEBUG0; 292 INP_INFO_WLOCK(&V_tcbinfo); 293 inp = sotoinpcb(so); 294 KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL")); 295 INP_WLOCK(inp); 296 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 297 error = EINVAL; 298 goto out; 299 } 300 tp = intotcpcb(inp); 301 TCPDEBUG1(); 302 error = in_pcbbind(inp, nam, td->td_ucred); 303 out: 304 TCPDEBUG2(PRU_BIND); 305 INP_WUNLOCK(inp); 306 INP_INFO_WUNLOCK(&V_tcbinfo); 307 308 return (error); 309 } 310 311 #ifdef INET6 312 static int 313 tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 314 { 315 INIT_VNET_INET(so->so_vnet); 316 int error = 0; 317 struct inpcb *inp; 318 struct tcpcb *tp = NULL; 319 struct sockaddr_in6 *sin6p; 320 321 sin6p = (struct sockaddr_in6 *)nam; 322 if (nam->sa_len != sizeof (*sin6p)) 323 return (EINVAL); 324 /* 325 * Must check for multicast addresses and disallow binding 326 * to them. 327 */ 328 if (sin6p->sin6_family == AF_INET6 && 329 IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) 330 return (EAFNOSUPPORT); 331 332 TCPDEBUG0; 333 INP_INFO_WLOCK(&V_tcbinfo); 334 inp = sotoinpcb(so); 335 KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL")); 336 INP_WLOCK(inp); 337 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 338 error = EINVAL; 339 goto out; 340 } 341 tp = intotcpcb(inp); 342 TCPDEBUG1(); 343 inp->inp_vflag &= ~INP_IPV4; 344 inp->inp_vflag |= INP_IPV6; 345 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) { 346 if (IN6_IS_ADDR_UNSPECIFIED(&sin6p->sin6_addr)) 347 inp->inp_vflag |= INP_IPV4; 348 else if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) { 349 struct sockaddr_in sin; 350 351 in6_sin6_2_sin(&sin, sin6p); 352 inp->inp_vflag |= INP_IPV4; 353 inp->inp_vflag &= ~INP_IPV6; 354 error = in_pcbbind(inp, (struct sockaddr *)&sin, 355 td->td_ucred); 356 goto out; 357 } 358 } 359 error = in6_pcbbind(inp, nam, td->td_ucred); 360 out: 361 TCPDEBUG2(PRU_BIND); 362 INP_WUNLOCK(inp); 363 INP_INFO_WUNLOCK(&V_tcbinfo); 364 return (error); 365 } 366 #endif /* INET6 */ 367 368 /* 369 * Prepare to accept connections. 370 */ 371 static int 372 tcp_usr_listen(struct socket *so, int backlog, struct thread *td) 373 { 374 INIT_VNET_INET(so->so_vnet); 375 int error = 0; 376 struct inpcb *inp; 377 struct tcpcb *tp = NULL; 378 379 TCPDEBUG0; 380 INP_INFO_WLOCK(&V_tcbinfo); 381 inp = sotoinpcb(so); 382 KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL")); 383 INP_WLOCK(inp); 384 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 385 error = EINVAL; 386 goto out; 387 } 388 tp = intotcpcb(inp); 389 TCPDEBUG1(); 390 SOCK_LOCK(so); 391 error = solisten_proto_check(so); 392 if (error == 0 && inp->inp_lport == 0) 393 error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); 394 if (error == 0) { 395 tp->t_state = TCPS_LISTEN; 396 solisten_proto(so, backlog); 397 tcp_offload_listen_open(tp); 398 } 399 SOCK_UNLOCK(so); 400 401 out: 402 TCPDEBUG2(PRU_LISTEN); 403 INP_WUNLOCK(inp); 404 INP_INFO_WUNLOCK(&V_tcbinfo); 405 return (error); 406 } 407 408 #ifdef INET6 409 static int 410 tcp6_usr_listen(struct socket *so, int backlog, struct thread *td) 411 { 412 INIT_VNET_INET(so->so_vnet); 413 int error = 0; 414 struct inpcb *inp; 415 struct tcpcb *tp = NULL; 416 417 TCPDEBUG0; 418 INP_INFO_WLOCK(&V_tcbinfo); 419 inp = sotoinpcb(so); 420 KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL")); 421 INP_WLOCK(inp); 422 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 423 error = EINVAL; 424 goto out; 425 } 426 tp = intotcpcb(inp); 427 TCPDEBUG1(); 428 SOCK_LOCK(so); 429 error = solisten_proto_check(so); 430 if (error == 0 && inp->inp_lport == 0) { 431 inp->inp_vflag &= ~INP_IPV4; 432 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) 433 inp->inp_vflag |= INP_IPV4; 434 error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); 435 } 436 if (error == 0) { 437 tp->t_state = TCPS_LISTEN; 438 solisten_proto(so, backlog); 439 } 440 SOCK_UNLOCK(so); 441 442 out: 443 TCPDEBUG2(PRU_LISTEN); 444 INP_WUNLOCK(inp); 445 INP_INFO_WUNLOCK(&V_tcbinfo); 446 return (error); 447 } 448 #endif /* INET6 */ 449 450 /* 451 * Initiate connection to peer. 452 * Create a template for use in transmissions on this connection. 453 * Enter SYN_SENT state, and mark socket as connecting. 454 * Start keep-alive timer, and seed output sequence space. 455 * Send initial segment on connection. 456 */ 457 static int 458 tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 459 { 460 INIT_VNET_INET(so->so_vnet); 461 int error = 0; 462 struct inpcb *inp; 463 struct tcpcb *tp = NULL; 464 struct sockaddr_in *sinp; 465 466 sinp = (struct sockaddr_in *)nam; 467 if (nam->sa_len != sizeof (*sinp)) 468 return (EINVAL); 469 /* 470 * Must disallow TCP ``connections'' to multicast addresses. 471 */ 472 if (sinp->sin_family == AF_INET 473 && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) 474 return (EAFNOSUPPORT); 475 if (jailed(td->td_ucred)) 476 prison_remote_ip(td->td_ucred, 0, &sinp->sin_addr.s_addr); 477 478 TCPDEBUG0; 479 INP_INFO_WLOCK(&V_tcbinfo); 480 inp = sotoinpcb(so); 481 KASSERT(inp != NULL, ("tcp_usr_connect: inp == NULL")); 482 INP_WLOCK(inp); 483 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 484 error = EINVAL; 485 goto out; 486 } 487 tp = intotcpcb(inp); 488 TCPDEBUG1(); 489 if ((error = tcp_connect(tp, nam, td)) != 0) 490 goto out; 491 error = tcp_output_connect(so, nam); 492 out: 493 TCPDEBUG2(PRU_CONNECT); 494 INP_WUNLOCK(inp); 495 INP_INFO_WUNLOCK(&V_tcbinfo); 496 return (error); 497 } 498 499 #ifdef INET6 500 static int 501 tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 502 { 503 INIT_VNET_INET(so->so_vnet); 504 int error = 0; 505 struct inpcb *inp; 506 struct tcpcb *tp = NULL; 507 struct sockaddr_in6 *sin6p; 508 509 TCPDEBUG0; 510 511 sin6p = (struct sockaddr_in6 *)nam; 512 if (nam->sa_len != sizeof (*sin6p)) 513 return (EINVAL); 514 /* 515 * Must disallow TCP ``connections'' to multicast addresses. 516 */ 517 if (sin6p->sin6_family == AF_INET6 518 && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) 519 return (EAFNOSUPPORT); 520 521 INP_INFO_WLOCK(&V_tcbinfo); 522 inp = sotoinpcb(so); 523 KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL")); 524 INP_WLOCK(inp); 525 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 526 error = EINVAL; 527 goto out; 528 } 529 tp = intotcpcb(inp); 530 TCPDEBUG1(); 531 if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) { 532 struct sockaddr_in sin; 533 534 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) { 535 error = EINVAL; 536 goto out; 537 } 538 539 in6_sin6_2_sin(&sin, sin6p); 540 inp->inp_vflag |= INP_IPV4; 541 inp->inp_vflag &= ~INP_IPV6; 542 if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0) 543 goto out; 544 error = tcp_output_connect(so, nam); 545 goto out; 546 } 547 inp->inp_vflag &= ~INP_IPV4; 548 inp->inp_vflag |= INP_IPV6; 549 inp->inp_inc.inc_isipv6 = 1; 550 if ((error = tcp6_connect(tp, nam, td)) != 0) 551 goto out; 552 error = tcp_output_connect(so, nam); 553 554 out: 555 TCPDEBUG2(PRU_CONNECT); 556 INP_WUNLOCK(inp); 557 INP_INFO_WUNLOCK(&V_tcbinfo); 558 return (error); 559 } 560 #endif /* INET6 */ 561 562 /* 563 * Initiate disconnect from peer. 564 * If connection never passed embryonic stage, just drop; 565 * else if don't need to let data drain, then can just drop anyways, 566 * else have to begin TCP shutdown process: mark socket disconnecting, 567 * drain unread data, state switch to reflect user close, and 568 * send segment (e.g. FIN) to peer. Socket will be really disconnected 569 * when peer sends FIN and acks ours. 570 * 571 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB. 572 */ 573 static int 574 tcp_usr_disconnect(struct socket *so) 575 { 576 INIT_VNET_INET(so->so_vnet); 577 struct inpcb *inp; 578 struct tcpcb *tp = NULL; 579 int error = 0; 580 581 TCPDEBUG0; 582 INP_INFO_WLOCK(&V_tcbinfo); 583 inp = sotoinpcb(so); 584 KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL")); 585 INP_WLOCK(inp); 586 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 587 error = ECONNRESET; 588 goto out; 589 } 590 tp = intotcpcb(inp); 591 TCPDEBUG1(); 592 tcp_disconnect(tp); 593 out: 594 TCPDEBUG2(PRU_DISCONNECT); 595 INP_WUNLOCK(inp); 596 INP_INFO_WUNLOCK(&V_tcbinfo); 597 return (error); 598 } 599 600 /* 601 * Accept a connection. Essentially all the work is 602 * done at higher levels; just return the address 603 * of the peer, storing through addr. 604 */ 605 static int 606 tcp_usr_accept(struct socket *so, struct sockaddr **nam) 607 { 608 INIT_VNET_INET(so->so_vnet); 609 int error = 0; 610 struct inpcb *inp = NULL; 611 struct tcpcb *tp = NULL; 612 struct in_addr addr; 613 in_port_t port = 0; 614 TCPDEBUG0; 615 616 if (so->so_state & SS_ISDISCONNECTED) 617 return (ECONNABORTED); 618 619 inp = sotoinpcb(so); 620 KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL")); 621 INP_INFO_RLOCK(&V_tcbinfo); 622 INP_WLOCK(inp); 623 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 624 error = ECONNABORTED; 625 goto out; 626 } 627 tp = intotcpcb(inp); 628 TCPDEBUG1(); 629 630 /* 631 * We inline in_getpeeraddr and COMMON_END here, so that we can 632 * copy the data of interest and defer the malloc until after we 633 * release the lock. 634 */ 635 port = inp->inp_fport; 636 addr = inp->inp_faddr; 637 638 out: 639 TCPDEBUG2(PRU_ACCEPT); 640 INP_WUNLOCK(inp); 641 INP_INFO_RUNLOCK(&V_tcbinfo); 642 if (error == 0) 643 *nam = in_sockaddr(port, &addr); 644 return error; 645 } 646 647 #ifdef INET6 648 static int 649 tcp6_usr_accept(struct socket *so, struct sockaddr **nam) 650 { 651 struct inpcb *inp = NULL; 652 int error = 0; 653 struct tcpcb *tp = NULL; 654 struct in_addr addr; 655 struct in6_addr addr6; 656 in_port_t port = 0; 657 int v4 = 0; 658 TCPDEBUG0; 659 660 if (so->so_state & SS_ISDISCONNECTED) 661 return (ECONNABORTED); 662 663 inp = sotoinpcb(so); 664 KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL")); 665 INP_WLOCK(inp); 666 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 667 error = ECONNABORTED; 668 goto out; 669 } 670 tp = intotcpcb(inp); 671 TCPDEBUG1(); 672 673 /* 674 * We inline in6_mapped_peeraddr and COMMON_END here, so that we can 675 * copy the data of interest and defer the malloc until after we 676 * release the lock. 677 */ 678 if (inp->inp_vflag & INP_IPV4) { 679 v4 = 1; 680 port = inp->inp_fport; 681 addr = inp->inp_faddr; 682 } else { 683 port = inp->inp_fport; 684 addr6 = inp->in6p_faddr; 685 } 686 687 out: 688 TCPDEBUG2(PRU_ACCEPT); 689 INP_WUNLOCK(inp); 690 if (error == 0) { 691 if (v4) 692 *nam = in6_v4mapsin6_sockaddr(port, &addr); 693 else 694 *nam = in6_sockaddr(port, &addr6); 695 } 696 return error; 697 } 698 #endif /* INET6 */ 699 700 /* 701 * Mark the connection as being incapable of further output. 702 */ 703 static int 704 tcp_usr_shutdown(struct socket *so) 705 { 706 INIT_VNET_INET(so->so_vnet); 707 int error = 0; 708 struct inpcb *inp; 709 struct tcpcb *tp = NULL; 710 711 TCPDEBUG0; 712 INP_INFO_WLOCK(&V_tcbinfo); 713 inp = sotoinpcb(so); 714 KASSERT(inp != NULL, ("inp == NULL")); 715 INP_WLOCK(inp); 716 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 717 error = ECONNRESET; 718 goto out; 719 } 720 tp = intotcpcb(inp); 721 TCPDEBUG1(); 722 socantsendmore(so); 723 tcp_usrclosed(tp); 724 error = tcp_output_disconnect(tp); 725 726 out: 727 TCPDEBUG2(PRU_SHUTDOWN); 728 INP_WUNLOCK(inp); 729 INP_INFO_WUNLOCK(&V_tcbinfo); 730 731 return (error); 732 } 733 734 /* 735 * After a receive, possibly send window update to peer. 736 */ 737 static int 738 tcp_usr_rcvd(struct socket *so, int flags) 739 { 740 struct inpcb *inp; 741 struct tcpcb *tp = NULL; 742 int error = 0; 743 744 TCPDEBUG0; 745 inp = sotoinpcb(so); 746 KASSERT(inp != NULL, ("tcp_usr_rcvd: inp == NULL")); 747 INP_WLOCK(inp); 748 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 749 error = ECONNRESET; 750 goto out; 751 } 752 tp = intotcpcb(inp); 753 TCPDEBUG1(); 754 tcp_output_rcvd(tp); 755 756 out: 757 TCPDEBUG2(PRU_RCVD); 758 INP_WUNLOCK(inp); 759 return (error); 760 } 761 762 /* 763 * Do a send by putting data in output queue and updating urgent 764 * marker if URG set. Possibly send more data. Unlike the other 765 * pru_*() routines, the mbuf chains are our responsibility. We 766 * must either enqueue them or free them. The other pru_* routines 767 * generally are caller-frees. 768 */ 769 static int 770 tcp_usr_send(struct socket *so, int flags, struct mbuf *m, 771 struct sockaddr *nam, struct mbuf *control, struct thread *td) 772 { 773 INIT_VNET_INET(so->so_vnet); 774 int error = 0; 775 struct inpcb *inp; 776 struct tcpcb *tp = NULL; 777 int headlocked = 0; 778 #ifdef INET6 779 int isipv6; 780 #endif 781 TCPDEBUG0; 782 783 /* 784 * We require the pcbinfo lock in two cases: 785 * 786 * (1) An implied connect is taking place, which can result in 787 * binding IPs and ports and hence modification of the pcb hash 788 * chains. 789 * 790 * (2) PRUS_EOF is set, resulting in explicit close on the send. 791 */ 792 if ((nam != NULL) || (flags & PRUS_EOF)) { 793 INP_INFO_WLOCK(&V_tcbinfo); 794 headlocked = 1; 795 } 796 inp = sotoinpcb(so); 797 KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL")); 798 INP_WLOCK(inp); 799 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 800 if (control) 801 m_freem(control); 802 if (m) 803 m_freem(m); 804 error = ECONNRESET; 805 goto out; 806 } 807 #ifdef INET6 808 isipv6 = nam && nam->sa_family == AF_INET6; 809 #endif /* INET6 */ 810 tp = intotcpcb(inp); 811 TCPDEBUG1(); 812 if (control) { 813 /* TCP doesn't do control messages (rights, creds, etc) */ 814 if (control->m_len) { 815 m_freem(control); 816 if (m) 817 m_freem(m); 818 error = EINVAL; 819 goto out; 820 } 821 m_freem(control); /* empty control, just free it */ 822 } 823 if (!(flags & PRUS_OOB)) { 824 sbappendstream(&so->so_snd, m); 825 if (nam && tp->t_state < TCPS_SYN_SENT) { 826 /* 827 * Do implied connect if not yet connected, 828 * initialize window to default value, and 829 * initialize maxseg/maxopd using peer's cached 830 * MSS. 831 */ 832 INP_INFO_WLOCK_ASSERT(&V_tcbinfo); 833 #ifdef INET6 834 if (isipv6) 835 error = tcp6_connect(tp, nam, td); 836 else 837 #endif /* INET6 */ 838 error = tcp_connect(tp, nam, td); 839 if (error) 840 goto out; 841 tp->snd_wnd = TTCP_CLIENT_SND_WND; 842 tcp_mss(tp, -1); 843 } 844 if (flags & PRUS_EOF) { 845 /* 846 * Close the send side of the connection after 847 * the data is sent. 848 */ 849 INP_INFO_WLOCK_ASSERT(&V_tcbinfo); 850 socantsendmore(so); 851 tcp_usrclosed(tp); 852 } 853 if (headlocked) { 854 INP_INFO_WUNLOCK(&V_tcbinfo); 855 headlocked = 0; 856 } 857 if (tp != NULL) { 858 if (flags & PRUS_MORETOCOME) 859 tp->t_flags |= TF_MORETOCOME; 860 error = tcp_output_send(tp); 861 if (flags & PRUS_MORETOCOME) 862 tp->t_flags &= ~TF_MORETOCOME; 863 } 864 } else { 865 /* 866 * XXXRW: PRUS_EOF not implemented with PRUS_OOB? 867 */ 868 SOCKBUF_LOCK(&so->so_snd); 869 if (sbspace(&so->so_snd) < -512) { 870 SOCKBUF_UNLOCK(&so->so_snd); 871 m_freem(m); 872 error = ENOBUFS; 873 goto out; 874 } 875 /* 876 * According to RFC961 (Assigned Protocols), 877 * the urgent pointer points to the last octet 878 * of urgent data. We continue, however, 879 * to consider it to indicate the first octet 880 * of data past the urgent section. 881 * Otherwise, snd_up should be one lower. 882 */ 883 sbappendstream_locked(&so->so_snd, m); 884 SOCKBUF_UNLOCK(&so->so_snd); 885 if (nam && tp->t_state < TCPS_SYN_SENT) { 886 /* 887 * Do implied connect if not yet connected, 888 * initialize window to default value, and 889 * initialize maxseg/maxopd using peer's cached 890 * MSS. 891 */ 892 INP_INFO_WLOCK_ASSERT(&V_tcbinfo); 893 #ifdef INET6 894 if (isipv6) 895 error = tcp6_connect(tp, nam, td); 896 else 897 #endif /* INET6 */ 898 error = tcp_connect(tp, nam, td); 899 if (error) 900 goto out; 901 tp->snd_wnd = TTCP_CLIENT_SND_WND; 902 tcp_mss(tp, -1); 903 INP_INFO_WUNLOCK(&V_tcbinfo); 904 headlocked = 0; 905 } else if (nam) { 906 INP_INFO_WUNLOCK(&V_tcbinfo); 907 headlocked = 0; 908 } 909 tp->snd_up = tp->snd_una + so->so_snd.sb_cc; 910 tp->t_flags |= TF_FORCEDATA; 911 error = tcp_output_send(tp); 912 tp->t_flags &= ~TF_FORCEDATA; 913 } 914 out: 915 TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB : 916 ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); 917 INP_WUNLOCK(inp); 918 if (headlocked) 919 INP_INFO_WUNLOCK(&V_tcbinfo); 920 return (error); 921 } 922 923 /* 924 * Abort the TCP. Drop the connection abruptly. 925 */ 926 static void 927 tcp_usr_abort(struct socket *so) 928 { 929 INIT_VNET_INET(so->so_vnet); 930 struct inpcb *inp; 931 struct tcpcb *tp = NULL; 932 TCPDEBUG0; 933 934 inp = sotoinpcb(so); 935 KASSERT(inp != NULL, ("tcp_usr_abort: inp == NULL")); 936 937 INP_INFO_WLOCK(&V_tcbinfo); 938 INP_WLOCK(inp); 939 KASSERT(inp->inp_socket != NULL, 940 ("tcp_usr_abort: inp_socket == NULL")); 941 942 /* 943 * If we still have full TCP state, and we're not dropped, drop. 944 */ 945 if (!(inp->inp_vflag & INP_TIMEWAIT) && 946 !(inp->inp_vflag & INP_DROPPED)) { 947 tp = intotcpcb(inp); 948 TCPDEBUG1(); 949 tcp_drop(tp, ECONNABORTED); 950 TCPDEBUG2(PRU_ABORT); 951 } 952 if (!(inp->inp_vflag & INP_DROPPED)) { 953 SOCK_LOCK(so); 954 so->so_state |= SS_PROTOREF; 955 SOCK_UNLOCK(so); 956 inp->inp_vflag |= INP_SOCKREF; 957 } 958 INP_WUNLOCK(inp); 959 INP_INFO_WUNLOCK(&V_tcbinfo); 960 } 961 962 /* 963 * TCP socket is closed. Start friendly disconnect. 964 */ 965 static void 966 tcp_usr_close(struct socket *so) 967 { 968 INIT_VNET_INET(so->so_vnet); 969 struct inpcb *inp; 970 struct tcpcb *tp = NULL; 971 TCPDEBUG0; 972 973 inp = sotoinpcb(so); 974 KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL")); 975 976 INP_INFO_WLOCK(&V_tcbinfo); 977 INP_WLOCK(inp); 978 KASSERT(inp->inp_socket != NULL, 979 ("tcp_usr_close: inp_socket == NULL")); 980 981 /* 982 * If we still have full TCP state, and we're not dropped, initiate 983 * a disconnect. 984 */ 985 if (!(inp->inp_vflag & INP_TIMEWAIT) && 986 !(inp->inp_vflag & INP_DROPPED)) { 987 tp = intotcpcb(inp); 988 TCPDEBUG1(); 989 tcp_disconnect(tp); 990 TCPDEBUG2(PRU_CLOSE); 991 } 992 if (!(inp->inp_vflag & INP_DROPPED)) { 993 SOCK_LOCK(so); 994 so->so_state |= SS_PROTOREF; 995 SOCK_UNLOCK(so); 996 inp->inp_vflag |= INP_SOCKREF; 997 } 998 INP_WUNLOCK(inp); 999 INP_INFO_WUNLOCK(&V_tcbinfo); 1000 } 1001 1002 /* 1003 * Receive out-of-band data. 1004 */ 1005 static int 1006 tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags) 1007 { 1008 int error = 0; 1009 struct inpcb *inp; 1010 struct tcpcb *tp = NULL; 1011 1012 TCPDEBUG0; 1013 inp = sotoinpcb(so); 1014 KASSERT(inp != NULL, ("tcp_usr_rcvoob: inp == NULL")); 1015 INP_WLOCK(inp); 1016 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 1017 error = ECONNRESET; 1018 goto out; 1019 } 1020 tp = intotcpcb(inp); 1021 TCPDEBUG1(); 1022 if ((so->so_oobmark == 0 && 1023 (so->so_rcv.sb_state & SBS_RCVATMARK) == 0) || 1024 so->so_options & SO_OOBINLINE || 1025 tp->t_oobflags & TCPOOB_HADDATA) { 1026 error = EINVAL; 1027 goto out; 1028 } 1029 if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) { 1030 error = EWOULDBLOCK; 1031 goto out; 1032 } 1033 m->m_len = 1; 1034 *mtod(m, caddr_t) = tp->t_iobc; 1035 if ((flags & MSG_PEEK) == 0) 1036 tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA); 1037 1038 out: 1039 TCPDEBUG2(PRU_RCVOOB); 1040 INP_WUNLOCK(inp); 1041 return (error); 1042 } 1043 1044 struct pr_usrreqs tcp_usrreqs = { 1045 .pru_abort = tcp_usr_abort, 1046 .pru_accept = tcp_usr_accept, 1047 .pru_attach = tcp_usr_attach, 1048 .pru_bind = tcp_usr_bind, 1049 .pru_connect = tcp_usr_connect, 1050 .pru_control = in_control, 1051 .pru_detach = tcp_usr_detach, 1052 .pru_disconnect = tcp_usr_disconnect, 1053 .pru_listen = tcp_usr_listen, 1054 .pru_peeraddr = in_getpeeraddr, 1055 .pru_rcvd = tcp_usr_rcvd, 1056 .pru_rcvoob = tcp_usr_rcvoob, 1057 .pru_send = tcp_usr_send, 1058 .pru_shutdown = tcp_usr_shutdown, 1059 .pru_sockaddr = in_getsockaddr, 1060 .pru_sosetlabel = in_pcbsosetlabel, 1061 .pru_close = tcp_usr_close, 1062 }; 1063 1064 #ifdef INET6 1065 struct pr_usrreqs tcp6_usrreqs = { 1066 .pru_abort = tcp_usr_abort, 1067 .pru_accept = tcp6_usr_accept, 1068 .pru_attach = tcp_usr_attach, 1069 .pru_bind = tcp6_usr_bind, 1070 .pru_connect = tcp6_usr_connect, 1071 .pru_control = in6_control, 1072 .pru_detach = tcp_usr_detach, 1073 .pru_disconnect = tcp_usr_disconnect, 1074 .pru_listen = tcp6_usr_listen, 1075 .pru_peeraddr = in6_mapped_peeraddr, 1076 .pru_rcvd = tcp_usr_rcvd, 1077 .pru_rcvoob = tcp_usr_rcvoob, 1078 .pru_send = tcp_usr_send, 1079 .pru_shutdown = tcp_usr_shutdown, 1080 .pru_sockaddr = in6_mapped_sockaddr, 1081 .pru_sosetlabel = in_pcbsosetlabel, 1082 .pru_close = tcp_usr_close, 1083 }; 1084 #endif /* INET6 */ 1085 1086 /* 1087 * Common subroutine to open a TCP connection to remote host specified 1088 * by struct sockaddr_in in mbuf *nam. Call in_pcbbind to assign a local 1089 * port number if needed. Call in_pcbconnect_setup to do the routing and 1090 * to choose a local host address (interface). If there is an existing 1091 * incarnation of the same connection in TIME-WAIT state and if the remote 1092 * host was sending CC options and if the connection duration was < MSL, then 1093 * truncate the previous TIME-WAIT state and proceed. 1094 * Initialize connection parameters and enter SYN-SENT state. 1095 */ 1096 static int 1097 tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) 1098 { 1099 struct inpcb *inp = tp->t_inpcb, *oinp; 1100 struct socket *so = inp->inp_socket; 1101 INIT_VNET_INET(so->so_vnet); 1102 struct in_addr laddr; 1103 u_short lport; 1104 int error; 1105 1106 INP_INFO_WLOCK_ASSERT(&V_tcbinfo); 1107 INP_WLOCK_ASSERT(inp); 1108 1109 if (inp->inp_lport == 0) { 1110 error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); 1111 if (error) 1112 return error; 1113 } 1114 1115 /* 1116 * Cannot simply call in_pcbconnect, because there might be an 1117 * earlier incarnation of this same connection still in 1118 * TIME_WAIT state, creating an ADDRINUSE error. 1119 */ 1120 laddr = inp->inp_laddr; 1121 lport = inp->inp_lport; 1122 error = in_pcbconnect_setup(inp, nam, &laddr.s_addr, &lport, 1123 &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td->td_ucred); 1124 if (error && oinp == NULL) 1125 return error; 1126 if (oinp) 1127 return EADDRINUSE; 1128 inp->inp_laddr = laddr; 1129 in_pcbrehash(inp); 1130 1131 /* 1132 * Compute window scaling to request: 1133 * Scale to fit into sweet spot. See tcp_syncache.c. 1134 * XXX: This should move to tcp_output(). 1135 */ 1136 while (tp->request_r_scale < TCP_MAX_WINSHIFT && 1137 (TCP_MAXWIN << tp->request_r_scale) < sb_max) 1138 tp->request_r_scale++; 1139 1140 soisconnecting(so); 1141 V_tcpstat.tcps_connattempt++; 1142 tp->t_state = TCPS_SYN_SENT; 1143 tcp_timer_activate(tp, TT_KEEP, tcp_keepinit); 1144 tp->iss = tcp_new_isn(tp); 1145 tp->t_bw_rtseq = tp->iss; 1146 tcp_sendseqinit(tp); 1147 1148 return 0; 1149 } 1150 1151 #ifdef INET6 1152 static int 1153 tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) 1154 { 1155 struct inpcb *inp = tp->t_inpcb, *oinp; 1156 struct socket *so = inp->inp_socket; 1157 INIT_VNET_INET(so->so_vnet); 1158 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; 1159 struct in6_addr *addr6; 1160 int error; 1161 1162 INP_INFO_WLOCK_ASSERT(&V_tcbinfo); 1163 INP_WLOCK_ASSERT(inp); 1164 1165 if (inp->inp_lport == 0) { 1166 error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); 1167 if (error) 1168 return error; 1169 } 1170 1171 /* 1172 * Cannot simply call in_pcbconnect, because there might be an 1173 * earlier incarnation of this same connection still in 1174 * TIME_WAIT state, creating an ADDRINUSE error. 1175 * in6_pcbladdr() also handles scope zone IDs. 1176 */ 1177 error = in6_pcbladdr(inp, nam, &addr6); 1178 if (error) 1179 return error; 1180 oinp = in6_pcblookup_hash(inp->inp_pcbinfo, 1181 &sin6->sin6_addr, sin6->sin6_port, 1182 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) 1183 ? addr6 1184 : &inp->in6p_laddr, 1185 inp->inp_lport, 0, NULL); 1186 if (oinp) 1187 return EADDRINUSE; 1188 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) 1189 inp->in6p_laddr = *addr6; 1190 inp->in6p_faddr = sin6->sin6_addr; 1191 inp->inp_fport = sin6->sin6_port; 1192 /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */ 1193 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK; 1194 if (inp->in6p_flags & IN6P_AUTOFLOWLABEL) 1195 inp->in6p_flowinfo |= 1196 (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK); 1197 in_pcbrehash(inp); 1198 1199 /* Compute window scaling to request. */ 1200 while (tp->request_r_scale < TCP_MAX_WINSHIFT && 1201 (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 1202 tp->request_r_scale++; 1203 1204 soisconnecting(so); 1205 V_tcpstat.tcps_connattempt++; 1206 tp->t_state = TCPS_SYN_SENT; 1207 tcp_timer_activate(tp, TT_KEEP, tcp_keepinit); 1208 tp->iss = tcp_new_isn(tp); 1209 tp->t_bw_rtseq = tp->iss; 1210 tcp_sendseqinit(tp); 1211 1212 return 0; 1213 } 1214 #endif /* INET6 */ 1215 1216 /* 1217 * Export TCP internal state information via a struct tcp_info, based on the 1218 * Linux 2.6 API. Not ABI compatible as our constants are mapped differently 1219 * (TCP state machine, etc). We export all information using FreeBSD-native 1220 * constants -- for example, the numeric values for tcpi_state will differ 1221 * from Linux. 1222 */ 1223 static void 1224 tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti) 1225 { 1226 1227 INP_WLOCK_ASSERT(tp->t_inpcb); 1228 bzero(ti, sizeof(*ti)); 1229 1230 ti->tcpi_state = tp->t_state; 1231 if ((tp->t_flags & TF_REQ_TSTMP) && (tp->t_flags & TF_RCVD_TSTMP)) 1232 ti->tcpi_options |= TCPI_OPT_TIMESTAMPS; 1233 if (tp->t_flags & TF_SACK_PERMIT) 1234 ti->tcpi_options |= TCPI_OPT_SACK; 1235 if ((tp->t_flags & TF_REQ_SCALE) && (tp->t_flags & TF_RCVD_SCALE)) { 1236 ti->tcpi_options |= TCPI_OPT_WSCALE; 1237 ti->tcpi_snd_wscale = tp->snd_scale; 1238 ti->tcpi_rcv_wscale = tp->rcv_scale; 1239 } 1240 1241 ti->tcpi_rtt = ((u_int64_t)tp->t_srtt * tick) >> TCP_RTT_SHIFT; 1242 ti->tcpi_rttvar = ((u_int64_t)tp->t_rttvar * tick) >> TCP_RTTVAR_SHIFT; 1243 1244 ti->tcpi_snd_ssthresh = tp->snd_ssthresh; 1245 ti->tcpi_snd_cwnd = tp->snd_cwnd; 1246 1247 /* 1248 * FreeBSD-specific extension fields for tcp_info. 1249 */ 1250 ti->tcpi_rcv_space = tp->rcv_wnd; 1251 ti->tcpi_rcv_nxt = tp->rcv_nxt; 1252 ti->tcpi_snd_wnd = tp->snd_wnd; 1253 ti->tcpi_snd_bwnd = tp->snd_bwnd; 1254 ti->tcpi_snd_nxt = tp->snd_nxt; 1255 ti->__tcpi_snd_mss = tp->t_maxseg; 1256 ti->__tcpi_rcv_mss = tp->t_maxseg; 1257 if (tp->t_flags & TF_TOE) 1258 ti->tcpi_options |= TCPI_OPT_TOE; 1259 } 1260 1261 /* 1262 * tcp_ctloutput() must drop the inpcb lock before performing copyin on 1263 * socket option arguments. When it re-acquires the lock after the copy, it 1264 * has to revalidate that the connection is still valid for the socket 1265 * option. 1266 */ 1267 #define INP_WLOCK_RECHECK(inp) do { \ 1268 INP_WLOCK(inp); \ 1269 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { \ 1270 INP_WUNLOCK(inp); \ 1271 return (ECONNRESET); \ 1272 } \ 1273 tp = intotcpcb(inp); \ 1274 } while(0) 1275 1276 int 1277 tcp_ctloutput(struct socket *so, struct sockopt *sopt) 1278 { 1279 INIT_VNET_INET(so->so_vnet); 1280 int error, opt, optval; 1281 struct inpcb *inp; 1282 struct tcpcb *tp; 1283 struct tcp_info ti; 1284 1285 error = 0; 1286 inp = sotoinpcb(so); 1287 KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL")); 1288 INP_WLOCK(inp); 1289 if (sopt->sopt_level != IPPROTO_TCP) { 1290 #ifdef INET6 1291 if (INP_CHECK_SOCKAF(so, AF_INET6)) { 1292 INP_WUNLOCK(inp); 1293 error = ip6_ctloutput(so, sopt); 1294 } else { 1295 #endif /* INET6 */ 1296 INP_WUNLOCK(inp); 1297 error = ip_ctloutput(so, sopt); 1298 #ifdef INET6 1299 } 1300 #endif 1301 return (error); 1302 } 1303 if (inp->inp_vflag & (INP_TIMEWAIT | INP_DROPPED)) { 1304 INP_WUNLOCK(inp); 1305 return (ECONNRESET); 1306 } 1307 1308 switch (sopt->sopt_dir) { 1309 case SOPT_SET: 1310 switch (sopt->sopt_name) { 1311 #ifdef TCP_SIGNATURE 1312 case TCP_MD5SIG: 1313 INP_WUNLOCK(inp); 1314 error = sooptcopyin(sopt, &optval, sizeof optval, 1315 sizeof optval); 1316 if (error) 1317 return (error); 1318 1319 INP_WLOCK_RECHECK(inp); 1320 if (optval > 0) 1321 tp->t_flags |= TF_SIGNATURE; 1322 else 1323 tp->t_flags &= ~TF_SIGNATURE; 1324 INP_WUNLOCK(inp); 1325 break; 1326 #endif /* TCP_SIGNATURE */ 1327 case TCP_NODELAY: 1328 case TCP_NOOPT: 1329 INP_WUNLOCK(inp); 1330 error = sooptcopyin(sopt, &optval, sizeof optval, 1331 sizeof optval); 1332 if (error) 1333 return (error); 1334 1335 INP_WLOCK_RECHECK(inp); 1336 switch (sopt->sopt_name) { 1337 case TCP_NODELAY: 1338 opt = TF_NODELAY; 1339 break; 1340 case TCP_NOOPT: 1341 opt = TF_NOOPT; 1342 break; 1343 default: 1344 opt = 0; /* dead code to fool gcc */ 1345 break; 1346 } 1347 1348 if (optval) 1349 tp->t_flags |= opt; 1350 else 1351 tp->t_flags &= ~opt; 1352 INP_WUNLOCK(inp); 1353 break; 1354 1355 case TCP_NOPUSH: 1356 INP_WUNLOCK(inp); 1357 error = sooptcopyin(sopt, &optval, sizeof optval, 1358 sizeof optval); 1359 if (error) 1360 return (error); 1361 1362 INP_WLOCK_RECHECK(inp); 1363 if (optval) 1364 tp->t_flags |= TF_NOPUSH; 1365 else { 1366 tp->t_flags &= ~TF_NOPUSH; 1367 error = tcp_output(tp); 1368 } 1369 INP_WUNLOCK(inp); 1370 break; 1371 1372 case TCP_MAXSEG: 1373 INP_WUNLOCK(inp); 1374 error = sooptcopyin(sopt, &optval, sizeof optval, 1375 sizeof optval); 1376 if (error) 1377 return (error); 1378 1379 INP_WLOCK_RECHECK(inp); 1380 if (optval > 0 && optval <= tp->t_maxseg && 1381 optval + 40 >= V_tcp_minmss) 1382 tp->t_maxseg = optval; 1383 else 1384 error = EINVAL; 1385 INP_WUNLOCK(inp); 1386 break; 1387 1388 case TCP_INFO: 1389 INP_WUNLOCK(inp); 1390 error = EINVAL; 1391 break; 1392 1393 default: 1394 INP_WUNLOCK(inp); 1395 error = ENOPROTOOPT; 1396 break; 1397 } 1398 break; 1399 1400 case SOPT_GET: 1401 tp = intotcpcb(inp); 1402 switch (sopt->sopt_name) { 1403 #ifdef TCP_SIGNATURE 1404 case TCP_MD5SIG: 1405 optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0; 1406 INP_WUNLOCK(inp); 1407 error = sooptcopyout(sopt, &optval, sizeof optval); 1408 break; 1409 #endif 1410 1411 case TCP_NODELAY: 1412 optval = tp->t_flags & TF_NODELAY; 1413 INP_WUNLOCK(inp); 1414 error = sooptcopyout(sopt, &optval, sizeof optval); 1415 break; 1416 case TCP_MAXSEG: 1417 optval = tp->t_maxseg; 1418 INP_WUNLOCK(inp); 1419 error = sooptcopyout(sopt, &optval, sizeof optval); 1420 break; 1421 case TCP_NOOPT: 1422 optval = tp->t_flags & TF_NOOPT; 1423 INP_WUNLOCK(inp); 1424 error = sooptcopyout(sopt, &optval, sizeof optval); 1425 break; 1426 case TCP_NOPUSH: 1427 optval = tp->t_flags & TF_NOPUSH; 1428 INP_WUNLOCK(inp); 1429 error = sooptcopyout(sopt, &optval, sizeof optval); 1430 break; 1431 case TCP_INFO: 1432 tcp_fill_info(tp, &ti); 1433 INP_WUNLOCK(inp); 1434 error = sooptcopyout(sopt, &ti, sizeof ti); 1435 break; 1436 default: 1437 INP_WUNLOCK(inp); 1438 error = ENOPROTOOPT; 1439 break; 1440 } 1441 break; 1442 } 1443 return (error); 1444 } 1445 #undef INP_WLOCK_RECHECK 1446 1447 /* 1448 * tcp_sendspace and tcp_recvspace are the default send and receive window 1449 * sizes, respectively. These are obsolescent (this information should 1450 * be set by the route). 1451 */ 1452 u_long tcp_sendspace = 1024*32; 1453 SYSCTL_ULONG(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLFLAG_RW, 1454 &tcp_sendspace , 0, "Maximum outgoing TCP datagram size"); 1455 u_long tcp_recvspace = 1024*64; 1456 SYSCTL_ULONG(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLFLAG_RW, 1457 &tcp_recvspace , 0, "Maximum incoming TCP datagram size"); 1458 1459 /* 1460 * Attach TCP protocol to socket, allocating 1461 * internet protocol control block, tcp control block, 1462 * bufer space, and entering LISTEN state if to accept connections. 1463 */ 1464 static int 1465 tcp_attach(struct socket *so) 1466 { 1467 INIT_VNET_INET(so->so_vnet); 1468 struct tcpcb *tp; 1469 struct inpcb *inp; 1470 int error; 1471 #ifdef INET6 1472 int isipv6 = INP_CHECK_SOCKAF(so, AF_INET6) != 0; 1473 #endif 1474 1475 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 1476 error = soreserve(so, tcp_sendspace, tcp_recvspace); 1477 if (error) 1478 return (error); 1479 } 1480 so->so_rcv.sb_flags |= SB_AUTOSIZE; 1481 so->so_snd.sb_flags |= SB_AUTOSIZE; 1482 INP_INFO_WLOCK(&V_tcbinfo); 1483 error = in_pcballoc(so, &V_tcbinfo); 1484 if (error) { 1485 INP_INFO_WUNLOCK(&V_tcbinfo); 1486 return (error); 1487 } 1488 inp = sotoinpcb(so); 1489 #ifdef INET6 1490 if (isipv6) { 1491 inp->inp_vflag |= INP_IPV6; 1492 inp->in6p_hops = -1; /* use kernel default */ 1493 } 1494 else 1495 #endif 1496 inp->inp_vflag |= INP_IPV4; 1497 tp = tcp_newtcpcb(inp); 1498 if (tp == NULL) { 1499 #ifdef INET6 1500 if (isipv6) { 1501 in6_pcbdetach(inp); 1502 in6_pcbfree(inp); 1503 } else { 1504 #endif 1505 in_pcbdetach(inp); 1506 in_pcbfree(inp); 1507 #ifdef INET6 1508 } 1509 #endif 1510 INP_INFO_WUNLOCK(&V_tcbinfo); 1511 return (ENOBUFS); 1512 } 1513 tp->t_state = TCPS_CLOSED; 1514 INP_WUNLOCK(inp); 1515 INP_INFO_WUNLOCK(&V_tcbinfo); 1516 return (0); 1517 } 1518 1519 /* 1520 * Initiate (or continue) disconnect. 1521 * If embryonic state, just send reset (once). 1522 * If in ``let data drain'' option and linger null, just drop. 1523 * Otherwise (hard), mark socket disconnecting and drop 1524 * current input data; switch states based on user close, and 1525 * send segment to peer (with FIN). 1526 */ 1527 static void 1528 tcp_disconnect(struct tcpcb *tp) 1529 { 1530 struct inpcb *inp = tp->t_inpcb; 1531 struct socket *so = inp->inp_socket; 1532 #ifdef INVARIANTS 1533 INIT_VNET_INET(so->so_vnet); 1534 #endif 1535 1536 INP_INFO_WLOCK_ASSERT(&V_tcbinfo); 1537 INP_WLOCK_ASSERT(inp); 1538 1539 /* 1540 * Neither tcp_close() nor tcp_drop() should return NULL, as the 1541 * socket is still open. 1542 */ 1543 if (tp->t_state < TCPS_ESTABLISHED) { 1544 tp = tcp_close(tp); 1545 KASSERT(tp != NULL, 1546 ("tcp_disconnect: tcp_close() returned NULL")); 1547 } else if ((so->so_options & SO_LINGER) && so->so_linger == 0) { 1548 tp = tcp_drop(tp, 0); 1549 KASSERT(tp != NULL, 1550 ("tcp_disconnect: tcp_drop() returned NULL")); 1551 } else { 1552 soisdisconnecting(so); 1553 sbflush(&so->so_rcv); 1554 tcp_usrclosed(tp); 1555 if (!(inp->inp_vflag & INP_DROPPED)) 1556 tcp_output_disconnect(tp); 1557 } 1558 } 1559 1560 /* 1561 * User issued close, and wish to trail through shutdown states: 1562 * if never received SYN, just forget it. If got a SYN from peer, 1563 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 1564 * If already got a FIN from peer, then almost done; go to LAST_ACK 1565 * state. In all other cases, have already sent FIN to peer (e.g. 1566 * after PRU_SHUTDOWN), and just have to play tedious game waiting 1567 * for peer to send FIN or not respond to keep-alives, etc. 1568 * We can let the user exit from the close as soon as the FIN is acked. 1569 */ 1570 static void 1571 tcp_usrclosed(struct tcpcb *tp) 1572 { 1573 #ifdef INVARIANTS 1574 INIT_VNET_INET(tp->t_inpcb->inp_vnet); 1575 #endif 1576 1577 INP_INFO_WLOCK_ASSERT(&V_tcbinfo); 1578 INP_WLOCK_ASSERT(tp->t_inpcb); 1579 1580 switch (tp->t_state) { 1581 case TCPS_LISTEN: 1582 tcp_offload_listen_close(tp); 1583 /* FALLTHROUGH */ 1584 case TCPS_CLOSED: 1585 tp->t_state = TCPS_CLOSED; 1586 tp = tcp_close(tp); 1587 /* 1588 * tcp_close() should never return NULL here as the socket is 1589 * still open. 1590 */ 1591 KASSERT(tp != NULL, 1592 ("tcp_usrclosed: tcp_close() returned NULL")); 1593 break; 1594 1595 case TCPS_SYN_SENT: 1596 case TCPS_SYN_RECEIVED: 1597 tp->t_flags |= TF_NEEDFIN; 1598 break; 1599 1600 case TCPS_ESTABLISHED: 1601 tp->t_state = TCPS_FIN_WAIT_1; 1602 break; 1603 1604 case TCPS_CLOSE_WAIT: 1605 tp->t_state = TCPS_LAST_ACK; 1606 break; 1607 } 1608 if (tp->t_state >= TCPS_FIN_WAIT_2) { 1609 soisdisconnected(tp->t_inpcb->inp_socket); 1610 /* Prevent the connection hanging in FIN_WAIT_2 forever. */ 1611 if (tp->t_state == TCPS_FIN_WAIT_2) { 1612 int timeout; 1613 1614 timeout = (tcp_fast_finwait2_recycle) ? 1615 tcp_finwait2_timeout : tcp_maxidle; 1616 tcp_timer_activate(tp, TT_2MSL, timeout); 1617 } 1618 } 1619 } 1620 1621 #ifdef DDB 1622 static void 1623 db_print_indent(int indent) 1624 { 1625 int i; 1626 1627 for (i = 0; i < indent; i++) 1628 db_printf(" "); 1629 } 1630 1631 static void 1632 db_print_tstate(int t_state) 1633 { 1634 1635 switch (t_state) { 1636 case TCPS_CLOSED: 1637 db_printf("TCPS_CLOSED"); 1638 return; 1639 1640 case TCPS_LISTEN: 1641 db_printf("TCPS_LISTEN"); 1642 return; 1643 1644 case TCPS_SYN_SENT: 1645 db_printf("TCPS_SYN_SENT"); 1646 return; 1647 1648 case TCPS_SYN_RECEIVED: 1649 db_printf("TCPS_SYN_RECEIVED"); 1650 return; 1651 1652 case TCPS_ESTABLISHED: 1653 db_printf("TCPS_ESTABLISHED"); 1654 return; 1655 1656 case TCPS_CLOSE_WAIT: 1657 db_printf("TCPS_CLOSE_WAIT"); 1658 return; 1659 1660 case TCPS_FIN_WAIT_1: 1661 db_printf("TCPS_FIN_WAIT_1"); 1662 return; 1663 1664 case TCPS_CLOSING: 1665 db_printf("TCPS_CLOSING"); 1666 return; 1667 1668 case TCPS_LAST_ACK: 1669 db_printf("TCPS_LAST_ACK"); 1670 return; 1671 1672 case TCPS_FIN_WAIT_2: 1673 db_printf("TCPS_FIN_WAIT_2"); 1674 return; 1675 1676 case TCPS_TIME_WAIT: 1677 db_printf("TCPS_TIME_WAIT"); 1678 return; 1679 1680 default: 1681 db_printf("unknown"); 1682 return; 1683 } 1684 } 1685 1686 static void 1687 db_print_tflags(u_int t_flags) 1688 { 1689 int comma; 1690 1691 comma = 0; 1692 if (t_flags & TF_ACKNOW) { 1693 db_printf("%sTF_ACKNOW", comma ? ", " : ""); 1694 comma = 1; 1695 } 1696 if (t_flags & TF_DELACK) { 1697 db_printf("%sTF_DELACK", comma ? ", " : ""); 1698 comma = 1; 1699 } 1700 if (t_flags & TF_NODELAY) { 1701 db_printf("%sTF_NODELAY", comma ? ", " : ""); 1702 comma = 1; 1703 } 1704 if (t_flags & TF_NOOPT) { 1705 db_printf("%sTF_NOOPT", comma ? ", " : ""); 1706 comma = 1; 1707 } 1708 if (t_flags & TF_SENTFIN) { 1709 db_printf("%sTF_SENTFIN", comma ? ", " : ""); 1710 comma = 1; 1711 } 1712 if (t_flags & TF_REQ_SCALE) { 1713 db_printf("%sTF_REQ_SCALE", comma ? ", " : ""); 1714 comma = 1; 1715 } 1716 if (t_flags & TF_RCVD_SCALE) { 1717 db_printf("%sTF_RECVD_SCALE", comma ? ", " : ""); 1718 comma = 1; 1719 } 1720 if (t_flags & TF_REQ_TSTMP) { 1721 db_printf("%sTF_REQ_TSTMP", comma ? ", " : ""); 1722 comma = 1; 1723 } 1724 if (t_flags & TF_RCVD_TSTMP) { 1725 db_printf("%sTF_RCVD_TSTMP", comma ? ", " : ""); 1726 comma = 1; 1727 } 1728 if (t_flags & TF_SACK_PERMIT) { 1729 db_printf("%sTF_SACK_PERMIT", comma ? ", " : ""); 1730 comma = 1; 1731 } 1732 if (t_flags & TF_NEEDSYN) { 1733 db_printf("%sTF_NEEDSYN", comma ? ", " : ""); 1734 comma = 1; 1735 } 1736 if (t_flags & TF_NEEDFIN) { 1737 db_printf("%sTF_NEEDFIN", comma ? ", " : ""); 1738 comma = 1; 1739 } 1740 if (t_flags & TF_NOPUSH) { 1741 db_printf("%sTF_NOPUSH", comma ? ", " : ""); 1742 comma = 1; 1743 } 1744 if (t_flags & TF_NOPUSH) { 1745 db_printf("%sTF_NOPUSH", comma ? ", " : ""); 1746 comma = 1; 1747 } 1748 if (t_flags & TF_MORETOCOME) { 1749 db_printf("%sTF_MORETOCOME", comma ? ", " : ""); 1750 comma = 1; 1751 } 1752 if (t_flags & TF_LQ_OVERFLOW) { 1753 db_printf("%sTF_LQ_OVERFLOW", comma ? ", " : ""); 1754 comma = 1; 1755 } 1756 if (t_flags & TF_LASTIDLE) { 1757 db_printf("%sTF_LASTIDLE", comma ? ", " : ""); 1758 comma = 1; 1759 } 1760 if (t_flags & TF_RXWIN0SENT) { 1761 db_printf("%sTF_RXWIN0SENT", comma ? ", " : ""); 1762 comma = 1; 1763 } 1764 if (t_flags & TF_FASTRECOVERY) { 1765 db_printf("%sTF_FASTRECOVERY", comma ? ", " : ""); 1766 comma = 1; 1767 } 1768 if (t_flags & TF_WASFRECOVERY) { 1769 db_printf("%sTF_WASFRECOVERY", comma ? ", " : ""); 1770 comma = 1; 1771 } 1772 if (t_flags & TF_SIGNATURE) { 1773 db_printf("%sTF_SIGNATURE", comma ? ", " : ""); 1774 comma = 1; 1775 } 1776 if (t_flags & TF_FORCEDATA) { 1777 db_printf("%sTF_FORCEDATA", comma ? ", " : ""); 1778 comma = 1; 1779 } 1780 if (t_flags & TF_TSO) { 1781 db_printf("%sTF_TSO", comma ? ", " : ""); 1782 comma = 1; 1783 } 1784 if (t_flags & TF_ECN_PERMIT) { 1785 db_printf("%sTF_ECN_PERMIT", comma ? ", " : ""); 1786 comma = 1; 1787 } 1788 } 1789 1790 static void 1791 db_print_toobflags(char t_oobflags) 1792 { 1793 int comma; 1794 1795 comma = 0; 1796 if (t_oobflags & TCPOOB_HAVEDATA) { 1797 db_printf("%sTCPOOB_HAVEDATA", comma ? ", " : ""); 1798 comma = 1; 1799 } 1800 if (t_oobflags & TCPOOB_HADDATA) { 1801 db_printf("%sTCPOOB_HADDATA", comma ? ", " : ""); 1802 comma = 1; 1803 } 1804 } 1805 1806 static void 1807 db_print_tcpcb(struct tcpcb *tp, const char *name, int indent) 1808 { 1809 1810 db_print_indent(indent); 1811 db_printf("%s at %p\n", name, tp); 1812 1813 indent += 2; 1814 1815 db_print_indent(indent); 1816 db_printf("t_segq first: %p t_segqlen: %d t_dupacks: %d\n", 1817 LIST_FIRST(&tp->t_segq), tp->t_segqlen, tp->t_dupacks); 1818 1819 db_print_indent(indent); 1820 db_printf("tt_rexmt: %p tt_persist: %p tt_keep: %p\n", 1821 &tp->t_timers->tt_rexmt, &tp->t_timers->tt_persist, &tp->t_timers->tt_keep); 1822 1823 db_print_indent(indent); 1824 db_printf("tt_2msl: %p tt_delack: %p t_inpcb: %p\n", &tp->t_timers->tt_2msl, 1825 &tp->t_timers->tt_delack, tp->t_inpcb); 1826 1827 db_print_indent(indent); 1828 db_printf("t_state: %d (", tp->t_state); 1829 db_print_tstate(tp->t_state); 1830 db_printf(")\n"); 1831 1832 db_print_indent(indent); 1833 db_printf("t_flags: 0x%x (", tp->t_flags); 1834 db_print_tflags(tp->t_flags); 1835 db_printf(")\n"); 1836 1837 db_print_indent(indent); 1838 db_printf("snd_una: 0x%08x snd_max: 0x%08x snd_nxt: x0%08x\n", 1839 tp->snd_una, tp->snd_max, tp->snd_nxt); 1840 1841 db_print_indent(indent); 1842 db_printf("snd_up: 0x%08x snd_wl1: 0x%08x snd_wl2: 0x%08x\n", 1843 tp->snd_up, tp->snd_wl1, tp->snd_wl2); 1844 1845 db_print_indent(indent); 1846 db_printf("iss: 0x%08x irs: 0x%08x rcv_nxt: 0x%08x\n", 1847 tp->iss, tp->irs, tp->rcv_nxt); 1848 1849 db_print_indent(indent); 1850 db_printf("rcv_adv: 0x%08x rcv_wnd: %lu rcv_up: 0x%08x\n", 1851 tp->rcv_adv, tp->rcv_wnd, tp->rcv_up); 1852 1853 db_print_indent(indent); 1854 db_printf("snd_wnd: %lu snd_cwnd: %lu snd_bwnd: %lu\n", 1855 tp->snd_wnd, tp->snd_cwnd, tp->snd_bwnd); 1856 1857 db_print_indent(indent); 1858 db_printf("snd_ssthresh: %lu snd_bandwidth: %lu snd_recover: " 1859 "0x%08x\n", tp->snd_ssthresh, tp->snd_bandwidth, 1860 tp->snd_recover); 1861 1862 db_print_indent(indent); 1863 db_printf("t_maxopd: %u t_rcvtime: %lu t_startime: %lu\n", 1864 tp->t_maxopd, tp->t_rcvtime, tp->t_starttime); 1865 1866 db_print_indent(indent); 1867 db_printf("t_rttime: %d t_rtsq: 0x%08x t_bw_rtttime: %d\n", 1868 tp->t_rtttime, tp->t_rtseq, tp->t_bw_rtttime); 1869 1870 db_print_indent(indent); 1871 db_printf("t_bw_rtseq: 0x%08x t_rxtcur: %d t_maxseg: %u " 1872 "t_srtt: %d\n", tp->t_bw_rtseq, tp->t_rxtcur, tp->t_maxseg, 1873 tp->t_srtt); 1874 1875 db_print_indent(indent); 1876 db_printf("t_rttvar: %d t_rxtshift: %d t_rttmin: %u " 1877 "t_rttbest: %u\n", tp->t_rttvar, tp->t_rxtshift, tp->t_rttmin, 1878 tp->t_rttbest); 1879 1880 db_print_indent(indent); 1881 db_printf("t_rttupdated: %lu max_sndwnd: %lu t_softerror: %d\n", 1882 tp->t_rttupdated, tp->max_sndwnd, tp->t_softerror); 1883 1884 db_print_indent(indent); 1885 db_printf("t_oobflags: 0x%x (", tp->t_oobflags); 1886 db_print_toobflags(tp->t_oobflags); 1887 db_printf(") t_iobc: 0x%02x\n", tp->t_iobc); 1888 1889 db_print_indent(indent); 1890 db_printf("snd_scale: %u rcv_scale: %u request_r_scale: %u\n", 1891 tp->snd_scale, tp->rcv_scale, tp->request_r_scale); 1892 1893 db_print_indent(indent); 1894 db_printf("ts_recent: %u ts_recent_age: %lu\n", 1895 tp->ts_recent, tp->ts_recent_age); 1896 1897 db_print_indent(indent); 1898 db_printf("ts_offset: %u last_ack_sent: 0x%08x snd_cwnd_prev: " 1899 "%lu\n", tp->ts_offset, tp->last_ack_sent, tp->snd_cwnd_prev); 1900 1901 db_print_indent(indent); 1902 db_printf("snd_ssthresh_prev: %lu snd_recover_prev: 0x%08x " 1903 "t_badrxtwin: %lu\n", tp->snd_ssthresh_prev, 1904 tp->snd_recover_prev, tp->t_badrxtwin); 1905 1906 db_print_indent(indent); 1907 db_printf("snd_numholes: %d snd_holes first: %p\n", 1908 tp->snd_numholes, TAILQ_FIRST(&tp->snd_holes)); 1909 1910 db_print_indent(indent); 1911 db_printf("snd_fack: 0x%08x rcv_numsacks: %d sack_newdata: " 1912 "0x%08x\n", tp->snd_fack, tp->rcv_numsacks, tp->sack_newdata); 1913 1914 /* Skip sackblks, sackhint. */ 1915 1916 db_print_indent(indent); 1917 db_printf("t_rttlow: %d rfbuf_ts: %u rfbuf_cnt: %d\n", 1918 tp->t_rttlow, tp->rfbuf_ts, tp->rfbuf_cnt); 1919 } 1920 1921 DB_SHOW_COMMAND(tcpcb, db_show_tcpcb) 1922 { 1923 struct tcpcb *tp; 1924 1925 if (!have_addr) { 1926 db_printf("usage: show tcpcb <addr>\n"); 1927 return; 1928 } 1929 tp = (struct tcpcb *)addr; 1930 1931 db_print_tcpcb(tp, "tcpcb", 0); 1932 } 1933 #endif 1934