diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-06-12 14:48:00 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-06-12 14:48:00 +0200 |
commit | f6a87ee66310529edf76c0fab76cdc7cd2aac216 (patch) | |
tree | e3697e5f549bd6d0adbeede9935b67313d4907cf /src | |
parent | ae8b5cb2eac770be0d18b7d46c238bf865e34023 (diff) |
ensure datacache does not return expired records, fixig pq behavior with respect to FOREVER absolute time
Diffstat (limited to 'src')
-rw-r--r-- | src/datacache/plugin_datacache_heap.c | 3 | ||||
-rw-r--r-- | src/datacache/plugin_datacache_postgres.c | 33 | ||||
-rw-r--r-- | src/datacache/test_datacache.c | 73 | ||||
-rw-r--r-- | src/datacache/test_datacache_quota.c | 31 | ||||
-rw-r--r-- | src/pq/pq_query_helper.c | 58 | ||||
-rw-r--r-- | src/pq/pq_result_helper.c | 85 |
6 files changed, 242 insertions, 41 deletions
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c index 2a08fc81b2..494d1ae17c 100644 --- a/src/datacache/plugin_datacache_heap.c +++ b/src/datacache/plugin_datacache_heap.c @@ -314,6 +314,9 @@ get_cb (void *cls, if ( (get_ctx->type != val->type) && (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) ) return GNUNET_OK; + if (0 == + GNUNET_TIME_absolute_get_remaining (val->discard_time).rel_value_us) + return GNUNET_OK; if (NULL != get_ctx->iter) ret = get_ctx->iter (get_ctx->iter_cls, key, diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index 6eeeb5873d..ea87acc1f0 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c @@ -82,12 +82,12 @@ init_connection (struct Plugin *plugin) struct GNUNET_PQ_PreparedStatement ps[] = { GNUNET_PQ_make_prepare ("getkt", "SELECT discard_time,type,value,path FROM gn011dc " - "WHERE key=$1 AND type=$2", - 2), + "WHERE key=$1 AND type=$2 AND discard_time >= $3", + 3), GNUNET_PQ_make_prepare ("getk", "SELECT discard_time,type,value,path FROM gn011dc " - "WHERE key=$1", - 1), + "WHERE key=$1 AND discard_time >= $2", + 2), GNUNET_PQ_make_prepare ("getex", "SELECT length(value) AS len,oid,key FROM gn011dc" " WHERE discard_time < $1" @@ -97,18 +97,15 @@ init_connection (struct Plugin *plugin) "SELECT length(value) AS len,oid,key FROM gn011dc" " ORDER BY prox ASC, discard_time ASC LIMIT 1", 0), - GNUNET_PQ_make_prepare ("getp", - "SELECT length(value) AS len,oid,key FROM gn011dc " - "ORDER BY discard_time ASC LIMIT 1", - 0), GNUNET_PQ_make_prepare ("get_random", - "SELECT discard_time,type,value,path,key FROM gn011dc " - "ORDER BY key ASC LIMIT 1 OFFSET $1", - 1), + "SELECT discard_time,type,value,path,key FROM gn011dc" + " WHERE discard_time >= $1" + " ORDER BY key ASC LIMIT 1 OFFSET $2", + 2), GNUNET_PQ_make_prepare ("get_closest", "SELECT discard_time,type,value,path,key FROM gn011dc " - "WHERE key>=$1 ORDER BY key ASC LIMIT $2", - 1), + "WHERE key>=$1 AND discard_time >= $2 ORDER BY key ASC LIMIT $3", + 3), GNUNET_PQ_make_prepare ("delrow", "DELETE FROM gn011dc WHERE oid=$1", 1), @@ -313,18 +310,22 @@ postgres_plugin_get (void *cls, { struct Plugin *plugin = cls; uint32_t type32 = (uint32_t) type; + struct GNUNET_TIME_Absolute now; struct GNUNET_PQ_QueryParam paramk[] = { GNUNET_PQ_query_param_auto_from_type (key), + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_QueryParam paramkt[] = { GNUNET_PQ_query_param_auto_from_type (key), GNUNET_PQ_query_param_uint32 (&type32), + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus res; struct HandleResultContext hr_ctx; + now = GNUNET_TIME_absolute_get (); hr_ctx.iter = iter; hr_ctx.iter_cls = iter_cls; hr_ctx.key = key; @@ -427,6 +428,7 @@ postgres_plugin_get_random (void *cls, { struct Plugin *plugin = cls; uint32_t off; + struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute expiration_time; size_t data_size; void *data; @@ -436,6 +438,7 @@ postgres_plugin_get_random (void *cls, uint32_t type; enum GNUNET_DB_QueryStatus res; struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_uint32 (&off), GNUNET_PQ_query_param_end }; @@ -459,6 +462,7 @@ postgres_plugin_get_random (void *cls, return 0; if (NULL == iter) return 1; + now = GNUNET_TIME_absolute_get (); off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, plugin->num_items); res = GNUNET_PQ_eval_prepared_singleton_select (plugin->dbh, @@ -620,8 +624,10 @@ postgres_plugin_get_closest (void *cls, { struct Plugin *plugin = cls; uint32_t num_results32 = (uint32_t) num_results; + struct GNUNET_TIME_Absolute now; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (key), + GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_uint32 (&num_results32), GNUNET_PQ_query_param_end }; @@ -630,6 +636,7 @@ postgres_plugin_get_closest (void *cls, erc.iter = iter; erc.iter_cls = iter_cls; + now = GNUNET_TIME_absolute_get (); res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh, "get_closest", params, diff --git a/src/datacache/test_datacache.c b/src/datacache/test_datacache.c index 12edb62f80..50e45012df 100644 --- a/src/datacache/test_datacache.c +++ b/src/datacache/test_datacache.c @@ -44,6 +44,11 @@ checkIt (void *cls, unsigned int path_len, const struct GNUNET_PeerIdentity *path) { + (void) key; + (void) type; + (void) exp; + (void) path_len; + (void) path; if (size != sizeof (struct GNUNET_HashCode)) { GNUNET_break (0); @@ -59,17 +64,22 @@ checkIt (void *cls, static void -run (void *cls, char *const *args, const char *cfgfile, +run (void *cls, + char *const *args, + const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_DATACACHE_Handle *h; struct GNUNET_HashCode k; struct GNUNET_HashCode n; struct GNUNET_TIME_Absolute exp; - unsigned int i; + (void) cls; + (void) args; + (void) cfgfile; ok = 0; - h = GNUNET_DATACACHE_create (cfg, "testcache"); + h = GNUNET_DATACACHE_create (cfg, + "testcache"); if (h == NULL) { FPRINTF (stderr, @@ -81,7 +91,7 @@ run (void *cls, char *const *args, const char *cfgfile, exp = GNUNET_TIME_absolute_get (); exp.abs_value_us += 5 * 60 * 1000 * 1000LL; memset (&k, 0, sizeof (struct GNUNET_HashCode)); - for (i = 0; i < 100; i++) + for (unsigned int i = 0; i < 100; i++) { GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); ASSERT (GNUNET_OK == @@ -93,26 +103,43 @@ run (void *cls, char *const *args, const char *cfgfile, 0, NULL)); k = n; } - memset (&k, 0, sizeof (struct GNUNET_HashCode)); - for (i = 0; i < 100; i++) + memset (&k, + 0, + sizeof (struct GNUNET_HashCode)); + for (unsigned int i = 0; i < 100; i++) { - GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); - ASSERT (1 == GNUNET_DATACACHE_get (h, &k, 1 + i % 16, &checkIt, &n)); + GNUNET_CRYPTO_hash (&k, + sizeof (struct GNUNET_HashCode), + &n); + ASSERT (1 == GNUNET_DATACACHE_get (h, + &k, + 1 + i % 16, + &checkIt, + &n)); k = n; } - memset (&k, 42, sizeof (struct GNUNET_HashCode)); - GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n); + memset (&k, + 42, + sizeof (struct GNUNET_HashCode)); + GNUNET_CRYPTO_hash (&k, + sizeof (struct GNUNET_HashCode), + &n); ASSERT (GNUNET_OK == GNUNET_DATACACHE_put (h, &k, GNUNET_YES, sizeof (struct GNUNET_HashCode), - (const char *) &n, 792, + (const char *) &n, + 792, GNUNET_TIME_UNIT_FOREVER_ABS, - 0, NULL)); - ASSERT (0 != GNUNET_DATACACHE_get (h, &k, 792, &checkIt, &n)); - + 0, + NULL)); + ASSERT (0 != GNUNET_DATACACHE_get (h, + &k, + 792, + &checkIt, + &n)); GNUNET_DATACACHE_destroy (h); ASSERT (ok == 0); return; @@ -137,16 +164,26 @@ main (int argc, char *argv[]) GNUNET_GETOPT_OPTION_END }; + (void) argc; GNUNET_log_setup ("test-datacache", "WARNING", NULL); plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); - GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_datacache_data_%s.conf", + GNUNET_snprintf (cfg_name, + sizeof (cfg_name), + "test_datacache_data_%s.conf", plugin_name); - GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, - "test-datacache", "nohelp", options, &run, NULL); + GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, + xargv, + "test-datacache", + "nohelp", + options, + &run, + NULL); if ( (0 != ok) && (77 != ok) ) - FPRINTF (stderr, "Missed some testcases: %d\n", ok); + FPRINTF (stderr, + "Missed some testcases: %d\n", + ok); return ok; } diff --git a/src/datacache/test_datacache_quota.c b/src/datacache/test_datacache_quota.c index 3d02a7244b..21e3736086 100644 --- a/src/datacache/test_datacache_quota.c +++ b/src/datacache/test_datacache_quota.c @@ -41,7 +41,9 @@ static const char *plugin_name; * some of the data from the last iteration is still there. */ static void -run (void *cls, char *const *args, const char *cfgfile, +run (void *cls, + char *const *args, + const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_DATACACHE_Handle *h; @@ -50,8 +52,12 @@ run (void *cls, char *const *args, const char *cfgfile, char buf[3200]; struct GNUNET_TIME_Absolute exp; + (void) cls; + (void) args; + (void) cfgfile; ok = 0; - h = GNUNET_DATACACHE_create (cfg, "testcache"); + h = GNUNET_DATACACHE_create (cfg, + "testcache"); if (h == NULL) { @@ -112,7 +118,8 @@ FAILURE: int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { char cfg_name[128]; char *const xargv[] = { @@ -125,17 +132,27 @@ main (int argc, char *argv[]) GNUNET_GETOPT_OPTION_END }; + (void) argc; GNUNET_log_setup ("test-datacache-quota", "WARNING", NULL); plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); - GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_datacache_data_%s.conf", + GNUNET_snprintf (cfg_name, + sizeof (cfg_name), + "test_datacache_data_%s.conf", plugin_name); - GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv, - "test-datacache-quota", "nohelp", options, &run, NULL); + GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, + xargv, + "test-datacache-quota", + "nohelp", + options, + &run, + NULL); if (0 != ok) - FPRINTF (stderr, "Missed some testcases: %d\n", ok); + FPRINTF (stderr, + "Missed some testcases: %d\n", + ok); return ok; } diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 799f82ebe8..98f697b5d6 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -50,6 +50,8 @@ qconv_fixed (void *cls, void *scratch[], unsigned int scratch_length) { + (void) scratch; + (void) scratch_length; GNUNET_break (NULL == cls); if (1 != param_length) return -1; @@ -117,6 +119,8 @@ qconv_uint16 (void *cls, const uint16_t *u_hbo = data; uint16_t *u_nbo; + (void) scratch; + (void) scratch_length; GNUNET_break (NULL == cls); if (1 != param_length) return -1; @@ -172,6 +176,8 @@ qconv_uint32 (void *cls, const uint32_t *u_hbo = data; uint32_t *u_nbo; + (void) scratch; + (void) scratch_length; GNUNET_break (NULL == cls); if (1 != param_length) return -1; @@ -227,6 +233,8 @@ qconv_uint64 (void *cls, const uint64_t *u_hbo = data; uint64_t *u_nbo; + (void) scratch; + (void) scratch_length; GNUNET_break (NULL == cls); if (1 != param_length) return -1; @@ -371,6 +379,51 @@ GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) /** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument + * @param data_len number of bytes in @a data (if applicable) + * @param[out] param_values SQL data to set + * @param[out] param_lengths SQL length data to set + * @param[out] param_formats SQL format data to set + * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays + * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc() + * @param scratch_length number of entries left in @a scratch + * @return -1 on error, number of offsets used in @a scratch otherwise + */ +static int +qconv_abs_time (void *cls, + const void *data, + size_t data_len, + void *param_values[], + int param_lengths[], + int param_formats[], + unsigned int param_length, + void *scratch[], + unsigned int scratch_length) +{ + const struct GNUNET_TIME_Absolute *u = data; + struct GNUNET_TIME_Absolute abs; + uint64_t *u_nbo; + + GNUNET_break (NULL == cls); + if (1 != param_length) + return -1; + abs = *u; + if (abs.abs_value_us > INT64_MAX) + abs.abs_value_us = INT64_MAX; + u_nbo = GNUNET_new (uint64_t); + scratch[0] = u_nbo; + *u_nbo = GNUNET_htonll (abs.abs_value_us); + param_values[0] = (void *) u_nbo; + param_lengths[0] = sizeof (uint64_t); + param_formats[0] = 1; + return 1; +} + + +/** * Generate query parameter for an absolute time value. * The database must store a 64-bit integer. * @@ -380,7 +433,10 @@ GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) { - return GNUNET_PQ_query_param_uint64 (&x->abs_value_us); + struct GNUNET_PQ_QueryParam res = + { &qconv_abs_time, NULL, x, sizeof (*x), 1 }; + + return res; } diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 3805b8a8d9..dc1a1554f3 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -38,6 +38,7 @@ clean_varsize_blob (void *cls, { void **dst = rd; + (void) cls; if (NULL != *dst) { GNUNET_free (*dst); @@ -72,6 +73,7 @@ extract_varsize_blob (void *cls, void *idst; int fnum; + (void) cls; *dst_size = 0; *((void **) dst) = NULL; @@ -154,6 +156,7 @@ extract_fixed_blob (void *cls, const char *res; int fnum; + (void) cls; fnum = PQfnumber (result, fname); if (fnum < 0) @@ -237,6 +240,7 @@ extract_rsa_public_key (void *cls, const char *res; int fnum; + (void) cls; *pk = NULL; fnum = PQfnumber (result, fname); @@ -284,6 +288,7 @@ clean_rsa_public_key (void *cls, { struct GNUNET_CRYPTO_RsaPublicKey **pk = rd; + (void) cls; if (NULL != *pk) { GNUNET_CRYPTO_rsa_public_key_free (*pk); @@ -338,6 +343,7 @@ extract_rsa_signature (void *cls, const char *res; int fnum; + (void) cls; *sig = NULL; fnum = PQfnumber (result, fname); @@ -385,6 +391,7 @@ clean_rsa_signature (void *cls, { struct GNUNET_CRYPTO_RsaSignature **sig = rd; + (void) cls; if (NULL != *sig) { GNUNET_CRYPTO_rsa_signature_free (*sig); @@ -439,6 +446,7 @@ extract_string (void *cls, const char *res; int fnum; + (void) cls; *str = NULL; fnum = PQfnumber (result, fname); @@ -486,6 +494,7 @@ clean_string (void *cls, { char **str = rd; + (void) cls; if (NULL != *str) { GNUNET_free (*str); @@ -515,6 +524,71 @@ GNUNET_PQ_result_spec_string (const char *name, /** + * Extract data from a Postgres database @a result at row @a row. + * + * @param cls closure + * @param result where to extract data from + * @param int row to extract data from + * @param fname name (or prefix) of the fields to extract from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + * #GNUNET_YES if all results could be extracted + * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static int +extract_abs_time (void *cls, + PGresult *result, + int row, + const char *fname, + size_t *dst_size, + void *dst) +{ + struct GNUNET_TIME_Absolute *udst = dst; + const int64_t *res; + int fnum; + + (void) cls; + fnum = PQfnumber (result, + fname); + if (fnum < 0) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (PQgetisnull (result, + row, + fnum)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + GNUNET_assert (NULL != dst); + if (sizeof (struct GNUNET_TIME_Absolute) != *dst_size) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (sizeof (int64_t) != + PQgetlength (result, + row, + fnum)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + res = (int64_t *) PQgetvalue (result, + row, + fnum); + if (INT64_MAX == *res) + *udst = GNUNET_TIME_UNIT_FOREVER_ABS; + else + udst->abs_value_us = GNUNET_ntohll ((uint64_t) *res); + return GNUNET_OK; +} + + +/** * Absolute time expected. * * @param name name of the field in the table @@ -525,8 +599,12 @@ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_absolute_time (const char *name, struct GNUNET_TIME_Absolute *at) { - return GNUNET_PQ_result_spec_uint64 (name, - &at->abs_value_us); + struct GNUNET_PQ_ResultSpec res = + { &extract_abs_time, + NULL, + NULL, + (void *) at, sizeof (*at), (name), NULL }; + return res; } @@ -572,6 +650,7 @@ extract_uint16 (void *cls, const uint16_t *res; int fnum; + (void) cls; fnum = PQfnumber (result, fname); if (fnum < 0) @@ -653,6 +732,7 @@ extract_uint32 (void *cls, const uint32_t *res; int fnum; + (void) cls; fnum = PQfnumber (result, fname); if (fnum < 0) @@ -734,6 +814,7 @@ extract_uint64 (void *cls, const uint64_t *res; int fnum; + (void) cls; fnum = PQfnumber (result, fname); if (fnum < 0) |