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