1b516438kmacy/*-
24736ccfpfg * SPDX-License-Identifier: BSD-3-Clause
34736ccfpfg *
4b516438kmacy * Copyright (c) 1982, 1986, 1990, 1993
5b516438kmacy *	The Regents of the University of California.  All rights reserved.
6b516438kmacy *
7b516438kmacy * Redistribution and use in source and binary forms, with or without
8b516438kmacy * modification, are permitted provided that the following conditions
9b516438kmacy * are met:
10b516438kmacy * 1. Redistributions of source code must retain the above copyright
11b516438kmacy *    notice, this list of conditions and the following disclaimer.
12b516438kmacy * 2. Redistributions in binary form must reproduce the above copyright
13b516438kmacy *    notice, this list of conditions and the following disclaimer in the
14b516438kmacy *    documentation and/or other materials provided with the distribution.
157e6cabdimp * 3. Neither the name of the University nor the names of its contributors
16b516438kmacy *    may be used to endorse or promote products derived from this software
17b516438kmacy *    without specific prior written permission.
18b516438kmacy *
19b516438kmacy * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20b516438kmacy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21b516438kmacy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22b516438kmacy * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23b516438kmacy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24b516438kmacy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25b516438kmacy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26b516438kmacy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27b516438kmacy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28b516438kmacy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29b516438kmacy * SUCH DAMAGE.
30b516438kmacy *
31b516438kmacy *	@(#)socketvar.h	8.3 (Berkeley) 2/19/95
32b516438kmacy *
33b516438kmacy * $FreeBSD$
34b516438kmacy */
35b516438kmacy#ifndef _SYS_SOCKBUF_H_
36b516438kmacy#define _SYS_SOCKBUF_H_
37b516438kmacy
38b516438kmacy/*
393f2bf60glebius * Constants for sb_flags field of struct sockbuf/xsockbuf.
40b516438kmacy */
41fb264c6jhb#define	SB_TLS_RX	0x01		/* using KTLS on RX */
42fb264c6jhb#define	SB_TLS_RX_RUNNING 0x02		/* KTLS RX operation running */
43b516438kmacy#define	SB_WAIT		0x04		/* someone is waiting for data/space */
44b516438kmacy#define	SB_SEL		0x08		/* someone is selecting */
45b516438kmacy#define	SB_ASYNC	0x10		/* ASYNC I/O, need signals */
46b516438kmacy#define	SB_UPCALL	0x20		/* someone wants an upcall */
47b516438kmacy#define	SB_NOINTR	0x40		/* operations not interruptible */
48b516438kmacy#define	SB_AIO		0x80		/* AIO operations queued */
49b516438kmacy#define	SB_KNOTE	0x100		/* kernel note attached */
50b516438kmacy#define	SB_NOCOALESCE	0x200		/* don't coalesce new data into existing mbufs */
51b516438kmacy#define	SB_IN_TOE	0x400		/* socket buffer is in the middle of an operation */
52b516438kmacy#define	SB_AUTOSIZE	0x800		/* automatically size socket buffer */
53b56bd6basomers#define	SB_STOP		0x1000		/* backpressure indicator */
54be47bc6jhb#define	SB_AIO_RUNNING	0x2000		/* AIO operation running */
551cf3162jhb#define	SB_TLS_IFNET	0x4000		/* has used / is using ifnet KTLS */
56b516438kmacy
57b516438kmacy#define	SBS_CANTSENDMORE	0x0010	/* can't send more data to peer */
58b516438kmacy#define	SBS_CANTRCVMORE		0x0020	/* can't receive more data from peer */
59b516438kmacy#define	SBS_RCVATMARK		0x0040	/* at mark on input */
60b516438kmacy
613f2bf60glebius#if defined(_KERNEL) || defined(_WANT_SOCKET)
623f2bf60glebius#include <sys/_lock.h>
633f2bf60glebius#include <sys/_mutex.h>
643f2bf60glebius#include <sys/_sx.h>
653f2bf60glebius#include <sys/_task.h>
663f2bf60glebius
673f2bf60glebius#define	SB_MAX		(2*1024*1024)	/* default for max chars in sockbuf */
683f2bf60glebius
691cf3162jhbstruct ktls_session;
70b516438kmacystruct mbuf;
711b467f0kmacystruct sockaddr;
721b467f0kmacystruct socket;
731b467f0kmacystruct thread;
74e35d543glebiusstruct selinfo;
75b516438kmacy
76b516438kmacy/*
77b516438kmacy * Variables for socket buffering.
78bc275cajhb *
79bc275cajhb * Locking key to struct sockbuf:
80bc275cajhb * (a) locked by SOCKBUF_LOCK().
811cf3162jhb * (b) locked by sblock()
82b516438kmacy */
83b516438kmacystruct	sockbuf {
84e35d543glebius	struct	mtx sb_mtx;		/* sockbuf lock */
85e35d543glebius	struct	sx sb_sx;		/* prevent I/O interlacing */
86e35d543glebius	struct	selinfo *sb_sel;	/* process selecting read/write */
87bc275cajhb	short	sb_state;	/* (a) socket state on sockbuf */
88b516438kmacy#define	sb_startzero	sb_mb
89bc275cajhb	struct	mbuf *sb_mb;	/* (a) the mbuf chain */
90bc275cajhb	struct	mbuf *sb_mbtail; /* (a) the last mbuf in the chain */
91bc275cajhb	struct	mbuf *sb_lastrecord;	/* (a) first mbuf of last
92b516438kmacy					 * record in socket buffer */
93bc275cajhb	struct	mbuf *sb_sndptr; /* (a) pointer into mbuf chain */
94bc275cajhb	struct	mbuf *sb_fnrdy;	/* (a) pointer to first not ready buffer */
95bc275cajhb	u_int	sb_sndptroff;	/* (a) byte offset of ptr into chain */
96bc275cajhb	u_int	sb_acc;		/* (a) available chars in buffer */
97bc275cajhb	u_int	sb_ccc;		/* (a) claimed chars in buffer */
98bc275cajhb	u_int	sb_hiwat;	/* (a) max actual char count */
99bc275cajhb	u_int	sb_mbcnt;	/* (a) chars of mbufs used */
100bc275cajhb	u_int   sb_mcnt;        /* (a) number of mbufs in buffer */
101bc275cajhb	u_int   sb_ccnt;        /* (a) number of clusters in buffer */
102bc275cajhb	u_int	sb_mbmax;	/* (a) max chars of mbufs to use */
103bc275cajhb	u_int	sb_ctl;		/* (a) non-data chars in buffer */
104fb264c6jhb	u_int	sb_tlscc;	/* (a) TLS chain characters */
105fb264c6jhb	u_int	sb_tlsdcc;	/* (a) TLS characters being decrypted */
106bc275cajhb	int	sb_lowat;	/* (a) low water mark */
107bc275cajhb	sbintime_t	sb_timeo;	/* (a) timeout for read/write */
1081cf3162jhb	uint64_t sb_tls_seqno;	/* (a) TLS seqno */
1091cf3162jhb	struct	ktls_session *sb_tls_info; /* (a + b) TLS state */
110fb264c6jhb	struct	mbuf *sb_mtls;	/* (a) TLS mbuf chain */
111fb264c6jhb	struct	mbuf *sb_mtlstail; /* (a) last mbuf in TLS chain */
1123078edcglebius	short	sb_flags;	/* (a) flags, see above */
113bc275cajhb	int	(*sb_upcall)(struct socket *, void *, int); /* (a) */
114bc275cajhb	void	*sb_upcallarg;	/* (a) */
115be47bc6jhb	TAILQ_HEAD(, kaiocb) sb_aiojobq; /* (a) pending AIO ops */
116be47bc6jhb	struct	task sb_aiotask; /* AIO task */
117b516438kmacy};
1181b467f0kmacy
1193f2bf60glebius#endif	/* defined(_KERNEL) || defined(_WANT_SOCKET) */
1201b467f0kmacy#ifdef _KERNEL
1215b3bca2cognet
1223bdaf5bkmacy/*
1233bdaf5bkmacy * Per-socket buffer mutex used to protect most fields in the socket
1243bdaf5bkmacy * buffer.
1253bdaf5bkmacy */
1263bdaf5bkmacy#define	SOCKBUF_MTX(_sb)		(&(_sb)->sb_mtx)
1273bdaf5bkmacy#define	SOCKBUF_LOCK_INIT(_sb, _name) \
1283bdaf5bkmacy	mtx_init(SOCKBUF_MTX(_sb), _name, NULL, MTX_DEF)
1293bdaf5bkmacy#define	SOCKBUF_LOCK_DESTROY(_sb)	mtx_destroy(SOCKBUF_MTX(_sb))
1303bdaf5bkmacy#define	SOCKBUF_LOCK(_sb)		mtx_lock(SOCKBUF_MTX(_sb))
1313bdaf5bkmacy#define	SOCKBUF_OWNED(_sb)		mtx_owned(SOCKBUF_MTX(_sb))
1323bdaf5bkmacy#define	SOCKBUF_UNLOCK(_sb)		mtx_unlock(SOCKBUF_MTX(_sb))
1333bdaf5bkmacy#define	SOCKBUF_LOCK_ASSERT(_sb)	mtx_assert(SOCKBUF_MTX(_sb), MA_OWNED)
1343bdaf5bkmacy#define	SOCKBUF_UNLOCK_ASSERT(_sb)	mtx_assert(SOCKBUF_MTX(_sb), MA_NOTOWNED)
1353bdaf5bkmacy
13625da94eglebius/*
13725da94eglebius * Socket buffer private mbuf(9) flags.
13825da94eglebius */
13925da94eglebius#define	M_NOTREADY	M_PROTO1	/* m_data not populated yet */
14025da94eglebius#define	M_BLOCKED	M_PROTO2	/* M_NOTREADY in front of m */
14125da94eglebius#define	M_NOTAVAIL	(M_NOTREADY | M_BLOCKED)
14225da94eglebius
143e25e77fglebiusvoid	sbappend(struct sockbuf *sb, struct mbuf *m, int flags);
144e25e77fglebiusvoid	sbappend_locked(struct sockbuf *sb, struct mbuf *m, int flags);
1459cadf1bglebiusvoid	sbappendstream(struct sockbuf *sb, struct mbuf *m, int flags);
1469cadf1bglebiusvoid	sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags);
147b516438kmacyint	sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
148b516438kmacy	    struct mbuf *m0, struct mbuf *control);
149b516438kmacyint	sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
150b516438kmacy	    struct mbuf *m0, struct mbuf *control);
1512a6c6c5asomersint	sbappendaddr_nospacecheck_locked(struct sockbuf *sb,
1522a6c6c5asomers	    const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control);
15375b64femarkjvoid	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
1543d36b36markj	    struct mbuf *control, int flags);
15575b64femarkjvoid	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
1563d36b36markj	    struct mbuf *control, int flags);
157b516438kmacyvoid	sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
158b516438kmacyvoid	sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
159b516438kmacyvoid	sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
160b516438kmacystruct mbuf *
161b516438kmacy	sbcreatecontrol(caddr_t p, int size, int type, int level);
162fb264c6jhbstruct mbuf *
163fb264c6jhb	sbcreatecontrol_how(void *p, int size, int type, int level,
164fb264c6jhb	    int wait);
165b516438kmacyvoid	sbdestroy(struct sockbuf *sb, struct socket *so);
166b516438kmacyvoid	sbdrop(struct sockbuf *sb, int len);
167b516438kmacyvoid	sbdrop_locked(struct sockbuf *sb, int len);
1680216035glebiusstruct mbuf *
1690216035glebius	sbcut_locked(struct sockbuf *sb, int len);
170b516438kmacyvoid	sbdroprecord(struct sockbuf *sb);
171b516438kmacyvoid	sbdroprecord_locked(struct sockbuf *sb);
172b516438kmacyvoid	sbflush(struct sockbuf *sb);
173b516438kmacyvoid	sbflush_locked(struct sockbuf *sb);
174b516438kmacyvoid	sbrelease(struct sockbuf *sb, struct socket *so);
175b516438kmacyvoid	sbrelease_internal(struct sockbuf *sb, struct socket *so);
176b516438kmacyvoid	sbrelease_locked(struct sockbuf *sb, struct socket *so);
1774cfe976glebiusint	sbsetopt(struct socket *so, int cmd, u_long cc);
178b516438kmacyint	sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
179b516438kmacy	    struct thread *td);
180439be2cjhbvoid	sbsndptr_adv(struct sockbuf *sb, struct mbuf *mb, u_int len);
181bdacf9bhselaskystruct mbuf *
182e4ec942rrs	sbsndptr_noadv(struct sockbuf *sb, u_int off, u_int *moff);
183e4ec942rrsstruct mbuf *
184bdacf9bhselasky	sbsndmbuf(struct sockbuf *sb, u_int off, u_int *moff);
185b516438kmacyint	sbwait(struct sockbuf *sb);
186b516438kmacyint	sblock(struct sockbuf *sb, int flags);
187b516438kmacyvoid	sbunlock(struct sockbuf *sb);
188843bdafglebiusvoid	sballoc(struct sockbuf *, struct mbuf *);
189843bdafglebiusvoid	sbfree(struct sockbuf *, struct mbuf *);
190fb264c6jhbvoid	sballoc_ktls_rx(struct sockbuf *sb, struct mbuf *m);
191fb264c6jhbvoid	sbfree_ktls_rx(struct sockbuf *sb, struct mbuf *m);
19225da94eglebiusint	sbready(struct sockbuf *, struct mbuf *, int);
193b516438kmacy
194b516438kmacy/*
195c0b38b5glebius * Return how much data is available to be taken out of socket
19625da94eglebius * buffer right now.
197c0b38b5glebius */
198c0b38b5glebiusstatic inline u_int
199c0b38b5glebiussbavail(struct sockbuf *sb)
200c0b38b5glebius{
201c0b38b5glebius
202c0b38b5glebius#if 0
203c0b38b5glebius	SOCKBUF_LOCK_ASSERT(sb);
204c0b38b5glebius#endif
20525da94eglebius	return (sb->sb_acc);
206c0b38b5glebius}
207c0b38b5glebius
208c0b38b5glebius/*
209c0b38b5glebius * Return how much data sits there in the socket buffer
210c0b38b5glebius * It might be that some data is not yet ready to be read.
211c0b38b5glebius */
212c0b38b5glebiusstatic inline u_int
213c0b38b5glebiussbused(struct sockbuf *sb)
214c0b38b5glebius{
215c0b38b5glebius
216c0b38b5glebius#if 0
217c0b38b5glebius	SOCKBUF_LOCK_ASSERT(sb);
218c0b38b5glebius#endif
21925da94eglebius	return (sb->sb_ccc);
220c0b38b5glebius}
221c0b38b5glebius
222c0b38b5glebius/*
223b516438kmacy * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
224b516438kmacy * This is problematical if the fields are unsigned, as the space might
22525da94eglebius * still be negative (ccc > hiwat or mbcnt > mbmax).
226b516438kmacy */
22725da94eglebiusstatic inline long
228b56bd6basomerssbspace(struct sockbuf *sb)
229b56bd6basomers{
2306e75dabsjg	int bleft, mleft;		/* size should match sockbuf fields */
23125da94eglebius
23225da94eglebius#if 0
23325da94eglebius	SOCKBUF_LOCK_ASSERT(sb);
23425da94eglebius#endif
235b56bd6basomers
236b56bd6basomers	if (sb->sb_flags & SB_STOP)
237b56bd6basomers		return(0);
23825da94eglebius
23925da94eglebius	bleft = sb->sb_hiwat - sb->sb_ccc;
240b56bd6basomers	mleft = sb->sb_mbmax - sb->sb_mbcnt;
24125da94eglebius
24225da94eglebius	return ((bleft < mleft) ? bleft : mleft);
243b56bd6basomers}
244b516438kmacy
245b516438kmacy#define SB_EMPTY_FIXUP(sb) do {						\
246b516438kmacy	if ((sb)->sb_mb == NULL) {					\
247b516438kmacy		(sb)->sb_mbtail = NULL;					\
248b516438kmacy		(sb)->sb_lastrecord = NULL;				\
249b516438kmacy	}								\
250b516438kmacy} while (/*CONSTCOND*/0)
251b516438kmacy
252b516438kmacy#ifdef SOCKBUF_DEBUG
253b516438kmacyvoid	sblastrecordchk(struct sockbuf *, const char *, int);
254b516438kmacyvoid	sblastmbufchk(struct sockbuf *, const char *, int);
255176ae22glebiusvoid	sbcheck(struct sockbuf *, const char *, int);
256176ae22glebius#define	SBLASTRECORDCHK(sb)	sblastrecordchk((sb), __FILE__, __LINE__)
257b516438kmacy#define	SBLASTMBUFCHK(sb)	sblastmbufchk((sb), __FILE__, __LINE__)
258176ae22glebius#define	SBCHECK(sb)		sbcheck((sb), __FILE__, __LINE__)
259b516438kmacy#else
260176ae22glebius#define	SBLASTRECORDCHK(sb)	do {} while (0)
261176ae22glebius#define	SBLASTMBUFCHK(sb)	do {} while (0)
262176ae22glebius#define	SBCHECK(sb)		do {} while (0)
263b516438kmacy#endif /* SOCKBUF_DEBUG */
264b516438kmacy
2655b3bca2cognet#endif /* _KERNEL */
2665b3bca2cognet
267b516438kmacy#endif /* _SYS_SOCKBUF_H_ */
268