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