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