1
0
Files
irix-657m-src/irix/kern/sys/vsocket.h
2022-09-29 17:59:04 +03:00

408 lines
15 KiB
C

/**************************************************************************
* *
* Copyright (C) 1996, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ident "sys/vsocket.h: $Revision: 1.32 $"
#ifndef __VSOCKET_H__
#define __VSOCKET_H__
#include <sys/socket.h>
#include <sys/socketvar.h>
#ifdef _KERNEL
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <ksys/behavior.h>
#endif
struct vattr;
/*
* The vsocket is the distributed version of the Irix struct
* socket. It contains an interposer object containing an
* ops-vector which allows operations to be passed down to the
* real socket, if the server which implements the socket is
* in the same cell as the application which owns the vsocket.
* In this case the ops-vector is populated by lvector op-
* erations which know how to translate vsocket address to
* socket address and invoke the correct socket operations.
*
*
* struct vfile
* |
* |
* |
* struct vsocket ----
* | |
* | {lvector)
* | |
* struct socket <----
* |
* |
*
*
* If the server which implements the socket is on a different
* cell to the application which owns the vsocket, then the
* ops-vector on the client side is populated by the dc_vector
* operations, which know how to carry out rcp operations to
* the server cell, and on the server side by ds_vector operations
* which know how to invoke the corresponding socket operations
* and pass the results back.
*
* struct vfile
* |
* |
* |
* struct vsocket struct vsocket
* | |
* (dc_vector) | | (ds_vector)
* | |
* struct dcvsock <======> struct dsvsock
* |
* | (direct *so)
* |
* struct socket
*/
typedef struct vsocket {
bhv_head_t vs_bh; /* Base behaviour */
u_int vs_flags;
mutex_t vs_lock;
sv_t vs_sv;
int vs_refcnt;
int vs_type; /* cached from create */
int vs_protocol; /* cached from create */
int vs_domain; /* cached from create */
void *vs_vsent;
} vsock_t;
#ifdef _KERNEL
/*
* Flag values for vs_flags
*/
#define VS_LASTREFWAIT 0x0001 /* someone waiting for last ref */
#define VS_RELEWAIT 0x0002 /* wakeup on each rele */
#define VS_CLIENT_CLOSE 0x0004 /* XXX not used? */
#define VS_SERVER_CLOSE 0x0008 /* XXX not used? */
#define VS_IDLE 0x0010 /* token module called idle */
/*
* Conversion macros.
*/
#define VSOCK_TO_FIRST_BHV(vs) (BHV_HEAD_FIRST(&(vs)->vs_bh))
#define VS_BHV_HEAD(vs) ((bhv_head_t *)(&((vs)->vs_bh)))
#define BHV_TO_VSOCK(bhv) ((struct vsocket *)(BHV_VOBJ(bhv)))
#define BHV_TO_VSOCK_TRY(bhv) ((struct vsocket *)(BHV_VOBJNULL(bhv)))
/*
* Locking macros.
*/
#define VSOCKET_LOCK_INIT(v) mutex_init(&(v->vs_lock), MUTEX_DEFAULT, "vsock")
#define VSOCKET_LOCK_DESTROY(v) mutex_destroy(&(v->vs_lock))
#define VSOCKET_LOCK(v) mutex_lock(&(v->vs_lock), PZERO)
#define VSOCKET_LOCK_TRY(v) mutex_trylock(&(v->vs_lock))
#define VSOCKET_UNLOCK(v) mutex_unlock(&(v->vs_lock))
enum vs_type {VS_CREATE, VS_CLOSE, VS_ABORT, VS_SEND, VS_RECEIVE,
VS_ACCEPT, VS_LISTEN, VS_CONNECT, VS_CONNECT2, VS_BIND,
VS_SHUTDOWN, VS_GETATTR, VS_SETATTR, VS_IOCTL, VS_SELECT,
VS_GETSOCKNAME, VS_SETFL, VS_GETPEERNAME, VS_FSTAT, VS_FCNTL,
VS_PATHCONF, VS_MAX};
typedef struct vsocket_ops {
bhv_position_t vs_position; /* position within behavior chain */
int (*vs_create)(struct vsocket *, int, struct vsocket **, int,
int);
int (*vs_close)(bhv_desc_t *, int, int);
int (*vs_abort)();
int (*vs_send)(bhv_desc_t *, struct mbuf *, struct uio *,
int, struct mbuf *);
int (*vs_sendit)(bhv_desc_t *, struct msghdr *,
int, rval_t *);
int (*vs_receive)(bhv_desc_t *, struct mbuf **, struct uio *,
int *, struct mbuf **);
int (*vs_recvit)(bhv_desc_t *, struct msghdr *,
int *, void *, void *, rval_t *, int);
int (*vs_accept)(bhv_desc_t *, caddr_t, sysarg_t *, sysarg_t,
rval_t *, struct vsocket **);
int (*vs_listen)(bhv_desc_t *, int);
int (*vs_connect)(bhv_desc_t *, caddr_t, sysarg_t);
int (*vs_connect2)(bhv_desc_t *, bhv_desc_t *);
int (*vs_bind)(bhv_desc_t *, struct mbuf *);
int (*vs_shutdown)(bhv_desc_t *, int);
int (*vs_getattr)(bhv_desc_t *, int, int, struct mbuf **);
int (*vs_setattr)(bhv_desc_t *, int, int, struct mbuf *);
int (*vs_ioctl)(bhv_desc_t *, int, void *, int, struct cred *,
rval_t *);
int (*vs_select)(bhv_desc_t *, short, int, short *,
struct pollhead **, unsigned int *);
int (*vs_getsockname)(bhv_desc_t *, caddr_t, sysarg_t *,
sysarg_t, rval_t *);
int (*vs_setfl)(bhv_desc_t *, int, int, struct cred *);
int (*vs_getpeername)(bhv_desc_t *, caddr_t, sysarg_t *, rval_t *);
int (*vs_fstat)(bhv_desc_t *, struct vattr *, int, struct cred *);
int (*vs_fcntl)(bhv_desc_t *, int, void *, rval_t *);
int (*vs_pathconf)(bhv_desc_t *, int, long *, struct cred *);
} vsocket_ops_t;
extern struct vsocket_ops lvector;
#define VS_VOP(vs) ((vsocket_ops_t *)(BHV_OPS(BHV_HEAD_FIRST(&(vs->vs_bh)))))
#define VSOP_CREATE(vs, dom, avso, type, proto, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_create)(VSOCK_TO_FIRST_BHV(vs), dom, avso, type, proto); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_CLOSE(vs, lastclose, fflag, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_close)(VSOCK_TO_FIRST_BHV(vs), lastclose, fflag); \
if (!lastclose) BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_SEND(vs, nam, uio, flags, rights, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_send)(VSOCK_TO_FIRST_BHV(vs), nam, uio, flags, rights); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_SENDIT(vs, mp, flags, rvp, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_sendit)(VSOCK_TO_FIRST_BHV(vs), mp, flags, rvp); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_RECEIVE(vs, nam, uio, flags, rights, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_receive)(VSOCK_TO_FIRST_BHV(vs), nam, uio, flags, rights); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_RECVIT(vs, mp, flags, a1, a2, rvp, t, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_recvit)(VSOCK_TO_FIRST_BHV(vs), mp, flags, a1, a2, rvp, t); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_CONNECT(vs, nam, namelen, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_connect)(VSOCK_TO_FIRST_BHV(vs), nam, namelen); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_BIND(vs, nam, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_bind)(VSOCK_TO_FIRST_BHV(vs), nam); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_GETATTR(vs, level, name, m, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_getattr)(VSOCK_TO_FIRST_BHV(vs), level, name, m); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_SETATTR(vs, level, name, m, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_setattr)(VSOCK_TO_FIRST_BHV(vs), level, name, m); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_IOCTL(vs, cmd, arg, flag, cr, rvalp, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_ioctl)(VSOCK_TO_FIRST_BHV(vs), cmd, arg, flag, cr, rvalp); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_SELECT(vs, vents, anyyet, reventsp, phpp, genp, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_select)(VSOCK_TO_FIRST_BHV(vs), vents, anyyet, reventsp, phpp, genp); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_LISTEN(vs, backlog, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_listen)(VSOCK_TO_FIRST_BHV(vs), backlog); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_ACCEPT(vs, nam, anamelen, namelen, rvp, nvso, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_accept)(VSOCK_TO_FIRST_BHV(vs), nam, anamelen, namelen, rvp, nvso); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_GETSOCKNAME(vs, asa, alen, len, rvp, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_getsockname)(VSOCK_TO_FIRST_BHV(vs), asa, alen, len, rvp); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_SHUTDOWN(vs, how, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_shutdown)(VSOCK_TO_FIRST_BHV(vs), how); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_SETFL(vs, oflags, nflags, cr, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_setfl)(VSOCK_TO_FIRST_BHV(vs), oflags, nflags, cr); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_GETPEERNAME(vs, asa, alen, rvp, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_getpeername)(VSOCK_TO_FIRST_BHV(vs), asa, alen, rvp); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_FSTAT(vs, vap, flags, cr, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_fstat)(VSOCK_TO_FIRST_BHV(vs), vap, flags, cr); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_CONNECT2(vs1, vs2, error) \
{ \
BHV_READ_LOCK(&(vs1)->vs_bh); \
error=(*VS_VOP(vs1)->vs_connect2)(VSOCK_TO_FIRST_BHV(vs1), VSOCK_TO_FIRST_BHV(vs2)); \
BHV_READ_UNLOCK(&(vs1)->vs_bh); \
}
#define VSOP_FCNTL(vs, cmd, arg, rvp, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_fcntl)(VSOCK_TO_FIRST_BHV(vs), cmd, arg, rvp); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
#define VSOP_PATHCONF(vs, cmd, val, cr, error) \
{ \
BHV_READ_LOCK(&(vs)->vs_bh); \
error=(*VS_VOP(vs)->vs_pathconf)(VSOCK_TO_FIRST_BHV(vs), cmd, val, cr); \
BHV_READ_UNLOCK(&(vs)->vs_bh); \
}
/*
* Registration for the positions at which the different vsock behaviors
* are chained. When on the same chain, a behavior with a higher position
* number is invoked before one with a lower position number.
*/
#define VSOCK_POSITION_SOCK BHV_POSITION_BASE /* chain bottom */
#define VSOCK_POSITION_DC BHV_POSITION_TOP /* distr. client */
#define VSOCK_POSITION_DS BHV_POSITION_TOP /* distr. server */
#define VS_NEXT(cur, next, op) \
{ \
next = BHV_NEXT(cur); \
ASSERT(next); \
}
#define PVS_VOP(bdp) ((struct vsocket_ops *)(BHV_OPS(bdp)))
#define PVSOP_SEND(bdp, nam, uio, flags, rights, error) \
error=(*PVS_VOP(bdp)->vs_send)(bdp, nam, uio, flags, rights)
#define PVSOP_SENDIT(bdp, mp, flags, rvp, error) \
error=(*PVS_VOP(bdp)->vs_sendit)(bdp, mp, flags, rvp)
#define PVSOP_RECEIVE(bdp, nam, uio, flags, rights, error) \
error=(*PVS_VOP(bdp)->vs_receive)(bdp, nam, uio, flags, rights)
#define PVSOP_RECVIT(bdp, mp, flags, a1, a2, rvp, t, error)\
error=(*PVS_VOP(bdp)->vs_recvit)(bdp, mp, flags, a1, a2, rvp, t)
#define PVSOP_CONNECT(bdp, nam, namelen, error) \
error=(*PVS_VOP(bdp)->vs_connect)(bdp, nam, namelen)
#define PVSOP_CONNECT2(bdp1, bdp2, error) \
error=(*PVS_VOP(bdp1)->vs_connect2)(bdp1, bdp2)
#define PVSOP_BIND(bdp, nam, error) \
error=(*PVS_VOP(bdp)->vs_bind)(bdp, nam)
#define PVSOP_GETATTR(bdp, level, name, m, error) \
error=(*PVS_VOP(bdp)->vs_getattr)(bdp, level, name, m)
#define PVSOP_SETATTR(bdp, level, name, m, error) \
error=(*PVS_VOP(bdp)->vs_setattr)(bdp, level, name, m)
#define PVSOP_IOCTL(bdp, cmd, arg, flag, cr, rvalp, error) \
error=(*PVS_VOP(bdp)->vs_ioctl)(bdp, cmd, arg, flag, cr, rvalp)
#define PVSOP_SELECT(bdp, vents, anyyet, reventsp, phpp, genp, error) \
error=(*PVS_VOP(bdp)->vs_select)(bdp, vents, anyyet, reventsp, phpp, genp)
#define PVSOP_SHUTDOWN(bdp, how, error) \
error=(*PVS_VOP(bdp)->vs_shutdown)(bdp, how)
#define PVSOP_LISTEN(bdp, backlog, error) \
error=(*PVS_VOP(bdp)->vs_listen)(bdp, backlog)
#define PVSOP_ACCEPT(bdp, nam, anamelen, namelen, rvp, nvso, error) \
error=(*PVS_VOP(bdp)->vs_accept)(bdp, nam, anamelen, namelen, \
rvp, nvso)
#define PVSOP_GETSOCKNAME(bdp, asa, alen, len, rvp, error) \
error=(*PVS_VOP(bdp)->vs_getsockname)(bdp, asa, alen, len, rvp)
#define PVSOP_GETPEERNAME(bdp, asa, alen, rvp, error) \
error=(*PVS_VOP(bdp)->vs_getpeername)(bdp, asa, alen, rvp)
#define PVSOP_SETFL(bdp, oflags, nflags, cr, error) \
error=(*PVS_VOP(bdp)->vs_setfl)(bdp, oflags, nflags, cr)
#define PVSOP_FCNTL(bdp, cmd, arg, rvp, error) \
error=(*PVS_VOP(bdp)->vs_fcntl)(bdp, cmd, arg, rvp)
#define PVSOP_FSTAT(bdp, vap, flags, cr, error) \
error=(*PVS_VOP(bdp)->vs_fstat)(bdp, vap, flags, cr)
enum vsockop {VT_CREATE, VT_CLOSE, VT_ABORT, VT_SEND, VT_RECEIVE,
VT_ACCEPT, VT_LISTEN, VT_CONNECT, VT_CONNECT2, VT_BIND,
VT_SHUTDOWN, VT_GETATTR, VT_SETATTR, VT_IOCTL, VT_SELECT};
#ifdef DEBUG
#define LSTATISTICS(i) lstatistics[i]++
#define DCSTATISTICS(i) dcstatistics[i]++
#define DSSTATISTICS(i) dsstatistics[i]++
#define DSS_STATISTICS(i) dss_statistics[i]++
#else
#define LSTATISTICS(i)
#define DCSTATISTICS(i)
#define DSSTATISTICS(i)
#define DSS_STATISTICS(i)
#endif /* DEBUG */
/* Create a new vsocket/socket */
#define vsocreate(dom, avso, type, proto) \
vsocreate_internal(dom, avso, type, proto, NULL)
/* Wrap an existing socket in a vsocket */
#define vsowrap(so, avso, dom, type, proto) \
vsocreate_internal(dom, avso, type, proto, so)
int vsocreate_internal(int, struct vsocket **, int, int, struct socket *);
int vsoo_close(struct vsocket *, int);
int getvsock(int, struct vsocket **);
int vso_bind(struct vsocket *, struct mbuf *);
int vsoo_listen(struct vsocket *, int);
int vso_connect(struct vsocket *, caddr_t, int);
int vsoo_send(struct vsocket *, struct mbuf *,
register struct uio *, int, struct mbuf *);
int vsoo_receive(struct vsocket *, struct mbuf **,
struct uio *, int, struct mbuf **);
int vsoo_setopt(struct vsocket *, int, int, struct mbuf *);
void vso_initialize(void);
struct vsocket *vsocket_alloc(void);
void vsocket_release(struct vsocket *);
int vsock_drop_ref(struct vsocket *);
void vsock_trace_init(void);
void vsock_trace_header (void);
void vsock_trace (enum vs_type, void *,
void *, u_int, long, long, long);
void idbg_vsocket(struct vsocket *);
int sendit(bhv_desc_t *, struct msghdr *, int, rval_t *);
int recvit(bhv_desc_t *, struct msghdr *, int *, void *,
void *, rval_t *, int);
#endif /* _KERNEL */
#endif /* __VSOCKET_H__ */