socketvar.h revision 160619
1251881Speter/*-
2251881Speter * Copyright (c) 1982, 1986, 1990, 1993
3251881Speter *	The Regents of the University of California.  All rights reserved.
4251881Speter *
5251881Speter * Redistribution and use in source and binary forms, with or without
6251881Speter * modification, are permitted provided that the following conditions
7251881Speter * are met:
8251881Speter * 1. Redistributions of source code must retain the above copyright
9251881Speter *    notice, this list of conditions and the following disclaimer.
10251881Speter * 2. Redistributions in binary form must reproduce the above copyright
11251881Speter *    notice, this list of conditions and the following disclaimer in the
12251881Speter *    documentation and/or other materials provided with the distribution.
13251881Speter * 4. Neither the name of the University nor the names of its contributors
14251881Speter *    may be used to endorse or promote products derived from this software
15251881Speter *    without specific prior written permission.
16251881Speter *
17251881Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18251881Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19251881Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20251881Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21251881Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22251881Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23251881Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24251881Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25251881Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26251881Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27251881Speter * SUCH DAMAGE.
28251881Speter *
29251881Speter *	@(#)socketvar.h	8.3 (Berkeley) 2/19/95
30251881Speter * $FreeBSD: head/sys/sys/socketvar.h 160619 2006-07-24 15:20:08Z rwatson $
31251881Speter */
32251881Speter
33251881Speter#ifndef _SYS_SOCKETVAR_H_
34251881Speter#define _SYS_SOCKETVAR_H_
35251881Speter
36251881Speter#include <sys/queue.h>			/* for TAILQ macros */
37251881Speter#include <sys/selinfo.h>		/* for struct selinfo */
38251881Speter#include <sys/_lock.h>
39251881Speter#include <sys/_mutex.h>
40251881Speter
41251881Speter/*
42251881Speter * Kernel structure per socket.
43251881Speter * Contains send and receive buffer queues,
44251881Speter * handle on protocol and pointer to protocol
45251881Speter * private data and error information.
46251881Speter */
47251881Spetertypedef	u_quad_t so_gen_t;
48251881Speter
49251881Speter/*-
50251881Speter * Locking key to struct socket:
51251881Speter * (a) constant after allocation, no locking required.
52251881Speter * (b) locked by SOCK_LOCK(so).
53251881Speter * (c) locked by SOCKBUF_LOCK(&so->so_rcv).
54251881Speter * (d) locked by SOCKBUF_LOCK(&so->so_snd).
55251881Speter * (e) locked by ACCEPT_LOCK().
56251881Speter * (f) not locked since integer reads/writes are atomic.
57251881Speter * (g) used only as a sleep/wakeup address, no value.
58251881Speter * (h) locked by global mutex so_global_mtx.
59251881Speter */
60251881Speterstruct socket {
61251881Speter	int	so_count;		/* (b) reference count */
62251881Speter	short	so_type;		/* (a) generic type, see socket.h */
63251881Speter	short	so_options;		/* from socket call, see socket.h */
64251881Speter	short	so_linger;		/* time to linger while closing */
65251881Speter	short	so_state;		/* (b) internal state flags SS_* */
66251881Speter	int	so_qstate;		/* (e) internal state flags SQ_* */
67251881Speter	void	*so_pcb;		/* protocol control block */
68251881Speter	struct	protosw *so_proto;	/* (a) protocol handle */
69251881Speter/*
70251881Speter * Variables for connection queuing.
71251881Speter * Socket where accepts occur is so_head in all subsidiary sockets.
72251881Speter * If so_head is 0, socket is not related to an accept.
73251881Speter * For head socket so_incomp queues partially completed connections,
74251881Speter * while so_comp is a queue of connections ready to be accepted.
75251881Speter * If a connection is aborted and it has so_head set, then
76251881Speter * it has to be pulled out of either so_incomp or so_comp.
77251881Speter * We allow connections to queue up based on current queue lengths
78251881Speter * and limit on number of queued connections for this socket.
79251881Speter */
80251881Speter	struct	socket *so_head;	/* (e) back pointer to listen socket */
81251881Speter	TAILQ_HEAD(, socket) so_incomp;	/* (e) queue of partial unaccepted connections */
82251881Speter	TAILQ_HEAD(, socket) so_comp;	/* (e) queue of complete unaccepted connections */
83251881Speter	TAILQ_ENTRY(socket) so_list;	/* (e) list of unaccepted connections */
84251881Speter	u_short	so_qlen;		/* (e) number of unaccepted connections */
85251881Speter	u_short	so_incqlen;		/* (e) number of unaccepted incomplete
86251881Speter					   connections */
87251881Speter	u_short	so_qlimit;		/* (e) max number queued connections */
88251881Speter	short	so_timeo;		/* (g) connection timeout */
89251881Speter	u_short	so_error;		/* (f) error affecting connection */
90251881Speter	struct	sigio *so_sigio;	/* [sg] information for async I/O or
91251881Speter					   out of band data (SIGURG) */
92251881Speter	u_long	so_oobmark;		/* (c) chars to oob mark */
93251881Speter	TAILQ_HEAD(, aiocblist) so_aiojobq; /* AIO ops waiting on socket */
94251881Speter/*
95251881Speter * Variables for socket buffering.
96251881Speter */
97251881Speter	struct sockbuf {
98251881Speter		struct	selinfo sb_sel;	/* process selecting read/write */
99251881Speter		struct	mtx sb_mtx;	/* sockbuf lock */
100251881Speter		short	sb_state;	/* (c/d) socket state on sockbuf */
101251881Speter#define	sb_startzero	sb_mb
102251881Speter		struct	mbuf *sb_mb;	/* (c/d) the mbuf chain */
103251881Speter		struct	mbuf *sb_mbtail; /* (c/d) the last mbuf in the chain */
104251881Speter		struct	mbuf *sb_lastrecord;	/* (c/d) first mbuf of last
105251881Speter						 * record in socket buffer */
106251881Speter		u_int	sb_cc;		/* (c/d) actual chars in buffer */
107251881Speter		u_int	sb_hiwat;	/* (c/d) max actual char count */
108251881Speter		u_int	sb_mbcnt;	/* (c/d) chars of mbufs used */
109251881Speter		u_int	sb_mbmax;	/* (c/d) max chars of mbufs to use */
110251881Speter		u_int	sb_ctl;		/* (c/d) non-data chars in buffer */
111251881Speter		int	sb_lowat;	/* (c/d) low water mark */
112251881Speter		int	sb_timeo;	/* (c/d) timeout for read/write */
113251881Speter		short	sb_flags;	/* (c/d) flags, see below */
114251881Speter	} so_rcv, so_snd;
115251881Speter/*
116251881Speter * Constants for sb_flags field of struct sockbuf.
117251881Speter */
118251881Speter#define	SB_MAX		(256*1024)	/* default for max chars in sockbuf */
119251881Speter/*
120251881Speter * Constants for sb_flags field of struct sockbuf.
121251881Speter */
122251881Speter#define	SB_LOCK		0x01		/* lock on data queue */
123251881Speter#define	SB_WANT		0x02		/* someone is waiting to lock */
124251881Speter#define	SB_WAIT		0x04		/* someone is waiting for data/space */
125251881Speter#define	SB_SEL		0x08		/* someone is selecting */
126251881Speter#define	SB_ASYNC	0x10		/* ASYNC I/O, need signals */
127251881Speter#define	SB_UPCALL	0x20		/* someone wants an upcall */
128251881Speter#define	SB_NOINTR	0x40		/* operations not interruptible */
129251881Speter#define SB_AIO		0x80		/* AIO operations queued */
130251881Speter#define SB_KNOTE	0x100		/* kernel note attached */
131251881Speter
132251881Speter	void	(*so_upcall)(struct socket *, void *, int);
133251881Speter	void	*so_upcallarg;
134251881Speter	struct	ucred *so_cred;		/* (a) user credentials */
135251881Speter	struct	label *so_label;	/* (b) MAC label for socket */
136251881Speter	struct	label *so_peerlabel;	/* (b) cached MAC label for peer */
137251881Speter	/* NB: generation count must not be first. */
138251881Speter	so_gen_t so_gencnt;		/* (h) generation count */
139251881Speter	void	*so_emuldata;		/* (b) private data for emulators */
140251881Speter 	struct so_accf {
141251881Speter		struct	accept_filter *so_accept_filter;
142251881Speter		void	*so_accept_filter_arg;	/* saved filter args */
143251881Speter		char	*so_accept_filter_str;	/* saved user args */
144251881Speter	} *so_accf;
145251881Speter};
146251881Speter
147251881Speter#define SB_EMPTY_FIXUP(sb) do {						\
148251881Speter	if ((sb)->sb_mb == NULL) {					\
149251881Speter		(sb)->sb_mbtail = NULL;					\
150251881Speter		(sb)->sb_lastrecord = NULL;				\
151251881Speter	}								\
152251881Speter} while (/*CONSTCOND*/0)
153251881Speter
154251881Speter/*
155251881Speter * Global accept mutex to serialize access to accept queues and
156251881Speter * fields associated with multiple sockets.  This allows us to
157251881Speter * avoid defining a lock order between listen and accept sockets
158251881Speter * until such time as it proves to be a good idea.
159251881Speter */
160251881Speterextern struct mtx accept_mtx;
161251881Speter#define	ACCEPT_LOCK_ASSERT()		mtx_assert(&accept_mtx, MA_OWNED)
162251881Speter#define	ACCEPT_UNLOCK_ASSERT()		mtx_assert(&accept_mtx, MA_NOTOWNED)
163251881Speter#define	ACCEPT_LOCK()			mtx_lock(&accept_mtx)
164251881Speter#define	ACCEPT_UNLOCK()			mtx_unlock(&accept_mtx)
165251881Speter
166251881Speter/*
167251881Speter * Per-socket buffer mutex used to protect most fields in the socket
168251881Speter * buffer.
169251881Speter */
170251881Speter#define	SOCKBUF_MTX(_sb)		(&(_sb)->sb_mtx)
171251881Speter#define	SOCKBUF_LOCK_INIT(_sb, _name) \
172251881Speter	mtx_init(SOCKBUF_MTX(_sb), _name, NULL, MTX_DEF)
173251881Speter#define	SOCKBUF_LOCK_DESTROY(_sb)	mtx_destroy(SOCKBUF_MTX(_sb))
174251881Speter#define	SOCKBUF_LOCK(_sb)		mtx_lock(SOCKBUF_MTX(_sb))
175251881Speter#define	SOCKBUF_OWNED(_sb)		mtx_owned(SOCKBUF_MTX(_sb))
176251881Speter#define	SOCKBUF_UNLOCK(_sb)		mtx_unlock(SOCKBUF_MTX(_sb))
177251881Speter#define	SOCKBUF_LOCK_ASSERT(_sb)	mtx_assert(SOCKBUF_MTX(_sb), MA_OWNED)
178251881Speter#define	SOCKBUF_UNLOCK_ASSERT(_sb)	mtx_assert(SOCKBUF_MTX(_sb), MA_NOTOWNED)
179251881Speter
180251881Speter/*
181251881Speter * Per-socket mutex: we reuse the receive socket buffer mutex for space
182251881Speter * efficiency.  This decision should probably be revisited as we optimize
183251881Speter * locking for the socket code.
184251881Speter */
185251881Speter#define	SOCK_MTX(_so)			SOCKBUF_MTX(&(_so)->so_rcv)
186251881Speter#define	SOCK_LOCK(_so)			SOCKBUF_LOCK(&(_so)->so_rcv)
187251881Speter#define	SOCK_OWNED(_so)			SOCKBUF_OWNED(&(_so)->so_rcv)
188251881Speter#define	SOCK_UNLOCK(_so)		SOCKBUF_UNLOCK(&(_so)->so_rcv)
189251881Speter#define	SOCK_LOCK_ASSERT(_so)		SOCKBUF_LOCK_ASSERT(&(_so)->so_rcv)
190251881Speter
191251881Speter/*
192251881Speter * Socket state bits.
193251881Speter *
194251881Speter * Historically, this bits were all kept in the so_state field.  For
195251881Speter * locking reasons, they are now in multiple fields, as they are
196251881Speter * locked differently.  so_state maintains basic socket state protected
197251881Speter * by the socket lock.  so_qstate holds information about the socket
198251881Speter * accept queues.  Each socket buffer also has a state field holding
199251881Speter * information relevant to that socket buffer (can't send, rcv).  Many
200251881Speter * fields will be read without locks to improve performance and avoid
201251881Speter * lock order issues.  However, this approach must be used with caution.
202251881Speter */
203251881Speter#define	SS_NOFDREF		0x0001	/* no file table ref any more */
204251881Speter#define	SS_ISCONNECTED		0x0002	/* socket connected to a peer */
205251881Speter#define	SS_ISCONNECTING		0x0004	/* in process of connecting to peer */
206251881Speter#define	SS_ISDISCONNECTING	0x0008	/* in process of disconnecting */
207251881Speter#define	SS_NBIO			0x0100	/* non-blocking ops */
208251881Speter#define	SS_ASYNC		0x0200	/* async i/o notify */
209251881Speter#define	SS_ISCONFIRMING		0x0400	/* deciding to accept connection req */
210251881Speter#define	SS_ISDISCONNECTED	0x2000	/* socket disconnected from peer */
211251881Speter/*
212251881Speter * Protocols can mark a socket as SS_PROTOREF to indicate that, following
213251881Speter * pru_detach, they still want the socket to persist, and will free it
214251881Speter * themselves when they are done.  Protocols should only ever call sofree()
215251881Speter * following setting this flag in pru_detach(), and never otherwise, as
216251881Speter * sofree() bypasses socket reference counting.
217251881Speter */
218251881Speter#define	SS_PROTOREF		0x4000	/* strong protocol reference */
219251881Speter
220251881Speter/*
221251881Speter * Socket state bits now stored in the socket buffer state field.
222251881Speter */
223251881Speter#define	SBS_CANTSENDMORE	0x0010	/* can't send more data to peer */
224251881Speter#define	SBS_CANTRCVMORE		0x0020	/* can't receive more data from peer */
225251881Speter#define	SBS_RCVATMARK		0x0040	/* at mark on input */
226251881Speter
227251881Speter/*
228251881Speter * Socket state bits stored in so_qstate.
229251881Speter */
230251881Speter#define	SQ_INCOMP		0x0800	/* unaccepted, incomplete connection */
231251881Speter#define	SQ_COMP			0x1000	/* unaccepted, complete connection */
232251881Speter
233251881Speter/*
234251881Speter * Externalized form of struct socket used by the sysctl(3) interface.
235251881Speter */
236251881Speterstruct xsocket {
237251881Speter	size_t	xso_len;	/* length of this structure */
238251881Speter	struct	socket *xso_so;	/* makes a convenient handle sometimes */
239251881Speter	short	so_type;
240251881Speter	short	so_options;
241251881Speter	short	so_linger;
242251881Speter	short	so_state;
243251881Speter	caddr_t	so_pcb;		/* another convenient handle */
244251881Speter	int	xso_protocol;
245251881Speter	int	xso_family;
246251881Speter	u_short	so_qlen;
247251881Speter	u_short	so_incqlen;
248251881Speter	u_short	so_qlimit;
249251881Speter	short	so_timeo;
250251881Speter	u_short	so_error;
251251881Speter	pid_t	so_pgid;
252251881Speter	u_long	so_oobmark;
253251881Speter	struct xsockbuf {
254251881Speter		u_int	sb_cc;
255251881Speter		u_int	sb_hiwat;
256251881Speter		u_int	sb_mbcnt;
257251881Speter		u_int	sb_mbmax;
258251881Speter		int	sb_lowat;
259251881Speter		int	sb_timeo;
260251881Speter		short	sb_flags;
261251881Speter	} so_rcv, so_snd;
262251881Speter	uid_t	so_uid;		/* XXX */
263251881Speter};
264251881Speter
265251881Speter#ifdef _KERNEL
266251881Speter
267251881Speter/*
268251881Speter * Macros for sockets and socket buffering.
269251881Speter */
270251881Speter
271251881Speter/*
272251881Speter * Do we need to notify the other side when I/O is possible?
273251881Speter */
274251881Speter#define	sb_notify(sb)	(((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \
275251881Speter    SB_UPCALL | SB_AIO | SB_KNOTE)) != 0)
276251881Speter
277251881Speter/*
278251881Speter * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
279251881Speter * This is problematical if the fields are unsigned, as the space might
280251881Speter * still be negative (cc > hiwat or mbcnt > mbmax).  Should detect
281251881Speter * overflow and return 0.  Should use "lmin" but it doesn't exist now.
282251881Speter */
283251881Speter#define	sbspace(sb) \
284251881Speter    ((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \
285251881Speter	 (int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
286251881Speter
287251881Speter/* do we have to send all at once on a socket? */
288251881Speter#define	sosendallatonce(so) \
289251881Speter    ((so)->so_proto->pr_flags & PR_ATOMIC)
290251881Speter
291251881Speter/* can we read something from so? */
292251881Speter#define	soreadable(so) \
293251881Speter    ((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
294251881Speter	((so)->so_rcv.sb_state & SBS_CANTRCVMORE) || \
295251881Speter	!TAILQ_EMPTY(&(so)->so_comp) || (so)->so_error)
296251881Speter
297251881Speter/* can we write something to so? */
298251881Speter#define	sowriteable(so) \
299251881Speter    ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
300251881Speter	(((so)->so_state&SS_ISCONNECTED) || \
301251881Speter	  ((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0)) || \
302251881Speter     ((so)->so_snd.sb_state & SBS_CANTSENDMORE) || \
303251881Speter     (so)->so_error)
304251881Speter
305251881Speter/* adjust counters in sb reflecting allocation of m */
306251881Speter#define	sballoc(sb, m) { \
307251881Speter	(sb)->sb_cc += (m)->m_len; \
308251881Speter	if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
309251881Speter		(sb)->sb_ctl += (m)->m_len; \
310251881Speter	(sb)->sb_mbcnt += MSIZE; \
311251881Speter	if ((m)->m_flags & M_EXT) \
312251881Speter		(sb)->sb_mbcnt += (m)->m_ext.ext_size; \
313251881Speter}
314251881Speter
315251881Speter/* adjust counters in sb reflecting freeing of m */
316251881Speter#define	sbfree(sb, m) { \
317251881Speter	(sb)->sb_cc -= (m)->m_len; \
318251881Speter	if ((m)->m_type != MT_DATA && (m)->m_type != MT_OOBDATA) \
319251881Speter		(sb)->sb_ctl -= (m)->m_len; \
320251881Speter	(sb)->sb_mbcnt -= MSIZE; \
321251881Speter	if ((m)->m_flags & M_EXT) \
322251881Speter		(sb)->sb_mbcnt -= (m)->m_ext.ext_size; \
323251881Speter}
324251881Speter
325251881Speter/*
326251881Speter * Set lock on sockbuf sb; sleep if lock is already held.
327251881Speter * Unless SB_NOINTR is set on sockbuf, sleep is interruptible.
328251881Speter * Returns error without lock if sleep is interrupted.
329251881Speter */
330251881Speter#define sblock(sb, wf) ((sb)->sb_flags & SB_LOCK ? \
331251881Speter		(((wf) == M_WAITOK) ? sb_lock(sb) : EWOULDBLOCK) : \
332251881Speter		((sb)->sb_flags |= SB_LOCK), 0)
333251881Speter
334251881Speter/* release lock on sockbuf sb */
335251881Speter#define	sbunlock(sb) do { \
336251881Speter	SOCKBUF_LOCK_ASSERT(sb); \
337251881Speter	(sb)->sb_flags &= ~SB_LOCK; \
338251881Speter	if ((sb)->sb_flags & SB_WANT) { \
339251881Speter		(sb)->sb_flags &= ~SB_WANT; \
340251881Speter		wakeup(&(sb)->sb_flags); \
341251881Speter	} \
342251881Speter} while (0)
343251881Speter
344251881Speter/*
345251881Speter * soref()/sorele() ref-count the socket structure.  Note that you must
346251881Speter * still explicitly close the socket, but the last ref count will free
347251881Speter * the structure.
348251881Speter */
349251881Speter#define	soref(so) do {							\
350251881Speter	SOCK_LOCK_ASSERT(so);						\
351251881Speter	++(so)->so_count;						\
352251881Speter} while (0)
353251881Speter
354251881Speter#define	sorele(so) do {							\
355251881Speter	ACCEPT_LOCK_ASSERT();						\
356251881Speter	SOCK_LOCK_ASSERT(so);						\
357251881Speter	if ((so)->so_count <= 0)					\
358251881Speter		panic("sorele");					\
359251881Speter	if (--(so)->so_count == 0)					\
360251881Speter		sofree(so);						\
361251881Speter	else {								\
362251881Speter		SOCK_UNLOCK(so);					\
363251881Speter		ACCEPT_UNLOCK();					\
364251881Speter	}								\
365251881Speter} while (0)
366251881Speter
367251881Speter#define	sotryfree(so) do {						\
368251881Speter	ACCEPT_LOCK_ASSERT();						\
369251881Speter	SOCK_LOCK_ASSERT(so);						\
370251881Speter	if ((so)->so_count == 0)					\
371251881Speter		sofree(so);						\
372251881Speter	else {								\
373251881Speter		SOCK_UNLOCK(so);					\
374251881Speter		ACCEPT_UNLOCK();					\
375251881Speter	}								\
376251881Speter} while(0)
377251881Speter
378251881Speter/*
379251881Speter * In sorwakeup() and sowwakeup(), acquire the socket buffer lock to
380251881Speter * avoid a non-atomic test-and-wakeup.  However, sowakeup is
381251881Speter * responsible for releasing the lock if it is called.  We unlock only
382251881Speter * if we don't call into sowakeup.  If any code is introduced that
383251881Speter * directly invokes the underlying sowakeup() primitives, it must
384251881Speter * maintain the same semantics.
385251881Speter */
386251881Speter#define	sorwakeup_locked(so) do {					\
387251881Speter	SOCKBUF_LOCK_ASSERT(&(so)->so_rcv);				\
388251881Speter	if (sb_notify(&(so)->so_rcv))					\
389251881Speter		sowakeup((so), &(so)->so_rcv);	 			\
390251881Speter	else								\
391251881Speter		SOCKBUF_UNLOCK(&(so)->so_rcv);				\
392251881Speter} while (0)
393251881Speter
394251881Speter#define	sorwakeup(so) do {						\
395251881Speter	SOCKBUF_LOCK(&(so)->so_rcv);					\
396251881Speter	sorwakeup_locked(so);						\
397251881Speter} while (0)
398251881Speter
399251881Speter#define	sowwakeup_locked(so) do {					\
400251881Speter	SOCKBUF_LOCK_ASSERT(&(so)->so_snd);				\
401251881Speter	if (sb_notify(&(so)->so_snd))					\
402251881Speter		sowakeup((so), &(so)->so_snd); 				\
403251881Speter	else								\
404251881Speter		SOCKBUF_UNLOCK(&(so)->so_snd);				\
405251881Speter} while (0)
406251881Speter
407251881Speter#define	sowwakeup(so) do {						\
408251881Speter	SOCKBUF_LOCK(&(so)->so_snd);					\
409251881Speter	sowwakeup_locked(so);						\
410251881Speter} while (0)
411251881Speter
412251881Speter/*
413251881Speter * Argument structure for sosetopt et seq.  This is in the KERNEL
414251881Speter * section because it will never be visible to user code.
415251881Speter */
416251881Speterenum sopt_dir { SOPT_GET, SOPT_SET };
417251881Speterstruct sockopt {
418251881Speter	enum	sopt_dir sopt_dir; /* is this a get or a set? */
419251881Speter	int	sopt_level;	/* second arg of [gs]etsockopt */
420251881Speter	int	sopt_name;	/* third arg of [gs]etsockopt */
421251881Speter	void   *sopt_val;	/* fourth arg of [gs]etsockopt */
422251881Speter	size_t	sopt_valsize;	/* (almost) fifth arg of [gs]etsockopt */
423251881Speter	struct	thread *sopt_td; /* calling thread or null if kernel */
424251881Speter};
425251881Speter
426251881Speterstruct accept_filter {
427251881Speter	char	accf_name[16];
428251881Speter	void	(*accf_callback)
429251881Speter		(struct socket *so, void *arg, int waitflag);
430251881Speter	void *	(*accf_create)
431251881Speter		(struct socket *so, char *arg);
432251881Speter	void	(*accf_destroy)
433251881Speter		(struct socket *so);
434251881Speter	SLIST_ENTRY(accept_filter) accf_next;
435251881Speter};
436251881Speter
437251881Speter#ifdef MALLOC_DECLARE
438251881SpeterMALLOC_DECLARE(M_ACCF);
439251881SpeterMALLOC_DECLARE(M_PCB);
440251881SpeterMALLOC_DECLARE(M_SONAME);
441251881Speter#endif
442251881Speter
443251881Speterextern int	maxsockets;
444251881Speterextern u_long	sb_max;
445251881Speterextern struct uma_zone *socket_zone;
446251881Speterextern so_gen_t so_gencnt;
447251881Speter
448251881Speterstruct mbuf;
449251881Speterstruct sockaddr;
450251881Speterstruct ucred;
451251881Speterstruct uio;
452251881Speter
453251881Speter/*
454251881Speter * From uipc_socket and friends
455251881Speter */
456251881Speterint	do_getopt_accept_filter(struct socket *so, struct sockopt *sopt);
457251881Speterint	do_setopt_accept_filter(struct socket *so, struct sockopt *sopt);
458251881Speterint	so_setsockopt(struct socket *so, int level, int optname,
459251881Speter	    void *optval, size_t optlen);
460251881Speterint	sockargs(struct mbuf **mp, caddr_t buf, int buflen, int type);
461251881Speterint	getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len);
462251881Spetervoid	sbappend(struct sockbuf *sb, struct mbuf *m);
463251881Spetervoid	sbappend_locked(struct sockbuf *sb, struct mbuf *m);
464251881Spetervoid	sbappendstream(struct sockbuf *sb, struct mbuf *m);
465251881Spetervoid	sbappendstream_locked(struct sockbuf *sb, struct mbuf *m);
466251881Speterint	sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
467251881Speter	    struct mbuf *m0, struct mbuf *control);
468251881Speterint	sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
469251881Speter	    struct mbuf *m0, struct mbuf *control);
470251881Speterint	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
471251881Speter	    struct mbuf *control);
472251881Speterint	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
473251881Speter	    struct mbuf *control);
474251881Spetervoid	sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
475251881Spetervoid	sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
476251881Spetervoid	sbcheck(struct sockbuf *sb);
477251881Spetervoid	sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
478251881Speterstruct mbuf *
479251881Speter	sbcreatecontrol(caddr_t p, int size, int type, int level);
480251881Spetervoid	sbdrop(struct sockbuf *sb, int len);
481251881Spetervoid	sbdrop_locked(struct sockbuf *sb, int len);
482251881Spetervoid	sbdroprecord(struct sockbuf *sb);
483251881Spetervoid	sbdroprecord_locked(struct sockbuf *sb);
484251881Spetervoid	sbflush(struct sockbuf *sb);
485251881Spetervoid	sbflush_locked(struct sockbuf *sb);
486251881Spetervoid	sbrelease(struct sockbuf *sb, struct socket *so);
487251881Spetervoid	sbrelease_locked(struct sockbuf *sb, struct socket *so);
488251881Speterint	sbreserve(struct sockbuf *sb, u_long cc, struct socket *so,
489251881Speter	    struct thread *td);
490251881Speterint	sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
491251881Speter	    struct thread *td);
492251881Spetervoid	sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb);
493251881Speterint	sbwait(struct sockbuf *sb);
494251881Speterint	sb_lock(struct sockbuf *sb);
495251881Spetervoid	soabort(struct socket *so);
496251881Speterint	soaccept(struct socket *so, struct sockaddr **nam);
497251881Speterint	socheckuid(struct socket *so, uid_t uid);
498251881Speterint	sobind(struct socket *so, struct sockaddr *nam, struct thread *td);
499251881Spetervoid	socantrcvmore(struct socket *so);
500251881Spetervoid	socantrcvmore_locked(struct socket *so);
501251881Spetervoid	socantsendmore(struct socket *so);
502251881Spetervoid	socantsendmore_locked(struct socket *so);
503251881Speterint	soclose(struct socket *so);
504251881Speterint	soconnect(struct socket *so, struct sockaddr *nam, struct thread *td);
505251881Speterint	soconnect2(struct socket *so1, struct socket *so2);
506251881Speterint	socow_setup(struct mbuf *m0, struct uio *uio);
507251881Speterint	socreate(int dom, struct socket **aso, int type, int proto,
508251881Speter	    struct ucred *cred, struct thread *td);
509251881Speterint	sodisconnect(struct socket *so);
510251881Speterstruct	sockaddr *sodupsockaddr(const struct sockaddr *sa, int mflags);
511251881Spetervoid	sofree(struct socket *so);
512251881Speterint	sogetopt(struct socket *so, struct sockopt *sopt);
513251881Spetervoid	sohasoutofband(struct socket *so);
514251881Spetervoid	soisconnected(struct socket *so);
515251881Spetervoid	soisconnecting(struct socket *so);
516251881Spetervoid	soisdisconnected(struct socket *so);
517251881Spetervoid	soisdisconnecting(struct socket *so);
518251881Speterint	solisten(struct socket *so, int backlog, struct thread *td);
519251881Spetervoid	solisten_proto(struct socket *so, int backlog);
520251881Speterint	solisten_proto_check(struct socket *so);
521251881Speterstruct socket *
522251881Speter	sonewconn(struct socket *head, int connstatus);
523251881Speterint	sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen);
524251881Speterint	sooptcopyout(struct sockopt *sopt, const void *buf, size_t len);
525251881Speter
526251881Speter/* XXX; prepare mbuf for (__FreeBSD__ < 3) routines. */
527251881Speterint	soopt_getm(struct sockopt *sopt, struct mbuf **mp);
528251881Speterint	soopt_mcopyin(struct sockopt *sopt, struct mbuf *m);
529251881Speterint	soopt_mcopyout(struct sockopt *sopt, struct mbuf *m);
530251881Speter
531251881Speterint	sopoll(struct socket *so, int events, struct ucred *active_cred,
532251881Speter	    struct thread *td);
533251881Speterint	sopoll_generic(struct socket *so, int events,
534251881Speter	    struct ucred *active_cred, struct thread *td);
535251881Speterint	soreceive(struct socket *so, struct sockaddr **paddr, struct uio *uio,
536251881Speter	    struct mbuf **mp0, struct mbuf **controlp, int *flagsp);
537251881Speterint	soreceive_generic(struct socket *so, struct sockaddr **paddr,
538251881Speter	    struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
539251881Speter	    int *flagsp);
540251881Speterint	soreserve(struct socket *so, u_long sndcc, u_long rcvcc);
541251881Spetervoid	sorflush(struct socket *so);
542251881Speterint	sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
543251881Speter	    struct mbuf *top, struct mbuf *control, int flags,
544251881Speter	    struct thread *td);
545251881Speterint	sosend_dgram(struct socket *so, struct sockaddr *addr,
546251881Speter	    struct uio *uio, struct mbuf *top, struct mbuf *control,
547251881Speter	    int flags, struct thread *td);
548251881Speterint	sosend_generic(struct socket *so, struct sockaddr *addr,
549251881Speter	    struct uio *uio, struct mbuf *top, struct mbuf *control,
550251881Speter	    int flags, struct thread *td);
551251881Speterint	sosetopt(struct socket *so, struct sockopt *sopt);
552251881Speterint	soshutdown(struct socket *so, int how);
553251881Spetervoid	sotoxsocket(struct socket *so, struct xsocket *xso);
554251881Spetervoid	sowakeup(struct socket *so, struct sockbuf *sb);
555251881Speter
556251881Speter#ifdef SOCKBUF_DEBUG
557251881Spetervoid	sblastrecordchk(struct sockbuf *, const char *, int);
558251881Speter#define	SBLASTRECORDCHK(sb)	sblastrecordchk((sb), __FILE__, __LINE__)
559251881Speter
560251881Spetervoid	sblastmbufchk(struct sockbuf *, const char *, int);
561251881Speter#define	SBLASTMBUFCHK(sb)	sblastmbufchk((sb), __FILE__, __LINE__)
562251881Speter#else
563251881Speter#define	SBLASTRECORDCHK(sb)      /* nothing */
564251881Speter#define	SBLASTMBUFCHK(sb)        /* nothing */
565251881Speter#endif /* SOCKBUF_DEBUG */
566251881Speter
567251881Speter/*
568251881Speter * Accept filter functions (duh).
569251881Speter */
570251881Speterint	accept_filt_add(struct accept_filter *filt);
571251881Speterint	accept_filt_del(char *name);
572251881Speterstruct	accept_filter *accept_filt_get(char *name);
573251881Speter#ifdef ACCEPT_FILTER_MOD
574251881Speter#ifdef SYSCTL_DECL
575251881SpeterSYSCTL_DECL(_net_inet_accf);
576251881Speter#endif
577251881Speterint	accept_filt_generic_mod_event(module_t mod, int event, void *data);
578251881Speter#endif
579251881Speter
580251881Speter#endif /* _KERNEL */
581251881Speter
582251881Speter#endif /* !_SYS_SOCKETVAR_H_ */
583251881Speter