|
|
| version 1.1, 2003/11/24 21:15:54 | version 1.2, 2004/01/18 12:29:50 |
|---|---|
| Line 16 | Line 16 |
| #include <sys/msgport.h> | #include <sys/msgport.h> |
| #endif | #endif |
| #define CAPS_USER 0x00000001 | typedef enum caps_msg_state { |
| #define CAPS_GROUP 0x00000002 | CAPMS_REQUEST, |
| #define CAPS_WORLD 0x00000004 | CAPMS_REQUEST_RETRY, /* internal / FUTURE */ |
| #define CAPS_EXCL 0x00000008 | CAPMS_REPLY, |
| #define CAPS_ANYCLIENT (CAPS_USER|CAPS_GROUP|CAPS_WORLD) | CAPMS_REPLY_RETRY, /* internal / FUGURE */ |
| #define CAPS_WCRED 0x00000010 /* waiting for cred */ | 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: | * Note: upper 16 bits reserved for kernel use |
| * | |
| * 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) | |
| * | |
| */ | */ |
| 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_MAXGROUPS 16 |
| #define CAPS_MAXNAMELEN 64 | |
| #define CAPS_MAXINPROG 128 | |
| struct thread; | 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; | pid_t pid; |
| uid_t uid; | uid_t uid; |
| uid_t euid; | uid_t euid; |
| gid_t gid; | gid_t gid; |
| int ngroups; | int ngroups; |
| int cacheid; | |
| gid_t groups[CAPS_MAXGROUPS]; | gid_t groups[CAPS_MAXGROUPS]; |
| }; | } *caps_cred_t; |
| #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) | |
| struct caps_port { | typedef enum caps_type { |
| struct lwkt_port lport; | CAPT_UNKNOWN, CAPT_CLIENT, CAPT_SERVICE, CAPT_REMOTE |
| caps_port_t server; /* if CAPT_REMOTE, pointer to server */ | } caps_type_t; |
| enum caps_type type; | |
| int kqfd; /* kqueue to collect active connects */ | struct caps_kmsg; |
| int lfd; /* server: listening on (server) */ | |
| int cfd; /* client/remote connection fd */ | TAILQ_HEAD(caps_kmsg_queue, caps_kmsg); |
| int flags; | |
| TAILQ_HEAD(, caps_port) clist; /* server: client client connections */ | /* |
| TAILQ_ENTRY(caps_port) centry; | * caps_kinfo - Holds a client or service registration |
| TAILQ_HEAD(, lwkt_msg) wlist; /* queue of outgoing messages */ | * |
| TAILQ_HEAD(, lwkt_msg) mlist; /* written message waiting for reply */ | * ci_msgpendq: holds the kernel copy of the message after it has been |
| struct lwkt_msg rmsg_static; | * sent to the local port. The message is matched up against |
| lwkt_msg_t rmsg; /* read message in progress */ | * replies and automatically replied if the owner closes its |
| struct caps_cred cred; /* cred of owner of port */ | * connection. |
| 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 | |
| */ | */ |
| caps_port_t caps_service(const char *name, gid_t gid, mode_t modes, int flags); | typedef struct caps_kinfo { |
| caps_port_t caps_client(const char *name, uid_t uid, int flags); | 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 | #endif |