netwerk/sctp/src/user_socketvar.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/sctp/src/user_socketvar.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,842 @@
     1.4 +/*-
     1.5 + * Copyright (c) 1982, 1986, 1990, 1993
     1.6 + *	The Regents of the University of California.  All rights reserved.
     1.7 + *
     1.8 + * Redistribution and use in source and binary forms, with or without
     1.9 + * modification, are permitted provided that the following conditions
    1.10 + * are met:
    1.11 + * 1. Redistributions of source code must retain the above copyright
    1.12 + *    notice, this list of conditions and the following disclaimer.
    1.13 + * 2. Redistributions in binary form must reproduce the above copyright
    1.14 + *    notice, this list of conditions and the following disclaimer in the
    1.15 + *    documentation and/or other materials provided with the distribution.
    1.16 + * 4. Neither the name of the University nor the names of its contributors
    1.17 + *    may be used to endorse or promote products derived from this software
    1.18 + *    without specific prior written permission.
    1.19 + *
    1.20 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    1.21 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.22 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.23 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    1.24 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.25 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.26 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.27 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.28 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.29 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.30 + * SUCH DAMAGE.
    1.31 + *
    1.32 + */
    1.33 +
    1.34 +/* __Userspace__ version of <sys/socketvar.h> goes here.*/
    1.35 +
    1.36 +#ifndef _USER_SOCKETVAR_H_
    1.37 +#define _USER_SOCKETVAR_H_
    1.38 +
    1.39 +#if defined(__Userspace_os_Darwin)
    1.40 +#include <sys/types.h>
    1.41 +#include <unistd.h>
    1.42 +#endif
    1.43 +
    1.44 +/* #include <sys/selinfo.h> */ /*__Userspace__ alternative?*/	/* for struct selinfo */
    1.45 +/* #include <sys/_lock.h>  was 0 byte file */
    1.46 +/* #include <sys/_mutex.h> was 0 byte file */
    1.47 +/* #include <sys/_sx.h> */ /*__Userspace__ alternative?*/
    1.48 +#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_Windows) 
    1.49 +#include <sys/uio.h>
    1.50 +#endif
    1.51 +#define SOCK_MAXADDRLEN 255
    1.52 +#if !defined(MSG_NOTIFICATION)
    1.53 +#define MSG_NOTIFICATION 0x2000         /* SCTP notification */
    1.54 +#endif
    1.55 +#define SCTP_SO_LINGER     0x0001
    1.56 +#define SCTP_SO_ACCEPTCONN 0x0002
    1.57 +#define SS_CANTRCVMORE 0x020
    1.58 +#define SS_CANTSENDMORE 0x010
    1.59 +
    1.60 +#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined (__Userspace_os_Windows)
    1.61 +#define UIO_MAXIOV 1024
    1.62 +#define ERESTART (-1)
    1.63 +#endif
    1.64 +
    1.65 +#if !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_OpenBSD)
    1.66 +enum	uio_rw { UIO_READ, UIO_WRITE };
    1.67 +#endif
    1.68 +
    1.69 +#if !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_OpenBSD)
    1.70 +/* Segment flag values. */
    1.71 +enum uio_seg {
    1.72 +	UIO_USERSPACE,		/* from user data space */
    1.73 +	UIO_SYSSPACE		/* from system space */
    1.74 +};
    1.75 +#endif
    1.76 +
    1.77 +struct proc {
    1.78 +    int stub; /* struct proc is a dummy for __Userspace__ */
    1.79 +};
    1.80 +
    1.81 +MALLOC_DECLARE(M_ACCF);
    1.82 +MALLOC_DECLARE(M_PCB);
    1.83 +MALLOC_DECLARE(M_SONAME);
    1.84 +
    1.85 +/* __Userspace__ Are these all the fields we need?
    1.86 + * Removing struct thread *uio_td;    owner field
    1.87 +*/
    1.88 +struct uio {
    1.89 +    struct	iovec *uio_iov;		/* scatter/gather list */
    1.90 +    int	        uio_iovcnt;		/* length of scatter/gather list */
    1.91 +    off_t	uio_offset;		/* offset in target object */
    1.92 +    int 	uio_resid;		/* remaining bytes to process */
    1.93 +    enum	uio_seg uio_segflg;	/* address space */
    1.94 +    enum	uio_rw uio_rw;		/* operation */
    1.95 +};
    1.96 +
    1.97 +
    1.98 +/* __Userspace__ */
    1.99 +
   1.100 +/*
   1.101 + * Kernel structure per socket.
   1.102 + * Contains send and receive buffer queues,
   1.103 + * handle on protocol and pointer to protocol
   1.104 + * private data and error information.
   1.105 + */
   1.106 +#if defined (__Userspace_os_Windows)
   1.107 +#define AF_ROUTE  17
   1.108 +typedef __int32 pid_t;
   1.109 +typedef unsigned __int32 uid_t;
   1.110 +enum sigType {
   1.111 +	SIGNAL = 0,
   1.112 +	BROADCAST = 1,
   1.113 +	MAX_EVENTS = 2
   1.114 +};
   1.115 +#endif
   1.116 +
   1.117 +/*-
   1.118 + * Locking key to struct socket:
   1.119 + * (a) constant after allocation, no locking required.
   1.120 + * (b) locked by SOCK_LOCK(so).
   1.121 + * (c) locked by SOCKBUF_LOCK(&so->so_rcv).
   1.122 + * (d) locked by SOCKBUF_LOCK(&so->so_snd).
   1.123 + * (e) locked by ACCEPT_LOCK().
   1.124 + * (f) not locked since integer reads/writes are atomic.
   1.125 + * (g) used only as a sleep/wakeup address, no value.
   1.126 + * (h) locked by global mutex so_global_mtx.
   1.127 + */
   1.128 +struct socket {
   1.129 +	int	so_count;		/* (b) reference count */
   1.130 +	short	so_type;		/* (a) generic type, see socket.h */
   1.131 +	short	so_options;		/* from socket call, see socket.h */
   1.132 +	short	so_linger;		/* time to linger while closing */
   1.133 +	short	so_state;		/* (b) internal state flags SS_* */
   1.134 +	int	so_qstate;		/* (e) internal state flags SQ_* */
   1.135 +	void	*so_pcb;		/* protocol control block */
   1.136 +	int	so_dom;
   1.137 +/*
   1.138 + * Variables for connection queuing.
   1.139 + * Socket where accepts occur is so_head in all subsidiary sockets.
   1.140 + * If so_head is 0, socket is not related to an accept.
   1.141 + * For head socket so_incomp queues partially completed connections,
   1.142 + * while so_comp is a queue of connections ready to be accepted.
   1.143 + * If a connection is aborted and it has so_head set, then
   1.144 + * it has to be pulled out of either so_incomp or so_comp.
   1.145 + * We allow connections to queue up based on current queue lengths
   1.146 + * and limit on number of queued connections for this socket.
   1.147 + */
   1.148 +	struct	socket *so_head;	/* (e) back pointer to listen socket */
   1.149 +	TAILQ_HEAD(, socket) so_incomp;	/* (e) queue of partial unaccepted connections */
   1.150 +	TAILQ_HEAD(, socket) so_comp;	/* (e) queue of complete unaccepted connections */
   1.151 +	TAILQ_ENTRY(socket) so_list;	/* (e) list of unaccepted connections */
   1.152 +	u_short	so_qlen;		/* (e) number of unaccepted connections */
   1.153 +	u_short	so_incqlen;		/* (e) number of unaccepted incomplete
   1.154 +					   connections */
   1.155 +	u_short	so_qlimit;		/* (e) max number queued connections */
   1.156 +	short	so_timeo;		/* (g) connection timeout */
   1.157 +	userland_cond_t timeo_cond;      /* timeo_cond condition variable being used in wakeup */
   1.158 +
   1.159 +	u_short	so_error;		/* (f) error affecting connection */
   1.160 +	struct	sigio *so_sigio;	/* [sg] information for async I/O or
   1.161 +					   out of band data (SIGURG) */
   1.162 +	u_long	so_oobmark;		/* (c) chars to oob mark */
   1.163 +	TAILQ_HEAD(, aiocblist) so_aiojobq; /* AIO ops waiting on socket */
   1.164 +/*
   1.165 + * Variables for socket buffering.
   1.166 + */
   1.167 +	struct sockbuf {
   1.168 +		/* __Userspace__ Many of these fields may
   1.169 +		 * not be required for the sctp stack.
   1.170 +		 * Commenting out the following.
   1.171 +		 * Including pthread mutex and condition variable to be
   1.172 +		 * used by sbwait, sorwakeup and sowwakeup.
   1.173 +		*/
   1.174 +		/* struct	selinfo sb_sel;*/ /* process selecting read/write */
   1.175 +		/* struct	mtx sb_mtx;*/	/* sockbuf lock */
   1.176 +		/* struct	sx sb_sx;*/	/* prevent I/O interlacing */
   1.177 +		userland_cond_t sb_cond; /* sockbuf condition variable */
   1.178 +		userland_mutex_t sb_mtx; /* sockbuf lock associated with sb_cond */
   1.179 +		short	sb_state;	/* (c/d) socket state on sockbuf */
   1.180 +#define	sb_startzero	sb_mb
   1.181 +		struct	mbuf *sb_mb;	/* (c/d) the mbuf chain */
   1.182 +		struct	mbuf *sb_mbtail; /* (c/d) the last mbuf in the chain */
   1.183 +		struct	mbuf *sb_lastrecord;	/* (c/d) first mbuf of last
   1.184 +						 * record in socket buffer */
   1.185 +		struct	mbuf *sb_sndptr; /* (c/d) pointer into mbuf chain */
   1.186 +		u_int	sb_sndptroff;	/* (c/d) byte offset of ptr into chain */
   1.187 +		u_int	sb_cc;		/* (c/d) actual chars in buffer */
   1.188 +		u_int	sb_hiwat;	/* (c/d) max actual char count */
   1.189 +		u_int	sb_mbcnt;	/* (c/d) chars of mbufs used */
   1.190 +		u_int	sb_mbmax;	/* (c/d) max chars of mbufs to use */
   1.191 +		u_int	sb_ctl;		/* (c/d) non-data chars in buffer */
   1.192 +		int	sb_lowat;	/* (c/d) low water mark */
   1.193 +		int	sb_timeo;	/* (c/d) timeout for read/write */
   1.194 +		short	sb_flags;	/* (c/d) flags, see below */
   1.195 +	} so_rcv, so_snd;
   1.196 +/*
   1.197 + * Constants for sb_flags field of struct sockbuf.
   1.198 + */
   1.199 +#define	SB_MAX		(256*1024)	/* default for max chars in sockbuf */
   1.200 +#define SB_RAW          (64*1024*2)    /*Aligning so->so_rcv.sb_hiwat with the receive buffer size of raw socket*/
   1.201 +/*
   1.202 + * Constants for sb_flags field of struct sockbuf.
   1.203 + */
   1.204 +#define	SB_WAIT		0x04		/* someone is waiting for data/space */
   1.205 +#define	SB_SEL		0x08		/* someone is selecting */
   1.206 +#define	SB_ASYNC	0x10		/* ASYNC I/O, need signals */
   1.207 +#define	SB_UPCALL	0x20		/* someone wants an upcall */
   1.208 +#define	SB_NOINTR	0x40		/* operations not interruptible */
   1.209 +#define	SB_AIO		0x80		/* AIO operations queued */
   1.210 +#define	SB_KNOTE	0x100		/* kernel note attached */
   1.211 +#define	SB_AUTOSIZE	0x800		/* automatically size socket buffer */
   1.212 +
   1.213 +	void	(*so_upcall)(struct socket *, void *, int);
   1.214 +	void	*so_upcallarg;
   1.215 +	struct	ucred *so_cred;		/* (a) user credentials */
   1.216 +	struct	label *so_label;	/* (b) MAC label for socket */
   1.217 +	struct	label *so_peerlabel;	/* (b) cached MAC label for peer */
   1.218 +	/* NB: generation count must not be first. */
   1.219 +	uint32_t so_gencnt;		/* (h) generation count */
   1.220 +	void	*so_emuldata;		/* (b) private data for emulators */
   1.221 + 	struct so_accf {
   1.222 +		struct	accept_filter *so_accept_filter;
   1.223 +		void	*so_accept_filter_arg;	/* saved filter args */
   1.224 +		char	*so_accept_filter_str;	/* saved user args */
   1.225 +	} *so_accf;
   1.226 +};
   1.227 +
   1.228 +#define SB_EMPTY_FIXUP(sb) do {						\
   1.229 +	if ((sb)->sb_mb == NULL) {					\
   1.230 +		(sb)->sb_mbtail = NULL;					\
   1.231 +		(sb)->sb_lastrecord = NULL;				\
   1.232 +	}								\
   1.233 +} while (/*CONSTCOND*/0)
   1.234 +
   1.235 +/*
   1.236 + * Global accept mutex to serialize access to accept queues and
   1.237 + * fields associated with multiple sockets.  This allows us to
   1.238 + * avoid defining a lock order between listen and accept sockets
   1.239 + * until such time as it proves to be a good idea.
   1.240 + */
   1.241 +#if defined(__Userspace_os_Windows)
   1.242 +extern userland_mutex_t accept_mtx;
   1.243 +extern userland_cond_t accept_cond;
   1.244 +#define ACCEPT_LOCK_ASSERT()
   1.245 +#define	ACCEPT_LOCK() do { \
   1.246 +	EnterCriticalSection(&accept_mtx); \
   1.247 +} while (0)
   1.248 +#define	ACCEPT_UNLOCK()	do { \
   1.249 +	LeaveCriticalSection(&accept_mtx); \
   1.250 +} while (0)
   1.251 +#define	ACCEPT_UNLOCK_ASSERT()
   1.252 +#else
   1.253 +extern userland_mutex_t accept_mtx;
   1.254 +extern userland_cond_t accept_cond;
   1.255 +#define	ACCEPT_LOCK_ASSERT()		KASSERT(pthread_mutex_trylock(&accept_mtx) == EBUSY, ("%s: accept_mtx not locked", __func__))
   1.256 +#define	ACCEPT_LOCK()			(void)pthread_mutex_lock(&accept_mtx)
   1.257 +#define	ACCEPT_UNLOCK()			(void)pthread_mutex_unlock(&accept_mtx)
   1.258 +#define	ACCEPT_UNLOCK_ASSERT()	 do{                                                            \
   1.259 +	KASSERT(pthread_mutex_trylock(&accept_mtx) == 0, ("%s: accept_mtx  locked", __func__)); \
   1.260 +	(void)pthread_mutex_unlock(&accept_mtx);                                                \
   1.261 +} while (0)
   1.262 +#endif
   1.263 +
   1.264 +/*
   1.265 + * Per-socket buffer mutex used to protect most fields in the socket
   1.266 + * buffer.
   1.267 + */
   1.268 +#define	SOCKBUF_MTX(_sb) (&(_sb)->sb_mtx)
   1.269 +#if defined (__Userspace_os_Windows)
   1.270 +#define SOCKBUF_LOCK_INIT(_sb, _name) \
   1.271 +	InitializeCriticalSection(SOCKBUF_MTX(_sb))
   1.272 +#define SOCKBUF_LOCK_DESTROY(_sb) DeleteCriticalSection(SOCKBUF_MTX(_sb))
   1.273 +#define SOCKBUF_COND_INIT(_sb) InitializeConditionVariable((&(_sb)->sb_cond))
   1.274 +#define SOCKBUF_COND_DESTROY(_sb) DeleteConditionVariable((&(_sb)->sb_cond))
   1.275 +#define SOCK_COND_INIT(_so) InitializeConditionVariable((&(_so)->timeo_cond))
   1.276 +#define SOCK_COND_DESTROY(_so) DeleteConditionVariable((&(_so)->timeo_cond))
   1.277 +#define SOCK_COND(_so) (&(_so)->timeo_cond)
   1.278 +#else
   1.279 +#define SOCKBUF_LOCK_INIT(_sb, _name) \
   1.280 +	pthread_mutex_init(SOCKBUF_MTX(_sb), NULL)
   1.281 +#define SOCKBUF_LOCK_DESTROY(_sb) pthread_mutex_destroy(SOCKBUF_MTX(_sb))
   1.282 +#define SOCKBUF_COND_INIT(_sb) pthread_cond_init((&(_sb)->sb_cond), NULL)
   1.283 +#define SOCKBUF_COND_DESTROY(_sb) pthread_cond_destroy((&(_sb)->sb_cond))
   1.284 +#define SOCK_COND_INIT(_so) pthread_cond_init((&(_so)->timeo_cond), NULL)
   1.285 +#define SOCK_COND_DESTROY(_so) pthread_cond_destroy((&(_so)->timeo_cond))
   1.286 +#define SOCK_COND(_so) (&(_so)->timeo_cond)
   1.287 +#endif
   1.288 +/*__Userspace__ SOCKBUF_LOCK(_sb) is now defined in netinet/sctp_process_lock.h */
   1.289 +
   1.290 +/* #define	SOCKBUF_OWNED(_sb)		mtx_owned(SOCKBUF_MTX(_sb)) unused */
   1.291 +/*__Userspace__ SOCKBUF_UNLOCK(_sb) is now defined in netinet/sctp_process_lock.h */
   1.292 +
   1.293 +/*__Userspace__ SOCKBUF_LOCK_ASSERT(_sb) is now defined in netinet/sctp_process_lock.h */
   1.294 +
   1.295 +/* #define	SOCKBUF_UNLOCK_ASSERT(_sb)	mtx_assert(SOCKBUF_MTX(_sb), MA_NOTOWNED)   unused */
   1.296 +
   1.297 +/*
   1.298 + * Per-socket mutex: we reuse the receive socket buffer mutex for space
   1.299 + * efficiency.  This decision should probably be revisited as we optimize
   1.300 + * locking for the socket code.
   1.301 + */
   1.302 +#define	SOCK_MTX(_so)			SOCKBUF_MTX(&(_so)->so_rcv)
   1.303 +/*__Userspace__ SOCK_LOCK(_so) is now defined in netinet/sctp_process_lock.h */
   1.304 +
   1.305 +/* #define	SOCK_OWNED(_so)			SOCKBUF_OWNED(&(_so)->so_rcv) unused */
   1.306 +/*__Userspace__ SOCK_UNLOCK(_so) is now defined in netinet/sctp_process_lock.h */
   1.307 +
   1.308 +#define	SOCK_LOCK_ASSERT(_so)		SOCKBUF_LOCK_ASSERT(&(_so)->so_rcv)
   1.309 +
   1.310 +/*
   1.311 + * Socket state bits.
   1.312 + *
   1.313 + * Historically, this bits were all kept in the so_state field.  For
   1.314 + * locking reasons, they are now in multiple fields, as they are
   1.315 + * locked differently.  so_state maintains basic socket state protected
   1.316 + * by the socket lock.  so_qstate holds information about the socket
   1.317 + * accept queues.  Each socket buffer also has a state field holding
   1.318 + * information relevant to that socket buffer (can't send, rcv).  Many
   1.319 + * fields will be read without locks to improve performance and avoid
   1.320 + * lock order issues.  However, this approach must be used with caution.
   1.321 + */
   1.322 +#define	SS_NOFDREF		0x0001	/* no file table ref any more */
   1.323 +#define	SS_ISCONNECTED		0x0002	/* socket connected to a peer */
   1.324 +#define	SS_ISCONNECTING		0x0004	/* in process of connecting to peer */
   1.325 +#define	SS_ISDISCONNECTING	0x0008	/* in process of disconnecting */
   1.326 +#define	SS_NBIO			0x0100	/* non-blocking ops */
   1.327 +#define	SS_ASYNC		0x0200	/* async i/o notify */
   1.328 +#define	SS_ISCONFIRMING		0x0400	/* deciding to accept connection req */
   1.329 +#define	SS_ISDISCONNECTED	0x2000	/* socket disconnected from peer */
   1.330 +/*
   1.331 + * Protocols can mark a socket as SS_PROTOREF to indicate that, following
   1.332 + * pru_detach, they still want the socket to persist, and will free it
   1.333 + * themselves when they are done.  Protocols should only ever call sofree()
   1.334 + * following setting this flag in pru_detach(), and never otherwise, as
   1.335 + * sofree() bypasses socket reference counting.
   1.336 + */
   1.337 +#define	SS_PROTOREF		0x4000	/* strong protocol reference */
   1.338 +
   1.339 +/*
   1.340 + * Socket state bits now stored in the socket buffer state field.
   1.341 + */
   1.342 +#define	SBS_CANTSENDMORE	0x0010	/* can't send more data to peer */
   1.343 +#define	SBS_CANTRCVMORE		0x0020	/* can't receive more data from peer */
   1.344 +#define	SBS_RCVATMARK		0x0040	/* at mark on input */
   1.345 +
   1.346 +/*
   1.347 + * Socket state bits stored in so_qstate.
   1.348 + */
   1.349 +#define	SQ_INCOMP		0x0800	/* unaccepted, incomplete connection */
   1.350 +#define	SQ_COMP			0x1000	/* unaccepted, complete connection */
   1.351 +
   1.352 +/*
   1.353 + * Externalized form of struct socket used by the sysctl(3) interface.
   1.354 + */
   1.355 +struct xsocket {
   1.356 +	size_t	xso_len;	/* length of this structure */
   1.357 +	struct	socket *xso_so;	/* makes a convenient handle sometimes */
   1.358 +	short	so_type;
   1.359 +	short	so_options;
   1.360 +	short	so_linger;
   1.361 +	short	so_state;
   1.362 +	caddr_t	so_pcb;		/* another convenient handle */
   1.363 +	int	xso_protocol;
   1.364 +	int	xso_family;
   1.365 +	u_short	so_qlen;
   1.366 +	u_short	so_incqlen;
   1.367 +	u_short	so_qlimit;
   1.368 +	short	so_timeo;
   1.369 +	u_short	so_error;
   1.370 +	pid_t	so_pgid;
   1.371 +	u_long	so_oobmark;
   1.372 +	struct xsockbuf {
   1.373 +		u_int	sb_cc;
   1.374 +		u_int	sb_hiwat;
   1.375 +		u_int	sb_mbcnt;
   1.376 +		u_int	sb_mbmax;
   1.377 +		int	sb_lowat;
   1.378 +		int	sb_timeo;
   1.379 +		short	sb_flags;
   1.380 +	} so_rcv, so_snd;
   1.381 +	uid_t	so_uid;		/* XXX */
   1.382 +};
   1.383 +
   1.384 +#if defined(_KERNEL)
   1.385 +
   1.386 +
   1.387 +/*
   1.388 + * Macros for sockets and socket buffering.
   1.389 + */
   1.390 +
   1.391 +/*
   1.392 + * Do we need to notify the other side when I/O is possible?
   1.393 + */
   1.394 +#define	sb_notify(sb)	(((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \
   1.395 +    SB_UPCALL | SB_AIO | SB_KNOTE)) != 0)
   1.396 +
   1.397 +/*
   1.398 + * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
   1.399 + * This is problematical if the fields are unsigned, as the space might
   1.400 + * still be negative (cc > hiwat or mbcnt > mbmax).  Should detect
   1.401 + * overflow and return 0.  Should use "lmin" but it doesn't exist now.
   1.402 + */
   1.403 +#define	sbspace(sb) \
   1.404 +    ((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \
   1.405 +	 (int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
   1.406 +
   1.407 +/* do we have to send all at once on a socket? */
   1.408 +#define	sosendallatonce(so) \
   1.409 +    ((so)->so_proto->pr_flags & PR_ATOMIC)
   1.410 +
   1.411 +/* can we read something from so? */
   1.412 +#define	soreadable(so) \
   1.413 +    ((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
   1.414 +	((so)->so_rcv.sb_state & SBS_CANTRCVMORE) || \
   1.415 +	!TAILQ_EMPTY(&(so)->so_comp) || (so)->so_error)
   1.416 +
   1.417 +/* can we write something to so? */
   1.418 +#define	sowriteable(so) \
   1.419 +    ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
   1.420 +	(((so)->so_state&SS_ISCONNECTED) || \
   1.421 +	  ((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0)) || \
   1.422 +     ((so)->so_snd.sb_state & SBS_CANTSENDMORE) || \
   1.423 +     (so)->so_error)
   1.424 +
   1.425 +/* adjust counters in sb reflecting allocation of m */
   1.426 +#define	sballoc(sb, m) { \
   1.427 +	(sb)->sb_cc += (m)->m_len; \
   1.428 +	if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
   1.429 +		(sb)->sb_ctl += (m)->m_len; \
   1.430 +	(sb)->sb_mbcnt += MSIZE; \
   1.431 +	if ((m)->m_flags & M_EXT) \
   1.432 +		(sb)->sb_mbcnt += (m)->m_ext.ext_size; \
   1.433 +}
   1.434 +
   1.435 +/* adjust counters in sb reflecting freeing of m */
   1.436 +#define	sbfree(sb, m) { \
   1.437 +	(sb)->sb_cc -= (m)->m_len; \
   1.438 +	if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
   1.439 +		(sb)->sb_ctl -= (m)->m_len; \
   1.440 +	(sb)->sb_mbcnt -= MSIZE; \
   1.441 +	if ((m)->m_flags & M_EXT) \
   1.442 +		(sb)->sb_mbcnt -= (m)->m_ext.ext_size; \
   1.443 +	if ((sb)->sb_sndptr == (m)) { \
   1.444 +		(sb)->sb_sndptr = NULL; \
   1.445 +		(sb)->sb_sndptroff = 0; \
   1.446 +	} \
   1.447 +	if ((sb)->sb_sndptroff != 0) \
   1.448 +		(sb)->sb_sndptroff -= (m)->m_len; \
   1.449 +}
   1.450 +
   1.451 +/*
   1.452 + * soref()/sorele() ref-count the socket structure.  Note that you must
   1.453 + * still explicitly close the socket, but the last ref count will free
   1.454 + * the structure.
   1.455 + */
   1.456 +#define	soref(so) do {							\
   1.457 +	SOCK_LOCK_ASSERT(so);						\
   1.458 +	++(so)->so_count;						\
   1.459 +} while (0)
   1.460 +
   1.461 +#define	sorele(so) do {							\
   1.462 +	ACCEPT_LOCK_ASSERT();						\
   1.463 +	SOCK_LOCK_ASSERT(so);						\
   1.464 +	KASSERT((so)->so_count > 0, ("sorele"));			\
   1.465 +	if (--(so)->so_count == 0)					\
   1.466 +		sofree(so);						\
   1.467 +	else {								\
   1.468 +		SOCK_UNLOCK(so);					\
   1.469 +		ACCEPT_UNLOCK();					\
   1.470 +	}								\
   1.471 +} while (0)
   1.472 +
   1.473 +#define	sotryfree(so) do {						\
   1.474 +	ACCEPT_LOCK_ASSERT();						\
   1.475 +	SOCK_LOCK_ASSERT(so);						\
   1.476 +	if ((so)->so_count == 0)					\
   1.477 +		sofree(so);						\
   1.478 +	else {								\
   1.479 +		SOCK_UNLOCK(so);					\
   1.480 +		ACCEPT_UNLOCK();					\
   1.481 +	}								\
   1.482 +} while(0)
   1.483 +
   1.484 +/*
   1.485 + * In sorwakeup() and sowwakeup(), acquire the socket buffer lock to
   1.486 + * avoid a non-atomic test-and-wakeup.  However, sowakeup is
   1.487 + * responsible for releasing the lock if it is called.  We unlock only
   1.488 + * if we don't call into sowakeup.  If any code is introduced that
   1.489 + * directly invokes the underlying sowakeup() primitives, it must
   1.490 + * maintain the same semantics.
   1.491 + */
   1.492 +#define	sorwakeup_locked(so) do {					\
   1.493 +	SOCKBUF_LOCK_ASSERT(&(so)->so_rcv);				\
   1.494 +	if (sb_notify(&(so)->so_rcv))					\
   1.495 +		sowakeup((so), &(so)->so_rcv);	 			\
   1.496 +	else								\
   1.497 +		SOCKBUF_UNLOCK(&(so)->so_rcv);				\
   1.498 +} while (0)
   1.499 +
   1.500 +#define	sorwakeup(so) do {						\
   1.501 +	SOCKBUF_LOCK(&(so)->so_rcv);					\
   1.502 +	sorwakeup_locked(so);						\
   1.503 +} while (0)
   1.504 +
   1.505 +#define	sowwakeup_locked(so) do {					\
   1.506 +	SOCKBUF_LOCK_ASSERT(&(so)->so_snd);				\
   1.507 +	if (sb_notify(&(so)->so_snd))					\
   1.508 +		sowakeup((so), &(so)->so_snd); 				\
   1.509 +	else								\
   1.510 +		SOCKBUF_UNLOCK(&(so)->so_snd);				\
   1.511 +} while (0)
   1.512 +
   1.513 +#define	sowwakeup(so) do {						\
   1.514 +	SOCKBUF_LOCK(&(so)->so_snd);					\
   1.515 +	sowwakeup_locked(so);						\
   1.516 +} while (0)
   1.517 +
   1.518 +/*
   1.519 + * Argument structure for sosetopt et seq.  This is in the KERNEL
   1.520 + * section because it will never be visible to user code.
   1.521 + */
   1.522 +enum sopt_dir { SOPT_GET, SOPT_SET };
   1.523 +struct sockopt {
   1.524 +	enum	sopt_dir sopt_dir; /* is this a get or a set? */
   1.525 +	int	sopt_level;	/* second arg of [gs]etsockopt */
   1.526 +	int	sopt_name;	/* third arg of [gs]etsockopt */
   1.527 +	void   *sopt_val;	/* fourth arg of [gs]etsockopt */
   1.528 +	size_t	sopt_valsize;	/* (almost) fifth arg of [gs]etsockopt */
   1.529 +	struct	thread *sopt_td; /* calling thread or null if kernel */
   1.530 +};
   1.531 +
   1.532 +struct accept_filter {
   1.533 +	char	accf_name[16];
   1.534 +	void	(*accf_callback)
   1.535 +		(struct socket *so, void *arg, int waitflag);
   1.536 +	void *	(*accf_create)
   1.537 +		(struct socket *so, char *arg);
   1.538 +	void	(*accf_destroy)
   1.539 +		(struct socket *so);
   1.540 +	SLIST_ENTRY(accept_filter) accf_next;
   1.541 +};
   1.542 +
   1.543 +extern int	maxsockets;
   1.544 +extern u_long	sb_max;
   1.545 +extern struct uma_zone *socket_zone;
   1.546 +extern so_gen_t so_gencnt;
   1.547 +
   1.548 +struct mbuf;
   1.549 +struct sockaddr;
   1.550 +struct ucred;
   1.551 +struct uio;
   1.552 +
   1.553 +/*
   1.554 + * From uipc_socket and friends
   1.555 + */
   1.556 +int	do_getopt_accept_filter(struct socket *so, struct sockopt *sopt);
   1.557 +int	do_setopt_accept_filter(struct socket *so, struct sockopt *sopt);
   1.558 +int	so_setsockopt(struct socket *so, int level, int optname,
   1.559 +	    void *optval, size_t optlen);
   1.560 +int	sockargs(struct mbuf **mp, caddr_t buf, int buflen, int type);
   1.561 +int	getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
   1.562 +void	sbappend(struct sockbuf *sb, struct mbuf *m);
   1.563 +void	sbappend_locked(struct sockbuf *sb, struct mbuf *m);
   1.564 +void	sbappendstream(struct sockbuf *sb, struct mbuf *m);
   1.565 +void	sbappendstream_locked(struct sockbuf *sb, struct mbuf *m);
   1.566 +int	sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
   1.567 +	    struct mbuf *m0, struct mbuf *control);
   1.568 +int	sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
   1.569 +	    struct mbuf *m0, struct mbuf *control);
   1.570 +int	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
   1.571 +	    struct mbuf *control);
   1.572 +int	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
   1.573 +	    struct mbuf *control);
   1.574 +void	sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
   1.575 +void	sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
   1.576 +void	sbcheck(struct sockbuf *sb);
   1.577 +void	sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
   1.578 +struct mbuf *
   1.579 +	sbcreatecontrol(caddr_t p, int size, int type, int level);
   1.580 +void	sbdestroy(struct sockbuf *sb, struct socket *so);
   1.581 +void	sbdrop(struct sockbuf *sb, int len);
   1.582 +void	sbdrop_locked(struct sockbuf *sb, int len);
   1.583 +void	sbdroprecord(struct sockbuf *sb);
   1.584 +void	sbdroprecord_locked(struct sockbuf *sb);
   1.585 +void	sbflush(struct sockbuf *sb);
   1.586 +void	sbflush_locked(struct sockbuf *sb);
   1.587 +void	sbrelease(struct sockbuf *sb, struct socket *so);
   1.588 +void	sbrelease_locked(struct sockbuf *sb, struct socket *so);
   1.589 +int	sbreserve(struct sockbuf *sb, u_long cc, struct socket *so,
   1.590 +	    struct thread *td);
   1.591 +int	sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
   1.592 +	    struct thread *td);
   1.593 +struct mbuf *
   1.594 +	sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff);
   1.595 +void	sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb);
   1.596 +int	sbwait(struct sockbuf *sb);
   1.597 +int	sblock(struct sockbuf *sb, int flags);
   1.598 +void	sbunlock(struct sockbuf *sb);
   1.599 +void	soabort(struct socket *so);
   1.600 +int	soaccept(struct socket *so, struct sockaddr **nam);
   1.601 +int	socheckuid(struct socket *so, uid_t uid);
   1.602 +int	sobind(struct socket *so, struct sockaddr *nam, struct thread *td);
   1.603 +void	socantrcvmore(struct socket *so);
   1.604 +void	socantrcvmore_locked(struct socket *so);
   1.605 +void	socantsendmore(struct socket *so);
   1.606 +void	socantsendmore_locked(struct socket *so);
   1.607 +int	soclose(struct socket *so);
   1.608 +int	soconnect(struct socket *so, struct sockaddr *nam, struct thread *td);
   1.609 +int	soconnect2(struct socket *so1, struct socket *so2);
   1.610 +int	socow_setup(struct mbuf *m0, struct uio *uio);
   1.611 +int	socreate(int dom, struct socket **aso, int type, int proto,
   1.612 +	    struct ucred *cred, struct thread *td);
   1.613 +int	sodisconnect(struct socket *so);
   1.614 +struct	sockaddr *sodupsockaddr(const struct sockaddr *sa, int mflags);
   1.615 +void	sofree(struct socket *so);
   1.616 +int	sogetopt(struct socket *so, struct sockopt *sopt);
   1.617 +void	sohasoutofband(struct socket *so);
   1.618 +void	soisconnected(struct socket *so);
   1.619 +void	soisconnecting(struct socket *so);
   1.620 +void	soisdisconnected(struct socket *so);
   1.621 +void	soisdisconnecting(struct socket *so);
   1.622 +int	solisten(struct socket *so, int backlog, struct thread *td);
   1.623 +void	solisten_proto(struct socket *so, int backlog);
   1.624 +int	solisten_proto_check(struct socket *so);
   1.625 +struct socket *
   1.626 +	sonewconn(struct socket *head, int connstatus);
   1.627 +int	sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen);
   1.628 +int	sooptcopyout(struct sockopt *sopt, const void *buf, size_t len);
   1.629 +
   1.630 +/* XXX; prepare mbuf for (__FreeBSD__ < 3) routines. */
   1.631 +int	soopt_getm(struct sockopt *sopt, struct mbuf **mp);
   1.632 +int	soopt_mcopyin(struct sockopt *sopt, struct mbuf *m);
   1.633 +int	soopt_mcopyout(struct sockopt *sopt, struct mbuf *m);
   1.634 +
   1.635 +int	sopoll(struct socket *so, int events, struct ucred *active_cred,
   1.636 +	    struct thread *td);
   1.637 +int	sopoll_generic(struct socket *so, int events,
   1.638 +	    struct ucred *active_cred, struct thread *td);
   1.639 +int	soreceive(struct socket *so, struct sockaddr **paddr, struct uio *uio,
   1.640 +	    struct mbuf **mp0, struct mbuf **controlp, int *flagsp);
   1.641 +int	soreceive_generic(struct socket *so, struct sockaddr **paddr,
   1.642 +	    struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
   1.643 +	    int *flagsp);
   1.644 +int	soreserve(struct socket *so, u_long sndcc, u_long rcvcc);
   1.645 +void	sorflush(struct socket *so);
   1.646 +int	sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
   1.647 +	    struct mbuf *top, struct mbuf *control, int flags,
   1.648 +	    struct thread *td);
   1.649 +int	sosend_dgram(struct socket *so, struct sockaddr *addr,
   1.650 +	    struct uio *uio, struct mbuf *top, struct mbuf *control,
   1.651 +	    int flags, struct thread *td);
   1.652 +int	sosend_generic(struct socket *so, struct sockaddr *addr,
   1.653 +	    struct uio *uio, struct mbuf *top, struct mbuf *control,
   1.654 +	    int flags, struct thread *td);
   1.655 +int	sosetopt(struct socket *so, struct sockopt *sopt);
   1.656 +int	soshutdown(struct socket *so, int how);
   1.657 +void	sotoxsocket(struct socket *so, struct xsocket *xso);
   1.658 +void	sowakeup(struct socket *so, struct sockbuf *sb);
   1.659 +
   1.660 +#ifdef SOCKBUF_DEBUG
   1.661 +void	sblastrecordchk(struct sockbuf *, const char *, int);
   1.662 +#define	SBLASTRECORDCHK(sb)	sblastrecordchk((sb), __FILE__, __LINE__)
   1.663 +
   1.664 +void	sblastmbufchk(struct sockbuf *, const char *, int);
   1.665 +#define	SBLASTMBUFCHK(sb)	sblastmbufchk((sb), __FILE__, __LINE__)
   1.666 +#else
   1.667 +#define	SBLASTRECORDCHK(sb)      /* nothing */
   1.668 +#define	SBLASTMBUFCHK(sb)        /* nothing */
   1.669 +#endif /* SOCKBUF_DEBUG */
   1.670 +
   1.671 +/*
   1.672 + * Accept filter functions (duh).
   1.673 + */
   1.674 +int	accept_filt_add(struct accept_filter *filt);
   1.675 +int	accept_filt_del(char *name);
   1.676 +struct	accept_filter *accept_filt_get(char *name);
   1.677 +#ifdef ACCEPT_FILTER_MOD
   1.678 +#ifdef SYSCTL_DECL
   1.679 +SYSCTL_DECL(_net_inet_accf);
   1.680 +#endif
   1.681 +int	accept_filt_generic_mod_event(module_t mod, int event, void *data);
   1.682 +#endif
   1.683 +
   1.684 +#endif /* _KERNEL */
   1.685 +
   1.686 +
   1.687 +/*-------------------------------------------------------------*/
   1.688 +/*-------------------------------------------------------------*/
   1.689 +/*                   __Userspace__                             */
   1.690 +/*-------------------------------------------------------------*/
   1.691 +/*-------------------------------------------------------------*/
   1.692 +/* this new __Userspace__ section is to copy portions of the _KERNEL block
   1.693 + *  above into, avoiding having to port the entire thing at once...
   1.694 + *  For function prototypes, the full bodies are in user_socket.c .
   1.695 + */
   1.696 +#if defined(__Userspace__)
   1.697 +
   1.698 +/* ---------------------------------------------------------- */
   1.699 +/* --- function prototypes (implemented in user_socket.c) --- */
   1.700 +/* ---------------------------------------------------------- */
   1.701 +void	soisconnecting(struct socket *so);
   1.702 +void	soisdisconnecting(struct socket *so);
   1.703 +void	soisconnected(struct socket *so);
   1.704 +struct socket * sonewconn(struct socket *head, int connstatus);
   1.705 +void	socantrcvmore(struct socket *so);
   1.706 +void	socantsendmore(struct socket *so);
   1.707 +
   1.708 +
   1.709 +
   1.710 +/* -------------- */
   1.711 +/* --- macros --- */
   1.712 +/* -------------- */
   1.713 +
   1.714 +#define	soref(so) do {							\
   1.715 +	SOCK_LOCK_ASSERT(so);						\
   1.716 +	++(so)->so_count;						\
   1.717 +} while (0)
   1.718 +
   1.719 +#define	sorele(so) do {							\
   1.720 +	ACCEPT_LOCK_ASSERT();						\
   1.721 +	SOCK_LOCK_ASSERT(so);						\
   1.722 +	KASSERT((so)->so_count > 0, ("sorele"));			\
   1.723 +	if (--(so)->so_count == 0)					\
   1.724 +		sofree(so);						\
   1.725 +	else {								\
   1.726 +		SOCK_UNLOCK(so);					\
   1.727 +		ACCEPT_UNLOCK();					\
   1.728 +	}								\
   1.729 +} while (0)
   1.730 +
   1.731 +
   1.732 +/* replacing imin with min (user_environment.h) */
   1.733 +#define	sbspace(sb) \
   1.734 +    ((long) min((int)((sb)->sb_hiwat - (sb)->sb_cc), \
   1.735 +	 (int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
   1.736 +
   1.737 +/* do we have to send all at once on a socket? */
   1.738 +#define	sosendallatonce(so) \
   1.739 +    ((so)->so_proto->pr_flags & PR_ATOMIC)
   1.740 +
   1.741 +/* can we read something from so? */
   1.742 +#define	soreadable(so) \
   1.743 +    ((int)((so)->so_rcv.sb_cc) >= (so)->so_rcv.sb_lowat || \
   1.744 +	((so)->so_rcv.sb_state & SBS_CANTRCVMORE) || \
   1.745 +	!TAILQ_EMPTY(&(so)->so_comp) || (so)->so_error)
   1.746 +
   1.747 +#if 0  /*  original */
   1.748 +#define PR_CONNREQUIRED 0x04  /* from sys/protosw.h "needed" for sowriteable */
   1.749 +#define	sowriteable(so) \
   1.750 +    ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
   1.751 +	(((so)->so_state&SS_ISCONNECTED) || \
   1.752 +	  ((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0)) || \
   1.753 +     ((so)->so_snd.sb_state & SBS_CANTSENDMORE) || \
   1.754 +     (so)->so_error)
   1.755 +#else  /* line with PR_CONNREQUIRED removed */
   1.756 +/* can we write something to so? */
   1.757 +#define	sowriteable(so) \
   1.758 +    ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
   1.759 +      (((so)->so_state&SS_ISCONNECTED))) ||              \
   1.760 +     ((so)->so_snd.sb_state & SBS_CANTSENDMORE) || \
   1.761 +     (so)->so_error)
   1.762 +#endif
   1.763 +
   1.764 +extern void solisten_proto(struct socket *so, int backlog);
   1.765 +extern int solisten_proto_check(struct socket *so);
   1.766 +extern int sctp_listen(struct socket *so, int backlog, struct proc *p);
   1.767 +extern void socantrcvmore_locked(struct socket *so);
   1.768 +extern int sctp_bind(struct socket *so, struct sockaddr *addr);
   1.769 +extern int sctp6_bind(struct socket *so, struct sockaddr *addr, void *proc);
   1.770 +#if defined(__Userspace__)
   1.771 +extern int sctpconn_bind(struct socket *so, struct sockaddr *addr);
   1.772 +#endif
   1.773 +extern int sctp_accept(struct socket *so, struct sockaddr **addr);
   1.774 +extern int sctp_attach(struct socket *so, int proto, uint32_t vrf_id);
   1.775 +extern int sctp6_attach(struct socket *so, int proto, uint32_t vrf_id);
   1.776 +extern int sctp_abort(struct socket *so);
   1.777 +extern int sctp6_abort(struct socket *so);
   1.778 +extern void sctp_close(struct socket *so);
   1.779 +extern int soaccept(struct socket *so, struct sockaddr **nam);
   1.780 +extern int solisten(struct socket *so, int backlog);
   1.781 +extern int  soreserve(struct socket *so, u_long sndcc, u_long rcvcc);
   1.782 +extern void sowakeup(struct socket *so, struct sockbuf *sb);
   1.783 +extern void wakeup(void *ident, struct socket *so); /*__Userspace__ */
   1.784 +extern int uiomove(void *cp, int n, struct uio *uio);
   1.785 +extern int sbwait(struct sockbuf *sb);
   1.786 +extern int sodisconnect(struct socket *so);
   1.787 +extern int soconnect(struct socket *so, struct sockaddr *nam);
   1.788 +extern int sctp_disconnect(struct socket *so);
   1.789 +extern int sctp_connect(struct socket *so, struct sockaddr *addr);
   1.790 +extern int sctp6_connect(struct socket *so, struct sockaddr *addr);
   1.791 +#if defined(__Userspace__)
   1.792 +extern int sctpconn_connect(struct socket *so, struct sockaddr *addr);
   1.793 +#endif
   1.794 +extern void sctp_finish(void);
   1.795 +
   1.796 +/* ------------------------------------------------ */
   1.797 +/* -----  macros copied from above ---- */
   1.798 +/* ------------------------------------------------ */
   1.799 +
   1.800 +/*
   1.801 + * Do we need to notify the other side when I/O is possible?
   1.802 + */
   1.803 +#define	sb_notify(sb)	(((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \
   1.804 +    SB_UPCALL | SB_AIO | SB_KNOTE)) != 0)
   1.805 +
   1.806 +
   1.807 +/*
   1.808 + * In sorwakeup() and sowwakeup(), acquire the socket buffer lock to
   1.809 + * avoid a non-atomic test-and-wakeup.  However, sowakeup is
   1.810 + * responsible for releasing the lock if it is called.  We unlock only
   1.811 + * if we don't call into sowakeup.  If any code is introduced that
   1.812 + * directly invokes the underlying sowakeup() primitives, it must
   1.813 + * maintain the same semantics.
   1.814 + */
   1.815 +#define	sorwakeup_locked(so) do {					\
   1.816 +	SOCKBUF_LOCK_ASSERT(&(so)->so_rcv);				\
   1.817 +	if (sb_notify(&(so)->so_rcv))					\
   1.818 +		sowakeup((so), &(so)->so_rcv);	 			\
   1.819 +	else								\
   1.820 +		SOCKBUF_UNLOCK(&(so)->so_rcv);				\
   1.821 +} while (0)
   1.822 +
   1.823 +#define	sorwakeup(so) do {						\
   1.824 +	SOCKBUF_LOCK(&(so)->so_rcv);					\
   1.825 +	sorwakeup_locked(so);						\
   1.826 +} while (0)
   1.827 +
   1.828 +#define	sowwakeup_locked(so) do {					\
   1.829 +	SOCKBUF_LOCK_ASSERT(&(so)->so_snd);				\
   1.830 +	if (sb_notify(&(so)->so_snd))					\
   1.831 +		sowakeup((so), &(so)->so_snd); 				\
   1.832 +	else								\
   1.833 +		SOCKBUF_UNLOCK(&(so)->so_snd);				\
   1.834 +} while (0)
   1.835 +
   1.836 +#define	sowwakeup(so) do {						\
   1.837 +	SOCKBUF_LOCK(&(so)->so_snd);					\
   1.838 +	sowwakeup_locked(so);						\
   1.839 +} while (0)
   1.840 +
   1.841 +
   1.842 +
   1.843 +#endif /* __Userspace__ */
   1.844 +
   1.845 +#endif /* !_SYS_SOCKETVAR_H_ */

mercurial