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