[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] branch master updated: implemented new DHT path signing with or
From: |
gnunet |
Subject: |
[gnunet] branch master updated: implemented new DHT path signing with origin authentication |
Date: |
Thu, 07 Jul 2022 20:29:32 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new 3abeb4555 implemented new DHT path signing with origin authentication
3abeb4555 is described below
commit 3abeb45550e1cbf4939583c9b6ff48335fe6f1a9
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Jul 7 20:29:24 2022 +0200
implemented new DHT path signing with origin authentication
---
src/cadet/gnunet-service-cadet_dht.c | 3 +
src/datacache/plugin_datacache_heap.c | 5 +-
src/datacache/plugin_datacache_postgres.c | 30 +-
src/datacache/plugin_datacache_sqlite.c | 17 +-
src/datacache/test_datacache.c | 6 +
src/datacache/test_datacache_quota.c | 3 +
src/dht/Makefile.am | 2 +-
src/dht/dht.h | 27 +-
src/dht/dht_api.c | 308 +++++++++-------
src/dht/gnunet-dht-get.c | 6 +
src/dht/gnunet-dht-monitor.c | 8 +-
src/dht/gnunet-service-dht.h | 5 +-
src/dht/gnunet-service-dht_clients.c | 137 +++++---
src/dht/gnunet-service-dht_neighbours.c | 566 ++++++++++++++++++++++--------
src/dht/gnunet_dht_profiler.c | 5 +-
src/dht/test_dht_api.c | 1 +
src/dht/test_dht_monitor.c | 14 +-
src/dht/test_dht_topo.c | 3 +
src/fs/gnunet-service-fs_pr.c | 2 +
src/gns/gnunet-service-gns_resolver.c | 10 +-
src/include/gnunet_datacache_lib.h | 6 +
src/include/gnunet_dht_service.h | 19 +-
src/pt/gnunet-daemon-pt.c | 2 +
src/regex/regex_internal_dht.c | 4 +
24 files changed, 819 insertions(+), 370 deletions(-)
diff --git a/src/cadet/gnunet-service-cadet_dht.c
b/src/cadet/gnunet-service-cadet_dht.c
index d44a50f50..3df2687de 100644
--- a/src/cadet/gnunet-service-cadet_dht.c
+++ b/src/cadet/gnunet-service-cadet_dht.c
@@ -101,6 +101,7 @@ static struct GNUNET_TIME_Relative announce_delay;
* @param cls closure
* @param exp when will this value expire
* @param key key of the result
+ * @param trunc_peer peer preceeding with invalid signature, or NULL
* @param get_path path of the get request
* @param get_path_length length of @a get_path
* @param put_path path of the put request
@@ -112,6 +113,7 @@ static struct GNUNET_TIME_Relative announce_delay;
static void
dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -122,6 +124,7 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute
exp,
{
const struct GNUNET_HELLO_Message *hello = data;
+ (void) trunc_peer;
GCPP_try_path_from_dht (get_path,
get_path_length,
put_path,
diff --git a/src/datacache/plugin_datacache_heap.c
b/src/datacache/plugin_datacache_heap.c
index a2b60c8da..0dd8e47f8 100644
--- a/src/datacache/plugin_datacache_heap.c
+++ b/src/datacache/plugin_datacache_heap.c
@@ -196,10 +196,13 @@ heap_plugin_put (void *cls,
else
val->distance = xor_distance;
if (0 != block->put_path_length)
- val->block.put_path
+ {
+ val->put_path
= GNUNET_memdup (block->put_path,
block->put_path_length
* sizeof (struct GNUNET_DHT_PathElement));
+ val->block.put_path = val->put_path;
+ }
(void) GNUNET_CONTAINER_multihashmap_put (plugin->map,
&val->block.key,
val,
diff --git a/src/datacache/plugin_datacache_postgres.c
b/src/datacache/plugin_datacache_postgres.c
index d9e25992b..b1f9a1b8e 100644
--- a/src/datacache/plugin_datacache_postgres.c
+++ b/src/datacache/plugin_datacache_postgres.c
@@ -71,11 +71,12 @@ init_connection (struct Plugin *plugin)
"CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn180dc_oid_seq"),
GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn180dc ("
" oid OID NOT NULL DEFAULT
nextval('gn180dc_oid_seq'),"
- " type INTEGER NOT NULL,"
- " ro INTEGER NOT NULL,"
- " prox INTEGER NOT NULL,"
- " expiration_time BIGINT NOT NULL,"
- " key BYTEA NOT NULL,"
+ " type INT4 NOT NULL,"
+ " ro INT4 NOT NULL,"
+ " prox INT4 NOT NULL,"
+ " expiration_time INT8 NOT NULL,"
+ " key BYTEA NOT NULL CHECK(LENGTH(key)=64),"
+ " trunc BYTEA NOT NULL CHECK(LENGTH(trunc)=32),"
" value BYTEA NOT NULL,"
" path BYTEA DEFAULT NULL)"),
GNUNET_PQ_make_try_execute (
@@ -93,11 +94,11 @@ init_connection (struct Plugin *plugin)
};
struct GNUNET_PQ_PreparedStatement ps[] = {
GNUNET_PQ_make_prepare ("getkt",
- "SELECT expiration_time,type,ro,value,path FROM
gn180dc "
+ "SELECT expiration_time,type,ro,value,trunc,path
FROM gn180dc "
"WHERE key=$1 AND type=$2 AND expiration_time >=
$3",
3),
GNUNET_PQ_make_prepare ("getk",
- "SELECT expiration_time,type,ro,value,path FROM
gn180dc "
+ "SELECT expiration_time,type,ro,value,trunc,path
FROM gn180dc "
"WHERE key=$1 AND expiration_time >= $2",
2),
GNUNET_PQ_make_prepare ("getex",
@@ -110,14 +111,14 @@ init_connection (struct Plugin *plugin)
" ORDER BY prox ASC, expiration_time ASC LIMIT 1",
0),
GNUNET_PQ_make_prepare ("get_closest",
- "(SELECT expiration_time,type,ro,value,path,key
FROM gn180dc"
+ "(SELECT
expiration_time,type,ro,value,trunc,path,key FROM gn180dc"
" WHERE key >= $1"
" AND expiration_time >= $2"
" AND ( (type = $3) OR ( 0 = $3) )"
" ORDER BY key ASC"
" LIMIT $4)"
" UNION "
- "(SELECT expiration_time,type,ro,value,path,key
FROM gn180dc"
+ "(SELECT
expiration_time,type,ro,value,trunc,path,key FROM gn180dc"
" WHERE key <= $1"
" AND expiration_time >= $2"
" AND ( (type = $3) OR ( 0 = $3) )"
@@ -129,9 +130,9 @@ init_connection (struct Plugin *plugin)
1),
GNUNET_PQ_make_prepare ("put",
"INSERT INTO gn180dc"
- " (type, ro, prox, expiration_time, key, value,
path) "
- "VALUES ($1, $2, $3, $4, $5, $6, $7)",
- 7),
+ " (type, ro, prox, expiration_time, key, value,
trunc, path) "
+ "VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
+ 8),
GNUNET_PQ_PREPARED_STATEMENT_END
};
@@ -170,6 +171,7 @@ postgres_plugin_put (void *cls,
GNUNET_PQ_query_param_auto_from_type (&block->key),
GNUNET_PQ_query_param_fixed_size (block->data,
block->data_size),
+ GNUNET_PQ_query_param_auto_from_type (&block->trunc_peer),
GNUNET_PQ_query_param_fixed_size (block->put_path,
block->put_path_length
* sizeof(struct GNUNET_DHT_PathElement)),
@@ -243,6 +245,8 @@ handle_results (void *cls,
GNUNET_PQ_result_spec_variable_size ("value",
&data,
&block.data_size),
+ GNUNET_PQ_result_spec_auto_from_type ("trunc",
+ &block.trunc_peer),
GNUNET_PQ_result_spec_variable_size ("path",
&path,
&path_size),
@@ -465,6 +469,8 @@ extract_result_cb (void *cls,
GNUNET_PQ_result_spec_variable_size ("value",
&data,
&block.data_size),
+ GNUNET_PQ_result_spec_auto_from_type ("trunc",
+ &block.trunc_peer),
GNUNET_PQ_result_spec_variable_size ("path",
&path,
&path_size),
diff --git a/src/datacache/plugin_datacache_sqlite.c
b/src/datacache/plugin_datacache_sqlite.c
index 22ae5c0f5..0753d87ce 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -207,6 +207,7 @@ sqlite_plugin_put (void *cls,
GNUNET_SQ_query_param_fixed_size (block->put_path,
block->put_path_length
* sizeof(struct GNUNET_DHT_PathElement)),
+ GNUNET_SQ_query_param_auto_from_type (&block->trunc_peer),
GNUNET_SQ_query_param_end
};
@@ -290,6 +291,7 @@ get_any (void *cls,
GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
GNUNET_SQ_result_spec_variable_size (&path,
&path_size),
+ GNUNET_SQ_result_spec_auto_from_type (&block.trunc_peer),
GNUNET_SQ_result_spec_uint32 (&btype32),
GNUNET_SQ_result_spec_uint32 (&bro32),
GNUNET_SQ_result_spec_end
@@ -451,6 +453,7 @@ get_typed (void *cls,
GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
GNUNET_SQ_result_spec_variable_size (&path,
&path_size),
+ GNUNET_SQ_result_spec_auto_from_type (&block.trunc_peer),
GNUNET_SQ_result_spec_uint32 (&bro32),
GNUNET_SQ_result_spec_end
};
@@ -749,6 +752,7 @@ sqlite_plugin_get_closest (void *cls,
GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
GNUNET_SQ_result_spec_variable_size (&path,
&path_size),
+ GNUNET_SQ_result_spec_auto_from_type (&block.trunc_peer),
GNUNET_SQ_result_spec_uint32 (&rtype32),
GNUNET_SQ_result_spec_uint32 (&bro32),
GNUNET_SQ_result_spec_auto_from_type (&block.key),
@@ -882,6 +886,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
" key BLOB NOT NULL DEFAULT '',"
" prox INTEGER NOT NULL,"
" value BLOB NOT NULL,"
+ " trunc BLOB NOT NULL,"
" path BLOB DEFAULT '')");
SQLITE3_EXEC (dbh,
"CREATE INDEX idx_hashidx"
@@ -900,8 +905,8 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
if ((SQLITE_OK !=
sq_prepare (plugin->dbh,
"INSERT INTO ds180"
- " (type, ro, expire, key, prox, value, path)"
- " VALUES (?, ?, ?, ?, ?, ?, ?)",
+ " (type, ro, expire, key, prox, value, path, trunc)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
&plugin->insert_stmt)) ||
(SQLITE_OK !=
sq_prepare (plugin->dbh,
@@ -917,7 +922,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
&plugin->get_count_any_stmt)) ||
(SQLITE_OK !=
sq_prepare (plugin->dbh,
- "SELECT value,expire,path,ro"
+ "SELECT value,expire,path,trunc,ro"
" FROM ds180"
" WHERE key=?"
" AND type=?"
@@ -926,7 +931,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
&plugin->get_stmt)) ||
(SQLITE_OK !=
sq_prepare (plugin->dbh,
- "SELECT value,expire,path,type,ro"
+ "SELECT value,expire,path,trunc,type,ro"
" FROM ds180"
" WHERE key=?"
" AND expire >= ?"
@@ -950,7 +955,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
(SQLITE_OK !=
sq_prepare (plugin->dbh,
"SELECT * FROM ("
- " SELECT value,expire,path,type,ro,key"
+ " SELECT value,expire,path,trunc,type,ro,key"
" FROM ds180 "
" WHERE key>=?1 "
" AND expire >= ?2"
@@ -958,7 +963,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
" ORDER BY KEY ASC LIMIT ?4)"
"UNION "
"SELECT * FROM ("
- " SELECT value,expire,path,type,ro,key"
+ " SELECT value,expire,path,trunc,type,ro,key"
" FROM ds180 "
" WHERE key<=?1 "
" AND expire >= ?2"
diff --git a/src/datacache/test_datacache.c b/src/datacache/test_datacache.c
index b5d978995..fd5a5f54c 100644
--- a/src/datacache/test_datacache.c
+++ b/src/datacache/test_datacache.c
@@ -97,6 +97,9 @@ run (void *cls,
block.key = k;
block.data = &n;
block.data_size = sizeof (n);
+ memset (&block.trunc_peer,
+ 43,
+ sizeof (block.trunc_peer));
block.ro = 42;
block.type = (enum GNUNET_BLOCK_Type) (1 + i % 16);
block.put_path = NULL;
@@ -134,6 +137,9 @@ run (void *cls,
block.data = &n;
block.data_size = sizeof (n);
block.ro = 42;
+ memset (&block.trunc_peer,
+ 44,
+ sizeof (block.trunc_peer));
block.type = (enum GNUNET_BLOCK_Type) 792;
block.put_path = NULL;
block.put_path_length = 0;
diff --git a/src/datacache/test_datacache_quota.c
b/src/datacache/test_datacache_quota.c
index 0b647ee99..994147a64 100644
--- a/src/datacache/test_datacache_quota.c
+++ b/src/datacache/test_datacache_quota.c
@@ -92,6 +92,9 @@ run (void *cls,
block.key = k;
block.data = buf;
block.data_size = j;
+ memset (&block.trunc_peer,
+ 43,
+ sizeof (block.trunc_peer));
block.ro = 42;
block.type = (enum GNUNET_BLOCK_Type) (1 + i);
block.put_path = NULL;
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
index 68a17723d..124f95a77 100644
--- a/src/dht/Makefile.am
+++ b/src/dht/Makefile.am
@@ -26,7 +26,7 @@ libgnunetdht_la_LIBADD = \
$(LTLIBINTL)
libgnunetdht_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) \
- -version-info 3:0:0
+ -version-info 4:0:0
plugin_LTLIBRARIES = \
diff --git a/src/dht/dht.h b/src/dht/dht.h
index c69b69f07..6a137defe 100644
--- a/src/dht/dht.h
+++ b/src/dht/dht.h
@@ -152,6 +152,16 @@ struct GNUNET_DHT_ClientResultMessage
*/
uint32_t type GNUNET_PACKED;
+ /**
+ * Reserved, always 0.
+ */
+ uint32_t reserved GNUNET_PACKED;
+
+ /**
+ * Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
+ */
+ uint32_t options GNUNET_PACKED;
+
/**
* Number of peers recorded in the outgoing path from source to the
* storgage location of this message.
@@ -179,7 +189,7 @@ struct GNUNET_DHT_ClientResultMessage
*/
struct GNUNET_HashCode key GNUNET_PACKED;
- /* put path, get path and actual data are copied to end of this dealy do */
+ /* trunc_peer, put path, get path and actual data are copied to end of this
dealy do */
};
@@ -348,10 +358,9 @@ struct GNUNET_DHT_MonitorGetMessage
uint32_t desired_replication_level GNUNET_PACKED;
/**
- * Number of peers recorded in the outgoing path from source to the
- * storage location of this message.
+ * Always zero.
*/
- uint32_t get_path_length GNUNET_PACKED;
+ uint32_t reserved GNUNET_PACKED;
/**
* The key to store the value under.
@@ -376,6 +385,16 @@ struct GNUNET_DHT_MonitorGetRespMessage
*/
uint32_t type GNUNET_PACKED;
+ /**
+ * Reserved, always 0.
+ */
+ uint32_t reserved GNUNET_PACKED;
+
+ /**
+ * Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
+ */
+ uint32_t options GNUNET_PACKED;
+
/**
* Length of the PUT path that follows (if tracked).
*/
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c
index 474198004..5fa8f759f 100644
--- a/src/dht/dht_api.c
+++ b/src/dht/dht_api.c
@@ -525,31 +525,6 @@ mq_error_handler (void *cls,
}
-/**
- * Verify integrity of a get monitor message from the service.
- *
- * @param cls The DHT handle.
- * @param msg Monitor get message from the service.
- * @return #GNUNET_OK if everything went fine,
- * #GNUNET_SYSERR if the message is malformed.
- */
-static enum GNUNET_GenericReturnValue
-check_monitor_get (void *cls,
- const struct GNUNET_DHT_MonitorGetMessage *msg)
-{
- uint32_t plen = ntohl (msg->get_path_length);
- uint16_t msize = ntohs (msg->header.size) - sizeof(*msg);
-
- if ((plen > UINT16_MAX) ||
- (plen * sizeof(struct GNUNET_DHT_PathElement) != msize))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
/**
* Process a get monitor message from the service.
*
@@ -561,6 +536,8 @@ handle_monitor_get (void *cls,
const struct GNUNET_DHT_MonitorGetMessage *msg)
{
struct GNUNET_DHT_Handle *handle = cls;
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
NULL != mh;
@@ -568,20 +545,19 @@ handle_monitor_get (void *cls,
{
if (NULL == mh->get_cb)
continue;
- if (((GNUNET_BLOCK_TYPE_ANY == mh->type) ||
- (mh->type == ntohl (msg->type))) &&
- ((NULL == mh->key) ||
- (0 == memcmp (mh->key,
- &msg->key,
- sizeof(struct GNUNET_HashCode)))))
- mh->get_cb (mh->cb_cls,
- ntohl (msg->options),
- (enum GNUNET_BLOCK_Type) ntohl (msg->type),
- ntohl (msg->hop_count),
- ntohl (msg->desired_replication_level),
- ntohl (msg->get_path_length),
- (struct GNUNET_DHT_PathElement *) &msg[1],
- &msg->key);
+ if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
+ (mh->type != ntohl (msg->type)))
+ continue;
+ if ( (NULL != mh->key) &&
+ (0 != GNUNET_memcmp (mh->key,
+ &msg->key)) )
+ continue;
+ mh->get_cb (mh->cb_cls,
+ ro,
+ (enum GNUNET_BLOCK_Type) ntohl (msg->type),
+ ntohl (msg->hop_count),
+ ntohl (msg->desired_replication_level),
+ &msg->key);
}
}
@@ -601,7 +577,19 @@ check_monitor_get_resp (void *cls,
size_t msize = ntohs (msg->header.size) - sizeof(*msg);
uint32_t getl = ntohl (msg->get_path_length);
uint32_t putl = ntohl (msg->put_path_length);
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ if (truncated)
+ {
+ if (msize < sizeof (struct GNUNET_PeerIdentity))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ msize -= sizeof (struct GNUNET_PeerIdentity);
+ }
if ((getl + putl < getl) ||
((msize / sizeof(struct GNUNET_DHT_PathElement)) < getl + putl))
{
@@ -624,35 +612,47 @@ handle_monitor_get_resp (void *cls,
{
struct GNUNET_DHT_Handle *handle = cls;
size_t msize = ntohs (msg->header.size) - sizeof(*msg);
- const struct GNUNET_DHT_PathElement *path;
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
uint32_t getl = ntohl (msg->get_path_length);
uint32_t putl = ntohl (msg->put_path_length);
-
-
- path = (const struct GNUNET_DHT_PathElement *) &msg[1];
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ const struct GNUNET_PeerIdentity *trunc_peer
+ = truncated
+ ? (const struct GNUNET_PeerIdentity *) &msg[1]
+ : NULL;
+ const struct GNUNET_DHT_PathElement *path
+ = truncated
+ ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
+ : (const struct GNUNET_DHT_PathElement *) &msg[1];
+
+ if (truncated)
+ msize -= sizeof (struct GNUNET_PeerIdentity);
+ msize -= sizeof(struct GNUNET_DHT_PathElement) * (putl + getl);
for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
NULL != mh;
mh = mh->next)
{
if (NULL == mh->get_resp_cb)
continue;
- if (((GNUNET_BLOCK_TYPE_ANY == mh->type) ||
- (mh->type == ntohl (msg->type))) &&
- ((NULL == mh->key) ||
- (0 == memcmp (mh->key,
- &msg->key,
- sizeof(struct GNUNET_HashCode)))))
- mh->get_resp_cb (mh->cb_cls,
- (enum GNUNET_BLOCK_Type) ntohl (msg->type),
- &path[putl],
- getl,
- path,
- putl,
- GNUNET_TIME_absolute_ntoh (msg->expiration_time),
- &msg->key,
- (const void *) &path[getl + putl],
- msize - sizeof(struct GNUNET_DHT_PathElement) * (putl
- +
getl));
+ if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
+ (mh->type != ntohl (msg->type)) )
+ continue;
+ if ( (NULL != mh->key) &&
+ (0 != GNUNET_memcmp (mh->key,
+ &msg->key)) )
+ continue;
+ mh->get_resp_cb (mh->cb_cls,
+ (enum GNUNET_BLOCK_Type) ntohl (msg->type),
+ trunc_peer,
+ &path[putl],
+ getl,
+ path,
+ putl,
+ GNUNET_TIME_absolute_ntoh (msg->expiration_time),
+ &msg->key,
+ (const void *) &path[getl + putl],
+ msize);
}
}
@@ -669,11 +669,21 @@ static enum GNUNET_GenericReturnValue
check_monitor_put (void *cls,
const struct GNUNET_DHT_MonitorPutMessage *msg)
{
- size_t msize;
- uint32_t putl;
+ size_t msize = ntohs (msg->header.size) - sizeof(*msg);
+ uint32_t putl = ntohl (msg->put_path_length);
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
- msize = ntohs (msg->header.size) - sizeof(*msg);
- putl = ntohl (msg->put_path_length);
+ if (truncated)
+ {
+ if (msize < sizeof (struct GNUNET_PeerIdentity))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ msize -= sizeof (struct GNUNET_PeerIdentity);
+ }
if ((msize / sizeof(struct GNUNET_DHT_PathElement)) < putl)
{
GNUNET_break (0);
@@ -696,31 +706,46 @@ handle_monitor_put (void *cls,
struct GNUNET_DHT_Handle *handle = cls;
size_t msize = ntohs (msg->header.size) - sizeof(*msg);
uint32_t putl = ntohl (msg->put_path_length);
- const struct GNUNET_DHT_PathElement *path;
- struct GNUNET_DHT_MonitorHandle *mh;
-
- path = (const struct GNUNET_DHT_PathElement *) &msg[1];
- for (mh = handle->monitor_head; NULL != mh; mh = mh->next)
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ const struct GNUNET_PeerIdentity *trunc_peer
+ = truncated
+ ? (const struct GNUNET_PeerIdentity *) &msg[1]
+ : NULL;
+ const struct GNUNET_DHT_PathElement *path
+ = truncated
+ ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
+ : (const struct GNUNET_DHT_PathElement *) &msg[1];
+
+ if (truncated)
+ msize -= sizeof (struct GNUNET_PeerIdentity);
+ msize -= sizeof(struct GNUNET_DHT_PathElement) * putl;
+ for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
+ NULL != mh;
+ mh = mh->next)
{
if (NULL == mh->put_cb)
continue;
- if (((GNUNET_BLOCK_TYPE_ANY == mh->type) ||
- (mh->type == ntohl (msg->type))) &&
- ((NULL == mh->key) ||
- (0 == memcmp (mh->key,
- &msg->key,
- sizeof(struct GNUNET_HashCode)))))
- mh->put_cb (mh->cb_cls,
- ntohl (msg->options),
- (enum GNUNET_BLOCK_Type) ntohl (msg->type),
- ntohl (msg->hop_count),
- ntohl (msg->desired_replication_level),
- putl,
- path,
- GNUNET_TIME_absolute_ntoh (msg->expiration_time),
- &msg->key,
- (const void *) &path[putl],
- msize - sizeof(struct GNUNET_DHT_PathElement) * putl);
+ if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
+ (mh->type != ntohl (msg->type)) )
+ continue;
+ if ( (NULL != mh->key) &&
+ (0 != GNUNET_memcmp (mh->key,
+ &msg->key)) )
+ continue;
+ mh->put_cb (mh->cb_cls,
+ ro,
+ (enum GNUNET_BLOCK_Type) ntohl (msg->type),
+ ntohl (msg->hop_count),
+ ntohl (msg->desired_replication_level),
+ trunc_peer,
+ putl,
+ path,
+ GNUNET_TIME_absolute_ntoh (msg->expiration_time),
+ &msg->key,
+ (const void *) &path[putl],
+ msize);
}
}
@@ -740,15 +765,25 @@ check_client_result (void *cls,
size_t msize = ntohs (msg->header.size) - sizeof(*msg);
uint32_t put_path_length = ntohl (msg->put_path_length);
uint32_t get_path_length = ntohl (msg->get_path_length);
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
size_t meta_length;
- meta_length =
- sizeof(struct GNUNET_DHT_PathElement) * (get_path_length +
put_path_length);
- if ((msize < meta_length) ||
- (get_path_length >
- GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
- (put_path_length >
- GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)))
+ if (truncated)
+ {
+ if (msize < sizeof (struct GNUNET_PeerIdentity))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ msize -= sizeof (struct GNUNET_PeerIdentity);
+ }
+ meta_length = msize / sizeof(struct GNUNET_DHT_PathElement);
+ if ( (get_path_length + put_path_length >
+ meta_length) ||
+ (get_path_length + put_path_length <
+ get_path_length) )
{
GNUNET_break (0);
return GNUNET_SYSERR;
@@ -774,21 +809,35 @@ process_client_result (void *cls,
struct GNUNET_DHT_GetHandle *get_handle = value;
size_t msize = ntohs (crm->header.size) - sizeof(*crm);
uint16_t type = ntohl (crm->type);
- uint32_t put_path_length = ntohl (crm->put_path_length);
- uint32_t get_path_length = ntohl (crm->get_path_length);
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohl (crm->options);
+ bool truncated
+ = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ uint32_t put_path_length
+ = ntohl (crm->put_path_length);
+ uint32_t get_path_length
+ = ntohl (crm->get_path_length);
+ const struct GNUNET_PeerIdentity *trunc_peer
+ = truncated
+ ? (const struct GNUNET_PeerIdentity *) &crm[1]
+ : NULL;
const struct GNUNET_DHT_PathElement *put_path
- = (const struct GNUNET_DHT_PathElement *) &crm[1];
+ = truncated
+ ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
+ : (const struct GNUNET_DHT_PathElement *) &crm[1];
const struct GNUNET_DHT_PathElement *get_path
= &put_path[put_path_length];
const void *data
= &get_path[get_path_length];
size_t meta_length
- = sizeof(struct GNUNET_DHT_PathElement) * (get_path_length
- + put_path_length);
+ = sizeof(struct GNUNET_DHT_PathElement)
+ * (get_path_length + put_path_length);
size_t data_length
= msize - meta_length;
struct GNUNET_HashCode hc;
+ if (truncated)
+ data_length -= sizeof (struct GNUNET_PeerIdentity);
if (crm->unique_id != get_handle->unique_id)
{
/* UID mismatch */
@@ -837,6 +886,7 @@ process_client_result (void *cls,
get_handle->iter (get_handle->iter_cls,
GNUNET_TIME_absolute_ntoh (crm->expiration),
key,
+ trunc_peer,
get_path,
get_path_length,
put_path,
@@ -945,10 +995,10 @@ static enum GNUNET_GenericReturnValue
try_connect (struct GNUNET_DHT_Handle *h)
{
struct GNUNET_MQ_MessageHandler handlers[] = {
- GNUNET_MQ_hd_var_size (monitor_get,
- GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET,
- struct GNUNET_DHT_MonitorGetMessage,
- h),
+ GNUNET_MQ_hd_fixed_size (monitor_get,
+ GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET,
+ struct GNUNET_DHT_MonitorGetMessage,
+ h),
GNUNET_MQ_hd_var_size (monitor_get_resp,
GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP,
struct GNUNET_DHT_MonitorGetRespMessage,
@@ -1303,19 +1353,19 @@ unsigned int
GNUNET_DHT_verify_path (const void *data,
size_t data_size,
struct GNUNET_TIME_Absolute exp_time,
+ const struct GNUNET_PeerIdentity *bpid,
const struct GNUNET_DHT_PathElement *put_path,
unsigned int put_path_len,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_len,
const struct GNUNET_PeerIdentity *me)
{
+ static struct GNUNET_PeerIdentity zero;
struct GNUNET_DHT_HopSignature hs = {
.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP),
.purpose.size = htonl (sizeof (hs)),
.expiration_time = GNUNET_TIME_absolute_hton (exp_time)
};
- const struct GNUNET_PeerIdentity *pred;
- const struct GNUNET_PeerIdentity *succ;
unsigned int i;
if (0 == get_path_len + put_path_len)
@@ -1336,38 +1386,56 @@ GNUNET_DHT_verify_path (const void *data,
j,
GNUNET_i2s (&get_path[j].pred));
- i = put_path_len + get_path_len - 1;
GNUNET_CRYPTO_hash (data,
data_size,
&hs.h_data);
+ i = put_path_len + get_path_len;
while (i > 0)
{
- pred = (i - 1 >= put_path_len)
- ? &get_path[i - put_path_len - 1].pred
- : &put_path[i - 1].pred;
- if (i + 1 == get_path_len + put_path_len)
+ const struct GNUNET_PeerIdentity *pred;
+ const struct GNUNET_PeerIdentity *succ;
+ const struct GNUNET_DHT_PathElement *pe;
+
+ i--;
+ if (0 == i)
+ {
+ pred = (NULL == bpid) ? &zero : bpid;
+ }
+ else
+ {
+ unsigned int off = i - 1;
+
+ pred = (off >= put_path_len)
+ ? &get_path[off - put_path_len].pred
+ : &put_path[off].pred;
+ }
+ if (i == get_path_len + put_path_len - 1)
+ {
succ = me;
+ }
else
- succ = (i + 1 >= put_path_len)
- ? &get_path[i + 1 - put_path_len].pred
- : &put_path[i + 1].pred;
+ {
+ unsigned int off = i + 1;
+
+ succ = (off >= put_path_len)
+ ? &get_path[off - put_path_len].pred
+ : &put_path[off].pred;
+ }
hs.pred = *pred;
hs.succ = *succ;
+ pe = (i >= put_path_len)
+ ? &get_path[i - put_path_len]
+ : &put_path[i];
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (
GNUNET_SIGNATURE_PURPOSE_DHT_HOP,
&hs,
- (i - 1 >= put_path_len)
- ? &get_path[i - put_path_len - 1].sig
- : &put_path[i - 1].sig,
- (i >= put_path_len)
- ? &get_path[i - put_path_len].pred.public_key
- : &put_path[i].pred.public_key))
+ &pe->sig,
+ &pe->pred.public_key))
{
GNUNET_break_op (0);
- return i;
+ return i + 1;
}
- i--;
}
return i;
}
diff --git a/src/dht/gnunet-dht-get.c b/src/dht/gnunet-dht-get.c
index 42ffe75ba..806cafd0d 100644
--- a/src/dht/gnunet-dht-get.c
+++ b/src/dht/gnunet-dht-get.c
@@ -139,6 +139,7 @@ timeout_task (void *cls)
* @param cls closure
* @param exp when will this value expire
* @param key key of the result
+ * @param trunc_peer peer at which the path was truncated, or NULL if not
* @param get_path peers on reply path (or NULL if not recorded)
* @param get_path_length number of entries in get_path
* @param put_path peers on the PUT path (or NULL if not recorded)
@@ -151,6 +152,7 @@ static void
get_result_iterator (void *cls,
struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -183,6 +185,10 @@ get_result_iterator (void *cls,
"%s%s",
(0 == i) ? "" : "-",
GNUNET_i2s (&put_path[i].pred));
+ if (NULL != trunc_peer)
+ fprintf (stdout,
+ "T%s",
+ GNUNET_i2s (trunc_peer));
fprintf (stdout,
"\n");
}
diff --git a/src/dht/gnunet-dht-monitor.c b/src/dht/gnunet-dht-monitor.c
index b4ec497e4..93ea1284a 100644
--- a/src/dht/gnunet-dht-monitor.c
+++ b/src/dht/gnunet-dht-monitor.c
@@ -125,8 +125,6 @@ timeout_task (void *cls)
* @param options Options, for instance RecordRoute, DemultiplexEverywhere.
* @param type The type of data in the request.
* @param hop_count Hop count so far.
- * @param path_length number of entries in path (or 0 if not recorded).
- * @param path peers on the GET path (or NULL if not recorded).
* @param desired_replication_level Desired replication level.
* @param key Key of the requested data.
*/
@@ -136,8 +134,6 @@ get_callback (void *cls,
enum GNUNET_BLOCK_Type type,
uint32_t hop_count,
uint32_t desired_replication_level,
- unsigned int path_length,
- const struct GNUNET_DHT_PathElement *path,
const struct GNUNET_HashCode *key)
{
fprintf (stdout,
@@ -154,6 +150,7 @@ get_callback (void *cls,
*
* @param cls Closure.
* @param type The type of data in the result.
+ * @param trunc_peer peer where the path was truncated, or NULL if the path is
complete
* @param get_path Peers on GET path (or NULL if not recorded).
* @param get_path_length number of entries in get_path.
* @param put_path peers on the PUT path (or NULL if not recorded).
@@ -166,6 +163,7 @@ get_callback (void *cls,
static void
get_resp_callback (void *cls,
enum GNUNET_BLOCK_Type type,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -196,6 +194,7 @@ get_resp_callback (void *cls,
* @param options Options, for instance RecordRoute, DemultiplexEverywhere.
* @param type The type of data in the request.
* @param hop_count Hop count so far.
+ * @param trunc_peer peer where the path was truncated, or NULL if the path is
complete
* @param path_length number of entries in path (or 0 if not recorded).
* @param path peers on the PUT path (or NULL if not recorded).
* @param desired_replication_level Desired replication level.
@@ -210,6 +209,7 @@ put_callback (void *cls,
enum GNUNET_BLOCK_Type type,
uint32_t hop_count,
uint32_t desired_replication_level,
+ const struct GNUNET_PeerIdentity *trunc_peer,
unsigned int path_length,
const struct GNUNET_DHT_PathElement *path,
struct GNUNET_TIME_Absolute exp,
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index 5507dcea0..ecb79fa50 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -144,6 +144,7 @@ GDS_u_hold (struct GDS_Underlay *u,
*
* @param bd block details
* @param query_hash hash of the original query, might not match key in @a bd
+ * @param trunc_peer peer at which the path was truncated, or NULL if path
starts at the origin
* @param get_path_length number of entries in @a get_path
* @param get_path path the reply has taken
* @return true on success, false on failures
@@ -162,8 +163,6 @@ GDS_CLIENTS_handle_reply (const struct
GNUNET_DATACACHE_Block *bd,
* @param options Options, for instance RecordRoute, DemultiplexEverywhere.
* @param type The type of data in the request.
* @param hop_count Hop count so far.
- * @param path_length number of entries in path (or 0 if not recorded).
- * @param path peers on the GET path (or NULL if not recorded).
* @param desired_replication_level Desired replication level.
* @param key Key of the requested data.
*/
@@ -172,8 +171,6 @@ GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption
options,
enum GNUNET_BLOCK_Type type,
uint32_t hop_count,
uint32_t desired_replication_level,
- unsigned int path_length,
- const struct GNUNET_DHT_PathElement *path,
const struct GNUNET_HashCode *key);
diff --git a/src/dht/gnunet-service-dht_clients.c
b/src/dht/gnunet-service-dht_clients.c
index 631c4f68b..fdcc31f13 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -656,8 +656,6 @@ handle_dht_local_get (void *cls,
cqr->type,
0, /* hop count */
cqr->replication,
- 0, /* path length */
- NULL,
&get->key);
/* start remote requests */
if (NULL != retry_task)
@@ -907,12 +905,15 @@ forward_reply (void *cls,
{
struct ForwardReplyContext *frc = cls;
struct ClientQueryRecord *record = value;
+ const struct GNUNET_DATACACHE_Block *bd = frc->bd;
struct GNUNET_MQ_Envelope *env;
struct GNUNET_DHT_ClientResultMessage *reply;
enum GNUNET_BLOCK_ReplyEvaluationResult eval;
bool do_free;
struct GNUNET_HashCode ch;
struct GNUNET_DHT_PathElement *paths;
+ bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
+ size_t xsize = bd->data_size;
LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG,
"CLIENT-RESULT %s\n",
@@ -995,18 +996,34 @@ forward_reply (void *cls,
"# RESULTS queued for clients",
1,
GNUNET_NO);
+ xsize += (frc->get_path_length + frc->bd->put_path_length)
+ * sizeof(struct GNUNET_DHT_PathElement);
+ if (truncated)
+ xsize += sizeof (struct GNUNET_PeerIdentity);
env = GNUNET_MQ_msg_extra (reply,
- frc->bd->data_size
- + (frc->get_path_length +
frc->bd->put_path_length)
- * sizeof(struct GNUNET_DHT_PathElement),
+ xsize,
GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT);
reply->type = htonl (frc->bd->type);
+ reply->options = htonl (bd->ro);
reply->get_path_length = htonl (frc->get_path_length);
reply->put_path_length = htonl (frc->bd->put_path_length);
reply->unique_id = record->unique_id;
reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time);
reply->key = *query_hash;
- paths = (struct GNUNET_DHT_PathElement *) &reply[1];
+ if (truncated)
+ {
+ void *tgt = &reply[1];
+
+ GNUNET_memcpy (tgt,
+ &bd->trunc_peer,
+ sizeof (struct GNUNET_PeerIdentity));
+ paths = (struct GNUNET_DHT_PathElement *)
+ (tgt + sizeof (struct GNUNET_PeerIdentity));
+ }
+ else
+ {
+ paths = (struct GNUNET_DHT_PathElement *) &reply[1];
+ }
GNUNET_memcpy (paths,
frc->bd->put_path,
sizeof(struct GNUNET_DHT_PathElement)
@@ -1041,6 +1058,7 @@ GDS_CLIENTS_handle_reply (const struct
GNUNET_DATACACHE_Block *bd,
+ bd->data_size
+ (get_path_length + bd->put_path_length)
* sizeof(struct GNUNET_DHT_PathElement);
+ bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
if (msize >= GNUNET_MAX_MESSAGE_SIZE)
{
@@ -1052,6 +1070,9 @@ GDS_CLIENTS_handle_reply (const struct
GNUNET_DATACACHE_Block *bd,
GNUNET_DHT_verify_path (bd->data,
bd->data_size,
bd->expiration_time,
+ truncated
+ ? &bd->trunc_peer
+ : NULL,
bd->put_path,
bd->put_path_length,
get_path,
@@ -1291,27 +1312,30 @@ for_matching_monitors (enum GNUNET_BLOCK_Type type,
NULL != m;
m = m->next)
{
- if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) ||
- (m->type == type) ) &&
- ( (GNUNET_is_zero (&m->key)) ||
- (0 ==
- GNUNET_memcmp (key,
- &m->key)) ) )
- {
- unsigned int i;
-
- /* Don't send duplicates */
- for (i = 0; i < cl_size; i++)
- if (cl[i] == m->ch)
- break;
- if (i < cl_size)
- continue;
- GNUNET_array_append (cl,
- cl_size,
- m->ch);
- cb (cb_cls,
- m);
- }
+ bool found = false;
+
+ if ( (GNUNET_BLOCK_TYPE_ANY != m->type) &&
+ (m->type != type) )
+ continue;
+ if ( (! GNUNET_is_zero (&m->key)) &&
+ (0 ==
+ GNUNET_memcmp (key,
+ &m->key)) )
+ continue;
+ /* Don't send duplicates */
+ for (unsigned i = 0; i < cl_size; i++)
+ if (cl[i] == m->ch)
+ {
+ found = true;
+ break;
+ }
+ if (found)
+ continue;
+ GNUNET_array_append (cl,
+ cl_size,
+ m->ch);
+ cb (cb_cls,
+ m);
}
GNUNET_free (cl);
}
@@ -1326,8 +1350,7 @@ struct GetActionContext
enum GNUNET_BLOCK_Type type;
uint32_t hop_count;
uint32_t desired_replication_level;
- unsigned int get_path_length;
- const struct GNUNET_DHT_PathElement *get_path;
+ struct GNUNET_PeerIdentity trunc_peer;
const struct GNUNET_HashCode *key;
};
@@ -1346,23 +1369,14 @@ get_action (void *cls,
struct GetActionContext *gac = cls;
struct GNUNET_MQ_Envelope *env;
struct GNUNET_DHT_MonitorGetMessage *mmsg;
- struct GNUNET_DHT_PathElement *msg_path;
- size_t msize;
- msize = gac->get_path_length * sizeof(struct GNUNET_DHT_PathElement);
- env = GNUNET_MQ_msg_extra (mmsg,
- msize,
- GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET);
+ env = GNUNET_MQ_msg (mmsg,
+ GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET);
mmsg->options = htonl (gac->options);
mmsg->type = htonl (gac->type);
mmsg->hop_count = htonl (gac->hop_count);
mmsg->desired_replication_level = htonl (gac->desired_replication_level);
- mmsg->get_path_length = htonl (gac->get_path_length);
mmsg->key = *gac->key;
- msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
- GNUNET_memcpy (msg_path,
- gac->get_path,
- gac->get_path_length * sizeof(struct GNUNET_DHT_PathElement));
GNUNET_MQ_send (m->ch->mq,
env);
}
@@ -1375,8 +1389,6 @@ get_action (void *cls,
* @param options Options, for instance RecordRoute, DemultiplexEverywhere.
* @param type The type of data in the request.
* @param hop_count Hop count so far.
- * @param path_length number of entries in path (or 0 if not recorded).
- * @param path peers on the GET path (or NULL if not recorded).
* @param desired_replication_level Desired replication level.
* @param key Key of the requested data.
*/
@@ -1385,8 +1397,6 @@ GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption
options,
enum GNUNET_BLOCK_Type type,
uint32_t hop_count,
uint32_t desired_replication_level,
- unsigned int path_length,
- const struct GNUNET_DHT_PathElement *path,
const struct GNUNET_HashCode *key)
{
struct GetActionContext gac = {
@@ -1394,8 +1404,6 @@ GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption
options,
.type = type,
.hop_count = hop_count,
.desired_replication_level = desired_replication_level,
- .get_path_length = path_length,
- .get_path = path,
.key = key
};
@@ -1430,7 +1438,7 @@ response_action (void *cls,
{
const struct ResponseActionContext *resp_ctx = cls;
const struct GNUNET_DATACACHE_Block *bd = resp_ctx->bd;
-
+ bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
struct GNUNET_MQ_Envelope *env;
struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
struct GNUNET_DHT_PathElement *path;
@@ -1439,6 +1447,8 @@ response_action (void *cls,
msize = bd->data_size;
msize += (resp_ctx->get_path_length + bd->put_path_length)
* sizeof(struct GNUNET_DHT_PathElement);
+ if (truncated)
+ msize += sizeof (struct GNUNET_PeerIdentity);
env = GNUNET_MQ_msg_extra (mmsg,
msize,
GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP);
@@ -1447,7 +1457,20 @@ response_action (void *cls,
mmsg->get_path_length = htonl (resp_ctx->get_path_length);
mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
mmsg->key = bd->key;
- path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
+ if (truncated)
+ {
+ void *tgt = &mmsg[1];
+
+ GNUNET_memcpy (tgt,
+ &bd->trunc_peer,
+ sizeof (struct GNUNET_PeerIdentity));
+ path = (struct GNUNET_DHT_PathElement *)
+ (tgt + sizeof (struct GNUNET_PeerIdentity));
+ }
+ else
+ {
+ path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
+ }
GNUNET_memcpy (path,
bd->put_path,
bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
@@ -1505,6 +1528,7 @@ put_action (void *cls,
{
const struct PutActionContext *put_ctx = cls;
const struct GNUNET_DATACACHE_Block *bd = put_ctx->bd;
+ bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
struct GNUNET_MQ_Envelope *env;
struct GNUNET_DHT_MonitorPutMessage *mmsg;
struct GNUNET_DHT_PathElement *msg_path;
@@ -1513,6 +1537,8 @@ put_action (void *cls,
msize = bd->data_size
+ bd->put_path_length
* sizeof(struct GNUNET_DHT_PathElement);
+ if (truncated)
+ msize += sizeof (struct GNUNET_PeerIdentity);
env = GNUNET_MQ_msg_extra (mmsg,
msize,
GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
@@ -1523,7 +1549,20 @@ put_action (void *cls,
mmsg->put_path_length = htonl (bd->put_path_length);
mmsg->key = bd->key;
mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
- msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
+ if (truncated)
+ {
+ void *tgt = &mmsg[1];
+
+ GNUNET_memcpy (tgt,
+ &bd->trunc_peer,
+ sizeof (struct GNUNET_PeerIdentity));
+ msg_path = (struct GNUNET_DHT_PathElement *)
+ (tgt + sizeof (struct GNUNET_PeerIdentity));
+ }
+ else
+ {
+ msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
+ }
GNUNET_memcpy (msg_path,
bd->put_path,
bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
diff --git a/src/dht/gnunet-service-dht_neighbours.c
b/src/dht/gnunet-service-dht_neighbours.c
index 2a54f715a..cc7333a9c 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -150,8 +150,12 @@ struct PeerPutMessage
*/
struct GNUNET_HashCode key;
+ /* trunc_peer (if truncated) */
+
/* put path (if tracked) */
+ /* sender_sig (if path tracking is on) */
+
/* Payload */
};
@@ -172,9 +176,9 @@ struct PeerResultMessage
uint32_t type GNUNET_PACKED;
/**
- * Reserved.
+ * Message options, actually an 'enum GNUNET_DHT_RouteOption' value in NBO.
*/
- uint32_t reserved GNUNET_PACKED;
+ uint32_t options GNUNET_PACKED;
/**
* Length of the PUT path that follows (if tracked).
@@ -196,10 +200,14 @@ struct PeerResultMessage
*/
struct GNUNET_HashCode key;
+ /* trunc_peer (if truncated) */
+
/* put path (if tracked) */
/* get path (if tracked) */
+ /* sender_sig (if path tracking is on) */
+
/* Payload */
};
@@ -537,10 +545,11 @@ sign_path (const void *data,
.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP),
.purpose.size = htonl (sizeof (hs)),
.expiration_time = GNUNET_TIME_absolute_hton (exp_time),
- .pred = *pred,
.succ = *succ
};
+ if (NULL != pred)
+ hs.pred = *pred;
GNUNET_CRYPTO_hash (data,
data_size,
&hs.h_data);
@@ -1314,21 +1323,36 @@ GDS_NEIGHBOURS_handle_put (const struct
GNUNET_DATACACHE_Block *bd,
struct PeerInfo **targets;
size_t msize;
unsigned int skip_count;
+ enum GNUNET_DHT_RouteOption ro = bd->ro;
unsigned int put_path_length = bd->put_path_length;
+ const struct GNUNET_DHT_PathElement *put_path = bd->put_path;
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ bool tracking = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
+ const struct GNUNET_PeerIdentity *trunc_peer
+ = truncated
+ ? &bd->trunc_peer
+ : NULL;
- GNUNET_assert (NULL != bf);
#if SANITY_CHECKS > 1
- if (0 !=
- GNUNET_DHT_verify_path (bd->data,
+ unsigned int failure_offset;
+
+ failure_offset
+ = GNUNET_DHT_verify_path (bd->data,
bd->data_size,
bd->expiration_time,
- bd->put_path,
- bd->put_path_length,
- NULL, 0, /* get_path */
- &GDS_my_identity))
+ trunc_peer,
+ put_path,
+ put_path_length,
+ NULL, 0, /* get_path */
+ &GDS_my_identity);
+ if (0 != failure_offset)
{
GNUNET_break_op (0);
- put_path_length = 0;
+ truncated = true;
+ trunc_peer = &put_path[failure_offset - 1].pred;
+ put_path = &put_path[failure_offset];
+ put_path_length = put_path_length - failure_offset;
+ ro |= GNUNET_DHT_RO_TRUNCATED;
}
#endif
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1340,12 +1364,70 @@ GDS_NEIGHBOURS_handle_put (const struct
GNUNET_DATACACHE_Block *bd,
/* if we got a HELLO, consider it for our own routing table */
hello_check (bd);
+ GNUNET_assert (NULL != bf);
GNUNET_CONTAINER_bloomfilter_add (bf,
&GDS_my_identity_hash);
GNUNET_STATISTICS_update (GDS_stats,
"# PUT requests routed",
1,
GNUNET_NO);
+ if (bd->data_size
+ > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE
+ - sizeof(struct PeerPutMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ msize = bd->data_size + sizeof(struct PeerPutMessage);
+ if (tracking)
+ {
+ if (msize + sizeof (struct GNUNET_CRYPTO_EddsaSignature)
+ > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Discarding message that is too large due to tracking\n");
+ return GNUNET_NO;
+ }
+ msize += sizeof (struct GNUNET_CRYPTO_EddsaSignature);
+ }
+ else
+ {
+ /* If tracking is disabled, also discard any path we might have
+ gotten from some broken peer */
+ GNUNET_break_op (0 == put_path_length);
+ put_path_length = 0;
+ }
+ if (truncated)
+ msize += sizeof (struct GNUNET_PeerIdentity);
+ if (msize + put_path_length * sizeof(struct GNUNET_DHT_PathElement)
+ > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
+ {
+ unsigned int mlen;
+ unsigned int ppl;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Truncating path that is too large due\n");
+ mlen = GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE - msize;
+ if (! truncated)
+ {
+ /* We need extra space for the truncation, consider that,
+ too! */
+ truncated = true;
+ mlen -= sizeof (struct GNUNET_PeerIdentity);
+ msize += sizeof (struct GNUNET_PeerIdentity);
+ }
+ /* compute maximum length of path we can keep */
+ ppl = mlen / sizeof (struct GNUNET_DHT_PathElement);
+ GNUNET_assert (put_path_length - ppl > 0);
+ trunc_peer = &put_path[put_path_length - ppl - 1].pred;
+ put_path = &put_path[put_path_length - ppl];
+ put_path_length = ppl;
+ ro |= GNUNET_DHT_RO_TRUNCATED;
+ }
+ else
+ {
+ msize += bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement);
+ }
target_count
= get_target_peers (&bd->key,
bf,
@@ -1361,28 +1443,14 @@ GDS_NEIGHBOURS_handle_put (const struct
GNUNET_DATACACHE_Block *bd,
GNUNET_i2s (&GDS_my_identity));
return GNUNET_NO;
}
- msize = bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement)
- + bd->data_size;
- if (msize + sizeof(struct PeerPutMessage)
- >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
- {
- put_path_length = 0;
- msize = bd->data_size;
- }
- if (msize + sizeof(struct PeerPutMessage)
- >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
- {
- GNUNET_break (0);
- GNUNET_free (targets);
- return GNUNET_NO;
- }
skip_count = 0;
for (unsigned int i = 0; i < target_count; i++)
{
struct PeerInfo *target = targets[i];
struct PeerPutMessage *ppm;
- char buf[sizeof (*ppm) + msize] GNUNET_ALIGN;
+ char buf[msize] GNUNET_ALIGN;
struct GNUNET_DHT_PathElement *pp;
+ void *data;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Routing PUT for %s after %u hops to %s\n",
@@ -1393,7 +1461,7 @@ GDS_NEIGHBOURS_handle_put (const struct
GNUNET_DATACACHE_Block *bd,
ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
ppm->header.size = htons (sizeof (buf));
ppm->type = htonl (bd->type);
- ppm->options = htons (bd->ro);
+ ppm->options = htons (ro);
ppm->hop_count = htons (hop_count + 1);
ppm->desired_replication_level = htons (desired_replication_level);
ppm->put_path_length = htons (put_path_length);
@@ -1406,28 +1474,62 @@ GDS_NEIGHBOURS_handle_put (const struct
GNUNET_DATACACHE_Block *bd,
ppm->bloomfilter,
DHT_BLOOM_SIZE));
ppm->key = bd->key;
- pp = (struct GNUNET_DHT_PathElement *) &ppm[1];
+ if (truncated)
+ {
+ void *tgt = &ppm[1];
+
+ GNUNET_memcpy (tgt,
+ trunc_peer,
+ sizeof (struct GNUNET_PeerIdentity));
+ pp = (struct GNUNET_DHT_PathElement *)
+ (tgt + sizeof (struct GNUNET_PeerIdentity));
+ }
+ else
+ {
+ pp = (struct GNUNET_DHT_PathElement *) &ppm[1];
+ }
GNUNET_memcpy (pp,
- bd->put_path,
+ put_path,
sizeof (struct GNUNET_DHT_PathElement) * put_path_length);
- /* 0 == put_path_length means path is not being tracked */
- if (0 != put_path_length)
+ if (tracking)
{
- /* Note that the signature in 'put_path' was not initialized before,
- so this is crucial to avoid sending garbage. */
- sign_path (bd->data,
- bd->data_size,
- bd->expiration_time,
- &pp[put_path_length - 1].pred,
- &target->id,
- &pp[put_path_length - 1].sig);
+ void *tgt = &pp[put_path_length];
+ struct GNUNET_CRYPTO_EddsaSignature last_sig;
+
+ if (0 == put_path_length)
+ {
+ /* Note that the signature in 'put_path' was not initialized before,
+ so this is crucial to avoid sending garbage. */
+ sign_path (bd->data,
+ bd->data_size,
+ bd->expiration_time,
+ trunc_peer,
+ &target->id,
+ &last_sig);
+ }
+ else
+ {
+ sign_path (bd->data,
+ bd->data_size,
+ bd->expiration_time,
+ &pp[put_path_length - 1].pred,
+ &target->id,
+ &last_sig);
+ }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Signing PUT PATH %u => %s\n",
put_path_length,
- GNUNET_B2S (&pp[put_path_length - 1].sig));
+ GNUNET_B2S (&last_sig));
+ memcpy (tgt,
+ &last_sig,
+ sizeof (last_sig));
+ data = tgt + sizeof (last_sig);
}
-
- GNUNET_memcpy (&pp[put_path_length],
+ else /* ! tracking */
+ {
+ data = &ppm[1];
+ }
+ GNUNET_memcpy (data,
bd->data,
bd->data_size);
do_send (target,
@@ -1572,46 +1674,86 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
struct GNUNET_DHT_PathElement *paths;
size_t msize;
unsigned int ppl = bd->put_path_length;
-
+ const struct GNUNET_DHT_PathElement *put_path = bd->put_path;
+ enum GNUNET_DHT_RouteOption ro = bd->ro;
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ const struct GNUNET_PeerIdentity *trunc_peer
+ = truncated
+ ? &bd->trunc_peer
+ : NULL;
+ bool tracking = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
#if SANITY_CHECKS > 1
- if (0 !=
- GNUNET_DHT_verify_path (bd->data,
+ unsigned int failure_offset;
+
+ failure_offset
+ = GNUNET_DHT_verify_path (bd->data,
bd->data_size,
bd->expiration_time,
- bd->put_path,
- bd->put_path_length,
+ trunc_peer,
+ put_path,
+ ppl,
get_path,
get_path_length,
- &GDS_my_identity))
+ &GDS_my_identity);
+ if (0 != failure_offset)
{
+ GNUNET_assert (failure_offset <= ppl + get_path_length);
GNUNET_break_op (0);
- return false;
+ if (failure_offset < ppl)
+ {
+ trunc_peer = &put_path[failure_offset - 1].pred;
+ put_path += failure_offset;
+ ppl -= failure_offset;
+ truncated = true;
+ ro |= GNUNET_DHT_RO_TRUNCATED;
+ }
+ else
+ {
+ failure_offset -= ppl;
+ if (0 == failure_offset)
+ trunc_peer = &put_path[ppl - 1].pred;
+ else
+ trunc_peer = &get_path[failure_offset - 1].pred;
+ ppl = 0;
+ put_path = NULL;
+ truncated = true;
+ ro |= GNUNET_DHT_RO_TRUNCATED;
+ get_path += failure_offset;
+ get_path_length -= failure_offset;
+ }
}
#endif
- msize = bd->data_size + (get_path_length + ppl)
- * sizeof(struct GNUNET_DHT_PathElement);
- if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
- (get_path_length >
- GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
- (ppl >
- GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
- (bd->data_size > GNUNET_MAX_MESSAGE_SIZE))
+ msize = bd->data_size + sizeof (struct PeerResultMessage);
+ if (msize > GNUNET_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break_op (0);
+ return false;
+ }
+ if (truncated)
+ msize += sizeof (struct GNUNET_PeerIdentity);
+ if (tracking)
+ msize += sizeof (struct GNUNET_CRYPTO_EddsaSignature);
+ if (msize < bd->data_size)
+ {
+ GNUNET_break_op (0);
+ return false;
+ }
+ if ( (GNUNET_MAX_MESSAGE_SIZE - msize)
+ / sizeof(struct GNUNET_DHT_PathElement)
+ < (get_path_length + ppl) )
{
- ppl = 0;
get_path_length = 0;
- msize = bd->data_size + (get_path_length + ppl)
- * sizeof(struct GNUNET_DHT_PathElement);
+ ppl = 0;
}
- if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
- (get_path_length >
- GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
- (ppl >
- GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
- (bd->data_size > GNUNET_MAX_MESSAGE_SIZE))
+ if ( (get_path_length > UINT16_MAX) ||
+ (ppl > UINT16_MAX) )
{
GNUNET_break (0);
- return false;
+ get_path_length = 0;
+ ppl = 0;
}
+ msize += (get_path_length + ppl)
+ * sizeof(struct GNUNET_DHT_PathElement);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Forwarding reply for key %s to peer %s\n",
GNUNET_h2s (query_hash),
@@ -1622,22 +1764,36 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
GNUNET_NO);
{
struct PeerResultMessage *prm;
- char buf[sizeof (*prm) + msize] GNUNET_ALIGN;
+ char buf[msize] GNUNET_ALIGN;
+ void *data;
prm = (struct PeerResultMessage *) buf;
prm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT);
prm->header.size = htons (sizeof (buf));
- prm->type = htonl (bd->type);
- prm->reserved = htonl (0);
- prm->put_path_length = htons (ppl);
- prm->get_path_length = htons (get_path_length);
+ prm->type = htonl ((uint32_t) bd->type);
+ prm->options = htonl ((uint32_t) ro);
+ prm->put_path_length = htons ((uint16_t) ppl);
+ prm->get_path_length = htons ((uint16_t) get_path_length);
prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
prm->key = *query_hash;
- paths = (struct GNUNET_DHT_PathElement *) &prm[1];
- if (NULL != bd->put_path)
+ if (truncated)
+ {
+ void *tgt = &prm[1];
+
+ GNUNET_memcpy (tgt,
+ trunc_peer,
+ sizeof (struct GNUNET_PeerIdentity));
+ paths = (struct GNUNET_DHT_PathElement *)
+ (tgt + sizeof (struct GNUNET_PeerIdentity));
+ }
+ else
+ {
+ paths = (struct GNUNET_DHT_PathElement *) &prm[1];
+ }
+ if (NULL != put_path)
{
GNUNET_memcpy (paths,
- bd->put_path,
+ put_path,
ppl * sizeof(struct GNUNET_DHT_PathElement));
}
else
@@ -1654,51 +1810,69 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
{
GNUNET_assert (0 == get_path_length);
}
- /* 0 == get_path_length+ppl means path is not being tracked */
- if (0 != (get_path_length + ppl))
+ if (tracking)
{
+ struct GNUNET_CRYPTO_EddsaSignature sig;
+ void *tgt = &paths[get_path_length + ppl];
+ const struct GNUNET_PeerIdentity *pred;
+
+ if (ppl + get_path_length > 0)
+ pred = &paths[ppl + get_path_length - 1].pred;
+ else if (truncated)
+ pred = trunc_peer;
+ else
+ pred = NULL; /* we are first! */
/* Note that the last signature in 'paths' was not initialized before,
so this is crucial to avoid sending garbage. */
sign_path (bd->data,
bd->data_size,
bd->expiration_time,
- &paths[ppl + get_path_length - 1].pred,
+ pred,
&pi->id,
- &paths[ppl + get_path_length - 1].sig);
+ &sig);
+ memcpy (tgt,
+ &sig,
+ sizeof (sig));
+ data = tgt + sizeof (sig);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Signing GET PATH %u/%u of %s => %s\n",
ppl,
get_path_length,
GNUNET_h2s (query_hash),
- GNUNET_B2S (&paths[ppl + get_path_length - 1].sig));
- }
- GNUNET_memcpy (&paths[ppl + get_path_length],
- bd->data,
- bd->data_size);
-
+ GNUNET_B2S (&sig));
#if SANITY_CHECKS > 1
- {
- struct GNUNET_DHT_PathElement xpaths[get_path_length + 1];
-
- memcpy (xpaths,
- &paths[ppl],
- get_path_length * sizeof (struct GNUNET_DHT_PathElement));
- xpaths[get_path_length].pred = GDS_my_identity;
- if (0 !=
- GNUNET_DHT_verify_path (bd->data,
- bd->data_size,
- bd->expiration_time,
- paths,
- ppl,
- xpaths,
- get_path_length + 1,
- &pi->id))
{
- GNUNET_break (0);
- return false;
+ struct GNUNET_DHT_PathElement xpaths[get_path_length + 1];
+
+ memcpy (xpaths,
+ &paths[ppl],
+ get_path_length * sizeof (struct GNUNET_DHT_PathElement));
+ xpaths[get_path_length].sig = sig;
+ xpaths[get_path_length].pred = GDS_my_identity;
+ if (0 !=
+ GNUNET_DHT_verify_path (bd->data,
+ bd->data_size,
+ bd->expiration_time,
+ trunc_peer,
+ paths,
+ ppl,
+ xpaths,
+ get_path_length + 1,
+ &pi->id))
+ {
+ GNUNET_break (0);
+ return false;
+ }
}
- }
#endif
+ }
+ else
+ {
+ data = &prm[1];
+ }
+ GNUNET_memcpy (data,
+ bd->data,
+ bd->data_size);
do_send (pi,
&prm->header);
}
@@ -1717,15 +1891,30 @@ static enum GNUNET_GenericReturnValue
check_dht_p2p_put (void *cls,
const struct PeerPutMessage *put)
{
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohs (put->options);
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ bool has_path = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
uint16_t msize = ntohs (put->header.size);
uint16_t putlen = ntohs (put->put_path_length);
+ size_t xsize = (has_path
+ ? sizeof (struct GNUNET_CRYPTO_EddsaSignature)
+ : 0)
+ + (truncated
+ ? sizeof (struct GNUNET_PeerIdentity)
+ : 0);
+ size_t var_meta_size
+ = putlen * sizeof(struct GNUNET_DHT_PathElement)
+ + xsize;
(void) cls;
if ( (msize <
- sizeof(struct PeerPutMessage)
- + putlen * sizeof(struct GNUNET_DHT_PathElement)) ||
+ sizeof (struct PeerPutMessage) + var_meta_size) ||
(putlen >
- GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) )
+ (GNUNET_MAX_MESSAGE_SIZE
+ - sizeof (struct PeerPutMessage)
+ - xsize)
+ / sizeof(struct GNUNET_DHT_PathElement)) )
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -1746,27 +1935,49 @@ handle_dht_p2p_put (void *cls,
{
struct Target *t = cls;
struct PeerInfo *peer = t->pi;
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohs (put->options);
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ bool has_path = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
uint16_t msize = ntohs (put->header.size);
+ uint16_t putlen = ntohs (put->put_path_length);
+ const struct GNUNET_PeerIdentity *trunc_peer
+ = truncated
+ ? (const struct GNUNET_PeerIdentity *) &put[1]
+ : NULL;
const struct GNUNET_DHT_PathElement *put_path
- = (const struct GNUNET_DHT_PathElement *) &put[1];
- uint16_t putlen
- = ntohs (put->put_path_length);
+ = truncated
+ ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
+ : (const struct GNUNET_DHT_PathElement *) &put[1];
+ const struct GNUNET_CRYPTO_EddsaSignature *last_sig
+ = has_path
+ ? (const struct GNUNET_CRYPTO_EddsaSignature *) &put_path[putlen]
+ : NULL;
+ const char *data
+ = has_path
+ ? (const char *) &last_sig[1]
+ : (const char *) &put_path[putlen];
+ size_t var_meta_size
+ = putlen * sizeof(struct GNUNET_DHT_PathElement)
+ + has_path ? sizeof (*last_sig) : 0
+ + truncated ? sizeof (*trunc_peer) : 0;
struct GNUNET_DATACACHE_Block bd = {
.key = put->key,
.expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time),
.type = ntohl (put->type),
- .ro = (enum GNUNET_DHT_RouteOption) ntohs (put->options),
- .data_size = msize - (sizeof(*put)
- + putlen * sizeof(struct GNUNET_DHT_PathElement)),
- .data = &put_path[putlen]
+ .ro = ro,
+ .data_size = msize - sizeof(*put) - var_meta_size,
+ .data = data
};
+ if (NULL != trunc_peer)
+ bd.trunc_peer = *trunc_peer;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"PUT for `%s' from %s with RO (%s/%s)\n",
GNUNET_h2s (&put->key),
GNUNET_i2s (&peer->id),
(bd.ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-",
- (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-");
+ has_path ? "R" : "-");
if (GNUNET_TIME_absolute_is_past (bd.expiration_time))
{
GNUNET_STATISTICS_update (GDS_stats,
@@ -1784,7 +1995,7 @@ handle_dht_p2p_put (void *cls,
GNUNET_break_op (0);
return;
}
- if (0 == (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE))
+ if (! has_path)
putlen = 0;
GNUNET_STATISTICS_update (GDS_stats,
"# P2P PUT requests received",
@@ -1835,7 +2046,7 @@ handle_dht_p2p_put (void *cls,
/* extend 'put path' by sender */
bd.put_path = (const struct GNUNET_DHT_PathElement *) pp;
bd.put_path_length = putlen + 1;
- if (0 != (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE))
+ if (has_path)
{
unsigned int failure_offset;
@@ -1843,10 +2054,7 @@ handle_dht_p2p_put (void *cls,
put_path,
putlen * sizeof(struct GNUNET_DHT_PathElement));
pp[putlen].pred = peer->id;
- /* zero-out signature, not valid until we actually do forward! */
- memset (&pp[putlen].sig,
- 0,
- sizeof (pp[putlen].sig));
+ pp[putlen].sig = *last_sig;
#if SANITY_CHECKS
/* TODO: might want to eventually implement probabilistic
load-based path verification, but for now it is all or nothing */
@@ -1854,6 +2062,7 @@ handle_dht_p2p_put (void *cls,
= GNUNET_DHT_verify_path (bd.data,
bd.data_size,
bd.expiration_time,
+ trunc_peer,
pp,
putlen + 1,
NULL, 0, /* get_path */
@@ -1863,12 +2072,15 @@ handle_dht_p2p_put (void *cls,
#endif
if (0 != failure_offset)
{
+ GNUNET_break_op (0);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Recorded put path invalid at offset %u, truncating\n",
failure_offset);
- GNUNET_assert (failure_offset <= putlen);
+ GNUNET_assert (failure_offset <= putlen + 1);
bd.put_path = &pp[failure_offset];
bd.put_path_length = putlen - failure_offset;
+ bd.ro |= GNUNET_DHT_RO_TRUNCATED;
+ bd.trunc_peer = pp[failure_offset - 1].pred;
}
}
else
@@ -2218,8 +2430,6 @@ handle_dht_p2p_get (void *cls,
type,
hop_count,
desired_replication_level,
- 0,
- NULL,
&get->key);
}
/* clean up; note that 'bg' is owned by routing now! */
@@ -2326,17 +2536,44 @@ handle_dht_p2p_result (void *cls,
{
struct Target *t = cls;
struct PeerInfo *peer = t->pi;
- uint16_t msize = ntohs (prm->header.size);
+ uint16_t msize = ntohs (prm->header.size) - sizeof (*prm);
+ enum GNUNET_DHT_RouteOption ro
+ = (enum GNUNET_DHT_RouteOption) ntohl (prm->options);
+ bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
+ bool tracked = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
uint16_t get_path_length = ntohs (prm->get_path_length);
+ uint16_t put_path_length = ntohs (prm->put_path_length);
+ const struct GNUNET_PeerIdentity *trunc_peer
+ = truncated
+ ? (const struct GNUNET_PeerIdentity *) &prm[1]
+ : NULL;
+ const struct GNUNET_DHT_PathElement *put_path
+ = truncated
+ ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
+ : (const struct GNUNET_DHT_PathElement *) &prm[1];
+ const struct GNUNET_DHT_PathElement *get_path
+ = &put_path[put_path_length];
+ const struct GNUNET_CRYPTO_EddsaSignature *last_sig
+ = tracked
+ ? (const struct GNUNET_CRYPTO_EddsaSignature *) &get_path[get_path_length]
+ : NULL;
+ const void *data
+ = tracked
+ ? (const void *) &last_sig[1]
+ : (const void *) &get_path[get_path_length];
+ size_t vsize = (truncated ? sizeof (struct GNUNET_PeerIdentity) : 0)
+ + (tracked ? sizeof (struct GNUNET_CRYPTO_EddsaSignature) :
0);
struct GNUNET_DATACACHE_Block bd = {
.expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time),
- .put_path = (const struct GNUNET_DHT_PathElement *) &prm[1],
- .put_path_length = ntohs (prm->put_path_length),
+ .put_path = put_path,
+ .put_path_length = put_path_length,
.key = prm->key,
- .type = ntohl (prm->type)
+ .type = ntohl (prm->type),
+ .ro = ro,
+ .data = data,
+ .data_size = msize - vsize - (get_path_length + put_path_length)
+ * sizeof(struct GNUNET_DHT_PathElement)
};
- const struct GNUNET_DHT_PathElement *get_path
- = &bd.put_path[bd.put_path_length];
/* parse and validate message */
if (GNUNET_TIME_absolute_is_past (bd.expiration_time))
@@ -2347,11 +2584,6 @@ handle_dht_p2p_result (void *cls,
GNUNET_NO);
return;
}
- get_path = &bd.put_path[bd.put_path_length];
- bd.data = (const void *) &get_path[get_path_length];
- bd.data_size = msize - (sizeof(struct PeerResultMessage)
- + (get_path_length + bd.put_path_length)
- * sizeof(struct GNUNET_DHT_PathElement));
if (GNUNET_OK !=
GNUNET_BLOCK_check_block (GDS_block_context,
bd.type,
@@ -2385,6 +2617,7 @@ handle_dht_p2p_result (void *cls,
hello_check (&bd);
/* Need to append 'peer' to 'get_path' */
+ if (tracked)
{
struct GNUNET_DHT_PathElement xget_path[get_path_length + 1];
struct GNUNET_DHT_PathElement *gp = xget_path;
@@ -2394,9 +2627,10 @@ handle_dht_p2p_result (void *cls,
get_path,
get_path_length * sizeof(struct GNUNET_DHT_PathElement));
xget_path[get_path_length].pred = peer->id;
- memset (&xget_path[get_path_length].sig,
- 0,
- sizeof (xget_path[get_path_length].sig));
+ /* use memcpy(), as last_sig may not be aligned */
+ memcpy (&xget_path[get_path_length].sig,
+ last_sig,
+ sizeof (*last_sig));
#if SANITY_CHECKS
/* TODO: might want to eventually implement probabilistic
load-based path verification, but for now it is all or nothing */
@@ -2404,9 +2638,10 @@ handle_dht_p2p_result (void *cls,
= GNUNET_DHT_verify_path (bd.data,
bd.data_size,
bd.expiration_time,
- bd.put_path,
- bd.put_path_length,
- xget_path,
+ trunc_peer,
+ put_path,
+ put_path_length,
+ gp,
get_path_length + 1,
&GDS_my_identity);
#else
@@ -2417,30 +2652,59 @@ handle_dht_p2p_result (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Recorded path invalid at offset %u, truncating\n",
failure_offset);
- GNUNET_assert (failure_offset <= bd.put_path_length + get_path_length);
- if (failure_offset >= bd.put_path_length)
- {
- /* failure on get path */
- get_path_length -= (failure_offset - bd.put_path_length);
- gp = &xget_path[failure_offset - bd.put_path_length];
- bd.put_path_length = 0;
- }
- else
+ GNUNET_assert (failure_offset <= bd.put_path_length + get_path_length
+ + 1);
+ if (failure_offset < bd.put_path_length)
{
/* failure on put path */
+ trunc_peer = &bd.put_path[failure_offset - 1].pred;
+ bd.ro |= GNUNET_DHT_RO_TRUNCATED;
bd.put_path = &bd.put_path[failure_offset];
bd.put_path_length -= failure_offset;
+ truncated = true;
+ }
+ else
+ {
+ /* failure on get path */
+ failure_offset -= bd.put_path_length;
+ if (0 == failure_offset)
+ trunc_peer = &bd.put_path[bd.put_path_length - 1].pred;
+ else
+ trunc_peer = &gp[failure_offset - 1].pred;
+ get_path_length -= failure_offset;
+ gp = &gp[failure_offset];
+ bd.put_path_length = 0;
+ bd.put_path = NULL;
+ bd.ro |= GNUNET_DHT_RO_TRUNCATED;
+ truncated = true;
}
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Extending GET path of length %u with %s\n",
get_path_length,
GNUNET_i2s (&peer->id));
+ if (truncated)
+ {
+ GNUNET_assert (NULL != trunc_peer);
+ bd.trunc_peer = *trunc_peer;
+ }
GNUNET_break (process_reply_with_path (&bd,
&prm->key,
get_path_length + 1,
gp));
}
+ else
+ {
+ if (truncated)
+ {
+ GNUNET_assert (NULL != trunc_peer);
+ bd.trunc_peer = *trunc_peer;
+ }
+ GNUNET_break (process_reply_with_path (&bd,
+ &prm->key,
+ 0,
+ NULL));
+ }
}
diff --git a/src/dht/gnunet_dht_profiler.c b/src/dht/gnunet_dht_profiler.c
index bac101bdd..55a34bdf0 100644
--- a/src/dht/gnunet_dht_profiler.c
+++ b/src/dht/gnunet_dht_profiler.c
@@ -455,6 +455,7 @@ cancel_get (void *cls)
* @param cls closure
* @param exp when will this value expire
* @param key key of the result
+ * @param trunc_peer peer the path was truncated at, or NULL
* @param get_path peers on reply path (or NULL if not recorded)
* [0] = datastore's first neighbor, [length - 1] = local peer
* @param get_path_length number of entries in @a get_path
@@ -469,12 +470,14 @@ static void
get_iter (void *cls,
struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
unsigned int put_path_length,
enum GNUNET_BLOCK_Type type,
- size_t size, const void *data)
+ size_t size,
+ const void *data)
{
struct ActiveContext *ac = cls;
struct ActiveContext *get_ac = ac->get_ac;
diff --git a/src/dht/test_dht_api.c b/src/dht/test_dht_api.c
index 4d557bba8..044983b7e 100644
--- a/src/dht/test_dht_api.c
+++ b/src/dht/test_dht_api.c
@@ -87,6 +87,7 @@ static void
test_get_iterator (void *cls,
struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
diff --git a/src/dht/test_dht_monitor.c b/src/dht/test_dht_monitor.c
index 8af02ad8a..3960a2235 100644
--- a/src/dht/test_dht_monitor.c
+++ b/src/dht/test_dht_monitor.c
@@ -163,6 +163,7 @@ timeout_task_cb (void *cls)
* @param cls closure with our 'struct GetOperation'
* @param exp when will this value expire
* @param key key of the result
+ * @param trunc_peer peer the path was truncated at, or NULL
* @param get_path peers on reply path (or NULL if not recorded)
* @param get_path_length number of entries in get_path
* @param put_path peers on the PUT path (or NULL if not recorded)
@@ -174,6 +175,7 @@ timeout_task_cb (void *cls)
static void
dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -189,7 +191,9 @@ dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp,
GNUNET_break (0);
return;
}
- GNUNET_CRYPTO_hash (key, sizeof(*key), &want);
+ GNUNET_CRYPTO_hash (key,
+ sizeof(*key),
+ &want);
if (0 != memcmp (&want, data, sizeof(want)))
{
GNUNET_break (0);
@@ -249,8 +253,6 @@ do_puts (void *cls)
* @param options Options, for instance RecordRoute, DemultiplexEverywhere.
* @param type The type of data in the request.
* @param hop_count Hop count so far.
- * @param path_length number of entries in path (or 0 if not recorded).
- * @param path peers on the GET path (or NULL if not recorded).
* @param desired_replication_level Desired replication level.
* @param key Key of the requested data.
*/
@@ -260,8 +262,6 @@ monitor_get_cb (void *cls,
enum GNUNET_BLOCK_Type type,
uint32_t hop_count,
uint32_t desired_replication_level,
- unsigned int path_length,
- const struct GNUNET_DHT_PathElement *path,
const struct GNUNET_HashCode *key)
{
unsigned int i;
@@ -283,6 +283,7 @@ monitor_get_cb (void *cls,
* @param options Options, for instance RecordRoute, DemultiplexEverywhere.
* @param type The type of data in the request.
* @param hop_count Hop count so far.
+ * @param trunc_peer peer the path was truncated at, or NULL
* @param path_length number of entries in path (or 0 if not recorded).
* @param path peers on the PUT path (or NULL if not recorded).
* @param desired_replication_level Desired replication level.
@@ -297,6 +298,7 @@ monitor_put_cb (void *cls,
enum GNUNET_BLOCK_Type type,
uint32_t hop_count,
uint32_t desired_replication_level,
+ const struct GNUNET_PeerIdentity *trunc_peer,
unsigned int path_length,
const struct GNUNET_DHT_PathElement *path,
struct GNUNET_TIME_Absolute exp,
@@ -322,6 +324,7 @@ monitor_put_cb (void *cls,
*
* @param cls Closure.
* @param type The type of data in the result.
+ * @param trunc_peer peer the path was truncated at, or NULL
* @param get_path Peers on GET path (or NULL if not recorded).
* @param get_path_length number of entries in get_path.
* @param put_path peers on the PUT path (or NULL if not recorded).
@@ -334,6 +337,7 @@ monitor_put_cb (void *cls,
static void
monitor_res_cb (void *cls,
enum GNUNET_BLOCK_Type type,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c
index 4830ba629..a8294c65d 100644
--- a/src/dht/test_dht_topo.c
+++ b/src/dht/test_dht_topo.c
@@ -327,6 +327,7 @@ timeout_cb (void *cls)
* @param cls closure with our 'struct GetOperation'
* @param exp when will this value expire
* @param query query hash
+ * @param trunc_peer peer the path was truncated at, or NULL
* @param get_path peers on reply path (or NULL if not recorded)
* @param get_path_length number of entries in @a get_path
* @param put_path peers on the PUT path (or NULL if not recorded)
@@ -339,6 +340,7 @@ static void
dht_get_handler (void *cls,
struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *query,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -380,6 +382,7 @@ dht_get_handler (void *cls,
GNUNET_DHT_verify_path (data,
size,
exp,
+ trunc_peer,
put_path,
put_path_length,
get_path,
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c
index f05194907..ee2dbca32 100644
--- a/src/fs/gnunet-service-fs_pr.c
+++ b/src/fs/gnunet-service-fs_pr.c
@@ -1077,6 +1077,7 @@ test_put_load_too_high (uint32_t priority)
* @param cls closure
* @param exp when will this value expire
* @param key key of the result
+ * @param trunc_peer truncated peer, NULL for none
* @param get_path peers on reply path (or NULL if not recorded)
* @param get_path_length number of entries in @a get_path
* @param put_path peers on the PUT path (or NULL if not recorded)
@@ -1089,6 +1090,7 @@ static void
handle_dht_reply (void *cls,
struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
diff --git a/src/gns/gnunet-service-gns_resolver.c
b/src/gns/gnunet-service-gns_resolver.c
index 9d26e1777..0d844bc2e 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -1335,7 +1335,6 @@ handle_gns_redirect_result (struct GNS_ResolverHandle *rh,
}
-
/**
* We encountered a CNAME record during our resolution.
* Merge it into our chain.
@@ -1392,7 +1391,6 @@ handle_gns_resolution_result (void *cls,
const struct GNUNET_GNSRECORD_Data *rd);
-
/**
* We have resolved one or more of the nameservers for a
* GNS2DNS lookup. Once we have some of them, begin using
@@ -1592,6 +1590,7 @@ handle_gns2dns_ip (void *cls,
ac->authority_info.dns_authority.found = GNUNET_YES;
}
+
/**
* We found a REDIRECT record, perform recursive resolution on it.
*
@@ -2329,7 +2328,7 @@ handle_gns_resolution_result (void *cls,
_ ("Unable to process critical delegation record\n"));
break;
}
- fail:
+fail:
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_ ("GNS lookup recursion failed (no delegation record
found)\n"));
fail_resolution (rh);
@@ -2370,6 +2369,7 @@ namecache_cache_continuation (void *cls,
* @param cls closure with the `struct GNS_ResolverHandle`
* @param exp when will this value expire
* @param key key of the result
+ * @param trunc_peer truncated peer, NULL if not truncated
* @param get_path peers on reply path (or NULL if not recorded)
* [0] = datastore's first neighbor, [length - 1] = local peer
* @param get_path_length number of entries in @a get_path
@@ -2384,6 +2384,7 @@ static void
handle_dht_response (void *cls,
struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -2552,7 +2553,8 @@ handle_namecache_block_response (void *cls,
else
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Got block with expiration %s\n",
- GNUNET_STRINGS_absolute_time_to_string
(GNUNET_GNSRECORD_block_get_expiration (block)));
+ GNUNET_STRINGS_absolute_time_to_string (
+ GNUNET_GNSRECORD_block_get_expiration (block)));
if (((GNUNET_GNS_LO_DEFAULT == rh->options) ||
((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) &&
(ac != rh->ac_head))) &&
diff --git a/src/include/gnunet_datacache_lib.h
b/src/include/gnunet_datacache_lib.h
index c4d74524a..b4ef346e2 100644
--- a/src/include/gnunet_datacache_lib.h
+++ b/src/include/gnunet_datacache_lib.h
@@ -65,6 +65,12 @@ struct GNUNET_DATACACHE_Block
*/
struct GNUNET_TIME_Absolute expiration_time;
+ /**
+ * If the path was truncated, this is the peer
+ * ID at which the path was truncated.
+ */
+ struct GNUNET_PeerIdentity trunc_peer;
+
/**
* PUT path taken by the block, array of peer identities.
*/
diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h
index d683ae0bf..49a7831e6 100644
--- a/src/include/gnunet_dht_service.h
+++ b/src/include/gnunet_dht_service.h
@@ -268,6 +268,7 @@ GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph);
* @param cls closure
* @param exp when will this value expire
* @param query_hash key of the query
+ * @param trunc_peer peer where the path was truncated, or NULL if the path is
complete
* @param get_path peers on reply path (or NULL if not recorded)
* [0] = datastore's first neighbor, [length - 1] = local peer
* @param get_path_length number of entries in @a get_path
@@ -284,6 +285,7 @@ typedef void
(*GNUNET_DHT_GetIterator) (void *cls,
struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *query_hash,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -359,10 +361,6 @@ struct GNUNET_DHT_MonitorHandle;
* @param options Options, for instance RecordRoute, DemultiplexEverywhere.
* @param type The type of data in the request.
* @param hop_count Hop count so far.
- * @param path_length number of entries in @a path (or 0 if not recorded).
- * @param path peers on the GET path (or NULL if not recorded).
- * note that the last signature will be all zeros as
- * we did not forward and thus did not sign!
* @param desired_replication_level Desired replication level.
* @param key Key of the requested data.
*/
@@ -372,8 +370,6 @@ typedef void
enum GNUNET_BLOCK_Type type,
uint32_t hop_count,
uint32_t desired_replication_level,
- unsigned int path_length,
- const struct GNUNET_DHT_PathElement *path,
const struct GNUNET_HashCode *key);
@@ -382,6 +378,7 @@ typedef void
*
* @param cls Closure.
* @param type The type of data in the result.
+ * @param trunc_peer peer where the path was truncated, or NULL if the path is
complete
* @param get_path Peers on GET path (or NULL if not recorded).
* note that the last signature will be all zeros as
* we did not forward and thus did not sign!
@@ -396,6 +393,7 @@ typedef void
typedef void
(*GNUNET_DHT_MonitorGetRespCB) (void *cls,
enum GNUNET_BLOCK_Type type,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -413,11 +411,12 @@ typedef void
* @param options Options, for instance RecordRoute, DemultiplexEverywhere.
* @param type The type of data in the request.
* @param hop_count Hop count so far.
+ * @param desired_replication_level Desired replication level.
+ * @param trunc_peer peer where the path was truncated, or NULL if the path is
complete
* @param path_length number of entries in @a path (or 0 if not recorded).
* @param path peers on the PUT path (or NULL if not recorded).
* note that the last signature will be all zeros as
* we did not forward and thus did not sign!
- * @param desired_replication_level Desired replication level.
* @param exp Expiration time of the data.
* @param key Key under which data is to be stored.
* @param data Pointer to the data carried.
@@ -429,6 +428,7 @@ typedef void
enum GNUNET_BLOCK_Type type,
uint32_t hop_count,
uint32_t desired_replication_level,
+ const struct GNUNET_PeerIdentity *trunc_peer,
unsigned int path_length,
const struct GNUNET_DHT_PathElement *path,
struct GNUNET_TIME_Absolute exp,
@@ -491,6 +491,8 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path,
* @param data payload (the block)
* @param data_size number of bytes in @a data
* @param exp_time expiration time of @a data
+ * @param trunc_peer peer which signature was broken or where the path was
truncated,
+ * NULL if path is not truncated
* @param get_path array of path elements to verify
* @param get_path_len length of the @a get_path array
* @param put_path array of path elements to verify
@@ -498,12 +500,13 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement
*path,
* @param me our own peer identity (needed to verify the last element)
* @return 0 on success, otherwise the index of
* the last path element that succeeded with verification;
- * @a get_path_len + @a put_path_len - 1 if no signature was valid
+ * @a get_path_len + @a put_path_len if no signature was valid
*/
unsigned int
GNUNET_DHT_verify_path (const void *data,
size_t data_size,
struct GNUNET_TIME_Absolute exp_time,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *put_path,
unsigned int put_path_len,
const struct GNUNET_DHT_PathElement *get_path,
diff --git a/src/pt/gnunet-daemon-pt.c b/src/pt/gnunet-daemon-pt.c
index b79a8e464..67227b97f 100644
--- a/src/pt/gnunet-daemon-pt.c
+++ b/src/pt/gnunet-daemon-pt.c
@@ -1126,6 +1126,7 @@ try_open_exit ()
* @param cls closure
* @param exp when will this value expire
* @param key key of the result
+ * @param trunc_peer peer that was truncated (or NULL if not truncated)
* @param get_path peers on reply path (or NULL if not recorded)
* [0] = datastore's first neighbor, [length - 1] = local peer
* @param get_path_length number of entries in @a get_path
@@ -1140,6 +1141,7 @@ static void
handle_dht_result (void *cls,
struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
diff --git a/src/regex/regex_internal_dht.c b/src/regex/regex_internal_dht.c
index 2248de1f1..e578fba2c 100644
--- a/src/regex/regex_internal_dht.c
+++ b/src/regex/regex_internal_dht.c
@@ -372,6 +372,7 @@ regex_next_edge (const struct RegexBlock *block,
*
* @param cls Closure (search context).
* @param exp When will this value expire.
+ * @param trunc_peer truncated peer, or NULL if none was truncated
* @param key Key of the result.
* @param get_path Path of the get request.
* @param get_path_length Length of get_path.
@@ -384,6 +385,7 @@ regex_next_edge (const struct RegexBlock *block,
static void
dht_get_string_accept_handler (void *cls, struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
@@ -451,6 +453,7 @@ regex_find_path (const struct GNUNET_HashCode *key,
* @param cls closure (search context)
* @param exp when will this value expire
* @param key key of the result
+ * @param trunc_peer NULL if not truncated
* @param get_path path of the get request (not used)
* @param get_path_length length of @a get_path (not used)
* @param put_path path of the put request (not used)
@@ -464,6 +467,7 @@ regex_find_path (const struct GNUNET_HashCode *key,
static void
dht_get_string_handler (void *cls, struct GNUNET_TIME_Absolute exp,
const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *trunc_peer,
const struct GNUNET_DHT_PathElement *get_path,
unsigned int get_path_length,
const struct GNUNET_DHT_PathElement *put_path,
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: implemented new DHT path signing with origin authentication,
gnunet <=