6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015, Joyent, Inc.
25 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
26 */
27
28 #include <sys/types.h>
29 #include <sys/t_lock.h>
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/buf.h>
33 #include <sys/conf.h>
34 #include <sys/cred.h>
35 #include <sys/kmem.h>
36 #include <sys/kmem_impl.h>
37 #include <sys/sysmacros.h>
38 #include <sys/vfs.h>
39 #include <sys/vnode.h>
40 #include <sys/debug.h>
41 #include <sys/errno.h>
42 #include <sys/time.h>
43 #include <sys/file.h>
44 #include <sys/open.h>
45 #include <sys/user.h>
244 sonodeops_t sotpi_sonodeops = {
245 sotpi_init, /* sop_init */
246 sotpi_accept, /* sop_accept */
247 sotpi_bind, /* sop_bind */
248 sotpi_listen, /* sop_listen */
249 sotpi_connect, /* sop_connect */
250 sotpi_recvmsg, /* sop_recvmsg */
251 sotpi_sendmsg, /* sop_sendmsg */
252 sotpi_sendmblk, /* sop_sendmblk */
253 sotpi_getpeername, /* sop_getpeername */
254 sotpi_getsockname, /* sop_getsockname */
255 sotpi_shutdown, /* sop_shutdown */
256 sotpi_getsockopt, /* sop_getsockopt */
257 sotpi_setsockopt, /* sop_setsockopt */
258 sotpi_ioctl, /* sop_ioctl */
259 sotpi_poll, /* sop_poll */
260 sotpi_close, /* sop_close */
261 };
262
263 /*
264 * Return a TPI socket vnode.
265 *
266 * Note that sockets assume that the driver will clone (either itself
267 * or by using the clone driver) i.e. a socket() call will always
268 * result in a new vnode being created.
269 */
270
271 /*
272 * Common create code for socket and accept. If tso is set the values
273 * from that node is used instead of issuing a T_INFO_REQ.
274 */
275
276 /* ARGSUSED */
277 static struct sonode *
278 sotpi_create(struct sockparams *sp, int family, int type, int protocol,
279 int version, int sflags, int *errorp, cred_t *cr)
280 {
281 struct sonode *so;
282 kmem_cache_t *cp;
283 int sfamily = family;
986 if (error) {
987 if (error == EEXIST)
988 error = EADDRINUSE;
989 eprintsoline(so, error);
990 goto done;
991 }
992 /*
993 * Establish pointer from the underlying filesystem
994 * vnode to the socket node.
995 * sti_ux_bound_vp and v_stream->sd_vnode form the
996 * cross-linkage between the underlying filesystem
997 * node and the socket node.
998 */
999
1000 if ((VOP_REALVP(vp, &rvp, NULL) == 0) && (vp != rvp)) {
1001 VN_HOLD(rvp);
1002 VN_RELE(vp);
1003 vp = rvp;
1004 }
1005
1006 ASSERT(SOTOV(so)->v_stream);
1007 mutex_enter(&vp->v_lock);
1008 vp->v_stream = SOTOV(so)->v_stream;
1009 sti->sti_ux_bound_vp = vp;
1010 mutex_exit(&vp->v_lock);
1011
1012 /*
1013 * Use the vnode pointer value as a unique address
1014 * (together with the magic number to avoid conflicts
1015 * with implicit binds) in the transport provider.
1016 */
1017 sti->sti_ux_laddr.soua_vp =
1018 (void *)sti->sti_ux_bound_vp;
1019 sti->sti_ux_laddr.soua_magic = SOU_MAGIC_EXPLICIT;
1020 addr = &sti->sti_ux_laddr;
1021 addrlen = (t_uscalar_t)sizeof (sti->sti_ux_laddr);
1022 dprintso(so, 1, ("sobind UNIX: addrlen %d, addr %p\n",
1023 addrlen,
1024 (void *)((struct so_ux_addr *)addr)->soua_vp));
1025 break;
1026 }
4951 return (strwrite_common(SOTOV(so), uiop, cr, wflag));
4952 }
4953 }
4954 return (0);
4955 }
4956
4957 /*
4958 * Update sti_faddr by asking the transport (unless AF_UNIX).
4959 */
4960 /* ARGSUSED */
4961 int
4962 sotpi_getpeername(struct sonode *so, struct sockaddr *name, socklen_t *namelen,
4963 boolean_t accept, struct cred *cr)
4964 {
4965 struct strbuf strbuf;
4966 int error = 0, res;
4967 void *addr;
4968 t_uscalar_t addrlen;
4969 k_sigset_t smask;
4970 sotpi_info_t *sti = SOTOTPI(so);
4971
4972 dprintso(so, 1, ("sotpi_getpeername(%p) %s\n",
4973 (void *)so, pr_state(so->so_state, so->so_mode)));
4974
4975 ASSERT(*namelen > 0);
4976 mutex_enter(&so->so_lock);
4977 so_lock_single(so); /* Set SOLOCKED */
4978
4979 if (accept) {
4980 bcopy(sti->sti_faddr_sa, name,
4981 MIN(*namelen, sti->sti_faddr_len));
4982 *namelen = sti->sti_faddr_noxlate ? 0: sti->sti_faddr_len;
4983 goto done;
4984 }
4985
4986 if (!(so->so_state & SS_ISCONNECTED)) {
4987 error = ENOTCONN;
4988 goto done;
4989 }
4990 /* Added this check for X/Open */
4991 if ((so->so_state & SS_CANTSENDMORE) && !xnet_skip_checks) {
4992 error = EINVAL;
4993 if (xnet_check_print) {
4994 printf("sockfs: X/Open getpeername check => EINVAL\n");
4995 }
4996 goto done;
4997 }
5022 ASSERT(sti->sti_faddr_sa);
5023 /* Allocate local buffer to use with ioctl */
5024 addrlen = (t_uscalar_t)sti->sti_faddr_maxlen;
5025 mutex_exit(&so->so_lock);
5026 addr = kmem_alloc(addrlen, KM_SLEEP);
5027
5028 /*
5029 * Issue TI_GETPEERNAME with signals masked.
5030 * Put the result in sti_faddr_sa so that getpeername works after
5031 * a shutdown(output).
5032 * If the ioctl fails (e.g. due to a ECONNRESET) the error is reposted
5033 * back to the socket.
5034 */
5035 strbuf.buf = addr;
5036 strbuf.maxlen = addrlen;
5037 strbuf.len = 0;
5038
5039 sigintr(&smask, 0);
5040 res = 0;
5041 ASSERT(cr);
5042 error = strioctl(SOTOV(so), TI_GETPEERNAME, (intptr_t)&strbuf,
5043 0, K_TO_K, cr, &res);
5044 sigunintr(&smask);
5045
5046 mutex_enter(&so->so_lock);
5047 /*
5048 * If there is an error record the error in so_error put don't fail
5049 * the getpeername. Instead fallback on the recorded
5050 * sti->sti_faddr_sa.
5051 */
5052 if (error) {
5053 /*
5054 * Various stream head errors can be returned to the ioctl.
5055 * However, it is impossible to determine which ones of
5056 * these are really socket level errors that were incorrectly
5057 * consumed by the ioctl. Thus this code silently ignores the
5058 * error - to code explicitly does not reinstate the error
5059 * using soseterror().
5060 * Experiments have shows that at least this set of
5061 * errors are reported and should not be reinstated on the
5062 * socket:
5087 #endif /* DEBUG */
5088 done:
5089 so_unlock_single(so, SOLOCKED);
5090 mutex_exit(&so->so_lock);
5091 return (error);
5092 }
5093
5094 /*
5095 * Update sti_laddr by asking the transport (unless AF_UNIX).
5096 */
5097 int
5098 sotpi_getsockname(struct sonode *so, struct sockaddr *name, socklen_t *namelen,
5099 struct cred *cr)
5100 {
5101 struct strbuf strbuf;
5102 int error = 0, res;
5103 void *addr;
5104 t_uscalar_t addrlen;
5105 k_sigset_t smask;
5106 sotpi_info_t *sti = SOTOTPI(so);
5107
5108 dprintso(so, 1, ("sotpi_getsockname(%p) %s\n",
5109 (void *)so, pr_state(so->so_state, so->so_mode)));
5110
5111 ASSERT(*namelen > 0);
5112 mutex_enter(&so->so_lock);
5113 so_lock_single(so); /* Set SOLOCKED */
5114
5115 #ifdef DEBUG
5116
5117 dprintso(so, 1, ("sotpi_getsockname (local): %s\n",
5118 pr_addr(so->so_family, sti->sti_laddr_sa,
5119 (t_uscalar_t)sti->sti_laddr_len)));
5120 #endif /* DEBUG */
5121 if (sti->sti_laddr_valid) {
5122 bcopy(sti->sti_laddr_sa, name,
5123 MIN(*namelen, sti->sti_laddr_len));
5124 *namelen = sti->sti_laddr_len;
5125 goto done;
5126 }
5127
5128 if (so->so_family == AF_UNIX) {
5129 /*
5130 * Transport has different name space - return local info. If we
5131 * have enough space, let consumers know the family.
5132 */
5133 if (*namelen >= sizeof (sa_family_t)) {
5147
5148 /* Allocate local buffer to use with ioctl */
5149 addrlen = (t_uscalar_t)sti->sti_laddr_maxlen;
5150 mutex_exit(&so->so_lock);
5151 addr = kmem_alloc(addrlen, KM_SLEEP);
5152
5153 /*
5154 * Issue TI_GETMYNAME with signals masked.
5155 * Put the result in sti_laddr_sa so that getsockname works after
5156 * a shutdown(output).
5157 * If the ioctl fails (e.g. due to a ECONNRESET) the error is reposted
5158 * back to the socket.
5159 */
5160 strbuf.buf = addr;
5161 strbuf.maxlen = addrlen;
5162 strbuf.len = 0;
5163
5164 sigintr(&smask, 0);
5165 res = 0;
5166 ASSERT(cr);
5167 error = strioctl(SOTOV(so), TI_GETMYNAME, (intptr_t)&strbuf,
5168 0, K_TO_K, cr, &res);
5169 sigunintr(&smask);
5170
5171 mutex_enter(&so->so_lock);
5172 /*
5173 * If there is an error record the error in so_error put don't fail
5174 * the getsockname. Instead fallback on the recorded
5175 * sti->sti_laddr_sa.
5176 */
5177 if (error) {
5178 /*
5179 * Various stream head errors can be returned to the ioctl.
5180 * However, it is impossible to determine which ones of
5181 * these are really socket level errors that were incorrectly
5182 * consumed by the ioctl. Thus this code silently ignores the
5183 * error - to code explicitly does not reinstate the error
5184 * using soseterror().
5185 * Experiments have shows that at least this set of
5186 * errors are reported and should not be reinstated on the
5187 * socket:
5221 * On the return most *optlenp bytes are copied to optval.
5222 */
5223 /* ARGSUSED */
5224 int
5225 sotpi_getsockopt(struct sonode *so, int level, int option_name,
5226 void *optval, socklen_t *optlenp, int flags, struct cred *cr)
5227 {
5228 struct T_optmgmt_req optmgmt_req;
5229 struct T_optmgmt_ack *optmgmt_ack;
5230 struct opthdr oh;
5231 struct opthdr *opt_res;
5232 mblk_t *mp = NULL;
5233 int error = 0;
5234 void *option = NULL; /* Set if fallback value */
5235 t_uscalar_t maxlen = *optlenp;
5236 t_uscalar_t len;
5237 uint32_t value;
5238 struct timeval tmo_val; /* used for SO_RCVTIMEO, SO_SNDTIMEO */
5239 struct timeval32 tmo_val32;
5240 struct so_snd_bufinfo snd_bufinfo; /* used for zero copy */
5241
5242 dprintso(so, 1, ("sotpi_getsockopt(%p, 0x%x, 0x%x, %p, %p) %s\n",
5243 (void *)so, level, option_name, optval, (void *)optlenp,
5244 pr_state(so->so_state, so->so_mode)));
5245
5246 mutex_enter(&so->so_lock);
5247 so_lock_single(so); /* Set SOLOCKED */
5248
5249 /*
5250 * Check for SOL_SOCKET options.
5251 * Certain SOL_SOCKET options are returned directly whereas
5252 * others only provide a default (fallback) value should
5253 * the T_SVR4_OPTMGMT_REQ fail.
5254 */
5255 if (level == SOL_SOCKET) {
5256 /* Check parameters */
5257 switch (option_name) {
5258 case SO_TYPE:
5259 case SO_ERROR:
5260 case SO_DEBUG:
5261 case SO_ACCEPTCONN:
5262 case SO_REUSEADDR:
5263 case SO_KEEPALIVE:
5264 case SO_DONTROUTE:
5265 case SO_BROADCAST:
5266 case SO_USELOOPBACK:
5267 case SO_OOBINLINE:
5372 /*
5373 * The following options are only returned by sockfs when the
5374 * T_SVR4_OPTMGMT_REQ fails.
5375 */
5376 case SO_LINGER:
5377 option = &so->so_linger;
5378 len = (t_uscalar_t)sizeof (struct linger);
5379 break;
5380 case SO_SNDBUF: {
5381 ssize_t lvalue;
5382
5383 /*
5384 * If the option has not been set then get a default
5385 * value from the read queue. This value is
5386 * returned if the transport fails
5387 * the T_SVR4_OPTMGMT_REQ.
5388 */
5389 lvalue = so->so_sndbuf;
5390 if (lvalue == 0) {
5391 mutex_exit(&so->so_lock);
5392 (void) strqget(strvp2wq(SOTOV(so))->q_next,
5393 QHIWAT, 0, &lvalue);
5394 mutex_enter(&so->so_lock);
5395 dprintso(so, 1,
5396 ("got SO_SNDBUF %ld from q\n", lvalue));
5397 }
5398 value = (int)lvalue;
5399 option = &value;
5400 len = (t_uscalar_t)sizeof (so->so_sndbuf);
5401 break;
5402 }
5403 case SO_RCVBUF: {
5404 ssize_t lvalue;
5405
5406 /*
5407 * If the option has not been set then get a default
5408 * value from the read queue. This value is
5409 * returned if the transport fails
5410 * the T_SVR4_OPTMGMT_REQ.
5411 *
5412 * XXX If SO_RCVBUF has been set and this is an
5413 * XPG 4.2 application then do not ask the transport
5414 * since the transport might adjust the value and not
5415 * return exactly what was set by the application.
5416 * For non-XPG 4.2 application we return the value
5417 * that the transport is actually using.
5418 */
5419 lvalue = so->so_rcvbuf;
5420 if (lvalue == 0) {
5421 mutex_exit(&so->so_lock);
5422 (void) strqget(RD(strvp2wq(SOTOV(so))),
5423 QHIWAT, 0, &lvalue);
5424 mutex_enter(&so->so_lock);
5425 dprintso(so, 1,
5426 ("got SO_RCVBUF %ld from q\n", lvalue));
5427 } else if (flags & _SOGETSOCKOPT_XPG4_2) {
5428 value = (int)lvalue;
5429 option = &value;
5430 goto copyout; /* skip asking transport */
5431 }
5432 value = (int)lvalue;
5433 option = &value;
5434 len = (t_uscalar_t)sizeof (so->so_rcvbuf);
5435 break;
5436 }
5437 case SO_DOMAIN:
5438 value = so->so_family;
5439 option = &value;
5440 goto copyout; /* No need to issue T_SVR4_OPTMGMT_REQ */
5441
5442 #ifdef notyet
5488 break;
5489 }
5490 }
5491 }
5492
5493 mutex_exit(&so->so_lock);
5494
5495 /* Send request */
5496 optmgmt_req.PRIM_type = T_SVR4_OPTMGMT_REQ;
5497 optmgmt_req.MGMT_flags = T_CHECK;
5498 optmgmt_req.OPT_length = (t_scalar_t)(sizeof (oh) + maxlen);
5499 optmgmt_req.OPT_offset = (t_scalar_t)sizeof (optmgmt_req);
5500
5501 oh.level = level;
5502 oh.name = option_name;
5503 oh.len = maxlen;
5504
5505 mp = soallocproto3(&optmgmt_req, sizeof (optmgmt_req),
5506 &oh, sizeof (oh), NULL, maxlen, 0, _ALLOC_SLEEP, cr);
5507 /* Let option management work in the presence of data flow control */
5508 error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0,
5509 MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR|MSG_IGNFLOW, 0);
5510 mp = NULL;
5511 mutex_enter(&so->so_lock);
5512 if (error) {
5513 eprintsoline(so, error);
5514 goto done2;
5515 }
5516 error = sowaitprim(so, T_SVR4_OPTMGMT_REQ, T_OPTMGMT_ACK,
5517 (t_uscalar_t)(sizeof (*optmgmt_ack) + sizeof (*opt_res)), &mp, 0);
5518 if (error) {
5519 if (option != NULL) {
5520 /* We have a fallback value */
5521 error = 0;
5522 goto copyout;
5523 }
5524 eprintsoline(so, error);
5525 goto done2;
5526 }
5527 ASSERT(mp);
5528 optmgmt_ack = (struct T_optmgmt_ack *)mp->b_rptr;
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015, Joyent, Inc.
25 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
26 * Copyright 2022 MNX Cloud, Inc.
27 */
28
29 #include <sys/types.h>
30 #include <sys/t_lock.h>
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/buf.h>
34 #include <sys/conf.h>
35 #include <sys/cred.h>
36 #include <sys/kmem.h>
37 #include <sys/kmem_impl.h>
38 #include <sys/sysmacros.h>
39 #include <sys/vfs.h>
40 #include <sys/vnode.h>
41 #include <sys/debug.h>
42 #include <sys/errno.h>
43 #include <sys/time.h>
44 #include <sys/file.h>
45 #include <sys/open.h>
46 #include <sys/user.h>
245 sonodeops_t sotpi_sonodeops = {
246 sotpi_init, /* sop_init */
247 sotpi_accept, /* sop_accept */
248 sotpi_bind, /* sop_bind */
249 sotpi_listen, /* sop_listen */
250 sotpi_connect, /* sop_connect */
251 sotpi_recvmsg, /* sop_recvmsg */
252 sotpi_sendmsg, /* sop_sendmsg */
253 sotpi_sendmblk, /* sop_sendmblk */
254 sotpi_getpeername, /* sop_getpeername */
255 sotpi_getsockname, /* sop_getsockname */
256 sotpi_shutdown, /* sop_shutdown */
257 sotpi_getsockopt, /* sop_getsockopt */
258 sotpi_setsockopt, /* sop_setsockopt */
259 sotpi_ioctl, /* sop_ioctl */
260 sotpi_poll, /* sop_poll */
261 sotpi_close, /* sop_close */
262 };
263
264 /*
265 * Post-close reality check for NULL v_stream...
266 *
267 * Kernel callers (e.g. in procfs) may attempt socket operations, after
268 * holding the vnode, after it has been closed. For TPI sockets, post-close
269 * operations will have a NULL v_stream (which all functions here assume
270 * or even ASSERT() is non-NULL). See sotpi_close for where we wipe it out.
271 *
272 * If we are in a state where we lost a race to close(), we need to stop ASAP,
273 * and return the acceptable-as-an-errno EBADF. Because cleanup may be
274 * required, this macro only checks the v_stream.
275 *
276 * Checking should only be relevant for in-kernel other-thread inspectors.
277 * Userland ones (i.e. same process that opened the socktpi socket) SHOULD be
278 * protected by higher-level mechanisms. The only in-kernel inspector in the
279 * source base is procfs, which only accesses get{sockname,peername,sockopt}().
280 */
281 #define SOTPI_VN_NOSTREAM(vn) ((vn)->v_stream == NULL)
282
283 /*
284 * Return a TPI socket vnode.
285 *
286 * Note that sockets assume that the driver will clone (either itself
287 * or by using the clone driver) i.e. a socket() call will always
288 * result in a new vnode being created.
289 */
290
291 /*
292 * Common create code for socket and accept. If tso is set the values
293 * from that node is used instead of issuing a T_INFO_REQ.
294 */
295
296 /* ARGSUSED */
297 static struct sonode *
298 sotpi_create(struct sockparams *sp, int family, int type, int protocol,
299 int version, int sflags, int *errorp, cred_t *cr)
300 {
301 struct sonode *so;
302 kmem_cache_t *cp;
303 int sfamily = family;
1006 if (error) {
1007 if (error == EEXIST)
1008 error = EADDRINUSE;
1009 eprintsoline(so, error);
1010 goto done;
1011 }
1012 /*
1013 * Establish pointer from the underlying filesystem
1014 * vnode to the socket node.
1015 * sti_ux_bound_vp and v_stream->sd_vnode form the
1016 * cross-linkage between the underlying filesystem
1017 * node and the socket node.
1018 */
1019
1020 if ((VOP_REALVP(vp, &rvp, NULL) == 0) && (vp != rvp)) {
1021 VN_HOLD(rvp);
1022 VN_RELE(vp);
1023 vp = rvp;
1024 }
1025
1026 ASSERT(SOTOV(so)->v_stream != NULL);
1027 mutex_enter(&vp->v_lock);
1028 vp->v_stream = SOTOV(so)->v_stream;
1029 sti->sti_ux_bound_vp = vp;
1030 mutex_exit(&vp->v_lock);
1031
1032 /*
1033 * Use the vnode pointer value as a unique address
1034 * (together with the magic number to avoid conflicts
1035 * with implicit binds) in the transport provider.
1036 */
1037 sti->sti_ux_laddr.soua_vp =
1038 (void *)sti->sti_ux_bound_vp;
1039 sti->sti_ux_laddr.soua_magic = SOU_MAGIC_EXPLICIT;
1040 addr = &sti->sti_ux_laddr;
1041 addrlen = (t_uscalar_t)sizeof (sti->sti_ux_laddr);
1042 dprintso(so, 1, ("sobind UNIX: addrlen %d, addr %p\n",
1043 addrlen,
1044 (void *)((struct so_ux_addr *)addr)->soua_vp));
1045 break;
1046 }
4971 return (strwrite_common(SOTOV(so), uiop, cr, wflag));
4972 }
4973 }
4974 return (0);
4975 }
4976
4977 /*
4978 * Update sti_faddr by asking the transport (unless AF_UNIX).
4979 */
4980 /* ARGSUSED */
4981 int
4982 sotpi_getpeername(struct sonode *so, struct sockaddr *name, socklen_t *namelen,
4983 boolean_t accept, struct cred *cr)
4984 {
4985 struct strbuf strbuf;
4986 int error = 0, res;
4987 void *addr;
4988 t_uscalar_t addrlen;
4989 k_sigset_t smask;
4990 sotpi_info_t *sti = SOTOTPI(so);
4991 vnode_t *vn;
4992
4993 dprintso(so, 1, ("sotpi_getpeername(%p) %s\n",
4994 (void *)so, pr_state(so->so_state, so->so_mode)));
4995
4996 ASSERT(*namelen > 0);
4997 mutex_enter(&so->so_lock);
4998 so_lock_single(so); /* Set SOLOCKED */
4999 vn = SOTOV(so);
5000 if (SOTPI_VN_NOSTREAM(vn)) {
5001 error = EBADF;
5002 goto done;
5003 }
5004
5005 if (accept) {
5006 bcopy(sti->sti_faddr_sa, name,
5007 MIN(*namelen, sti->sti_faddr_len));
5008 *namelen = sti->sti_faddr_noxlate ? 0: sti->sti_faddr_len;
5009 goto done;
5010 }
5011
5012 if (!(so->so_state & SS_ISCONNECTED)) {
5013 error = ENOTCONN;
5014 goto done;
5015 }
5016 /* Added this check for X/Open */
5017 if ((so->so_state & SS_CANTSENDMORE) && !xnet_skip_checks) {
5018 error = EINVAL;
5019 if (xnet_check_print) {
5020 printf("sockfs: X/Open getpeername check => EINVAL\n");
5021 }
5022 goto done;
5023 }
5048 ASSERT(sti->sti_faddr_sa);
5049 /* Allocate local buffer to use with ioctl */
5050 addrlen = (t_uscalar_t)sti->sti_faddr_maxlen;
5051 mutex_exit(&so->so_lock);
5052 addr = kmem_alloc(addrlen, KM_SLEEP);
5053
5054 /*
5055 * Issue TI_GETPEERNAME with signals masked.
5056 * Put the result in sti_faddr_sa so that getpeername works after
5057 * a shutdown(output).
5058 * If the ioctl fails (e.g. due to a ECONNRESET) the error is reposted
5059 * back to the socket.
5060 */
5061 strbuf.buf = addr;
5062 strbuf.maxlen = addrlen;
5063 strbuf.len = 0;
5064
5065 sigintr(&smask, 0);
5066 res = 0;
5067 ASSERT(cr);
5068 error = strioctl(vn, TI_GETPEERNAME, (intptr_t)&strbuf,
5069 0, K_TO_K, cr, &res);
5070 sigunintr(&smask);
5071
5072 mutex_enter(&so->so_lock);
5073 /*
5074 * If there is an error record the error in so_error put don't fail
5075 * the getpeername. Instead fallback on the recorded
5076 * sti->sti_faddr_sa.
5077 */
5078 if (error) {
5079 /*
5080 * Various stream head errors can be returned to the ioctl.
5081 * However, it is impossible to determine which ones of
5082 * these are really socket level errors that were incorrectly
5083 * consumed by the ioctl. Thus this code silently ignores the
5084 * error - to code explicitly does not reinstate the error
5085 * using soseterror().
5086 * Experiments have shows that at least this set of
5087 * errors are reported and should not be reinstated on the
5088 * socket:
5113 #endif /* DEBUG */
5114 done:
5115 so_unlock_single(so, SOLOCKED);
5116 mutex_exit(&so->so_lock);
5117 return (error);
5118 }
5119
5120 /*
5121 * Update sti_laddr by asking the transport (unless AF_UNIX).
5122 */
5123 int
5124 sotpi_getsockname(struct sonode *so, struct sockaddr *name, socklen_t *namelen,
5125 struct cred *cr)
5126 {
5127 struct strbuf strbuf;
5128 int error = 0, res;
5129 void *addr;
5130 t_uscalar_t addrlen;
5131 k_sigset_t smask;
5132 sotpi_info_t *sti = SOTOTPI(so);
5133 vnode_t *vn;
5134
5135 dprintso(so, 1, ("sotpi_getsockname(%p) %s\n",
5136 (void *)so, pr_state(so->so_state, so->so_mode)));
5137
5138 ASSERT(*namelen > 0);
5139 mutex_enter(&so->so_lock);
5140 so_lock_single(so); /* Set SOLOCKED */
5141 vn = SOTOV(so);
5142 if (SOTPI_VN_NOSTREAM(vn)) {
5143 error = EBADF;
5144 goto done;
5145 }
5146
5147 #ifdef DEBUG
5148
5149 dprintso(so, 1, ("sotpi_getsockname (local): %s\n",
5150 pr_addr(so->so_family, sti->sti_laddr_sa,
5151 (t_uscalar_t)sti->sti_laddr_len)));
5152 #endif /* DEBUG */
5153 if (sti->sti_laddr_valid) {
5154 bcopy(sti->sti_laddr_sa, name,
5155 MIN(*namelen, sti->sti_laddr_len));
5156 *namelen = sti->sti_laddr_len;
5157 goto done;
5158 }
5159
5160 if (so->so_family == AF_UNIX) {
5161 /*
5162 * Transport has different name space - return local info. If we
5163 * have enough space, let consumers know the family.
5164 */
5165 if (*namelen >= sizeof (sa_family_t)) {
5179
5180 /* Allocate local buffer to use with ioctl */
5181 addrlen = (t_uscalar_t)sti->sti_laddr_maxlen;
5182 mutex_exit(&so->so_lock);
5183 addr = kmem_alloc(addrlen, KM_SLEEP);
5184
5185 /*
5186 * Issue TI_GETMYNAME with signals masked.
5187 * Put the result in sti_laddr_sa so that getsockname works after
5188 * a shutdown(output).
5189 * If the ioctl fails (e.g. due to a ECONNRESET) the error is reposted
5190 * back to the socket.
5191 */
5192 strbuf.buf = addr;
5193 strbuf.maxlen = addrlen;
5194 strbuf.len = 0;
5195
5196 sigintr(&smask, 0);
5197 res = 0;
5198 ASSERT(cr);
5199 error = strioctl(vn, TI_GETMYNAME, (intptr_t)&strbuf,
5200 0, K_TO_K, cr, &res);
5201 sigunintr(&smask);
5202
5203 mutex_enter(&so->so_lock);
5204 /*
5205 * If there is an error record the error in so_error put don't fail
5206 * the getsockname. Instead fallback on the recorded
5207 * sti->sti_laddr_sa.
5208 */
5209 if (error) {
5210 /*
5211 * Various stream head errors can be returned to the ioctl.
5212 * However, it is impossible to determine which ones of
5213 * these are really socket level errors that were incorrectly
5214 * consumed by the ioctl. Thus this code silently ignores the
5215 * error - to code explicitly does not reinstate the error
5216 * using soseterror().
5217 * Experiments have shows that at least this set of
5218 * errors are reported and should not be reinstated on the
5219 * socket:
5253 * On the return most *optlenp bytes are copied to optval.
5254 */
5255 /* ARGSUSED */
5256 int
5257 sotpi_getsockopt(struct sonode *so, int level, int option_name,
5258 void *optval, socklen_t *optlenp, int flags, struct cred *cr)
5259 {
5260 struct T_optmgmt_req optmgmt_req;
5261 struct T_optmgmt_ack *optmgmt_ack;
5262 struct opthdr oh;
5263 struct opthdr *opt_res;
5264 mblk_t *mp = NULL;
5265 int error = 0;
5266 void *option = NULL; /* Set if fallback value */
5267 t_uscalar_t maxlen = *optlenp;
5268 t_uscalar_t len;
5269 uint32_t value;
5270 struct timeval tmo_val; /* used for SO_RCVTIMEO, SO_SNDTIMEO */
5271 struct timeval32 tmo_val32;
5272 struct so_snd_bufinfo snd_bufinfo; /* used for zero copy */
5273 vnode_t *vn;
5274
5275 dprintso(so, 1, ("sotpi_getsockopt(%p, 0x%x, 0x%x, %p, %p) %s\n",
5276 (void *)so, level, option_name, optval, (void *)optlenp,
5277 pr_state(so->so_state, so->so_mode)));
5278
5279 mutex_enter(&so->so_lock);
5280 so_lock_single(so); /* Set SOLOCKED */
5281 vn = SOTOV(so);
5282 if (SOTPI_VN_NOSTREAM(vn)) {
5283 error = EBADF;
5284 eprintsoline(so, error);
5285 goto done2;
5286 }
5287
5288 /*
5289 * Check for SOL_SOCKET options.
5290 * Certain SOL_SOCKET options are returned directly whereas
5291 * others only provide a default (fallback) value should
5292 * the T_SVR4_OPTMGMT_REQ fail.
5293 */
5294 if (level == SOL_SOCKET) {
5295 /* Check parameters */
5296 switch (option_name) {
5297 case SO_TYPE:
5298 case SO_ERROR:
5299 case SO_DEBUG:
5300 case SO_ACCEPTCONN:
5301 case SO_REUSEADDR:
5302 case SO_KEEPALIVE:
5303 case SO_DONTROUTE:
5304 case SO_BROADCAST:
5305 case SO_USELOOPBACK:
5306 case SO_OOBINLINE:
5411 /*
5412 * The following options are only returned by sockfs when the
5413 * T_SVR4_OPTMGMT_REQ fails.
5414 */
5415 case SO_LINGER:
5416 option = &so->so_linger;
5417 len = (t_uscalar_t)sizeof (struct linger);
5418 break;
5419 case SO_SNDBUF: {
5420 ssize_t lvalue;
5421
5422 /*
5423 * If the option has not been set then get a default
5424 * value from the read queue. This value is
5425 * returned if the transport fails
5426 * the T_SVR4_OPTMGMT_REQ.
5427 */
5428 lvalue = so->so_sndbuf;
5429 if (lvalue == 0) {
5430 mutex_exit(&so->so_lock);
5431 (void) strqget(strvp2wq(vn)->q_next,
5432 QHIWAT, 0, &lvalue);
5433 mutex_enter(&so->so_lock);
5434 dprintso(so, 1,
5435 ("got SO_SNDBUF %ld from q\n", lvalue));
5436 }
5437 value = (int)lvalue;
5438 option = &value;
5439 len = (t_uscalar_t)sizeof (so->so_sndbuf);
5440 break;
5441 }
5442 case SO_RCVBUF: {
5443 ssize_t lvalue;
5444
5445 /*
5446 * If the option has not been set then get a default
5447 * value from the read queue. This value is
5448 * returned if the transport fails
5449 * the T_SVR4_OPTMGMT_REQ.
5450 *
5451 * XXX If SO_RCVBUF has been set and this is an
5452 * XPG 4.2 application then do not ask the transport
5453 * since the transport might adjust the value and not
5454 * return exactly what was set by the application.
5455 * For non-XPG 4.2 application we return the value
5456 * that the transport is actually using.
5457 */
5458 lvalue = so->so_rcvbuf;
5459 if (lvalue == 0) {
5460 mutex_exit(&so->so_lock);
5461 (void) strqget(RD(strvp2wq(vn)),
5462 QHIWAT, 0, &lvalue);
5463 mutex_enter(&so->so_lock);
5464 dprintso(so, 1,
5465 ("got SO_RCVBUF %ld from q\n", lvalue));
5466 } else if (flags & _SOGETSOCKOPT_XPG4_2) {
5467 value = (int)lvalue;
5468 option = &value;
5469 goto copyout; /* skip asking transport */
5470 }
5471 value = (int)lvalue;
5472 option = &value;
5473 len = (t_uscalar_t)sizeof (so->so_rcvbuf);
5474 break;
5475 }
5476 case SO_DOMAIN:
5477 value = so->so_family;
5478 option = &value;
5479 goto copyout; /* No need to issue T_SVR4_OPTMGMT_REQ */
5480
5481 #ifdef notyet
5527 break;
5528 }
5529 }
5530 }
5531
5532 mutex_exit(&so->so_lock);
5533
5534 /* Send request */
5535 optmgmt_req.PRIM_type = T_SVR4_OPTMGMT_REQ;
5536 optmgmt_req.MGMT_flags = T_CHECK;
5537 optmgmt_req.OPT_length = (t_scalar_t)(sizeof (oh) + maxlen);
5538 optmgmt_req.OPT_offset = (t_scalar_t)sizeof (optmgmt_req);
5539
5540 oh.level = level;
5541 oh.name = option_name;
5542 oh.len = maxlen;
5543
5544 mp = soallocproto3(&optmgmt_req, sizeof (optmgmt_req),
5545 &oh, sizeof (oh), NULL, maxlen, 0, _ALLOC_SLEEP, cr);
5546 /* Let option management work in the presence of data flow control */
5547 error = kstrputmsg(vn, mp, NULL, 0, 0,
5548 MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR|MSG_IGNFLOW, 0);
5549 mp = NULL;
5550 mutex_enter(&so->so_lock);
5551 if (error) {
5552 eprintsoline(so, error);
5553 goto done2;
5554 }
5555 error = sowaitprim(so, T_SVR4_OPTMGMT_REQ, T_OPTMGMT_ACK,
5556 (t_uscalar_t)(sizeof (*optmgmt_ack) + sizeof (*opt_res)), &mp, 0);
5557 if (error) {
5558 if (option != NULL) {
5559 /* We have a fallback value */
5560 error = 0;
5561 goto copyout;
5562 }
5563 eprintsoline(so, error);
5564 goto done2;
5565 }
5566 ASSERT(mp);
5567 optmgmt_ack = (struct T_optmgmt_ack *)mp->b_rptr;
|