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