aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrothoff <grothoff@140774ce-b5e7-0310-ab8b-a85725594a96>2012-11-13 20:05:40 +0000
committergrothoff <grothoff@140774ce-b5e7-0310-ab8b-a85725594a96>2012-11-13 20:05:40 +0000
commit9e60dddece6bf27697e97363294b821b516e4795 (patch)
treedf5c5a0d972f35d741b51c3a3fc8d2298ac8b4fd
parent200fc7133325e844371909fce57cd34b39ff23d9 (diff)
changing datacache API to separate put-paths from data (so that plugins can test for duplicates), removing support for MySQL
git-svn-id: https://gnunet.org/svn/gnunet@24938 140774ce-b5e7-0310-ab8b-a85725594a96
-rw-r--r--src/datacache/Makefile.am48
-rw-r--r--src/datacache/datacache.c24
-rw-r--r--src/datacache/perf_datacache.c10
-rw-r--r--src/datacache/perf_datacache_data_heap.conf5
-rw-r--r--src/datacache/perf_datacache_data_mysql.conf13
-rw-r--r--src/datacache/plugin_datacache_heap.c73
-rw-r--r--src/datacache/plugin_datacache_mysql.c474
-rw-r--r--src/datacache/plugin_datacache_postgres.c69
-rw-r--r--src/datacache/plugin_datacache_sqlite.c53
-rw-r--r--src/datacache/plugin_datacache_template.c12
-rw-r--r--src/datacache/test_datacache.c16
-rw-r--r--src/datacache/test_datacache_data_heap.conf4
-rw-r--r--src/datacache/test_datacache_data_mysql.conf13
-rw-r--r--src/datacache/test_datacache_quota.c2
-rw-r--r--src/dht/gnunet-service-dht_datacache.c80
-rw-r--r--src/include/gnunet_datacache_lib.h20
-rw-r--r--src/include/gnunet_datacache_plugin.h12
17 files changed, 253 insertions, 675 deletions
diff --git a/src/datacache/Makefile.am b/src/datacache/Makefile.am
index 99e333dc95..c6c27b3275 100644
--- a/src/datacache/Makefile.am
+++ b/src/datacache/Makefile.am
@@ -19,9 +19,6 @@ endif
if HAVE_SQLITE
SQLITE_PLUGIN = libgnunet_plugin_datacache_sqlite.la
endif
-if HAVE_MYSQL
- MYSQL_PLUGIN = libgnunet_plugin_datacache_mysql.la
-endif
if HAVE_POSTGRES
POSTGRES_PLUGIN = libgnunet_plugin_datacache_postgres.la
endif
@@ -42,7 +39,6 @@ libgnunetdatacache_la_LDFLAGS = \
plugin_LTLIBRARIES = \
$(SQLITE_PLUGIN) \
- $(MYSQL_PLUGIN) \
$(POSTGRES_PLUGIN) \
libgnunet_plugin_datacache_heap.la \
libgnunet_plugin_datacache_template.la
@@ -66,18 +62,6 @@ libgnunet_plugin_datacache_heap_la_LIBADD = \
libgnunet_plugin_datacache_heap_la_LDFLAGS = \
$(GN_PLUGIN_LDFLAGS)
-libgnunet_plugin_datacache_mysql_la_SOURCES = \
- plugin_datacache_mysql.c
-libgnunet_plugin_datacache_mysql_la_LIBADD = \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/mysql/libgnunetmysql.la \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient
-libgnunet_plugin_datacache_mysql_la_CPPFLAGS = \
- $(MYSQL_CPPFLAGS)
-libgnunet_plugin_datacache_mysql_la_LDFLAGS = \
- $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient
-
libgnunet_plugin_datacache_postgres_la_SOURCES = \
plugin_datacache_postgres.c
libgnunet_plugin_datacache_postgres_la_LIBADD = \
@@ -110,16 +94,14 @@ SQLITE_TESTS = \
$(SQLITE_BENCHMARKS)
endif
-if HAVE_MYSQL
if HAVE_BENCHMARKS
- MYSQL_BENCHMARKS = \
- perf_datacache_mysql
-endif
-MYSQL_TESTS = \
- test_datacache_mysql \
- test_datacache_quota_mysql \
- $(MYSQL_BENCHMARKS)
+ HEAP_BENCHMARKS = \
+ perf_datacache_heap
endif
+HEAP_TESTS = \
+ test_datacache_heap \
+ test_datacache_quota_heap \
+ $(HEAP_BENCHMARKS)
if HAVE_POSTGRES
if HAVE_BENCHMARKS
@@ -134,7 +116,7 @@ endif
check_PROGRAMS = \
$(SQLITE_TESTS) \
- $(MYSQL_TESTS) \
+ $(HEAP_TESTS) \
$(POSTGRES_TESTS)
if ENABLE_TEST_RUN
@@ -162,23 +144,23 @@ perf_datacache_sqlite_LDADD = \
$(top_builddir)/src/datacache/libgnunetdatacache.la \
$(top_builddir)/src/util/libgnunetutil.la
-test_datacache_mysql_SOURCES = \
+test_datacache_heap_SOURCES = \
test_datacache.c
-test_datacache_mysql_LDADD = \
+test_datacache_heap_LDADD = \
$(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/datacache/libgnunetdatacache.la \
$(top_builddir)/src/util/libgnunetutil.la
-test_datacache_quota_mysql_SOURCES = \
+test_datacache_quota_heap_SOURCES = \
test_datacache_quota.c
-test_datacache_quota_mysql_LDADD = \
+test_datacache_quota_heap_LDADD = \
$(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/datacache/libgnunetdatacache.la \
$(top_builddir)/src/util/libgnunetutil.la
-perf_datacache_mysql_SOURCES = \
+perf_datacache_heap_SOURCES = \
perf_datacache.c
-perf_datacache_mysql_LDADD = \
+perf_datacache_heap_LDADD = \
$(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/datacache/libgnunetdatacache.la \
$(top_builddir)/src/util/libgnunetutil.la
@@ -207,7 +189,7 @@ perf_datacache_postgres_LDADD = \
EXTRA_DIST = \
test_datacache_data_sqlite.conf \
perf_datacache_data_sqlite.conf \
- test_datacache_data_mysql.conf \
- perf_datacache_data_mysql.conf \
+ test_datacache_data_heap.conf \
+ perf_datacache_data_heap.conf \
test_datacache_data_postgres.conf \
perf_datacache_data_postgres.conf
diff --git a/src/datacache/datacache.c b/src/datacache/datacache.c
index e5dbfac161..0cd6f884b3 100644
--- a/src/datacache/datacache.c
+++ b/src/datacache/datacache.c
@@ -233,22 +233,34 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h)
* @param data data to store
* @param type type of the value
* @param discard_time when to discard the value in any case
- * @return GNUNET_OK on success, GNUNET_SYSERR on error (full, etc.)
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error, GNUNET_NO if duplicate
*/
int
GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
const struct GNUNET_HashCode * key, size_t size,
const char *data, enum GNUNET_BLOCK_Type type,
- struct GNUNET_TIME_Absolute discard_time)
+ struct GNUNET_TIME_Absolute discard_time,
+ unsigned int path_info_len,
+ const struct GNUNET_PeerIdentity *path_info)
{
- uint32_t used;
+ ssize_t used;
- used = h->api->put (h->api->cls, key, size, data, type, discard_time);
- if (0 == used)
+ used = h->api->put (h->api->cls, key,
+ size, data,
+ type, discard_time,
+ path_info_len, path_info);
+ if (-1 == used)
{
- /* error or duplicate */
+ GNUNET_break (0);
return GNUNET_SYSERR;
}
+ if (0 == used)
+ {
+ /* duplicate */
+ return GNUNET_NO;
+ }
LOG (GNUNET_ERROR_TYPE_DEBUG, "Stored data under key `%s' in cache\n",
GNUNET_h2s (key));
GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), size,
diff --git a/src/datacache/perf_datacache.c b/src/datacache/perf_datacache.c
index 10289ec68b..e30ae869d3 100644
--- a/src/datacache/perf_datacache.c
+++ b/src/datacache/perf_datacache.c
@@ -44,9 +44,12 @@ static const char *plugin_name;
static int
-checkIt (void *cls, struct GNUNET_TIME_Absolute exp,
+checkIt (void *cls,
const struct GNUNET_HashCode * key, size_t size, const char *data,
- enum GNUNET_BLOCK_Type type)
+ enum GNUNET_BLOCK_Type type,
+ struct GNUNET_TIME_Absolute exp,
+ unsigned int path_len,
+ const struct GNUNET_PeerIdentity *path)
{
if ((size == sizeof (struct GNUNET_HashCode)) && (0 == memcmp (data, cls, size)))
found++;
@@ -84,7 +87,8 @@ run (void *cls, char *const *args, const char *cfgfile,
GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
ASSERT (GNUNET_OK ==
GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode),
- (const char *) &n, 1 + i % 16, exp));
+ (const char *) &n, 1 + i % 16, exp,
+ 0, NULL));
k = n;
}
FPRINTF (stderr, "%s", "\n");
diff --git a/src/datacache/perf_datacache_data_heap.conf b/src/datacache/perf_datacache_data_heap.conf
new file mode 100644
index 0000000000..3680c020b9
--- /dev/null
+++ b/src/datacache/perf_datacache_data_heap.conf
@@ -0,0 +1,5 @@
+[perfcache]
+QUOTA = 500 KB
+DATABASE = heap
+
+
diff --git a/src/datacache/perf_datacache_data_mysql.conf b/src/datacache/perf_datacache_data_mysql.conf
deleted file mode 100644
index 1760f7d08e..0000000000
--- a/src/datacache/perf_datacache_data_mysql.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-[perfcache]
-QUOTA = 500 KB
-DATABASE = mysql
-
-[datacache-mysql]
-DATABASE = gnunetcheck
-# CONFIG = ~/.my.cnf
-# USER =
-# PASSWORD =
-# HOST =
-# PORT =
-
-
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c
index 2f55bcf533..8bc9b29f65 100644
--- a/src/datacache/plugin_datacache_heap.c
+++ b/src/datacache/plugin_datacache_heap.c
@@ -32,6 +32,7 @@
#define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache-heap", op, fn)
+
/**
* Context for all functions in this plugin.
*/
@@ -76,11 +77,21 @@ struct Value
struct GNUNET_CONTAINER_HeapNode *hn;
/**
+ * Path information.
+ */
+ struct GNUNET_PeerIdentity *path_info;
+
+ /**
* Payload (actual payload follows this struct)
*/
size_t size;
/**
+ * Number of entries in 'path_info'.
+ */
+ unsigned int path_info_len;
+
+ /**
* Type of the block.
*/
enum GNUNET_BLOCK_Type type;
@@ -88,6 +99,9 @@ struct Value
};
+#define OVERHEAD (sizeof (struct Value) + 64)
+
+
/**
* Closure for 'put_cb'.
*/
@@ -109,6 +123,11 @@ struct PutContext
struct GNUNET_CONTAINER_Heap *heap;
/**
+ * Path information.
+ */
+ const struct GNUNET_PeerIdentity *path_info;
+
+ /**
* Number of bytes in 'data'.
*/
size_t size;
@@ -119,6 +138,11 @@ struct PutContext
enum GNUNET_BLOCK_Type type;
/**
+ * Number of entries in 'path_info'.
+ */
+ unsigned int path_info_len;
+
+ /**
* Value to set to GNUNET_YES if an equivalent block was found.
*/
int found;
@@ -149,13 +173,20 @@ put_cb (void *cls,
put_ctx->found = GNUNET_YES;
val->discard_time = GNUNET_TIME_absolute_max (val->discard_time,
put_ctx->discard_time);
+ /* replace old path with new path */
+ GNUNET_array_grow (val->path_info,
+ val->path_info_len,
+ put_ctx->path_info_len);
+ memcpy (val->path_info,
+ put_ctx->path_info,
+ put_ctx->path_info_len * sizeof (struct GNUNET_PeerIdentity));
GNUNET_CONTAINER_heap_update_cost (put_ctx->heap,
val->hn,
val->discard_time.abs_value);
return GNUNET_NO;
}
if (val->type == put_ctx->type)
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Got another value for key %s and type %d (size %u vs %u)\n",
GNUNET_h2s (key),
val->type,
@@ -174,12 +205,16 @@ put_cb (void *cls,
* @param data data to store
* @param type type of the value
* @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @return 0 if duplicate, -1 on error, number of bytes used otherwise
*/
-static size_t
+static ssize_t
heap_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
- const char *data, enum GNUNET_BLOCK_Type type,
- struct GNUNET_TIME_Absolute discard_time)
+ const char *data, enum GNUNET_BLOCK_Type type,
+ struct GNUNET_TIME_Absolute discard_time,
+ unsigned int path_info_len,
+ const struct GNUNET_PeerIdentity *path_info)
{
struct Plugin *plugin = cls;
struct Value *val;
@@ -189,6 +224,8 @@ heap_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
put_ctx.heap = plugin->heap;
put_ctx.data = data;
put_ctx.size = size;
+ put_ctx.path_info = path_info;
+ put_ctx.path_info_len = path_info_len;
put_ctx.discard_time = discard_time;
put_ctx.type = type;
GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map,
@@ -203,6 +240,11 @@ heap_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
val->type = type;
val->discard_time = discard_time;
val->size = size;
+ GNUNET_array_grow (val->path_info,
+ val->path_info_len,
+ path_info_len);
+ memcpy (val->path_info, path_info,
+ path_info_len * sizeof (struct GNUNET_PeerIdentity));
(void) GNUNET_CONTAINER_multihashmap_put (plugin->map,
&val->key,
val,
@@ -210,7 +252,7 @@ heap_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
val->hn = GNUNET_CONTAINER_heap_insert (plugin->heap,
val,
val->discard_time.abs_value);
- return size;
+ return size + OVERHEAD;
}
@@ -263,13 +305,17 @@ get_cb (void *cls,
if ( (get_ctx->type != val->type) &&
(GNUNET_BLOCK_TYPE_ANY != get_ctx->type) )
return GNUNET_OK;
- ret = get_ctx->iter (get_ctx->iter_cls,
+ if (NULL != get_ctx->iter)
+ ret = get_ctx->iter (get_ctx->iter_cls,
+ key,
+ val->size,
+ (const char *) &val[1],
+ val->type,
val->discard_time,
- key,
- val->size,
- (const char *) &val[1],
- val->type);
-
+ val->path_info_len,
+ val->path_info);
+ else
+ ret = GNUNET_YES;
get_ctx->cnt++;
return ret;
}
@@ -328,7 +374,8 @@ heap_plugin_del (void *cls)
val));
plugin->env->delete_notify (plugin->env->cls,
&val->key,
- val->size);
+ val->size + OVERHEAD);
+ GNUNET_free_non_null (val->path_info);
GNUNET_free (val);
return GNUNET_OK;
}
diff --git a/src/datacache/plugin_datacache_mysql.c b/src/datacache/plugin_datacache_mysql.c
deleted file mode 100644
index 1457eddfb7..0000000000
--- a/src/datacache/plugin_datacache_mysql.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- This file is part of GNUnet
- (C) 2006, 2009, 2010 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file datacache/plugin_datacache_mysql.c
- * @brief mysql for an implementation of a database backend for the datacache
- * @author Christian Grothoff
- *
- * SETUP INSTRUCTIONS:
- *
- * 1) Access mysql as root,
- * <pre>
- *
- * $ mysql -u root -p
- *
- * </pre>
- * and do the following. [You should replace $USER with the username
- * that will be running the gnunetd process].
- * @verbatim
- CREATE DATABASE gnunet;
- GRANT select,insert,update,delete,create,alter,drop,create temporary tables
- ON gnunet.* TO $USER@localhost;
- SET PASSWORD FOR $USER@localhost=PASSWORD('$the_password_you_like');
- FLUSH PRIVILEGES;
- @endverbatim
- * 2) In the $HOME directory of $USER, create a ".my.cnf" file
- * with the following lines
- * @verbatim
- [client]
- user=$USER
- password=$the_password_you_like
- @endverbatim
- *
- * Thats it -- now you can configure your datastores in GNUnet to
- * use MySQL. Note that .my.cnf file is a security risk unless its on
- * a safe partition etc. The $HOME/.my.cnf can of course be a symbolic
- * link. Even greater security risk can be achieved by setting no
- * password for $USER. Luckily $USER has only priviledges to mess
- * up GNUnet's tables, nothing else (unless you give him more,
- * of course).<p>
- *
- * 3) Still, perhaps you should briefly try if the DB connection
- * works. First, login as $USER. Then use,
- * @verbatim
- $ mysql -u $USER -p $the_password_you_like
- mysql> use gnunet;
- @endverbatim
- *
- * If you get the message &quot;Database changed&quot; it probably works.
- *
- * [If you get &quot;ERROR 2002: Can't connect to local MySQL server
- * through socket '/tmp/mysql.sock' (2)&quot; it may be resolvable by
- * &quot;ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock&quot;
- * so there may be some additional trouble depending on your mysql setup.]
- *
- * PROBLEMS?
- *
- * If you have problems related to the mysql module, your best
- * friend is probably the mysql manual. The first thing to check
- * is that mysql is basically operational, that you can connect
- * to it, create tables, issue queries etc.
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_datacache_plugin.h"
-#include "gnunet_mysql_lib.h"
-#include <mysql/mysql.h>
-
-
-/**
- * Estimate of the per-entry overhead (including indices).
- */
-#define OVERHEAD ((4*2+4*2+8*2+8*2+sizeof(struct GNUNET_HashCode)*5+8))
-
-/**
- * Die with an error message that indicates
- * a failure of the command 'cmd' with the message given
- * by strerror(errno).
- */
-#define DIE_MYSQL(cmd, dbh) do { GNUNET_log(GNUNET_ERROR_TYPE__ERROR, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); GNUNET_abort(); } while(0);
-
-/**
- * Log an error message at log-level 'level' that indicates
- * a failure of the command 'cmd' on file 'filename'
- * with the message given by strerror(errno).
- */
-#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } while(0);
-
-
-/**
- * Context for all functions in this plugin.
- */
-struct Plugin
-{
- /**
- * Our execution environment.
- */
- struct GNUNET_DATACACHE_PluginEnvironment *env;
-
- /**
- * Handle to the mysql database.
- */
- struct GNUNET_MYSQL_Context *mc;
-
-#define SELECT_VALUE_STMT "SELECT value,expire FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?"
- struct GNUNET_MYSQL_StatementHandle *select_value;
-
-#define COUNT_VALUE_STMT "SELECT count(*) FROM gn080dstore FORCE INDEX (hashidx) WHERE hash=? AND type=? AND expire >= ?"
- struct GNUNET_MYSQL_StatementHandle *count_value;
-
-#define SELECT_OLD_VALUE_STMT "SELECT hash, vhash, type, value FROM gn080dstore FORCE INDEX (expireidx) ORDER BY puttime ASC LIMIT 1"
- struct GNUNET_MYSQL_StatementHandle *select_old_value;
-
-#define DELETE_VALUE_STMT "DELETE FROM gn080dstore WHERE hash = ? AND vhash = ? AND type = ? AND value = ?"
- struct GNUNET_MYSQL_StatementHandle *delete_value;
-
-#define INSERT_VALUE_STMT "INSERT INTO gn080dstore (type, puttime, expire, hash, vhash, value) "\
- "VALUES (?, ?, ?, ?, ?, ?)"
- struct GNUNET_MYSQL_StatementHandle *insert_value;
-
-#define UPDATE_VALUE_STMT "UPDATE gn080dstore FORCE INDEX (allidx) SET puttime=?, expire=? "\
- "WHERE hash=? AND vhash=? AND type=?"
- struct GNUNET_MYSQL_StatementHandle *update_value;
-
-};
-
-
-/**
- * Create temporary table and prepare statements.
- *
- * @param plugin plugin context
- * @return GNUNET_OK on success
- */
-static int
-itable (struct Plugin *plugin)
-{
-#define MRUNS(a) (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, a) )
- if (MRUNS
- ("CREATE TEMPORARY TABLE gn080dstore ("
- " type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
- " puttime BIGINT UNSIGNED NOT NULL DEFAULT 0,"
- " expire BIGINT UNSIGNED NOT NULL DEFAULT 0,"
- " hash BINARY(64) NOT NULL DEFAULT '',"
- " vhash BINARY(64) NOT NULL DEFAULT '',"
- " value BLOB NOT NULL DEFAULT '',"
- " INDEX hashidx (hash(64),type,expire),"
- " INDEX allidx (hash(64),vhash(64),type)," " INDEX expireidx (puttime)"
- ") ENGINE=InnoDB") || MRUNS ("SET AUTOCOMMIT = 1"))
- return GNUNET_SYSERR;
-#undef MRUNS
-#define PINIT(a,b) (NULL == (a = GNUNET_MYSQL_statement_prepare (plugin->mc, b)))
- if (PINIT (plugin->select_value, SELECT_VALUE_STMT) ||
- PINIT (plugin->count_value, COUNT_VALUE_STMT) ||
- PINIT (plugin->select_old_value, SELECT_OLD_VALUE_STMT) ||
- PINIT (plugin->delete_value, DELETE_VALUE_STMT) ||
- PINIT (plugin->insert_value, INSERT_VALUE_STMT) ||
- PINIT (plugin->update_value, UPDATE_VALUE_STMT))
- return GNUNET_SYSERR;
-#undef PINIT
- return GNUNET_OK;
-}
-
-
-/**
- * Store an item in the datastore.
- *
- * @param cls closure (our "struct Plugin")
- * @param key key to store data under
- * @param size number of bytes in data
- * @param data data to store
- * @param type type of the value
- * @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
- */
-static size_t
-mysql_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
- const char *data, enum GNUNET_BLOCK_Type type,
- struct GNUNET_TIME_Absolute discard_time)
-{
- struct Plugin *plugin = cls;
- struct GNUNET_TIME_Absolute now;
- unsigned long k_length;
- unsigned long h_length;
- unsigned long v_length;
- unsigned long long v_now;
- unsigned long long v_discard_time;
- unsigned int v_type;
- struct GNUNET_HashCode vhash;
- int ret;
-
- if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
- return GNUNET_SYSERR;
- GNUNET_CRYPTO_hash (data, size, &vhash);
- now = GNUNET_TIME_absolute_get ();
-
- /* first try UPDATE */
- h_length = sizeof (struct GNUNET_HashCode);
- k_length = sizeof (struct GNUNET_HashCode);
- v_length = size;
- v_type = type;
- v_now = (unsigned long long) now.abs_value;
- v_discard_time = (unsigned long long) discard_time.abs_value;
- if (GNUNET_OK ==
- GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->update_value, NULL,
- MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
- MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES,
- MYSQL_TYPE_BLOB, key, sizeof (struct GNUNET_HashCode),
- &k_length, MYSQL_TYPE_BLOB, &vhash,
- sizeof (struct GNUNET_HashCode), &h_length,
- MYSQL_TYPE_LONG, &v_type, GNUNET_YES, -1))
- return GNUNET_OK;
-
- /* now try INSERT */
- h_length = sizeof (struct GNUNET_HashCode);
- k_length = sizeof (struct GNUNET_HashCode);
- v_length = size;
- if (GNUNET_OK !=
- (ret =
- GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->insert_value, NULL,
- MYSQL_TYPE_LONG, &type, GNUNET_YES,
- MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
- MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES,
- MYSQL_TYPE_BLOB, key, sizeof (struct GNUNET_HashCode),
- &k_length, MYSQL_TYPE_BLOB, &vhash,
- sizeof (struct GNUNET_HashCode), &h_length,
- MYSQL_TYPE_BLOB, data, (unsigned long) size,
- &v_length, -1)))
- {
- if (ret == GNUNET_SYSERR)
- itable (plugin);
- return GNUNET_SYSERR;
- }
- return size + OVERHEAD;
-}
-
-
-static int
-return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values)
-{
- return GNUNET_OK;
-}
-
-
-/**
- * Iterate over the results for a particular key
- * in the datastore.
- *
- * @param cls closure (our "struct Plugin")
- * @param key
- * @param type entries of which type are relevant?
- * @param iter maybe NULL (to just count)
- * @param iter_cls closure for iter
- * @return the number of results found
- */
-static unsigned int
-mysql_plugin_get (void *cls, const struct GNUNET_HashCode * key,
- enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter,
- void *iter_cls)
-{
- struct Plugin *plugin = cls;
- MYSQL_BIND rbind[3];
- unsigned long h_length;
- unsigned long v_length;
- unsigned long long v_expire;
- struct GNUNET_TIME_Absolute now;
- struct GNUNET_TIME_Absolute expire;
- unsigned int cnt;
- unsigned long long total;
- unsigned long long v_now;
- unsigned int off;
- unsigned int v_type;
- int ret;
- char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE];
-
- now = GNUNET_TIME_absolute_get ();
- h_length = sizeof (struct GNUNET_HashCode);
- v_length = sizeof (buffer);
- total = -1;
- memset (rbind, 0, sizeof (rbind));
- rbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
- rbind[0].buffer = &total;
- rbind[0].is_unsigned = GNUNET_YES;
- v_type = type;
- v_now = (unsigned long long) now.abs_value;
- if ((GNUNET_OK !=
- (ret =
- GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->count_value, 1, rbind,
- return_ok, NULL, MYSQL_TYPE_BLOB, key,
- sizeof (struct GNUNET_HashCode), &h_length,
- MYSQL_TYPE_LONG, &v_type, GNUNET_YES,
- MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
- -1))) || (-1 == total))
- {
- if (ret == GNUNET_SYSERR)
- itable (plugin);
- return GNUNET_SYSERR;
- }
- if ((iter == NULL) || (total == 0))
- return (int) total;
-
- off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total);
- cnt = 0;
- while (cnt < total)
- {
- memset (rbind, 0, sizeof (rbind));
- rbind[0].buffer_type = MYSQL_TYPE_BLOB;
- rbind[0].buffer_length = sizeof (buffer);
- rbind[0].length = &v_length;
- rbind[0].buffer = buffer;
- rbind[1].buffer_type = MYSQL_TYPE_LONGLONG;
- rbind[1].is_unsigned = 1;
- rbind[1].buffer = &v_expire;
- off = (off + 1) % total;
- if (GNUNET_OK !=
- (ret =
- GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->select_value, 2, rbind,
- return_ok, NULL, MYSQL_TYPE_BLOB, key,
- sizeof (struct GNUNET_HashCode), &h_length,
- MYSQL_TYPE_LONG, &v_type, GNUNET_YES,
- MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
- MYSQL_TYPE_LONG, &off, GNUNET_YES, -1)))
- {
- if (ret == GNUNET_SYSERR)
- itable (plugin);
- return GNUNET_SYSERR;
- }
- cnt++;
- expire.abs_value = v_expire;
- if (GNUNET_OK != iter (iter_cls, expire, key, v_length, buffer, type))
- break;
- }
- return cnt;
-}
-
-
-/**
- * Delete the entry with the lowest expiration value
- * from the datacache right now.
- *
- * @param cls closure (our "struct Plugin")
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-static int
-mysql_plugin_del (void *cls)
-{
- struct Plugin *plugin = cls;
-
- MYSQL_BIND rbind[5];
- unsigned int v_type;
- struct GNUNET_HashCode v_key;
- struct GNUNET_HashCode vhash;
- unsigned long k_length;
- unsigned long h_length;
- unsigned long v_length;
- int ret;
- char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE];
-
- k_length = sizeof (struct GNUNET_HashCode);
- h_length = sizeof (struct GNUNET_HashCode);
- v_length = sizeof (buffer);
- memset (rbind, 0, sizeof (rbind));
- rbind[0].buffer_type = MYSQL_TYPE_BLOB;
- rbind[0].buffer_length = sizeof (struct GNUNET_HashCode);
- rbind[0].length = &k_length;
- rbind[0].buffer = &v_key;
- rbind[1].buffer_type = MYSQL_TYPE_BLOB;
- rbind[1].buffer_length = sizeof (struct GNUNET_HashCode);
- rbind[1].length = &h_length;
- rbind[1].buffer = &vhash;
- rbind[2].buffer_type = MYSQL_TYPE_LONG;
- rbind[2].is_unsigned = 1;
- rbind[2].buffer = &v_type;
- rbind[3].buffer_type = MYSQL_TYPE_BLOB;
- rbind[3].buffer_length = sizeof (buffer);
- rbind[3].length = &v_length;
- rbind[3].buffer = buffer;
- if ((GNUNET_OK !=
- (ret =
- GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, plugin->select_old_value, 4,
- rbind, return_ok, NULL, -1))) ||
- (GNUNET_OK !=
- (ret =
- GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->delete_value, NULL,
- MYSQL_TYPE_BLOB, &v_key,
- sizeof (struct GNUNET_HashCode), &k_length,
- MYSQL_TYPE_BLOB, &vhash,
- sizeof (struct GNUNET_HashCode), &h_length,
- MYSQL_TYPE_LONG, &v_type, GNUNET_YES,
- MYSQL_TYPE_BLOB, buffer,
- (unsigned long) sizeof (buffer), &v_length,
- -1))))
- {
- if (ret == GNUNET_SYSERR)
- itable (plugin);
- return GNUNET_SYSERR;
- }
- plugin->env->delete_notify (plugin->env->cls, &v_key, v_length + OVERHEAD);
-
- return GNUNET_OK;
-}
-
-
-/**
- * Entry point for the plugin.
- *
- * @param cls closure (the "struct GNUNET_DATACACHE_PluginEnvironmnet")
- * @return the plugin's closure (our "struct Plugin")
- */
-void *
-libgnunet_plugin_datacache_mysql_init (void *cls)
-{
- struct GNUNET_DATACACHE_PluginEnvironment *env = cls;
- struct GNUNET_DATACACHE_PluginFunctions *api;
- struct Plugin *plugin;
-
- plugin = GNUNET_malloc (sizeof (struct Plugin));
- plugin->env = env;
- plugin->mc = GNUNET_MYSQL_context_create (env->cfg, "datacache-mysql");
- if ( (NULL == plugin->mc) ||
- (GNUNET_OK != itable (plugin)) )
- {
- if (NULL != plugin->mc)
- GNUNET_MYSQL_context_destroy (plugin->mc);
- GNUNET_free (plugin);
- return NULL;
- }
- api = GNUNET_malloc (sizeof (struct GNUNET_DATACACHE_PluginFunctions));
- api->cls = plugin;
- api->get = &mysql_plugin_get;
- api->put = &mysql_plugin_put;
- api->del = &mysql_plugin_del;
- GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "mysql",
- _("MySQL datacache running\n"));
- return api;
-}
-
-
-/**
- * Exit point from the plugin.
- *
- * @param cls closure (our "struct Plugin")
- * @return NULL
- */
-void *
-libgnunet_plugin_datacache_mysql_done (void *cls)
-{
- struct GNUNET_DATACACHE_PluginFunctions *api = cls;
- struct Plugin *plugin = api->cls;
-
- GNUNET_MYSQL_context_destroy (plugin->mc);
- GNUNET_free (plugin);
- GNUNET_free (api);
- return NULL;
-}
-
-
-/* end of plugin_datacache_mysql.c */
diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c
index e9157742cd..e7d2e72c27 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -75,13 +75,18 @@ init_connection (struct Plugin *plugin)
" type INTEGER NOT NULL DEFAULT 0,"
" discard_time BIGINT NOT NULL DEFAULT 0,"
" key BYTEA NOT NULL DEFAULT '',"
- " value BYTEA NOT NULL DEFAULT '')" "WITH OIDS");
- if ((ret == NULL) || ((PQresultStatus (ret) != PGRES_COMMAND_OK) && (0 != strcmp ("42P07", /* duplicate table */
- PQresultErrorField
- (ret,
- PG_DIAG_SQLSTATE)))))
+ " value BYTEA NOT NULL DEFAULT '',"
+ " path BYTEA DEFAULT '')"
+ "WITH OIDS");
+ if ( (ret == NULL) ||
+ ((PQresultStatus (ret) != PGRES_COMMAND_OK) &&
+ (0 != strcmp ("42P07", /* duplicate table */
+ PQresultErrorField
+ (ret,
+ PG_DIAG_SQLSTATE)))))
{
- (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "CREATE TABLE",
+ (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret,
+ PGRES_COMMAND_OK, "CREATE TABLE",
"gn090dc");
PQfinish (plugin->dbh);
plugin->dbh = NULL;
@@ -123,11 +128,11 @@ init_connection (struct Plugin *plugin)
PQclear (ret);
if ((GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh, "getkt",
- "SELECT discard_time,type,value FROM gn090dc "
+ "SELECT discard_time,type,value,path FROM gn090dc "
"WHERE key=$1 AND type=$2 ", 2)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh, "getk",
- "SELECT discard_time,type,value FROM gn090dc "
+ "SELECT discard_time,type,value,path FROM gn090dc "
"WHERE key=$1", 1)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh, "getm",
@@ -137,8 +142,8 @@ init_connection (struct Plugin *plugin)
GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090dc WHERE oid=$1", 1)) ||
(GNUNET_OK !=
GNUNET_POSTGRES_prepare (plugin->dbh, "put",
- "INSERT INTO gn090dc (type, discard_time, key, value) "
- "VALUES ($1, $2, $3, $4)", 4)))
+ "INSERT INTO gn090dc (type, discard_time, key, value, path) "
+ "VALUES ($1, $2, $3, $4, $5)", 5)))
{
PQfinish (plugin->dbh);
plugin->dbh = NULL;
@@ -157,12 +162,16 @@ init_connection (struct Plugin *plugin)
* @param data data to store
* @param type type of the value
* @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @return 0 if duplicate, -1 on error, number of bytes used otherwise
*/
-static size_t
+static ssize_t
postgres_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
const char *data, enum GNUNET_BLOCK_Type type,
- struct GNUNET_TIME_Absolute discard_time)
+ struct GNUNET_TIME_Absolute discard_time,
+ unsigned int path_info_len,
+ const struct GNUNET_PeerIdentity *path_info)
{
struct Plugin *plugin = cls;
PGresult *ret;
@@ -173,22 +182,25 @@ postgres_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
(const char *) &btype,
(const char *) &bexpi,
(const char *) key,
- (const char *) data
+ (const char *) data,
+ (const char *) path_info
};
int paramLengths[] = {
sizeof (btype),
sizeof (bexpi),
sizeof (struct GNUNET_HashCode),
- size
+ size,
+ path_info_len * sizeof (struct GNUNET_PeerIdentity)
};
- const int paramFormats[] = { 1, 1, 1, 1 };
+ const int paramFormats[] = { 1, 1, 1, 1, 1 };
ret =
- PQexecPrepared (plugin->dbh, "put", 4, paramValues, paramLengths,
+ PQexecPrepared (plugin->dbh, "put", 5, paramValues, paramLengths,
paramFormats, 1);
if (GNUNET_OK !=
- GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, "PQexecPrepared", "put"))
- return GNUNET_SYSERR;
+ GNUNET_POSTGRES_check_result (plugin->dbh, ret,
+ PGRES_COMMAND_OK, "PQexecPrepared", "put"))
+ return -1;
PQclear (ret);
return size + OVERHEAD;
}
@@ -226,6 +238,8 @@ postgres_plugin_get (void *cls, const struct GNUNET_HashCode * key,
uint32_t size;
unsigned int cnt;
unsigned int i;
+ unsigned int path_len;
+ const struct GNUNET_PeerIdentity *path;
PGresult *res;
res =
@@ -254,7 +268,7 @@ postgres_plugin_get (void *cls, const struct GNUNET_HashCode * key,
PQclear (res);
return cnt;
}
- if ((3 != PQnfields (res)) || (sizeof (uint64_t) != PQfsize (res, 0)) ||
+ if ((4 != PQnfields (res)) || (sizeof (uint64_t) != PQfsize (res, 0)) ||
(sizeof (uint32_t) != PQfsize (res, 1)))
{
GNUNET_break (0);
@@ -267,12 +281,23 @@ postgres_plugin_get (void *cls, const struct GNUNET_HashCode * key,
GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0));
type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1));
size = PQgetlength (res, i, 2);
+ path_len = PQgetlength (res, i, 3);
+ if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity)))
+ {
+ GNUNET_break (0);
+ path_len = 0;
+ }
+ path_len %= sizeof (struct GNUNET_PeerIdentity);
+ path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, i, 3);
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Found result of size %u bytes and type %u in database\n",
(unsigned int) size, (unsigned int) type);
if (GNUNET_SYSERR ==
- iter (iter_cls, expiration_time, key, size, PQgetvalue (res, i, 2),
- (enum GNUNET_BLOCK_Type) type))
+ iter (iter_cls, key, size, PQgetvalue (res, i, 2),
+ (enum GNUNET_BLOCK_Type) type,
+ expiration_time,
+ path_len,
+ path))
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Ending iteration (client error)\n");
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index 74fa385441..3dae4643a7 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -95,12 +95,16 @@ sq_prepare (sqlite3 * dbh, const char *zSql, /* SQL statement, UTF-8 encoded
* @param data data to store
* @param type type of the value
* @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+ * @return 0 if duplicate, -1 on error, number of bytes used otherwise
*/
-static size_t
-sqlite_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
- const char *data, enum GNUNET_BLOCK_Type type,
- struct GNUNET_TIME_Absolute discard_time)
+static ssize_t
+sqlite_plugin_put (void *cls,
+ const struct GNUNET_HashCode *key,
+ size_t size, const char *data,
+ enum GNUNET_BLOCK_Type type,
+ struct GNUNET_TIME_Absolute discard_time,
+ unsigned int path_info_len,
+ const struct GNUNET_PeerIdentity *path_info)
{
struct Plugin *plugin = cls;
sqlite3_stmt *stmt;
@@ -115,31 +119,38 @@ sqlite_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
dval = INT64_MAX;
if (sq_prepare
(plugin->dbh,
- "INSERT INTO ds090 (type, expire, key, value) VALUES (?, ?, ?, ?)",
+ "INSERT INTO ds090 (type, expire, key, value, path) VALUES (?, ?, ?, ?, ?)",
&stmt) != SQLITE_OK)
{
LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"sq_prepare");
- return 0;
+ return -1;
}
if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, type)) ||
(SQLITE_OK != sqlite3_bind_int64 (stmt, 2, dval)) ||
(SQLITE_OK !=
- sqlite3_bind_blob (stmt, 3, key, sizeof (struct GNUNET_HashCode),
+ sqlite3_bind_blob (stmt, 3,
+ key, sizeof (struct GNUNET_HashCode),
SQLITE_TRANSIENT)) ||
- (SQLITE_OK != sqlite3_bind_blob (stmt, 4, data, size, SQLITE_TRANSIENT)))
+ (SQLITE_OK != sqlite3_bind_blob (stmt, 4,
+ data, size,
+ SQLITE_TRANSIENT)) ||
+ (SQLITE_OK != sqlite3_bind_blob (stmt, 5,
+ path_info,
+ path_info_len * sizeof (struct GNUNET_PeerIdentity),
+ SQLITE_TRANSIENT)))
{
LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"sqlite3_bind_xxx");
sqlite3_finalize (stmt);
- return 0;
+ return -1;
}
if (SQLITE_DONE != sqlite3_step (stmt))
{
LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"sqlite3_step");
sqlite3_finalize (stmt);
- return 0;
+ return -1;
}
if (SQLITE_OK != sqlite3_finalize (stmt))
LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -173,8 +184,10 @@ sqlite_plugin_get (void *cls, const struct GNUNET_HashCode * key,
unsigned int cnt;
unsigned int off;
unsigned int total;
+ unsigned int psize;
char scratch[256];
int64_t ntime;
+ const struct GNUNET_PeerIdentity *path;
now = GNUNET_TIME_absolute_get ();
LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' for key `%4s'\n", "GET",
@@ -229,7 +242,7 @@ sqlite_plugin_get (void *cls, const struct GNUNET_HashCode * key,
{
off = (off + 1) % total;
GNUNET_snprintf (scratch, sizeof (scratch),
- "SELECT value,expire FROM ds090 WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET %u",
+ "SELECT value,expire,path FROM ds090 WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET %u",
off);
if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
{
@@ -253,6 +266,17 @@ sqlite_plugin_get (void *cls, const struct GNUNET_HashCode * key,
size = sqlite3_column_bytes (stmt, 0);
dat = sqlite3_column_blob (stmt, 0);
exp.abs_value = sqlite3_column_int64 (stmt, 1);
+ psize = sqlite3_column_bytes (stmt, 2);
+ if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
+ {
+ GNUNET_break (0);
+ psize = 0;
+ }
+ psize /= sizeof (struct GNUNET_PeerIdentity);
+ if (0 != psize)
+ path = sqlite3_column_blob (stmt, 2);
+ else
+ path = NULL;
ntime = (int64_t) exp.abs_value;
if (ntime == INT64_MAX)
exp = GNUNET_TIME_UNIT_FOREVER_ABS;
@@ -260,7 +284,7 @@ sqlite_plugin_get (void *cls, const struct GNUNET_HashCode * key,
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Found %u-byte result when processing `%s' for key `%4s'\n",
(unsigned int) size, "GET", GNUNET_h2s (key));
- if (GNUNET_OK != iter (iter_cls, exp, key, size, dat, type))
+ if (GNUNET_OK != iter (iter_cls, key, size, dat, type, exp, psize, path))
{
sqlite3_finalize (stmt);
break;
@@ -408,7 +432,8 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
"CREATE TABLE ds090 (" " type INTEGER NOT NULL DEFAULT 0,"
" expire INTEGER NOT NULL DEFAULT 0,"
" key BLOB NOT NULL DEFAULT '',"
- " value BLOB NOT NULL DEFAULT '')");
+ " value BLOB NOT NULL DEFAULT '',"
+ " path BLOB DEFAULT '')");
SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds090 (key,type,expire)");
SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds090 (expire)");
plugin = GNUNET_malloc (sizeof (struct Plugin));
diff --git a/src/datacache/plugin_datacache_template.c b/src/datacache/plugin_datacache_template.c
index 6c43959825..306615571f 100644
--- a/src/datacache/plugin_datacache_template.c
+++ b/src/datacache/plugin_datacache_template.c
@@ -49,15 +49,19 @@ struct Plugin
* @param data data to store
* @param type type of the value
* @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @return 0 if duplicate, -1 on error, number of bytes used otherwise
*/
-static size_t
+static ssize_t
template_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
const char *data, enum GNUNET_BLOCK_Type type,
- struct GNUNET_TIME_Absolute discard_time)
+ struct GNUNET_TIME_Absolute discard_time,
+ unsigned int path_info_len,
+ const struct GNUNET_PeerIdentity *path_info)
{
GNUNET_break (0);
- return 0;
+ return -1;
}
diff --git a/src/datacache/test_datacache.c b/src/datacache/test_datacache.c
index 1d8cd32952..5162924f72 100644
--- a/src/datacache/test_datacache.c
+++ b/src/datacache/test_datacache.c
@@ -38,9 +38,13 @@ static const char *plugin_name;
static int
-checkIt (void *cls, struct GNUNET_TIME_Absolute exp,
- const struct GNUNET_HashCode * key, size_t size, const char *data,
- enum GNUNET_BLOCK_Type type)
+checkIt (void *cls,
+ const struct GNUNET_HashCode *key,
+ size_t size, const char *data,
+ enum GNUNET_BLOCK_Type type,
+ struct GNUNET_TIME_Absolute exp,
+ unsigned int path_len,
+ const struct GNUNET_PeerIdentity *path)
{
if (size != sizeof (struct GNUNET_HashCode))
{
@@ -83,7 +87,8 @@ run (void *cls, char *const *args, const char *cfgfile,
GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
ASSERT (GNUNET_OK ==
GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode),
- (const char *) &n, 1 + i % 16, exp));
+ (const char *) &n, 1 + i % 16, exp,
+ 0, NULL));
k = n;
}
memset (&k, 0, sizeof (struct GNUNET_HashCode));
@@ -99,7 +104,8 @@ run (void *cls, char *const *args, const char *cfgfile,
ASSERT (GNUNET_OK ==
GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode),
(const char *) &n, 792,
- GNUNET_TIME_UNIT_FOREVER_ABS));
+ GNUNET_TIME_UNIT_FOREVER_ABS,
+ 0, NULL));
ASSERT (0 != GNUNET_DATACACHE_get (h, &k, 792, &checkIt, &n));
GNUNET_DATACACHE_destroy (h);
diff --git a/src/datacache/test_datacache_data_heap.conf b/src/datacache/test_datacache_data_heap.conf
new file mode 100644
index 0000000000..082cf48f44
--- /dev/null
+++ b/src/datacache/test_datacache_data_heap.conf
@@ -0,0 +1,4 @@
+[testcache]
+QUOTA = 1 MB
+DATABASE = heap
+
diff --git a/src/datacache/test_datacache_data_mysql.conf b/src/datacache/test_datacache_data_mysql.conf
deleted file mode 100644
index bc9daa3ad3..0000000000
--- a/src/datacache/test_datacache_data_mysql.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-[testcache]
-QUOTA = 1 MB
-DATABASE = mysql
-
-[datacache-mysql]
-DATABASE = gnunetcheck
-# CONFIG = ~/.my.cnf
-# USER =
-# PASSWORD =
-# HOST =
-# PORT =
-
-
diff --git a/src/datacache/test_datacache_quota.c b/src/datacache/test_datacache_quota.c
index 1f252c14a5..cac4d18786 100644
--- a/src/datacache/test_datacache_quota.c
+++ b/src/datacache/test_datacache_quota.c
@@ -73,7 +73,7 @@ run (void *cls, char *const *args, const char *cfgfile,
{
exp.abs_value++;
buf[j] = i;
- ASSERT (GNUNET_OK == GNUNET_DATACACHE_put (h, &k, j, buf, 1 + i, exp));
+ ASSERT (GNUNET_OK == GNUNET_DATACACHE_put (h, &k, j, buf, 1 + i, exp, 0, NULL));
ASSERT (0 < GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL));
}
k = n;
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
index b2cb93d12f..4768c14fd7 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -39,28 +39,6 @@ static struct GNUNET_DATACACHE_Handle *datacache;
/**
- * Entry for inserting data into datacache from the DHT.
- */
-struct DHTPutEntry
-{
- /**
- * Size of data.
- */
- uint16_t data_size;
-
- /**
- * Length of recorded path.
- */
- uint16_t path_length;
-
- /* PATH ENTRIES */
-
- /* PUT DATA */
-
-};
-
-
-/**
* Handle a datum we've received from another peer. Cache if
* possible.
*
@@ -80,14 +58,7 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
enum GNUNET_BLOCK_Type type, size_t data_size,
const void *data)
{
- size_t plen =
- data_size + put_path_length * sizeof (struct GNUNET_PeerIdentity) +
- sizeof (struct DHTPutEntry);
- char buf[plen];
- struct DHTPutEntry *pe;
- struct GNUNET_PeerIdentity *pp;
-
- if (datacache == NULL)
+ if (NULL == datacache)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("%s request received, but have no datacache!\n"), "PUT");
@@ -102,14 +73,9 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
GNUNET_STATISTICS_update (GDS_stats,
gettext_noop ("# ITEMS stored in datacache"), 1,
GNUNET_NO);
- pe = (struct DHTPutEntry *) buf;
- pe->data_size = htons (data_size);
- pe->path_length = htons ((uint16_t) put_path_length);
- pp = (struct GNUNET_PeerIdentity *) &pe[1];
- memcpy (pp, put_path, put_path_length * sizeof (struct GNUNET_PeerIdentity));
- memcpy (&pp[put_path_length], data, data_size);
- (void) GNUNET_DATACACHE_put (datacache, key, plen, (const char *) pe, type,
- expiration);
+ (void) GNUNET_DATACACHE_put (datacache, key,
+ data_size, data, type,
+ expiration, put_path_length, put_path);
}
@@ -159,40 +125,26 @@ struct GetRequestContext
* @param size the size of the data identified by key
* @param data the actual data
* @param type the type of the data
- *
+ * @param put_path_length number of peers in 'put_path'
+ * @param put_path path the reply took on put
* @return GNUNET_OK to continue iteration, anything else
* to stop iteration.
*/
static int
-datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
+datacache_get_iterator (void *cls,
const struct GNUNET_HashCode * key, size_t size,
- const char *data, enum GNUNET_BLOCK_Type type)
+ const char *data, enum GNUNET_BLOCK_Type type,
+ struct GNUNET_TIME_Absolute exp,
+ unsigned int put_path_length,
+ const struct GNUNET_PeerIdentity *put_path)
{
struct GetRequestContext *ctx = cls;
- const struct DHTPutEntry *pe;
- const struct GNUNET_PeerIdentity *pp;
- const char *rdata;
- size_t rdata_size;
- uint16_t put_path_length;
enum GNUNET_BLOCK_EvaluationResult eval;
- pe = (const struct DHTPutEntry *) data;
- put_path_length = ntohs (pe->path_length);
- rdata_size = ntohs (pe->data_size);
-
- if (size !=
- sizeof (struct DHTPutEntry) + rdata_size +
- (put_path_length * sizeof (struct GNUNET_PeerIdentity)))
- {
- GNUNET_break (0);
- return GNUNET_OK;
- }
- pp = (const struct GNUNET_PeerIdentity *) &pe[1];
- rdata = (const char *) &pp[put_path_length];
eval =
GNUNET_BLOCK_evaluate (GDS_block_context, type, key, ctx->reply_bf,
ctx->reply_bf_mutator, ctx->xquery,
- ctx->xquery_size, rdata, rdata_size);
+ ctx->xquery_size, data, size);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Found reply for query %s in datacache, evaluation result is %d\n",
GNUNET_h2s (key), (int) eval);
@@ -206,11 +158,11 @@ datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
gettext_noop
("# Good RESULTS found in datacache"), 1,
GNUNET_NO);
- GDS_CLIENTS_handle_reply (exp, key, 0, NULL, put_path_length, pp, type,
- rdata_size, rdata);
+ GDS_CLIENTS_handle_reply (exp, key, 0, NULL, put_path_length, put_path, type,
+ size, data);
/* forward to other peers */
- GDS_ROUTING_process (type, exp, key, put_path_length, pp, 0, NULL, rdata,
- rdata_size);
+ GDS_ROUTING_process (type, exp, key, put_path_length, put_path, 0, NULL, data,
+ size);
break;
case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
GNUNET_STATISTICS_update (GDS_stats,
diff --git a/src/include/gnunet_datacache_lib.h b/src/include/gnunet_datacache_lib.h
index 071b304be2..4f97ee5264 100644
--- a/src/include/gnunet_datacache_lib.h
+++ b/src/include/gnunet_datacache_lib.h
@@ -74,18 +74,22 @@ GNUNET_DATACACHE_destroy (struct GNUNET_DATACACHE_Handle *h);
* An iterator over a set of items stored in the datacache.
*
* @param cls closure
- * @param exp when will the content expire?
* @param key key for the content
* @param size number of bytes in data
* @param data content stored
* @param type type of the content
+ * @param exp when will the content expire?
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
* @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort
*/
typedef int (*GNUNET_DATACACHE_Iterator) (void *cls,
- struct GNUNET_TIME_Absolute exp,
- const struct GNUNET_HashCode * key,
+ const struct GNUNET_HashCode *key,
size_t size, const char *data,
- enum GNUNET_BLOCK_Type type);
+ enum GNUNET_BLOCK_Type type,
+ struct GNUNET_TIME_Absolute exp,
+ unsigned int path_info_len,
+ const struct GNUNET_PeerIdentity *path_info);
/**
@@ -97,13 +101,17 @@ typedef int (*GNUNET_DATACACHE_Iterator) (void *cls,
* @param data data to store
* @param type type of the value
* @param discard_time when to discard the value in any case
- * @return GNUNET_OK on success, GNUNET_SYSERR on error (full, etc.)
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error, GNUNET_NO if duplicate
*/
int
GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
const struct GNUNET_HashCode * key, size_t size,
const char *data, enum GNUNET_BLOCK_Type type,
- struct GNUNET_TIME_Absolute discard_time);
+ struct GNUNET_TIME_Absolute discard_time,
+ unsigned int path_info_len,
+ const struct GNUNET_PeerIdentity *path_info);
/**
diff --git a/src/include/gnunet_datacache_plugin.h b/src/include/gnunet_datacache_plugin.h
index 18268efd78..2e07501608 100644
--- a/src/include/gnunet_datacache_plugin.h
+++ b/src/include/gnunet_datacache_plugin.h
@@ -107,11 +107,15 @@ struct GNUNET_DATACACHE_PluginFunctions
* @param data data to store
* @param type type of the value
* @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @return 0 if duplicate, -1 on error, number of bytes used otherwise
*/
- size_t (*put) (void *cls, const struct GNUNET_HashCode * key, size_t size,
- const char *data, enum GNUNET_BLOCK_Type type,
- struct GNUNET_TIME_Absolute discard_time);
+ ssize_t (*put) (void *cls, const struct GNUNET_HashCode * key, size_t size,
+ const char *data, enum GNUNET_BLOCK_Type type,
+ struct GNUNET_TIME_Absolute discard_time,
+ unsigned int path_info_len,
+ const struct GNUNET_PeerIdentity *path_info);
/**