1*73e0ad59Sderaadt /* $OpenBSD: socketvar.h,v 1.27 2002/05/11 00:06:33 deraadt Exp $ */ 2ad43b9c6Smickey /* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */ 3df930be7Sderaadt 4df930be7Sderaadt /*- 5df930be7Sderaadt * Copyright (c) 1982, 1986, 1990, 1993 6df930be7Sderaadt * The Regents of the University of California. All rights reserved. 7df930be7Sderaadt * 8df930be7Sderaadt * Redistribution and use in source and binary forms, with or without 9df930be7Sderaadt * modification, are permitted provided that the following conditions 10df930be7Sderaadt * are met: 11df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright 12df930be7Sderaadt * notice, this list of conditions and the following disclaimer. 13df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 14df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the 15df930be7Sderaadt * documentation and/or other materials provided with the distribution. 16df930be7Sderaadt * 3. All advertising materials mentioning features or use of this software 17df930be7Sderaadt * must display the following acknowledgement: 18df930be7Sderaadt * This product includes software developed by the University of 19df930be7Sderaadt * California, Berkeley and its contributors. 20df930be7Sderaadt * 4. Neither the name of the University nor the names of its contributors 21df930be7Sderaadt * may be used to endorse or promote products derived from this software 22df930be7Sderaadt * without specific prior written permission. 23df930be7Sderaadt * 24df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34df930be7Sderaadt * SUCH DAMAGE. 35df930be7Sderaadt * 36df930be7Sderaadt * @(#)socketvar.h 8.1 (Berkeley) 6/2/93 37df930be7Sderaadt */ 38df930be7Sderaadt 39df930be7Sderaadt #include <sys/select.h> /* for struct selinfo */ 40145e6cebSprovos #include <sys/queue.h> 41145e6cebSprovos 42145e6cebSprovos TAILQ_HEAD(soqhead, socket); 43df930be7Sderaadt 44df930be7Sderaadt /* 45df930be7Sderaadt * Kernel structure per socket. 46df930be7Sderaadt * Contains send and receive buffer queues, 47df930be7Sderaadt * handle on protocol and pointer to protocol 48df930be7Sderaadt * private data and error information. 49df930be7Sderaadt */ 50df930be7Sderaadt struct socket { 51df930be7Sderaadt short so_type; /* generic type, see socket.h */ 52df930be7Sderaadt short so_options; /* from socket call, see socket.h */ 53df930be7Sderaadt short so_linger; /* time to linger while closing */ 54df930be7Sderaadt short so_state; /* internal state flags SS_*, below */ 55df930be7Sderaadt void *so_pcb; /* protocol control block */ 56df930be7Sderaadt struct protosw *so_proto; /* protocol handle */ 57df930be7Sderaadt /* 58df930be7Sderaadt * Variables for connection queueing. 59df930be7Sderaadt * Socket where accepts occur is so_head in all subsidiary sockets. 60df930be7Sderaadt * If so_head is 0, socket is not related to an accept. 61df930be7Sderaadt * For head socket so_q0 queues partially completed connections, 62df930be7Sderaadt * while so_q is a queue of connections ready to be accepted. 63df930be7Sderaadt * If a connection is aborted and it has so_head set, then 64df930be7Sderaadt * it has to be pulled out of either so_q0 or so_q. 65df930be7Sderaadt * We allow connections to queue up based on current queue lengths 66df930be7Sderaadt * and limit on number of queued connections for this socket. 67df930be7Sderaadt */ 68df930be7Sderaadt struct socket *so_head; /* back pointer to accept socket */ 69145e6cebSprovos struct soqhead *so_onq; /* queue (q or q0) that we're on */ 70145e6cebSprovos struct soqhead so_q0; /* queue of partial connections */ 71145e6cebSprovos struct soqhead so_q; /* queue of incoming connections */ 72145e6cebSprovos TAILQ_ENTRY(socket) so_qe; /* our queue entry (q or q0) */ 73df930be7Sderaadt short so_q0len; /* partials on so_q0 */ 74df930be7Sderaadt short so_qlen; /* number of connections on so_q */ 75df930be7Sderaadt short so_qlimit; /* max number queued connections */ 76df930be7Sderaadt short so_timeo; /* connection timeout */ 77df930be7Sderaadt u_short so_error; /* error affecting connection */ 78df930be7Sderaadt pid_t so_pgid; /* pgid for signals */ 7931e15491Sderaadt uid_t so_siguid; /* uid of process who set so_pgid */ 8031e15491Sderaadt uid_t so_sigeuid; /* euid of process who set so_pgid */ 81df930be7Sderaadt u_long so_oobmark; /* chars to oob mark */ 82df930be7Sderaadt /* 83df930be7Sderaadt * Variables for socket buffering. 84df930be7Sderaadt */ 85df930be7Sderaadt struct sockbuf { 86df930be7Sderaadt u_long sb_cc; /* actual chars in buffer */ 87df930be7Sderaadt u_long sb_hiwat; /* max actual char count */ 88df930be7Sderaadt u_long sb_mbcnt; /* chars of mbufs used */ 89df930be7Sderaadt u_long sb_mbmax; /* max chars of mbufs to use */ 90df930be7Sderaadt long sb_lowat; /* low water mark */ 91df930be7Sderaadt struct mbuf *sb_mb; /* the mbuf chain */ 92df930be7Sderaadt struct selinfo sb_sel; /* process selecting read/write */ 93df930be7Sderaadt short sb_flags; /* flags, see below */ 94df930be7Sderaadt short sb_timeo; /* timeout for read/write */ 95df930be7Sderaadt } so_rcv, so_snd; 96df930be7Sderaadt #define SB_MAX (256*1024) /* default for max chars in sockbuf */ 97df930be7Sderaadt #define SB_LOCK 0x01 /* lock on data queue */ 98df930be7Sderaadt #define SB_WANT 0x02 /* someone is waiting to lock */ 99df930be7Sderaadt #define SB_WAIT 0x04 /* someone is waiting for data/space */ 100df930be7Sderaadt #define SB_SEL 0x08 /* someone is selecting */ 101df930be7Sderaadt #define SB_ASYNC 0x10 /* ASYNC I/O, need signals */ 102df930be7Sderaadt #define SB_NOINTR 0x40 /* operations not interruptible */ 1031a12e8a7Sprovos #define SB_KNOTE 0x80 /* kernel note attached */ 104df930be7Sderaadt 105ad43b9c6Smickey void *so_internal; /* Space for svr4 stream data */ 106c4071fd1Smillert void (*so_upcall)(struct socket *so, caddr_t arg, int waitf); 107df930be7Sderaadt caddr_t so_upcallarg; /* Arg for above */ 108*73e0ad59Sderaadt uid_t so_euid, so_ruid; /* who opened the socket */ 109*73e0ad59Sderaadt gid_t so_egid, so_rgid; 110df930be7Sderaadt }; 111df930be7Sderaadt 112df930be7Sderaadt /* 113df930be7Sderaadt * Socket state bits. 114df930be7Sderaadt */ 115df930be7Sderaadt #define SS_NOFDREF 0x001 /* no file table ref any more */ 116df930be7Sderaadt #define SS_ISCONNECTED 0x002 /* socket connected to a peer */ 117df930be7Sderaadt #define SS_ISCONNECTING 0x004 /* in process of connecting to peer */ 118df930be7Sderaadt #define SS_ISDISCONNECTING 0x008 /* in process of disconnecting */ 119df930be7Sderaadt #define SS_CANTSENDMORE 0x010 /* can't send more data to peer */ 120df930be7Sderaadt #define SS_CANTRCVMORE 0x020 /* can't receive more data from peer */ 121df930be7Sderaadt #define SS_RCVATMARK 0x040 /* at mark on input */ 122751be64bSmillert #define SS_ISDISCONNECTED 0x800 /* socket disconnected from peer */ 123df930be7Sderaadt 124df930be7Sderaadt #define SS_PRIV 0x080 /* privileged for broadcast, raw... */ 125df930be7Sderaadt #define SS_NBIO 0x100 /* non-blocking ops */ 126df930be7Sderaadt #define SS_ASYNC 0x200 /* async i/o notify */ 127df930be7Sderaadt #define SS_ISCONFIRMING 0x400 /* deciding to accept connection req */ 128f1ea8dcbSderaadt #define SS_CONNECTOUT 0x1000 /* connect, not accept, at this end */ 129df930be7Sderaadt 130df930be7Sderaadt /* 131df930be7Sderaadt * Macros for sockets and socket buffering. 132df930be7Sderaadt */ 133df930be7Sderaadt 134df930be7Sderaadt /* 135df930be7Sderaadt * Do we need to notify the other side when I/O is possible? 136df930be7Sderaadt */ 1371a12e8a7Sprovos #define sb_notify(sb) (((sb)->sb_flags & (SB_WAIT|SB_SEL|SB_ASYNC| \ 1381a12e8a7Sprovos SB_KNOTE)) != 0) 139df930be7Sderaadt 140df930be7Sderaadt /* 141df930be7Sderaadt * How much space is there in a socket buffer (so->so_snd or so->so_rcv)? 142df930be7Sderaadt * This is problematical if the fields are unsigned, as the space might 143df930be7Sderaadt * still be negative (cc > hiwat or mbcnt > mbmax). Should detect 144df930be7Sderaadt * overflow and return 0. Should use "lmin" but it doesn't exist now. 145df930be7Sderaadt */ 146df930be7Sderaadt #define sbspace(sb) \ 147df930be7Sderaadt ((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \ 148df930be7Sderaadt (int)((sb)->sb_mbmax - (sb)->sb_mbcnt))) 149df930be7Sderaadt 150df930be7Sderaadt /* do we have to send all at once on a socket? */ 151df930be7Sderaadt #define sosendallatonce(so) \ 152df930be7Sderaadt ((so)->so_proto->pr_flags & PR_ATOMIC) 153df930be7Sderaadt 154df930be7Sderaadt /* can we read something from so? */ 155df930be7Sderaadt #define soreadable(so) \ 156df930be7Sderaadt ((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \ 157df930be7Sderaadt ((so)->so_state & SS_CANTRCVMORE) || \ 158df930be7Sderaadt (so)->so_qlen || (so)->so_error) 159df930be7Sderaadt 160df930be7Sderaadt /* can we write something to so? */ 161df930be7Sderaadt #define sowriteable(so) \ 162ad43b9c6Smickey ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \ 163df930be7Sderaadt (((so)->so_state&SS_ISCONNECTED) || \ 164ad43b9c6Smickey ((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0)) || \ 1657ad69040Sderaadt ((so)->so_state & SS_CANTSENDMORE) || (so)->so_error) 166df930be7Sderaadt 167df930be7Sderaadt /* adjust counters in sb reflecting allocation of m */ 168df930be7Sderaadt #define sballoc(sb, m) { \ 169df930be7Sderaadt (sb)->sb_cc += (m)->m_len; \ 170df930be7Sderaadt (sb)->sb_mbcnt += MSIZE; \ 171df930be7Sderaadt if ((m)->m_flags & M_EXT) \ 172df930be7Sderaadt (sb)->sb_mbcnt += (m)->m_ext.ext_size; \ 173df930be7Sderaadt } 174df930be7Sderaadt 175df930be7Sderaadt /* adjust counters in sb reflecting freeing of m */ 176df930be7Sderaadt #define sbfree(sb, m) { \ 177df930be7Sderaadt (sb)->sb_cc -= (m)->m_len; \ 178df930be7Sderaadt (sb)->sb_mbcnt -= MSIZE; \ 179df930be7Sderaadt if ((m)->m_flags & M_EXT) \ 180df930be7Sderaadt (sb)->sb_mbcnt -= (m)->m_ext.ext_size; \ 181df930be7Sderaadt } 182df930be7Sderaadt 183df930be7Sderaadt /* 184df930be7Sderaadt * Set lock on sockbuf sb; sleep if lock is already held. 185df930be7Sderaadt * Unless SB_NOINTR is set on sockbuf, sleep is interruptible. 186df930be7Sderaadt * Returns error without lock if sleep is interrupted. 187df930be7Sderaadt */ 188df930be7Sderaadt #define sblock(sb, wf) ((sb)->sb_flags & SB_LOCK ? \ 189df930be7Sderaadt (((wf) == M_WAITOK) ? sb_lock(sb) : EWOULDBLOCK) : \ 190df930be7Sderaadt ((sb)->sb_flags |= SB_LOCK), 0) 191df930be7Sderaadt 192df930be7Sderaadt /* release lock on sockbuf sb */ 193df930be7Sderaadt #define sbunlock(sb) { \ 194df930be7Sderaadt (sb)->sb_flags &= ~SB_LOCK; \ 195df930be7Sderaadt if ((sb)->sb_flags & SB_WANT) { \ 196df930be7Sderaadt (sb)->sb_flags &= ~SB_WANT; \ 197df930be7Sderaadt wakeup((caddr_t)&(sb)->sb_flags); \ 198df930be7Sderaadt } \ 199df930be7Sderaadt } 200df930be7Sderaadt 201df930be7Sderaadt #define sorwakeup(so) { sowakeup((so), &(so)->so_rcv); \ 202df930be7Sderaadt if ((so)->so_upcall) \ 203df930be7Sderaadt (*((so)->so_upcall))((so), (so)->so_upcallarg, M_DONTWAIT); \ 204df930be7Sderaadt } 205df930be7Sderaadt 206df930be7Sderaadt #define sowwakeup(so) sowakeup((so), &(so)->so_snd) 207df930be7Sderaadt 208df930be7Sderaadt #ifdef _KERNEL 209df930be7Sderaadt u_long sb_max; 210c4071fd1Smillert struct socket *sonewconn(struct socket *head, int connstatus); 211df930be7Sderaadt 212df930be7Sderaadt /* strings for sleep message: */ 213df930be7Sderaadt extern char netio[], netcon[], netcls[]; 214df930be7Sderaadt 2158f4b9dbeSprovos extern struct pool socket_pool; 2168f4b9dbeSprovos 217ad43b9c6Smickey struct mbuf; 218ad43b9c6Smickey struct sockaddr; 219ad43b9c6Smickey struct proc; 220ad43b9c6Smickey struct msghdr; 221ad43b9c6Smickey struct stat; 222cc90df54Sprovos struct knote; 223ad43b9c6Smickey 224df930be7Sderaadt /* 225df930be7Sderaadt * File operations on sockets. 226df930be7Sderaadt */ 227c4071fd1Smillert int soo_read(struct file *fp, off_t *, struct uio *uio, 228c4071fd1Smillert struct ucred *cred); 229c4071fd1Smillert int soo_write(struct file *fp, off_t *, struct uio *uio, 230c4071fd1Smillert struct ucred *cred); 231c4071fd1Smillert int soo_ioctl(struct file *fp, u_long cmd, caddr_t data, 232c4071fd1Smillert struct proc *p); 233c4071fd1Smillert int soo_select(struct file *fp, int which, struct proc *p); 234c4071fd1Smillert int soo_kqfilter(struct file *fp, struct knote *kn); 235c4071fd1Smillert int soo_close(struct file *fp, struct proc *p); 236c4071fd1Smillert int soo_stat(struct file *, struct stat *, struct proc *); 237c4071fd1Smillert int uipc_usrreq(struct socket *, int , struct mbuf *, 238c4071fd1Smillert struct mbuf *, struct mbuf *); 239c4071fd1Smillert void sbappend(struct sockbuf *sb, struct mbuf *m); 240c4071fd1Smillert int sbappendaddr(struct sockbuf *sb, struct sockaddr *asa, 241c4071fd1Smillert struct mbuf *m0, struct mbuf *control); 242c4071fd1Smillert int sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, 243c4071fd1Smillert struct mbuf *control); 244c4071fd1Smillert void sbappendrecord(struct sockbuf *sb, struct mbuf *m0); 245c4071fd1Smillert void sbcheck(struct sockbuf *sb); 246c4071fd1Smillert void sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n); 247287546eaSitojun struct mbuf * 248c4071fd1Smillert sbcreatecontrol(caddr_t p, int size, int type, int level); 249c4071fd1Smillert void sbdrop(struct sockbuf *sb, int len); 250c4071fd1Smillert void sbdroprecord(struct sockbuf *sb); 251c4071fd1Smillert void sbflush(struct sockbuf *sb); 252c4071fd1Smillert void sbinsertoob(struct sockbuf *sb, struct mbuf *m0); 253c4071fd1Smillert void sbrelease(struct sockbuf *sb); 254c4071fd1Smillert int sbreserve(struct sockbuf *sb, u_long cc); 255c4071fd1Smillert int sbwait(struct sockbuf *sb); 256c4071fd1Smillert int sb_lock(struct sockbuf *sb); 2578f4b9dbeSprovos void soinit(void); 258c4071fd1Smillert int soabort(struct socket *so); 259c4071fd1Smillert int soaccept(struct socket *so, struct mbuf *nam); 260c4071fd1Smillert int sobind(struct socket *so, struct mbuf *nam); 261c4071fd1Smillert void socantrcvmore(struct socket *so); 262c4071fd1Smillert void socantsendmore(struct socket *so); 263c4071fd1Smillert int soclose(struct socket *so); 264c4071fd1Smillert int soconnect(struct socket *so, struct mbuf *nam); 265c4071fd1Smillert int soconnect2(struct socket *so1, struct socket *so2); 266c4071fd1Smillert int socreate(int dom, struct socket **aso, int type, int proto); 267c4071fd1Smillert int sodisconnect(struct socket *so); 268c4071fd1Smillert void sofree(struct socket *so); 269c4071fd1Smillert int sogetopt(struct socket *so, int level, int optname, 270c4071fd1Smillert struct mbuf **mp); 271c4071fd1Smillert void sohasoutofband(struct socket *so); 272c4071fd1Smillert void soisconnected(struct socket *so); 273c4071fd1Smillert void soisconnecting(struct socket *so); 274c4071fd1Smillert void soisdisconnected(struct socket *so); 275c4071fd1Smillert void soisdisconnecting(struct socket *so); 276c4071fd1Smillert int solisten(struct socket *so, int backlog); 277c4071fd1Smillert struct socket *sonewconn(struct socket *head, int connstatus); 278c4071fd1Smillert void soqinsque(struct socket *head, struct socket *so, int q); 279c4071fd1Smillert int soqremque(struct socket *so, int q); 280c4071fd1Smillert int soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio, 281c4071fd1Smillert struct mbuf **mp0, struct mbuf **controlp, int *flagsp); 282c4071fd1Smillert int soreserve(struct socket *so, u_long sndcc, u_long rcvcc); 283c4071fd1Smillert void sorflush(struct socket *so); 284c4071fd1Smillert int sosend(struct socket *so, struct mbuf *addr, struct uio *uio, 285c4071fd1Smillert struct mbuf *top, struct mbuf *control, int flags); 286c4071fd1Smillert int sosetopt(struct socket *so, int level, int optname, 287c4071fd1Smillert struct mbuf *m0); 288c4071fd1Smillert int soshutdown(struct socket *so, int how); 289c4071fd1Smillert void sowakeup(struct socket *so, struct sockbuf *sb); 290c4071fd1Smillert int sockargs(struct mbuf **, caddr_t, socklen_t, int); 291ad43b9c6Smickey 292c4071fd1Smillert int sendit(struct proc *, int, struct msghdr *, int, register_t *); 293c4071fd1Smillert int recvit(struct proc *, int, struct msghdr *, caddr_t, 294c4071fd1Smillert register_t *); 295ad43b9c6Smickey 296df930be7Sderaadt #endif /* _KERNEL */ 297