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