diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cache.c | 2 | ||||
-rw-r--r-- | src/cynagora-protocol.txt | 122 | ||||
-rw-r--r-- | src/cynagora.c | 39 | ||||
-rw-r--r-- | src/cynagora.h | 18 | ||||
-rw-r--r-- | src/main-cynagora-admin.c | 31 |
5 files changed, 149 insertions, 63 deletions
diff --git a/src/cache.c b/src/cache.c index c3f83cc..c19cc66 100644 --- a/src/cache.c +++ b/src/cache.c @@ -338,7 +338,7 @@ cache_clear( cache_t *cache, uint32_t cacheid ) { - if (cache && (!cacheid || cache->cacheid != cacheid)) { + if (cache && (cache->cacheid != cacheid || !cacheid)) { cache->cacheid = cacheid; cache->used = 0; } diff --git a/src/cynagora-protocol.txt b/src/cynagora-protocol.txt index 10668ca..2afd43b 100644 --- a/src/cynagora-protocol.txt +++ b/src/cynagora-protocol.txt @@ -1,15 +1,47 @@ -protocol -======== +The cynagora protocol +===================== -hello: +Introduction +------------ - c->s cynagora 1 - s->c yes 1 CACHEID +### Notations: -invalidate cache: + - c->s: from client to cynagora server + - s->c: from cynagora server to client + - EXPIRE: if missing, means forever + if positive, a number of second since EPOCH, invalid after it + - CACHEID: a 32 bits positive integer + - ASKID: a 32 bits positive integer - s->c clear CACHEID +Messages +-------- + +### hello + +synopsis: + + c->s cynagora 1 + s->c yes 1 CACHEID + +The client present itself with the version of the protocol it expects to +speak (today version 1 only). The server answer yes with the acknoledged +version it will use and the CACHEID that identify the cache (see note on +CACHEID) + +If hello is used, it must be the first message. If it is not used, the +protocol implicitely switch to the default version. + + +### invalidate cache + +synopsis: + + s->c clear CACHEID + +The server ask the client to clear its cache and to start the cache whose +identifier is CACHEID + ### test a permission synopsis: @@ -27,6 +59,7 @@ synopsis: s->c (yes|no) [EXPIRE] + ### enter critical (admin) synopsis: @@ -45,52 +78,59 @@ synopsis: synopsis: - c->s drop CLIENT SESSION USER PERMISSION - s->c done|error ... + c->s drop CLIENT SESSION USER PERMISSION + s->c done|error ... -set (admin): +### set (admin) - c->s set CLIENT SESSION USER PERMISSION VALUE [EXPIRE] - s->c done|error ... +synopsis: -list permissions (admin): + c->s set CLIENT SESSION USER PERMISSION VALUE [EXPIRE] + s->c done|error ... + +### list permissions (admin): + +synopsis: - c->s get CLIENT SESSION USER PERMISSION - s->c item CLIENT SESSION USER PERMISSION VALUE [EXPIRE] - s->c ... - s->c done + c->s get CLIENT SESSION USER PERMISSION + s->c item CLIENT SESSION USER PERMISSION VALUE [EXPIRE] + s->c ... + s->c done -logging set/get (admin) +### logging set/get (admin) - c->s log [on|off] - s->c done (on|off) +synopsis: -register agent (agent): + c->s log [on|off] + s->c done (on|off) - s->c ask ASKID NAME VALUE CLIENT SESSION USER PERMISSION - c->s reply ASKID (yes|no|error) [EXPIRE] +### register agent (agent) -ask agent (agent): +synopsis: - s->c ask NAME VALUE CLIENT SESSION USER PERMISSION - c->s done | ([yes|no] [always|session|one-time|EXPIRE]) + c->s agent NAME + s->c done|error ... + +### ask agent (agent): + +synopsis: + + s->c ask ASKID NAME VALUE CLIENT SESSION USER PERMISSION + c->s reply ASKID ([yes|no] [always|session|one-time|EXPIRE]) + +### sub queries (agent): + +synopsis: + c->s sub ASKID (test|check) CLIENT SESSION USER PERMISSION + s->c reply ASKID (done|yes|no) [EXPIRE] ----------------------------------------------------------- - c->s c(heck) CLIENT SESSION USER PERMISSION - c->s d(rop) CLIENT SESSION USER PERMISSION - c->s e(nter) - c->s g(et) CLIENT SESSION USER PERMISSION - c->s l(eave) [commit|rollback] - c->s r(cyn) - c->s s(et) CLIENT SESSION USER PERMISSION VALUE EXPIRE - c->s t(est) CLIENT SESSION USER PERMISSION +Notes +----- - s->c clear - s->c done - s->c done [CLIENT SESSION USER PERMISSION VALUE] - s->c done|error ... - s->c item CLIENT SESSION USER PERMISSION VALUE EXPIRE - s->c done VALUE EXPIRE +### CACHEID +The cacheid identify the current cache. It changes each time the database +changes. After a disconnection, clients can use HELLO to check whether their +version of cache is still valid. This is implemented by the default C library. diff --git a/src/cynagora.c b/src/cynagora.c index b4bd7e9..2928779 100644 --- a/src/cynagora.c +++ b/src/cynagora.c @@ -613,9 +613,10 @@ ensure_opened( /** * Check or test synchronously * - * @param cynagora - * @param key - * @param action + * @param cynagora the handler of the client + * @param key the key to test/check + * @param force if not set forbids cache use + * @param action test or check * * @return 0 in case of success or a negative -errno value */ @@ -624,6 +625,7 @@ int check_or_test( cynagora_t *cynagora, const cynagora_key_t *key, + int force, const char *action ) { int rc; @@ -642,9 +644,11 @@ check_or_test( flushr(cynagora); /* check cache item */ - rc = cache_search(cynagora->cache, key); - if (rc >= 0) - return rc; + if (!force) { + rc = cache_search(cynagora->cache, key); + if (rc >= 0) + return rc; + } /* send the request */ rc = putxkv(cynagora, action, 0, key, 0); @@ -851,18 +855,20 @@ cynagora_cache_check( int cynagora_check( cynagora_t *cynagora, - const cynagora_key_t *key + const cynagora_key_t *key, + int force ) { - return check_or_test(cynagora, key, _check_); + return check_or_test(cynagora, key, force, _check_); } /* see cynagora.h */ int cynagora_test( cynagora_t *cynagora, - const cynagora_key_t *key + const cynagora_key_t *key, + int force ) { - return check_or_test(cynagora, key, _test_); + return check_or_test(cynagora, key, force, _test_); } /* see cynagora.h */ @@ -870,6 +876,7 @@ int cynagora_async_check( cynagora_t *cynagora, const cynagora_key_t *key, + int force, int simple, cynagora_async_check_cb_t *callback, void *closure @@ -882,6 +889,18 @@ cynagora_async_check( if (rc < 0) return rc; + /* ensure there is no clear cache pending */ + flushr(cynagora); + + /* check cache item */ + if (!force) { + rc = cache_search(cynagora->cache, key); + if (rc >= 0) { + callback(closure, rc); + return 0; + } + } + /* allocate */ ar = malloc(sizeof *ar + strlen(key->client) + strlen(key->session) + strlen(key->user) + strlen(key->permission) + 4); if (ar == NULL) diff --git a/src/cynagora.h b/src/cynagora.h index aff1720..d5dc80f 100644 --- a/src/cynagora.h +++ b/src/cynagora.h @@ -20,7 +20,9 @@ /* IMPLEMENTATION OF CLIENT PART OF CYNAGORA-PROTOCOL */ /******************************************************************************/ /******************************************************************************/ - +/** + * @file cynagora.h + */ /******************************************************************************/ /* COMMON PART - types and functions common to check/admin/agent clients */ /******************************************************************************/ @@ -216,6 +218,7 @@ cynagora_cache_check( * * @param cynagora the client handler * @param key the key to check + * @param force if not set forbids cache use * * @return 0 if permission forbidden, 1 if permission granted * or if error a negative -errno value @@ -226,7 +229,8 @@ extern int cynagora_check( cynagora_t *cynagora, - const cynagora_key_t *key + const cynagora_key_t *key, + int force ); /** @@ -235,7 +239,10 @@ cynagora_check( * * @param cynagora the client handler * @param key - * @return + * @param force if not set forbids cache use + * + * @return 0 if permission forbidden, 1 if permission granted + * or if error a negative -errno value * * @see cynagora_check */ @@ -243,7 +250,8 @@ extern int cynagora_test( cynagora_t *cynagora, - const cynagora_key_t *key + const cynagora_key_t *key, + int force ); /** @@ -251,6 +259,7 @@ cynagora_test( * * @param cynagora the handler of the client * @param key the key to query + * @param force if not set forbids cache use * @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 @@ -262,6 +271,7 @@ int cynagora_async_check( cynagora_t *cynagora, const cynagora_key_t *key, + int force, int simple, cynagora_async_check_cb_t *callback, void *closure diff --git a/src/main-cynagora-admin.c b/src/main-cynagora-admin.c index c748b4b..210084c 100644 --- a/src/main-cynagora-admin.c +++ b/src/main-cynagora-admin.c @@ -91,7 +91,7 @@ static const char help__text[] = "\n" - "Commands are: list, set, drop, check, test, cache, clear, quit, log, help\n" + "Commands are: list, set, drop, acheck, check, atest, test, cache, clear, quit, log, help\n" "Type 'help command' to get help on the command\n" "Type 'help expiration' to get help on expirations\n" "\n" @@ -518,19 +518,17 @@ int do_drop(int ac, char **av) return uc; } -int do_check(int ac, char **av, int (*f)(cynagora_t*,const cynagora_key_t*)) +int do_check(int ac, char **av, int (*f)(cynagora_t*,const cynagora_key_t*,int)) { int uc, rc; rc = get_csup(ac, av, &uc, NULL); if (rc == 0) { - rc = f(cynagora, &key); + rc = f(cynagora, &key, 0); if (rc > 0) fprintf(stdout, "allowed\n"); else if (rc == 0) fprintf(stdout, "denied\n"); - else if (rc == -ENOENT && f == cynagora_cache_check) - fprintf(stdout, "not in cache!\n"); else if (rc == -EEXIST) fprintf(stderr, "denied but an entry exist\n"); else @@ -539,6 +537,25 @@ int do_check(int ac, char **av, int (*f)(cynagora_t*,const cynagora_key_t*)) return uc; } +int do_cache_check(int ac, char **av) +{ + int uc, rc; + + rc = get_csup(ac, av, &uc, NULL); + if (rc == 0) { + rc = cynagora_cache_check(cynagora, &key); + if (rc > 0) + fprintf(stdout, "allowed\n"); + else if (rc == 0) + fprintf(stdout, "denied\n"); + else if (rc == -ENOENT) + fprintf(stdout, "not in cache!\n"); + else + fprintf(stderr, "error %s\n", strerror(-rc)); + } + return uc; +} + void acheck_cb(void *closure, int status) { if (status > 0) @@ -557,7 +574,7 @@ int do_acheck(int ac, char **av, bool simple) rc = get_csup(ac, av, &uc, NULL); if (rc == 0) { pending++; - rc = cynagora_async_check(cynagora, &key, simple, acheck_cb, NULL); + rc = cynagora_async_check(cynagora, &key, 0, simple, acheck_cb, NULL); if (rc < 0) { fprintf(stderr, "error %s\n", strerror(-rc)); pending--; @@ -650,7 +667,7 @@ int do_any(int ac, char **av) return do_acheck(ac, av, 1); if (!strcmp(av[0], "cache")) - return do_check(ac, av, cynagora_cache_check); + return do_cache_check(ac, av); if (!strcmp(av[0], "log")) return do_log(ac, av); |