4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/stropts.h>
34 #include <sys/socketvar.h>
35 #include <sys/ksocket.h>
36 #include <io/ksocket/ksocket_impl.h>
37 #include "sockcommon.h"
39 #include "sockfilter_impl.h"
42 * There can only be a single thread waiting for data (enforced by
43 * so_lock_read()), whereas for write there might be multiple threads
44 * waiting for transmit buffers. So therefore we use cv_broadcast for
45 * write and cv_signal for read.
47 #define SO_WAKEUP_READER(so) { \
48 if ((so)->so_rcv_wakeup) { \
49 (so)->so_rcv_wakeup = B_FALSE; \
50 cv_signal(&(so)->so_rcv_cv); \
54 #define SO_WAKEUP_WRITER(so) { \
55 if ((so)->so_snd_wakeup) { \
56 (so)->so_snd_wakeup = B_FALSE; \
57 cv_broadcast(&(so)->so_snd_cv); \
61 static int i_so_notify_last_rx(struct sonode
*, int *, int *);
62 static int i_so_notify_last_tx(struct sonode
*, int *, int *);
65 * The notification functions must be called with so_lock held,
66 * and they will all *drop* so_lock before returning.
70 * Wake up anyone waiting for the connection to be established.
73 so_notify_connected(struct sonode
*so
)
75 ASSERT(MUTEX_HELD(&so
->so_lock
));
77 if (IS_KERNEL_SOCKET(so
)) {
78 KSOCKET_CALLBACK(so
, connected
, 0);
79 mutex_exit(&so
->so_lock
);
81 socket_sendsig(so
, SOCKETSIG_WRITE
);
82 mutex_exit(&so
->so_lock
);
83 pollwakeup(&so
->so_poll_list
, POLLOUT
);
85 sof_sonode_notify_filters(so
, SOF_EV_CONNECTED
, 0);
87 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
91 * The socket is disconnecting, so no more data can be sent. Wake up
92 * anyone that is waiting to send data.
95 so_notify_disconnecting(struct sonode
*so
)
100 ASSERT(MUTEX_HELD(&so
->so_lock
));
101 (void) i_so_notify_last_tx(so
, &pollev
, &sigev
);
103 if (IS_KERNEL_SOCKET(so
)) {
104 KSOCKET_CALLBACK(so
, cantsendmore
, 0);
105 mutex_exit(&so
->so_lock
);
108 socket_sendsig(so
, sigev
);
109 mutex_exit(&so
->so_lock
);
112 pollwakeup(&so
->so_poll_list
, pollev
);
114 sof_sonode_notify_filters(so
, SOF_EV_CANTSENDMORE
, 0);
116 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
120 * The socket is disconnected, so not more data can be sent or received.
121 * Wake up anyone that is waiting to send or receive data.
124 so_notify_disconnected(struct sonode
*so
, boolean_t connfailed
, int error
)
129 ASSERT(MUTEX_HELD(&so
->so_lock
));
131 (void) i_so_notify_last_tx(so
, &pollev
, &sigev
);
132 (void) i_so_notify_last_rx(so
, &pollev
, &sigev
);
134 if (IS_KERNEL_SOCKET(so
)) {
136 KSOCKET_CALLBACK(so
, disconnected
, error
);
138 KSOCKET_CALLBACK(so
, connectfailed
, error
);
140 mutex_exit(&so
->so_lock
);
143 socket_sendsig(so
, sigev
);
144 mutex_exit(&so
->so_lock
);
147 * If we're here because the socket has become disconnected,
148 * we explicitly set POLLHUP. At the same time, we also clear
149 * POLLOUT, as POLLOUT and POLLHUP are defined to be mutually
150 * exclusive with respect to one another.
153 pollev
= (pollev
| POLLHUP
) & ~POLLOUT
;
156 pollwakeup(&so
->so_poll_list
, pollev
);
158 sof_sonode_notify_filters(so
, (connfailed
) ? SOF_EV_CONNECTFAILED
:
159 SOF_EV_DISCONNECTED
, error
);
161 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
165 * The socket is writeable. Wake up anyone waiting to send data.
168 so_notify_writable(struct sonode
*so
)
170 ASSERT(MUTEX_HELD(&so
->so_lock
));
172 SO_WAKEUP_WRITER(so
);
174 if (IS_KERNEL_SOCKET(so
)) {
175 KSOCKET_CALLBACK(so
, cansend
, 0);
176 mutex_exit(&so
->so_lock
);
178 socket_sendsig(so
, SOCKETSIG_WRITE
);
179 mutex_exit(&so
->so_lock
);
180 pollwakeup(&so
->so_poll_list
, POLLOUT
);
183 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
185 /* filters can start injecting data */
186 if (so
->so_filter_active
> 0)
187 sof_sonode_notify_filters(so
, SOF_EV_INJECT_DATA_OUT_OK
, 0);
191 * Data is available, so wake up anyone waiting for data.
194 so_notify_data(struct sonode
*so
, size_t qlen
)
196 ASSERT(MUTEX_HELD(&so
->so_lock
));
198 SO_WAKEUP_READER(so
);
200 if (IS_KERNEL_SOCKET(so
)) {
201 KSOCKET_CALLBACK(so
, newdata
, qlen
);
202 mutex_exit(&so
->so_lock
);
204 socket_sendsig(so
, SOCKETSIG_READ
);
205 if (so
->so_pollev
& (SO_POLLEV_IN
|SO_POLLEV_ALWAYS
)) {
206 so
->so_pollev
&= ~SO_POLLEV_IN
;
207 mutex_exit(&so
->so_lock
);
208 pollwakeup(&so
->so_poll_list
, POLLIN
|POLLRDNORM
);
210 mutex_exit(&so
->so_lock
);
214 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
218 * Transient error. Wake up anyone waiting to send or receive data.
221 so_notify_error(struct sonode
*so
)
223 ASSERT(MUTEX_HELD(&so
->so_lock
));
225 SO_WAKEUP_WRITER(so
);
226 SO_WAKEUP_READER(so
);
228 if (IS_KERNEL_SOCKET(so
)) {
229 KSOCKET_CALLBACK(so
, error
, 0);
230 mutex_exit(&so
->so_lock
);
232 socket_sendsig(so
, SOCKETSIG_WRITE
|SOCKETSIG_READ
);
233 so
->so_pollev
&= ~SO_POLLEV_IN
;
234 mutex_exit(&so
->so_lock
);
235 pollwakeup(&so
->so_poll_list
, POLLOUT
|POLLIN
|POLLRDNORM
);
238 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
242 * Out-of-band data is incoming, notify any interested parties.
245 so_notify_oobsig(struct sonode
*so
)
247 socket_sendsig(so
, SOCKETSIG_URG
);
248 mutex_exit(&so
->so_lock
);
249 pollwakeup(&so
->so_poll_list
, POLLRDBAND
);
253 * Received out-of-band data. If the OOB data is delivered inline, then
254 * in addition of regular OOB notification, anyone waiting for normal
255 * data is also notified.
258 so_notify_oobdata(struct sonode
*so
, boolean_t oob_inline
)
260 ASSERT(MUTEX_HELD(&so
->so_lock
));
261 if (so
->so_direct
!= NULL
)
262 SOD_UIOAFINI(so
->so_direct
);
264 SO_WAKEUP_READER(so
);
266 if (IS_KERNEL_SOCKET(so
)) {
267 KSOCKET_CALLBACK(so
, oobdata
, 0);
268 mutex_exit(&so
->so_lock
);
271 socket_sendsig(so
, SOCKETSIG_READ
);
272 so
->so_pollev
&= ~SO_POLLEV_IN
;
273 mutex_exit(&so
->so_lock
);
274 pollwakeup(&so
->so_poll_list
,
275 POLLRDBAND
|POLLIN
|POLLRDNORM
);
277 mutex_exit(&so
->so_lock
);
278 pollwakeup(&so
->so_poll_list
, POLLRDBAND
);
282 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
286 * End-of-file has been reach, so peer will send no new data. Wake up
287 * anyone that is waiting for data.
290 so_notify_eof(struct sonode
*so
)
295 ASSERT(MUTEX_HELD(&so
->so_lock
));
297 (void) i_so_notify_last_rx(so
, &pollev
, &sigev
);
299 if (IS_KERNEL_SOCKET(so
)) {
300 KSOCKET_CALLBACK(so
, cantrecvmore
, 0);
301 mutex_exit(&so
->so_lock
);
304 socket_sendsig(so
, sigev
);
305 mutex_exit(&so
->so_lock
);
307 pollwakeup(&so
->so_poll_list
, pollev
);
310 sof_sonode_notify_filters(so
, SOF_EV_CANTRECVMORE
, 0);
312 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
316 * Wake up anyone waiting for a new connection.
319 so_notify_newconn(struct sonode
*so
)
321 ASSERT(MUTEX_HELD(&so
->so_lock
));
323 if (IS_KERNEL_SOCKET(so
)) {
324 KSOCKET_CALLBACK(so
, newconn
, 0);
325 mutex_exit(&so
->so_lock
);
327 socket_sendsig(so
, SOCKETSIG_READ
);
328 if (so
->so_pollev
& (SO_POLLEV_IN
|SO_POLLEV_ALWAYS
)) {
329 so
->so_pollev
&= ~SO_POLLEV_IN
;
330 mutex_exit(&so
->so_lock
);
331 pollwakeup(&so
->so_poll_list
, POLLIN
|POLLRDNORM
);
333 mutex_exit(&so
->so_lock
);
337 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
341 * User initated shutdown/close, wake anyone that is trying to do
342 * an operation that is no longer possible.
345 so_notify_shutdown(struct sonode
*so
)
350 ASSERT(MUTEX_HELD(&so
->so_lock
));
351 ASSERT(so
->so_state
& (SS_CANTSENDMORE
|SS_CANTRCVMORE
));
353 if (so
->so_state
& SS_CANTSENDMORE
)
354 (void) i_so_notify_last_tx(so
, &pollev
, &sigev
);
355 if (so
->so_state
& SS_CANTRCVMORE
)
356 (void) i_so_notify_last_rx(so
, &pollev
, &sigev
);
359 socket_sendsig(so
, sigev
);
360 mutex_exit(&so
->so_lock
);
362 pollwakeup(&so
->so_poll_list
, pollev
);
364 ASSERT(MUTEX_NOT_HELD(&so
->so_lock
));
368 * No more data will be coming in, and this will be the last notification
372 i_so_notify_last_rx(struct sonode
*so
, int *pollev
, int *sigev
)
374 if (!(so
->so_state
& SS_SENTLASTREADSIG
)) {
375 SOCKET_TIMER_CANCEL(so
);
376 SO_WAKEUP_READER(so
);
377 so
->so_state
|= SS_SENTLASTREADSIG
;
378 so
->so_pollev
&= ~SO_POLLEV_IN
;
380 *pollev
|= POLLIN
|POLLRDNORM
|POLLRDHUP
;
381 *sigev
|= SOCKETSIG_READ
;
390 * The socket is un-writeable. Make one last notification.
393 i_so_notify_last_tx(struct sonode
*so
, int *pollev
, int *sigev
)
395 if (!(so
->so_state
& SS_SENTLASTWRITESIG
)) {
396 SO_WAKEUP_WRITER(so
);
397 so
->so_state
|= SS_SENTLASTWRITESIG
;
400 *sigev
|= SOCKETSIG_WRITE
;