summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose Bollo <jose.bollo@iot.bzh>2019-10-14 12:25:35 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2019-10-15 22:06:24 +0200
commitf53a76ce91ab83c7345a104b57f148738101c58d (patch)
tree90fae562195d8030903828e0319693fbe880dfd8
parentb5fdd44014207c619b937e5c202ba27e77a2593c (diff)
Transmit expiration in relative values
This will at the end allow unsynchronized clients to query the server efficiently. Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/cache.c8
-rw-r--r--src/cache.h3
-rw-r--r--src/cyn-server.c19
-rw-r--r--src/cynagora.c14
-rw-r--r--src/dbinit.c2
-rw-r--r--src/expire.c13
-rw-r--r--src/expire.h6
-rw-r--r--src/main-cynagoracli.c4
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;