--- src/sys/sys/caps.h 2003/11/24 21:15:54 1.1 +++ src/sys/sys/caps.h 2004/01/18 12:29:50 1.2 @@ -16,78 +16,170 @@ #include #endif -#define CAPS_USER 0x00000001 -#define CAPS_GROUP 0x00000002 -#define CAPS_WORLD 0x00000004 -#define CAPS_EXCL 0x00000008 -#define CAPS_ANYCLIENT (CAPS_USER|CAPS_GROUP|CAPS_WORLD) -#define CAPS_WCRED 0x00000010 /* waiting for cred */ +typedef enum caps_msg_state { + CAPMS_REQUEST, + CAPMS_REQUEST_RETRY, /* internal / FUTURE */ + CAPMS_REPLY, + CAPMS_REPLY_RETRY, /* internal / FUGURE */ + CAPMS_DISPOSE +} caps_msg_state_t; + +typedef struct caps_msgid { + off_t c_id; + caps_msg_state_t c_state; + int c_reserved01; +} *caps_msgid_t; /* - * caps_type associated with caps_port: - * - * CAPT_CLIENT port returned to client representing connection to - * service. - * CAPT_SERVICE port returned to service representing namespace - * CAPT_REMOTE temporary port used by service to represent - * client connections to service (set as replyport for - * messages) - * + * Note: upper 16 bits reserved for kernel use */ -enum caps_type { CAPT_UNKNOWN, CAPT_CLIENT, CAPT_SERVICE, CAPT_REMOTE }; +#define CAPF_UFLAGS 0xFFFF +#define CAPF_USER 0x0001 +#define CAPF_GROUP 0x0002 +#define CAPF_WORLD 0x0004 +#define CAPF_EXCL 0x0008 +#define CAPF_ANYCLIENT (CAPF_USER|CAPF_GROUP|CAPF_WORLD) +#define CAPF_WCRED 0x0010 /* waiting for cred */ +/* FUTURE: CAPF_ASYNC - support async services */ +/* FUTURE: CAPF_NOGROUPS - don't bother filling in the groups[] array */ +/* FUTURE: CAPF_TERM - send termination request to existing service */ +/* FUTURE: CAPF_TAKE - take over existing service's connections */ +/* FUTURE: CAPF_DISPOSE_IMM - need immediate dispose wakeups */ + +/* + * Abort codes + */ +#define CAPS_ABORT_NOTIMPL 0 /* abort not implemented, no action */ +#define CAPS_ABORT_RETURNED 1 /* already returned, no action */ +#define CAPS_ABORT_BEFORESERVER 2 /* caught before the server got it */ +#define CAPS_ABORT_ATSERVER 3 /* server had retrieved message */ + +#define CAPF_ABORT_HARD 0x0001 /* rip out from under server (3) */ #define CAPS_MAXGROUPS 16 +#define CAPS_MAXNAMELEN 64 +#define CAPS_MAXINPROG 128 struct thread; -struct caps_port; -typedef struct caps_port *caps_port_t; +typedef struct caps_port { + struct lwkt_port cp_lport; + int cp_portid; /* caps port id */ + int cp_upcallid; /* upcall id */ +} *caps_port_t; -struct caps_cred { +typedef struct caps_cred { pid_t pid; uid_t uid; uid_t euid; gid_t gid; int ngroups; + int cacheid; gid_t groups[CAPS_MAXGROUPS]; -}; +} *caps_cred_t; + +#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) -struct caps_port { - struct lwkt_port lport; - caps_port_t server; /* if CAPT_REMOTE, pointer to server */ - enum caps_type type; - int kqfd; /* kqueue to collect active connects */ - int lfd; /* server: listening on (server) */ - int cfd; /* client/remote connection fd */ - int flags; - TAILQ_HEAD(, caps_port) clist; /* server: client client connections */ - TAILQ_ENTRY(caps_port) centry; - TAILQ_HEAD(, lwkt_msg) wlist; /* queue of outgoing messages */ - TAILQ_HEAD(, lwkt_msg) mlist; /* written message waiting for reply */ - struct lwkt_msg rmsg_static; - lwkt_msg_t rmsg; /* read message in progress */ - struct caps_cred cred; /* cred of owner of port */ - int rbytes; /* read in progress byte count */ - int wbytes; /* write in progress byte count */ -}; - -#define CAPPF_WAITCRED 0x0001 -#define CAPPF_ONLIST 0x0002 -#define CAPPF_WREQUESTED 0x0004 /* write event requested */ -#define CAPPF_SHUTDOWN 0x0008 /* terminated/failed */ - -#define CAPMSG_MAXSIZE (1024+64*1024) - -/* - * API +typedef enum caps_type { + CAPT_UNKNOWN, CAPT_CLIENT, CAPT_SERVICE, CAPT_REMOTE +} caps_type_t; + +struct caps_kmsg; + +TAILQ_HEAD(caps_kmsg_queue, caps_kmsg); + +/* + * caps_kinfo - Holds a client or service registration + * + * ci_msgpendq: holds the kernel copy of the message after it has been + * sent to the local port. The message is matched up against + * replies and automatically replied if the owner closes its + * connection. */ -caps_port_t caps_service(const char *name, gid_t gid, mode_t modes, int flags); -caps_port_t caps_client(const char *name, uid_t uid, int flags); +typedef struct caps_kinfo { + struct lwkt_port ci_lport; /* embedded local port */ + struct caps_kinfo *ci_tdnext; /* per-process list */ + struct caps_kinfo *ci_hnext; /* registration hash table */ + struct thread *ci_td; /* owner */ + struct caps_kmsg_queue ci_msgpendq; /* pending reply (just rcvd) */ + struct caps_kmsg_queue ci_msguserq; /* pending reply (user holds) */ + struct caps_kinfo *ci_rcaps; /* connected to remote */ + int ci_cmsgcount; /* client in-progress msgs */ + int ci_id; + int ci_flags; + int ci_refs; + int ci_mrefs; /* message (vmspace) refs */ + caps_type_t ci_type; + uid_t ci_uid; + gid_t ci_gid; + int ci_namelen; + char ci_name[4]; /* variable length */ + /* ci_name must be last element */ +} *caps_kinfo_t; + +/* note: user flags are held in the low 16 bits */ +#define CAPKF_TDLIST 0x00010000 +#define CAPKF_HLIST 0x00020000 +#define CAPKF_FLUSH 0x00040000 +#define CAPKF_RCAPS 0x00080000 +#define CAPKF_CLOSED 0x00100000 +#define CAPKF_MWAIT 0x00200000 /* - * Temporary hack until LWKT threading is integrated. + * Kernel caps message. The kernel keepps track of messagse received, + * undergoing processing by the service, and returned. User-supplied data + * is copied on reception rather then transmission. */ -void *caps_client_waitreply(caps_port_t port, lwkt_msg_t msg); +typedef struct caps_kmsg { + TAILQ_ENTRY(caps_kmsg) km_node; + caps_kinfo_t km_mcaps; /* message sender */ + void *km_umsg; /* mcaps vmspace */ + int km_umsg_size; /* mcaps vmspace */ + struct caps_cred km_ccr; /* caps cred for msg */ + struct caps_msgid km_msgid; + int km_flags; +} *caps_kmsg_t; + +#define km_state km_msgid.c_state + +#define CAPKMF_ONUSERQ 0x0001 +#define CAPKMF_ONPENDQ 0x0002 +#define CAPKMF_REPLY 0x0004 +#define CAPKMF_CDONE 0x0008 +#define CAPKMF_PEEKED 0x0010 +#define CAPKMF_ABORTED 0x0020 + +#endif + +#ifdef _KERNEL + +/* + * kernel support + */ +void caps_exit(struct thread *td); +void caps_fork(struct proc *p1, struct proc *p2); + +#else + +/* + * Userland API (libcaps) + */ +caps_port_t caps_service(const char *name, uid_t uid, gid_t gid, + mode_t modes, int flags); +caps_port_t caps_client(const char *name, uid_t uid, gid_t gid, int flags); + +/* + * Syscall API + */ +int caps_sys_service(const char *name, uid_t uid, gid_t gid, int upcid, int flags); +int caps_sys_client(const char *name, uid_t uid, gid_t gid, int upcid, int flags); +off_t caps_sys_put(int portid, void *msg, int msgsize); +int caps_sys_reply(int portid, void *msg, int msgsize, off_t msgcid); +int caps_sys_get(int portid, void *msg, int maxsize, caps_msgid_t msgid, caps_cred_t ccr); +int caps_sys_wait(int portid, void *msg, int maxsize, caps_msgid_t msgid, caps_cred_t ccr); +int caps_sys_abort(int portid, off_t msgcid, int flags); + +#endif #endif