PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/bsd/sys/sys/sockbuf.h

https://gitlab.com/jforge/osv
C Header | 238 lines | 163 code | 22 blank | 53 comment | 17 complexity | badf1ad2d8b94c85c35514eef20139f3 MD5 | raw file
Possible License(s): BSD-3-Clause, 0BSD, MPL-2.0-no-copyleft-exception
  1. /*-
  2. * Copyright (c) 1982, 1986, 1990, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 4. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. *
  29. * @(#)socketvar.h 8.3 (Berkeley) 2/19/95
  30. *
  31. * $FreeBSD$
  32. */
  33. #ifndef _SYS_SOCKBUF_H_
  34. #define _SYS_SOCKBUF_H_
  35. #include <sys/cdefs.h>
  36. #include <bsd/porting/netport.h>
  37. #include <bsd/porting/sync_stub.h>
  38. #include <bsd/porting/rwlock.h>
  39. #include <osv/waitqueue.hh>
  40. #include <chrono>
  41. #include <boost/optional/optional.hpp>
  42. #define SB_MAX (2*1024*1024) /* default for max chars in sockbuf */
  43. /*
  44. * Constants for sb_flags field of struct sockbuf.
  45. */
  46. #define SB_WAIT 0x04 /* someone is waiting for data/space */
  47. #define SB_SEL 0x08 /* someone is selecting */
  48. #define SB_ASYNC 0x10 /* ASYNC I/O, need signals */
  49. #define SB_UPCALL 0x20 /* someone wants an upcall */
  50. #define SB_NOINTR 0x40 /* operations not interruptible */
  51. #define SB_AIO 0x80 /* AIO operations queued */
  52. #define SB_KNOTE 0x100 /* kernel note attached */
  53. #define SB_NOCOALESCE 0x200 /* don't coalesce new data into existing mbufs */
  54. #define SB_IN_TOE 0x400 /* socket buffer is in the middle of an operation */
  55. #define SB_AUTOSIZE 0x800 /* automatically size socket buffer */
  56. #define SBS_CANTSENDMORE 0x0010 /* can't send more data to peer */
  57. #define SBS_CANTRCVMORE 0x0020 /* can't receive more data from peer */
  58. #define SBS_RCVATMARK 0x0040 /* at mark on input */
  59. struct mbuf;
  60. struct bsd_sockaddr;
  61. struct socket;
  62. struct thread;
  63. struct xsockbuf {
  64. u_int sb_cc;
  65. u_int sb_hiwat;
  66. u_int sb_mbcnt;
  67. u_int sb_mcnt;
  68. u_int sb_ccnt;
  69. u_int sb_mbmax;
  70. int sb_lowat;
  71. int sb_timeo;
  72. short sb_flags;
  73. };
  74. // light-weight lock that depends on an external mutex for
  75. // synchronization. Used for sockbuf I/O thread serialization.
  76. class sockbuf_iolock {
  77. public:
  78. void lock(mutex& mtx);
  79. bool try_lock(mutex& mtx);
  80. void unlock(mutex& mtx);
  81. private:
  82. waitqueue _wq;
  83. sched::thread* _owner = nullptr;
  84. };
  85. /*
  86. * Variables for socket buffering.
  87. */
  88. struct sockbuf {
  89. sockbuf_iolock sb_iolock; /* prevent I/O interlacing */
  90. short sb_state; /* (c/d) socket state on sockbuf */
  91. #define sb_startzero sb_mb
  92. struct mbuf *sb_mb; /* (c/d) the mbuf chain */
  93. struct mbuf *sb_mbtail; /* (c/d) the last mbuf in the chain */
  94. struct mbuf *sb_lastrecord; /* (c/d) first mbuf of last
  95. * record in socket buffer */
  96. struct mbuf *sb_sndptr; /* (c/d) pointer into mbuf chain */
  97. u_int sb_sndptroff; /* (c/d) byte offset of ptr into chain */
  98. u_int sb_cc; /* (c/d) actual chars in buffer */
  99. waitqueue sb_cc_wq; /* waiting on sb_cc change */
  100. u_int sb_hiwat; /* (c/d) max actual char count */
  101. u_int sb_mbcnt; /* (c/d) chars of mbufs used */
  102. u_int sb_mcnt; /* (c/d) number of mbufs in buffer */
  103. u_int sb_ccnt; /* (c/d) number of clusters in buffer */
  104. u_int sb_mbmax; /* (c/d) max chars of mbufs to use */
  105. u_int sb_ctl; /* (c/d) non-data chars in buffer */
  106. int sb_lowat; /* (c/d) low water mark */
  107. int sb_timeo; /* (c/d) timeout for read/write */
  108. short sb_flags; /* (c/d) flags, see below */
  109. int (*sb_upcall)(struct socket *, void *, int); /* (c/d) */
  110. void *sb_upcallarg; /* (c/d) */
  111. };
  112. #ifdef _KERNEL
  113. /*
  114. * Per-socket buffer mutex used to protect most fields in the socket
  115. * buffer.
  116. */
  117. __BEGIN_DECLS
  118. void sbappend(socket* so, struct sockbuf *sb, struct mbuf *m);
  119. void sbappend_locked(socket* so, struct sockbuf *sb, struct mbuf *m);
  120. void sbappendstream(socket* so, struct sockbuf *sb, struct mbuf *m);
  121. void sbappendstream_locked(socket* so, struct sockbuf *sb, struct mbuf *m);
  122. int sbappendaddr(socket* so, struct sockbuf *sb, const struct bsd_sockaddr *asa,
  123. struct mbuf *m0, struct mbuf *control);
  124. int sbappendaddr_locked(socket* so, struct sockbuf *sb, const struct bsd_sockaddr *asa,
  125. struct mbuf *m0, struct mbuf *control);
  126. int sbappendcontrol(socket* so, struct sockbuf *sb, struct mbuf *m0,
  127. struct mbuf *control);
  128. int sbappendcontrol_locked(socket* so, struct sockbuf *sb, struct mbuf *m0,
  129. struct mbuf *control);
  130. void sbappendrecord(socket* so, struct sockbuf *sb, struct mbuf *m0);
  131. void sbappendrecord_locked(socket* so, struct sockbuf *sb, struct mbuf *m0);
  132. void sbcheck(struct sockbuf *sb);
  133. void sbcompress(socket* so, struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
  134. struct mbuf *
  135. sbcreatecontrol(caddr_t p, int size, int type, int level);
  136. void sbdestroy(struct sockbuf *sb, struct socket *so);
  137. void sbdrop(socket* so, struct sockbuf *sb, int len);
  138. void sbdrop_locked(socket* so, struct sockbuf *sb, int len);
  139. void sbdroprecord(struct sockbuf *sb);
  140. void sbdroprecord_locked(socket* so, struct sockbuf *sb);
  141. void sbflush(socket* so, struct sockbuf *sb);
  142. void sbflush_locked(socket* so, struct sockbuf *sb);
  143. void sbrelease(struct sockbuf *sb, struct socket *so);
  144. void sbrelease_internal(struct sockbuf *sb, struct socket *so);
  145. void sbrelease_locked(struct sockbuf *sb, struct socket *so);
  146. int sbreserve(struct sockbuf *sb, u_long cc, struct socket *so,
  147. struct thread *td);
  148. int sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
  149. struct thread *td);
  150. int sbreserve_internal(struct sockbuf *sb, u_long cc, struct socket *so,
  151. struct thread *td);
  152. struct mbuf *
  153. sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff);
  154. void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb);
  155. int sbwait(socket* so, struct sockbuf *sb);
  156. int sblock(socket* so, struct sockbuf *sb, int flags);
  157. void sbunlock(socket* so, struct sockbuf *sb);
  158. __END_DECLS
  159. template<typename Clock>
  160. int sbwait_tmo(socket* so, struct sockbuf *sb, boost::optional<std::chrono::time_point<Clock>> timeout);
  161. /*
  162. * How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
  163. * This is problematical if the fields are unsigned, as the space might
  164. * still be negative (cc > hiwat or mbcnt > mbmax). Should detect
  165. * overflow and return 0. Should use "lmin" but it doesn't exist now.
  166. */
  167. #define sbspace(sb) \
  168. ((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \
  169. (int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
  170. /* adjust counters in sb reflecting allocation of m */
  171. #define sballoc(sb, m) { \
  172. (sb)->sb_cc += (m)->m_hdr.mh_len; \
  173. if ((m)->m_hdr.mh_type != MT_DATA && (m)->m_hdr.mh_type != MT_OOBDATA) \
  174. (sb)->sb_ctl += (m)->m_hdr.mh_len; \
  175. (sb)->sb_mbcnt += MSIZE; \
  176. (sb)->sb_mcnt += 1; \
  177. if ((m)->m_hdr.mh_flags & M_EXT) { \
  178. (sb)->sb_mbcnt += (m)->M_dat.MH.MH_dat.MH_ext.ext_size; \
  179. (sb)->sb_ccnt += 1; \
  180. } \
  181. }
  182. /* adjust counters in sb reflecting freeing of m */
  183. #define sbfree(sb, m) { \
  184. (sb)->sb_cc -= (m)->m_hdr.mh_len; \
  185. if ((m)->m_hdr.mh_type != MT_DATA && (m)->m_hdr.mh_type != MT_OOBDATA) \
  186. (sb)->sb_ctl -= (m)->m_hdr.mh_len; \
  187. (sb)->sb_mbcnt -= MSIZE; \
  188. (sb)->sb_mcnt -= 1; \
  189. if ((m)->m_hdr.mh_flags & M_EXT) { \
  190. (sb)->sb_mbcnt -= (m)->M_dat.MH.MH_dat.MH_ext.ext_size; \
  191. (sb)->sb_ccnt -= 1; \
  192. } \
  193. if ((sb)->sb_sndptr == (m)) { \
  194. (sb)->sb_sndptr = NULL; \
  195. (sb)->sb_sndptroff = 0; \
  196. } \
  197. if ((sb)->sb_sndptroff != 0) \
  198. (sb)->sb_sndptroff -= (m)->m_hdr.mh_len; \
  199. }
  200. #define SB_EMPTY_FIXUP(sb) do { \
  201. if ((sb)->sb_mb == NULL) { \
  202. (sb)->sb_mbtail = NULL; \
  203. (sb)->sb_lastrecord = NULL; \
  204. } \
  205. } while (/*CONSTCOND*/0)
  206. #ifdef SOCKBUF_DEBUG
  207. void sblastrecordchk(struct sockbuf *, const char *, int);
  208. #define SBLASTRECORDCHK(sb) sblastrecordchk((sb), __FILE__, __LINE__)
  209. void sblastmbufchk(struct sockbuf *, const char *, int);
  210. #define SBLASTMBUFCHK(sb) sblastmbufchk((sb), __FILE__, __LINE__)
  211. #else
  212. #define SBLASTRECORDCHK(sb) /* nothing */
  213. #define SBLASTMBUFCHK(sb) /* nothing */
  214. #endif /* SOCKBUF_DEBUG */
  215. #endif /* _KERNEL */
  216. #endif /* _SYS_SOCKBUF_H_ */