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 mblk_t *sctp_get_sock_pid_mblk(sock_upper_handle_t);
111
112 sonodeops_t sosctp_sonodeops = {
113 sosctp_init, /* sop_init */
114 sosctp_accept, /* sop_accept */
115 sosctp_bind, /* sop_bind */
116 sosctp_listen, /* sop_listen */
117 sosctp_connect, /* sop_connect */
118 sosctp_recvmsg, /* sop_recvmsg */
119 sosctp_sendmsg, /* sop_sendmsg */
120 so_sendmblk_notsupp, /* sop_sendmblk */
121 sosctp_getpeername, /* sop_getpeername */
122 sosctp_getsockname, /* sop_getsockname */
123 sosctp_shutdown, /* sop_shutdown */
124 sosctp_getsockopt, /* sop_getsockopt */
125 sosctp_setsockopt, /* sop_setsockopt */
126 sosctp_ioctl, /* sop_ioctl */
127 so_poll, /* sop_poll */
128 sosctp_close, /* sop_close */
129 };
130
153 so_connected,
154 so_disconnected,
155 so_opctl,
156 so_queue_msg,
157 so_set_prop,
158 so_txq_full,
159 NULL, /* su_signal_oob */
160 };
161
162 /* All the upcalls expect the upper handle to be sctp_sonode/sctp_soassoc. */
163 sock_upcalls_t sosctp_assoc_upcalls = {
164 sctp_assoc_newconn,
165 sctp_assoc_connected,
166 sctp_assoc_disconnected,
167 sctp_assoc_disconnecting,
168 sctp_assoc_recv,
169 sctp_assoc_properties,
170 sctp_assoc_xmitted,
171 NULL, /* su_recv_space */
172 NULL, /* su_signal_oob */
173 NULL, /* su_set_error */
174 NULL, /* su_closed */
175 sctp_get_sock_pid_mblk
176 };
177
178 /* ARGSUSED */
179 static int
180 sosctp_init(struct sonode *so, struct sonode *pso, struct cred *cr, int flags)
181 {
182 struct sctp_sonode *ss;
183 struct sctp_sonode *pss;
184 sctp_sockbuf_limits_t sbl;
185 int err;
186
187 ss = SOTOSSO(so);
188
189 if (pso != NULL) {
190 /*
191 * Passive open, just inherit settings from parent. We should
192 * not end up here for SOCK_SEQPACKET type sockets, since no
193 * new sonode is created in that case.
194 */
195 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 }
|