388 lines
13 KiB
C
388 lines
13 KiB
C
/* @(#)74 1.12.2.16 src/bos/kernel/sys/socketvar.h, sockinc, bos41B, 412_41B_sync 11/29/94 13:02:15 */
|
|
/*
|
|
* COMPONENT_NAME: SOCKINC
|
|
*
|
|
* FUNCTIONS: SOCKBUF_ISLOCKED
|
|
* SOCKBUF_LOCK
|
|
* SOCKBUF_UNLOCK
|
|
* SOCKET_ISLOCKED
|
|
* SOCKET_LOCK
|
|
* SOCKET_LOCK2
|
|
* SOCKET_LOCKINIT
|
|
* SOCKET_UNLOCK
|
|
* SOCKET_UNLOCK2
|
|
* SOHASUAREA
|
|
* sballoc
|
|
* sbfree
|
|
* sbspace
|
|
* sodomain
|
|
* sonewconn
|
|
* soreadable
|
|
* sorwakeup
|
|
* sosendallatonce
|
|
* sowatomic
|
|
* sowriteable
|
|
* sowwakeup
|
|
*
|
|
*
|
|
* ORIGINS: 26,27,85
|
|
*
|
|
*
|
|
* (C) COPYRIGHT International Business Machines Corp. 1988,1993
|
|
* All Rights Reserved
|
|
* Licensed Materials - Property of IBM
|
|
* US Government Users Restricted Rights - Use, duplication or
|
|
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
|
*/
|
|
/*
|
|
*
|
|
* (c) Copyright 1991, OPEN SOFTWARE FOUNDATION, INC.
|
|
* ALL RIGHTS RESERVED
|
|
*
|
|
*/
|
|
/*
|
|
* OSF/1 1.2
|
|
*/
|
|
/* socketvar.h 2.1 16:08:08 4/20/90 SecureWare */
|
|
/*
|
|
* Copyright (C) 1988,1989 Encore Computer Corporation. All Rights Reserved
|
|
*
|
|
* Property of Encore Computer Corporation.
|
|
* This software is made available solely pursuant to the terms of
|
|
* a software license agreement which governs its use. Unauthorized
|
|
* duplication, distribution or sale are strictly prohibited.
|
|
*
|
|
*/
|
|
/*
|
|
* Copyright (c) 1982, 1986, 1990 Regents of the University of California.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms are permitted provided
|
|
* that: (1) source distributions retain this entire copyright notice and
|
|
* comment, and (2) distributions including binaries display the following
|
|
* acknowledgement: ``This product includes software developed by the
|
|
* University of California, Berkeley and its contributors'' in the
|
|
* documentation or other materials provided with the distribution and in
|
|
* all advertising materials mentioning features or use of this software.
|
|
* Neither the name of the University nor the names of its contributors may
|
|
* be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* Base: socketvar.h 7.6 (Berkeley) 9/4/89
|
|
* Merged: socketvar.h 7.11 (Berkeley) 6/30/90
|
|
*/
|
|
|
|
#ifndef _SYS_SOCKETVAR_H_
|
|
#define _SYS_SOCKETVAR_H_
|
|
|
|
#if defined(_KERNEL) && !defined(_NET_GLOBALS_H_)
|
|
#include "net/net_globals.h"
|
|
#endif
|
|
|
|
#ifdef _KERNEL
|
|
typedef simple_lock_t sb_lock_t;
|
|
#else
|
|
typedef int sb_lock_t;
|
|
#endif
|
|
|
|
#if MACH
|
|
#include <sys/secdefines.h>
|
|
#if SEC_ARCH
|
|
#include <sys/security.h>
|
|
#endif
|
|
#endif
|
|
|
|
/*
|
|
* Kernel structure per socket.
|
|
* Contains send and receive buffer queues,
|
|
* handle on protocol and pointer to protocol
|
|
* private data and error information.
|
|
*/
|
|
struct socket {
|
|
short so_type; /* generic type, see socket.h */
|
|
short so_options; /* from socket call, see socket.h */
|
|
short so_linger; /* time to linger while closing */
|
|
short so_state; /* internal state flags SS_*, below */
|
|
caddr_t so_pcb; /* protocol control block */
|
|
struct protosw *so_proto; /* protocol handle */
|
|
struct socklocks *so_lock; /* socket structure lock(s) */
|
|
/*
|
|
* Variables for connection queueing.
|
|
* Socket where accepts occur is so_head in all subsidiary sockets.
|
|
* If so_head is 0, socket is not related to an accept.
|
|
* For head socket so_q0 queues partially completed connections,
|
|
* while so_q is a queue of connections ready to be accepted.
|
|
* If a connection is aborted and it has so_head set, then
|
|
* it has to be pulled out of either so_q0 or so_q.
|
|
* We allow connections to queue up based on current queue lengths
|
|
* and limit on number of queued connections for this socket.
|
|
*/
|
|
struct socket *so_head; /* back pointer to accept socket */
|
|
struct socket *so_q0; /* queue of partial connections */
|
|
struct socket *so_q; /* queue of incoming connections */
|
|
struct socket *so_dq; /* queue of defunct connections */
|
|
short so_q0len; /* partials on so_q0 */
|
|
short so_qlen; /* number of connections on so_q */
|
|
short so_qlimit; /* max number queued connections */
|
|
short so_dqlen; /* listener dequeues in progress */
|
|
short so_timeo; /* connection timeout */
|
|
u_short so_error; /* error affecting connection */
|
|
short so_special; /* special state flags SP_*, below */
|
|
short so_spare; /* available: pad for pid_t */
|
|
pid_t so_pgid; /* pgid for signals */
|
|
u_long so_oobmark; /* chars to oob mark */
|
|
/*
|
|
* Variables for socket buffering.
|
|
*/
|
|
struct sockbuf {
|
|
u_long sb_cc; /* actual chars in buffer */
|
|
u_long sb_hiwat; /* max actual char count */
|
|
u_long sb_mbcnt; /* chars of mbufs used */
|
|
u_long sb_mbmax; /* max chars of mbufs to use */
|
|
long sb_lowat; /* low water mark */
|
|
struct mbuf *sb_mb; /* the mbuf chain */
|
|
union { /* process selecting read/write */
|
|
struct proc *sb_selproc; /* UNIX */
|
|
struct sbselque { /* MACH */
|
|
struct sbselque *next, *prev;
|
|
} sb_selque;
|
|
} sb_select;
|
|
ushort sb_reqevents; /* current pending events */
|
|
int (*sb_iodone)(); /* I/O done function */
|
|
caddr_t sb_ioarg; /* arg for sb_iodone */
|
|
struct mbuf *sb_lastpkt; /* last packet of mbuf chain */
|
|
int sb_wakeone; /* SB_WAKEONE sleep event */
|
|
caddr_t sb_timer; /* pre-allocated trb */
|
|
short sb_flags; /* flags, see below */
|
|
ushort sb_timeo; /* timeout for read/write */
|
|
#ifdef _KERNEL
|
|
void (*sb_wakeup)(caddr_t, int);
|
|
#else
|
|
void (*sb_wakeup)(); /* upcall instead of sowakeup */
|
|
#endif
|
|
caddr_t sb_wakearg; /* (*sb_wakeup)(sb_wakearg, state) */
|
|
sb_lock_t sb_lock; /* sockbuf lock (in socklocks) */
|
|
} so_rcv, so_snd;
|
|
#define sb_sel sb_select.sb_selproc
|
|
#define sb_selq sb_select.sb_selque
|
|
#define SB_MAX (64*1024) /* default for max chars in sockbuf */
|
|
#define SB_LOCK 0x01 /* lock on data queue */
|
|
#define SB_WANT 0x02 /* someone is waiting to lock */
|
|
#define SB_WAIT 0x04 /* someone is waiting for data/space */
|
|
#define SB_SEL 0x08 /* someone is selecting */
|
|
#define SB_ASYNC 0x10 /* ASYNC I/O, need signals */
|
|
#define SB_COLL 0x20 /* collision selecting (UNIX) */
|
|
#define SB_NOINTR 0x40 /* operations not interruptible */
|
|
#define SB_WAKEONE 0x80 /* wakeup only one on notify */
|
|
#define SB_WAITING 0x100 /* MSG_WAITALL receive in progress */
|
|
#define SB_INHERIT (SB_NOINTR|SB_WAKEONE)
|
|
#ifdef _AIX
|
|
#define SB_KIODONE 0x400 /* socket kernel iodone */
|
|
#define SB_NOTIFY (SB_WAIT|SB_SEL|SB_ASYNC|SB_WAKEONE|SB_KIODONE)
|
|
#else /* _AIX */
|
|
#define SB_NOTIFY (SB_WAIT|SB_SEL|SB_ASYNC|SB_WAKEONE)
|
|
#endif /* _AIX */
|
|
#define SB_NOSELECT 0x800
|
|
|
|
caddr_t so_tpcb; /* Wisc. protocol control block XXX */
|
|
};
|
|
|
|
/*
|
|
* Socket state bits.
|
|
*/
|
|
#define SS_NOFDREF 0x001 /* no file table ref any more */
|
|
#define SS_ISCONNECTED 0x002 /* socket connected to a peer */
|
|
#define SS_ISCONNECTING 0x004 /* in process of connecting to peer */
|
|
#define SS_ISDISCONNECTING 0x008 /* in process of disconnecting */
|
|
#define SS_CANTSENDMORE 0x010 /* can't send more data to peer */
|
|
#define SS_CANTRCVMORE 0x020 /* can't receive more data from peer */
|
|
#define SS_RCVATMARK 0x040 /* at mark on input */
|
|
|
|
#define SS_PRIV 0x080 /* privileged for broadcast, raw... */
|
|
#define SS_NBIO 0x100 /* non-blocking ops */
|
|
#define SS_ASYNC 0x200 /* async i/o notify */
|
|
#define SS_ISCONFIRMING 0x400 /* deciding to accept connection req */
|
|
|
|
|
|
/*
|
|
* Special socket state bits.
|
|
*/
|
|
#define SP_PIPE 0x0001 /* socket is (unnamed) pipe */
|
|
#define SP_WATOMIC 0x0002 /* pipe write atomicity */
|
|
#define SP_NOUAREA 0x0004 /* no u-area available (XTI - XXX) */
|
|
#define SP_LOCKABLE 0x0008 /* socket of parallel domain */
|
|
#define SP_CLOSING 0x0010 /* closing a listening socket */
|
|
#define SP_RWAKEUP 0x0020 /* sorwakeup pending release of lock */
|
|
#define SP_WWAKEUP 0x0040 /* sowwakeup pending release of lock */
|
|
#define SP_EXTPRIV 0x0080 /* SS_PRIV managed externally */
|
|
#define SP_DISABLE 0x0800 /* use disable_lock for serialization */
|
|
#define SP_FREEABLE 0x8000 /* free socket on unlock */
|
|
#define SP_INHERIT (SP_PIPE|SP_WATOMIC|SP_NOUAREA|SP_LOCKABLE|SP_DISABLE)
|
|
|
|
#ifdef _KERNEL
|
|
|
|
/*
|
|
* Macros for sockets, socket locking and socket buffering.
|
|
*/
|
|
|
|
struct socklocks {
|
|
simple_lock_data_t sock_lock;
|
|
simple_lock_data_t snd_lock;
|
|
simple_lock_data_t rcv_lock;
|
|
int refcnt;
|
|
struct socket *sp_wake;
|
|
struct socket *so; /* back pointer */
|
|
int spl;
|
|
struct socklocks *freelist;
|
|
};
|
|
|
|
#define SOCKET_LOCKINIT(so, lp) { \
|
|
(so)->so_lock = (lp); \
|
|
(so)->so_snd.sb_lock = &((lp)->snd_lock); \
|
|
(so)->so_rcv.sb_lock = &((lp)->rcv_lock); \
|
|
(lp)->refcnt = 0; \
|
|
(lp)->sp_wake = 0; \
|
|
(lp)->so = so; \
|
|
(lp)->freelist = 0; \
|
|
lock_alloc(&((lp)->sock_lock), LOCK_ALLOC_PIN, SOCKET_LOCK_FAMILY, so);\
|
|
simple_lock_init(&((lp)->sock_lock)); \
|
|
}
|
|
|
|
/* The socket is considered locked for assertions if not lockable */
|
|
#define SOCKET_ISLOCKED(so) 1
|
|
|
|
/* Lock order of unpaired sockets is critical to avoid deadlock. */
|
|
#define SOCKET_LOCK2(so1, so2) { \
|
|
if ((so1) < (so2)) { \
|
|
SOCKET_LOCK(so1); \
|
|
if ((so1)->so_lock != (so2)->so_lock) \
|
|
SOCKET_LOCK(so2); \
|
|
} else { \
|
|
SOCKET_LOCK(so2); \
|
|
if ((so1)->so_lock != (so2)->so_lock) \
|
|
SOCKET_LOCK(so1); \
|
|
} \
|
|
}
|
|
#define SOCKET_UNLOCK2(so1, so2) { \
|
|
if ((so1) < (so2)) { \
|
|
if ((so1)->so_lock != (so2)->so_lock) \
|
|
SOCKET_UNLOCK(so2); \
|
|
SOCKET_UNLOCK(so1); \
|
|
} else { \
|
|
if ((so1)->so_lock != (so2)->so_lock) \
|
|
SOCKET_UNLOCK(so1); \
|
|
SOCKET_UNLOCK(so2); \
|
|
} \
|
|
}
|
|
|
|
#define SOCKET_LOCK(so) { \
|
|
if ((so)->so_special & SP_DISABLE) \
|
|
(so)->so_lock->spl = disable_lock(PL_IMP, &((so)->so_lock->sock_lock));\
|
|
else { \
|
|
simple_lock_data_t *lw = &((so)->so_lock->sock_lock); \
|
|
\
|
|
simple_lock(lw); \
|
|
while (lw != &((so)->so_lock->sock_lock)) { \
|
|
simple_unlock(lw); \
|
|
lw = &((so)->so_lock->sock_lock); \
|
|
simple_lock(lw); \
|
|
} \
|
|
} \
|
|
}
|
|
#define SOCKET_UNLOCK(so) (void)sounlock(so)
|
|
/* Sockbuf locks are disabled in non-debug kernel */
|
|
#define SOCKBUF_LOCKTEST 0
|
|
#define SOCKBUF_LOCK(sb) /*simple_lock((sb)->sb_lock)*/
|
|
#define SOCKBUF_UNLOCK(sb) /*simple_unlock((sb)->sb_lock)*/
|
|
#define SOCKBUF_ISLOCKED(sb) 1 /*lock_islocked((sb)->sb_lock)*/
|
|
|
|
/* Bits for network events to sb_wakeup */
|
|
#define SE_ERROR 0x0001 /* so_error non-0 */
|
|
#define SE_HAVEDATA 0x0002 /* data in send or recv q */
|
|
#define SE_HAVEOOB 0x0004 /* oob data in recv q */
|
|
#define SE_DATAFULL 0x0008 /* send or recv q is full */
|
|
#define SE_CONNOUT 0x0010 /* outgoing connect complete (connect) */
|
|
#define SE_CONNIN 0x0020 /* incoming connect complete (listen) */
|
|
#define SE_SENDCONN 0x0040 /* connected for send */
|
|
#define SE_RECVCONN 0x0080 /* connected for recv */
|
|
#define SE_POLL 0x4000 /* wakeup is synchronous poll */
|
|
#define SE_STATUS 0x8000 /* above status bits valid */
|
|
|
|
/* does socket have a valid u-area associated? (for stats, security, etc) */
|
|
#define SOHASUAREA(so) (!((so)->so_special & SP_NOUAREA))
|
|
|
|
/* what is the domain associated with this socket? */
|
|
#define sodomain(so) ((so)->so_proto->pr_domain)
|
|
|
|
/*
|
|
* How much space is there in a socket buffer (so->so_snd or so->so_rcv)?
|
|
* This is problematical if the fields are unsigned, as the space might
|
|
* still be negative (cc > hiwat or mbcnt > mbmax). Should detect
|
|
* overflow and return 0. Should use "lmin" but it doesn't exist now.
|
|
*/
|
|
#ifdef _AIX_FULLOSF
|
|
#define sbspace(sb) \
|
|
((long) imin((int)((sb)->sb_hiwat - (sb)->sb_cc), \
|
|
(int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
|
|
#else /* _AIX_FULLOSF */
|
|
#define sbspace(sb) \
|
|
(MIN((int)((sb)->sb_hiwat - (sb)->sb_cc), \
|
|
(int)((sb)->sb_mbmax - (sb)->sb_mbcnt)))
|
|
#endif /* _AIX_FULLOSF */
|
|
|
|
/* do we have to send all at once on a socket? */
|
|
#define sosendallatonce(so) \
|
|
((so)->so_proto->pr_flags & PR_ATOMIC)
|
|
|
|
/*
|
|
* Is write of len bytes to be atomic (for pipes)? Since sb_hiwat
|
|
* is adjusted by uipc_usrreq, it's not usable for this purpose,
|
|
* so we look straight at syslimits.h with the danger of
|
|
* PIPE_BUF > PIPSIZ.
|
|
*/
|
|
#define sowatomic(so, len) \
|
|
(((so)->so_special & SP_WATOMIC) && ((len) <= PIPE_BUF))
|
|
|
|
/* can we read something from so? */
|
|
#define soreadable(so) \
|
|
((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
|
|
((so)->so_state & SS_CANTRCVMORE) || \
|
|
(so)->so_qlen || (so)->so_error)
|
|
|
|
/* can we write something to so? */
|
|
#define sowriteable(so) \
|
|
(sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
|
|
(((so)->so_state&SS_ISCONNECTED) || \
|
|
((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0) || \
|
|
((so)->so_state & SS_CANTSENDMORE) || \
|
|
(so)->so_error)
|
|
|
|
/* adjust counters in sb reflecting allocation of m */
|
|
#define sballoc(sb, m) { \
|
|
(sb)->sb_cc += (m)->m_len; \
|
|
(sb)->sb_mbcnt += MSIZE; \
|
|
if ((m)->m_flags & M_EXT) \
|
|
(sb)->sb_mbcnt += (m)->m_ext.ext_size; \
|
|
}
|
|
|
|
/* adjust counters in sb reflecting freeing of m */
|
|
#define sbfree(sb, m) { \
|
|
(sb)->sb_cc -= (m)->m_len; \
|
|
(sb)->sb_mbcnt -= MSIZE; \
|
|
if ((m)->m_flags & M_EXT) \
|
|
(sb)->sb_mbcnt -= (m)->m_ext.ext_size; \
|
|
}
|
|
|
|
#define sorwakeup(so) sowakeup((so), &(so)->so_rcv)
|
|
#define sowwakeup(so) sowakeup((so), &(so)->so_snd)
|
|
|
|
/* to catch callers missing new second argument to sonewconn: */
|
|
#define sonewconn(head, connstatus) sonewsock((head), (connstatus))
|
|
extern u_long sb_max;
|
|
#endif /* _KERNEL */
|
|
|
|
#endif
|