xref: /f-stack/freebsd/sys/sockbuf.h (revision 22ce4aff)
1a9643ea8Slogwang /*-
2*22ce4affSfengbojiang  * SPDX-License-Identifier: BSD-3-Clause
3*22ce4affSfengbojiang  *
4a9643ea8Slogwang  * Copyright (c) 1982, 1986, 1990, 1993
5a9643ea8Slogwang  *	The Regents of the University of California.  All rights reserved.
6a9643ea8Slogwang  *
7a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
8a9643ea8Slogwang  * modification, are permitted provided that the following conditions
9a9643ea8Slogwang  * are met:
10a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright
11a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer.
12a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
13a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer in the
14a9643ea8Slogwang  *    documentation and/or other materials provided with the distribution.
15*22ce4affSfengbojiang  * 3. Neither the name of the University nor the names of its contributors
16a9643ea8Slogwang  *    may be used to endorse or promote products derived from this software
17a9643ea8Slogwang  *    without specific prior written permission.
18a9643ea8Slogwang  *
19a9643ea8Slogwang  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20a9643ea8Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21a9643ea8Slogwang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22a9643ea8Slogwang  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23a9643ea8Slogwang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24a9643ea8Slogwang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25a9643ea8Slogwang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26a9643ea8Slogwang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27a9643ea8Slogwang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28a9643ea8Slogwang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29a9643ea8Slogwang  * SUCH DAMAGE.
30a9643ea8Slogwang  *
31a9643ea8Slogwang  *	@(#)socketvar.h	8.3 (Berkeley) 2/19/95
32a9643ea8Slogwang  *
33a9643ea8Slogwang  * $FreeBSD$
34a9643ea8Slogwang  */
35a9643ea8Slogwang #ifndef _SYS_SOCKBUF_H_
36a9643ea8Slogwang #define _SYS_SOCKBUF_H_
37a9643ea8Slogwang 
38a9643ea8Slogwang /*
39*22ce4affSfengbojiang  * Constants for sb_flags field of struct sockbuf/xsockbuf.
40a9643ea8Slogwang  */
41*22ce4affSfengbojiang #define	SB_TLS_RX	0x01		/* using KTLS on RX */
42*22ce4affSfengbojiang #define	SB_TLS_RX_RUNNING 0x02		/* KTLS RX operation running */
43a9643ea8Slogwang #define	SB_WAIT		0x04		/* someone is waiting for data/space */
44a9643ea8Slogwang #define	SB_SEL		0x08		/* someone is selecting */
45a9643ea8Slogwang #define	SB_ASYNC	0x10		/* ASYNC I/O, need signals */
46a9643ea8Slogwang #define	SB_UPCALL	0x20		/* someone wants an upcall */
47a9643ea8Slogwang #define	SB_NOINTR	0x40		/* operations not interruptible */
48a9643ea8Slogwang #define	SB_AIO		0x80		/* AIO operations queued */
49a9643ea8Slogwang #define	SB_KNOTE	0x100		/* kernel note attached */
50a9643ea8Slogwang #define	SB_NOCOALESCE	0x200		/* don't coalesce new data into existing mbufs */
51a9643ea8Slogwang #define	SB_IN_TOE	0x400		/* socket buffer is in the middle of an operation */
52a9643ea8Slogwang #define	SB_AUTOSIZE	0x800		/* automatically size socket buffer */
53a9643ea8Slogwang #define	SB_STOP		0x1000		/* backpressure indicator */
54a9643ea8Slogwang #define	SB_AIO_RUNNING	0x2000		/* AIO operation running */
55*22ce4affSfengbojiang #define	SB_TLS_IFNET	0x4000		/* has used / is using ifnet KTLS */
56a9643ea8Slogwang 
57a9643ea8Slogwang #define	SBS_CANTSENDMORE	0x0010	/* can't send more data to peer */
58a9643ea8Slogwang #define	SBS_CANTRCVMORE		0x0020	/* can't receive more data from peer */
59a9643ea8Slogwang #define	SBS_RCVATMARK		0x0040	/* at mark on input */
60a9643ea8Slogwang 
61*22ce4affSfengbojiang #if defined(_KERNEL) || defined(_WANT_SOCKET)
62*22ce4affSfengbojiang #include <sys/_lock.h>
63*22ce4affSfengbojiang #include <sys/_mutex.h>
64*22ce4affSfengbojiang #include <sys/_sx.h>
65*22ce4affSfengbojiang #include <sys/_task.h>
66*22ce4affSfengbojiang 
67*22ce4affSfengbojiang #define	SB_MAX		(2*1024*1024)	/* default for max chars in sockbuf */
68*22ce4affSfengbojiang 
69*22ce4affSfengbojiang struct ktls_session;
70a9643ea8Slogwang struct mbuf;
71a9643ea8Slogwang struct sockaddr;
72a9643ea8Slogwang struct socket;
73a9643ea8Slogwang struct thread;
74*22ce4affSfengbojiang struct selinfo;
75a9643ea8Slogwang 
76a9643ea8Slogwang /*
77a9643ea8Slogwang  * Variables for socket buffering.
78a9643ea8Slogwang  *
79a9643ea8Slogwang  * Locking key to struct sockbuf:
80a9643ea8Slogwang  * (a) locked by SOCKBUF_LOCK().
81*22ce4affSfengbojiang  * (b) locked by sblock()
82a9643ea8Slogwang  */
83a9643ea8Slogwang struct	sockbuf {
84a9643ea8Slogwang 	struct	mtx sb_mtx;		/* sockbuf lock */
85a9643ea8Slogwang 	struct	sx sb_sx;		/* prevent I/O interlacing */
86*22ce4affSfengbojiang 	struct	selinfo *sb_sel;	/* process selecting read/write */
87a9643ea8Slogwang 	short	sb_state;	/* (a) socket state on sockbuf */
88a9643ea8Slogwang #define	sb_startzero	sb_mb
89a9643ea8Slogwang 	struct	mbuf *sb_mb;	/* (a) the mbuf chain */
90a9643ea8Slogwang 	struct	mbuf *sb_mbtail; /* (a) the last mbuf in the chain */
91a9643ea8Slogwang 	struct	mbuf *sb_lastrecord;	/* (a) first mbuf of last
92a9643ea8Slogwang 					 * record in socket buffer */
93a9643ea8Slogwang 	struct	mbuf *sb_sndptr; /* (a) pointer into mbuf chain */
94a9643ea8Slogwang 	struct	mbuf *sb_fnrdy;	/* (a) pointer to first not ready buffer */
95a9643ea8Slogwang 	u_int	sb_sndptroff;	/* (a) byte offset of ptr into chain */
96a9643ea8Slogwang 	u_int	sb_acc;		/* (a) available chars in buffer */
97a9643ea8Slogwang 	u_int	sb_ccc;		/* (a) claimed chars in buffer */
98a9643ea8Slogwang 	u_int	sb_hiwat;	/* (a) max actual char count */
99a9643ea8Slogwang 	u_int	sb_mbcnt;	/* (a) chars of mbufs used */
100a9643ea8Slogwang 	u_int   sb_mcnt;        /* (a) number of mbufs in buffer */
101a9643ea8Slogwang 	u_int   sb_ccnt;        /* (a) number of clusters in buffer */
102a9643ea8Slogwang 	u_int	sb_mbmax;	/* (a) max chars of mbufs to use */
103a9643ea8Slogwang 	u_int	sb_ctl;		/* (a) non-data chars in buffer */
104*22ce4affSfengbojiang 	u_int	sb_tlscc;	/* (a) TLS chain characters */
105*22ce4affSfengbojiang 	u_int	sb_tlsdcc;	/* (a) TLS characters being decrypted */
106a9643ea8Slogwang 	int	sb_lowat;	/* (a) low water mark */
107a9643ea8Slogwang 	sbintime_t	sb_timeo;	/* (a) timeout for read/write */
108*22ce4affSfengbojiang 	uint64_t sb_tls_seqno;	/* (a) TLS seqno */
109*22ce4affSfengbojiang 	struct	ktls_session *sb_tls_info; /* (a + b) TLS state */
110*22ce4affSfengbojiang 	struct	mbuf *sb_mtls;	/* (a) TLS mbuf chain */
111*22ce4affSfengbojiang 	struct	mbuf *sb_mtlstail; /* (a) last mbuf in TLS chain */
112*22ce4affSfengbojiang 	short	sb_flags;	/* (a) flags, see above */
113a9643ea8Slogwang 	int	(*sb_upcall)(struct socket *, void *, int); /* (a) */
114a9643ea8Slogwang 	void	*sb_upcallarg;	/* (a) */
115a9643ea8Slogwang 	TAILQ_HEAD(, kaiocb) sb_aiojobq; /* (a) pending AIO ops */
116a9643ea8Slogwang 	struct	task sb_aiotask; /* AIO task */
117a9643ea8Slogwang };
118a9643ea8Slogwang 
119*22ce4affSfengbojiang #endif	/* defined(_KERNEL) || defined(_WANT_SOCKET) */
120a9643ea8Slogwang #ifdef _KERNEL
121a9643ea8Slogwang 
122a9643ea8Slogwang /*
123a9643ea8Slogwang  * Per-socket buffer mutex used to protect most fields in the socket
124a9643ea8Slogwang  * buffer.
125a9643ea8Slogwang  */
126a9643ea8Slogwang #define	SOCKBUF_MTX(_sb)		(&(_sb)->sb_mtx)
127a9643ea8Slogwang #define	SOCKBUF_LOCK_INIT(_sb, _name) \
128a9643ea8Slogwang 	mtx_init(SOCKBUF_MTX(_sb), _name, NULL, MTX_DEF)
129a9643ea8Slogwang #define	SOCKBUF_LOCK_DESTROY(_sb)	mtx_destroy(SOCKBUF_MTX(_sb))
130a9643ea8Slogwang #define	SOCKBUF_LOCK(_sb)		mtx_lock(SOCKBUF_MTX(_sb))
131a9643ea8Slogwang #define	SOCKBUF_OWNED(_sb)		mtx_owned(SOCKBUF_MTX(_sb))
132a9643ea8Slogwang #define	SOCKBUF_UNLOCK(_sb)		mtx_unlock(SOCKBUF_MTX(_sb))
133a9643ea8Slogwang #define	SOCKBUF_LOCK_ASSERT(_sb)	mtx_assert(SOCKBUF_MTX(_sb), MA_OWNED)
134a9643ea8Slogwang #define	SOCKBUF_UNLOCK_ASSERT(_sb)	mtx_assert(SOCKBUF_MTX(_sb), MA_NOTOWNED)
135a9643ea8Slogwang 
136a9643ea8Slogwang /*
137a9643ea8Slogwang  * Socket buffer private mbuf(9) flags.
138a9643ea8Slogwang  */
139a9643ea8Slogwang #define	M_NOTREADY	M_PROTO1	/* m_data not populated yet */
140a9643ea8Slogwang #define	M_BLOCKED	M_PROTO2	/* M_NOTREADY in front of m */
141a9643ea8Slogwang #define	M_NOTAVAIL	(M_NOTREADY | M_BLOCKED)
142a9643ea8Slogwang 
143a9643ea8Slogwang void	sbappend(struct sockbuf *sb, struct mbuf *m, int flags);
144a9643ea8Slogwang void	sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags);
145a9643ea8Slogwang void	sbappendstream(struct sockbuf *sb, struct mbuf *m, int flags);
146a9643ea8Slogwang void	sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags);
147a9643ea8Slogwang int	sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
148a9643ea8Slogwang 	    struct mbuf *m0, struct mbuf *control);
149a9643ea8Slogwang int	sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
150a9643ea8Slogwang 	    struct mbuf *m0, struct mbuf *control);
151a9643ea8Slogwang int	sbappendaddr_nospacecheck_locked(struct sockbuf *sb,
152a9643ea8Slogwang 	    const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control);
153*22ce4affSfengbojiang void	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
154*22ce4affSfengbojiang 	    struct mbuf *control, int flags);
155*22ce4affSfengbojiang void	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
156*22ce4affSfengbojiang 	    struct mbuf *control, int flags);
157a9643ea8Slogwang void	sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
158a9643ea8Slogwang void	sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
159a9643ea8Slogwang void	sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
160a9643ea8Slogwang struct mbuf *
161a9643ea8Slogwang 	sbcreatecontrol(caddr_t p, int size, int type, int level);
162*22ce4affSfengbojiang struct mbuf *
163*22ce4affSfengbojiang 	sbcreatecontrol_how(void *p, int size, int type, int level,
164*22ce4affSfengbojiang 	    int wait);
165a9643ea8Slogwang void	sbdestroy(struct sockbuf *sb, struct socket *so);
166a9643ea8Slogwang void	sbdrop(struct sockbuf *sb, int len);
167a9643ea8Slogwang void	sbdrop_locked(struct sockbuf *sb, int len);
168a9643ea8Slogwang struct mbuf *
169a9643ea8Slogwang 	sbcut_locked(struct sockbuf *sb, int len);
170a9643ea8Slogwang void	sbdroprecord(struct sockbuf *sb);
171a9643ea8Slogwang void	sbdroprecord_locked(struct sockbuf *sb);
172a9643ea8Slogwang void	sbflush(struct sockbuf *sb);
173a9643ea8Slogwang void	sbflush_locked(struct sockbuf *sb);
174a9643ea8Slogwang void	sbrelease(struct sockbuf *sb, struct socket *so);
175a9643ea8Slogwang void	sbrelease_internal(struct sockbuf *sb, struct socket *so);
176a9643ea8Slogwang void	sbrelease_locked(struct sockbuf *sb, struct socket *so);
177*22ce4affSfengbojiang int	sbsetopt(struct socket *so, int cmd, u_long cc);
178a9643ea8Slogwang int	sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
179a9643ea8Slogwang 	    struct thread *td);
180*22ce4affSfengbojiang void	sbsndptr_adv(struct sockbuf *sb, struct mbuf *mb, u_int len);
181a9643ea8Slogwang struct mbuf *
182*22ce4affSfengbojiang 	sbsndptr_noadv(struct sockbuf *sb, u_int off, u_int *moff);
183a9643ea8Slogwang struct mbuf *
184a9643ea8Slogwang 	sbsndmbuf(struct sockbuf *sb, u_int off, u_int *moff);
185a9643ea8Slogwang int	sbwait(struct sockbuf *sb);
186a9643ea8Slogwang int	sblock(struct sockbuf *sb, int flags);
187a9643ea8Slogwang void	sbunlock(struct sockbuf *sb);
188a9643ea8Slogwang void	sballoc(struct sockbuf *, struct mbuf *);
189a9643ea8Slogwang void	sbfree(struct sockbuf *, struct mbuf *);
190*22ce4affSfengbojiang void	sballoc_ktls_rx(struct sockbuf *sb, struct mbuf *m);
191*22ce4affSfengbojiang void	sbfree_ktls_rx(struct sockbuf *sb, struct mbuf *m);
192a9643ea8Slogwang int	sbready(struct sockbuf *, struct mbuf *, int);
193a9643ea8Slogwang 
194a9643ea8Slogwang /*
195a9643ea8Slogwang  * Return how much data is available to be taken out of socket
196a9643ea8Slogwang  * buffer right now.
197a9643ea8Slogwang  */
198a9643ea8Slogwang static inline u_int
sbavail(struct sockbuf * sb)199a9643ea8Slogwang sbavail(struct sockbuf *sb)
200a9643ea8Slogwang {
201a9643ea8Slogwang 
202a9643ea8Slogwang #if 0
203a9643ea8Slogwang 	SOCKBUF_LOCK_ASSERT(sb);
204a9643ea8Slogwang #endif
205a9643ea8Slogwang 	return (sb->sb_acc);
206a9643ea8Slogwang }
207a9643ea8Slogwang 
208a9643ea8Slogwang /*
209a9643ea8Slogwang  * Return how much data sits there in the socket buffer
210a9643ea8Slogwang  * It might be that some data is not yet ready to be read.
211a9643ea8Slogwang  */
212a9643ea8Slogwang static inline u_int
sbused(struct sockbuf * sb)213a9643ea8Slogwang sbused(struct sockbuf *sb)
214a9643ea8Slogwang {
215a9643ea8Slogwang 
216a9643ea8Slogwang #if 0
217a9643ea8Slogwang 	SOCKBUF_LOCK_ASSERT(sb);
218a9643ea8Slogwang #endif
219a9643ea8Slogwang 	return (sb->sb_ccc);
220a9643ea8Slogwang }
221a9643ea8Slogwang 
222a9643ea8Slogwang /*
223a9643ea8Slogwang  * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
224a9643ea8Slogwang  * This is problematical if the fields are unsigned, as the space might
225a9643ea8Slogwang  * still be negative (ccc > hiwat or mbcnt > mbmax).
226a9643ea8Slogwang  */
227a9643ea8Slogwang static inline long
sbspace(struct sockbuf * sb)228a9643ea8Slogwang sbspace(struct sockbuf *sb)
229a9643ea8Slogwang {
230a9643ea8Slogwang 	int bleft, mleft;		/* size should match sockbuf fields */
231a9643ea8Slogwang 
232a9643ea8Slogwang #if 0
233a9643ea8Slogwang 	SOCKBUF_LOCK_ASSERT(sb);
234a9643ea8Slogwang #endif
235a9643ea8Slogwang 
236a9643ea8Slogwang 	if (sb->sb_flags & SB_STOP)
237a9643ea8Slogwang 		return(0);
238a9643ea8Slogwang 
239a9643ea8Slogwang 	bleft = sb->sb_hiwat - sb->sb_ccc;
240a9643ea8Slogwang 	mleft = sb->sb_mbmax - sb->sb_mbcnt;
241a9643ea8Slogwang 
242a9643ea8Slogwang 	return ((bleft < mleft) ? bleft : mleft);
243a9643ea8Slogwang }
244a9643ea8Slogwang 
245a9643ea8Slogwang #define SB_EMPTY_FIXUP(sb) do {						\
246a9643ea8Slogwang 	if ((sb)->sb_mb == NULL) {					\
247a9643ea8Slogwang 		(sb)->sb_mbtail = NULL;					\
248a9643ea8Slogwang 		(sb)->sb_lastrecord = NULL;				\
249a9643ea8Slogwang 	}								\
250a9643ea8Slogwang } while (/*CONSTCOND*/0)
251a9643ea8Slogwang 
252a9643ea8Slogwang #ifdef SOCKBUF_DEBUG
253a9643ea8Slogwang void	sblastrecordchk(struct sockbuf *, const char *, int);
254a9643ea8Slogwang void	sblastmbufchk(struct sockbuf *, const char *, int);
255a9643ea8Slogwang void	sbcheck(struct sockbuf *, const char *, int);
256a9643ea8Slogwang #define	SBLASTRECORDCHK(sb)	sblastrecordchk((sb), __FILE__, __LINE__)
257a9643ea8Slogwang #define	SBLASTMBUFCHK(sb)	sblastmbufchk((sb), __FILE__, __LINE__)
258a9643ea8Slogwang #define	SBCHECK(sb)		sbcheck((sb), __FILE__, __LINE__)
259a9643ea8Slogwang #else
260a9643ea8Slogwang #define	SBLASTRECORDCHK(sb)	do {} while (0)
261a9643ea8Slogwang #define	SBLASTMBUFCHK(sb)	do {} while (0)
262a9643ea8Slogwang #define	SBCHECK(sb)		do {} while (0)
263a9643ea8Slogwang #endif /* SOCKBUF_DEBUG */
264a9643ea8Slogwang 
265a9643ea8Slogwang #endif /* _KERNEL */
266a9643ea8Slogwang 
267a9643ea8Slogwang #endif /* _SYS_SOCKBUF_H_ */
268