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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2015 Joyent, Inc. All rights reserved.
25 */
26
27 #include <sys/types.h>
28 #include <sys/t_lock.h>
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/buf.h>
32 #include <sys/vfs.h>
33 #include <sys/vnode.h>
34 #include <sys/debug.h>
35 #include <sys/errno.h>
36 #include <sys/stropts.h>
37 #include <sys/cmn_err.h>
38 #include <sys/sysmacros.h>
39 #include <sys/filio.h>
40 #include <sys/policy.h>
41
42 #include <sys/project.h>
43 #include <sys/tihdr.h>
44 #include <sys/strsubr.h>
45 #include <sys/esunddi.h>
46 #include <sys/ddi.h>
47
48 #include <sys/sockio.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/strsun.h>
52
53 #include <netinet/sctp.h>
90 socklen_t, int, int, struct cred *);
91 static int sosctp_seq_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
92 struct cred *);
93
94 /*
95 * Socket association upcalls, 1-N socket connection
96 */
97 sock_upper_handle_t sctp_assoc_newconn(sock_upper_handle_t,
98 sock_lower_handle_t, sock_downcalls_t *, struct cred *, pid_t,
99 sock_upcalls_t **);
100 static void sctp_assoc_connected(sock_upper_handle_t, sock_connid_t,
101 struct cred *, pid_t);
102 static int sctp_assoc_disconnected(sock_upper_handle_t, sock_connid_t, int);
103 static void sctp_assoc_disconnecting(sock_upper_handle_t, sock_opctl_action_t,
104 uintptr_t arg);
105 static ssize_t sctp_assoc_recv(sock_upper_handle_t, mblk_t *, size_t, int,
106 int *, boolean_t *);
107 static void sctp_assoc_xmitted(sock_upper_handle_t, boolean_t);
108 static void sctp_assoc_properties(sock_upper_handle_t,
109 struct sock_proto_props *);
110
111 sonodeops_t sosctp_sonodeops = {
112 sosctp_init, /* sop_init */
113 sosctp_accept, /* sop_accept */
114 sosctp_bind, /* sop_bind */
115 sosctp_listen, /* sop_listen */
116 sosctp_connect, /* sop_connect */
117 sosctp_recvmsg, /* sop_recvmsg */
118 sosctp_sendmsg, /* sop_sendmsg */
119 so_sendmblk_notsupp, /* sop_sendmblk */
120 sosctp_getpeername, /* sop_getpeername */
121 sosctp_getsockname, /* sop_getsockname */
122 sosctp_shutdown, /* sop_shutdown */
123 sosctp_getsockopt, /* sop_getsockopt */
124 sosctp_setsockopt, /* sop_setsockopt */
125 sosctp_ioctl, /* sop_ioctl */
126 so_poll, /* sop_poll */
127 sosctp_close, /* sop_close */
128 };
129
152 so_connected,
153 so_disconnected,
154 so_opctl,
155 so_queue_msg,
156 so_set_prop,
157 so_txq_full,
158 NULL, /* su_signal_oob */
159 };
160
161 /* All the upcalls expect the upper handle to be sctp_sonode/sctp_soassoc. */
162 sock_upcalls_t sosctp_assoc_upcalls = {
163 sctp_assoc_newconn,
164 sctp_assoc_connected,
165 sctp_assoc_disconnected,
166 sctp_assoc_disconnecting,
167 sctp_assoc_recv,
168 sctp_assoc_properties,
169 sctp_assoc_xmitted,
170 NULL, /* su_recv_space */
171 NULL, /* su_signal_oob */
172 };
173
174 /* ARGSUSED */
175 static int
176 sosctp_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
177 {
178 struct sctp_sonode *ss;
179 struct sctp_sonode *pss;
180 sctp_sockbuf_limits_t sbl;
181 int err;
182
183 ss = SOTOSSO(so);
184
185 if (pso != NULL) {
186 /*
187 * Passive open, just inherit settings from parent. We should
188 * not end up here for SOCK_SEQPACKET type sockets, since no
189 * new sonode is created in that case.
190 */
191 ASSERT(so->so_type == SOCK_STREAM);
1756 */
1757 mutex_enter(&nso->so_lock);
1758
1759 error = sctp_set_opt((struct sctp_s *)ssa->ssa_conn,
1760 IPPROTO_SCTP, SCTP_UC_SWAP, &us, sizeof (us));
1761 if (error) {
1762 goto peelerr;
1763 }
1764 error = falloc(nvp, FWRITE|FREAD, &nfp, NULL);
1765 if (error) {
1766 goto peelerr;
1767 }
1768
1769 /*
1770 * fill in the entries that falloc reserved
1771 */
1772 nfp->f_vnode = nvp;
1773 mutex_exit(&nfp->f_tlock);
1774 setf(nfd, nfp);
1775
1776 mutex_enter(&so->so_lock);
1777
1778 sosctp_assoc_move(ss, SOTOSSO(nso), ssa);
1779
1780 mutex_exit(&nso->so_lock);
1781
1782 ssa->ssa_conn = NULL;
1783 sosctp_assoc_free(ss, ssa);
1784
1785 so_unlock_single(so, SOLOCKED);
1786 mutex_exit(&so->so_lock);
1787
1788 return (0);
1789
1790 err:
1791 SOCKPARAMS_DEC_REF(sp);
1792 setf(nfd, NULL);
1793 eprintsoline(so, error);
1794 return (error);
1795
2212 if (soppp->sopp_flags & SOCKOPT_RCVHIWAT) {
2213 ssize_t lowat;
2214
2215 so->so_rcvbuf = soppp->sopp_rxhiwat;
2216 /*
2217 * The low water mark should be adjusted properly
2218 * if the high water mark is changed. It should
2219 * not be bigger than 1/4 of high water mark.
2220 */
2221 lowat = soppp->sopp_rxhiwat >> 2;
2222 if (so->so_rcvlowat > lowat) {
2223 /* Sanity check... */
2224 if (lowat == 0)
2225 so->so_rcvlowat = soppp->sopp_rxhiwat;
2226 else
2227 so->so_rcvlowat = lowat;
2228 }
2229 }
2230 }
2231 mutex_exit(&so->so_lock);
2232 }
|
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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2015 Joyent, Inc. All rights reserved.
25 */
26
27 #include <sys/types.h>
28 #include <sys/t_lock.h>
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/buf.h>
32 #include <sys/vfs.h>
33 #include <sys/vnode.h>
34 #include <sys/fcntl.h>
35 #include <sys/debug.h>
36 #include <sys/errno.h>
37 #include <sys/stropts.h>
38 #include <sys/cmn_err.h>
39 #include <sys/sysmacros.h>
40 #include <sys/filio.h>
41 #include <sys/policy.h>
42
43 #include <sys/project.h>
44 #include <sys/tihdr.h>
45 #include <sys/strsubr.h>
46 #include <sys/esunddi.h>
47 #include <sys/ddi.h>
48
49 #include <sys/sockio.h>
50 #include <sys/socket.h>
51 #include <sys/socketvar.h>
52 #include <sys/strsun.h>
53
54 #include <netinet/sctp.h>
91 socklen_t, int, int, struct cred *);
92 static int sosctp_seq_sendmsg(struct sonode *, struct nmsghdr *, struct uio *,
93 struct cred *);
94
95 /*
96 * Socket association upcalls, 1-N socket connection
97 */
98 sock_upper_handle_t sctp_assoc_newconn(sock_upper_handle_t,
99 sock_lower_handle_t, sock_downcalls_t *, struct cred *, pid_t,
100 sock_upcalls_t **);
101 static void sctp_assoc_connected(sock_upper_handle_t, sock_connid_t,
102 struct cred *, pid_t);
103 static int sctp_assoc_disconnected(sock_upper_handle_t, sock_connid_t, int);
104 static void sctp_assoc_disconnecting(sock_upper_handle_t, sock_opctl_action_t,
105 uintptr_t arg);
106 static ssize_t sctp_assoc_recv(sock_upper_handle_t, mblk_t *, size_t, int,
107 int *, boolean_t *);
108 static void sctp_assoc_xmitted(sock_upper_handle_t, boolean_t);
109 static void sctp_assoc_properties(sock_upper_handle_t,
110 struct sock_proto_props *);
111 static mblk_t *sctp_get_sock_pid_mblk(sock_upper_handle_t);
112
113 sonodeops_t sosctp_sonodeops = {
114 sosctp_init, /* sop_init */
115 sosctp_accept, /* sop_accept */
116 sosctp_bind, /* sop_bind */
117 sosctp_listen, /* sop_listen */
118 sosctp_connect, /* sop_connect */
119 sosctp_recvmsg, /* sop_recvmsg */
120 sosctp_sendmsg, /* sop_sendmsg */
121 so_sendmblk_notsupp, /* sop_sendmblk */
122 sosctp_getpeername, /* sop_getpeername */
123 sosctp_getsockname, /* sop_getsockname */
124 sosctp_shutdown, /* sop_shutdown */
125 sosctp_getsockopt, /* sop_getsockopt */
126 sosctp_setsockopt, /* sop_setsockopt */
127 sosctp_ioctl, /* sop_ioctl */
128 so_poll, /* sop_poll */
129 sosctp_close, /* sop_close */
130 };
131
154 so_connected,
155 so_disconnected,
156 so_opctl,
157 so_queue_msg,
158 so_set_prop,
159 so_txq_full,
160 NULL, /* su_signal_oob */
161 };
162
163 /* All the upcalls expect the upper handle to be sctp_sonode/sctp_soassoc. */
164 sock_upcalls_t sosctp_assoc_upcalls = {
165 sctp_assoc_newconn,
166 sctp_assoc_connected,
167 sctp_assoc_disconnected,
168 sctp_assoc_disconnecting,
169 sctp_assoc_recv,
170 sctp_assoc_properties,
171 sctp_assoc_xmitted,
172 NULL, /* su_recv_space */
173 NULL, /* su_signal_oob */
174 NULL, /* su_set_error */
175 NULL, /* su_closed */
176 sctp_get_sock_pid_mblk
177 };
178
179 /* ARGSUSED */
180 static int
181 sosctp_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
182 {
183 struct sctp_sonode *ss;
184 struct sctp_sonode *pss;
185 sctp_sockbuf_limits_t sbl;
186 int err;
187
188 ss = SOTOSSO(so);
189
190 if (pso != NULL) {
191 /*
192 * Passive open, just inherit settings from parent. We should
193 * not end up here for SOCK_SEQPACKET type sockets, since no
194 * new sonode is created in that case.
195 */
196 ASSERT(so->so_type == SOCK_STREAM);
1761 */
1762 mutex_enter(&nso->so_lock);
1763
1764 error = sctp_set_opt((struct sctp_s *)ssa->ssa_conn,
1765 IPPROTO_SCTP, SCTP_UC_SWAP, &us, sizeof (us));
1766 if (error) {
1767 goto peelerr;
1768 }
1769 error = falloc(nvp, FWRITE|FREAD, &nfp, NULL);
1770 if (error) {
1771 goto peelerr;
1772 }
1773
1774 /*
1775 * fill in the entries that falloc reserved
1776 */
1777 nfp->f_vnode = nvp;
1778 mutex_exit(&nfp->f_tlock);
1779 setf(nfd, nfp);
1780
1781 /* Add pid to the list associated with that socket. */
1782 if (nfp->f_vnode != NULL) {
1783 (void) VOP_IOCTL(nfp->f_vnode, F_ASSOCI_PID,
1784 (intptr_t)curproc->p_pidp->pid_id, FKIOCTL, kcred,
1785 NULL, NULL);
1786 }
1787
1788 mutex_enter(&so->so_lock);
1789
1790 sosctp_assoc_move(ss, SOTOSSO(nso), ssa);
1791
1792 mutex_exit(&nso->so_lock);
1793
1794 ssa->ssa_conn = NULL;
1795 sosctp_assoc_free(ss, ssa);
1796
1797 so_unlock_single(so, SOLOCKED);
1798 mutex_exit(&so->so_lock);
1799
1800 return (0);
1801
1802 err:
1803 SOCKPARAMS_DEC_REF(sp);
1804 setf(nfd, NULL);
1805 eprintsoline(so, error);
1806 return (error);
1807
2224 if (soppp->sopp_flags & SOCKOPT_RCVHIWAT) {
2225 ssize_t lowat;
2226
2227 so->so_rcvbuf = soppp->sopp_rxhiwat;
2228 /*
2229 * The low water mark should be adjusted properly
2230 * if the high water mark is changed. It should
2231 * not be bigger than 1/4 of high water mark.
2232 */
2233 lowat = soppp->sopp_rxhiwat >> 2;
2234 if (so->so_rcvlowat > lowat) {
2235 /* Sanity check... */
2236 if (lowat == 0)
2237 so->so_rcvlowat = soppp->sopp_rxhiwat;
2238 else
2239 so->so_rcvlowat = lowat;
2240 }
2241 }
2242 }
2243 mutex_exit(&so->so_lock);
2244 }
2245
2246 static mblk_t *
2247 sctp_get_sock_pid_mblk(sock_upper_handle_t handle)
2248 {
2249 struct sctp_soassoc *ssa = (struct sctp_soassoc *)handle;
2250 struct sonode *so;
2251
2252 if (ssa->ssa_type == SOSCTP_ASSOC)
2253 so = &ssa->ssa_sonode->ss_so;
2254 else
2255 so = &((struct sctp_sonode *)handle)->ss_so;
2256
2257 return (so_get_sock_pid_mblk((sock_upper_handle_t)so));
2258 }
|