1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1548 rshoaib * Common Development and Distribution License (the "License"). 6 1548 rshoaib * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 1548 rshoaib 22 1548 rshoaib /* 23 8477 Rao * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel #include <sys/types.h> 28 0 stevel #include <sys/t_lock.h> 29 0 stevel #include <sys/param.h> 30 0 stevel #include <sys/systm.h> 31 0 stevel #include <sys/buf.h> 32 0 stevel #include <sys/conf.h> 33 0 stevel #include <sys/cred.h> 34 0 stevel #include <sys/kmem.h> 35 8348 Eric #include <sys/kmem_impl.h> 36 0 stevel #include <sys/sysmacros.h> 37 0 stevel #include <sys/vfs.h> 38 0 stevel #include <sys/vnode.h> 39 0 stevel #include <sys/debug.h> 40 0 stevel #include <sys/errno.h> 41 0 stevel #include <sys/time.h> 42 0 stevel #include <sys/file.h> 43 0 stevel #include <sys/open.h> 44 0 stevel #include <sys/user.h> 45 0 stevel #include <sys/termios.h> 46 0 stevel #include <sys/stream.h> 47 0 stevel #include <sys/strsubr.h> 48 0 stevel #include <sys/strsun.h> 49 8348 Eric #include <sys/suntpi.h> 50 0 stevel #include <sys/ddi.h> 51 0 stevel #include <sys/esunddi.h> 52 0 stevel #include <sys/flock.h> 53 0 stevel #include <sys/modctl.h> 54 0 stevel #include <sys/vtrace.h> 55 0 stevel #include <sys/cmn_err.h> 56 0 stevel #include <sys/pathname.h> 57 0 stevel 58 0 stevel #include <sys/socket.h> 59 0 stevel #include <sys/socketvar.h> 60 741 masputra #include <sys/sockio.h> 61 0 stevel #include <netinet/in.h> 62 0 stevel #include <sys/un.h> 63 0 stevel #include <sys/strsun.h> 64 0 stevel 65 0 stevel #include <sys/tiuser.h> 66 0 stevel #define _SUN_TPI_VERSION 2 67 0 stevel #include <sys/tihdr.h> 68 0 stevel #include <sys/timod.h> /* TI_GETMYNAME, TI_GETPEERNAME */ 69 0 stevel 70 0 stevel #include <c2/audit.h> 71 0 stevel 72 0 stevel #include <inet/common.h> 73 0 stevel #include <inet/ip.h> 74 0 stevel #include <inet/ip6.h> 75 0 stevel #include <inet/tcp.h> 76 741 masputra #include <inet/udp_impl.h> 77 0 stevel 78 1974 brutus #include <sys/zone.h> 79 1974 brutus 80 0 stevel #include <fs/sockfs/nl7c.h> 81 1974 brutus #include <fs/sockfs/nl7curi.h> 82 0 stevel 83 898 kais #include <inet/kssl/ksslapi.h> 84 8348 Eric 85 8348 Eric #include <fs/sockfs/sockcommon.h> 86 8348 Eric #include <fs/sockfs/socktpi.h> 87 8348 Eric #include <fs/sockfs/socktpi_impl.h> 88 898 kais 89 0 stevel /* 90 0 stevel * Possible failures when memory can't be allocated. The documented behavior: 91 0 stevel * 92 0 stevel * 5.5: 4.X: XNET: 93 0 stevel * accept: ENOMEM/ENOSR/EINTR - (EINTR) ENOMEM/ENOBUFS/ENOSR/ 94 0 stevel * EINTR 95 0 stevel * (4.X does not document EINTR but returns it) 96 0 stevel * bind: ENOSR - ENOBUFS/ENOSR 97 0 stevel * connect: EINTR EINTR ENOBUFS/ENOSR/EINTR 98 0 stevel * getpeername: ENOMEM/ENOSR ENOBUFS (-) ENOBUFS/ENOSR 99 0 stevel * getsockname: ENOMEM/ENOSR ENOBUFS (-) ENOBUFS/ENOSR 100 0 stevel * (4.X getpeername and getsockname do not fail in practice) 101 0 stevel * getsockopt: ENOMEM/ENOSR - ENOBUFS/ENOSR 102 0 stevel * listen: - - ENOBUFS 103 0 stevel * recv: ENOMEM/ENOSR/EINTR EINTR ENOBUFS/ENOMEM/ENOSR/ 104 0 stevel * EINTR 105 0 stevel * send: ENOMEM/ENOSR/EINTR ENOBUFS/EINTR ENOBUFS/ENOMEM/ENOSR/ 106 0 stevel * EINTR 107 0 stevel * setsockopt: ENOMEM/ENOSR - ENOBUFS/ENOMEM/ENOSR 108 0 stevel * shutdown: ENOMEM/ENOSR - ENOBUFS/ENOSR 109 0 stevel * socket: ENOMEM/ENOSR ENOBUFS ENOBUFS/ENOMEM/ENOSR 110 0 stevel * socketpair: ENOMEM/ENOSR - ENOBUFS/ENOMEM/ENOSR 111 0 stevel * 112 0 stevel * Resolution. When allocation fails: 113 0 stevel * recv: return EINTR 114 0 stevel * send: return EINTR 115 0 stevel * connect, accept: EINTR 116 0 stevel * bind, listen, shutdown (unbind, unix_close, disconnect): sleep 117 0 stevel * socket, socketpair: ENOBUFS 118 0 stevel * getpeername, getsockname: sleep 119 0 stevel * getsockopt, setsockopt: sleep 120 0 stevel */ 121 0 stevel 122 0 stevel #ifdef SOCK_TEST 123 0 stevel /* 124 0 stevel * Variables that make sockfs do something other than the standard TPI 125 0 stevel * for the AF_INET transports. 126 0 stevel * 127 0 stevel * solisten_tpi_tcp: 128 0 stevel * TCP can handle a O_T_BIND_REQ with an increased backlog even though 129 0 stevel * the transport is already bound. This is needed to avoid loosing the 130 0 stevel * port number should listen() do a T_UNBIND_REQ followed by a 131 0 stevel * O_T_BIND_REQ. 132 0 stevel * 133 0 stevel * soconnect_tpi_udp: 134 0 stevel * UDP and ICMP can handle a T_CONN_REQ. 135 0 stevel * This is needed to make the sequence of connect(), getsockname() 136 0 stevel * return the local IP address used to send packets to the connected to 137 0 stevel * destination. 138 0 stevel * 139 0 stevel * soconnect_tpi_tcp: 140 0 stevel * TCP can handle a T_CONN_REQ without seeing a O_T_BIND_REQ. 141 0 stevel * Set this to non-zero to send TPI conformant messages to TCP in this 142 0 stevel * respect. This is a performance optimization. 143 0 stevel * 144 0 stevel * soaccept_tpi_tcp: 145 0 stevel * TCP can handle a T_CONN_REQ without the acceptor being bound. 146 0 stevel * This is a performance optimization that has been picked up in XTI. 147 0 stevel * 148 0 stevel * soaccept_tpi_multioptions: 149 0 stevel * When inheriting SOL_SOCKET options from the listener to the accepting 150 0 stevel * socket send them as a single message for AF_INET{,6}. 151 0 stevel */ 152 0 stevel int solisten_tpi_tcp = 0; 153 0 stevel int soconnect_tpi_udp = 0; 154 0 stevel int soconnect_tpi_tcp = 0; 155 0 stevel int soaccept_tpi_tcp = 0; 156 0 stevel int soaccept_tpi_multioptions = 1; 157 0 stevel #else /* SOCK_TEST */ 158 0 stevel #define soconnect_tpi_tcp 0 159 0 stevel #define soconnect_tpi_udp 0 160 0 stevel #define solisten_tpi_tcp 0 161 0 stevel #define soaccept_tpi_tcp 0 162 0 stevel #define soaccept_tpi_multioptions 1 163 0 stevel #endif /* SOCK_TEST */ 164 0 stevel 165 0 stevel #ifdef SOCK_TEST 166 0 stevel extern int do_useracc; 167 0 stevel extern clock_t sock_test_timelimit; 168 0 stevel #endif /* SOCK_TEST */ 169 0 stevel 170 0 stevel /* 171 0 stevel * Some X/Open added checks might have to be backed out to keep SunOS 4.X 172 0 stevel * applications working. Turn on this flag to disable these checks. 173 0 stevel */ 174 0 stevel int xnet_skip_checks = 0; 175 0 stevel int xnet_check_print = 0; 176 0 stevel int xnet_truncate_print = 0; 177 0 stevel 178 8348 Eric static void sotpi_destroy(struct sonode *); 179 8348 Eric static struct sonode *sotpi_create(struct sockparams *, int, int, int, int, 180 8348 Eric int, int *, cred_t *cr); 181 8348 Eric 182 8348 Eric static boolean_t sotpi_info_create(struct sonode *, int); 183 8348 Eric static void sotpi_info_init(struct sonode *); 184 8348 Eric static void sotpi_info_fini(struct sonode *); 185 8348 Eric static void sotpi_info_destroy(struct sonode *); 186 8348 Eric 187 8348 Eric /* 188 8348 Eric * Do direct function call to the transport layer below; this would 189 8348 Eric * also allow the transport to utilize read-side synchronous stream 190 8348 Eric * interface if necessary. This is a /etc/system tunable that must 191 8348 Eric * not be modified on a running system. By default this is enabled 192 8348 Eric * for performance reasons and may be disabled for debugging purposes. 193 8348 Eric */ 194 8348 Eric boolean_t socktpi_direct = B_TRUE; 195 8348 Eric 196 8348 Eric static struct kmem_cache *socktpi_cache, *socktpi_unix_cache; 197 8348 Eric 198 0 stevel extern void sigintr(k_sigset_t *, int); 199 0 stevel extern void sigunintr(k_sigset_t *); 200 0 stevel 201 898 kais /* Sockets acting as an in-kernel SSL proxy */ 202 898 kais extern mblk_t *strsock_kssl_input(vnode_t *, mblk_t *, strwakeup_t *, 203 898 kais strsigset_t *, strsigset_t *, strpollset_t *); 204 898 kais extern mblk_t *strsock_kssl_output(vnode_t *, mblk_t *, strwakeup_t *, 205 898 kais strsigset_t *, strsigset_t *, strpollset_t *); 206 898 kais 207 0 stevel static int sotpi_unbind(struct sonode *, int); 208 6707 brutus 209 0 stevel /* TPI sockfs sonode operations */ 210 8348 Eric int sotpi_init(struct sonode *, struct sonode *, struct cred *, 211 8348 Eric int); 212 8348 Eric static int sotpi_accept(struct sonode *, int, struct cred *, 213 8348 Eric struct sonode **); 214 0 stevel static int sotpi_bind(struct sonode *, struct sockaddr *, socklen_t, 215 8348 Eric int, struct cred *); 216 8348 Eric static int sotpi_listen(struct sonode *, int, struct cred *); 217 0 stevel static int sotpi_connect(struct sonode *, const struct sockaddr *, 218 8348 Eric socklen_t, int, int, struct cred *); 219 8348 Eric extern int sotpi_recvmsg(struct sonode *, struct nmsghdr *, 220 8348 Eric struct uio *, struct cred *); 221 0 stevel static int sotpi_sendmsg(struct sonode *, struct nmsghdr *, 222 8348 Eric struct uio *, struct cred *); 223 8348 Eric static int sotpi_sendmblk(struct sonode *, struct nmsghdr *, int, 224 8348 Eric struct cred *, mblk_t **); 225 741 masputra static int sosend_dgramcmsg(struct sonode *, struct sockaddr *, socklen_t, 226 741 masputra struct uio *, void *, t_uscalar_t, int); 227 741 masputra static int sodgram_direct(struct sonode *, struct sockaddr *, 228 741 masputra socklen_t, struct uio *, int); 229 8348 Eric extern int sotpi_getpeername(struct sonode *, struct sockaddr *, 230 8348 Eric socklen_t *, boolean_t, struct cred *); 231 8348 Eric static int sotpi_getsockname(struct sonode *, struct sockaddr *, 232 8348 Eric socklen_t *, struct cred *); 233 8348 Eric static int sotpi_shutdown(struct sonode *, int, struct cred *); 234 8348 Eric extern int sotpi_getsockopt(struct sonode *, int, int, void *, 235 8348 Eric socklen_t *, int, struct cred *); 236 8348 Eric extern int sotpi_setsockopt(struct sonode *, int, int, const void *, 237 8348 Eric socklen_t, struct cred *); 238 8348 Eric static int sotpi_ioctl(struct sonode *, int, intptr_t, int, struct cred *, 239 8348 Eric int32_t *); 240 8348 Eric static int socktpi_plumbioctl(struct vnode *, int, intptr_t, int, 241 8348 Eric struct cred *, int32_t *); 242 8348 Eric static int sotpi_poll(struct sonode *, short, int, short *, 243 8348 Eric struct pollhead **); 244 8348 Eric static int sotpi_close(struct sonode *, int, struct cred *); 245 8348 Eric 246 8348 Eric static int i_sotpi_info_constructor(sotpi_info_t *); 247 8348 Eric static void i_sotpi_info_destructor(sotpi_info_t *); 248 0 stevel 249 0 stevel sonodeops_t sotpi_sonodeops = { 250 8348 Eric sotpi_init, /* sop_init */ 251 0 stevel sotpi_accept, /* sop_accept */ 252 0 stevel sotpi_bind, /* sop_bind */ 253 0 stevel sotpi_listen, /* sop_listen */ 254 0 stevel sotpi_connect, /* sop_connect */ 255 0 stevel sotpi_recvmsg, /* sop_recvmsg */ 256 0 stevel sotpi_sendmsg, /* sop_sendmsg */ 257 8348 Eric sotpi_sendmblk, /* sop_sendmblk */ 258 0 stevel sotpi_getpeername, /* sop_getpeername */ 259 0 stevel sotpi_getsockname, /* sop_getsockname */ 260 0 stevel sotpi_shutdown, /* sop_shutdown */ 261 0 stevel sotpi_getsockopt, /* sop_getsockopt */ 262 8348 Eric sotpi_setsockopt, /* sop_setsockopt */ 263 8348 Eric sotpi_ioctl, /* sop_ioctl */ 264 8348 Eric sotpi_poll, /* sop_poll */ 265 8348 Eric sotpi_close, /* sop_close */ 266 0 stevel }; 267 8348 Eric 268 8348 Eric /* 269 8348 Eric * Return a TPI socket vnode. 270 8348 Eric * 271 8348 Eric * Note that sockets assume that the driver will clone (either itself 272 8348 Eric * or by using the clone driver) i.e. a socket() call will always 273 8348 Eric * result in a new vnode being created. 274 8348 Eric */ 275 0 stevel 276 0 stevel /* 277 0 stevel * Common create code for socket and accept. If tso is set the values 278 0 stevel * from that node is used instead of issuing a T_INFO_REQ. 279 8348 Eric */ 280 8348 Eric 281 8348 Eric /* ARGSUSED */ 282 8348 Eric static struct sonode * 283 8348 Eric sotpi_create(struct sockparams *sp, int family, int type, int protocol, 284 8348 Eric int version, int sflags, int *errorp, cred_t *cr) 285 0 stevel { 286 0 stevel struct sonode *so; 287 8348 Eric kmem_cache_t *cp; 288 8348 Eric int sfamily = family; 289 8348 Eric 290 8348 Eric ASSERT(sp->sp_sdev_info.sd_vnode != NULL); 291 8348 Eric 292 8348 Eric if (family == AF_NCA) { 293 8348 Eric /* 294 8348 Eric * The request is for an NCA socket so for NL7C use the 295 8348 Eric * INET domain instead and mark NL7C_AF_NCA below. 296 8348 Eric */ 297 8348 Eric family = AF_INET; 298 8348 Eric /* 299 8348 Eric * NL7C is not supported in the non-global zone, 300 8348 Eric * we enforce this restriction here. 301 8348 Eric */ 302 8348 Eric if (getzoneid() != GLOBAL_ZONEID) { 303 8348 Eric *errorp = ENOTSUP; 304 8348 Eric return (NULL); 305 8348 Eric } 306 8348 Eric } 307 8348 Eric 308 8348 Eric /* 309 8348 Eric * to be compatible with old tpi socket implementation ignore 310 8348 Eric * sleep flag (sflags) passed in 311 8348 Eric */ 312 8348 Eric cp = (family == AF_UNIX) ? socktpi_unix_cache : socktpi_cache; 313 8348 Eric so = kmem_cache_alloc(cp, KM_SLEEP); 314 8348 Eric if (so == NULL) { 315 8348 Eric *errorp = ENOMEM; 316 8348 Eric return (NULL); 317 8348 Eric } 318 8348 Eric 319 8348 Eric sonode_init(so, sp, family, type, protocol, &sotpi_sonodeops); 320 8348 Eric sotpi_info_init(so); 321 8348 Eric 322 8348 Eric if (sfamily == AF_NCA) { 323 8348 Eric SOTOTPI(so)->sti_nl7c_flags = NL7C_AF_NCA; 324 8348 Eric } 325 8348 Eric 326 8348 Eric if (version == SOV_DEFAULT) 327 8348 Eric version = so_default_version; 328 8348 Eric 329 8348 Eric so->so_version = (short)version; 330 8348 Eric *errorp = 0; 331 8348 Eric 332 8348 Eric return (so); 333 8348 Eric } 334 8348 Eric 335 8348 Eric static void 336 8348 Eric sotpi_destroy(struct sonode *so) 337 8348 Eric { 338 8348 Eric kmem_cache_t *cp; 339 8348 Eric struct sockparams *origsp; 340 8348 Eric 341 8348 Eric /* 342 8348 Eric * If there is a new dealloc function (ie. smod_destroy_func), 343 8348 Eric * then it should check the correctness of the ops. 344 8348 Eric */ 345 8348 Eric 346 8348 Eric ASSERT(so->so_ops == &sotpi_sonodeops); 347 8348 Eric 348 8348 Eric origsp = SOTOTPI(so)->sti_orig_sp; 349 8348 Eric 350 8348 Eric sotpi_info_fini(so); 351 8348 Eric 352 8348 Eric if (so->so_state & SS_FALLBACK_COMP) { 353 8348 Eric /* 354 8348 Eric * A fallback happend, which means that a sotpi_info_t struct 355 8348 Eric * was allocated (as opposed to being allocated from the TPI 356 8348 Eric * sonode cache. Therefore we explicitly free the struct 357 8348 Eric * here. 358 8348 Eric */ 359 8348 Eric sotpi_info_destroy(so); 360 8348 Eric ASSERT(origsp != NULL); 361 8348 Eric 362 8348 Eric origsp->sp_smod_info->smod_sock_destroy_func(so); 363 8348 Eric SOCKPARAMS_DEC_REF(origsp); 364 8348 Eric } else { 365 8348 Eric sonode_fini(so); 366 8348 Eric cp = (so->so_family == AF_UNIX) ? socktpi_unix_cache : 367 8348 Eric socktpi_cache; 368 8348 Eric kmem_cache_free(cp, so); 369 8348 Eric } 370 8348 Eric } 371 8348 Eric 372 8348 Eric /* ARGSUSED1 */ 373 8348 Eric int 374 8348 Eric sotpi_init(struct sonode *so, struct sonode *tso, struct cred *cr, int flags) 375 8348 Eric { 376 8348 Eric major_t maj; 377 8348 Eric dev_t newdev; 378 8348 Eric struct vnode *vp; 379 8348 Eric int error = 0; 380 8348 Eric struct stdata *stp; 381 8348 Eric 382 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 383 8348 Eric 384 8348 Eric dprint(1, ("sotpi_init()\n")); 385 8348 Eric 386 8348 Eric /* 387 8348 Eric * over write the sleep flag passed in but that is ok 388 8348 Eric * as tpi socket does not honor sleep flag. 389 8348 Eric */ 390 8348 Eric flags |= FREAD|FWRITE; 391 8348 Eric 392 8348 Eric /* 393 8348 Eric * Record in so_flag that it is a clone. 394 8348 Eric */ 395 8348 Eric if (getmajor(sti->sti_dev) == clone_major) 396 8348 Eric so->so_flag |= SOCLONE; 397 8348 Eric 398 8348 Eric if ((so->so_type == SOCK_STREAM || so->so_type == SOCK_DGRAM) && 399 8348 Eric (so->so_family == AF_INET || so->so_family == AF_INET6) && 400 8348 Eric (so->so_protocol == IPPROTO_TCP || so->so_protocol == IPPROTO_UDP || 401 8348 Eric so->so_protocol == IPPROTO_IP)) { 402 741 masputra /* Tell tcp or udp that it's talking to sockets */ 403 741 masputra flags |= SO_SOCKSTR; 404 741 masputra 405 741 masputra /* 406 741 masputra * Here we indicate to socktpi_open() our attempt to 407 741 masputra * make direct calls between sockfs and transport. 408 741 masputra * The final decision is left to socktpi_open(). 409 741 masputra */ 410 8348 Eric sti->sti_direct = 1; 411 741 masputra 412 741 masputra ASSERT(so->so_type != SOCK_DGRAM || tso == NULL); 413 741 masputra if (so->so_type == SOCK_STREAM && tso != NULL) { 414 8348 Eric if (SOTOTPI(tso)->sti_direct) { 415 8348 Eric /* 416 8348 Eric * Inherit sti_direct from listener and pass 417 741 masputra * SO_ACCEPTOR open flag to tcp, indicating 418 741 masputra * that this is an accept fast-path instance. 419 741 masputra */ 420 741 masputra flags |= SO_ACCEPTOR; 421 741 masputra } else { 422 741 masputra /* 423 8348 Eric * sti_direct is not set on listener, meaning 424 741 masputra * that the listener has been converted from 425 741 masputra * a socket to a stream. Ensure that the 426 741 masputra * acceptor inherits these settings. 427 741 masputra */ 428 8348 Eric sti->sti_direct = 0; 429 741 masputra flags &= ~SO_SOCKSTR; 430 741 masputra } 431 0 stevel } 432 0 stevel } 433 0 stevel 434 0 stevel /* 435 0 stevel * Tell local transport that it is talking to sockets. 436 0 stevel */ 437 0 stevel if (so->so_family == AF_UNIX) { 438 0 stevel flags |= SO_SOCKSTR; 439 0 stevel } 440 0 stevel 441 8348 Eric vp = SOTOV(so); 442 8348 Eric newdev = vp->v_rdev; 443 8348 Eric maj = getmajor(newdev); 444 8348 Eric ASSERT(STREAMSTAB(maj)); 445 8348 Eric 446 8348 Eric error = stropen(vp, &newdev, flags, cr); 447 8348 Eric 448 8348 Eric stp = vp->v_stream; 449 8348 Eric if (error == 0) { 450 8348 Eric if (so->so_flag & SOCLONE) 451 8348 Eric ASSERT(newdev != vp->v_rdev); 452 8348 Eric mutex_enter(&so->so_lock); 453 8348 Eric sti->sti_dev = newdev; 454 8348 Eric vp->v_rdev = newdev; 455 8348 Eric mutex_exit(&so->so_lock); 456 8348 Eric 457 8348 Eric if (stp->sd_flag & STRISTTY) { 458 8348 Eric /* 459 8348 Eric * this is a post SVR4 tty driver - a socket can not 460 8348 Eric * be a controlling terminal. Fail the open. 461 8348 Eric */ 462 8348 Eric (void) sotpi_close(so, flags, cr); 463 8348 Eric return (ENOTTY); /* XXX */ 464 8348 Eric } 465 8348 Eric 466 8348 Eric ASSERT(stp->sd_wrq != NULL); 467 8348 Eric sti->sti_provinfo = tpi_findprov(stp->sd_wrq); 468 8348 Eric 469 8348 Eric /* 470 8348 Eric * If caller is interested in doing direct function call 471 8348 Eric * interface to/from transport module, probe the module 472 8348 Eric * directly beneath the streamhead to see if it qualifies. 473 8348 Eric * 474 8348 Eric * We turn off the direct interface when qualifications fail. 475 8348 Eric * In the acceptor case, we simply turn off the sti_direct 476 8348 Eric * flag on the socket. We do the fallback after the accept 477 8348 Eric * has completed, before the new socket is returned to the 478 8348 Eric * application. 479 8348 Eric */ 480 8348 Eric if (sti->sti_direct) { 481 8348 Eric queue_t *tq = stp->sd_wrq->q_next; 482 8348 Eric 483 8348 Eric /* 484 8348 Eric * sti_direct is currently supported and tested 485 8348 Eric * only for tcp/udp; this is the main reason to 486 8348 Eric * have the following assertions. 487 8348 Eric */ 488 8348 Eric ASSERT(so->so_family == AF_INET || 489 8348 Eric so->so_family == AF_INET6); 490 8348 Eric ASSERT(so->so_protocol == IPPROTO_UDP || 491 8348 Eric so->so_protocol == IPPROTO_TCP || 492 8348 Eric so->so_protocol == IPPROTO_IP); 493 8348 Eric ASSERT(so->so_type == SOCK_DGRAM || 494 8348 Eric so->so_type == SOCK_STREAM); 495 8348 Eric 496 8348 Eric /* 497 8348 Eric * Abort direct call interface if the module directly 498 8348 Eric * underneath the stream head is not defined with the 499 8348 Eric * _D_DIRECT flag. This could happen in the tcp or 500 8348 Eric * udp case, when some other module is autopushed 501 8348 Eric * above it, or for some reasons the expected module 502 8348 Eric * isn't purely D_MP (which is the main requirement). 503 8348 Eric */ 504 8348 Eric if (!socktpi_direct || !(tq->q_flag & _QDIRECT) || 505 8348 Eric !(_OTHERQ(tq)->q_flag & _QDIRECT)) { 506 8348 Eric int rval; 507 8348 Eric 508 8348 Eric /* Continue on without direct calls */ 509 8348 Eric sti->sti_direct = 0; 510 8348 Eric 511 8348 Eric /* 512 8348 Eric * Cannot issue ioctl on fallback socket since 513 8348 Eric * there is no conn associated with the queue. 514 8348 Eric * The fallback downcall will notify the proto 515 8348 Eric * of the change. 516 8348 Eric */ 517 8348 Eric if (!(flags & SO_ACCEPTOR) && 518 8348 Eric !(flags & SO_FALLBACK)) { 519 8348 Eric if ((error = strioctl(vp, 520 8348 Eric _SIOCSOCKFALLBACK, 0, 0, K_TO_K, 521 8348 Eric cr, &rval)) != 0) { 522 8348 Eric (void) sotpi_close(so, flags, 523 8348 Eric cr); 524 8348 Eric return (error); 525 8348 Eric } 526 8348 Eric } 527 8348 Eric } 528 8348 Eric } 529 8348 Eric 530 8348 Eric if (flags & SO_FALLBACK) { 531 8348 Eric /* 532 8348 Eric * The stream created does not have a conn. 533 8348 Eric * do stream set up after conn has been assigned 534 8348 Eric */ 535 8348 Eric return (error); 536 8348 Eric } 537 8348 Eric if (error = so_strinit(so, tso)) { 538 8348 Eric (void) sotpi_close(so, flags, cr); 539 8348 Eric return (error); 540 8348 Eric } 541 8348 Eric 542 8348 Eric /* Wildcard */ 543 8348 Eric if (so->so_protocol != so->so_sockparams->sp_protocol) { 544 8348 Eric int protocol = so->so_protocol; 545 8348 Eric /* 546 8348 Eric * Issue SO_PROTOTYPE setsockopt. 547 8348 Eric */ 548 8348 Eric error = sotpi_setsockopt(so, SOL_SOCKET, SO_PROTOTYPE, 549 8348 Eric &protocol, (t_uscalar_t)sizeof (protocol), cr); 550 8348 Eric if (error != 0) { 551 8348 Eric (void) sotpi_close(so, flags, cr); 552 8348 Eric /* 553 8348 Eric * Setsockopt often fails with ENOPROTOOPT but 554 8348 Eric * socket() should fail with 555 8348 Eric * EPROTONOSUPPORT/EPROTOTYPE. 556 8348 Eric */ 557 8348 Eric return (EPROTONOSUPPORT); 558 8348 Eric } 559 8348 Eric } 560 8348 Eric 561 8348 Eric } else { 562 8348 Eric /* 563 8348 Eric * While the same socket can not be reopened (unlike specfs) 564 8348 Eric * the stream head sets STREOPENFAIL when the autopush fails. 565 8348 Eric */ 566 8348 Eric if ((stp != NULL) && 567 8348 Eric (stp->sd_flag & STREOPENFAIL)) { 568 8348 Eric /* 569 8348 Eric * Open failed part way through. 570 8348 Eric */ 571 8348 Eric mutex_enter(&stp->sd_lock); 572 8348 Eric stp->sd_flag &= ~STREOPENFAIL; 573 8348 Eric mutex_exit(&stp->sd_lock); 574 8348 Eric (void) sotpi_close(so, flags, cr); 575 8348 Eric return (error); 576 8348 Eric /*NOTREACHED*/ 577 8348 Eric } 578 8348 Eric ASSERT(stp == NULL); 579 8348 Eric } 580 8348 Eric TRACE_4(TR_FAC_SOCKFS, TR_SOCKFS_OPEN, 581 8348 Eric "sockfs open:maj %d vp %p so %p error %d", 582 8348 Eric maj, vp, so, error); 583 8348 Eric return (error); 584 0 stevel } 585 0 stevel 586 0 stevel /* 587 0 stevel * Bind the socket to an unspecified address in sockfs only. 588 0 stevel * Used for TCP/UDP transports where we know that the O_T_BIND_REQ isn't 589 0 stevel * required in all cases. 590 0 stevel */ 591 0 stevel static void 592 0 stevel so_automatic_bind(struct sonode *so) 593 0 stevel { 594 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 595 0 stevel ASSERT(so->so_family == AF_INET || so->so_family == AF_INET6); 596 0 stevel 597 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 598 0 stevel ASSERT(!(so->so_state & SS_ISBOUND)); 599 8348 Eric ASSERT(sti->sti_unbind_mp); 600 8348 Eric 601 8348 Eric ASSERT(sti->sti_laddr_len <= sti->sti_laddr_maxlen); 602 8348 Eric bzero(sti->sti_laddr_sa, sti->sti_laddr_len); 603 8348 Eric sti->sti_laddr_sa->sa_family = so->so_family; 604 0 stevel so->so_state |= SS_ISBOUND; 605 0 stevel } 606 0 stevel 607 0 stevel 608 0 stevel /* 609 0 stevel * bind the socket. 610 0 stevel * 611 0 stevel * If the socket is already bound and none of _SOBIND_SOCKBSD or _SOBIND_XPG4_2 612 0 stevel * are passed in we allow rebinding. Note that for backwards compatibility 613 0 stevel * even "svr4" sockets pass in _SOBIND_SOCKBSD/SOV_SOCKBSD to sobind/bind. 614 0 stevel * Thus the rebinding code is currently not executed. 615 0 stevel * 616 0 stevel * The constraints for rebinding are: 617 0 stevel * - it is a SOCK_DGRAM, or 618 0 stevel * - it is a SOCK_STREAM/SOCK_SEQPACKET that has not been connected 619 0 stevel * and no listen() has been done. 620 0 stevel * This rebinding code was added based on some language in the XNET book 621 0 stevel * about not returning EINVAL it the protocol allows rebinding. However, 622 0 stevel * this language is not present in the Posix socket draft. Thus maybe the 623 0 stevel * rebinding logic should be deleted from the source. 624 0 stevel * 625 0 stevel * A null "name" can be used to unbind the socket if: 626 0 stevel * - it is a SOCK_DGRAM, or 627 0 stevel * - it is a SOCK_STREAM/SOCK_SEQPACKET that has not been connected 628 0 stevel * and no listen() has been done. 629 0 stevel */ 630 8348 Eric /* ARGSUSED */ 631 0 stevel static int 632 0 stevel sotpi_bindlisten(struct sonode *so, struct sockaddr *name, 633 8348 Eric socklen_t namelen, int backlog, int flags, struct cred *cr) 634 0 stevel { 635 0 stevel struct T_bind_req bind_req; 636 0 stevel struct T_bind_ack *bind_ack; 637 0 stevel int error = 0; 638 0 stevel mblk_t *mp; 639 0 stevel void *addr; 640 0 stevel t_uscalar_t addrlen; 641 0 stevel int unbind_on_err = 1; 642 0 stevel boolean_t clear_acceptconn_on_err = B_FALSE; 643 0 stevel boolean_t restore_backlog_on_err = B_FALSE; 644 0 stevel int save_so_backlog; 645 0 stevel t_scalar_t PRIM_type = O_T_BIND_REQ; 646 0 stevel boolean_t tcp_udp_xport; 647 0 stevel void *nl7c = NULL; 648 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 649 0 stevel 650 0 stevel dprintso(so, 1, ("sotpi_bindlisten(%p, %p, %d, %d, 0x%x) %s\n", 651 7240 rh87107 (void *)so, (void *)name, namelen, backlog, flags, 652 5240 nordmark pr_state(so->so_state, so->so_mode))); 653 0 stevel 654 0 stevel tcp_udp_xport = so->so_type == SOCK_STREAM || so->so_type == SOCK_DGRAM; 655 0 stevel 656 0 stevel if (!(flags & _SOBIND_LOCK_HELD)) { 657 0 stevel mutex_enter(&so->so_lock); 658 0 stevel so_lock_single(so); /* Set SOLOCKED */ 659 0 stevel } else { 660 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 661 0 stevel ASSERT(so->so_flag & SOLOCKED); 662 0 stevel } 663 0 stevel 664 0 stevel /* 665 0 stevel * Make sure that there is a preallocated unbind_req message 666 0 stevel * before binding. This message allocated when the socket is 667 0 stevel * created but it might be have been consumed. 668 0 stevel */ 669 8348 Eric if (sti->sti_unbind_mp == NULL) { 670 0 stevel dprintso(so, 1, ("sobind: allocating unbind_req\n")); 671 0 stevel /* NOTE: holding so_lock while sleeping */ 672 8348 Eric sti->sti_unbind_mp = 673 8778 Erik soallocproto(sizeof (struct T_unbind_req), _ALLOC_SLEEP, 674 8778 Erik cr); 675 0 stevel } 676 0 stevel 677 0 stevel if (flags & _SOBIND_REBIND) { 678 0 stevel /* 679 0 stevel * Called from solisten after doing an sotpi_unbind() or 680 0 stevel * potentially without the unbind (latter for AF_INET{,6}). 681 0 stevel */ 682 0 stevel ASSERT(name == NULL && namelen == 0); 683 0 stevel 684 0 stevel if (so->so_family == AF_UNIX) { 685 8348 Eric ASSERT(sti->sti_ux_bound_vp); 686 8348 Eric addr = &sti->sti_ux_laddr; 687 8348 Eric addrlen = (t_uscalar_t)sizeof (sti->sti_ux_laddr); 688 5240 nordmark dprintso(so, 1, ("sobind rebind UNIX: addrlen %d, " 689 5240 nordmark "addr 0x%p, vp %p\n", 690 0 stevel addrlen, 691 7240 rh87107 (void *)((struct so_ux_addr *)addr)->soua_vp, 692 8348 Eric (void *)sti->sti_ux_bound_vp)); 693 8348 Eric } else { 694 8348 Eric addr = sti->sti_laddr_sa; 695 8348 Eric addrlen = (t_uscalar_t)sti->sti_laddr_len; 696 0 stevel } 697 0 stevel } else if (flags & _SOBIND_UNSPEC) { 698 0 stevel ASSERT(name == NULL && namelen == 0); 699 0 stevel 700 0 stevel /* 701 0 stevel * The caller checked SS_ISBOUND but not necessarily 702 0 stevel * under so_lock 703 0 stevel */ 704 0 stevel if (so->so_state & SS_ISBOUND) { 705 0 stevel /* No error */ 706 0 stevel goto done; 707 0 stevel } 708 0 stevel 709 0 stevel /* Set an initial local address */ 710 0 stevel switch (so->so_family) { 711 0 stevel case AF_UNIX: 712 0 stevel /* 713 0 stevel * Use an address with same size as struct sockaddr 714 0 stevel * just like BSD. 715 0 stevel */ 716 8348 Eric sti->sti_laddr_len = 717 5240 nordmark (socklen_t)sizeof (struct sockaddr); 718 8348 Eric ASSERT(sti->sti_laddr_len <= sti->sti_laddr_maxlen); 719 8348 Eric bzero(sti->sti_laddr_sa, sti->sti_laddr_len); 720 8348 Eric sti->sti_laddr_sa->sa_family = so->so_family; 721 0 stevel 722 0 stevel /* 723 0 stevel * Pass down an address with the implicit bind 724 0 stevel * magic number and the rest all zeros. 725 0 stevel * The transport will return a unique address. 726 0 stevel */ 727 8348 Eric sti->sti_ux_laddr.soua_vp = NULL; 728 8348 Eric sti->sti_ux_laddr.soua_magic = SOU_MAGIC_IMPLICIT; 729 8348 Eric addr = &sti->sti_ux_laddr; 730 8348 Eric addrlen = (t_uscalar_t)sizeof (sti->sti_ux_laddr); 731 0 stevel break; 732 0 stevel 733 0 stevel case AF_INET: 734 0 stevel case AF_INET6: 735 0 stevel /* 736 0 stevel * An unspecified bind in TPI has a NULL address. 737 0 stevel * Set the address in sockfs to have the sa_family. 738 0 stevel */ 739 8348 Eric sti->sti_laddr_len = (so->so_family == AF_INET) ? 740 0 stevel (socklen_t)sizeof (sin_t) : 741 0 stevel (socklen_t)sizeof (sin6_t); 742 8348 Eric ASSERT(sti->sti_laddr_len <= sti->sti_laddr_maxlen); 743 8348 Eric bzero(sti->sti_laddr_sa, sti->sti_laddr_len); 744 8348 Eric sti->sti_laddr_sa->sa_family = so->so_family; 745 0 stevel addr = NULL; 746 0 stevel addrlen = 0; 747 0 stevel break; 748 0 stevel 749 0 stevel default: 750 0 stevel /* 751 0 stevel * An unspecified bind in TPI has a NULL address. 752 0 stevel * Set the address in sockfs to be zero length. 753 0 stevel * 754 0 stevel * Can not assume there is a sa_family for all 755 0 stevel * protocol families. For example, AF_X25 does not 756 0 stevel * have a family field. 757 0 stevel */ 758 8348 Eric bzero(sti->sti_laddr_sa, sti->sti_laddr_len); 759 8348 Eric sti->sti_laddr_len = 0; /* XXX correct? */ 760 0 stevel addr = NULL; 761 0 stevel addrlen = 0; 762 0 stevel break; 763 0 stevel } 764 0 stevel 765 0 stevel } else { 766 0 stevel if (so->so_state & SS_ISBOUND) { 767 0 stevel /* 768 0 stevel * If it is ok to rebind the socket, first unbind 769 0 stevel * with the transport. A rebind to the NULL address 770 0 stevel * is interpreted as an unbind. 771 0 stevel * Note that a bind to NULL in BSD does unbind the 772 0 stevel * socket but it fails with EINVAL. 773 0 stevel * Note that regular sockets set SOV_SOCKBSD i.e. 774 0 stevel * _SOBIND_SOCKBSD gets set here hence no type of 775 0 stevel * socket does currently allow rebinding. 776 0 stevel * 777 0 stevel * If the name is NULL just do an unbind. 778 0 stevel */ 779 0 stevel if (flags & (_SOBIND_SOCKBSD|_SOBIND_XPG4_2) && 780 0 stevel name != NULL) { 781 0 stevel error = EINVAL; 782 0 stevel unbind_on_err = 0; 783 0 stevel eprintsoline(so, error); 784 0 stevel goto done; 785 0 stevel } 786 0 stevel if ((so->so_mode & SM_CONNREQUIRED) && 787 0 stevel (so->so_state & SS_CANTREBIND)) { 788 0 stevel error = EINVAL; 789 0 stevel unbind_on_err = 0; 790 0 stevel eprintsoline(so, error); 791 0 stevel goto done; 792 0 stevel } 793 0 stevel error = sotpi_unbind(so, 0); 794 0 stevel if (error) { 795 0 stevel eprintsoline(so, error); 796 0 stevel goto done; 797 0 stevel } 798 0 stevel ASSERT(!(so->so_state & SS_ISBOUND)); 799 0 stevel if (name == NULL) { 800 0 stevel so->so_state &= 801 5240 nordmark ~(SS_ISCONNECTED|SS_ISCONNECTING); 802 0 stevel goto done; 803 0 stevel } 804 0 stevel } 805 8348 Eric 806 0 stevel /* X/Open requires this check */ 807 0 stevel if ((so->so_state & SS_CANTSENDMORE) && !xnet_skip_checks) { 808 0 stevel if (xnet_check_print) { 809 0 stevel printf("sockfs: X/Open bind state check " 810 0 stevel "caused EINVAL\n"); 811 0 stevel } 812 0 stevel error = EINVAL; 813 0 stevel goto done; 814 0 stevel } 815 0 stevel 816 0 stevel switch (so->so_family) { 817 0 stevel case AF_UNIX: 818 0 stevel /* 819 0 stevel * All AF_UNIX addresses are nul terminated 820 0 stevel * when copied (copyin_name) in so the minimum 821 0 stevel * length is 3 bytes. 822 0 stevel */ 823 0 stevel if (name == NULL || 824 0 stevel (ssize_t)namelen <= sizeof (short) + 1) { 825 0 stevel error = EISDIR; 826 0 stevel eprintsoline(so, error); 827 0 stevel goto done; 828 0 stevel } 829 0 stevel /* 830 0 stevel * Verify so_family matches the bound family. 831 0 stevel * BSD does not check this for AF_UNIX resulting 832 0 stevel * in funny mknods. 833 0 stevel */ 834 0 stevel if (name->sa_family != so->so_family) { 835 0 stevel error = EAFNOSUPPORT; 836 0 stevel goto done; 837 0 stevel } 838 0 stevel break; 839 0 stevel case AF_INET: 840 0 stevel if (name == NULL) { 841 0 stevel error = EINVAL; 842 0 stevel eprintsoline(so, error); 843 0 stevel goto done; 844 0 stevel } 845 0 stevel if ((size_t)namelen != sizeof (sin_t)) { 846 0 stevel error = name->sa_family != so->so_family ? 847 0 stevel EAFNOSUPPORT : EINVAL; 848 0 stevel eprintsoline(so, error); 849 0 stevel goto done; 850 0 stevel } 851 0 stevel if ((flags & _SOBIND_XPG4_2) && 852 0 stevel (name->sa_family != so->so_family)) { 853 0 stevel /* 854 0 stevel * This check has to be made for X/Open 855 0 stevel * sockets however application failures have 856 0 stevel * been observed when it is applied to 857 0 stevel * all sockets. 858 0 stevel */ 859 0 stevel error = EAFNOSUPPORT; 860 0 stevel eprintsoline(so, error); 861 0 stevel goto done; 862 0 stevel } 863 0 stevel /* 864 0 stevel * Force a zero sa_family to match so_family. 865 0 stevel * 866 0 stevel * Some programs like inetd(1M) don't set the 867 0 stevel * family field. Other programs leave 868 0 stevel * sin_family set to garbage - SunOS 4.X does 869 0 stevel * not check the family field on a bind. 870 0 stevel * We use the family field that 871 0 stevel * was passed in to the socket() call. 872 0 stevel */ 873 0 stevel name->sa_family = so->so_family; 874 0 stevel break; 875 0 stevel 876 0 stevel case AF_INET6: { 877 0 stevel #ifdef DEBUG 878 0 stevel sin6_t *sin6 = (sin6_t *)name; 879 0 stevel #endif /* DEBUG */ 880 0 stevel 881 0 stevel if (name == NULL) { 882 0 stevel error = EINVAL; 883 0 stevel eprintsoline(so, error); 884 0 stevel goto done; 885 0 stevel } 886 0 stevel if ((size_t)namelen != sizeof (sin6_t)) { 887 0 stevel error = name->sa_family != so->so_family ? 888 0 stevel EAFNOSUPPORT : EINVAL; 889 0 stevel eprintsoline(so, error); 890 0 stevel goto done; 891 0 stevel } 892 0 stevel if (name->sa_family != so->so_family) { 893 0 stevel /* 894 0 stevel * With IPv6 we require the family to match 895 0 stevel * unlike in IPv4. 896 0 stevel */ 897 0 stevel error = EAFNOSUPPORT; 898 0 stevel eprintsoline(so, error); 899 0 stevel goto done; 900 0 stevel } 901 0 stevel #ifdef DEBUG 902 0 stevel /* 903 0 stevel * Verify that apps don't forget to clear 904 0 stevel * sin6_scope_id etc 905 0 stevel */ 906 0 stevel if (sin6->sin6_scope_id != 0 && 907 0 stevel !IN6_IS_ADDR_LINKSCOPE(&sin6->sin6_addr)) { 908 1548 rshoaib zcmn_err(getzoneid(), CE_WARN, 909 0 stevel "bind with uninitialized sin6_scope_id " 910 0 stevel "(%d) on socket. Pid = %d\n", 911 0 stevel (int)sin6->sin6_scope_id, 912 0 stevel (int)curproc->p_pid); 913 0 stevel } 914 0 stevel if (sin6->__sin6_src_id != 0) { 915 1548 rshoaib zcmn_err(getzoneid(), CE_WARN, 916 0 stevel "bind with uninitialized __sin6_src_id " 917 0 stevel "(%d) on socket. Pid = %d\n", 918 0 stevel (int)sin6->__sin6_src_id, 919 0 stevel (int)curproc->p_pid); 920 0 stevel } 921 0 stevel #endif /* DEBUG */ 922 0 stevel break; 923 0 stevel } 924 0 stevel default: 925 0 stevel /* 926 0 stevel * Don't do any length or sa_family check to allow 927 0 stevel * non-sockaddr style addresses. 928 0 stevel */ 929 0 stevel if (name == NULL) { 930 0 stevel error = EINVAL; 931 0 stevel eprintsoline(so, error); 932 0 stevel goto done; 933 0 stevel } 934 0 stevel break; 935 0 stevel } 936 0 stevel 937 8348 Eric if (namelen > (t_uscalar_t)sti->sti_laddr_maxlen) { 938 0 stevel error = ENAMETOOLONG; 939 0 stevel eprintsoline(so, error); 940 0 stevel goto done; 941 0 stevel } 942 0 stevel /* 943 0 stevel * Save local address. 944 0 stevel */ 945 8348 Eric sti->sti_laddr_len = (socklen_t)namelen; 946 8348 Eric ASSERT(sti->sti_laddr_len <= sti->sti_laddr_maxlen); 947 8348 Eric bcopy(name, sti->sti_laddr_sa, namelen); 948 8348 Eric 949 8348 Eric addr = sti->sti_laddr_sa; 950 8348 Eric addrlen = (t_uscalar_t)sti->sti_laddr_len; 951 0 stevel switch (so->so_family) { 952 0 stevel case AF_INET6: 953 0 stevel case AF_INET: 954 0 stevel break; 955 0 stevel case AF_UNIX: { 956 0 stevel struct sockaddr_un *soun = 957 8348 Eric (struct sockaddr_un *)sti->sti_laddr_sa; 958 8032 Ric struct vnode *vp, *rvp; 959 0 stevel struct vattr vattr; 960 0 stevel 961 8348 Eric ASSERT(sti->sti_ux_bound_vp == NULL); 962 0 stevel /* 963 0 stevel * Create vnode for the specified path name. 964 8348 Eric * Keep vnode held with a reference in sti_ux_bound_vp. 965 0 stevel * Use the vnode pointer as the address used in the 966 0 stevel * bind with the transport. 967 0 stevel * 968 0 stevel * Use the same mode as in BSD. In particular this does 969 0 stevel * not observe the umask. 970 0 stevel */ 971 0 stevel /* MAXPATHLEN + soun_family + nul termination */ 972 8348 Eric if (sti->sti_laddr_len > 973 0 stevel (socklen_t)(MAXPATHLEN + sizeof (short) + 1)) { 974 0 stevel error = ENAMETOOLONG; 975 0 stevel eprintsoline(so, error); 976 0 stevel goto done; 977 0 stevel } 978 0 stevel vattr.va_type = VSOCK; 979 3446 mrj vattr.va_mode = 0777 & ~PTOU(curproc)->u_cmask; 980 0 stevel vattr.va_mask = AT_TYPE|AT_MODE; 981 0 stevel /* NOTE: holding so_lock */ 982 0 stevel error = vn_create(soun->sun_path, UIO_SYSSPACE, &vattr, 983 5240 nordmark EXCL, 0, &vp, CRMKNOD, 0, 0); 984 0 stevel if (error) { 985 0 stevel if (error == EEXIST) 986 0 stevel error = EADDRINUSE; 987 0 stevel eprintsoline(so, error); 988 0 stevel goto done; 989 0 stevel } 990 0 stevel /* 991 0 stevel * Establish pointer from the underlying filesystem 992 0 stevel * vnode to the socket node. 993 8348 Eric * sti_ux_bound_vp and v_stream->sd_vnode form the 994 0 stevel * cross-linkage between the underlying filesystem 995 0 stevel * node and the socket node. 996 0 stevel */ 997 8032 Ric 998 8032 Ric if ((VOP_REALVP(vp, &rvp, NULL) == 0) && (vp != rvp)) { 999 8032 Ric VN_HOLD(rvp); 1000 8032 Ric VN_RELE(vp); 1001 8032 Ric vp = rvp; 1002 8032 Ric } 1003 8032 Ric 1004 0 stevel ASSERT(SOTOV(so)->v_stream); 1005 0 stevel mutex_enter(&vp->v_lock); 1006 0 stevel vp->v_stream = SOTOV(so)->v_stream; 1007 8348 Eric sti->sti_ux_bound_vp = vp; 1008 0 stevel mutex_exit(&vp->v_lock); 1009 0 stevel 1010 0 stevel /* 1011 0 stevel * Use the vnode pointer value as a unique address 1012 0 stevel * (together with the magic number to avoid conflicts 1013 0 stevel * with implicit binds) in the transport provider. 1014 0 stevel */ 1015 8348 Eric sti->sti_ux_laddr.soua_vp = 1016 8348 Eric (void *)sti->sti_ux_bound_vp; 1017 8348 Eric sti->sti_ux_laddr.soua_magic = SOU_MAGIC_EXPLICIT; 1018 8348 Eric addr = &sti->sti_ux_laddr; 1019 8348 Eric addrlen = (t_uscalar_t)sizeof (sti->sti_ux_laddr); 1020 0 stevel dprintso(so, 1, ("sobind UNIX: addrlen %d, addr %p\n", 1021 0 stevel addrlen, 1022 8348 Eric (void *)((struct so_ux_addr *)addr)->soua_vp)); 1023 0 stevel break; 1024 0 stevel } 1025 0 stevel } /* end switch (so->so_family) */ 1026 0 stevel } 1027 0 stevel 1028 0 stevel /* 1029 0 stevel * set SS_ACCEPTCONN before sending down O_T_BIND_REQ since 1030 0 stevel * the transport can start passing up T_CONN_IND messages 1031 0 stevel * as soon as it receives the bind req and strsock_proto() 1032 0 stevel * insists that SS_ACCEPTCONN is set when processing T_CONN_INDs. 1033 0 stevel */ 1034 0 stevel if (flags & _SOBIND_LISTEN) { 1035 0 stevel if ((so->so_state & SS_ACCEPTCONN) == 0) 1036 0 stevel clear_acceptconn_on_err = B_TRUE; 1037 0 stevel save_so_backlog = so->so_backlog; 1038 0 stevel restore_backlog_on_err = B_TRUE; 1039 0 stevel so->so_state |= SS_ACCEPTCONN; 1040 0 stevel so->so_backlog = backlog; 1041 0 stevel } 1042 0 stevel 1043 0 stevel /* 1044 0 stevel * If NL7C addr(s) have been configured check for addr/port match, 1045 0 stevel * or if an implicit NL7C socket via AF_NCA mark socket as NL7C. 1046 0 stevel * 1047 0 stevel * NL7C supports the TCP transport only so check AF_INET and AF_INET6 1048 0 stevel * family sockets only. If match mark as such. 1049 0 stevel */ 1050 1974 brutus if (nl7c_enabled && ((addr != NULL && 1051 0 stevel (so->so_family == AF_INET || so->so_family == AF_INET6) && 1052 0 stevel (nl7c = nl7c_lookup_addr(addr, addrlen))) || 1053 8348 Eric sti->sti_nl7c_flags == NL7C_AF_NCA)) { 1054 0 stevel /* 1055 0 stevel * NL7C is not supported in non-global zones, 1056 0 stevel * we enforce this restriction here. 1057 0 stevel */ 1058 0 stevel if (so->so_zoneid == GLOBAL_ZONEID) { 1059 0 stevel /* An NL7C socket, mark it */ 1060 8348 Eric sti->sti_nl7c_flags |= NL7C_ENABLED; 1061 1974 brutus if (nl7c == NULL) { 1062 1974 brutus /* 1063 1974 brutus * Was an AF_NCA bind() so add it to the 1064 1974 brutus * addr list for reporting purposes. 1065 1974 brutus */ 1066 1974 brutus nl7c = nl7c_add_addr(addr, addrlen); 1067 1974 brutus } 1068 0 stevel } else 1069 0 stevel nl7c = NULL; 1070 0 stevel } 1071 8348 Eric 1072 0 stevel /* 1073 0 stevel * We send a T_BIND_REQ for TCP/UDP since we know it supports it, 1074 0 stevel * for other transports we will send in a O_T_BIND_REQ. 1075 0 stevel */ 1076 0 stevel if (tcp_udp_xport && 1077 0 stevel (so->so_family == AF_INET || so->so_family == AF_INET6)) 1078 0 stevel PRIM_type = T_BIND_REQ; 1079 0 stevel 1080 0 stevel bind_req.PRIM_type = PRIM_type; 1081 0 stevel bind_req.ADDR_length = addrlen; 1082 0 stevel bind_req.ADDR_offset = (t_scalar_t)sizeof (bind_req); 1083 0 stevel bind_req.CONIND_number = backlog; 1084 0 stevel /* NOTE: holding so_lock while sleeping */ 1085 0 stevel mp = soallocproto2(&bind_req, sizeof (bind_req), 1086 8778 Erik addr, addrlen, 0, _ALLOC_SLEEP, cr); 1087 8348 Eric sti->sti_laddr_valid = 0; 1088 8348 Eric 1089 8348 Eric /* Done using sti_laddr_sa - can drop the lock */ 1090 0 stevel mutex_exit(&so->so_lock); 1091 898 kais 1092 898 kais /* 1093 898 kais * Intercept the bind_req message here to check if this <address/port> 1094 898 kais * was configured as an SSL proxy server, or if another endpoint was 1095 898 kais * already configured to act as a proxy for us. 1096 1974 brutus * 1097 1974 brutus * Note, only if NL7C not enabled for this socket. 1098 1974 brutus */ 1099 1974 brutus if (nl7c == NULL && 1100 1974 brutus (so->so_family == AF_INET || so->so_family == AF_INET6) && 1101 898 kais so->so_type == SOCK_STREAM) { 1102 898 kais 1103 8348 Eric if (sti->sti_kssl_ent != NULL) { 1104 8348 Eric kssl_release_ent(sti->sti_kssl_ent, so, 1105 8348 Eric sti->sti_kssl_type); 1106 8348 Eric sti->sti_kssl_ent = NULL; 1107 8348 Eric } 1108 8348 Eric 1109 8348 Eric sti->sti_kssl_type = kssl_check_proxy(mp, so, 1110 8348 Eric &sti->sti_kssl_ent); 1111 8348 Eric switch (sti->sti_kssl_type) { 1112 898 kais case KSSL_NO_PROXY: 1113 898 kais break; 1114 898 kais 1115 898 kais case KSSL_HAS_PROXY: 1116 898 kais mutex_enter(&so->so_lock); 1117 898 kais goto skip_transport; 1118 898 kais 1119 898 kais case KSSL_IS_PROXY: 1120 898 kais break; 1121 898 kais } 1122 898 kais } 1123 0 stevel 1124 0 stevel error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0, 1125 5240 nordmark MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0); 1126 0 stevel if (error) { 1127 0 stevel eprintsoline(so, error); 1128 0 stevel mutex_enter(&so->so_lock); 1129 0 stevel goto done; 1130 0 stevel } 1131 0 stevel 1132 0 stevel mutex_enter(&so->so_lock); 1133 0 stevel error = sowaitprim(so, PRIM_type, T_BIND_ACK, 1134 0 stevel (t_uscalar_t)sizeof (*bind_ack), &mp, 0); 1135 0 stevel if (error) { 1136 0 stevel eprintsoline(so, error); 1137 0 stevel goto done; 1138 0 stevel } 1139 898 kais skip_transport: 1140 0 stevel ASSERT(mp); 1141 0 stevel /* 1142 0 stevel * Even if some TPI message (e.g. T_DISCON_IND) was received in 1143 0 stevel * strsock_proto while the lock was dropped above, the bind 1144 0 stevel * is allowed to complete. 1145 0 stevel */ 1146 0 stevel 1147 0 stevel /* Mark as bound. This will be undone if we detect errors below. */ 1148 0 stevel if (flags & _SOBIND_NOXLATE) { 1149 0 stevel ASSERT(so->so_family == AF_UNIX); 1150 8348 Eric sti->sti_faddr_noxlate = 1; 1151 0 stevel } 1152 0 stevel ASSERT(!(so->so_state & SS_ISBOUND) || (flags & _SOBIND_REBIND)); 1153 0 stevel so->so_state |= SS_ISBOUND; 1154 8348 Eric ASSERT(sti->sti_unbind_mp); 1155 0 stevel 1156 0 stevel /* note that we've already set SS_ACCEPTCONN above */ 1157 0 stevel 1158 0 stevel /* 1159 0 stevel * Recompute addrlen - an unspecied bind sent down an 1160 0 stevel * address of length zero but we expect the appropriate length 1161 0 stevel * in return. 1162 0 stevel */ 1163 0 stevel addrlen = (t_uscalar_t)(so->so_family == AF_UNIX ? 1164 8348 Eric sizeof (sti->sti_ux_laddr) : sti->sti_laddr_len); 1165 0 stevel 1166 0 stevel bind_ack = (struct T_bind_ack *)mp->b_rptr; 1167 0 stevel /* 1168 0 stevel * The alignment restriction is really too strict but 1169 0 stevel * we want enough alignment to inspect the fields of 1170 0 stevel * a sockaddr_in. 1171 0 stevel */ 1172 0 stevel addr = sogetoff(mp, bind_ack->ADDR_offset, 1173 5240 nordmark bind_ack->ADDR_length, 1174 5240 nordmark __TPI_ALIGN_SIZE); 1175 0 stevel if (addr == NULL) { 1176 0 stevel freemsg(mp); 1177 0 stevel error = EPROTO; 1178 0 stevel eprintsoline(so, error); 1179 0 stevel goto done; 1180 0 stevel } 1181 0 stevel if (!(flags & _SOBIND_UNSPEC)) { 1182 0 stevel /* 1183 0 stevel * Verify that the transport didn't return something we 1184 0 stevel * did not want e.g. an address other than what we asked for. 1185 0 stevel * 1186 0 stevel * NOTE: These checks would go away if/when we switch to 1187 0 stevel * using the new TPI (in which the transport would fail 1188 0 stevel * the request instead of assigning a different address). 1189 0 stevel * 1190 0 stevel * NOTE2: For protocols that we don't know (i.e. any 1191 0 stevel * other than AF_INET6, AF_INET and AF_UNIX), we 1192 0 stevel * cannot know if the transport should be expected to 1193 0 stevel * return the same address as that requested. 1194 0 stevel * 1195 0 stevel * NOTE3: For AF_INET and AF_INET6, TCP/UDP, we send 1196 0 stevel * down a T_BIND_REQ. We use O_T_BIND_REQ for others. 1197 0 stevel * 1198 0 stevel * For example, in the case of netatalk it may be 1199 0 stevel * inappropriate for the transport to return the 1200 0 stevel * requested address (as it may have allocated a local 1201 0 stevel * port number in behaviour similar to that of an 1202 0 stevel * AF_INET bind request with a port number of zero). 1203 0 stevel * 1204 0 stevel * Given the definition of O_T_BIND_REQ, where the 1205 0 stevel * transport may bind to an address other than the 1206 0 stevel * requested address, it's not possible to determine 1207 0 stevel * whether a returned address that differs from the 1208 0 stevel * requested address is a reason to fail (because the 1209 0 stevel * requested address was not available) or succeed 1210 0 stevel * (because the transport allocated an appropriate 1211 0 stevel * address and/or port). 1212 0 stevel * 1213 0 stevel * sockfs currently requires that the transport return 1214 0 stevel * the requested address in the T_BIND_ACK, unless 1215 0 stevel * there is code here to allow for any discrepancy. 1216 0 stevel * Such code exists for AF_INET and AF_INET6. 1217 0 stevel * 1218 0 stevel * Netatalk chooses to return the requested address 1219 0 stevel * rather than the (correct) allocated address. This 1220 0 stevel * means that netatalk violates the TPI specification 1221 0 stevel * (and would not function correctly if used from a 1222 0 stevel * TLI application), but it does mean that it works 1223 0 stevel * with sockfs. 1224 0 stevel * 1225 0 stevel * As noted above, using the newer XTI bind primitive 1226 0 stevel * (T_BIND_REQ) in preference to O_T_BIND_REQ would 1227 0 stevel * allow sockfs to be more sure about whether or not 1228 0 stevel * the bind request had succeeded (as transports are 1229 0 stevel * not permitted to bind to a different address than 1230 0 stevel * that requested - they must return failure). 1231 0 stevel * Unfortunately, support for T_BIND_REQ may not be 1232 0 stevel * present in all transport implementations (netatalk, 1233 0 stevel * for example, doesn't have it), making the 1234 0 stevel * transition difficult. 1235 0 stevel */ 1236 0 stevel if (bind_ack->ADDR_length != addrlen) { 1237 0 stevel /* Assumes that the requested address was in use */ 1238 0 stevel freemsg(mp); 1239 0 stevel error = EADDRINUSE; 1240 0 stevel eprintsoline(so, error); 1241 0 stevel goto done; 1242 0 stevel } 1243 0 stevel 1244 0 stevel switch (so->so_family) { 1245 0 stevel case AF_INET6: 1246 0 stevel case AF_INET: { 1247 0 stevel sin_t *rname, *aname; 1248 0 stevel 1249 0 stevel rname = (sin_t *)addr; 1250 8348 Eric aname = (sin_t *)sti->sti_laddr_sa; 1251 0 stevel 1252 0 stevel /* 1253 0 stevel * Take advantage of the alignment 1254 0 stevel * of sin_port and sin6_port which fall 1255 0 stevel * in the same place in their data structures. 1256 0 stevel * Just use sin_port for either address family. 1257 0 stevel * 1258 0 stevel * This may become a problem if (heaven forbid) 1259 0 stevel * there's a separate ipv6port_reserved... :-P 1260 0 stevel * 1261 0 stevel * Binding to port 0 has the semantics of letting 1262 0 stevel * the transport bind to any port. 1263 0 stevel * 1264 0 stevel * If the transport is TCP or UDP since we had sent 1265 0 stevel * a T_BIND_REQ we would not get a port other than 1266 0 stevel * what we asked for. 1267 0 stevel */ 1268 0 stevel if (tcp_udp_xport) { 1269 0 stevel /* 1270 0 stevel * Pick up the new port number if we bound to 1271 0 stevel * port 0. 1272 0 stevel */ 1273 0 stevel if (aname->sin_port == 0) 1274 0 stevel aname->sin_port = rname->sin_port; 1275 8348 Eric sti->sti_laddr_valid = 1; 1276 0 stevel break; 1277 0 stevel } 1278 0 stevel if (aname->sin_port != 0 && 1279 0 stevel aname->sin_port != rname->sin_port) { 1280 0 stevel freemsg(mp); 1281 0 stevel error = EADDRINUSE; 1282 0 stevel eprintsoline(so, error); 1283 0 stevel goto done; 1284 0 stevel } 1285 0 stevel /* 1286 0 stevel * Pick up the new port number if we bound to port 0. 1287 0 stevel */ 1288 0 stevel aname->sin_port = rname->sin_port; 1289 0 stevel 1290 0 stevel /* 1291 0 stevel * Unfortunately, addresses aren't _quite_ the same. 1292 0 stevel */ 1293 0 stevel if (so->so_family == AF_INET) { 1294 0 stevel if (aname->sin_addr.s_addr != 1295 0 stevel rname->sin_addr.s_addr) { 1296 0 stevel freemsg(mp); 1297 0 stevel error = EADDRNOTAVAIL; 1298 0 stevel eprintsoline(so, error); 1299 0 stevel goto done; 1300 0 stevel } 1301 0 stevel } else { 1302 0 stevel sin6_t *rname6 = (sin6_t *)rname; 1303 0 stevel sin6_t *aname6 = (sin6_t *)aname; 1304 0 stevel 1305 0 stevel if (!IN6_ARE_ADDR_EQUAL(&aname6->sin6_addr, 1306 0 stevel &rname6->sin6_addr)) { 1307 0 stevel freemsg(mp); 1308 0 stevel error = EADDRNOTAVAIL; 1309 0 stevel eprintsoline(so, error); 1310 0 stevel goto done; 1311 0 stevel } 1312 0 stevel } 1313 0 stevel break; 1314 0 stevel } 1315 0 stevel case AF_UNIX: 1316 8348 Eric if (bcmp(addr, &sti->sti_ux_laddr, addrlen) != 0) { 1317 0 stevel freemsg(mp); 1318 0 stevel error = EADDRINUSE; 1319 0 stevel eprintsoline(so, error); 1320 0 stevel eprintso(so, 1321 5240 nordmark ("addrlen %d, addr 0x%x, vp %p\n", 1322 5240 nordmark addrlen, *((int *)addr), 1323 8348 Eric (void *)sti->sti_ux_bound_vp)); 1324 8348 Eric goto done; 1325 8348 Eric } 1326 8348 Eric sti->sti_laddr_valid = 1; 1327 0 stevel break; 1328 0 stevel default: 1329 0 stevel /* 1330 0 stevel * NOTE: This assumes that addresses can be 1331 0 stevel * byte-compared for equivalence. 1332 0 stevel */ 1333 8348 Eric if (bcmp(addr, sti->sti_laddr_sa, addrlen) != 0) { 1334 0 stevel freemsg(mp); 1335 0 stevel error = EADDRINUSE; 1336 0 stevel eprintsoline(so, error); 1337 0 stevel goto done; 1338 0 stevel } 1339 0 stevel /* 1340 8348 Eric * Don't mark sti_laddr_valid, as we cannot be 1341 0 stevel * sure that the returned address is the real 1342 0 stevel * bound address when talking to an unknown 1343 0 stevel * transport. 1344 0 stevel */ 1345 0 stevel break; 1346 0 stevel } 1347 0 stevel } else { 1348 0 stevel /* 1349 0 stevel * Save for returned address for getsockname. 1350 0 stevel * Needed for unspecific bind unless transport supports 1351 0 stevel * the TI_GETMYNAME ioctl. 1352 0 stevel * Do this for AF_INET{,6} even though they do, as 1353 0 stevel * caching info here is much better performance than 1354 0 stevel * a TPI/STREAMS trip to the transport for getsockname. 1355 0 stevel * Any which can't for some reason _must_ _not_ set 1356 8348 Eric * sti_laddr_valid here for the caching version of 1357 8348 Eric * getsockname to not break; 1358 0 stevel */ 1359 0 stevel switch (so->so_family) { 1360 0 stevel case AF_UNIX: 1361 0 stevel /* 1362 0 stevel * Record the address bound with the transport 1363 0 stevel * for use by socketpair. 1364 0 stevel */ 1365 8348 Eric bcopy(addr, &sti->sti_ux_laddr, addrlen); 1366 8348 Eric sti->sti_laddr_valid = 1; 1367 0 stevel break; 1368 0 stevel case AF_INET: 1369 0 stevel case AF_INET6: 1370 8348 Eric ASSERT(sti->sti_laddr_len <= sti->sti_laddr_maxlen); 1371 8348 Eric bcopy(addr, sti->sti_laddr_sa, sti->sti_laddr_len); 1372 8348 Eric sti->sti_laddr_valid = 1; 1373 0 stevel break; 1374 0 stevel default: 1375 0 stevel /* 1376 8348 Eric * Don't mark sti_laddr_valid, as we cannot be 1377 0 stevel * sure that the returned address is the real 1378 0 stevel * bound address when talking to an unknown 1379 0 stevel * transport. 1380 0 stevel */ 1381 0 stevel break; 1382 0 stevel } 1383 0 stevel } 1384 0 stevel 1385 0 stevel if (nl7c != NULL) { 1386 1974 brutus /* Register listen()er sonode pointer with NL7C */ 1387 1974 brutus nl7c_listener_addr(nl7c, so); 1388 0 stevel } 1389 0 stevel 1390 0 stevel freemsg(mp); 1391 0 stevel 1392 0 stevel done: 1393 0 stevel if (error) { 1394 0 stevel /* reset state & backlog to values held on entry */ 1395 0 stevel if (clear_acceptconn_on_err == B_TRUE) 1396 0 stevel so->so_state &= ~SS_ACCEPTCONN; 1397 0 stevel if (restore_backlog_on_err == B_TRUE) 1398 0 stevel so->so_backlog = save_so_backlog; 1399 0 stevel 1400 0 stevel if (unbind_on_err && so->so_state & SS_ISBOUND) { 1401 0 stevel int err; 1402 0 stevel 1403 0 stevel err = sotpi_unbind(so, 0); 1404 0 stevel /* LINTED - statement has no consequent: if */ 1405 0 stevel if (err) { 1406 0 stevel eprintsoline(so, error); 1407 0 stevel } else { 1408 0 stevel ASSERT(!(so->so_state & SS_ISBOUND)); 1409 0 stevel } 1410 0 stevel } 1411 0 stevel } 1412 0 stevel if (!(flags & _SOBIND_LOCK_HELD)) { 1413 0 stevel so_unlock_single(so, SOLOCKED); 1414 0 stevel mutex_exit(&so->so_lock); 1415 0 stevel } else { 1416 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 1417 0 stevel ASSERT(so->so_flag & SOLOCKED); 1418 0 stevel } 1419 0 stevel return (error); 1420 0 stevel } 1421 0 stevel 1422 0 stevel /* bind the socket */ 1423 741 masputra static int 1424 0 stevel sotpi_bind(struct sonode *so, struct sockaddr *name, socklen_t namelen, 1425 8348 Eric int flags, struct cred *cr) 1426 0 stevel { 1427 0 stevel if ((flags & _SOBIND_SOCKETPAIR) == 0) 1428 8348 Eric return (sotpi_bindlisten(so, name, namelen, 0, flags, cr)); 1429 0 stevel 1430 0 stevel flags &= ~_SOBIND_SOCKETPAIR; 1431 8348 Eric return (sotpi_bindlisten(so, name, namelen, 1, flags, cr)); 1432 0 stevel } 1433 0 stevel 1434 0 stevel /* 1435 0 stevel * Unbind a socket - used when bind() fails, when bind() specifies a NULL 1436 0 stevel * address, or when listen needs to unbind and bind. 1437 0 stevel * If the _SOUNBIND_REBIND flag is specified the addresses are retained 1438 0 stevel * so that a sobind can pick them up. 1439 0 stevel */ 1440 0 stevel static int 1441 0 stevel sotpi_unbind(struct sonode *so, int flags) 1442 0 stevel { 1443 0 stevel struct T_unbind_req unbind_req; 1444 0 stevel int error = 0; 1445 0 stevel mblk_t *mp; 1446 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 1447 0 stevel 1448 0 stevel dprintso(so, 1, ("sotpi_unbind(%p, 0x%x) %s\n", 1449 7240 rh87107 (void *)so, flags, pr_state(so->so_state, so->so_mode))); 1450 0 stevel 1451 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 1452 0 stevel ASSERT(so->so_flag & SOLOCKED); 1453 0 stevel 1454 0 stevel if (!(so->so_state & SS_ISBOUND)) { 1455 0 stevel error = EINVAL; 1456 0 stevel eprintsoline(so, error); 1457 0 stevel goto done; 1458 0 stevel } 1459 0 stevel 1460 0 stevel mutex_exit(&so->so_lock); 1461 0 stevel 1462 0 stevel /* 1463 0 stevel * Flush the read and write side (except stream head read queue) 1464 0 stevel * and send down T_UNBIND_REQ. 1465 0 stevel */ 1466 0 stevel (void) putnextctl1(strvp2wq(SOTOV(so)), M_FLUSH, FLUSHRW); 1467 0 stevel 1468 0 stevel unbind_req.PRIM_type = T_UNBIND_REQ; 1469 0 stevel mp = soallocproto1(&unbind_req, sizeof (unbind_req), 1470 8778 Erik 0, _ALLOC_SLEEP, CRED()); 1471 0 stevel error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0, 1472 5240 nordmark MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0); 1473 0 stevel mutex_enter(&so->so_lock); 1474 0 stevel if (error) { 1475 0 stevel eprintsoline(so, error); 1476 0 stevel goto done; 1477 0 stevel } 1478 0 stevel 1479 0 stevel error = sowaitokack(so, T_UNBIND_REQ); 1480 0 stevel if (error) { 1481 0 stevel eprintsoline(so, error); 1482 0 stevel goto done; 1483 0 stevel } 1484 0 stevel 1485 0 stevel /* 1486 0 stevel * Even if some TPI message (e.g. T_DISCON_IND) was received in 1487 0 stevel * strsock_proto while the lock was dropped above, the unbind 1488 0 stevel * is allowed to complete. 1489 0 stevel */ 1490 0 stevel if (!(flags & _SOUNBIND_REBIND)) { 1491 0 stevel /* 1492 0 stevel * Clear out bound address. 1493 0 stevel */ 1494 0 stevel vnode_t *vp; 1495 0 stevel 1496 8348 Eric if ((vp = sti->sti_ux_bound_vp) != NULL) { 1497 898 kais 1498 898 kais /* Undo any SSL proxy setup */ 1499 898 kais if ((so->so_family == AF_INET || 1500 898 kais so->so_family == AF_INET6) && 1501 898 kais (so->so_type == SOCK_STREAM) && 1502 8348 Eric (sti->sti_kssl_ent != NULL)) { 1503 8348 Eric kssl_release_ent(sti->sti_kssl_ent, so, 1504 8348 Eric sti->sti_kssl_type); 1505 8348 Eric sti->sti_kssl_ent = NULL; 1506 8348 Eric sti->sti_kssl_type = KSSL_NO_PROXY; 1507 8348 Eric } 1508 8348 Eric sti->sti_ux_bound_vp = NULL; 1509 0 stevel vn_rele_stream(vp); 1510 0 stevel } 1511 0 stevel /* Clear out address */ 1512 8348 Eric sti->sti_laddr_len = 0; 1513 8348 Eric } 1514 8348 Eric so->so_state &= ~(SS_ISBOUND|SS_ACCEPTCONN); 1515 8348 Eric sti->sti_laddr_valid = 0; 1516 1974 brutus 1517 0 stevel done: 1518 898 kais 1519 0 stevel /* If the caller held the lock don't release it here */ 1520 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 1521 0 stevel ASSERT(so->so_flag & SOLOCKED); 1522 0 stevel 1523 0 stevel return (error); 1524 0 stevel } 1525 0 stevel 1526 0 stevel /* 1527 0 stevel * listen on the socket. 1528 0 stevel * For TPI conforming transports this has to first unbind with the transport 1529 0 stevel * and then bind again using the new backlog. 1530 0 stevel */ 1531 8348 Eric /* ARGSUSED */ 1532 8348 Eric int 1533 8348 Eric sotpi_listen(struct sonode *so, int backlog, struct cred *cr) 1534 0 stevel { 1535 0 stevel int error = 0; 1536 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 1537 0 stevel 1538 0 stevel dprintso(so, 1, ("sotpi_listen(%p, %d) %s\n", 1539 7240 rh87107 (void *)so, backlog, pr_state(so->so_state, so->so_mode))); 1540 0 stevel 1541 8348 Eric if (sti->sti_serv_type == T_CLTS) 1542 0 stevel return (EOPNOTSUPP); 1543 0 stevel 1544 0 stevel /* 1545 0 stevel * If the socket is ready to accept connections already, then 1546 0 stevel * return without doing anything. This avoids a problem where 1547 0 stevel * a second listen() call fails if a connection is pending and 1548 0 stevel * leaves the socket unbound. Only when we are not unbinding 1549 0 stevel * with the transport can we safely increase the backlog. 1550 0 stevel */ 1551 0 stevel if (so->so_state & SS_ACCEPTCONN && 1552 0 stevel !((so->so_family == AF_INET || so->so_family == AF_INET6) && 1553 5240 nordmark /*CONSTCOND*/ 1554 5240 nordmark !solisten_tpi_tcp)) 1555 0 stevel return (0); 1556 0 stevel 1557 0 stevel if (so->so_state & SS_ISCONNECTED) 1558 0 stevel return (EINVAL); 1559 0 stevel 1560 0 stevel mutex_enter(&so->so_lock); 1561 0 stevel so_lock_single(so); /* Set SOLOCKED */ 1562 0 stevel 1563 0 stevel /* 1564 0 stevel * If the listen doesn't change the backlog we do nothing. 1565 0 stevel * This avoids an EPROTO error from the transport. 1566 0 stevel */ 1567 0 stevel if ((so->so_state & SS_ACCEPTCONN) && 1568 0 stevel so->so_backlog == backlog) 1569 0 stevel goto done; 1570 0 stevel 1571 0 stevel if (!(so->so_state & SS_ISBOUND)) { 1572 0 stevel /* 1573 0 stevel * Must have been explicitly bound in the UNIX domain. 1574 0 stevel */ 1575 0 stevel if (so->so_family == AF_UNIX) { 1576 0 stevel error = EINVAL; 1577 0 stevel goto done; 1578 0 stevel } 1579 0 stevel error = sotpi_bindlisten(so, NULL, 0, backlog, 1580 8348 Eric _SOBIND_UNSPEC|_SOBIND_LOCK_HELD|_SOBIND_LISTEN, cr); 1581 0 stevel } else if (backlog > 0) { 1582 0 stevel /* 1583 0 stevel * AF_INET{,6} hack to avoid losing the port. 1584 0 stevel * Assumes that all AF_INET{,6} transports can handle a 1585 0 stevel * O_T_BIND_REQ with a non-zero CONIND_number when the TPI 1586 0 stevel * has already bound thus it is possible to avoid the unbind. 1587 0 stevel */ 1588 0 stevel if (!((so->so_family == AF_INET || so->so_family == AF_INET6) && 1589 0 stevel /*CONSTCOND*/ 1590 0 stevel !solisten_tpi_tcp)) { 1591 0 stevel error = sotpi_unbind(so, _SOUNBIND_REBIND); 1592 0 stevel if (error) 1593 0 stevel goto done; 1594 0 stevel } 1595 0 stevel error = sotpi_bindlisten(so, NULL, 0, backlog, 1596 8348 Eric _SOBIND_REBIND|_SOBIND_LOCK_HELD|_SOBIND_LISTEN, cr); 1597 0 stevel } else { 1598 0 stevel so->so_state |= SS_ACCEPTCONN; 1599 0 stevel so->so_backlog = backlog; 1600 0 stevel } 1601 0 stevel if (error) 1602 0 stevel goto done; 1603 0 stevel ASSERT(so->so_state & SS_ACCEPTCONN); 1604 0 stevel done: 1605 0 stevel so_unlock_single(so, SOLOCKED); 1606 0 stevel mutex_exit(&so->so_lock); 1607 0 stevel return (error); 1608 0 stevel } 1609 0 stevel 1610 0 stevel /* 1611 0 stevel * Disconnect either a specified seqno or all (-1). 1612 0 stevel * The former is used on listening sockets only. 1613 0 stevel * 1614 0 stevel * When seqno == -1 sodisconnect could call sotpi_unbind. However, 1615 0 stevel * the current use of sodisconnect(seqno == -1) is only for shutdown 1616 0 stevel * so there is no point (and potentially incorrect) to unbind. 1617 0 stevel */ 1618 8348 Eric static int 1619 0 stevel sodisconnect(struct sonode *so, t_scalar_t seqno, int flags) 1620 0 stevel { 1621 0 stevel struct T_discon_req discon_req; 1622 0 stevel int error = 0; 1623 0 stevel mblk_t *mp; 1624 0 stevel 1625 0 stevel dprintso(so, 1, ("sodisconnect(%p, %d, 0x%x) %s\n", 1626 7240 rh87107 (void *)so, seqno, flags, pr_state(so->so_state, so->so_mode))); 1627 0 stevel 1628 0 stevel if (!(flags & _SODISCONNECT_LOCK_HELD)) { 1629 0 stevel mutex_enter(&so->so_lock); 1630 0 stevel so_lock_single(so); /* Set SOLOCKED */ 1631 0 stevel } else { 1632 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 1633 0 stevel ASSERT(so->so_flag & SOLOCKED); 1634 0 stevel } 1635 0 stevel 1636 0 stevel if (!(so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING|SS_ACCEPTCONN))) { 1637 0 stevel error = EINVAL; 1638 0 stevel eprintsoline(so, error); 1639 0 stevel goto done; 1640 0 stevel } 1641 0 stevel 1642 0 stevel mutex_exit(&so->so_lock); 1643 0 stevel /* 1644 0 stevel * Flush the write side (unless this is a listener) 1645 0 stevel * and then send down a T_DISCON_REQ. 1646 0 stevel * (Don't flush on listener since it could flush {O_}T_CONN_RES 1647 0 stevel * and other messages.) 1648 0 stevel */ 1649 0 stevel if (!(so->so_state & SS_ACCEPTCONN)) 1650 0 stevel (void) putnextctl1(strvp2wq(SOTOV(so)), M_FLUSH, FLUSHW); 1651 0 stevel 1652 0 stevel discon_req.PRIM_type = T_DISCON_REQ; 1653 0 stevel discon_req.SEQ_number = seqno; 1654 0 stevel mp = soallocproto1(&discon_req, sizeof (discon_req), 1655 8778 Erik 0, _ALLOC_SLEEP, CRED()); 1656 0 stevel error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0, 1657 5240 nordmark MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0); 1658 0 stevel mutex_enter(&so->so_lock); 1659 0 stevel if (error) { 1660 0 stevel eprintsoline(so, error); 1661 0 stevel goto done; 1662 0 stevel } 1663 0 stevel 1664 0 stevel error = sowaitokack(so, T_DISCON_REQ); 1665 0 stevel if (error) { 1666 0 stevel eprintsoline(so, error); 1667 0 stevel goto done; 1668 0 stevel } 1669 0 stevel /* 1670 0 stevel * Even if some TPI message (e.g. T_DISCON_IND) was received in 1671 0 stevel * strsock_proto while the lock was dropped above, the disconnect 1672 0 stevel * is allowed to complete. However, it is not possible to 1673 0 stevel * assert that SS_ISCONNECTED|SS_ISCONNECTING are set. 1674 0 stevel */ 1675 8348 Eric so->so_state &= ~(SS_ISCONNECTED|SS_ISCONNECTING); 1676 8348 Eric SOTOTPI(so)->sti_laddr_valid = 0; 1677 8348 Eric SOTOTPI(so)->sti_faddr_valid = 0; 1678 0 stevel done: 1679 0 stevel if (!(flags & _SODISCONNECT_LOCK_HELD)) { 1680 0 stevel so_unlock_single(so, SOLOCKED); 1681 0 stevel mutex_exit(&so->so_lock); 1682 0 stevel } else { 1683 0 stevel /* If the caller held the lock don't release it here */ 1684 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 1685 0 stevel ASSERT(so->so_flag & SOLOCKED); 1686 0 stevel } 1687 0 stevel return (error); 1688 0 stevel } 1689 0 stevel 1690 8348 Eric /* ARGSUSED */ 1691 8348 Eric int 1692 8348 Eric sotpi_accept(struct sonode *so, int fflag, struct cred *cr, 1693 8348 Eric struct sonode **nsop) 1694 0 stevel { 1695 0 stevel struct T_conn_ind *conn_ind; 1696 0 stevel struct T_conn_res *conn_res; 1697 0 stevel int error = 0; 1698 4379 ja97890 mblk_t *mp, *ctxmp, *ack_mp; 1699 0 stevel struct sonode *nso; 1700 0 stevel vnode_t *nvp; 1701 0 stevel void *src; 1702 0 stevel t_uscalar_t srclen; 1703 0 stevel void *opt; 1704 0 stevel t_uscalar_t optlen; 1705 0 stevel t_scalar_t PRIM_type; 1706 0 stevel t_scalar_t SEQ_number; 1707 4379 ja97890 size_t sinlen; 1708 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 1709 8348 Eric sotpi_info_t *nsti; 1710 0 stevel 1711 0 stevel dprintso(so, 1, ("sotpi_accept(%p, 0x%x, %p) %s\n", 1712 7240 rh87107 (void *)so, fflag, (void *)nsop, 1713 7240 rh87107 pr_state(so->so_state, so->so_mode))); 1714 0 stevel 1715 0 stevel /* 1716 0 stevel * Defer single-threading the accepting socket until 1717 0 stevel * the T_CONN_IND has been received and parsed and the 1718 0 stevel * new sonode has been opened. 1719 0 stevel */ 1720 0 stevel 1721 0 stevel /* Check that we are not already connected */ 1722 0 stevel if ((so->so_state & SS_ACCEPTCONN) == 0) 1723 0 stevel goto conn_bad; 1724 0 stevel again: 1725 0 stevel if ((error = sowaitconnind(so, fflag, &mp)) != 0) 1726 0 stevel goto e_bad; 1727 0 stevel 1728 8348 Eric ASSERT(mp != NULL); 1729 0 stevel conn_ind = (struct T_conn_ind *)mp->b_rptr; 1730 898 kais ctxmp = mp->b_cont; 1731 898 kais 1732 0 stevel /* 1733 0 stevel * Save SEQ_number for error paths. 1734 0 stevel */ 1735 0 stevel SEQ_number = conn_ind->SEQ_number; 1736 0 stevel 1737 0 stevel srclen = conn_ind->SRC_length; 1738 0 stevel src = sogetoff(mp, conn_ind->SRC_offset, srclen, 1); 1739 0 stevel if (src == NULL) { 1740 0 stevel error = EPROTO; 1741 0 stevel freemsg(mp); 1742 0 stevel eprintsoline(so, error); 1743 0 stevel goto disconnect_unlocked; 1744 0 stevel } 1745 0 stevel optlen = conn_ind->OPT_length; 1746 0 stevel switch (so->so_family) { 1747 0 stevel case AF_INET: 1748 0 stevel case AF_INET6: 1749 8348 Eric if ((optlen == sizeof (intptr_t)) && (sti->sti_direct != 0)) { 1750 0 stevel bcopy(mp->b_rptr + conn_ind->OPT_offset, 1751 0 stevel &opt, conn_ind->OPT_length); 1752 0 stevel } else { 1753 0 stevel /* 1754 0 stevel * The transport (in this case TCP) hasn't sent up 1755 0 stevel * a pointer to an instance for the accept fast-path. 1756 0 stevel * Disable fast-path completely because the call to 1757 0 stevel * sotpi_create() below would otherwise create an 1758 0 stevel * incomplete TCP instance, which would lead to 1759 0 stevel * problems when sockfs sends a normal T_CONN_RES 1760 0 stevel * message down the new stream. 1761 0 stevel */ 1762 8348 Eric if (sti->sti_direct) { 1763 741 masputra int rval; 1764 741 masputra /* 1765 741 masputra * For consistency we inform tcp to disable 1766 741 masputra * direct interface on the listener, though 1767 741 masputra * we can certainly live without doing this 1768 741 masputra * because no data will ever travel upstream 1769 741 masputra * on the listening socket. 1770 741 masputra */ 1771 8348 Eric sti->sti_direct = 0; 1772 741 masputra (void) strioctl(SOTOV(so), _SIOCSOCKFALLBACK, 1773 8778 Erik 0, 0, K_TO_K, cr, &rval); 1774 741 masputra } 1775 0 stevel opt = NULL; 1776 0 stevel optlen = 0; 1777 0 stevel } 1778 0 stevel break; 1779 0 stevel case AF_UNIX: 1780 0 stevel default: 1781 0 stevel if (optlen != 0) { 1782 0 stevel opt = sogetoff(mp, conn_ind->OPT_offset, optlen, 1783 0 stevel __TPI_ALIGN_SIZE); 1784 0 stevel if (opt == NULL) { 1785 0 stevel error = EPROTO; 1786 0 stevel freemsg(mp); 1787 0 stevel eprintsoline(so, error); 1788 0 stevel goto disconnect_unlocked; 1789 0 stevel } 1790 0 stevel } 1791 0 stevel if (so->so_family == AF_UNIX) { 1792 8348 Eric if (!sti->sti_faddr_noxlate) { 1793 0 stevel src = NULL; 1794 0 stevel srclen = 0; 1795 0 stevel } 1796 0 stevel /* Extract src address from options */ 1797 0 stevel if (optlen != 0) 1798 0 stevel so_getopt_srcaddr(opt, optlen, &src, &srclen); 1799 0 stevel } 1800 0 stevel break; 1801 0 stevel } 1802 0 stevel 1803 0 stevel /* 1804 0 stevel * Create the new socket. 1805 0 stevel */ 1806 8348 Eric nso = socket_newconn(so, NULL, NULL, SOCKET_SLEEP, &error); 1807 0 stevel if (nso == NULL) { 1808 0 stevel ASSERT(error != 0); 1809 0 stevel /* 1810 0 stevel * Accept can not fail with ENOBUFS. sotpi_create 1811 0 stevel * sleeps waiting for memory until a signal is caught 1812 0 stevel * so return EINTR. 1813 0 stevel */ 1814 0 stevel freemsg(mp); 1815 0 stevel if (error == ENOBUFS) 1816 0 stevel error = EINTR; 1817 0 stevel goto e_disc_unl; 1818 0 stevel } 1819 0 stevel nvp = SOTOV(nso); 1820 8348 Eric nsti = SOTOTPI(nso); 1821 0 stevel 1822 898 kais /* 1823 898 kais * If the transport sent up an SSL connection context, then attach 1824 898 kais * it the new socket, and set the (sd_wputdatafunc)() and 1825 898 kais * (sd_rputdatafunc)() stream head hooks to intercept and process 1826 898 kais * SSL records. 1827 898 kais */ 1828 898 kais if (ctxmp != NULL) { 1829 898 kais /* 1830 898 kais * This kssl_ctx_t is already held for us by the transport. 1831 898 kais * So, we don't need to do a kssl_hold_ctx() here. 1832 898 kais */ 1833 8348 Eric nsti->sti_kssl_ctx = *((kssl_ctx_t *)ctxmp->b_rptr); 1834 898 kais freemsg(ctxmp); 1835 898 kais mp->b_cont = NULL; 1836 898 kais strsetrwputdatahooks(nvp, strsock_kssl_input, 1837 898 kais strsock_kssl_output); 1838 898 kais } 1839 0 stevel #ifdef DEBUG 1840 0 stevel /* 1841 0 stevel * SO_DEBUG is used to trigger the dprint* and eprint* macros thus 1842 0 stevel * it's inherited early to allow debugging of the accept code itself. 1843 0 stevel */ 1844 0 stevel nso->so_options |= so->so_options & SO_DEBUG; 1845 0 stevel #endif /* DEBUG */ 1846 0 stevel 1847 0 stevel /* 1848 0 stevel * Save the SRC address from the T_CONN_IND 1849 0 stevel * for getpeername to work on AF_UNIX and on transports that do not 1850 0 stevel * support TI_GETPEERNAME. 1851 0 stevel * 1852 0 stevel * NOTE: AF_UNIX NUL termination is ensured by the sender's 1853 0 stevel * copyin_name(). 1854 0 stevel */ 1855 8348 Eric if (srclen > (t_uscalar_t)nsti->sti_faddr_maxlen) { 1856 0 stevel error = EINVAL; 1857 0 stevel freemsg(mp); 1858 0 stevel eprintsoline(so, error); 1859 0 stevel goto disconnect_vp_unlocked; 1860 0 stevel } 1861 8348 Eric nsti->sti_faddr_len = (socklen_t)srclen; 1862 8348 Eric ASSERT(sti->sti_faddr_len <= sti->sti_faddr_maxlen); 1863 8348 Eric bcopy(src, nsti->sti_faddr_sa, srclen); 1864 8348 Eric nsti->sti_faddr_valid = 1; 1865 0 stevel 1866 8778 Erik /* 1867 8778 Erik * Record so_peercred and so_cpid from a cred in the T_CONN_IND. 1868 8778 Erik */ 1869 0 stevel if ((DB_REF(mp) > 1) || MBLKSIZE(mp) < 1870 0 stevel (sizeof (struct T_conn_res) + sizeof (intptr_t))) { 1871 8778 Erik cred_t *cr; 1872 8778 Erik pid_t cpid; 1873 8778 Erik 1874 8778 Erik cr = msg_getcred(mp, &cpid); 1875 8778 Erik if (cr != NULL) { 1876 0 stevel crhold(cr); 1877 0 stevel nso->so_peercred = cr; 1878 8778 Erik nso->so_cpid = cpid; 1879 0 stevel } 1880 0 stevel freemsg(mp); 1881 0 stevel 1882 0 stevel mp = soallocproto1(NULL, sizeof (struct T_conn_res) + 1883 8965 Anders sizeof (intptr_t), 0, _ALLOC_INTR, cr); 1884 0 stevel if (mp == NULL) { 1885 0 stevel /* 1886 0 stevel * Accept can not fail with ENOBUFS. 1887 0 stevel * A signal was caught so return EINTR. 1888 0 stevel */ 1889 0 stevel error = EINTR; 1890 0 stevel eprintsoline(so, error); 1891 0 stevel goto disconnect_vp_unlocked; 1892 0 stevel } 1893 0 stevel conn_res = (struct T_conn_res *)mp->b_rptr; 1894 0 stevel } else { 1895 8778 Erik /* 1896 8778 Erik * For efficency reasons we use msg_extractcred; no crhold 1897 8778 Erik * needed since db_credp is cleared (i.e., we move the cred 1898 8778 Erik * from the message to so_peercred. 1899 8778 Erik */ 1900 8778 Erik nso->so_peercred = msg_extractcred(mp, &nso->so_cpid); 1901 0 stevel 1902 0 stevel mp->b_rptr = DB_BASE(mp); 1903 0 stevel conn_res = (struct T_conn_res *)mp->b_rptr; 1904 0 stevel mp->b_wptr = mp->b_rptr + sizeof (struct T_conn_res); 1905 8965 Anders 1906 8965 Anders mblk_setcred(mp, cr, curproc->p_pid); 1907 0 stevel } 1908 0 stevel 1909 0 stevel /* 1910 0 stevel * New socket must be bound at least in sockfs and, except for AF_INET, 1911 0 stevel * (or AF_INET6) it also has to be bound in the transport provider. 1912 4379 ja97890 * We set the local address in the sonode from the T_OK_ACK of the 1913 4379 ja97890 * T_CONN_RES. For this reason the address we bind to here isn't 1914 4379 ja97890 * important. 1915 0 stevel */ 1916 0 stevel if ((nso->so_family == AF_INET || nso->so_family == AF_INET6) && 1917 0 stevel /*CONSTCOND*/ 1918 0 stevel nso->so_type == SOCK_STREAM && !soaccept_tpi_tcp) { 1919 0 stevel /* 1920 0 stevel * Optimization for AF_INET{,6} transports 1921 0 stevel * that can handle a T_CONN_RES without being bound. 1922 0 stevel */ 1923 0 stevel mutex_enter(&nso->so_lock); 1924 0 stevel so_automatic_bind(nso); 1925 0 stevel mutex_exit(&nso->so_lock); 1926 0 stevel } else { 1927 0 stevel /* Perform NULL bind with the transport provider. */ 1928 8348 Eric if ((error = sotpi_bind(nso, NULL, 0, _SOBIND_UNSPEC, 1929 8348 Eric cr)) != 0) { 1930 0 stevel ASSERT(error != ENOBUFS); 1931 0 stevel freemsg(mp); 1932 0 stevel eprintsoline(nso, error); 1933 0 stevel goto disconnect_vp_unlocked; 1934 0 stevel } 1935 0 stevel } 1936 0 stevel 1937 0 stevel /* 1938 0 stevel * Inherit SIOCSPGRP, SS_ASYNC before we send the {O_}T_CONN_RES 1939 0 stevel * so that any data arriving on the new socket will cause the 1940 0 stevel * appropriate signals to be delivered for the new socket. 1941 0 stevel * 1942 0 stevel * No other thread (except strsock_proto and strsock_misc) 1943 0 stevel * can access the new socket thus we relax the locking. 1944 0 stevel */ 1945 0 stevel nso->so_pgrp = so->so_pgrp; 1946 8348 Eric nso->so_state |= so->so_state & SS_ASYNC; 1947 8348 Eric nsti->sti_faddr_noxlate = sti->sti_faddr_noxlate; 1948 0 stevel 1949 0 stevel if (nso->so_pgrp != 0) { 1950 8778 Erik if ((error = so_set_events(nso, nvp, cr)) != 0) { 1951 0 stevel eprintsoline(nso, error); 1952 0 stevel error = 0; 1953 0 stevel nso->so_pgrp = 0; 1954 0 stevel } 1955 0 stevel } 1956 0 stevel 1957 0 stevel /* 1958 0 stevel * Make note of the socket level options. TCP and IP level options 1959 0 stevel * are already inherited. We could do all this after accept is 1960 0 stevel * successful but doing it here simplifies code and no harm done 1961 0 stevel * for error case. 1962 0 stevel */ 1963 0 stevel nso->so_options = so->so_options & (SO_DEBUG|SO_REUSEADDR|SO_KEEPALIVE| 1964 0 stevel SO_DONTROUTE|SO_BROADCAST|SO_USELOOPBACK| 1965 0 stevel SO_OOBINLINE|SO_DGRAM_ERRIND|SO_LINGER); 1966 0 stevel nso->so_sndbuf = so->so_sndbuf; 1967 0 stevel nso->so_rcvbuf = so->so_rcvbuf; 1968 0 stevel if (nso->so_options & SO_LINGER) 1969 0 stevel nso->so_linger = so->so_linger; 1970 0 stevel 1971 8348 Eric /* 1972 8348 Eric * Note that the following sti_direct code path should be 1973 8348 Eric * removed once we are confident that the direct sockets 1974 8348 Eric * do not result in any degradation. 1975 8348 Eric */ 1976 8348 Eric if (sti->sti_direct) { 1977 0 stevel 1978 0 stevel ASSERT(opt != NULL); 1979 0 stevel 1980 0 stevel conn_res->OPT_length = optlen; 1981 0 stevel conn_res->OPT_offset = MBLKL(mp); 1982 0 stevel bcopy(&opt, mp->b_wptr, optlen); 1983 0 stevel mp->b_wptr += optlen; 1984 0 stevel conn_res->PRIM_type = T_CONN_RES; 1985 0 stevel conn_res->ACCEPTOR_id = 0; 1986 0 stevel PRIM_type = T_CONN_RES; 1987 0 stevel 1988 0 stevel /* Send down the T_CONN_RES on acceptor STREAM */ 1989 0 stevel error = kstrputmsg(SOTOV(nso), mp, NULL, 1990 0 stevel 0, 0, MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0); 1991 0 stevel if (error) { 1992 0 stevel mutex_enter(&so->so_lock); 1993 0 stevel so_lock_single(so); 1994 0 stevel eprintsoline(so, error); 1995 0 stevel goto disconnect_vp; 1996 0 stevel } 1997 0 stevel mutex_enter(&nso->so_lock); 1998 0 stevel error = sowaitprim(nso, T_CONN_RES, T_OK_ACK, 1999 0 stevel (t_uscalar_t)sizeof (struct T_ok_ack), &ack_mp, 0); 2000 0 stevel if (error) { 2001 0 stevel mutex_exit(&nso->so_lock); 2002 0 stevel mutex_enter(&so->so_lock); 2003 0 stevel so_lock_single(so); 2004 0 stevel eprintsoline(so, error); 2005 0 stevel goto disconnect_vp; 2006 0 stevel } 2007 0 stevel if (nso->so_family == AF_INET) { 2008 0 stevel sin_t *sin; 2009 0 stevel 2010 0 stevel sin = (sin_t *)(ack_mp->b_rptr + 2011 0 stevel sizeof (struct T_ok_ack)); 2012 8348 Eric bcopy(sin, nsti->sti_laddr_sa, sizeof (sin_t)); 2013 8348 Eric nsti->sti_laddr_len = sizeof (sin_t); 2014 0 stevel } else { 2015 0 stevel sin6_t *sin6; 2016 0 stevel 2017 0 stevel sin6 = (sin6_t *)(ack_mp->b_rptr + 2018 0 stevel sizeof (struct T_ok_ack)); 2019 8348 Eric bcopy(sin6, nsti->sti_laddr_sa, sizeof (sin6_t)); 2020 8348 Eric nsti->sti_laddr_len = sizeof (sin6_t); 2021 0 stevel } 2022 0 stevel freemsg(ack_mp); 2023 0 stevel 2024 8348 Eric nso->so_state |= SS_ISCONNECTED; 2025 8348 Eric nso->so_proto_handle = (sock_lower_handle_t)opt; 2026 8348 Eric nsti->sti_laddr_valid = 1; 2027 8348 Eric 2028 8348 Eric if (sti->sti_nl7c_flags & NL7C_ENABLED) { 2029 0 stevel /* 2030 1974 brutus * A NL7C marked listen()er so the new socket 2031 1974 brutus * inherits the listen()er's NL7C state, except 2032 1974 brutus * for NL7C_POLLIN. 2033 1974 brutus * 2034 1974 brutus * Only call NL7C to process the new socket if 2035 1974 brutus * the listen socket allows blocking i/o. 2036 1974 brutus */ 2037 8348 Eric nsti->sti_nl7c_flags = 2038 8348 Eric sti->sti_nl7c_flags & (~NL7C_POLLIN); 2039 1974 brutus if (so->so_state & (SS_NONBLOCK|SS_NDELAY)) { 2040 1974 brutus /* 2041 1974 brutus * Nonblocking accept() just make it 2042 1974 brutus * persist to defer processing to the 2043 1974 brutus * read-side syscall (e.g. read). 2044 1974 brutus */ 2045 8348 Eric nsti->sti_nl7c_flags |= NL7C_SOPERSIST; 2046 1974 brutus } else if (nl7c_process(nso, B_FALSE)) { 2047 0 stevel /* 2048 0 stevel * NL7C has completed processing on the 2049 0 stevel * socket, close the socket and back to 2050 0 stevel * the top to await the next T_CONN_IND. 2051 0 stevel */ 2052 0 stevel mutex_exit(&nso->so_lock); 2053 0 stevel (void) VOP_CLOSE(nvp, 0, 1, (offset_t)0, 2054 8778 Erik cr, NULL); 2055 0 stevel VN_RELE(nvp); 2056 0 stevel goto again; 2057 0 stevel } 2058 0 stevel /* Pass the new socket out */ 2059 0 stevel } 2060 0 stevel 2061 0 stevel mutex_exit(&nso->so_lock); 2062 2811 ja97890 2063 2811 ja97890 /* 2064 2811 ja97890 * It's possible, through the use of autopush for example, 2065 8348 Eric * that the acceptor stream may not support sti_direct 2066 8348 Eric * semantics. If the new socket does not support sti_direct 2067 2811 ja97890 * we issue a _SIOCSOCKFALLBACK to inform the transport 2068 2811 ja97890 * as we would in the I_PUSH case. 2069 2811 ja97890 */ 2070 8348 Eric if (nsti->sti_direct == 0) { 2071 2811 ja97890 int rval; 2072 2811 ja97890 2073 2811 ja97890 if ((error = strioctl(SOTOV(nso), _SIOCSOCKFALLBACK, 2074 8778 Erik 0, 0, K_TO_K, cr, &rval)) != 0) { 2075 2811 ja97890 mutex_enter(&so->so_lock); 2076 2811 ja97890 so_lock_single(so); 2077 2811 ja97890 eprintsoline(so, error); 2078 2811 ja97890 goto disconnect_vp; 2079 2811 ja97890 } 2080 2811 ja97890 } 2081 0 stevel 2082 0 stevel /* 2083 0 stevel * Pass out new socket. 2084 0 stevel */ 2085 0 stevel if (nsop != NULL) 2086 0 stevel *nsop = nso; 2087 0 stevel 2088 0 stevel return (0); 2089 0 stevel } 2090 0 stevel 2091 0 stevel /* 2092 0 stevel * This is the non-performance case for sockets (e.g. AF_UNIX sockets) 2093 0 stevel * which don't support the FireEngine accept fast-path. It is also 2094 0 stevel * used when the virtual "sockmod" has been I_POP'd and I_PUSH'd 2095 0 stevel * again. Neither sockfs nor TCP attempt to find out if some other 2096 0 stevel * random module has been inserted in between (in which case we 2097 0 stevel * should follow TLI accept behaviour). We blindly assume the worst 2098 0 stevel * case and revert back to old behaviour i.e. TCP will not send us 2099 0 stevel * any option (eager) and the accept should happen on the listener 2100 0 stevel * queue. Any queued T_conn_ind have already got their options removed 2101 0 stevel * by so_sock2_stream() when "sockmod" was I_POP'd. 2102 0 stevel */ 2103 0 stevel /* 2104 0 stevel * Fill in the {O_}T_CONN_RES before getting SOLOCKED. 2105 0 stevel */ 2106 0 stevel if ((nso->so_mode & SM_ACCEPTOR_ID) == 0) { 2107 0 stevel #ifdef _ILP32 2108 0 stevel queue_t *q; 2109 0 stevel 2110 0 stevel /* 2111 0 stevel * Find read queue in driver 2112 0 stevel * Can safely do this since we "own" nso/nvp. 2113 0 stevel */ 2114 0 stevel q = strvp2wq(nvp)->q_next; 2115 0 stevel while (SAMESTR(q)) 2116 0 stevel q = q->q_next; 2117 0 stevel q = RD(q); 2118 0 stevel conn_res->ACCEPTOR_id = (t_uscalar_t)q; 2119 0 stevel #else 2120 0 stevel conn_res->ACCEPTOR_id = (t_uscalar_t)getminor(nvp->v_rdev); 2121 0 stevel #endif /* _ILP32 */ 2122 0 stevel conn_res->PRIM_type = O_T_CONN_RES; 2123 0 stevel PRIM_type = O_T_CONN_RES; 2124 0 stevel } else { 2125 8348 Eric conn_res->ACCEPTOR_id = nsti->sti_acceptor_id; 2126 0 stevel conn_res->PRIM_type = T_CONN_RES; 2127 0 stevel PRIM_type = T_CONN_RES; 2128 0 stevel } 2129 0 stevel conn_res->SEQ_number = SEQ_number; 2130 0 stevel conn_res->OPT_length = 0; 2131 0 stevel conn_res->OPT_offset = 0; 2132 0 stevel 2133 0 stevel mutex_enter(&so->so_lock); 2134 0 stevel so_lock_single(so); /* Set SOLOCKED */ 2135 0 stevel mutex_exit(&so->so_lock); 2136 0 stevel 2137 0 stevel error = kstrputmsg(SOTOV(so), mp, NULL, 2138 0 stevel 0, 0, MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0); 2139 0 stevel mutex_enter(&so->so_lock); 2140 0 stevel if (error) { 2141 0 stevel eprintsoline(so, error); 2142 0 stevel goto disconnect_vp; 2143 0 stevel } 2144 4379 ja97890 error = sowaitprim(so, PRIM_type, T_OK_ACK, 2145 4379 ja97890 (t_uscalar_t)sizeof (struct T_ok_ack), &ack_mp, 0); 2146 0 stevel if (error) { 2147 0 stevel eprintsoline(so, error); 2148 0 stevel goto disconnect_vp; 2149 0 stevel } 2150 4379 ja97890 /* 2151 4379 ja97890 * If there is a sin/sin6 appended onto the T_OK_ACK use 2152 4379 ja97890 * that to set the local address. If this is not present 2153 4379 ja97890 * then we zero out the address and don't set the 2154 8348 Eric * sti_laddr_valid bit. For AF_UNIX endpoints we copy over 2155 4678 ja97890 * the pathname from the listening socket. 2156 4379 ja97890 */ 2157 4379 ja97890 sinlen = (nso->so_family == AF_INET) ? sizeof (sin_t) : sizeof (sin6_t); 2158 4379 ja97890 if ((nso->so_family == AF_INET) || (nso->so_family == AF_INET6) && 2159 4379 ja97890 MBLKL(ack_mp) == (sizeof (struct T_ok_ack) + sinlen)) { 2160 4379 ja97890 ack_mp->b_rptr += sizeof (struct T_ok_ack); 2161 8348 Eric bcopy(ack_mp->b_rptr, nsti->sti_laddr_sa, sinlen); 2162 8348 Eric nsti->sti_laddr_len = sinlen; 2163 8348 Eric nsti->sti_laddr_valid = 1; 2164 4678 ja97890 } else if (nso->so_family == AF_UNIX) { 2165 4678 ja97890 ASSERT(so->so_family == AF_UNIX); 2166 8348 Eric nsti->sti_laddr_len = sti->sti_laddr_len; 2167 8348 Eric ASSERT(nsti->sti_laddr_len <= nsti->sti_laddr_maxlen); 2168 8348 Eric bcopy(sti->sti_laddr_sa, nsti->sti_laddr_sa, 2169 8348 Eric nsti->sti_laddr_len); 2170 8348 Eric nsti->sti_laddr_valid = 1; 2171 8348 Eric } else { 2172 8348 Eric nsti->sti_laddr_len = sti->sti_laddr_len; 2173 8348 Eric ASSERT(nsti->sti_laddr_len <= nsti->sti_laddr_maxlen); 2174 8348 Eric bzero(nsti->sti_laddr_sa, nsti->sti_addr_size); 2175 8348 Eric nsti->sti_laddr_sa->sa_family = nso->so_family; 2176 4379 ja97890 } 2177 4379 ja97890 freemsg(ack_mp); 2178 4379 ja97890 2179 0 stevel so_unlock_single(so, SOLOCKED); 2180 0 stevel mutex_exit(&so->so_lock); 2181 0 stevel 2182 0 stevel nso->so_state |= SS_ISCONNECTED; 2183 0 stevel 2184 0 stevel /* 2185 0 stevel * Pass out new socket. 2186 0 stevel */ 2187 0 stevel if (nsop != NULL) 2188 0 stevel *nsop = nso; 2189 0 stevel 2190 0 stevel return (0); 2191 0 stevel 2192 0 stevel 2193 0 stevel eproto_disc_unl: 2194 0 stevel error = EPROTO; 2195 0 stevel e_disc_unl: 2196 0 stevel eprintsoline(so, error); 2197 0 stevel goto disconnect_unlocked; 2198 0 stevel 2199 0 stevel pr_disc_vp_unl: 2200 0 stevel eprintsoline(so, error); 2201 0 stevel disconnect_vp_unlocked: 2202 8778 Erik (void) VOP_CLOSE(nvp, 0, 1, 0, cr, NULL); 2203 0 stevel VN_RELE(nvp); 2204 0 stevel disconnect_unlocked: 2205 0 stevel (void) sodisconnect(so, SEQ_number, 0); 2206 0 stevel return (error); 2207 0 stevel 2208 0 stevel pr_disc_vp: 2209 0 stevel eprintsoline(so, error); 2210 0 stevel disconnect_vp: 2211 0 stevel (void) sodisconnect(so, SEQ_number, _SODISCONNECT_LOCK_HELD); 2212 0 stevel so_unlock_single(so, SOLOCKED); 2213 0 stevel mutex_exit(&so->so_lock); 2214 8778 Erik (void) VOP_CLOSE(nvp, 0, 1, 0, cr, NULL); 2215 0 stevel VN_RELE(nvp); 2216 0 stevel return (error); 2217 0 stevel 2218 0 stevel conn_bad: /* Note: SunOS 4/BSD unconditionally returns EINVAL here */ 2219 0 stevel error = (so->so_type == SOCK_DGRAM || so->so_type == SOCK_RAW) 2220 0 stevel ? EOPNOTSUPP : EINVAL; 2221 0 stevel e_bad: 2222 0 stevel eprintsoline(so, error); 2223 0 stevel return (error); 2224 0 stevel } 2225 0 stevel 2226 0 stevel /* 2227 0 stevel * connect a socket. 2228 0 stevel * 2229 0 stevel * Allow SOCK_DGRAM sockets to reconnect (by specifying a new address) and to 2230 0 stevel * unconnect (by specifying a null address). 2231 0 stevel */ 2232 0 stevel int 2233 0 stevel sotpi_connect(struct sonode *so, 2234 0 stevel const struct sockaddr *name, 2235 0 stevel socklen_t namelen, 2236 0 stevel int fflag, 2237 8348 Eric int flags, 2238 8348 Eric struct cred *cr) 2239 0 stevel { 2240 0 stevel struct T_conn_req conn_req; 2241 0 stevel int error = 0; 2242 0 stevel mblk_t *mp; 2243 0 stevel void *src; 2244 0 stevel socklen_t srclen; 2245 0 stevel void *addr; 2246 0 stevel socklen_t addrlen; 2247 0 stevel boolean_t need_unlock; 2248 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 2249 0 stevel 2250 0 stevel dprintso(so, 1, ("sotpi_connect(%p, %p, %d, 0x%x, 0x%x) %s\n", 2251 7240 rh87107 (void *)so, (void *)name, namelen, fflag, flags, 2252 5240 nordmark pr_state(so->so_state, so->so_mode))); 2253 0 stevel 2254 0 stevel /* 2255 0 stevel * Preallocate the T_CONN_REQ mblk before grabbing SOLOCKED to 2256 0 stevel * avoid sleeping for memory with SOLOCKED held. 2257 8348 Eric * We know that the T_CONN_REQ can't be larger than 2 * sti_faddr_maxlen 2258 0 stevel * + sizeof (struct T_opthdr). 2259 0 stevel * (the AF_UNIX so_ux_addr_xlate() does not make the address 2260 8348 Eric * exceed sti_faddr_maxlen). 2261 0 stevel */ 2262 0 stevel mp = soallocproto(sizeof (struct T_conn_req) + 2263 8778 Erik 2 * sti->sti_faddr_maxlen + sizeof (struct T_opthdr), _ALLOC_INTR, 2264 8778 Erik cr); 2265 0 stevel if (mp == NULL) { 2266 0 stevel /* 2267 0 stevel * Connect can not fail with ENOBUFS. A signal was 2268 0 stevel * caught so return EINTR. 2269 0 stevel */ 2270 0 stevel error = EINTR; 2271 0 stevel eprintsoline(so, error); 2272 0 stevel return (error); 2273 0 stevel } 2274 0 stevel 2275 0 stevel mutex_enter(&so->so_lock); 2276 0 stevel /* 2277 5694 jprakash * Make sure there is a preallocated T_unbind_req message 2278 5694 jprakash * before any binding. This message is allocated when the 2279 5694 jprakash * socket is created. Since another thread can consume 2280 5694 jprakash * so_unbind_mp by the time we return from so_lock_single(), 2281 5694 jprakash * we should check the availability of so_unbind_mp after 2282 5694 jprakash * we return from so_lock_single(). 2283 5694 jprakash */ 2284 5694 jprakash 2285 5694 jprakash so_lock_single(so); /* Set SOLOCKED */ 2286 5694 jprakash need_unlock = B_TRUE; 2287 5694 jprakash 2288 8348 Eric if (sti->sti_unbind_mp == NULL) { 2289 0 stevel dprintso(so, 1, ("sotpi_connect: allocating unbind_req\n")); 2290 0 stevel /* NOTE: holding so_lock while sleeping */ 2291 8348 Eric sti->sti_unbind_mp = 2292 8778 Erik soallocproto(sizeof (struct T_unbind_req), _ALLOC_INTR, cr); 2293 8348 Eric if (sti->sti_unbind_mp == NULL) { 2294 0 stevel error = EINTR; 2295 5694 jprakash goto done; 2296 5694 jprakash } 2297 5694 jprakash } 2298 0 stevel 2299 0 stevel /* 2300 0 stevel * Can't have done a listen before connecting. 2301 0 stevel */ 2302 0 stevel if (so->so_state & SS_ACCEPTCONN) { 2303 0 stevel error = EOPNOTSUPP; 2304 0 stevel goto done; 2305 0 stevel } 2306 0 stevel 2307 0 stevel /* 2308 0 stevel * Must be bound with the transport 2309 0 stevel */ 2310 0 stevel if (!(so->so_state & SS_ISBOUND)) { 2311 0 stevel if ((so->so_family == AF_INET || so->so_family == AF_INET6) && 2312 0 stevel /*CONSTCOND*/ 2313 0 stevel so->so_type == SOCK_STREAM && !soconnect_tpi_tcp) { 2314 0 stevel /* 2315 0 stevel * Optimization for AF_INET{,6} transports 2316 0 stevel * that can handle a T_CONN_REQ without being bound. 2317 0 stevel */ 2318 0 stevel so_automatic_bind(so); 2319 0 stevel } else { 2320 0 stevel error = sotpi_bind(so, NULL, 0, 2321 8348 Eric _SOBIND_UNSPEC|_SOBIND_LOCK_HELD, cr); 2322 0 stevel if (error) 2323 0 stevel goto done; 2324 0 stevel } 2325 0 stevel ASSERT(so->so_state & SS_ISBOUND); 2326 0 stevel flags |= _SOCONNECT_DID_BIND; 2327 0 stevel } 2328 0 stevel 2329 0 stevel /* 2330 0 stevel * Handle a connect to a name parameter of type AF_UNSPEC like a 2331 0 stevel * connect to a null address. This is the portable method to 2332 0 stevel * unconnect a socket. 2333 0 stevel */ 2334 0 stevel if ((namelen >= sizeof (sa_family_t)) && 2335 0 stevel (name->sa_family == AF_UNSPEC)) { 2336 0 stevel name = NULL; 2337 0 stevel namelen = 0; 2338 0 stevel } 2339 0 stevel 2340 0 stevel /* 2341 0 stevel * Check that we are not already connected. 2342 0 stevel * A connection-oriented socket cannot be reconnected. 2343 0 stevel * A connected connection-less socket can be 2344 0 stevel * - connected to a different address by a subsequent connect 2345 0 stevel * - "unconnected" by a connect to the NULL address 2346 0 stevel */ 2347 0 stevel if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) { 2348 0 stevel ASSERT(!(flags & _SOCONNECT_DID_BIND)); 2349 0 stevel if (so->so_mode & SM_CONNREQUIRED) { 2350 0 stevel /* Connection-oriented socket */ 2351 0 stevel error = so->so_state & SS_ISCONNECTED ? 2352 0 stevel EISCONN : EALREADY; 2353 0 stevel goto done; 2354 0 stevel } 2355 0 stevel /* Connection-less socket */ 2356 0 stevel if (name == NULL) { 2357 0 stevel /* 2358 0 stevel * Remove the connected state and clear SO_DGRAM_ERRIND 2359 0 stevel * since it was set when the socket was connected. 2360 0 stevel * If this is UDP also send down a T_DISCON_REQ. 2361 0 stevel */ 2362 0 stevel int val; 2363 0 stevel 2364 0 stevel if ((so->so_family == AF_INET || 2365 5240 nordmark so->so_family == AF_INET6) && 2366 0 stevel (so->so_type == SOCK_DGRAM || 2367 5240 nordmark so->so_type == SOCK_RAW) && 2368 0 stevel /*CONSTCOND*/ 2369 0 stevel !soconnect_tpi_udp) { 2370 0 stevel /* XXX What about implicitly unbinding here? */ 2371 0 stevel error = sodisconnect(so, -1, 2372 5240 nordmark _SODISCONNECT_LOCK_HELD); 2373 0 stevel } else { 2374 0 stevel so->so_state &= 2375 8348 Eric ~(SS_ISCONNECTED | SS_ISCONNECTING); 2376 8348 Eric sti->sti_faddr_valid = 0; 2377 8348 Eric sti->sti_faddr_len = 0; 2378 8348 Eric } 2379 8348 Eric 2380 8348 Eric /* Remove SOLOCKED since setsockopt will grab it */ 2381 0 stevel so_unlock_single(so, SOLOCKED); 2382 0 stevel mutex_exit(&so->so_lock); 2383 0 stevel 2384 0 stevel val = 0; 2385 8348 Eric (void) sotpi_setsockopt(so, SOL_SOCKET, 2386 8348 Eric SO_DGRAM_ERRIND, &val, (t_uscalar_t)sizeof (val), 2387 8348 Eric cr); 2388 0 stevel 2389 0 stevel mutex_enter(&so->so_lock); 2390 0 stevel so_lock_single(so); /* Set SOLOCKED */ 2391 0 stevel goto done; 2392 0 stevel } 2393 0 stevel } 2394 0 stevel ASSERT(so->so_state & SS_ISBOUND); 2395 0 stevel 2396 0 stevel if (name == NULL || namelen == 0) { 2397 0 stevel error = EINVAL; 2398 0 stevel goto done; 2399 0 stevel } 2400 0 stevel /* 2401 8348 Eric * Mark the socket if sti_faddr_sa represents the transport level 2402 0 stevel * address. 2403 0 stevel */ 2404 0 stevel if (flags & _SOCONNECT_NOXLATE) { 2405 0 stevel struct sockaddr_ux *soaddr_ux; 2406 0 stevel 2407 0 stevel ASSERT(so->so_family == AF_UNIX); 2408 0 stevel if (namelen != sizeof (struct sockaddr_ux)) { 2409 0 stevel error = EINVAL; 2410 0 stevel goto done; 2411 0 stevel } 2412 0 stevel soaddr_ux = (struct sockaddr_ux *)name; 2413 0 stevel name = (struct sockaddr *)&soaddr_ux->sou_addr; 2414 0 stevel namelen = sizeof (soaddr_ux->sou_addr); 2415 8348 Eric sti->sti_faddr_noxlate = 1; 2416 0 stevel } 2417 0 stevel 2418 0 stevel /* 2419 0 stevel * Length and family checks. 2420 0 stevel */ 2421 0 stevel error = so_addr_verify(so, name, namelen); 2422 0 stevel if (error) 2423 0 stevel goto bad; 2424 0 stevel 2425 0 stevel /* 2426 0 stevel * Save foreign address. Needed for AF_UNIX as well as 2427 0 stevel * transport providers that do not support TI_GETPEERNAME. 2428 0 stevel * Also used for cached foreign address for TCP and UDP. 2429 0 stevel */ 2430 8348 Eric if (namelen > (t_uscalar_t)sti->sti_faddr_maxlen) { 2431 8348 Eric error = EINVAL; 2432 8348 Eric goto done; 2433 8348 Eric } 2434 8348 Eric sti->sti_faddr_len = (socklen_t)namelen; 2435 8348 Eric ASSERT(sti->sti_faddr_len <= sti->sti_faddr_maxlen); 2436 8348 Eric bcopy(name, sti->sti_faddr_sa, namelen); 2437 8348 Eric sti->sti_faddr_valid = 1; 2438 8348 Eric 2439 8348 Eric if (so->so_family == AF_UNIX) { 2440 8348 Eric if (sti->sti_faddr_noxlate) { 2441 0 stevel /* 2442 0 stevel * Already have a transport internal address. Do not 2443 0 stevel * pass any (transport internal) source address. 2444 0 stevel */ 2445 8348 Eric addr = sti->sti_faddr_sa; 2446 8348 Eric addrlen = (t_uscalar_t)sti->sti_faddr_len; 2447 0 stevel src = NULL; 2448 0 stevel srclen = 0; 2449 0 stevel } else { 2450 0 stevel /* 2451 0 stevel * Pass the sockaddr_un source address as an option 2452 0 stevel * and translate the remote address. 2453 8348 Eric * Holding so_lock thus sti_laddr_sa can not change. 2454 8348 Eric */ 2455 8348 Eric src = sti->sti_laddr_sa; 2456 8348 Eric srclen = (t_uscalar_t)sti->sti_laddr_len; 2457 0 stevel dprintso(so, 1, 2458 5240 nordmark ("sotpi_connect UNIX: srclen %d, src %p\n", 2459 5240 nordmark srclen, src)); 2460 0 stevel error = so_ux_addr_xlate(so, 2461 8348 Eric sti->sti_faddr_sa, (socklen_t)sti->sti_faddr_len, 2462 5240 nordmark (flags & _SOCONNECT_XPG4_2), 2463 5240 nordmark &addr, &addrlen); 2464 0 stevel if (error) 2465 0 stevel goto bad; 2466 0 stevel } 2467 0 stevel } else { 2468 8348 Eric addr = sti->sti_faddr_sa; 2469 8348 Eric addrlen = (t_uscalar_t)sti->sti_faddr_len; 2470 0 stevel src = NULL; 2471 0 stevel srclen = 0; 2472 0 stevel } 2473 0 stevel /* 2474 0 stevel * When connecting a datagram socket we issue the SO_DGRAM_ERRIND 2475 0 stevel * option which asks the transport provider to send T_UDERR_IND 2476 0 stevel * messages. These T_UDERR_IND messages are used to return connected 2477 0 stevel * style errors (e.g. ECONNRESET) for connected datagram sockets. 2478 0 stevel * 2479 0 stevel * In addition, for UDP (and SOCK_RAW AF_INET{,6} sockets) 2480 0 stevel * we send down a T_CONN_REQ. This is needed to let the 2481 0 stevel * transport assign a local address that is consistent with 2482 0 stevel * the remote address. Applications depend on a getsockname() 2483 0 stevel * after a connect() to retrieve the "source" IP address for 2484 0 stevel * the connected socket. Invalidate the cached local address 2485 0 stevel * to force getsockname() to enquire of the transport. 2486 0 stevel */ 2487 0 stevel if (!(so->so_mode & SM_CONNREQUIRED)) { 2488 0 stevel /* 2489 0 stevel * Datagram socket. 2490 0 stevel */ 2491 0 stevel int32_t val; 2492 0 stevel 2493 0 stevel so_unlock_single(so, SOLOCKED); 2494 0 stevel mutex_exit(&so->so_lock); 2495 0 stevel 2496 0 stevel val = 1; 2497 0 stevel (void) sotpi_setsockopt(so, SOL_SOCKET, SO_DGRAM_ERRIND, 2498 8348 Eric &val, (t_uscalar_t)sizeof (val), cr); 2499 0 stevel 2500 0 stevel mutex_enter(&so->so_lock); 2501 0 stevel so_lock_single(so); /* Set SOLOCKED */ 2502 0 stevel if ((so->so_family != AF_INET && so->so_family != AF_INET6) || 2503 0 stevel (so->so_type != SOCK_DGRAM && so->so_type != SOCK_RAW) || 2504 0 stevel soconnect_tpi_udp) { 2505 0 stevel soisconnected(so); 2506 0 stevel goto done; 2507 0 stevel } 2508 0 stevel /* 2509 0 stevel * Send down T_CONN_REQ etc. 2510 0 stevel * Clear fflag to avoid returning EWOULDBLOCK. 2511 0 stevel */ 2512 0 stevel fflag = 0; 2513 0 stevel ASSERT(so->so_family != AF_UNIX); 2514 8348 Eric sti->sti_laddr_valid = 0; 2515 8348 Eric } else if (sti->sti_laddr_len != 0) { 2516 0 stevel /* 2517 0 stevel * If the local address or port was "any" then it may be 2518 0 stevel * changed by the transport as a result of the 2519 0 stevel * connect. Invalidate the cached version if we have one. 2520 0 stevel */ 2521 0 stevel switch (so->so_family) { 2522 0 stevel case AF_INET: 2523 8348 Eric ASSERT(sti->sti_laddr_len == (socklen_t)sizeof (sin_t)); 2524 8348 Eric if (((sin_t *)sti->sti_laddr_sa)->sin_addr.s_addr == 2525 0 stevel INADDR_ANY || 2526 8348 Eric ((sin_t *)sti->sti_laddr_sa)->sin_port == 0) 2527 8348 Eric sti->sti_laddr_valid = 0; 2528 0 stevel break; 2529 0 stevel 2530 0 stevel case AF_INET6: 2531 8348 Eric ASSERT(sti->sti_laddr_len == 2532 8348 Eric (socklen_t)sizeof (sin6_t)); 2533 0 stevel if (IN6_IS_ADDR_UNSPECIFIED( 2534 8348 Eric &((sin6_t *)sti->sti_laddr_sa) ->sin6_addr) || 2535 0 stevel IN6_IS_ADDR_V4MAPPED_ANY( 2536 8348 Eric &((sin6_t *)sti->sti_laddr_sa)->sin6_addr) || 2537 8348 Eric ((sin6_t *)sti->sti_laddr_sa)->sin6_port == 0) 2538 8348 Eric sti->sti_laddr_valid = 0; 2539 0 stevel break; 2540 0 stevel 2541 0 stevel default: 2542 0 stevel break; 2543 0 stevel } 2544 0 stevel } 2545 0 stevel 2546 0 stevel /* 2547 0 stevel * Check for failure of an earlier call 2548 0 stevel */ 2549 0 stevel if (so->so_error != 0) 2550 0 stevel goto so_bad; 2551 0 stevel 2552 0 stevel /* 2553 0 stevel * Send down T_CONN_REQ. Message was allocated above. 2554 0 stevel */ 2555 0 stevel conn_req.PRIM_type = T_CONN_REQ; 2556 0 stevel conn_req.DEST_length = addrlen; 2557 0 stevel conn_req.DEST_offset = (t_scalar_t)sizeof (conn_req); 2558 0 stevel if (srclen == 0) { 2559 0 stevel conn_req.OPT_length = 0; 2560 0 stevel conn_req.OPT_offset = 0; 2561 0 stevel soappendmsg(mp, &conn_req, sizeof (conn_req)); 2562 0 stevel soappendmsg(mp, addr, addrlen); 2563 0 stevel } else { 2564 0 stevel /* 2565 0 stevel * There is a AF_UNIX sockaddr_un to include as a source 2566 0 stevel * address option. 2567 0 stevel */ 2568 0 stevel struct T_opthdr toh; 2569 0 stevel 2570 0 stevel toh.level = SOL_SOCKET; 2571 0 stevel toh.name = SO_SRCADDR; 2572 0 stevel toh.len = (t_uscalar_t)(srclen + sizeof (struct T_opthdr)); 2573 0 stevel toh.status = 0; 2574 0 stevel conn_req.OPT_length = 2575 5240 nordmark (t_scalar_t)(sizeof (toh) + _TPI_ALIGN_TOPT(srclen)); 2576 0 stevel conn_req.OPT_offset = (t_scalar_t)(sizeof (conn_req) + 2577 5240 nordmark _TPI_ALIGN_TOPT(addrlen)); 2578 0 stevel 2579 0 stevel soappendmsg(mp, &conn_req, sizeof (conn_req)); 2580 0 stevel soappendmsg(mp, addr, addrlen); 2581 0 stevel mp->b_wptr += _TPI_ALIGN_TOPT(addrlen) - addrlen; 2582 0 stevel soappendmsg(mp, &toh, sizeof (toh)); 2583 0 stevel soappendmsg(mp, src, srclen); 2584 0 stevel mp->b_wptr += _TPI_ALIGN_TOPT(srclen) - srclen; 2585 0 stevel ASSERT(mp->b_wptr <= mp->b_datap->db_lim); 2586 0 stevel } 2587 0 stevel /* 2588 0 stevel * Set SS_ISCONNECTING before sending down the T_CONN_REQ 2589 0 stevel * in order to have the right state when the T_CONN_CON shows up. 2590 0 stevel */ 2591 0 stevel soisconnecting(so); 2592 0 stevel mutex_exit(&so->so_lock); 2593 0 stevel 2594 0 stevel if (audit_active) 2595 0 stevel audit_sock(T_CONN_REQ, strvp2wq(SOTOV(so)), mp, 0); 2596 0 stevel 2597 0 stevel error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0, 2598 5240 nordmark MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0); 2599 0 stevel mp = NULL; 2600 0 stevel mutex_enter(&so->so_lock); 2601 0 stevel if (error != 0) 2602 0 stevel goto bad; 2603 0 stevel 2604 0 stevel if ((error = sowaitokack(so, T_CONN_REQ)) != 0) 2605 0 stevel goto bad; 2606 0 stevel 2607 0 stevel /* Allow other threads to access the socket */ 2608 0 stevel so_unlock_single(so, SOLOCKED); 2609 0 stevel need_unlock = B_FALSE; 2610 0 stevel 2611 0 stevel /* 2612 0 stevel * Wait until we get a T_CONN_CON or an error 2613 0 stevel */ 2614 0 stevel if ((error = sowaitconnected(so, fflag, 0)) != 0) { 2615 0 stevel so_lock_single(so); /* Set SOLOCKED */ 2616 0 stevel need_unlock = B_TRUE; 2617 0 stevel } 2618 0 stevel 2619 0 stevel done: 2620 0 stevel freemsg(mp); 2621 0 stevel switch (error) { 2622 0 stevel case EINPROGRESS: 2623 0 stevel case EALREADY: 2624 0 stevel case EISCONN: 2625 0 stevel case EINTR: 2626 0 stevel /* Non-fatal errors */ 2627 8348 Eric sti->sti_laddr_valid = 0; 2628 0 stevel /* FALLTHRU */ 2629 0 stevel case 0: 2630 0 stevel break; 2631 0 stevel default: 2632 0 stevel ASSERT(need_unlock); 2633 0 stevel /* 2634 0 stevel * Fatal errors: clear SS_ISCONNECTING in case it was set, 2635 0 stevel * and invalidate local-address cache 2636 0 stevel */ 2637 8348 Eric so->so_state &= ~SS_ISCONNECTING; 2638 8348 Eric sti->sti_laddr_valid = 0; 2639 0 stevel /* A discon_ind might have already unbound us */ 2640 0 stevel if ((flags & _SOCONNECT_DID_BIND) && 2641 0 stevel (so->so_state & SS_ISBOUND)) { 2642 0 stevel int err; 2643 0 stevel 2644 0 stevel err = sotpi_unbind(so, 0); 2645 0 stevel /* LINTED - statement has no conseq */ 2646 0 stevel if (err) { 2647 0 stevel eprintsoline(so, err); 2648 0 stevel } 2649 0 stevel } 2650 0 stevel break; 2651 0 stevel } 2652 0 stevel if (need_unlock) 2653 0 stevel so_unlock_single(so, SOLOCKED); 2654 0 stevel mutex_exit(&so->so_lock); 2655 0 stevel return (error); 2656 0 stevel 2657 8348 Eric so_bad: error = sogeterr(so, B_TRUE); 2658 0 stevel bad: eprintsoline(so, error); 2659 0 stevel goto done; 2660 0 stevel } 2661 0 stevel 2662 8348 Eric /* ARGSUSED */ 2663 8348 Eric int 2664 8348 Eric sotpi_shutdown(struct sonode *so, int how, struct cred *cr) 2665 0 stevel { 2666 0 stevel struct T_ordrel_req ordrel_req; 2667 0 stevel mblk_t *mp; 2668 0 stevel uint_t old_state, state_change; 2669 0 stevel int error = 0; 2670 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 2671 0 stevel 2672 0 stevel dprintso(so, 1, ("sotpi_shutdown(%p, %d) %s\n", 2673 7240 rh87107 (void *)so, how, pr_state(so->so_state, so->so_mode))); 2674 0 stevel 2675 0 stevel mutex_enter(&so->so_lock); 2676 0 stevel so_lock_single(so); /* Set SOLOCKED */ 2677 0 stevel 2678 0 stevel /* 2679 0 stevel * SunOS 4.X has no check for datagram sockets. 2680 0 stevel * 5.X checks that it is connected (ENOTCONN) 2681 0 stevel * X/Open requires that we check the connected state. 2682 0 stevel */ 2683 0 stevel if (!(so->so_state & SS_ISCONNECTED)) { 2684 0 stevel if (!xnet_skip_checks) { 2685 0 stevel error = ENOTCONN; 2686 0 stevel if (xnet_check_print) { 2687 0 stevel printf("sockfs: X/Open shutdown check " 2688 5240 nordmark "caused ENOTCONN\n"); 2689 0 stevel } 2690 0 stevel } 2691 0 stevel goto done; 2692 0 stevel } 2693 0 stevel /* 2694 0 stevel * Record the current state and then perform any state changes. 2695 0 stevel * Then use the difference between the old and new states to 2696 0 stevel * determine which messages need to be sent. 2697 0 stevel * This prevents e.g. duplicate T_ORDREL_REQ when there are 2698 0 stevel * duplicate calls to shutdown(). 2699 0 stevel */ 2700 0 stevel old_state = so->so_state; 2701 0 stevel 2702 0 stevel switch (how) { 2703 0 stevel case 0: 2704 0 stevel socantrcvmore(so); 2705 0 stevel break; 2706 0 stevel case 1: 2707 0 stevel socantsendmore(so); 2708 0 stevel break; 2709 0 stevel case 2: 2710 0 stevel socantsendmore(so); 2711 0 stevel socantrcvmore(so); 2712 0 stevel break; 2713 0 stevel default: 2714 0 stevel error = EINVAL; 2715 0 stevel goto done; 2716 0 stevel } 2717 0 stevel 2718 0 stevel /* 2719 0 stevel * Assumes that the SS_CANT* flags are never cleared in the above code. 2720 0 stevel */ 2721 0 stevel state_change = (so->so_state & (SS_CANTRCVMORE|SS_CANTSENDMORE)) - 2722 5240 nordmark (old_state & (SS_CANTRCVMORE|SS_CANTSENDMORE)); 2723 0 stevel ASSERT((state_change & ~(SS_CANTRCVMORE|SS_CANTSENDMORE)) == 0); 2724 0 stevel 2725 0 stevel switch (state_change) { 2726 0 stevel case 0: 2727 0 stevel dprintso(so, 1, 2728 0 stevel ("sotpi_shutdown: nothing to send in state 0x%x\n", 2729 0 stevel so->so_state)); 2730 0 stevel goto done; 2731 0 stevel 2732 0 stevel case SS_CANTRCVMORE: 2733 0 stevel mutex_exit(&so->so_lock); 2734 0 stevel strseteof(SOTOV(so), 1); 2735 0 stevel /* 2736 0 stevel * strseteof takes care of read side wakeups, 2737 0 stevel * pollwakeups, and signals. 2738 0 stevel */ 2739 0 stevel /* 2740 0 stevel * Get the read lock before flushing data to avoid problems 2741 0 stevel * with the T_EXDATA_IND MSG_PEEK code in sotpi_recvmsg. 2742 0 stevel */ 2743 0 stevel mutex_enter(&so->so_lock); 2744 0 stevel (void) so_lock_read(so, 0); /* Set SOREADLOCKED */ 2745 0 stevel mutex_exit(&so->so_lock); 2746 0 stevel 2747 0 stevel /* Flush read side queue */ 2748 0 stevel strflushrq(SOTOV(so), FLUSHALL); 2749 0 stevel 2750 0 stevel mutex_enter(&so->so_lock); 2751 0 stevel so_unlock_read(so); /* Clear SOREADLOCKED */ 2752 0 stevel break; 2753 0 stevel 2754 0 stevel case SS_CANTSENDMORE: 2755 0 stevel mutex_exit(&so->so_lock); 2756 0 stevel strsetwerror(SOTOV(so), 0, 0, sogetwrerr); 2757 0 stevel mutex_enter(&so->so_lock); 2758 0 stevel break; 2759 0 stevel 2760 0 stevel case SS_CANTSENDMORE|SS_CANTRCVMORE: 2761 0 stevel mutex_exit(&so->so_lock); 2762 0 stevel strsetwerror(SOTOV(so), 0, 0, sogetwrerr); 2763 0 stevel strseteof(SOTOV(so), 1); 2764 0 stevel /* 2765 0 stevel * strseteof takes care of read side wakeups, 2766 0 stevel * pollwakeups, and signals. 2767 0 stevel */ 2768 0 stevel /* 2769 0 stevel * Get the read lock before flushing data to avoid problems 2770 0 stevel * with the T_EXDATA_IND MSG_PEEK code in sotpi_recvmsg. 2771 0 stevel */ 2772 0 stevel mutex_enter(&so->so_lock); 2773 0 stevel (void) so_lock_read(so, 0); /* Set SOREADLOCKED */ 2774 0 stevel mutex_exit(&so->so_lock); 2775 0 stevel 2776 0 stevel /* Flush read side queue */ 2777 0 stevel strflushrq(SOTOV(so), FLUSHALL); 2778 0 stevel 2779 0 stevel mutex_enter(&so->so_lock); 2780 0 stevel so_unlock_read(so); /* Clear SOREADLOCKED */ 2781 0 stevel break; 2782 0 stevel } 2783 0 stevel 2784 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 2785 0 stevel 2786 0 stevel /* 2787 0 stevel * If either SS_CANTSENDMORE or SS_CANTRCVMORE or both of them 2788 0 stevel * was set due to this call and the new state has both of them set: 2789 0 stevel * Send the AF_UNIX close indication 2790 0 stevel * For T_COTS send a discon_ind 2791 0 stevel * 2792 0 stevel * If cantsend was set due to this call: 2793 0 stevel * For T_COTSORD send an ordrel_ind 2794 0 stevel * 2795 0 stevel * Note that for T_CLTS there is no message sent here. 2796 0 stevel */ 2797 0 stevel if ((so->so_state & (SS_CANTRCVMORE|SS_CANTSENDMORE)) == 2798 0 stevel (SS_CANTRCVMORE|SS_CANTSENDMORE)) { 2799 0 stevel /* 2800 0 stevel * For SunOS 4.X compatibility we tell the other end 2801 0 stevel * that we are unable to receive at this point. 2802 0 stevel */ 2803 8348 Eric if (so->so_family == AF_UNIX && sti->sti_serv_type != T_CLTS) 2804 0 stevel so_unix_close(so); 2805 0 stevel 2806 8348 Eric if (sti->sti_serv_type == T_COTS) 2807 0 stevel error = sodisconnect(so, -1, _SODISCONNECT_LOCK_HELD); 2808 0 stevel } 2809 0 stevel if ((state_change & SS_CANTSENDMORE) && 2810 8348 Eric (sti->sti_serv_type == T_COTS_ORD)) { 2811 0 stevel /* Send an orderly release */ 2812 0 stevel ordrel_req.PRIM_type = T_ORDREL_REQ; 2813 0 stevel 2814 0 stevel mutex_exit(&so->so_lock); 2815 0 stevel mp = soallocproto1(&ordrel_req, sizeof (ordrel_req), 2816 8778 Erik 0, _ALLOC_SLEEP, cr); 2817 0 stevel /* 2818 0 stevel * Send down the T_ORDREL_REQ even if there is flow control. 2819 0 stevel * This prevents shutdown from blocking. 2820 0 stevel * Note that there is no T_OK_ACK for ordrel_req. 2821 0 stevel */ 2822 0 stevel error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0, 2823 5240 nordmark MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR|MSG_IGNFLOW, 0); 2824 0 stevel mutex_enter(&so->so_lock); 2825 0 stevel if (error) { 2826 0 stevel eprintsoline(so, error); 2827 0 stevel goto done; 2828 0 stevel } 2829 0 stevel } 2830 0 stevel 2831 0 stevel done: 2832 0 stevel so_unlock_single(so, SOLOCKED); 2833 0 stevel mutex_exit(&so->so_lock); 2834 0 stevel return (error); 2835 0 stevel } 2836 0 stevel 2837 0 stevel /* 2838 0 stevel * For any connected SOCK_STREAM/SOCK_SEQPACKET AF_UNIX socket we send 2839 0 stevel * a zero-length T_OPTDATA_REQ with the SO_UNIX_CLOSE option to inform the peer 2840 0 stevel * that we have closed. 2841 0 stevel * Also, for connected AF_UNIX SOCK_DGRAM sockets we send a zero-length 2842 0 stevel * T_UNITDATA_REQ containing the same option. 2843 0 stevel * 2844 0 stevel * For SOCK_DGRAM half-connections (somebody connected to this end 2845 0 stevel * but this end is not connect) we don't know where to send any 2846 0 stevel * SO_UNIX_CLOSE. 2847 0 stevel * 2848 0 stevel * We have to ignore stream head errors just in case there has been 2849 0 stevel * a shutdown(output). 2850 0 stevel * Ignore any flow control to try to get the message more quickly to the peer. 2851 0 stevel * While locally ignoring flow control solves the problem when there 2852 0 stevel * is only the loopback transport on the stream it would not provide 2853 0 stevel * the correct AF_UNIX socket semantics when one or more modules have 2854 0 stevel * been pushed. 2855 0 stevel */ 2856 0 stevel void 2857 0 stevel so_unix_close(struct sonode *so) 2858 0 stevel { 2859 0 stevel int error; 2860 0 stevel struct T_opthdr toh; 2861 0 stevel mblk_t *mp; 2862 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 2863 0 stevel 2864 0 stevel ASSERT(MUTEX_HELD(&so->so_lock)); 2865 0 stevel 2866 0 stevel ASSERT(so->so_family == AF_UNIX); 2867 0 stevel 2868 0 stevel if ((so->so_state & (SS_ISCONNECTED|SS_ISBOUND)) != 2869 0 stevel (SS_ISCONNECTED|SS_ISBOUND)) 2870 0 stevel return; 2871 0 stevel 2872 0 stevel dprintso(so, 1, ("so_unix_close(%p) %s\n", 2873 7240 rh87107 (void *)so, pr_state(so->so_state, so->so_mode))); 2874 0 stevel 2875 0 stevel toh.level = SOL_SOCKET; 2876 0 stevel toh.name = SO_UNIX_CLOSE; 2877 0 stevel 2878 0 stevel /* zero length + header */ 2879 0 stevel toh.len = (t_uscalar_t)sizeof (struct T_opthdr); 2880 0 stevel toh.status = 0; 2881 0 stevel 2882 0 stevel if (so->so_type == SOCK_STREAM || so->so_type == SOCK_SEQPACKET) { 2883 0 stevel struct T_optdata_req tdr; 2884 0 stevel 2885 0 stevel tdr.PRIM_type = T_OPTDATA_REQ; 2886 0 stevel tdr.DATA_flag = 0; 2887 0 stevel 2888 0 stevel tdr.OPT_length = (t_scalar_t)sizeof (toh); 2889 0 stevel tdr.OPT_offset = (t_scalar_t)sizeof (tdr); 2890 0 stevel 2891 0 stevel /* NOTE: holding so_lock while sleeping */ 2892 0 stevel mp = soallocproto2(&tdr, sizeof (tdr), 2893 8778 Erik &toh, sizeof (toh), 0, _ALLOC_SLEEP, CRED()); 2894 0 stevel } else { 2895 0 stevel struct T_unitdata_req tudr; 2896 0 stevel void *addr; 2897 0 stevel socklen_t addrlen; 2898 0 stevel void *src; 2899 0 stevel socklen_t srclen; 2900 0 stevel struct T_opthdr toh2; 2901 0 stevel t_scalar_t size; 2902 0 stevel 2903 0 stevel /* Connecteded DGRAM socket */ 2904 0 stevel 2905 0 stevel /* 2906 0 stevel * For AF_UNIX the destination address is translated to 2907 0 stevel * an internal name and the source address is passed as 2908 0 stevel * an option. 2909 0 stevel */ 2910 0 stevel /* 2911 0 stevel * Length and family checks. 2912 0 stevel */ 2913 8348 Eric error = so_addr_verify(so, sti->sti_faddr_sa, 2914 8348 Eric (t_uscalar_t)sti->sti_faddr_len); 2915 0 stevel if (error) { 2916 0 stevel eprintsoline(so, error); 2917 0 stevel return; 2918 0 stevel } 2919 8348 Eric if (sti->sti_faddr_noxlate) { 2920 0 stevel /* 2921 0 stevel * Already have a transport internal address. Do not 2922 0 stevel * pass any (transport internal) source address. 2923 0 stevel */ 2924 8348 Eric addr = sti->sti_faddr_sa; 2925 8348 Eric addrlen = (t_uscalar_t)sti->sti_faddr_len; 2926 0 stevel src = NULL; 2927 0 stevel srclen = 0; 2928 0 stevel } else { 2929 0 stevel /* 2930 0 stevel * Pass the sockaddr_un source address as an option 2931 0 stevel * and translate the remote address. 2932 8348 Eric * Holding so_lock thus sti_laddr_sa can not change. 2933 8348 Eric */ 2934 8348 Eric src = sti->sti_laddr_sa; 2935 8348 Eric srclen = (socklen_t)sti->sti_laddr_len; 2936 0 stevel dprintso(so, 1, 2937 5240 nordmark ("so_ux_close: srclen %d, src %p\n", 2938 5240 nordmark srclen, src)); 2939 0 stevel error = so_ux_addr_xlate(so, 2940 8348 Eric sti->sti_faddr_sa, 2941 8348 Eric (socklen_t)sti->sti_faddr_len, 0, 2942 5240 nordmark &addr, &addrlen); 2943 0 stevel if (error) { 2944 0 stevel eprintsoline(so, error); 2945 0 stevel return; 2946 0 stevel } 2947 0 stevel } 2948 0 stevel tudr.PRIM_type = T_UNITDATA_REQ; 2949 0 stevel tudr.DEST_length = addrlen; 2950 0 stevel tudr.DEST_offset = (t_scalar_t)sizeof (tudr); 2951 0 stevel if (srclen == 0) { 2952 0 stevel tudr.OPT_length = (t_scalar_t)sizeof (toh); 2953 0 stevel tudr.OPT_offset = (t_scalar_t)(sizeof (tudr) + 2954 5240 nordmark _TPI_ALIGN_TOPT(addrlen)); 2955 0 stevel 2956 0 stevel size = tudr.OPT_offset + tudr.OPT_length; 2957 0 stevel /* NOTE: holding so_lock while sleeping */ 2958 0 stevel mp = soallocproto2(&tudr, sizeof (tudr), 2959 8778 Erik addr, addrlen, size, _ALLOC_SLEEP, CRED()); 2960 0 stevel mp->b_wptr += (_TPI_ALIGN_TOPT(addrlen) - addrlen); 2961 0 stevel soappendmsg(mp, &toh, sizeof (toh)); 2962 0 stevel } else { 2963 0 stevel /* 2964 0 stevel * There is a AF_UNIX sockaddr_un to include as a 2965 0 stevel * source address option. 2966 0 stevel */ 2967 0 stevel tudr.OPT_length = (t_scalar_t)(2 * sizeof (toh) + 2968 0 stevel _TPI_ALIGN_TOPT(srclen)); 2969 0 stevel tudr.OPT_offset = (t_scalar_t)(sizeof (tudr) + 2970 0 stevel _TPI_ALIGN_TOPT(addrlen)); 2971 0 stevel 2972 0 stevel toh2.level = SOL_SOCKET; 2973 0 stevel toh2.name = SO_SRCADDR; 2974 0 stevel toh2.len = (t_uscalar_t)(srclen + 2975 5240 nordmark sizeof (struct T_opthdr)); 2976 0 stevel toh2.status = 0; 2977 0 stevel 2978 0 stevel size = tudr.OPT_offset + tudr.OPT_length; 2979 0 stevel 2980 0 stevel /* NOTE: holding so_lock while sleeping */ 2981 0 stevel mp = soallocproto2(&tudr, sizeof (tudr), 2982 8778 Erik addr, addrlen, size, _ALLOC_SLEEP, CRED()); 2983 0 stevel mp->b_wptr += _TPI_ALIGN_TOPT(addrlen) - addrlen; 2984 0 stevel soappendmsg(mp, &toh, sizeof (toh)); 2985 0 stevel soappendmsg(mp, &toh2, sizeof (toh2)); 2986 0 stevel soappendmsg(mp, src, srclen); 2987 0 stevel mp->b_wptr += _TPI_ALIGN_TOPT(srclen) - srclen; 2988 0 stevel } 2989 0 stevel ASSERT(mp->b_wptr <= mp->b_datap->db_lim); 2990 0 stevel } 2991 0 stevel mutex_exit(&so->so_lock); 2992 0 stevel error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0, 2993 5240 nordmark MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR|MSG_IGNFLOW, 0); 2994 0 stevel mutex_enter(&so->so_lock); 2995 0 stevel } 2996 0 stevel 2997 0 stevel /* 2998 0 stevel * Called by sotpi_recvmsg when reading a non-zero amount of data. 2999 0 stevel * In addition, the caller typically verifies that there is some 3000 0 stevel * potential state to clear by checking 3001 0 stevel * if (so->so_state & (SS_OOBPEND|SS_HAVEOOBDATA|SS_RCVATMARK)) 3002 0 stevel * before calling this routine. 3003 0 stevel * Note that such a check can be made without holding so_lock since 3004 0 stevel * sotpi_recvmsg is single-threaded (using SOREADLOCKED) and only sotpi_recvmsg 3005 8348 Eric * decrements sti_oobsigcnt. 3006 0 stevel * 3007 0 stevel * When data is read *after* the point that all pending 3008 0 stevel * oob data has been consumed the oob indication is cleared. 3009 0 stevel * 3010 0 stevel * This logic keeps select/poll returning POLLRDBAND and 3011 0 stevel * SIOCATMARK returning true until we have read past 3012 0 stevel * the mark. 3013 0 stevel */ 3014 0 stevel static void 3015 0 stevel sorecv_update_oobstate(struct sonode *so) 3016 0 stevel { 3017 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 3018 8348 Eric 3019 0 stevel mutex_enter(&so->so_lock); 3020 0 stevel ASSERT(so_verify_oobstate(so)); 3021 0 stevel dprintso(so, 1, 3022 5240 nordmark ("sorecv_update_oobstate: counts %d/%d state %s\n", 3023 8348 Eric sti->sti_oobsigcnt, 3024 8348 Eric sti->sti_oobcnt, pr_state(so->so_state, so->so_mode))); 3025 8348 Eric if (sti->sti_oobsigcnt == 0) { 3026 0 stevel /* No more pending oob indications */ 3027 0 stevel so->so_state &= ~(SS_OOBPEND|SS_HAVEOOBDATA|SS_RCVATMARK); 3028 0 stevel freemsg(so->so_oobmsg); 3029 0 stevel so->so_oobmsg = NULL; 3030 0 stevel } 3031 0 stevel ASSERT(so_verify_oobstate(so)); 3032 0 stevel mutex_exit(&so->so_lock); 3033 0 stevel } 3034 0 stevel 3035 0 stevel /* 3036 0 stevel * Handle recv* calls for an so which has NL7C saved recv mblk_t(s). 3037 0 stevel */ 3038 0 stevel static int 3039 0 stevel nl7c_sorecv(struct sonode *so, mblk_t **rmp, uio_t *uiop, rval_t *rp) 3040 0 stevel { 3041 8348 Eric sotpi_info_t *sti = SOTOTPI(so); 3042 0 stevel int error = 0; 3043 0 stevel mblk_t *tmp = NULL; 3044 0 stevel mblk_t *pmp = NULL; 3045 8348 Eric mblk_t *nmp = sti->sti_nl7c_rcv_mp; 3046 0 stevel 3047 0 stevel ASSERT(nmp != NULL); 3048 0 stevel 3049 0 stevel while (nmp != NULL && uiop->uio_resid > 0) { 3050 0 stevel ssize_t n; 3051 0 stevel 3052 0 stevel if (DB_TYPE(nmp) == M_DATA) { 3053 0 stevel /* 3054 0 stevel * We have some data, uiomove up to resid bytes. 3055 0 stevel */ 3056 0 stevel n = MIN(MBLKL(nmp), uiop->uio_resid); 3057 0 stevel if (n > 0) 3058 0 stevel error = uiomove(nmp->b_rptr, n, UIO_READ, uiop); 3059 0 stevel nmp->b_rptr += n; 3060 0 stevel if (nmp->b_rptr == nmp->b_wptr) { 3061 0 stevel pmp = nmp; 3062 0 stevel nmp = nmp->b_cont; 3063 0 stevel } 3064 1974 brutus if (error) 3065 1974 brutus break; 3066 0 stevel } else { 3067 0 stevel /* 3068 0 stevel * We only handle data, save for caller to handle. 3069 0 stevel */ 3070 0 stevel if (pmp != NULL) { 3071 0 stevel pmp->b_cont = nmp->b_cont; 3072 0 stevel } 3073 0 stevel nmp->b_cont = NULL; 3074 0 stevel if (*rmp == NULL) { 3075 0 stevel *rmp = nmp; 3076 0 stevel } else { 3077 1974 brutus tmp->b_cont = nmp; 3078 0 stevel } 3079 0 stevel nmp = nmp->b_cont; 3080 0 stevel tmp = nmp; 3081 0 stevel } 3082 0 stevel } 3083 0 stevel if (pmp != NULL) { 3084 0 stevel /* Free any mblk_t(s) which we have consumed */ 3085 0 stevel pmp->b_cont = NULL; 3086 8348 Eric freemsg(sti->sti_nl7c_rcv_mp); 3087 8348 Eric } 3088 8348 Eric if ((sti->sti_nl7c_rcv_mp = nmp) == NULL) { 3089 1974 brutus /* Last mblk_t so return the saved kstrgetmsg() rval/error */ 3090 1974 brutus if (error == 0) { 3091 8348 Eric rval_t *p = (rval_t *)&sti->sti_nl7c_rcv_rval; 3092 1974 brutus 3093 1974 brutus error = p->r_v.r_v2; 3094 1974 brutus p->r_v.r_v2 = 0; 3095 1974 brutus } 3096 8348 Eric rp->r_vals = sti->sti_nl7c_rcv_rval; 3097 8348 Eric sti->sti_nl7c_rcv_rval = 0; 3098 0 stevel } else { 3099 0 stevel /* More mblk_t(s) to process so no rval to return */ 3100 0 stevel rp->r_vals =