From 4c52ca4ea2c7b2d9f50fcc867d40e5b2170d4f3c Mon Sep 17 00:00:00 2001 From: Jose Bollo Date: Mon, 7 Oct 2019 17:16:22 +0200 Subject: Add documentation and fixes Documents the client API Fixes few bugs Signed-off-by: Jose Bollo --- compat/src/lib-compat.c | 12 +- src/cyn-server.c | 30 ++-- src/cyn-server.h | 51 +++++- src/cynagora.c | 416 ++++++++++++++++++++++++++++++++---------------- src/cynagora.h | 292 ++++++++++++++++++++++++++++----- src/main-cynagoradm.c | 2 +- 6 files changed, 604 insertions(+), 199 deletions(-) diff --git a/compat/src/lib-compat.c b/compat/src/lib-compat.c index 8035292..a7c1532 100644 --- a/compat/src/lib-compat.c +++ b/compat/src/lib-compat.c @@ -151,12 +151,12 @@ struct cynara_admin; int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) { - return from_status(cynagora_open((cynagora_t**)pp_cynara_admin, cynagora_Admin, 1, 0)); + return from_status(cynagora_create((cynagora_t**)pp_cynara_admin, cynagora_Admin, 1, 0)); } int cynara_admin_finish(struct cynara_admin *p_cynara_admin) { - cynagora_close((cynagora_t*)p_cynara_admin); + cynagora_destroy((cynagora_t*)p_cynara_admin); return CYNARA_API_SUCCESS; } @@ -413,7 +413,7 @@ int cynara_async_initialize(cynara_async **pp_cynara, const cynara_async_configu if (p_cynara == NULL) ret = CYNARA_API_OUT_OF_MEMORY; else { - ret = from_status(cynagora_open(&p_cynara->rcyn, cynagora_Check, p_conf ? p_conf->szcache : 1, 0)); + ret = from_status(cynagora_create(&p_cynara->rcyn, cynagora_Check, p_conf ? p_conf->szcache : 1, 0)); if (ret != CYNARA_API_SUCCESS) free(p_cynara); else { @@ -439,7 +439,7 @@ void cynara_async_finish(cynara_async *p_cynara) } } - cynagora_close(p_cynara->rcyn); + cynagora_destroy(p_cynara->rcyn); while((req = p_cynara->reqs)) { p_cynara->reqs = req->next; @@ -569,12 +569,12 @@ int cynara_configuration_set_cache_size(cynara_configuration *p_conf, int cynara_initialize(cynara **pp_cynara, const cynara_configuration *p_conf) { - return from_status(cynagora_open((cynagora_t**)pp_cynara, cynagora_Check, p_conf ? p_conf->szcache : 1, 0)); + return from_status(cynagora_create((cynagora_t**)pp_cynara, cynagora_Check, p_conf ? p_conf->szcache : 1, 0)); } int cynara_finish(cynara *p_cynara) { - cynagora_close((cynagora_t*)p_cynara); + cynagora_destroy((cynagora_t*)p_cynara); return CYNARA_API_SUCCESS; } diff --git a/src/cyn-server.c b/src/cyn-server.c index 1921142..d751fda 100644 --- a/src/cyn-server.c +++ b/src/cyn-server.c @@ -108,6 +108,13 @@ struct cyn_server pollitem_t check; }; +/** + * Log the protocol + * @param cli the client handle + * @param c2s direction: if not 0: client to server, if 0: server to client + * @param count count of fields + * @param fields the fields + */ static void dolog( @@ -365,12 +372,16 @@ onrequest( /* version hand-shake */ if (!cli->version) { - if (!ckarg(args[0], _cynagora_, 0) || count != 2 || !ckarg(args[1], "1", 0)) - goto invalid; - putx(cli, _yes_, "1", cyn_changeid_string(), NULL); - flushw(cli); + if (ckarg(args[0], _cynagora_, 0)) { + if (count < 2 || !ckarg(args[1], "1", 0)) + goto invalid; + putx(cli, _yes_, "1", cyn_changeid_string(), NULL); + flushw(cli); + cli->version = 1; + return; + } + /* switch automatically to version 1 */ cli->version = 1; - return; } switch(args[0][0]) { @@ -703,7 +714,7 @@ on_agent_server_event( on_server_event(pollitem, events, pollfd, server_Agent); } -/** destroy a server */ +/* see cyn-server.h */ void cyn_server_destroy( cyn_server_t *server @@ -719,7 +730,7 @@ cyn_server_destroy( } } -/** create a server */ +/* see cyn-server.h */ int cyn_server_create( cyn_server_t **server, @@ -821,7 +832,7 @@ error: return rc; } -/** stop the server */ +/* see cyn-server.h */ void cyn_server_stop( cyn_server_t *server, @@ -830,7 +841,7 @@ cyn_server_stop( server->stopped = status ?: INT_MIN; } -/** create a server */ +/* see cyn-server.h */ int cyn_server_serve( cyn_server_t *server @@ -842,4 +853,3 @@ cyn_server_serve( } return server->stopped == INT_MIN ? 0 : server->stopped; } - diff --git a/src/cyn-server.h b/src/cyn-server.h index 8117724..d2c7984 100644 --- a/src/cyn-server.h +++ b/src/cyn-server.h @@ -23,16 +23,25 @@ typedef struct cyn_server cyn_server_t; +/** + * Boolean flag telling whether the server logs or not its received commands + */ extern bool cyn_server_log; -extern -void -cyn_server_destroy( - cyn_server_t *server -); - +/** + * Create a cynagora server + * + * @param server where to store the handler of the created server + * @param admin_socket_spec specification of the admin socket + * @param check_socket_spec specification of the check socket + * @param agent_socket_spec specification of the agent socket + * + * @return 0 on success or a negative -errno value + * + * @see cyn_server_destroy + */ extern int cyn_server_create( @@ -42,12 +51,42 @@ cyn_server_create( const char *agent_socket_spec ); +/** + * Destroy a created server and release its resources + * + * @param server the handler of the server + * + * @see cyn_server_create + */ +extern +void +cyn_server_destroy( + cyn_server_t *server +); + +/** + * Start the cynagora server and returns only when stopped + * + * @param server the handler of the server + * + * @return 0 on success or a negative -errno value + * + * @see cyn_server_stop + */ extern int cyn_server_serve( cyn_server_t *server ); +/** + * Stop the cynagora server + * + * @param server the handler of the server + * @param status the status that the function cyn_server_serve should return + * + * @see cyn_server_serve + */ extern void cyn_server_stop( diff --git a/src/cynagora.c b/src/cynagora.c index 1165e64..ee55dc6 100644 --- a/src/cynagora.c +++ b/src/cynagora.c @@ -52,9 +52,7 @@ struct asreq struct asreq *next; /** callback function */ - void (*callback)( - void *closure, - int status); + cynagora_async_check_cb_t *callback; /** closure of the callback */ void *closure; @@ -75,9 +73,6 @@ struct cynagora /** type of link */ cynagora_type_t type; - /** spec of the socket */ - const char *socketspec; - /** protocol manager object */ prot_t *prot; @@ -96,7 +91,7 @@ struct cynagora /** async */ struct { /** control callback */ - cynagora_async_ctl_t controlcb; + cynagora_async_ctl_cb_t *controlcb; /** closure */ void *closure; @@ -104,12 +99,17 @@ struct cynagora /** requests */ asreq_t *requests; } async; -}; -static void disconnection(cynagora_t *cynagora); + /** spec of the socket */ + char socketspec[]; +}; /** - * Flush the write buffer + * Flush the write buffer of the client + * + * @param cynagora the handler of the client + * + * @return 0 in case of success or a negative -errno value */ static int @@ -141,7 +141,14 @@ flushw( /** * Put the command made of arguments ... * Increment the count of pending requests. - * Return 0 in case of success or a negative number on error. + * + * @param cynagora the handler of the client + * @param command the command to send + * @param optarg an optional argument or NULL + * @param optkey an optional key or NULL + * @param optval an optional value or NULL + * + * @return 0 in case of success or a negative -errno value */ static int @@ -156,8 +163,10 @@ putxkv( prot_t *prot; char text[30]; + /* retrieves the protocol handler */ prot = cynagora->prot; for(trial = 0 ; ; trial++) { + /* fill the protocol handler with command and its arguments */ rc = prot_put_field(prot, command); if (!rc && optarg) rc = prot_put_field(prot, optarg); @@ -183,19 +192,33 @@ putxkv( if (!rc) rc = prot_put_end(prot); if (!rc) { + /* success ! */ /* client always flushes */ cynagora->pending++; return flushw(cynagora); } + + /* failed to fill protocol, cancel current composition */ prot_put_cancel(prot); + + /* fail if was last trial */ if (trial >= 1) return rc; + + /* try to flush the output buffer */ rc = flushw(cynagora); if (rc) return rc; } } +/** + * Wait some input event + * + * @param cynagora the handler of the client + * + * @return 0 in case of success or a negative -errno value + */ static int wait_input( @@ -210,19 +233,28 @@ wait_input( return rc < 0 ? -errno : 0; } +/** + * Get the next reply if any + * + * @param cynagora the handler of the client + * + * @return the count of field of the reply (can be 0) + * or -EAGAIN if there is no reply + */ static int get_reply( cynagora_t *cynagora ) { int rc; + uint32_t cacheid; prot_next(cynagora->prot); rc = prot_get(cynagora->prot, &cynagora->reply.fields); if (rc > 0) { if (0 == strcmp(cynagora->reply.fields[0], _clear_)) { - cache_clear(cynagora->cache, - rc > 1 ? (uint32_t)atol(cynagora->reply.fields[1]) : 0); + cacheid = rc > 1 ? (uint32_t)atol(cynagora->reply.fields[1]) : 0; + cache_clear(cynagora->cache, cacheid); rc = 0; } else { if (0 != strcmp(cynagora->reply.fields[0], _item_)) @@ -233,6 +265,16 @@ get_reply( return rc; } +/** + * Wait for a reply + * + * @param cynagora the handler of the client + * @param block + * + * @return the count of fields greater than 0 or a negative -errno value + * or -EAGAIN if nothing and block == 0 + * or -EPIPE if broken link + */ static int wait_reply( @@ -242,11 +284,13 @@ wait_reply( int rc; for(;;) { - prot_next(cynagora->prot); + /* get the next reply if any */ rc = get_reply(cynagora); if (rc > 0) return rc; + if (rc < 0) { + /* wait for an answer */ rc = prot_read(cynagora->prot, cynagora->fd); while (rc <= 0) { if (rc == 0) @@ -261,6 +305,13 @@ wait_reply( } } +/** + * Read and process any input data + * + * @param cynagora the client handler + * + * @return 0 on success or a negative -errno error code + */ static int flushr( @@ -272,6 +323,13 @@ flushr( return rc; } +/** + * Test if the first field is "done" + * + * @param cynagora the handler of the client + * + * @return 0 if done or -ECANCELED otherwise + */ static int status_done( @@ -280,6 +338,14 @@ status_done( return strcmp(cynagora->reply.fields[0], _done_) ? -ECANCELED : 0; } +/** + * Translates the check/test reply to a forbiden/granted status + * + * @param cynagora the handler of the client + * @param expire where to store the expiration read + * + * @return 0 in case of success or a negative -errno value + */ static int status_check( @@ -305,6 +371,13 @@ status_check( return rc; } +/** + * Wait for a reply + * + * @param cynagora the handler of the client + * + * @return 0 in case of success or a negative -errno value + */ static int wait_pending_reply( @@ -320,6 +393,14 @@ wait_pending_reply( } } +/** + * Wait the reply "done" + * + * @param cynagora the handler of the client + * + * @return 0 in case of success or a negative -errno value + * -ECANCELED when received an error status + */ static int wait_done( @@ -331,6 +412,15 @@ wait_done( return rc; } +/** + * Calls the asynchronous control callback with operation and the given events + * + * @param cynagora the handler of the client + * @param op operation (see epoll_ctl) + * @param events the events (see epoll_ctl) + * + * @return 0 in case of success or a negative -errno value + */ static int async( @@ -343,6 +433,11 @@ async( : 0; } +/** + * Disconnect the client + * + * @param cynagora the handler of the client + */ static void disconnection( @@ -355,6 +450,13 @@ disconnection( } } +/** + * connect the client + * + * @param cynagora the handler of the client + * + * @return 0 in case of success or a negative -errno value + */ static int connection( @@ -391,6 +493,13 @@ connection( return rc; } +/** + * ensure the connection is opened + * + * @param cynagora the handler of the client + * + * @return 0 in case of success or a negative -errno value + */ static int ensure_opened( @@ -401,10 +510,63 @@ ensure_opened( return cynagora->fd < 0 ? connection(cynagora) : 0; } -/************************************************************************************/ +/** + * Check or test synchronously + * + * @param cynagora + * @param key + * @param action + * + * @return 0 in case of success or a negative -errno value + */ +static +int +check_or_test( + cynagora_t *cynagora, + const cynagora_key_t *key, + const char *action +) { + int rc; + time_t expire; + + /* forbids 2 queries interleaved */ + if (cynagora->async.requests != NULL) + return -EINPROGRESS; + + /* ensure opened */ + rc = ensure_opened(cynagora); + if (rc < 0) + return rc; + + /* ensure there is no clear cache pending */ + flushr(cynagora); + + /* check cache item */ + rc = cache_search(cynagora->cache, key); + if (rc >= 0) + return rc; + + /* send the request */ + rc = putxkv(cynagora, action, 0, key, 0); + if (rc >= 0) { + /* get the response */ + rc = wait_pending_reply(cynagora); + if (rc >= 0) { + rc = status_check(cynagora, &expire); + if (rc >= 0 && action == _check_ && cynagora->cache) + cache_put(cynagora->cache, key, rc, expire); + } + } + return rc; +} + +/******************************************************************************/ +/*** PUBLIC METHODS ***/ +/******************************************************************************/ +/* see cynagora.h */ int -cynagora_open( +cynagora_create( cynagora_t **prcyn, cynagora_type_t type, uint32_t cache_size, @@ -415,10 +577,18 @@ cynagora_open( /* socket spec */ switch(type) { + case cynagora_Admin: + socketspec = cyn_get_socket_admin(socketspec); + break; + + case cynagora_Agent: + socketspec = cyn_get_socket_agent(socketspec); + break; + + case cynagora_Check: default: - case cynagora_Check: socketspec = cyn_get_socket_check(socketspec); break; - case cynagora_Admin: socketspec = cyn_get_socket_admin(socketspec); break; - case cynagora_Agent: socketspec = cyn_get_socket_agent(socketspec); break; + socketspec = cyn_get_socket_check(socketspec); + break; } /* allocate the structure */ @@ -434,12 +604,11 @@ cynagora_open( goto error2; /* socket spec */ - strcpy((char*)(cynagora+1), socketspec); + strcpy(cynagora->socketspec, socketspec); /* record type and weakly create cache */ - cache_create(&cynagora->cache, CACHESIZE(cache_size)); + cache_create(&cynagora->cache, CACHESIZE(cache_size)); /* ignore errors */ cynagora->type = type; - cynagora->socketspec = socketspec; cynagora->async.controlcb = NULL; cynagora->async.closure = 0; cynagora->async.requests = NULL; @@ -457,6 +626,7 @@ error: return rc; } +/* see cynagora.h */ void cynagora_disconnect( cynagora_t *cynagora @@ -464,8 +634,9 @@ cynagora_disconnect( disconnection(cynagora); } +/* see cynagora.h */ void -cynagora_close( +cynagora_destroy( cynagora_t *cynagora ) { cynagora_async_setup(cynagora, NULL, NULL); @@ -475,85 +646,33 @@ cynagora_close( free(cynagora); } +/* see cynagora.h */ int -cynagora_enter( - cynagora_t *cynagora +cynagora_cache_resize( + cynagora_t *cynagora, + uint32_t size ) { - int rc; - - if (cynagora->type != cynagora_Admin) - return -EPERM; - if (cynagora->async.requests != NULL) - return -EINPROGRESS; - rc = ensure_opened(cynagora); - if (rc < 0) - return rc; - - rc = putxkv(cynagora, _enter_, 0, 0, 0); - if (rc >= 0) - rc = wait_done(cynagora); - return rc; + return cache_resize(&cynagora->cache, CACHESIZE(size)); } -int -cynagora_leave( - cynagora_t *cynagora, - bool commit +/* see cynagora.h */ +void +cynagora_cache_clear( + cynagora_t *cynagora ) { - int rc; - - if (cynagora->type != cynagora_Admin) - return -EPERM; - if (cynagora->async.requests != NULL) - return -EINPROGRESS; - rc = ensure_opened(cynagora); - if (rc < 0) - return rc; - - rc = putxkv(cynagora, _leave_, commit ? _commit_ : 0/*default: rollback*/, 0, 0); - if (rc >= 0) - rc = wait_done(cynagora); - return rc; + cache_clear(cynagora->cache, 0); } -static +/* see cynagora.h */ int -check_or_test( +cynagora_cache_check( cynagora_t *cynagora, - const cynagora_key_t *key, - const char *action + const cynagora_key_t *key ) { - int rc; - time_t expire; - - if (cynagora->async.requests != NULL) - return -EINPROGRESS; - rc = ensure_opened(cynagora); - if (rc < 0) - return rc; - - /* ensure there is no clear cache pending */ - flushr(cynagora); - - /* check cache item */ - rc = cache_search(cynagora->cache, key); - if (rc >= 0) - return rc; - - /* send the request */ - rc = putxkv(cynagora, action, 0, key, 0); - if (rc >= 0) { - /* get the response */ - rc = wait_pending_reply(cynagora); - if (rc >= 0) { - rc = status_check(cynagora, &expire); - if (cynagora->cache && rc >= 0) - cache_put(cynagora->cache, key, rc, expire); - } - } - return rc; + return cache_search(cynagora->cache, key); } +/* see cynagora.h */ int cynagora_check( cynagora_t *cynagora, @@ -562,6 +681,7 @@ cynagora_check( return check_or_test(cynagora, key, _check_); } +/* see cynagora.h */ int cynagora_test( cynagora_t *cynagora, @@ -570,37 +690,12 @@ cynagora_test( return check_or_test(cynagora, key, _test_); } -int -cynagora_set( - cynagora_t *cynagora, - const cynagora_key_t *key, - const cynagora_value_t *value -) { - int rc; - - if (cynagora->type != cynagora_Admin) - return -EPERM; - if (cynagora->async.requests != NULL) - return -EINPROGRESS; - rc = ensure_opened(cynagora); - if (rc < 0) - return rc; - - rc = putxkv(cynagora, _set_, 0, key, value); - if (rc >= 0) - rc = wait_done(cynagora); - return rc; -} - +/* see cynagora.h */ int cynagora_get( cynagora_t *cynagora, const cynagora_key_t *key, - void (*callback)( - void *closure, - const cynagora_key_t *key, - const cynagora_value_t *value - ), + cynagora_get_cb_t *callback, void *closure ) { int rc; @@ -633,6 +728,7 @@ cynagora_get( return rc; } +/* see cynagora.h */ int cynagora_log( cynagora_t *cynagora, @@ -657,11 +753,10 @@ cynagora_log( return rc < 0 ? rc : cynagora->reply.count < 2 ? 0 : !strcmp(cynagora->reply.fields[1], _on_); } - +/* see cynagora.h */ int -cynagora_drop( - cynagora_t *cynagora, - const cynagora_key_t *key +cynagora_enter( + cynagora_t *cynagora ) { int rc; @@ -673,44 +768,84 @@ cynagora_drop( if (rc < 0) return rc; - rc = putxkv(cynagora, _drop_, 0, key, 0); + rc = putxkv(cynagora, _enter_, 0, 0, 0); if (rc >= 0) rc = wait_done(cynagora); return rc; } -/************************************************************************************/ - +/* see cynagora.h */ int -cynagora_cache_resize( +cynagora_leave( cynagora_t *cynagora, - uint32_t size + int commit ) { - return cache_resize(&cynagora->cache, CACHESIZE(size)); + int rc; + + if (cynagora->type != cynagora_Admin) + return -EPERM; + if (cynagora->async.requests != NULL) + return -ECANCELED; + rc = ensure_opened(cynagora); + if (rc < 0) + return rc; + + rc = putxkv(cynagora, _leave_, commit ? _commit_ : 0/*default: rollback*/, 0, 0); + if (rc >= 0) + rc = wait_done(cynagora); + return rc; } -void -cynagora_cache_clear( - cynagora_t *cynagora +/* see cynagora.h */ +int +cynagora_set( + cynagora_t *cynagora, + const cynagora_key_t *key, + const cynagora_value_t *value ) { - cache_clear(cynagora->cache, 0); + int rc; + + if (cynagora->type != cynagora_Admin) + return -EPERM; + if (cynagora->async.requests != NULL) + return -ECANCELED; + rc = ensure_opened(cynagora); + if (rc < 0) + return rc; + + rc = putxkv(cynagora, _set_, 0, key, value); + if (rc >= 0) + rc = wait_done(cynagora); + return rc; } +/* see cynagora.h */ int -cynagora_cache_check( +cynagora_drop( cynagora_t *cynagora, const cynagora_key_t *key ) { - return cache_search(cynagora->cache, key); -} + int rc; + if (cynagora->type != cynagora_Admin) + return -EPERM; + if (cynagora->async.requests != NULL) + return -ECANCELED; + rc = ensure_opened(cynagora); + if (rc < 0) + return rc; -/************************************************************************************/ + rc = putxkv(cynagora, _drop_, 0, key, 0); + if (rc >= 0) + rc = wait_done(cynagora); + return rc; +} +/* see cynagora.h */ int cynagora_async_setup( cynagora_t *cynagora, - cynagora_async_ctl_t controlcb, + cynagora_async_ctl_cb_t *controlcb, void *closure ) { asreq_t *ar; @@ -721,15 +856,19 @@ cynagora_async_setup( ar->callback(ar->closure, -ECANCELED); free(ar); } + /* remove existing polling */ async(cynagora, EPOLL_CTL_DEL, 0); + /* records new data */ cynagora->async.controlcb = controlcb; cynagora->async.closure = closure; + /* record to polling */ return async(cynagora, EPOLL_CTL_ADD, EPOLLIN); } +/* see cynagora.h */ int cynagora_async_process( cynagora_t *cynagora @@ -776,14 +915,13 @@ cynagora_async_process( } } +/* see cynagora.h */ int cynagora_async_check( cynagora_t *cynagora, const cynagora_key_t *key, int simple, - void (*callback)( - void *closure, - int status), + cynagora_async_check_cb_t *callback, void *closure ) { int rc; diff --git a/src/cynagora.h b/src/cynagora.h index 3b856da..d17476c 100644 --- a/src/cynagora.h +++ b/src/cynagora.h @@ -26,93 +26,240 @@ typedef enum cynagora_type cynagora_type_t; typedef struct cynagora_key cynagora_key_t; typedef struct cynagora_value cynagora_value_t; +/** + * type of the client interface + */ enum cynagora_type { + /** type for checking permissions */ cynagora_Check, + /** type for adminstration */ cynagora_Admin, + /** type for handling agents */ cynagora_Agent }; +/** + * Describes a query key + */ struct cynagora_key { + /** client item of the key */ const char *client; + /** session item of the key */ const char *session; + /** user item of the key */ const char *user; + /** permission item of the key */ const char *permission; }; +/** + * Describes the value associated to a key + */ struct cynagora_value { + /** the associated value */ const char *value; + /** the expiration */ time_t expire; }; +/** + * Callback for enumeration of items (admin) + * The function is called for each entry matching the selection key + * with the key and the associated value for that entry + * + * @see cynagora_get + */ +typedef void cynagora_get_cb_t( + void *closure, + const cynagora_key_t *key, + const cynagora_value_t *value); + +/** + * Callback for receiving asynchronousely the replies to the queries + * Receives: + * closure: the closure given to cynagora_async_check + * status: 0 if forbidden + * 1 if granted + * -ECANCELED if cancelled + */ +typedef void cynagora_async_check_cb_t( + void *closure, + int status); + +/** + * Callback for managing the connection in an external loop + * + * That callback receives epoll_ctl operations, a file descriptor number and + * a mask of expected events. + * + * @see epoll_ctl + */ +typedef int cynagora_async_ctl_cb_t( + void *closure, + int op, + int fd, + uint32_t events); + +/** + * Create a client to the permission server cynagora + * The client is created but not connected. The connection is made on need. + * + * @param cynagora pointer to the handle of the opened client + * @param type type of the client to open + * @param cache_size requested cache size + * @param socketspec specification of the socket to connect to or NULL for + * using the default + * + * @return 0 in case of success and in that case *cynagora is filled + * a negative -errno value and *cynara is set to NULL + * + * @see cynagora_destroy, cynagora_cache_resize + */ extern int -cynagora_open( +cynagora_create( cynagora_t **cynagora, cynagora_type_t type, uint32_t cache_size, const char *socketspec ); +/** + * Destroy the client handler and release its memory + * + * @param cynagora the client handler to close + * + * @see cynagora_create + */ extern void -cynagora_disconnect( +cynagora_destroy( cynagora_t *cynagora ); +/** + * Ask the client to disconnect from the server. + * The client will reconnect if needed. + * + * @param cynagora the client handler + */ extern void -cynagora_close( +cynagora_disconnect( cynagora_t *cynagora ); +/** + * Clear the cache + * + * @param cynagora the client handler + * + * @see cynagora_cache_resize + */ extern -int -cynagora_enter( +void +cynagora_cache_clear( cynagora_t *cynagora ); +/** + * Resize the cache + * + * @param cynagora the client handler + * @param size new expected cache + * + * @return 0 on success or -ENOMEM if out of memory + * + * @see cynagora_cache_clear, cynagora_create + */ extern int -cynagora_leave( +cynagora_cache_resize( cynagora_t *cynagora, - bool commit + uint32_t size ); +/** + * Check a key against the cache + * + * @param cynagora the client handler + * @param key the key to check + * + * @return 0 if forbidden, 1 if authorize, -ENOENT if cache miss + * + * @see cynagora_check + */ extern int -cynagora_check( +cynagora_cache_check( cynagora_t *cynagora, const cynagora_key_t *key ); +/** + * Query the permission database for the key (synchronous) + * Allows agent resolution. + * + * @param cynagora the client handler + * @param key the key to check + * + * @return 0 if permission forbidden, 1 if permission granted + * or if error a negative -errno value + * + * @see cynagora_test, cynagora_cache_check + */ extern int -cynagora_test( +cynagora_check( cynagora_t *cynagora, const cynagora_key_t *key ); +/** + * Query the permission database for the key (synchronous) + * Avoids agent resolution. + * + * @param cynagora the client handler + * @param key + * @return + * + * @see cynagora_check + */ extern int -cynagora_set( +cynagora_test( cynagora_t *cynagora, - const cynagora_key_t *key, - const cynagora_value_t *value + const cynagora_key_t *key ); +/** + * List any value of the permission database that matches the key (admin, synchronous) + * + * @param cynagora the client handler + * @param key the selection key + * @param callback the callback for receiving items + * @param closure closure of the callback + * + * @return 0 in case of success or a negative -errno value + */ extern int cynagora_get( cynagora_t *cynagora, const cynagora_key_t *key, - void (*callback)( - void *closure, - const cynagora_key_t *key, - const cynagora_value_t *value - ), + cynagora_get_cb_t *callback, void *closure ); +/** + * Query or set the logging of requests (admin, synchronous) + * + * @param cynagora the client handler + * @param on should set on + * @param off should set off + * + * @return 0 if not logging, 1 if logging or a negative -errno value + */ extern int cynagora_log( @@ -121,61 +268,132 @@ cynagora_log( int off ); +/** + * Enter cancelable section for modifying database (admin, synchronous) + * + * @param cynagora the handler of the client + * + * @return 0 in case of success or a negative -errno value + * -EPERM if not a admin client + * -EINPROGRESS if already entered + * + * @see cynagora_leave, cynagora_set, cynagora_drop + */ extern int -cynagora_drop( - cynagora_t *cynagora, - const cynagora_key_t *key +cynagora_enter( + cynagora_t *cynagora ); +/** + * Leave cancelable section for modifying database (admin, synchronous) + * + * @param cynagora the handler of the client + * @param commit if zero, cancel the modifications in progress otherwise if + * not zero, commit the changes + * + * @return 0 in case of success or a negative -errno value + * -EPERM if not a admin client + * -ECANCELED if not entered + * + * @see cynagora_enter, cynagora_set, cynagora_drop + */ extern -void -cynagora_cache_clear( - cynagora_t *cynagora +int +cynagora_leave( + cynagora_t *cynagora, + int commit ); +/** + * Set a rule (either create or change it) (admin, synchronous) + * This call requires to have entered the cancelable section. + * + * @param cynagora the handler of the client + * @param key the key to set + * @param value the value to set to the key + * + * @return 0 in case of success or a negative -errno value + * -EPERM if not a admin client + * -ECANCELED if not entered + * + * @see cynagora_enter, cynagora_leave, cynagora_drop + */ extern int -cynagora_cache_check( +cynagora_set( cynagora_t *cynagora, - const cynagora_key_t *key + const cynagora_key_t *key, + const cynagora_value_t *value ); +/** + * Drop items matching the key selector (admin, synchronous) + * This call requires to have entered the cancelable section. + * + * @param cynagora the handler of the client + * @param key Filter of the keys to drop + * + * @return 0 in case of success or a negative -errno value + * -EPERM if not a admin client + * -ECANCELED if not entered + * + * @see cynagora_enter, cynagora_leave, cynagora_set + */ extern int -cynagora_cache_resize( +cynagora_drop( cynagora_t *cynagora, - uint32_t size + const cynagora_key_t *key ); -typedef int (*cynagora_async_ctl_t)( - void *closure, - int op, - int fd, - uint32_t events); - +/** + * Set the asynchronous control function + * + * @param cynagora the handler of the client + * @param controlcb + * @param closure + * + * @return 0 in case of success or a negative -errno value + */ extern int cynagora_async_setup( cynagora_t *cynagora, - cynagora_async_ctl_t controlcb, + cynagora_async_ctl_cb_t *controlcb, void *closure ); +/** + * Process the inputs of the client + * + * @param cynagora the handler of the client + * + * @return 0 in case of success or a negative -errno value + */ extern int cynagora_async_process( cynagora_t *cynagora ); +/** + * Check the key asynchronousely (async) + * + * @param cynagora the handler of the client + * @param key the key to query + * @param simple if zero allows agent process else if not 0 forbids it + * @param callback the callback to call on reply + * @param closure a closure for the callback + * + * @return 0 in case of success or a negative -errno value + */ extern int cynagora_async_check( cynagora_t *cynagora, const cynagora_key_t *key, int simple, - void (*callback)( - void *closure, - int status), + cynagora_async_check_cb_t *callback, void *closure ); diff --git a/src/main-cynagoradm.c b/src/main-cynagoradm.c index 216dd7e..7b657c0 100644 --- a/src/main-cynagoradm.c +++ b/src/main-cynagoradm.c @@ -764,7 +764,7 @@ int main(int ac, char **av) /* initialize server */ signal(SIGPIPE, SIG_IGN); /* avoid SIGPIPE! */ - rc = cynagora_open(&cynagora, cynagora_Admin, cachesize, socket); + rc = cynagora_create(&cynagora, cynagora_Admin, cachesize, socket); if (rc < 0) { fprintf(stderr, "initialization failed: %s\n", strerror(-rc)); return 1; -- cgit 1.2.3-korg