From f53a76ce91ab83c7345a104b57f148738101c58d Mon Sep 17 00:00:00 2001 From: Jose Bollo Date: Mon, 14 Oct 2019 12:25:35 +0200 Subject: Transmit expiration in relative values This will at the end allow unsynchronized clients to query the server efficiently. Signed-off-by: Jose Bollo --- src/CMakeLists.txt | 1 + src/cache.c | 8 ++++---- src/cache.h | 3 ++- src/cyn-server.c | 19 ++++++++----------- src/cynagora.c | 14 +++++++++----- src/dbinit.c | 2 +- src/expire.c | 13 ++++++++----- src/expire.h | 6 +++++- src/main-cynagoracli.c | 4 ++-- 9 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bde17f6..300fd3d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,6 +39,7 @@ set(SERVER_SOURCES ) set(LIBCLI_SOURCES + expire.c cache.c prot.c cynagora.c diff --git a/src/cache.c b/src/cache.c index d14e877..c3f83cc 100644 --- a/src/cache.c +++ b/src/cache.c @@ -274,11 +274,11 @@ search( /* see cache.h */ int -cache_put( - cache_t *cache, +cache_put(cache_t *cache, const cynagora_key_t *key, int value, - time_t expire + time_t expire, + bool absolute ) { uint16_t length; item_t *item; @@ -308,7 +308,7 @@ cache_put( stpcpy(1 + stpcpy(1 + stpcpy(1 + stpcpy(item->strings, key->client), key->session), key->user), key->permission); cache->used += (uint32_t)size; } - item->expire = expire; + item->expire = !expire ? 0 : absolute ? expire : expire + time(NULL); item->hit = 255; item->value = (int8_t)value; return 0; diff --git a/src/cache.h b/src/cache.h index 713efa4..a23a7aa 100644 --- a/src/cache.h +++ b/src/cache.h @@ -53,7 +53,8 @@ cache_put( cache_t *cache, const cynagora_key_t *key, int value, - time_t expire + time_t expire, + bool absolute ); /** diff --git a/src/cyn-server.c b/src/cyn-server.c index 8339d09..be72e92 100644 --- a/src/cyn-server.c +++ b/src/cyn-server.c @@ -43,6 +43,7 @@ #include "cyn-server.h" #include "socket.h" #include "pollitem.h" +#include "expire.h" #define MAX_PUTX_ITEMS 15 @@ -283,8 +284,9 @@ exp2check( if (expire < 0) return "-"; /* no cache */ - /* TODO: check size */ - snprintf(buffer, bufsz, "%lld", (long long)expire); + if (exp2txt(expire, true, buffer, bufsz) >= bufsz) + return "-"; /* no cache */ + return buffer; } @@ -299,15 +301,9 @@ exp2get( if (!expire) return NULL; - if (expire < 0) { - expire = -(expire + 1); - if (!expire) - return "-"; - *buffer++ = '-'; - bufsz--; - } + if (exp2txt(expire, true, buffer, bufsz) >= bufsz) + return "-"; /* no cache */ - snprintf(buffer, bufsz, "%lld", (long long)expire); return buffer; } @@ -507,7 +503,8 @@ onrequest( if (count == 6) value.expire = 0; else - value.expire = strtoll(args[6], NULL, 10); + txt2exp(args[6], &value.expire, true); + key.client = args[1]; key.session = args[2]; key.user = args[3]; diff --git a/src/cynagora.c b/src/cynagora.c index 4434d89..96c6466 100644 --- a/src/cynagora.c +++ b/src/cynagora.c @@ -41,6 +41,7 @@ #include "cynagora.h" #include "cache.h" #include "socket.h" +#include "expire.h" #define MIN_CACHE_SIZE 400 #define CACHESIZE(x) ((x) >= MIN_CACHE_SIZE ? (x) : (x) ? MIN_CACHE_SIZE : 0) @@ -185,7 +186,7 @@ putxkv( if (!optval->expire) text[0] = 0; else - snprintf(text, sizeof text, "%lld", (long long)optval->expire); + exp2txt(optval->expire, true, text, sizeof text); rc = prot_put_field(prot, text); } } @@ -368,7 +369,7 @@ status_check( else if (cynagora->reply.fields[1][0] == '-') *expire = -1; else - *expire = strtoll(cynagora->reply.fields[1], NULL, 10); + txt2exp(cynagora->reply.fields[1], expire, true); return rc; } @@ -556,7 +557,7 @@ check_or_test( if (rc >= 0) { rc = status_check(cynagora, &expire); if (rc >= 0 && action == _check_) - cache_put(cynagora->cache, key, rc, expire); + cache_put(cynagora->cache, key, rc, expire, true); } } return rc; @@ -721,7 +722,10 @@ cynagora_get( k.user = cynagora->reply.fields[3]; k.permission = cynagora->reply.fields[4]; v.value = cynagora->reply.fields[5]; - v.expire = rc == 6 ? 0 : (time_t)strtoll(cynagora->reply.fields[6], NULL, 10); + if (rc == 6) + v.expire = 0; + else if (!txt2exp(cynagora->reply.fields[6], &v.expire, true)) + v.expire = -1; callback(closure, &k, &v); rc = wait_reply(cynagora, true); } @@ -910,7 +914,7 @@ cynagora_async_process( key.session = &key.client[1 + strlen(key.client)]; key.user = &key.session[1 + strlen(key.session)]; key.permission = &key.user[1 + strlen(key.user)]; - cache_put(cynagora->cache, &key, rc, expire); + cache_put(cynagora->cache, &key, rc, expire, true); } ar->callback(ar->closure, rc); free(ar); diff --git a/src/dbinit.c b/src/dbinit.c index 67738f4..9afac71 100644 --- a/src/dbinit.c +++ b/src/dbinit.c @@ -96,7 +96,7 @@ int dbinit_add_file(const char *path) key.user = item[2]; key.permission = item[3]; value.value = item[4]; - if (!txt2exp(item[5], &value.expire)) { + if (!txt2exp(item[5], &value.expire, true)) { fprintf(stderr, "bad expiration %s (%s:%d)\n", item[5], path, lino); rc = -EINVAL; goto error2; diff --git a/src/expire.c b/src/expire.c index 2207d3c..a90a8de 100644 --- a/src/expire.c +++ b/src/expire.c @@ -99,7 +99,7 @@ static bool parse_time_spec(const char *txt, time_t *time_out) /* see expire.h */ -bool txt2exp(const char *txt, time_t *time_out) +bool txt2exp(const char *txt, time_t *time_out, bool absolute) { bool nocache; time_t r; @@ -115,8 +115,10 @@ bool txt2exp(const char *txt, time_t *time_out) /* parse */ if (!parse_time_spec(txt, &r)) return false; - /* relative time */ - r = pt_add(r, time(NULL)); + if (absolute) { + /* absolute time */ + r = pt_add(r, time(NULL)); + } } *time_out = nocache ? -(r + 1) : r; @@ -124,7 +126,7 @@ bool txt2exp(const char *txt, time_t *time_out) } /* see expire.h */ -size_t exp2txt(time_t expire, char *buffer, size_t buflen) +size_t exp2txt(time_t expire, bool absolute, char *buffer, size_t buflen) { char b[100]; size_t l, n; @@ -139,7 +141,8 @@ size_t exp2txt(time_t expire, char *buffer, size_t buflen) if (!n) strncpy(b, "forever", sizeof b); } else { - expire -= time(NULL); + if (absolute) + expire -= time(NULL); #define ADD(C,U) \ if (expire >= U) { \ n += (size_t)snprintf(&b[n], sizeof b - (size_t)n, "%lld" #C, (long long)(expire / U)); \ diff --git a/src/expire.h b/src/expire.h index 4d996f8..ccb54f8 100644 --- a/src/expire.h +++ b/src/expire.h @@ -35,19 +35,22 @@ * * @param txt the text to convert * @param time_out where to store the result + * @param absolute return the expiration in epoch * @return true if valid false otherwise */ extern bool txt2exp( const char *txt, - time_t *time_out + time_t *time_out, + bool absolute ); /** * Converts the expiration in to its relative string representation * * @param expire the epiration to convert + * @param expire is expiration absolute? * @param buffer the buffer where to store the converted string * @param buflen length of the buffer * @return the length of the resulting string, can be greater than buflen but @@ -57,6 +60,7 @@ extern size_t exp2txt( time_t expire, + bool absolute, char *buffer, size_t buflen ); diff --git a/src/main-cynagoracli.c b/src/main-cynagoracli.c index af84760..fd92fad 100644 --- a/src/main-cynagoracli.c +++ b/src/main-cynagoracli.c @@ -336,7 +336,7 @@ int get_csupve(int ac, char **av, int *used, const char *def) value.value = n > 5 ? av[5] : "no"; if (n <= 6) value.expire = 0; - else if (!txt2exp(av[6], &value.expire)) + else if (!txt2exp(av[6], &value.expire, true)) return -EINVAL; return key.client && key.session && key.user && key.permission && value.value ? 0 : -EINVAL; @@ -416,7 +416,7 @@ void listcb(void *closure, const cynagora_key_t *k, const cynagora_value_t *v) size_t s, as; int i; - exp2txt(v->expire, buffer, sizeof buffer); + exp2txt(v->expire, true, buffer, sizeof buffer); items[0] = k->client; items[1] = k->session; items[2] = k->user; -- cgit 1.2.3-korg