aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cadet/gnunet-service-cadet_dht.c3
-rw-r--r--src/datacache/plugin_datacache_heap.c5
-rw-r--r--src/datacache/plugin_datacache_postgres.c30
-rw-r--r--src/datacache/plugin_datacache_sqlite.c17
-rw-r--r--src/datacache/test_datacache.c6
-rw-r--r--src/datacache/test_datacache_quota.c3
-rw-r--r--src/dht/Makefile.am2
-rw-r--r--src/dht/dht.h27
-rw-r--r--src/dht/dht_api.c308
-rw-r--r--src/dht/gnunet-dht-get.c6
-rw-r--r--src/dht/gnunet-dht-monitor.c8
-rw-r--r--src/dht/gnunet-service-dht.h5
-rw-r--r--src/dht/gnunet-service-dht_clients.c137
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c566
-rw-r--r--src/dht/gnunet_dht_profiler.c5
-rw-r--r--src/dht/test_dht_api.c1
-rw-r--r--src/dht/test_dht_monitor.c14
-rw-r--r--src/dht/test_dht_topo.c3
-rw-r--r--src/fs/gnunet-service-fs_pr.c2
-rw-r--r--src/gns/gnunet-service-gns_resolver.c10
-rw-r--r--src/include/gnunet_datacache_lib.h6
-rw-r--r--src/include/gnunet_dht_service.h19
-rw-r--r--src/pt/gnunet-daemon-pt.c2
-rw-r--r--src/regex/regex_internal_dht.c4
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;
101 * @param cls closure 101 * @param cls closure
102 * @param exp when will this value expire 102 * @param exp when will this value expire
103 * @param key key of the result 103 * @param key key of the result
104 * @param trunc_peer peer preceeding with invalid signature, or NULL
104 * @param get_path path of the get request 105 * @param get_path path of the get request
105 * @param get_path_length length of @a get_path 106 * @param get_path_length length of @a get_path
106 * @param put_path path of the put request 107 * @param put_path path of the put request
@@ -112,6 +113,7 @@ static struct GNUNET_TIME_Relative announce_delay;
112static void 113static void
113dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, 114dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
114 const struct GNUNET_HashCode *key, 115 const struct GNUNET_HashCode *key,
116 const struct GNUNET_PeerIdentity *trunc_peer,
115 const struct GNUNET_DHT_PathElement *get_path, 117 const struct GNUNET_DHT_PathElement *get_path,
116 unsigned int get_path_length, 118 unsigned int get_path_length,
117 const struct GNUNET_DHT_PathElement *put_path, 119 const struct GNUNET_DHT_PathElement *put_path,
@@ -122,6 +124,7 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
122{ 124{
123 const struct GNUNET_HELLO_Message *hello = data; 125 const struct GNUNET_HELLO_Message *hello = data;
124 126
127 (void) trunc_peer;
125 GCPP_try_path_from_dht (get_path, 128 GCPP_try_path_from_dht (get_path,
126 get_path_length, 129 get_path_length,
127 put_path, 130 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,
196 else 196 else
197 val->distance = xor_distance; 197 val->distance = xor_distance;
198 if (0 != block->put_path_length) 198 if (0 != block->put_path_length)
199 val->block.put_path 199 {
200 val->put_path
200 = GNUNET_memdup (block->put_path, 201 = GNUNET_memdup (block->put_path,
201 block->put_path_length 202 block->put_path_length
202 * sizeof (struct GNUNET_DHT_PathElement)); 203 * sizeof (struct GNUNET_DHT_PathElement));
204 val->block.put_path = val->put_path;
205 }
203 (void) GNUNET_CONTAINER_multihashmap_put (plugin->map, 206 (void) GNUNET_CONTAINER_multihashmap_put (plugin->map,
204 &val->block.key, 207 &val->block.key,
205 val, 208 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)
71 "CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn180dc_oid_seq"), 71 "CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn180dc_oid_seq"),
72 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn180dc (" 72 GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn180dc ("
73 " oid OID NOT NULL DEFAULT nextval('gn180dc_oid_seq')," 73 " oid OID NOT NULL DEFAULT nextval('gn180dc_oid_seq'),"
74 " type INTEGER NOT NULL," 74 " type INT4 NOT NULL,"
75 " ro INTEGER NOT NULL," 75 " ro INT4 NOT NULL,"
76 " prox INTEGER NOT NULL," 76 " prox INT4 NOT NULL,"
77 " expiration_time BIGINT NOT NULL," 77 " expiration_time INT8 NOT NULL,"
78 " key BYTEA NOT NULL," 78 " key BYTEA NOT NULL CHECK(LENGTH(key)=64),"
79 " trunc BYTEA NOT NULL CHECK(LENGTH(trunc)=32),"
79 " value BYTEA NOT NULL," 80 " value BYTEA NOT NULL,"
80 " path BYTEA DEFAULT NULL)"), 81 " path BYTEA DEFAULT NULL)"),
81 GNUNET_PQ_make_try_execute ( 82 GNUNET_PQ_make_try_execute (
@@ -93,11 +94,11 @@ init_connection (struct Plugin *plugin)
93 }; 94 };
94 struct GNUNET_PQ_PreparedStatement ps[] = { 95 struct GNUNET_PQ_PreparedStatement ps[] = {
95 GNUNET_PQ_make_prepare ("getkt", 96 GNUNET_PQ_make_prepare ("getkt",
96 "SELECT expiration_time,type,ro,value,path FROM gn180dc " 97 "SELECT expiration_time,type,ro,value,trunc,path FROM gn180dc "
97 "WHERE key=$1 AND type=$2 AND expiration_time >= $3", 98 "WHERE key=$1 AND type=$2 AND expiration_time >= $3",
98 3), 99 3),
99 GNUNET_PQ_make_prepare ("getk", 100 GNUNET_PQ_make_prepare ("getk",
100 "SELECT expiration_time,type,ro,value,path FROM gn180dc " 101 "SELECT expiration_time,type,ro,value,trunc,path FROM gn180dc "
101 "WHERE key=$1 AND expiration_time >= $2", 102 "WHERE key=$1 AND expiration_time >= $2",
102 2), 103 2),
103 GNUNET_PQ_make_prepare ("getex", 104 GNUNET_PQ_make_prepare ("getex",
@@ -110,14 +111,14 @@ init_connection (struct Plugin *plugin)
110 " ORDER BY prox ASC, expiration_time ASC LIMIT 1", 111 " ORDER BY prox ASC, expiration_time ASC LIMIT 1",
111 0), 112 0),
112 GNUNET_PQ_make_prepare ("get_closest", 113 GNUNET_PQ_make_prepare ("get_closest",
113 "(SELECT expiration_time,type,ro,value,path,key FROM gn180dc" 114 "(SELECT expiration_time,type,ro,value,trunc,path,key FROM gn180dc"
114 " WHERE key >= $1" 115 " WHERE key >= $1"
115 " AND expiration_time >= $2" 116 " AND expiration_time >= $2"
116 " AND ( (type = $3) OR ( 0 = $3) )" 117 " AND ( (type = $3) OR ( 0 = $3) )"
117 " ORDER BY key ASC" 118 " ORDER BY key ASC"
118 " LIMIT $4)" 119 " LIMIT $4)"
119 " UNION " 120 " UNION "
120 "(SELECT expiration_time,type,ro,value,path,key FROM gn180dc" 121 "(SELECT expiration_time,type,ro,value,trunc,path,key FROM gn180dc"
121 " WHERE key <= $1" 122 " WHERE key <= $1"
122 " AND expiration_time >= $2" 123 " AND expiration_time >= $2"
123 " AND ( (type = $3) OR ( 0 = $3) )" 124 " AND ( (type = $3) OR ( 0 = $3) )"
@@ -129,9 +130,9 @@ init_connection (struct Plugin *plugin)
129 1), 130 1),
130 GNUNET_PQ_make_prepare ("put", 131 GNUNET_PQ_make_prepare ("put",
131 "INSERT INTO gn180dc" 132 "INSERT INTO gn180dc"
132 " (type, ro, prox, expiration_time, key, value, path) " 133 " (type, ro, prox, expiration_time, key, value, trunc, path) "
133 "VALUES ($1, $2, $3, $4, $5, $6, $7)", 134 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
134 7), 135 8),
135 GNUNET_PQ_PREPARED_STATEMENT_END 136 GNUNET_PQ_PREPARED_STATEMENT_END
136 }; 137 };
137 138
@@ -170,6 +171,7 @@ postgres_plugin_put (void *cls,
170 GNUNET_PQ_query_param_auto_from_type (&block->key), 171 GNUNET_PQ_query_param_auto_from_type (&block->key),
171 GNUNET_PQ_query_param_fixed_size (block->data, 172 GNUNET_PQ_query_param_fixed_size (block->data,
172 block->data_size), 173 block->data_size),
174 GNUNET_PQ_query_param_auto_from_type (&block->trunc_peer),
173 GNUNET_PQ_query_param_fixed_size (block->put_path, 175 GNUNET_PQ_query_param_fixed_size (block->put_path,
174 block->put_path_length 176 block->put_path_length
175 * sizeof(struct GNUNET_DHT_PathElement)), 177 * sizeof(struct GNUNET_DHT_PathElement)),
@@ -243,6 +245,8 @@ handle_results (void *cls,
243 GNUNET_PQ_result_spec_variable_size ("value", 245 GNUNET_PQ_result_spec_variable_size ("value",
244 &data, 246 &data,
245 &block.data_size), 247 &block.data_size),
248 GNUNET_PQ_result_spec_auto_from_type ("trunc",
249 &block.trunc_peer),
246 GNUNET_PQ_result_spec_variable_size ("path", 250 GNUNET_PQ_result_spec_variable_size ("path",
247 &path, 251 &path,
248 &path_size), 252 &path_size),
@@ -465,6 +469,8 @@ extract_result_cb (void *cls,
465 GNUNET_PQ_result_spec_variable_size ("value", 469 GNUNET_PQ_result_spec_variable_size ("value",
466 &data, 470 &data,
467 &block.data_size), 471 &block.data_size),
472 GNUNET_PQ_result_spec_auto_from_type ("trunc",
473 &block.trunc_peer),
468 GNUNET_PQ_result_spec_variable_size ("path", 474 GNUNET_PQ_result_spec_variable_size ("path",
469 &path, 475 &path,
470 &path_size), 476 &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,
207 GNUNET_SQ_query_param_fixed_size (block->put_path, 207 GNUNET_SQ_query_param_fixed_size (block->put_path,
208 block->put_path_length 208 block->put_path_length
209 * sizeof(struct GNUNET_DHT_PathElement)), 209 * sizeof(struct GNUNET_DHT_PathElement)),
210 GNUNET_SQ_query_param_auto_from_type (&block->trunc_peer),
210 GNUNET_SQ_query_param_end 211 GNUNET_SQ_query_param_end
211 }; 212 };
212 213
@@ -290,6 +291,7 @@ get_any (void *cls,
290 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time), 291 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
291 GNUNET_SQ_result_spec_variable_size (&path, 292 GNUNET_SQ_result_spec_variable_size (&path,
292 &path_size), 293 &path_size),
294 GNUNET_SQ_result_spec_auto_from_type (&block.trunc_peer),
293 GNUNET_SQ_result_spec_uint32 (&btype32), 295 GNUNET_SQ_result_spec_uint32 (&btype32),
294 GNUNET_SQ_result_spec_uint32 (&bro32), 296 GNUNET_SQ_result_spec_uint32 (&bro32),
295 GNUNET_SQ_result_spec_end 297 GNUNET_SQ_result_spec_end
@@ -451,6 +453,7 @@ get_typed (void *cls,
451 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time), 453 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
452 GNUNET_SQ_result_spec_variable_size (&path, 454 GNUNET_SQ_result_spec_variable_size (&path,
453 &path_size), 455 &path_size),
456 GNUNET_SQ_result_spec_auto_from_type (&block.trunc_peer),
454 GNUNET_SQ_result_spec_uint32 (&bro32), 457 GNUNET_SQ_result_spec_uint32 (&bro32),
455 GNUNET_SQ_result_spec_end 458 GNUNET_SQ_result_spec_end
456 }; 459 };
@@ -749,6 +752,7 @@ sqlite_plugin_get_closest (void *cls,
749 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time), 752 GNUNET_SQ_result_spec_absolute_time (&block.expiration_time),
750 GNUNET_SQ_result_spec_variable_size (&path, 753 GNUNET_SQ_result_spec_variable_size (&path,
751 &path_size), 754 &path_size),
755 GNUNET_SQ_result_spec_auto_from_type (&block.trunc_peer),
752 GNUNET_SQ_result_spec_uint32 (&rtype32), 756 GNUNET_SQ_result_spec_uint32 (&rtype32),
753 GNUNET_SQ_result_spec_uint32 (&bro32), 757 GNUNET_SQ_result_spec_uint32 (&bro32),
754 GNUNET_SQ_result_spec_auto_from_type (&block.key), 758 GNUNET_SQ_result_spec_auto_from_type (&block.key),
@@ -882,6 +886,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
882 " key BLOB NOT NULL DEFAULT ''," 886 " key BLOB NOT NULL DEFAULT '',"
883 " prox INTEGER NOT NULL," 887 " prox INTEGER NOT NULL,"
884 " value BLOB NOT NULL," 888 " value BLOB NOT NULL,"
889 " trunc BLOB NOT NULL,"
885 " path BLOB DEFAULT '')"); 890 " path BLOB DEFAULT '')");
886 SQLITE3_EXEC (dbh, 891 SQLITE3_EXEC (dbh,
887 "CREATE INDEX idx_hashidx" 892 "CREATE INDEX idx_hashidx"
@@ -900,8 +905,8 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
900 if ((SQLITE_OK != 905 if ((SQLITE_OK !=
901 sq_prepare (plugin->dbh, 906 sq_prepare (plugin->dbh,
902 "INSERT INTO ds180" 907 "INSERT INTO ds180"
903 " (type, ro, expire, key, prox, value, path)" 908 " (type, ro, expire, key, prox, value, path, trunc)"
904 " VALUES (?, ?, ?, ?, ?, ?, ?)", 909 " VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
905 &plugin->insert_stmt)) || 910 &plugin->insert_stmt)) ||
906 (SQLITE_OK != 911 (SQLITE_OK !=
907 sq_prepare (plugin->dbh, 912 sq_prepare (plugin->dbh,
@@ -917,7 +922,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
917 &plugin->get_count_any_stmt)) || 922 &plugin->get_count_any_stmt)) ||
918 (SQLITE_OK != 923 (SQLITE_OK !=
919 sq_prepare (plugin->dbh, 924 sq_prepare (plugin->dbh,
920 "SELECT value,expire,path,ro" 925 "SELECT value,expire,path,trunc,ro"
921 " FROM ds180" 926 " FROM ds180"
922 " WHERE key=?" 927 " WHERE key=?"
923 " AND type=?" 928 " AND type=?"
@@ -926,7 +931,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
926 &plugin->get_stmt)) || 931 &plugin->get_stmt)) ||
927 (SQLITE_OK != 932 (SQLITE_OK !=
928 sq_prepare (plugin->dbh, 933 sq_prepare (plugin->dbh,
929 "SELECT value,expire,path,type,ro" 934 "SELECT value,expire,path,trunc,type,ro"
930 " FROM ds180" 935 " FROM ds180"
931 " WHERE key=?" 936 " WHERE key=?"
932 " AND expire >= ?" 937 " AND expire >= ?"
@@ -950,7 +955,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
950 (SQLITE_OK != 955 (SQLITE_OK !=
951 sq_prepare (plugin->dbh, 956 sq_prepare (plugin->dbh,
952 "SELECT * FROM (" 957 "SELECT * FROM ("
953 " SELECT value,expire,path,type,ro,key" 958 " SELECT value,expire,path,trunc,type,ro,key"
954 " FROM ds180 " 959 " FROM ds180 "
955 " WHERE key>=?1 " 960 " WHERE key>=?1 "
956 " AND expire >= ?2" 961 " AND expire >= ?2"
@@ -958,7 +963,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
958 " ORDER BY KEY ASC LIMIT ?4)" 963 " ORDER BY KEY ASC LIMIT ?4)"
959 "UNION " 964 "UNION "
960 "SELECT * FROM (" 965 "SELECT * FROM ("
961 " SELECT value,expire,path,type,ro,key" 966 " SELECT value,expire,path,trunc,type,ro,key"
962 " FROM ds180 " 967 " FROM ds180 "
963 " WHERE key<=?1 " 968 " WHERE key<=?1 "
964 " AND expire >= ?2" 969 " 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,
97 block.key = k; 97 block.key = k;
98 block.data = &n; 98 block.data = &n;
99 block.data_size = sizeof (n); 99 block.data_size = sizeof (n);
100 memset (&block.trunc_peer,
101 43,
102 sizeof (block.trunc_peer));
100 block.ro = 42; 103 block.ro = 42;
101 block.type = (enum GNUNET_BLOCK_Type) (1 + i % 16); 104 block.type = (enum GNUNET_BLOCK_Type) (1 + i % 16);
102 block.put_path = NULL; 105 block.put_path = NULL;
@@ -134,6 +137,9 @@ run (void *cls,
134 block.data = &n; 137 block.data = &n;
135 block.data_size = sizeof (n); 138 block.data_size = sizeof (n);
136 block.ro = 42; 139 block.ro = 42;
140 memset (&block.trunc_peer,
141 44,
142 sizeof (block.trunc_peer));
137 block.type = (enum GNUNET_BLOCK_Type) 792; 143 block.type = (enum GNUNET_BLOCK_Type) 792;
138 block.put_path = NULL; 144 block.put_path = NULL;
139 block.put_path_length = 0; 145 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,
92 block.key = k; 92 block.key = k;
93 block.data = buf; 93 block.data = buf;
94 block.data_size = j; 94 block.data_size = j;
95 memset (&block.trunc_peer,
96 43,
97 sizeof (block.trunc_peer));
95 block.ro = 42; 98 block.ro = 42;
96 block.type = (enum GNUNET_BLOCK_Type) (1 + i); 99 block.type = (enum GNUNET_BLOCK_Type) (1 + i);
97 block.put_path = NULL; 100 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 = \
26 $(LTLIBINTL) 26 $(LTLIBINTL)
27libgnunetdht_la_LDFLAGS = \ 27libgnunetdht_la_LDFLAGS = \
28 $(GN_LIB_LDFLAGS) \ 28 $(GN_LIB_LDFLAGS) \
29 -version-info 3:0:0 29 -version-info 4:0:0
30 30
31 31
32plugin_LTLIBRARIES = \ 32plugin_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
@@ -153,6 +153,16 @@ struct GNUNET_DHT_ClientResultMessage
153 uint32_t type GNUNET_PACKED; 153 uint32_t type GNUNET_PACKED;
154 154
155 /** 155 /**
156 * Reserved, always 0.
157 */
158 uint32_t reserved GNUNET_PACKED;
159
160 /**
161 * Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
162 */
163 uint32_t options GNUNET_PACKED;
164
165 /**
156 * Number of peers recorded in the outgoing path from source to the 166 * Number of peers recorded in the outgoing path from source to the
157 * storgage location of this message. 167 * storgage location of this message.
158 */ 168 */
@@ -179,7 +189,7 @@ struct GNUNET_DHT_ClientResultMessage
179 */ 189 */
180 struct GNUNET_HashCode key GNUNET_PACKED; 190 struct GNUNET_HashCode key GNUNET_PACKED;
181 191
182 /* put path, get path and actual data are copied to end of this dealy do */ 192 /* trunc_peer, put path, get path and actual data are copied to end of this dealy do */
183}; 193};
184 194
185 195
@@ -348,10 +358,9 @@ struct GNUNET_DHT_MonitorGetMessage
348 uint32_t desired_replication_level GNUNET_PACKED; 358 uint32_t desired_replication_level GNUNET_PACKED;
349 359
350 /** 360 /**
351 * Number of peers recorded in the outgoing path from source to the 361 * Always zero.
352 * storage location of this message.
353 */ 362 */
354 uint32_t get_path_length GNUNET_PACKED; 363 uint32_t reserved GNUNET_PACKED;
355 364
356 /** 365 /**
357 * The key to store the value under. 366 * The key to store the value under.
@@ -377,6 +386,16 @@ struct GNUNET_DHT_MonitorGetRespMessage
377 uint32_t type GNUNET_PACKED; 386 uint32_t type GNUNET_PACKED;
378 387
379 /** 388 /**
389 * Reserved, always 0.
390 */
391 uint32_t reserved GNUNET_PACKED;
392
393 /**
394 * Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
395 */
396 uint32_t options GNUNET_PACKED;
397
398 /**
380 * Length of the PUT path that follows (if tracked). 399 * Length of the PUT path that follows (if tracked).
381 */ 400 */
382 uint32_t put_path_length GNUNET_PACKED; 401 uint32_t put_path_length GNUNET_PACKED;
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
@@ -526,31 +526,6 @@ mq_error_handler (void *cls,
526 526
527 527
528/** 528/**
529 * Verify integrity of a get monitor message from the service.
530 *
531 * @param cls The DHT handle.
532 * @param msg Monitor get message from the service.
533 * @return #GNUNET_OK if everything went fine,
534 * #GNUNET_SYSERR if the message is malformed.
535 */
536static enum GNUNET_GenericReturnValue
537check_monitor_get (void *cls,
538 const struct GNUNET_DHT_MonitorGetMessage *msg)
539{
540 uint32_t plen = ntohl (msg->get_path_length);
541 uint16_t msize = ntohs (msg->header.size) - sizeof(*msg);
542
543 if ((plen > UINT16_MAX) ||
544 (plen * sizeof(struct GNUNET_DHT_PathElement) != msize))
545 {
546 GNUNET_break (0);
547 return GNUNET_SYSERR;
548 }
549 return GNUNET_OK;
550}
551
552
553/**
554 * Process a get monitor message from the service. 529 * Process a get monitor message from the service.
555 * 530 *
556 * @param cls The DHT handle. 531 * @param cls The DHT handle.
@@ -561,6 +536,8 @@ handle_monitor_get (void *cls,
561 const struct GNUNET_DHT_MonitorGetMessage *msg) 536 const struct GNUNET_DHT_MonitorGetMessage *msg)
562{ 537{
563 struct GNUNET_DHT_Handle *handle = cls; 538 struct GNUNET_DHT_Handle *handle = cls;
539 enum GNUNET_DHT_RouteOption ro
540 = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
564 541
565 for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head; 542 for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
566 NULL != mh; 543 NULL != mh;
@@ -568,20 +545,19 @@ handle_monitor_get (void *cls,
568 { 545 {
569 if (NULL == mh->get_cb) 546 if (NULL == mh->get_cb)
570 continue; 547 continue;
571 if (((GNUNET_BLOCK_TYPE_ANY == mh->type) || 548 if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
572 (mh->type == ntohl (msg->type))) && 549 (mh->type != ntohl (msg->type)))
573 ((NULL == mh->key) || 550 continue;
574 (0 == memcmp (mh->key, 551 if ( (NULL != mh->key) &&
575 &msg->key, 552 (0 != GNUNET_memcmp (mh->key,
576 sizeof(struct GNUNET_HashCode))))) 553 &msg->key)) )
577 mh->get_cb (mh->cb_cls, 554 continue;
578 ntohl (msg->options), 555 mh->get_cb (mh->cb_cls,
579 (enum GNUNET_BLOCK_Type) ntohl (msg->type), 556 ro,
580 ntohl (msg->hop_count), 557 (enum GNUNET_BLOCK_Type) ntohl (msg->type),
581 ntohl (msg->desired_replication_level), 558 ntohl (msg->hop_count),
582 ntohl (msg->get_path_length), 559 ntohl (msg->desired_replication_level),
583 (struct GNUNET_DHT_PathElement *) &msg[1], 560 &msg->key);
584 &msg->key);
585 } 561 }
586} 562}
587 563
@@ -601,7 +577,19 @@ check_monitor_get_resp (void *cls,
601 size_t msize = ntohs (msg->header.size) - sizeof(*msg); 577 size_t msize = ntohs (msg->header.size) - sizeof(*msg);
602 uint32_t getl = ntohl (msg->get_path_length); 578 uint32_t getl = ntohl (msg->get_path_length);
603 uint32_t putl = ntohl (msg->put_path_length); 579 uint32_t putl = ntohl (msg->put_path_length);
580 enum GNUNET_DHT_RouteOption ro
581 = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
582 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
604 583
584 if (truncated)
585 {
586 if (msize < sizeof (struct GNUNET_PeerIdentity))
587 {
588 GNUNET_break (0);
589 return GNUNET_SYSERR;
590 }
591 msize -= sizeof (struct GNUNET_PeerIdentity);
592 }
605 if ((getl + putl < getl) || 593 if ((getl + putl < getl) ||
606 ((msize / sizeof(struct GNUNET_DHT_PathElement)) < getl + putl)) 594 ((msize / sizeof(struct GNUNET_DHT_PathElement)) < getl + putl))
607 { 595 {
@@ -624,35 +612,47 @@ handle_monitor_get_resp (void *cls,
624{ 612{
625 struct GNUNET_DHT_Handle *handle = cls; 613 struct GNUNET_DHT_Handle *handle = cls;
626 size_t msize = ntohs (msg->header.size) - sizeof(*msg); 614 size_t msize = ntohs (msg->header.size) - sizeof(*msg);
627 const struct GNUNET_DHT_PathElement *path; 615 enum GNUNET_DHT_RouteOption ro
616 = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
628 uint32_t getl = ntohl (msg->get_path_length); 617 uint32_t getl = ntohl (msg->get_path_length);
629 uint32_t putl = ntohl (msg->put_path_length); 618 uint32_t putl = ntohl (msg->put_path_length);
630 619 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
631 620 const struct GNUNET_PeerIdentity *trunc_peer
632 path = (const struct GNUNET_DHT_PathElement *) &msg[1]; 621 = truncated
622 ? (const struct GNUNET_PeerIdentity *) &msg[1]
623 : NULL;
624 const struct GNUNET_DHT_PathElement *path
625 = truncated
626 ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
627 : (const struct GNUNET_DHT_PathElement *) &msg[1];
628
629 if (truncated)
630 msize -= sizeof (struct GNUNET_PeerIdentity);
631 msize -= sizeof(struct GNUNET_DHT_PathElement) * (putl + getl);
633 for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head; 632 for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
634 NULL != mh; 633 NULL != mh;
635 mh = mh->next) 634 mh = mh->next)
636 { 635 {
637 if (NULL == mh->get_resp_cb) 636 if (NULL == mh->get_resp_cb)
638 continue; 637 continue;
639 if (((GNUNET_BLOCK_TYPE_ANY == mh->type) || 638 if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
640 (mh->type == ntohl (msg->type))) && 639 (mh->type != ntohl (msg->type)) )
641 ((NULL == mh->key) || 640 continue;
642 (0 == memcmp (mh->key, 641 if ( (NULL != mh->key) &&
643 &msg->key, 642 (0 != GNUNET_memcmp (mh->key,
644 sizeof(struct GNUNET_HashCode))))) 643 &msg->key)) )
645 mh->get_resp_cb (mh->cb_cls, 644 continue;
646 (enum GNUNET_BLOCK_Type) ntohl (msg->type), 645 mh->get_resp_cb (mh->cb_cls,
647 &path[putl], 646 (enum GNUNET_BLOCK_Type) ntohl (msg->type),
648 getl, 647 trunc_peer,
649 path, 648 &path[putl],
650 putl, 649 getl,
651 GNUNET_TIME_absolute_ntoh (msg->expiration_time), 650 path,
652 &msg->key, 651 putl,
653 (const void *) &path[getl + putl], 652 GNUNET_TIME_absolute_ntoh (msg->expiration_time),
654 msize - sizeof(struct GNUNET_DHT_PathElement) * (putl 653 &msg->key,
655 + getl)); 654 (const void *) &path[getl + putl],
655 msize);
656 } 656 }
657} 657}
658 658
@@ -669,11 +669,21 @@ static enum GNUNET_GenericReturnValue
669check_monitor_put (void *cls, 669check_monitor_put (void *cls,
670 const struct GNUNET_DHT_MonitorPutMessage *msg) 670 const struct GNUNET_DHT_MonitorPutMessage *msg)
671{ 671{
672 size_t msize; 672 size_t msize = ntohs (msg->header.size) - sizeof(*msg);
673 uint32_t putl; 673 uint32_t putl = ntohl (msg->put_path_length);
674 enum GNUNET_DHT_RouteOption ro
675 = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
676 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
674 677
675 msize = ntohs (msg->header.size) - sizeof(*msg); 678 if (truncated)
676 putl = ntohl (msg->put_path_length); 679 {
680 if (msize < sizeof (struct GNUNET_PeerIdentity))
681 {
682 GNUNET_break (0);
683 return GNUNET_SYSERR;
684 }
685 msize -= sizeof (struct GNUNET_PeerIdentity);
686 }
677 if ((msize / sizeof(struct GNUNET_DHT_PathElement)) < putl) 687 if ((msize / sizeof(struct GNUNET_DHT_PathElement)) < putl)
678 { 688 {
679 GNUNET_break (0); 689 GNUNET_break (0);
@@ -696,31 +706,46 @@ handle_monitor_put (void *cls,
696 struct GNUNET_DHT_Handle *handle = cls; 706 struct GNUNET_DHT_Handle *handle = cls;
697 size_t msize = ntohs (msg->header.size) - sizeof(*msg); 707 size_t msize = ntohs (msg->header.size) - sizeof(*msg);
698 uint32_t putl = ntohl (msg->put_path_length); 708 uint32_t putl = ntohl (msg->put_path_length);
699 const struct GNUNET_DHT_PathElement *path; 709 enum GNUNET_DHT_RouteOption ro
700 struct GNUNET_DHT_MonitorHandle *mh; 710 = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
701 711 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
702 path = (const struct GNUNET_DHT_PathElement *) &msg[1]; 712 const struct GNUNET_PeerIdentity *trunc_peer
703 for (mh = handle->monitor_head; NULL != mh; mh = mh->next) 713 = truncated
714 ? (const struct GNUNET_PeerIdentity *) &msg[1]
715 : NULL;
716 const struct GNUNET_DHT_PathElement *path
717 = truncated
718 ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
719 : (const struct GNUNET_DHT_PathElement *) &msg[1];
720
721 if (truncated)
722 msize -= sizeof (struct GNUNET_PeerIdentity);
723 msize -= sizeof(struct GNUNET_DHT_PathElement) * putl;
724 for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
725 NULL != mh;
726 mh = mh->next)
704 { 727 {
705 if (NULL == mh->put_cb) 728 if (NULL == mh->put_cb)
706 continue; 729 continue;
707 if (((GNUNET_BLOCK_TYPE_ANY == mh->type) || 730 if ( (GNUNET_BLOCK_TYPE_ANY != mh->type) &&
708 (mh->type == ntohl (msg->type))) && 731 (mh->type != ntohl (msg->type)) )
709 ((NULL == mh->key) || 732 continue;
710 (0 == memcmp (mh->key, 733 if ( (NULL != mh->key) &&
711 &msg->key, 734 (0 != GNUNET_memcmp (mh->key,
712 sizeof(struct GNUNET_HashCode))))) 735 &msg->key)) )
713 mh->put_cb (mh->cb_cls, 736 continue;
714 ntohl (msg->options), 737 mh->put_cb (mh->cb_cls,
715 (enum GNUNET_BLOCK_Type) ntohl (msg->type), 738 ro,
716 ntohl (msg->hop_count), 739 (enum GNUNET_BLOCK_Type) ntohl (msg->type),
717 ntohl (msg->desired_replication_level), 740 ntohl (msg->hop_count),
718 putl, 741 ntohl (msg->desired_replication_level),
719 path, 742 trunc_peer,
720 GNUNET_TIME_absolute_ntoh (msg->expiration_time), 743 putl,
721 &msg->key, 744 path,
722 (const void *) &path[putl], 745 GNUNET_TIME_absolute_ntoh (msg->expiration_time),
723 msize - sizeof(struct GNUNET_DHT_PathElement) * putl); 746 &msg->key,
747 (const void *) &path[putl],
748 msize);
724 } 749 }
725} 750}
726 751
@@ -740,15 +765,25 @@ check_client_result (void *cls,
740 size_t msize = ntohs (msg->header.size) - sizeof(*msg); 765 size_t msize = ntohs (msg->header.size) - sizeof(*msg);
741 uint32_t put_path_length = ntohl (msg->put_path_length); 766 uint32_t put_path_length = ntohl (msg->put_path_length);
742 uint32_t get_path_length = ntohl (msg->get_path_length); 767 uint32_t get_path_length = ntohl (msg->get_path_length);
768 enum GNUNET_DHT_RouteOption ro
769 = (enum GNUNET_DHT_RouteOption) ntohl (msg->options);
770 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
743 size_t meta_length; 771 size_t meta_length;
744 772
745 meta_length = 773 if (truncated)
746 sizeof(struct GNUNET_DHT_PathElement) * (get_path_length + put_path_length); 774 {
747 if ((msize < meta_length) || 775 if (msize < sizeof (struct GNUNET_PeerIdentity))
748 (get_path_length > 776 {
749 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) || 777 GNUNET_break (0);
750 (put_path_length > 778 return GNUNET_SYSERR;
751 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement))) 779 }
780 msize -= sizeof (struct GNUNET_PeerIdentity);
781 }
782 meta_length = msize / sizeof(struct GNUNET_DHT_PathElement);
783 if ( (get_path_length + put_path_length >
784 meta_length) ||
785 (get_path_length + put_path_length <
786 get_path_length) )
752 { 787 {
753 GNUNET_break (0); 788 GNUNET_break (0);
754 return GNUNET_SYSERR; 789 return GNUNET_SYSERR;
@@ -774,21 +809,35 @@ process_client_result (void *cls,
774 struct GNUNET_DHT_GetHandle *get_handle = value; 809 struct GNUNET_DHT_GetHandle *get_handle = value;
775 size_t msize = ntohs (crm->header.size) - sizeof(*crm); 810 size_t msize = ntohs (crm->header.size) - sizeof(*crm);
776 uint16_t type = ntohl (crm->type); 811 uint16_t type = ntohl (crm->type);
777 uint32_t put_path_length = ntohl (crm->put_path_length); 812 enum GNUNET_DHT_RouteOption ro
778 uint32_t get_path_length = ntohl (crm->get_path_length); 813 = (enum GNUNET_DHT_RouteOption) ntohl (crm->options);
814 bool truncated
815 = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
816 uint32_t put_path_length
817 = ntohl (crm->put_path_length);
818 uint32_t get_path_length
819 = ntohl (crm->get_path_length);
820 const struct GNUNET_PeerIdentity *trunc_peer
821 = truncated
822 ? (const struct GNUNET_PeerIdentity *) &crm[1]
823 : NULL;
779 const struct GNUNET_DHT_PathElement *put_path 824 const struct GNUNET_DHT_PathElement *put_path
780 = (const struct GNUNET_DHT_PathElement *) &crm[1]; 825 = truncated
826 ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
827 : (const struct GNUNET_DHT_PathElement *) &crm[1];
781 const struct GNUNET_DHT_PathElement *get_path 828 const struct GNUNET_DHT_PathElement *get_path
782 = &put_path[put_path_length]; 829 = &put_path[put_path_length];
783 const void *data 830 const void *data
784 = &get_path[get_path_length]; 831 = &get_path[get_path_length];
785 size_t meta_length 832 size_t meta_length
786 = sizeof(struct GNUNET_DHT_PathElement) * (get_path_length 833 = sizeof(struct GNUNET_DHT_PathElement)
787 + put_path_length); 834 * (get_path_length + put_path_length);
788 size_t data_length 835 size_t data_length
789 = msize - meta_length; 836 = msize - meta_length;
790 struct GNUNET_HashCode hc; 837 struct GNUNET_HashCode hc;
791 838
839 if (truncated)
840 data_length -= sizeof (struct GNUNET_PeerIdentity);
792 if (crm->unique_id != get_handle->unique_id) 841 if (crm->unique_id != get_handle->unique_id)
793 { 842 {
794 /* UID mismatch */ 843 /* UID mismatch */
@@ -837,6 +886,7 @@ process_client_result (void *cls,
837 get_handle->iter (get_handle->iter_cls, 886 get_handle->iter (get_handle->iter_cls,
838 GNUNET_TIME_absolute_ntoh (crm->expiration), 887 GNUNET_TIME_absolute_ntoh (crm->expiration),
839 key, 888 key,
889 trunc_peer,
840 get_path, 890 get_path,
841 get_path_length, 891 get_path_length,
842 put_path, 892 put_path,
@@ -945,10 +995,10 @@ static enum GNUNET_GenericReturnValue
945try_connect (struct GNUNET_DHT_Handle *h) 995try_connect (struct GNUNET_DHT_Handle *h)
946{ 996{
947 struct GNUNET_MQ_MessageHandler handlers[] = { 997 struct GNUNET_MQ_MessageHandler handlers[] = {
948 GNUNET_MQ_hd_var_size (monitor_get, 998 GNUNET_MQ_hd_fixed_size (monitor_get,
949 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET, 999 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET,
950 struct GNUNET_DHT_MonitorGetMessage, 1000 struct GNUNET_DHT_MonitorGetMessage,
951 h), 1001 h),
952 GNUNET_MQ_hd_var_size (monitor_get_resp, 1002 GNUNET_MQ_hd_var_size (monitor_get_resp,
953 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP, 1003 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP,
954 struct GNUNET_DHT_MonitorGetRespMessage, 1004 struct GNUNET_DHT_MonitorGetRespMessage,
@@ -1303,19 +1353,19 @@ unsigned int
1303GNUNET_DHT_verify_path (const void *data, 1353GNUNET_DHT_verify_path (const void *data,
1304 size_t data_size, 1354 size_t data_size,
1305 struct GNUNET_TIME_Absolute exp_time, 1355 struct GNUNET_TIME_Absolute exp_time,
1356 const struct GNUNET_PeerIdentity *bpid,
1306 const struct GNUNET_DHT_PathElement *put_path, 1357 const struct GNUNET_DHT_PathElement *put_path,
1307 unsigned int put_path_len, 1358 unsigned int put_path_len,
1308 const struct GNUNET_DHT_PathElement *get_path, 1359 const struct GNUNET_DHT_PathElement *get_path,
1309 unsigned int get_path_len, 1360 unsigned int get_path_len,
1310 const struct GNUNET_PeerIdentity *me) 1361 const struct GNUNET_PeerIdentity *me)
1311{ 1362{
1363 static struct GNUNET_PeerIdentity zero;
1312 struct GNUNET_DHT_HopSignature hs = { 1364 struct GNUNET_DHT_HopSignature hs = {
1313 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), 1365 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP),
1314 .purpose.size = htonl (sizeof (hs)), 1366 .purpose.size = htonl (sizeof (hs)),
1315 .expiration_time = GNUNET_TIME_absolute_hton (exp_time) 1367 .expiration_time = GNUNET_TIME_absolute_hton (exp_time)
1316 }; 1368 };
1317 const struct GNUNET_PeerIdentity *pred;
1318 const struct GNUNET_PeerIdentity *succ;
1319 unsigned int i; 1369 unsigned int i;
1320 1370
1321 if (0 == get_path_len + put_path_len) 1371 if (0 == get_path_len + put_path_len)
@@ -1336,38 +1386,56 @@ GNUNET_DHT_verify_path (const void *data,
1336 j, 1386 j,
1337 GNUNET_i2s (&get_path[j].pred)); 1387 GNUNET_i2s (&get_path[j].pred));
1338 1388
1339 i = put_path_len + get_path_len - 1;
1340 GNUNET_CRYPTO_hash (data, 1389 GNUNET_CRYPTO_hash (data,
1341 data_size, 1390 data_size,
1342 &hs.h_data); 1391 &hs.h_data);
1392 i = put_path_len + get_path_len;
1343 while (i > 0) 1393 while (i > 0)
1344 { 1394 {
1345 pred = (i - 1 >= put_path_len) 1395 const struct GNUNET_PeerIdentity *pred;
1346 ? &get_path[i - put_path_len - 1].pred 1396 const struct GNUNET_PeerIdentity *succ;
1347 : &put_path[i - 1].pred; 1397 const struct GNUNET_DHT_PathElement *pe;
1348 if (i + 1 == get_path_len + put_path_len) 1398
1399 i--;
1400 if (0 == i)
1401 {
1402 pred = (NULL == bpid) ? &zero : bpid;
1403 }
1404 else
1405 {
1406 unsigned int off = i - 1;
1407
1408 pred = (off >= put_path_len)
1409 ? &get_path[off - put_path_len].pred
1410 : &put_path[off].pred;
1411 }
1412 if (i == get_path_len + put_path_len - 1)
1413 {
1349 succ = me; 1414 succ = me;
1415 }
1350 else 1416 else
1351 succ = (i + 1 >= put_path_len) 1417 {
1352 ? &get_path[i + 1 - put_path_len].pred 1418 unsigned int off = i + 1;
1353 : &put_path[i + 1].pred; 1419
1420 succ = (off >= put_path_len)
1421 ? &get_path[off - put_path_len].pred
1422 : &put_path[off].pred;
1423 }
1354 hs.pred = *pred; 1424 hs.pred = *pred;
1355 hs.succ = *succ; 1425 hs.succ = *succ;
1426 pe = (i >= put_path_len)
1427 ? &get_path[i - put_path_len]
1428 : &put_path[i];
1356 if (GNUNET_OK != 1429 if (GNUNET_OK !=
1357 GNUNET_CRYPTO_eddsa_verify ( 1430 GNUNET_CRYPTO_eddsa_verify (
1358 GNUNET_SIGNATURE_PURPOSE_DHT_HOP, 1431 GNUNET_SIGNATURE_PURPOSE_DHT_HOP,
1359 &hs, 1432 &hs,
1360 (i - 1 >= put_path_len) 1433 &pe->sig,
1361 ? &get_path[i - put_path_len - 1].sig 1434 &pe->pred.public_key))
1362 : &put_path[i - 1].sig,
1363 (i >= put_path_len)
1364 ? &get_path[i - put_path_len].pred.public_key
1365 : &put_path[i].pred.public_key))
1366 { 1435 {
1367 GNUNET_break_op (0); 1436 GNUNET_break_op (0);
1368 return i; 1437 return i + 1;
1369 } 1438 }
1370 i--;
1371 } 1439 }
1372 return i; 1440 return i;
1373} 1441}
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)
139 * @param cls closure 139 * @param cls closure
140 * @param exp when will this value expire 140 * @param exp when will this value expire
141 * @param key key of the result 141 * @param key key of the result
142 * @param trunc_peer peer at which the path was truncated, or NULL if not
142 * @param get_path peers on reply path (or NULL if not recorded) 143 * @param get_path peers on reply path (or NULL if not recorded)
143 * @param get_path_length number of entries in get_path 144 * @param get_path_length number of entries in get_path
144 * @param put_path peers on the PUT path (or NULL if not recorded) 145 * @param put_path peers on the PUT path (or NULL if not recorded)
@@ -151,6 +152,7 @@ static void
151get_result_iterator (void *cls, 152get_result_iterator (void *cls,
152 struct GNUNET_TIME_Absolute exp, 153 struct GNUNET_TIME_Absolute exp,
153 const struct GNUNET_HashCode *key, 154 const struct GNUNET_HashCode *key,
155 const struct GNUNET_PeerIdentity *trunc_peer,
154 const struct GNUNET_DHT_PathElement *get_path, 156 const struct GNUNET_DHT_PathElement *get_path,
155 unsigned int get_path_length, 157 unsigned int get_path_length,
156 const struct GNUNET_DHT_PathElement *put_path, 158 const struct GNUNET_DHT_PathElement *put_path,
@@ -183,6 +185,10 @@ get_result_iterator (void *cls,
183 "%s%s", 185 "%s%s",
184 (0 == i) ? "" : "-", 186 (0 == i) ? "" : "-",
185 GNUNET_i2s (&put_path[i].pred)); 187 GNUNET_i2s (&put_path[i].pred));
188 if (NULL != trunc_peer)
189 fprintf (stdout,
190 "T%s",
191 GNUNET_i2s (trunc_peer));
186 fprintf (stdout, 192 fprintf (stdout,
187 "\n"); 193 "\n");
188 } 194 }
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)
125 * @param options Options, for instance RecordRoute, DemultiplexEverywhere. 125 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
126 * @param type The type of data in the request. 126 * @param type The type of data in the request.
127 * @param hop_count Hop count so far. 127 * @param hop_count Hop count so far.
128 * @param path_length number of entries in path (or 0 if not recorded).
129 * @param path peers on the GET path (or NULL if not recorded).
130 * @param desired_replication_level Desired replication level. 128 * @param desired_replication_level Desired replication level.
131 * @param key Key of the requested data. 129 * @param key Key of the requested data.
132 */ 130 */
@@ -136,8 +134,6 @@ get_callback (void *cls,
136 enum GNUNET_BLOCK_Type type, 134 enum GNUNET_BLOCK_Type type,
137 uint32_t hop_count, 135 uint32_t hop_count,
138 uint32_t desired_replication_level, 136 uint32_t desired_replication_level,
139 unsigned int path_length,
140 const struct GNUNET_DHT_PathElement *path,
141 const struct GNUNET_HashCode *key) 137 const struct GNUNET_HashCode *key)
142{ 138{
143 fprintf (stdout, 139 fprintf (stdout,
@@ -154,6 +150,7 @@ get_callback (void *cls,
154 * 150 *
155 * @param cls Closure. 151 * @param cls Closure.
156 * @param type The type of data in the result. 152 * @param type The type of data in the result.
153 * @param trunc_peer peer where the path was truncated, or NULL if the path is complete
157 * @param get_path Peers on GET path (or NULL if not recorded). 154 * @param get_path Peers on GET path (or NULL if not recorded).
158 * @param get_path_length number of entries in get_path. 155 * @param get_path_length number of entries in get_path.
159 * @param put_path peers on the PUT path (or NULL if not recorded). 156 * @param put_path peers on the PUT path (or NULL if not recorded).
@@ -166,6 +163,7 @@ get_callback (void *cls,
166static void 163static void
167get_resp_callback (void *cls, 164get_resp_callback (void *cls,
168 enum GNUNET_BLOCK_Type type, 165 enum GNUNET_BLOCK_Type type,
166 const struct GNUNET_PeerIdentity *trunc_peer,
169 const struct GNUNET_DHT_PathElement *get_path, 167 const struct GNUNET_DHT_PathElement *get_path,
170 unsigned int get_path_length, 168 unsigned int get_path_length,
171 const struct GNUNET_DHT_PathElement *put_path, 169 const struct GNUNET_DHT_PathElement *put_path,
@@ -196,6 +194,7 @@ get_resp_callback (void *cls,
196 * @param options Options, for instance RecordRoute, DemultiplexEverywhere. 194 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
197 * @param type The type of data in the request. 195 * @param type The type of data in the request.
198 * @param hop_count Hop count so far. 196 * @param hop_count Hop count so far.
197 * @param trunc_peer peer where the path was truncated, or NULL if the path is complete
199 * @param path_length number of entries in path (or 0 if not recorded). 198 * @param path_length number of entries in path (or 0 if not recorded).
200 * @param path peers on the PUT path (or NULL if not recorded). 199 * @param path peers on the PUT path (or NULL if not recorded).
201 * @param desired_replication_level Desired replication level. 200 * @param desired_replication_level Desired replication level.
@@ -210,6 +209,7 @@ put_callback (void *cls,
210 enum GNUNET_BLOCK_Type type, 209 enum GNUNET_BLOCK_Type type,
211 uint32_t hop_count, 210 uint32_t hop_count,
212 uint32_t desired_replication_level, 211 uint32_t desired_replication_level,
212 const struct GNUNET_PeerIdentity *trunc_peer,
213 unsigned int path_length, 213 unsigned int path_length,
214 const struct GNUNET_DHT_PathElement *path, 214 const struct GNUNET_DHT_PathElement *path,
215 struct GNUNET_TIME_Absolute exp, 215 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,
144 * 144 *
145 * @param bd block details 145 * @param bd block details
146 * @param query_hash hash of the original query, might not match key in @a bd 146 * @param query_hash hash of the original query, might not match key in @a bd
147 * @param trunc_peer peer at which the path was truncated, or NULL if path starts at the origin
147 * @param get_path_length number of entries in @a get_path 148 * @param get_path_length number of entries in @a get_path
148 * @param get_path path the reply has taken 149 * @param get_path path the reply has taken
149 * @return true on success, false on failures 150 * @return true on success, false on failures
@@ -162,8 +163,6 @@ GDS_CLIENTS_handle_reply (const struct GNUNET_DATACACHE_Block *bd,
162 * @param options Options, for instance RecordRoute, DemultiplexEverywhere. 163 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
163 * @param type The type of data in the request. 164 * @param type The type of data in the request.
164 * @param hop_count Hop count so far. 165 * @param hop_count Hop count so far.
165 * @param path_length number of entries in path (or 0 if not recorded).
166 * @param path peers on the GET path (or NULL if not recorded).
167 * @param desired_replication_level Desired replication level. 166 * @param desired_replication_level Desired replication level.
168 * @param key Key of the requested data. 167 * @param key Key of the requested data.
169 */ 168 */
@@ -172,8 +171,6 @@ GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options,
172 enum GNUNET_BLOCK_Type type, 171 enum GNUNET_BLOCK_Type type,
173 uint32_t hop_count, 172 uint32_t hop_count,
174 uint32_t desired_replication_level, 173 uint32_t desired_replication_level,
175 unsigned int path_length,
176 const struct GNUNET_DHT_PathElement *path,
177 const struct GNUNET_HashCode *key); 174 const struct GNUNET_HashCode *key);
178 175
179 176
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,
656 cqr->type, 656 cqr->type,
657 0, /* hop count */ 657 0, /* hop count */
658 cqr->replication, 658 cqr->replication,
659 0, /* path length */
660 NULL,
661 &get->key); 659 &get->key);
662 /* start remote requests */ 660 /* start remote requests */
663 if (NULL != retry_task) 661 if (NULL != retry_task)
@@ -907,12 +905,15 @@ forward_reply (void *cls,
907{ 905{
908 struct ForwardReplyContext *frc = cls; 906 struct ForwardReplyContext *frc = cls;
909 struct ClientQueryRecord *record = value; 907 struct ClientQueryRecord *record = value;
908 const struct GNUNET_DATACACHE_Block *bd = frc->bd;
910 struct GNUNET_MQ_Envelope *env; 909 struct GNUNET_MQ_Envelope *env;
911 struct GNUNET_DHT_ClientResultMessage *reply; 910 struct GNUNET_DHT_ClientResultMessage *reply;
912 enum GNUNET_BLOCK_ReplyEvaluationResult eval; 911 enum GNUNET_BLOCK_ReplyEvaluationResult eval;
913 bool do_free; 912 bool do_free;
914 struct GNUNET_HashCode ch; 913 struct GNUNET_HashCode ch;
915 struct GNUNET_DHT_PathElement *paths; 914 struct GNUNET_DHT_PathElement *paths;
915 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
916 size_t xsize = bd->data_size;
916 917
917 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, 918 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG,
918 "CLIENT-RESULT %s\n", 919 "CLIENT-RESULT %s\n",
@@ -995,18 +996,34 @@ forward_reply (void *cls,
995 "# RESULTS queued for clients", 996 "# RESULTS queued for clients",
996 1, 997 1,
997 GNUNET_NO); 998 GNUNET_NO);
999 xsize += (frc->get_path_length + frc->bd->put_path_length)
1000 * sizeof(struct GNUNET_DHT_PathElement);
1001 if (truncated)
1002 xsize += sizeof (struct GNUNET_PeerIdentity);
998 env = GNUNET_MQ_msg_extra (reply, 1003 env = GNUNET_MQ_msg_extra (reply,
999 frc->bd->data_size 1004 xsize,
1000 + (frc->get_path_length + frc->bd->put_path_length)
1001 * sizeof(struct GNUNET_DHT_PathElement),
1002 GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); 1005 GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT);
1003 reply->type = htonl (frc->bd->type); 1006 reply->type = htonl (frc->bd->type);
1007 reply->options = htonl (bd->ro);
1004 reply->get_path_length = htonl (frc->get_path_length); 1008 reply->get_path_length = htonl (frc->get_path_length);
1005 reply->put_path_length = htonl (frc->bd->put_path_length); 1009 reply->put_path_length = htonl (frc->bd->put_path_length);
1006 reply->unique_id = record->unique_id; 1010 reply->unique_id = record->unique_id;
1007 reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time); 1011 reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time);
1008 reply->key = *query_hash; 1012 reply->key = *query_hash;
1009 paths = (struct GNUNET_DHT_PathElement *) &reply[1]; 1013 if (truncated)
1014 {
1015 void *tgt = &reply[1];
1016
1017 GNUNET_memcpy (tgt,
1018 &bd->trunc_peer,
1019 sizeof (struct GNUNET_PeerIdentity));
1020 paths = (struct GNUNET_DHT_PathElement *)
1021 (tgt + sizeof (struct GNUNET_PeerIdentity));
1022 }
1023 else
1024 {
1025 paths = (struct GNUNET_DHT_PathElement *) &reply[1];
1026 }
1010 GNUNET_memcpy (paths, 1027 GNUNET_memcpy (paths,
1011 frc->bd->put_path, 1028 frc->bd->put_path,
1012 sizeof(struct GNUNET_DHT_PathElement) 1029 sizeof(struct GNUNET_DHT_PathElement)
@@ -1041,6 +1058,7 @@ GDS_CLIENTS_handle_reply (const struct GNUNET_DATACACHE_Block *bd,
1041 + bd->data_size 1058 + bd->data_size
1042 + (get_path_length + bd->put_path_length) 1059 + (get_path_length + bd->put_path_length)
1043 * sizeof(struct GNUNET_DHT_PathElement); 1060 * sizeof(struct GNUNET_DHT_PathElement);
1061 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1044 1062
1045 if (msize >= GNUNET_MAX_MESSAGE_SIZE) 1063 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1046 { 1064 {
@@ -1052,6 +1070,9 @@ GDS_CLIENTS_handle_reply (const struct GNUNET_DATACACHE_Block *bd,
1052 GNUNET_DHT_verify_path (bd->data, 1070 GNUNET_DHT_verify_path (bd->data,
1053 bd->data_size, 1071 bd->data_size,
1054 bd->expiration_time, 1072 bd->expiration_time,
1073 truncated
1074 ? &bd->trunc_peer
1075 : NULL,
1055 bd->put_path, 1076 bd->put_path,
1056 bd->put_path_length, 1077 bd->put_path_length,
1057 get_path, 1078 get_path,
@@ -1291,27 +1312,30 @@ for_matching_monitors (enum GNUNET_BLOCK_Type type,
1291 NULL != m; 1312 NULL != m;
1292 m = m->next) 1313 m = m->next)
1293 { 1314 {
1294 if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) || 1315 bool found = false;
1295 (m->type == type) ) && 1316
1296 ( (GNUNET_is_zero (&m->key)) || 1317 if ( (GNUNET_BLOCK_TYPE_ANY != m->type) &&
1297 (0 == 1318 (m->type != type) )
1298 GNUNET_memcmp (key, 1319 continue;
1299 &m->key)) ) ) 1320 if ( (! GNUNET_is_zero (&m->key)) &&
1300 { 1321 (0 ==
1301 unsigned int i; 1322 GNUNET_memcmp (key,
1302 1323 &m->key)) )
1303 /* Don't send duplicates */ 1324 continue;
1304 for (i = 0; i < cl_size; i++) 1325 /* Don't send duplicates */
1305 if (cl[i] == m->ch) 1326 for (unsigned i = 0; i < cl_size; i++)
1306 break; 1327 if (cl[i] == m->ch)
1307 if (i < cl_size) 1328 {
1308 continue; 1329 found = true;
1309 GNUNET_array_append (cl, 1330 break;
1310 cl_size, 1331 }
1311 m->ch); 1332 if (found)
1312 cb (cb_cls, 1333 continue;
1313 m); 1334 GNUNET_array_append (cl,
1314 } 1335 cl_size,
1336 m->ch);
1337 cb (cb_cls,
1338 m);
1315 } 1339 }
1316 GNUNET_free (cl); 1340 GNUNET_free (cl);
1317} 1341}
@@ -1326,8 +1350,7 @@ struct GetActionContext
1326 enum GNUNET_BLOCK_Type type; 1350 enum GNUNET_BLOCK_Type type;
1327 uint32_t hop_count; 1351 uint32_t hop_count;
1328 uint32_t desired_replication_level; 1352 uint32_t desired_replication_level;
1329 unsigned int get_path_length; 1353 struct GNUNET_PeerIdentity trunc_peer;
1330 const struct GNUNET_DHT_PathElement *get_path;
1331 const struct GNUNET_HashCode *key; 1354 const struct GNUNET_HashCode *key;
1332}; 1355};
1333 1356
@@ -1346,23 +1369,14 @@ get_action (void *cls,
1346 struct GetActionContext *gac = cls; 1369 struct GetActionContext *gac = cls;
1347 struct GNUNET_MQ_Envelope *env; 1370 struct GNUNET_MQ_Envelope *env;
1348 struct GNUNET_DHT_MonitorGetMessage *mmsg; 1371 struct GNUNET_DHT_MonitorGetMessage *mmsg;
1349 struct GNUNET_DHT_PathElement *msg_path;
1350 size_t msize;
1351 1372
1352 msize = gac->get_path_length * sizeof(struct GNUNET_DHT_PathElement); 1373 env = GNUNET_MQ_msg (mmsg,
1353 env = GNUNET_MQ_msg_extra (mmsg, 1374 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET);
1354 msize,
1355 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET);
1356 mmsg->options = htonl (gac->options); 1375 mmsg->options = htonl (gac->options);
1357 mmsg->type = htonl (gac->type); 1376 mmsg->type = htonl (gac->type);
1358 mmsg->hop_count = htonl (gac->hop_count); 1377 mmsg->hop_count = htonl (gac->hop_count);
1359 mmsg->desired_replication_level = htonl (gac->desired_replication_level); 1378 mmsg->desired_replication_level = htonl (gac->desired_replication_level);
1360 mmsg->get_path_length = htonl (gac->get_path_length);
1361 mmsg->key = *gac->key; 1379 mmsg->key = *gac->key;
1362 msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1363 GNUNET_memcpy (msg_path,
1364 gac->get_path,
1365 gac->get_path_length * sizeof(struct GNUNET_DHT_PathElement));
1366 GNUNET_MQ_send (m->ch->mq, 1380 GNUNET_MQ_send (m->ch->mq,
1367 env); 1381 env);
1368} 1382}
@@ -1375,8 +1389,6 @@ get_action (void *cls,
1375 * @param options Options, for instance RecordRoute, DemultiplexEverywhere. 1389 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
1376 * @param type The type of data in the request. 1390 * @param type The type of data in the request.
1377 * @param hop_count Hop count so far. 1391 * @param hop_count Hop count so far.
1378 * @param path_length number of entries in path (or 0 if not recorded).
1379 * @param path peers on the GET path (or NULL if not recorded).
1380 * @param desired_replication_level Desired replication level. 1392 * @param desired_replication_level Desired replication level.
1381 * @param key Key of the requested data. 1393 * @param key Key of the requested data.
1382 */ 1394 */
@@ -1385,8 +1397,6 @@ GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options,
1385 enum GNUNET_BLOCK_Type type, 1397 enum GNUNET_BLOCK_Type type,
1386 uint32_t hop_count, 1398 uint32_t hop_count,
1387 uint32_t desired_replication_level, 1399 uint32_t desired_replication_level,
1388 unsigned int path_length,
1389 const struct GNUNET_DHT_PathElement *path,
1390 const struct GNUNET_HashCode *key) 1400 const struct GNUNET_HashCode *key)
1391{ 1401{
1392 struct GetActionContext gac = { 1402 struct GetActionContext gac = {
@@ -1394,8 +1404,6 @@ GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options,
1394 .type = type, 1404 .type = type,
1395 .hop_count = hop_count, 1405 .hop_count = hop_count,
1396 .desired_replication_level = desired_replication_level, 1406 .desired_replication_level = desired_replication_level,
1397 .get_path_length = path_length,
1398 .get_path = path,
1399 .key = key 1407 .key = key
1400 }; 1408 };
1401 1409
@@ -1430,7 +1438,7 @@ response_action (void *cls,
1430{ 1438{
1431 const struct ResponseActionContext *resp_ctx = cls; 1439 const struct ResponseActionContext *resp_ctx = cls;
1432 const struct GNUNET_DATACACHE_Block *bd = resp_ctx->bd; 1440 const struct GNUNET_DATACACHE_Block *bd = resp_ctx->bd;
1433 1441 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1434 struct GNUNET_MQ_Envelope *env; 1442 struct GNUNET_MQ_Envelope *env;
1435 struct GNUNET_DHT_MonitorGetRespMessage *mmsg; 1443 struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1436 struct GNUNET_DHT_PathElement *path; 1444 struct GNUNET_DHT_PathElement *path;
@@ -1439,6 +1447,8 @@ response_action (void *cls,
1439 msize = bd->data_size; 1447 msize = bd->data_size;
1440 msize += (resp_ctx->get_path_length + bd->put_path_length) 1448 msize += (resp_ctx->get_path_length + bd->put_path_length)
1441 * sizeof(struct GNUNET_DHT_PathElement); 1449 * sizeof(struct GNUNET_DHT_PathElement);
1450 if (truncated)
1451 msize += sizeof (struct GNUNET_PeerIdentity);
1442 env = GNUNET_MQ_msg_extra (mmsg, 1452 env = GNUNET_MQ_msg_extra (mmsg,
1443 msize, 1453 msize,
1444 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP); 1454 GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP);
@@ -1447,7 +1457,20 @@ response_action (void *cls,
1447 mmsg->get_path_length = htonl (resp_ctx->get_path_length); 1457 mmsg->get_path_length = htonl (resp_ctx->get_path_length);
1448 mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); 1458 mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
1449 mmsg->key = bd->key; 1459 mmsg->key = bd->key;
1450 path = (struct GNUNET_DHT_PathElement *) &mmsg[1]; 1460 if (truncated)
1461 {
1462 void *tgt = &mmsg[1];
1463
1464 GNUNET_memcpy (tgt,
1465 &bd->trunc_peer,
1466 sizeof (struct GNUNET_PeerIdentity));
1467 path = (struct GNUNET_DHT_PathElement *)
1468 (tgt + sizeof (struct GNUNET_PeerIdentity));
1469 }
1470 else
1471 {
1472 path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1473 }
1451 GNUNET_memcpy (path, 1474 GNUNET_memcpy (path,
1452 bd->put_path, 1475 bd->put_path,
1453 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement)); 1476 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
@@ -1505,6 +1528,7 @@ put_action (void *cls,
1505{ 1528{
1506 const struct PutActionContext *put_ctx = cls; 1529 const struct PutActionContext *put_ctx = cls;
1507 const struct GNUNET_DATACACHE_Block *bd = put_ctx->bd; 1530 const struct GNUNET_DATACACHE_Block *bd = put_ctx->bd;
1531 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1508 struct GNUNET_MQ_Envelope *env; 1532 struct GNUNET_MQ_Envelope *env;
1509 struct GNUNET_DHT_MonitorPutMessage *mmsg; 1533 struct GNUNET_DHT_MonitorPutMessage *mmsg;
1510 struct GNUNET_DHT_PathElement *msg_path; 1534 struct GNUNET_DHT_PathElement *msg_path;
@@ -1513,6 +1537,8 @@ put_action (void *cls,
1513 msize = bd->data_size 1537 msize = bd->data_size
1514 + bd->put_path_length 1538 + bd->put_path_length
1515 * sizeof(struct GNUNET_DHT_PathElement); 1539 * sizeof(struct GNUNET_DHT_PathElement);
1540 if (truncated)
1541 msize += sizeof (struct GNUNET_PeerIdentity);
1516 env = GNUNET_MQ_msg_extra (mmsg, 1542 env = GNUNET_MQ_msg_extra (mmsg,
1517 msize, 1543 msize,
1518 GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); 1544 GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
@@ -1523,7 +1549,20 @@ put_action (void *cls,
1523 mmsg->put_path_length = htonl (bd->put_path_length); 1549 mmsg->put_path_length = htonl (bd->put_path_length);
1524 mmsg->key = bd->key; 1550 mmsg->key = bd->key;
1525 mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); 1551 mmsg->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
1526 msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1]; 1552 if (truncated)
1553 {
1554 void *tgt = &mmsg[1];
1555
1556 GNUNET_memcpy (tgt,
1557 &bd->trunc_peer,
1558 sizeof (struct GNUNET_PeerIdentity));
1559 msg_path = (struct GNUNET_DHT_PathElement *)
1560 (tgt + sizeof (struct GNUNET_PeerIdentity));
1561 }
1562 else
1563 {
1564 msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1565 }
1527 GNUNET_memcpy (msg_path, 1566 GNUNET_memcpy (msg_path,
1528 bd->put_path, 1567 bd->put_path,
1529 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement)); 1568 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
150 */ 150 */
151 struct GNUNET_HashCode key; 151 struct GNUNET_HashCode key;
152 152
153 /* trunc_peer (if truncated) */
154
153 /* put path (if tracked) */ 155 /* put path (if tracked) */
154 156
157 /* sender_sig (if path tracking is on) */
158
155 /* Payload */ 159 /* Payload */
156}; 160};
157 161
@@ -172,9 +176,9 @@ struct PeerResultMessage
172 uint32_t type GNUNET_PACKED; 176 uint32_t type GNUNET_PACKED;
173 177
174 /** 178 /**
175 * Reserved. 179 * Message options, actually an 'enum GNUNET_DHT_RouteOption' value in NBO.
176 */ 180 */
177 uint32_t reserved GNUNET_PACKED; 181 uint32_t options GNUNET_PACKED;
178 182
179 /** 183 /**
180 * Length of the PUT path that follows (if tracked). 184 * Length of the PUT path that follows (if tracked).
@@ -196,10 +200,14 @@ struct PeerResultMessage
196 */ 200 */
197 struct GNUNET_HashCode key; 201 struct GNUNET_HashCode key;
198 202
203 /* trunc_peer (if truncated) */
204
199 /* put path (if tracked) */ 205 /* put path (if tracked) */
200 206
201 /* get path (if tracked) */ 207 /* get path (if tracked) */
202 208
209 /* sender_sig (if path tracking is on) */
210
203 /* Payload */ 211 /* Payload */
204}; 212};
205 213
@@ -537,10 +545,11 @@ sign_path (const void *data,
537 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), 545 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP),
538 .purpose.size = htonl (sizeof (hs)), 546 .purpose.size = htonl (sizeof (hs)),
539 .expiration_time = GNUNET_TIME_absolute_hton (exp_time), 547 .expiration_time = GNUNET_TIME_absolute_hton (exp_time),
540 .pred = *pred,
541 .succ = *succ 548 .succ = *succ
542 }; 549 };
543 550
551 if (NULL != pred)
552 hs.pred = *pred;
544 GNUNET_CRYPTO_hash (data, 553 GNUNET_CRYPTO_hash (data,
545 data_size, 554 data_size,
546 &hs.h_data); 555 &hs.h_data);
@@ -1314,21 +1323,36 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_DATACACHE_Block *bd,
1314 struct PeerInfo **targets; 1323 struct PeerInfo **targets;
1315 size_t msize; 1324 size_t msize;
1316 unsigned int skip_count; 1325 unsigned int skip_count;
1326 enum GNUNET_DHT_RouteOption ro = bd->ro;
1317 unsigned int put_path_length = bd->put_path_length; 1327 unsigned int put_path_length = bd->put_path_length;
1328 const struct GNUNET_DHT_PathElement *put_path = bd->put_path;
1329 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
1330 bool tracking = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
1331 const struct GNUNET_PeerIdentity *trunc_peer
1332 = truncated
1333 ? &bd->trunc_peer
1334 : NULL;
1318 1335
1319 GNUNET_assert (NULL != bf);
1320#if SANITY_CHECKS > 1 1336#if SANITY_CHECKS > 1
1321 if (0 != 1337 unsigned int failure_offset;
1322 GNUNET_DHT_verify_path (bd->data, 1338
1339 failure_offset
1340 = GNUNET_DHT_verify_path (bd->data,
1323 bd->data_size, 1341 bd->data_size,
1324 bd->expiration_time, 1342 bd->expiration_time,
1325 bd->put_path, 1343 trunc_peer,
1326 bd->put_path_length, 1344 put_path,
1327 NULL, 0, /* get_path */ 1345 put_path_length,
1328 &GDS_my_identity)) 1346 NULL, 0, /* get_path */
1347 &GDS_my_identity);
1348 if (0 != failure_offset)
1329 { 1349 {
1330 GNUNET_break_op (0); 1350 GNUNET_break_op (0);
1331 put_path_length = 0; 1351 truncated = true;
1352 trunc_peer = &put_path[failure_offset - 1].pred;
1353 put_path = &put_path[failure_offset];
1354 put_path_length = put_path_length - failure_offset;
1355 ro |= GNUNET_DHT_RO_TRUNCATED;
1332 } 1356 }
1333#endif 1357#endif
1334 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1340,12 +1364,70 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_DATACACHE_Block *bd,
1340 1364
1341 /* if we got a HELLO, consider it for our own routing table */ 1365 /* if we got a HELLO, consider it for our own routing table */
1342 hello_check (bd); 1366 hello_check (bd);
1367 GNUNET_assert (NULL != bf);
1343 GNUNET_CONTAINER_bloomfilter_add (bf, 1368 GNUNET_CONTAINER_bloomfilter_add (bf,
1344 &GDS_my_identity_hash); 1369 &GDS_my_identity_hash);
1345 GNUNET_STATISTICS_update (GDS_stats, 1370 GNUNET_STATISTICS_update (GDS_stats,
1346 "# PUT requests routed", 1371 "# PUT requests routed",
1347 1, 1372 1,
1348 GNUNET_NO); 1373 GNUNET_NO);
1374 if (bd->data_size
1375 > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE
1376 - sizeof(struct PeerPutMessage))
1377 {
1378 GNUNET_break (0);
1379 return GNUNET_SYSERR;
1380 }
1381 msize = bd->data_size + sizeof(struct PeerPutMessage);
1382 if (tracking)
1383 {
1384 if (msize + sizeof (struct GNUNET_CRYPTO_EddsaSignature)
1385 > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1386 {
1387 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1388 "Discarding message that is too large due to tracking\n");
1389 return GNUNET_NO;
1390 }
1391 msize += sizeof (struct GNUNET_CRYPTO_EddsaSignature);
1392 }
1393 else
1394 {
1395 /* If tracking is disabled, also discard any path we might have
1396 gotten from some broken peer */
1397 GNUNET_break_op (0 == put_path_length);
1398 put_path_length = 0;
1399 }
1400 if (truncated)
1401 msize += sizeof (struct GNUNET_PeerIdentity);
1402 if (msize + put_path_length * sizeof(struct GNUNET_DHT_PathElement)
1403 > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1404 {
1405 unsigned int mlen;
1406 unsigned int ppl;
1407
1408 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1409 "Truncating path that is too large due\n");
1410 mlen = GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE - msize;
1411 if (! truncated)
1412 {
1413 /* We need extra space for the truncation, consider that,
1414 too! */
1415 truncated = true;
1416 mlen -= sizeof (struct GNUNET_PeerIdentity);
1417 msize += sizeof (struct GNUNET_PeerIdentity);
1418 }
1419 /* compute maximum length of path we can keep */
1420 ppl = mlen / sizeof (struct GNUNET_DHT_PathElement);
1421 GNUNET_assert (put_path_length - ppl > 0);
1422 trunc_peer = &put_path[put_path_length - ppl - 1].pred;
1423 put_path = &put_path[put_path_length - ppl];
1424 put_path_length = ppl;
1425 ro |= GNUNET_DHT_RO_TRUNCATED;
1426 }
1427 else
1428 {
1429 msize += bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement);
1430 }
1349 target_count 1431 target_count
1350 = get_target_peers (&bd->key, 1432 = get_target_peers (&bd->key,
1351 bf, 1433 bf,
@@ -1361,28 +1443,14 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_DATACACHE_Block *bd,
1361 GNUNET_i2s (&GDS_my_identity)); 1443 GNUNET_i2s (&GDS_my_identity));
1362 return GNUNET_NO; 1444 return GNUNET_NO;
1363 } 1445 }
1364 msize = bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement)
1365 + bd->data_size;
1366 if (msize + sizeof(struct PeerPutMessage)
1367 >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1368 {
1369 put_path_length = 0;
1370 msize = bd->data_size;
1371 }
1372 if (msize + sizeof(struct PeerPutMessage)
1373 >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
1374 {
1375 GNUNET_break (0);
1376 GNUNET_free (targets);
1377 return GNUNET_NO;
1378 }
1379 skip_count = 0; 1446 skip_count = 0;
1380 for (unsigned int i = 0; i < target_count; i++) 1447 for (unsigned int i = 0; i < target_count; i++)
1381 { 1448 {
1382 struct PeerInfo *target = targets[i]; 1449 struct PeerInfo *target = targets[i];
1383 struct PeerPutMessage *ppm; 1450 struct PeerPutMessage *ppm;
1384 char buf[sizeof (*ppm) + msize] GNUNET_ALIGN; 1451 char buf[msize] GNUNET_ALIGN;
1385 struct GNUNET_DHT_PathElement *pp; 1452 struct GNUNET_DHT_PathElement *pp;
1453 void *data;
1386 1454
1387 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1388 "Routing PUT for %s after %u hops to %s\n", 1456 "Routing PUT for %s after %u hops to %s\n",
@@ -1393,7 +1461,7 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_DATACACHE_Block *bd,
1393 ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT); 1461 ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
1394 ppm->header.size = htons (sizeof (buf)); 1462 ppm->header.size = htons (sizeof (buf));
1395 ppm->type = htonl (bd->type); 1463 ppm->type = htonl (bd->type);
1396 ppm->options = htons (bd->ro); 1464 ppm->options = htons (ro);
1397 ppm->hop_count = htons (hop_count + 1); 1465 ppm->hop_count = htons (hop_count + 1);
1398 ppm->desired_replication_level = htons (desired_replication_level); 1466 ppm->desired_replication_level = htons (desired_replication_level);
1399 ppm->put_path_length = htons (put_path_length); 1467 ppm->put_path_length = htons (put_path_length);
@@ -1406,28 +1474,62 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_DATACACHE_Block *bd,
1406 ppm->bloomfilter, 1474 ppm->bloomfilter,
1407 DHT_BLOOM_SIZE)); 1475 DHT_BLOOM_SIZE));
1408 ppm->key = bd->key; 1476 ppm->key = bd->key;
1409 pp = (struct GNUNET_DHT_PathElement *) &ppm[1]; 1477 if (truncated)
1478 {
1479 void *tgt = &ppm[1];
1480
1481 GNUNET_memcpy (tgt,
1482 trunc_peer,
1483 sizeof (struct GNUNET_PeerIdentity));
1484 pp = (struct GNUNET_DHT_PathElement *)
1485 (tgt + sizeof (struct GNUNET_PeerIdentity));
1486 }
1487 else
1488 {
1489 pp = (struct GNUNET_DHT_PathElement *) &ppm[1];
1490 }
1410 GNUNET_memcpy (pp, 1491 GNUNET_memcpy (pp,
1411 bd->put_path, 1492 put_path,
1412 sizeof (struct GNUNET_DHT_PathElement) * put_path_length); 1493 sizeof (struct GNUNET_DHT_PathElement) * put_path_length);
1413 /* 0 == put_path_length means path is not being tracked */ 1494 if (tracking)
1414 if (0 != put_path_length)
1415 { 1495 {
1416 /* Note that the signature in 'put_path' was not initialized before, 1496 void *tgt = &pp[put_path_length];
1417 so this is crucial to avoid sending garbage. */ 1497 struct GNUNET_CRYPTO_EddsaSignature last_sig;
1418 sign_path (bd->data, 1498
1419 bd->data_size, 1499 if (0 == put_path_length)
1420 bd->expiration_time, 1500 {
1421 &pp[put_path_length - 1].pred, 1501 /* Note that the signature in 'put_path' was not initialized before,
1422 &target->id, 1502 so this is crucial to avoid sending garbage. */
1423 &pp[put_path_length - 1].sig); 1503 sign_path (bd->data,
1504 bd->data_size,
1505 bd->expiration_time,
1506 trunc_peer,
1507 &target->id,
1508 &last_sig);
1509 }
1510 else
1511 {
1512 sign_path (bd->data,
1513 bd->data_size,
1514 bd->expiration_time,
1515 &pp[put_path_length - 1].pred,
1516 &target->id,
1517 &last_sig);
1518 }
1424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1425 "Signing PUT PATH %u => %s\n", 1520 "Signing PUT PATH %u => %s\n",
1426 put_path_length, 1521 put_path_length,
1427 GNUNET_B2S (&pp[put_path_length - 1].sig)); 1522 GNUNET_B2S (&last_sig));
1523 memcpy (tgt,
1524 &last_sig,
1525 sizeof (last_sig));
1526 data = tgt + sizeof (last_sig);
1428 } 1527 }
1429 1528 else /* ! tracking */
1430 GNUNET_memcpy (&pp[put_path_length], 1529 {
1530 data = &ppm[1];
1531 }
1532 GNUNET_memcpy (data,
1431 bd->data, 1533 bd->data,
1432 bd->data_size); 1534 bd->data_size);
1433 do_send (target, 1535 do_send (target,
@@ -1572,46 +1674,86 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1572 struct GNUNET_DHT_PathElement *paths; 1674 struct GNUNET_DHT_PathElement *paths;
1573 size_t msize; 1675 size_t msize;
1574 unsigned int ppl = bd->put_path_length; 1676 unsigned int ppl = bd->put_path_length;
1575 1677 const struct GNUNET_DHT_PathElement *put_path = bd->put_path;
1678 enum GNUNET_DHT_RouteOption ro = bd->ro;
1679 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
1680 const struct GNUNET_PeerIdentity *trunc_peer
1681 = truncated
1682 ? &bd->trunc_peer
1683 : NULL;
1684 bool tracking = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
1576#if SANITY_CHECKS > 1 1685#if SANITY_CHECKS > 1
1577 if (0 != 1686 unsigned int failure_offset;
1578 GNUNET_DHT_verify_path (bd->data, 1687
1688 failure_offset
1689 = GNUNET_DHT_verify_path (bd->data,
1579 bd->data_size, 1690 bd->data_size,
1580 bd->expiration_time, 1691 bd->expiration_time,
1581 bd->put_path, 1692 trunc_peer,
1582 bd->put_path_length, 1693 put_path,
1694 ppl,
1583 get_path, 1695 get_path,
1584 get_path_length, 1696 get_path_length,
1585 &GDS_my_identity)) 1697 &GDS_my_identity);
1698 if (0 != failure_offset)
1586 { 1699 {
1700 GNUNET_assert (failure_offset <= ppl + get_path_length);
1587 GNUNET_break_op (0); 1701 GNUNET_break_op (0);
1588 return false; 1702 if (failure_offset < ppl)
1703 {
1704 trunc_peer = &put_path[failure_offset - 1].pred;
1705 put_path += failure_offset;
1706 ppl -= failure_offset;
1707 truncated = true;
1708 ro |= GNUNET_DHT_RO_TRUNCATED;
1709 }
1710 else
1711 {
1712 failure_offset -= ppl;
1713 if (0 == failure_offset)
1714 trunc_peer = &put_path[ppl - 1].pred;
1715 else
1716 trunc_peer = &get_path[failure_offset - 1].pred;
1717 ppl = 0;
1718 put_path = NULL;
1719 truncated = true;
1720 ro |= GNUNET_DHT_RO_TRUNCATED;
1721 get_path += failure_offset;
1722 get_path_length -= failure_offset;
1723 }
1589 } 1724 }
1590#endif 1725#endif
1591 msize = bd->data_size + (get_path_length + ppl) 1726 msize = bd->data_size + sizeof (struct PeerResultMessage);
1592 * sizeof(struct GNUNET_DHT_PathElement); 1727 if (msize > GNUNET_MAX_MESSAGE_SIZE)
1593 if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) || 1728 {
1594 (get_path_length > 1729 GNUNET_break_op (0);
1595 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) || 1730 return false;
1596 (ppl > 1731 }
1597 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) || 1732 if (truncated)
1598 (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) 1733 msize += sizeof (struct GNUNET_PeerIdentity);
1734 if (tracking)
1735 msize += sizeof (struct GNUNET_CRYPTO_EddsaSignature);
1736 if (msize < bd->data_size)
1737 {
1738 GNUNET_break_op (0);
1739 return false;
1740 }
1741 if ( (GNUNET_MAX_MESSAGE_SIZE - msize)
1742 / sizeof(struct GNUNET_DHT_PathElement)
1743 < (get_path_length + ppl) )
1599 { 1744 {
1600 ppl = 0;
1601 get_path_length = 0; 1745 get_path_length = 0;
1602 msize = bd->data_size + (get_path_length + ppl) 1746 ppl = 0;
1603 * sizeof(struct GNUNET_DHT_PathElement);
1604 } 1747 }
1605 if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) || 1748 if ( (get_path_length > UINT16_MAX) ||
1606 (get_path_length > 1749 (ppl > UINT16_MAX) )
1607 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1608 (ppl >
1609 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1610 (bd->data_size > GNUNET_MAX_MESSAGE_SIZE))
1611 { 1750 {
1612 GNUNET_break (0); 1751 GNUNET_break (0);
1613 return false; 1752 get_path_length = 0;
1753 ppl = 0;
1614 } 1754 }
1755 msize += (get_path_length + ppl)
1756 * sizeof(struct GNUNET_DHT_PathElement);
1615 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1616 "Forwarding reply for key %s to peer %s\n", 1758 "Forwarding reply for key %s to peer %s\n",
1617 GNUNET_h2s (query_hash), 1759 GNUNET_h2s (query_hash),
@@ -1622,22 +1764,36 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1622 GNUNET_NO); 1764 GNUNET_NO);
1623 { 1765 {
1624 struct PeerResultMessage *prm; 1766 struct PeerResultMessage *prm;
1625 char buf[sizeof (*prm) + msize] GNUNET_ALIGN; 1767 char buf[msize] GNUNET_ALIGN;
1768 void *data;
1626 1769
1627 prm = (struct PeerResultMessage *) buf; 1770 prm = (struct PeerResultMessage *) buf;
1628 prm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); 1771 prm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT);
1629 prm->header.size = htons (sizeof (buf)); 1772 prm->header.size = htons (sizeof (buf));
1630 prm->type = htonl (bd->type); 1773 prm->type = htonl ((uint32_t) bd->type);
1631 prm->reserved = htonl (0); 1774 prm->options = htonl ((uint32_t) ro);
1632 prm->put_path_length = htons (ppl); 1775 prm->put_path_length = htons ((uint16_t) ppl);
1633 prm->get_path_length = htons (get_path_length); 1776 prm->get_path_length = htons ((uint16_t) get_path_length);
1634 prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); 1777 prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
1635 prm->key = *query_hash; 1778 prm->key = *query_hash;
1636 paths = (struct GNUNET_DHT_PathElement *) &prm[1]; 1779 if (truncated)
1637 if (NULL != bd->put_path) 1780 {
1781 void *tgt = &prm[1];
1782
1783 GNUNET_memcpy (tgt,
1784 trunc_peer,
1785 sizeof (struct GNUNET_PeerIdentity));
1786 paths = (struct GNUNET_DHT_PathElement *)
1787 (tgt + sizeof (struct GNUNET_PeerIdentity));
1788 }
1789 else
1790 {
1791 paths = (struct GNUNET_DHT_PathElement *) &prm[1];
1792 }
1793 if (NULL != put_path)
1638 { 1794 {
1639 GNUNET_memcpy (paths, 1795 GNUNET_memcpy (paths,
1640 bd->put_path, 1796 put_path,
1641 ppl * sizeof(struct GNUNET_DHT_PathElement)); 1797 ppl * sizeof(struct GNUNET_DHT_PathElement));
1642 } 1798 }
1643 else 1799 else
@@ -1654,51 +1810,69 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1654 { 1810 {
1655 GNUNET_assert (0 == get_path_length); 1811 GNUNET_assert (0 == get_path_length);
1656 } 1812 }
1657 /* 0 == get_path_length+ppl means path is not being tracked */ 1813 if (tracking)
1658 if (0 != (get_path_length + ppl))
1659 { 1814 {
1815 struct GNUNET_CRYPTO_EddsaSignature sig;
1816 void *tgt = &paths[get_path_length + ppl];
1817 const struct GNUNET_PeerIdentity *pred;
1818
1819 if (ppl + get_path_length > 0)
1820 pred = &paths[ppl + get_path_length - 1].pred;
1821 else if (truncated)
1822 pred = trunc_peer;
1823 else
1824 pred = NULL; /* we are first! */
1660 /* Note that the last signature in 'paths' was not initialized before, 1825 /* Note that the last signature in 'paths' was not initialized before,
1661 so this is crucial to avoid sending garbage. */ 1826 so this is crucial to avoid sending garbage. */
1662 sign_path (bd->data, 1827 sign_path (bd->data,
1663 bd->data_size, 1828 bd->data_size,
1664 bd->expiration_time, 1829 bd->expiration_time,
1665 &paths[ppl + get_path_length - 1].pred, 1830 pred,
1666 &pi->id, 1831 &pi->id,
1667 &paths[ppl + get_path_length - 1].sig); 1832 &sig);
1833 memcpy (tgt,
1834 &sig,
1835 sizeof (sig));
1836 data = tgt + sizeof (sig);
1668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1669 "Signing GET PATH %u/%u of %s => %s\n", 1838 "Signing GET PATH %u/%u of %s => %s\n",
1670 ppl, 1839 ppl,
1671 get_path_length, 1840 get_path_length,
1672 GNUNET_h2s (query_hash), 1841 GNUNET_h2s (query_hash),
1673 GNUNET_B2S (&paths[ppl + get_path_length - 1].sig)); 1842 GNUNET_B2S (&sig));
1674 }
1675 GNUNET_memcpy (&paths[ppl + get_path_length],
1676 bd->data,
1677 bd->data_size);
1678
1679#if SANITY_CHECKS > 1 1843#if SANITY_CHECKS > 1
1680 {
1681 struct GNUNET_DHT_PathElement xpaths[get_path_length + 1];
1682
1683 memcpy (xpaths,
1684 &paths[ppl],
1685 get_path_length * sizeof (struct GNUNET_DHT_PathElement));
1686 xpaths[get_path_length].pred = GDS_my_identity;
1687 if (0 !=
1688 GNUNET_DHT_verify_path (bd->data,
1689 bd->data_size,
1690 bd->expiration_time,
1691 paths,
1692 ppl,
1693 xpaths,
1694 get_path_length + 1,
1695 &pi->id))
1696 { 1844 {
1697 GNUNET_break (0); 1845 struct GNUNET_DHT_PathElement xpaths[get_path_length + 1];
1698 return false; 1846
1847 memcpy (xpaths,
1848 &paths[ppl],
1849 get_path_length * sizeof (struct GNUNET_DHT_PathElement));
1850 xpaths[get_path_length].sig = sig;
1851 xpaths[get_path_length].pred = GDS_my_identity;
1852 if (0 !=
1853 GNUNET_DHT_verify_path (bd->data,
1854 bd->data_size,
1855 bd->expiration_time,
1856 trunc_peer,
1857 paths,
1858 ppl,
1859 xpaths,
1860 get_path_length + 1,
1861 &pi->id))
1862 {
1863 GNUNET_break (0);
1864 return false;
1865 }
1699 } 1866 }
1700 }
1701#endif 1867#endif
1868 }
1869 else
1870 {
1871 data = &prm[1];
1872 }
1873 GNUNET_memcpy (data,
1874 bd->data,
1875 bd->data_size);
1702 do_send (pi, 1876 do_send (pi,
1703 &prm->header); 1877 &prm->header);
1704 } 1878 }
@@ -1717,15 +1891,30 @@ static enum GNUNET_GenericReturnValue
1717check_dht_p2p_put (void *cls, 1891check_dht_p2p_put (void *cls,
1718 const struct PeerPutMessage *put) 1892 const struct PeerPutMessage *put)
1719{ 1893{
1894 enum GNUNET_DHT_RouteOption ro
1895 = (enum GNUNET_DHT_RouteOption) ntohs (put->options);
1896 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
1897 bool has_path = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
1720 uint16_t msize = ntohs (put->header.size); 1898 uint16_t msize = ntohs (put->header.size);
1721 uint16_t putlen = ntohs (put->put_path_length); 1899 uint16_t putlen = ntohs (put->put_path_length);
1900 size_t xsize = (has_path
1901 ? sizeof (struct GNUNET_CRYPTO_EddsaSignature)
1902 : 0)
1903 + (truncated
1904 ? sizeof (struct GNUNET_PeerIdentity)
1905 : 0);
1906 size_t var_meta_size
1907 = putlen * sizeof(struct GNUNET_DHT_PathElement)
1908 + xsize;
1722 1909
1723 (void) cls; 1910 (void) cls;
1724 if ( (msize < 1911 if ( (msize <
1725 sizeof(struct PeerPutMessage) 1912 sizeof (struct PeerPutMessage) + var_meta_size) ||
1726 + putlen * sizeof(struct GNUNET_DHT_PathElement)) ||
1727 (putlen > 1913 (putlen >
1728 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ) 1914 (GNUNET_MAX_MESSAGE_SIZE
1915 - sizeof (struct PeerPutMessage)
1916 - xsize)
1917 / sizeof(struct GNUNET_DHT_PathElement)) )
1729 { 1918 {
1730 GNUNET_break_op (0); 1919 GNUNET_break_op (0);
1731 return GNUNET_SYSERR; 1920 return GNUNET_SYSERR;
@@ -1746,27 +1935,49 @@ handle_dht_p2p_put (void *cls,
1746{ 1935{
1747 struct Target *t = cls; 1936 struct Target *t = cls;
1748 struct PeerInfo *peer = t->pi; 1937 struct PeerInfo *peer = t->pi;
1938 enum GNUNET_DHT_RouteOption ro
1939 = (enum GNUNET_DHT_RouteOption) ntohs (put->options);
1940 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
1941 bool has_path = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
1749 uint16_t msize = ntohs (put->header.size); 1942 uint16_t msize = ntohs (put->header.size);
1943 uint16_t putlen = ntohs (put->put_path_length);
1944 const struct GNUNET_PeerIdentity *trunc_peer
1945 = truncated
1946 ? (const struct GNUNET_PeerIdentity *) &put[1]
1947 : NULL;
1750 const struct GNUNET_DHT_PathElement *put_path 1948 const struct GNUNET_DHT_PathElement *put_path
1751 = (const struct GNUNET_DHT_PathElement *) &put[1]; 1949 = truncated
1752 uint16_t putlen 1950 ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
1753 = ntohs (put->put_path_length); 1951 : (const struct GNUNET_DHT_PathElement *) &put[1];
1952 const struct GNUNET_CRYPTO_EddsaSignature *last_sig
1953 = has_path
1954 ? (const struct GNUNET_CRYPTO_EddsaSignature *) &put_path[putlen]
1955 : NULL;
1956 const char *data
1957 = has_path
1958 ? (const char *) &last_sig[1]
1959 : (const char *) &put_path[putlen];
1960 size_t var_meta_size
1961 = putlen * sizeof(struct GNUNET_DHT_PathElement)
1962 + has_path ? sizeof (*last_sig) : 0
1963 + truncated ? sizeof (*trunc_peer) : 0;
1754 struct GNUNET_DATACACHE_Block bd = { 1964 struct GNUNET_DATACACHE_Block bd = {
1755 .key = put->key, 1965 .key = put->key,
1756 .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time), 1966 .expiration_time = GNUNET_TIME_absolute_ntoh (put->expiration_time),
1757 .type = ntohl (put->type), 1967 .type = ntohl (put->type),
1758 .ro = (enum GNUNET_DHT_RouteOption) ntohs (put->options), 1968 .ro = ro,
1759 .data_size = msize - (sizeof(*put) 1969 .data_size = msize - sizeof(*put) - var_meta_size,
1760 + putlen * sizeof(struct GNUNET_DHT_PathElement)), 1970 .data = data
1761 .data = &put_path[putlen]
1762 }; 1971 };
1763 1972
1973 if (NULL != trunc_peer)
1974 bd.trunc_peer = *trunc_peer;
1764 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1975 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1765 "PUT for `%s' from %s with RO (%s/%s)\n", 1976 "PUT for `%s' from %s with RO (%s/%s)\n",
1766 GNUNET_h2s (&put->key), 1977 GNUNET_h2s (&put->key),
1767 GNUNET_i2s (&peer->id), 1978 GNUNET_i2s (&peer->id),
1768 (bd.ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-", 1979 (bd.ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE) ? "x" : "-",
1769 (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE) ? "R" : "-"); 1980 has_path ? "R" : "-");
1770 if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) 1981 if (GNUNET_TIME_absolute_is_past (bd.expiration_time))
1771 { 1982 {
1772 GNUNET_STATISTICS_update (GDS_stats, 1983 GNUNET_STATISTICS_update (GDS_stats,
@@ -1784,7 +1995,7 @@ handle_dht_p2p_put (void *cls,
1784 GNUNET_break_op (0); 1995 GNUNET_break_op (0);
1785 return; 1996 return;
1786 } 1997 }
1787 if (0 == (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE)) 1998 if (! has_path)
1788 putlen = 0; 1999 putlen = 0;
1789 GNUNET_STATISTICS_update (GDS_stats, 2000 GNUNET_STATISTICS_update (GDS_stats,
1790 "# P2P PUT requests received", 2001 "# P2P PUT requests received",
@@ -1835,7 +2046,7 @@ handle_dht_p2p_put (void *cls,
1835 /* extend 'put path' by sender */ 2046 /* extend 'put path' by sender */
1836 bd.put_path = (const struct GNUNET_DHT_PathElement *) pp; 2047 bd.put_path = (const struct GNUNET_DHT_PathElement *) pp;
1837 bd.put_path_length = putlen + 1; 2048 bd.put_path_length = putlen + 1;
1838 if (0 != (bd.ro & GNUNET_DHT_RO_RECORD_ROUTE)) 2049 if (has_path)
1839 { 2050 {
1840 unsigned int failure_offset; 2051 unsigned int failure_offset;
1841 2052
@@ -1843,10 +2054,7 @@ handle_dht_p2p_put (void *cls,
1843 put_path, 2054 put_path,
1844 putlen * sizeof(struct GNUNET_DHT_PathElement)); 2055 putlen * sizeof(struct GNUNET_DHT_PathElement));
1845 pp[putlen].pred = peer->id; 2056 pp[putlen].pred = peer->id;
1846 /* zero-out signature, not valid until we actually do forward! */ 2057 pp[putlen].sig = *last_sig;
1847 memset (&pp[putlen].sig,
1848 0,
1849 sizeof (pp[putlen].sig));
1850#if SANITY_CHECKS 2058#if SANITY_CHECKS
1851 /* TODO: might want to eventually implement probabilistic 2059 /* TODO: might want to eventually implement probabilistic
1852 load-based path verification, but for now it is all or nothing */ 2060 load-based path verification, but for now it is all or nothing */
@@ -1854,6 +2062,7 @@ handle_dht_p2p_put (void *cls,
1854 = GNUNET_DHT_verify_path (bd.data, 2062 = GNUNET_DHT_verify_path (bd.data,
1855 bd.data_size, 2063 bd.data_size,
1856 bd.expiration_time, 2064 bd.expiration_time,
2065 trunc_peer,
1857 pp, 2066 pp,
1858 putlen + 1, 2067 putlen + 1,
1859 NULL, 0, /* get_path */ 2068 NULL, 0, /* get_path */
@@ -1863,12 +2072,15 @@ handle_dht_p2p_put (void *cls,
1863#endif 2072#endif
1864 if (0 != failure_offset) 2073 if (0 != failure_offset)
1865 { 2074 {
2075 GNUNET_break_op (0);
1866 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2076 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1867 "Recorded put path invalid at offset %u, truncating\n", 2077 "Recorded put path invalid at offset %u, truncating\n",
1868 failure_offset); 2078 failure_offset);
1869 GNUNET_assert (failure_offset <= putlen); 2079 GNUNET_assert (failure_offset <= putlen + 1);
1870 bd.put_path = &pp[failure_offset]; 2080 bd.put_path = &pp[failure_offset];
1871 bd.put_path_length = putlen - failure_offset; 2081 bd.put_path_length = putlen - failure_offset;
2082 bd.ro |= GNUNET_DHT_RO_TRUNCATED;
2083 bd.trunc_peer = pp[failure_offset - 1].pred;
1872 } 2084 }
1873 } 2085 }
1874 else 2086 else
@@ -2218,8 +2430,6 @@ handle_dht_p2p_get (void *cls,
2218 type, 2430 type,
2219 hop_count, 2431 hop_count,
2220 desired_replication_level, 2432 desired_replication_level,
2221 0,
2222 NULL,
2223 &get->key); 2433 &get->key);
2224 } 2434 }
2225 /* clean up; note that 'bg' is owned by routing now! */ 2435 /* clean up; note that 'bg' is owned by routing now! */
@@ -2326,17 +2536,44 @@ handle_dht_p2p_result (void *cls,
2326{ 2536{
2327 struct Target *t = cls; 2537 struct Target *t = cls;
2328 struct PeerInfo *peer = t->pi; 2538 struct PeerInfo *peer = t->pi;
2329 uint16_t msize = ntohs (prm->header.size); 2539 uint16_t msize = ntohs (prm->header.size) - sizeof (*prm);
2540 enum GNUNET_DHT_RouteOption ro
2541 = (enum GNUNET_DHT_RouteOption) ntohl (prm->options);
2542 bool truncated = (0 != (ro & GNUNET_DHT_RO_TRUNCATED));
2543 bool tracked = (0 != (ro & GNUNET_DHT_RO_RECORD_ROUTE));
2330 uint16_t get_path_length = ntohs (prm->get_path_length); 2544 uint16_t get_path_length = ntohs (prm->get_path_length);
2545 uint16_t put_path_length = ntohs (prm->put_path_length);
2546 const struct GNUNET_PeerIdentity *trunc_peer
2547 = truncated
2548 ? (const struct GNUNET_PeerIdentity *) &prm[1]
2549 : NULL;
2550 const struct GNUNET_DHT_PathElement *put_path
2551 = truncated
2552 ? (const struct GNUNET_DHT_PathElement *) &trunc_peer[1]
2553 : (const struct GNUNET_DHT_PathElement *) &prm[1];
2554 const struct GNUNET_DHT_PathElement *get_path
2555 = &put_path[put_path_length];
2556 const struct GNUNET_CRYPTO_EddsaSignature *last_sig
2557 = tracked
2558 ? (const struct GNUNET_CRYPTO_EddsaSignature *) &get_path[get_path_length]
2559 : NULL;
2560 const void *data
2561 = tracked
2562 ? (const void *) &last_sig[1]
2563 : (const void *) &get_path[get_path_length];
2564 size_t vsize = (truncated ? sizeof (struct GNUNET_PeerIdentity) : 0)
2565 + (tracked ? sizeof (struct GNUNET_CRYPTO_EddsaSignature) : 0);
2331 struct GNUNET_DATACACHE_Block bd = { 2566 struct GNUNET_DATACACHE_Block bd = {
2332 .expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time), 2567 .expiration_time = GNUNET_TIME_absolute_ntoh (prm->expiration_time),
2333 .put_path = (const struct GNUNET_DHT_PathElement *) &prm[1], 2568 .put_path = put_path,
2334 .put_path_length = ntohs (prm->put_path_length), 2569 .put_path_length = put_path_length,
2335 .key = prm->key, 2570 .key = prm->key,
2336 .type = ntohl (prm->type) 2571 .type = ntohl (prm->type),
2572 .ro = ro,
2573 .data = data,
2574 .data_size = msize - vsize - (get_path_length + put_path_length)
2575 * sizeof(struct GNUNET_DHT_PathElement)
2337 }; 2576 };
2338 const struct GNUNET_DHT_PathElement *get_path
2339 = &bd.put_path[bd.put_path_length];
2340 2577
2341 /* parse and validate message */ 2578 /* parse and validate message */
2342 if (GNUNET_TIME_absolute_is_past (bd.expiration_time)) 2579 if (GNUNET_TIME_absolute_is_past (bd.expiration_time))
@@ -2347,11 +2584,6 @@ handle_dht_p2p_result (void *cls,
2347 GNUNET_NO); 2584 GNUNET_NO);
2348 return; 2585 return;
2349 } 2586 }
2350 get_path = &bd.put_path[bd.put_path_length];
2351 bd.data = (const void *) &get_path[get_path_length];
2352 bd.data_size = msize - (sizeof(struct PeerResultMessage)
2353 + (get_path_length + bd.put_path_length)
2354 * sizeof(struct GNUNET_DHT_PathElement));
2355 if (GNUNET_OK != 2587 if (GNUNET_OK !=
2356 GNUNET_BLOCK_check_block (GDS_block_context, 2588 GNUNET_BLOCK_check_block (GDS_block_context,
2357 bd.type, 2589 bd.type,
@@ -2385,6 +2617,7 @@ handle_dht_p2p_result (void *cls,
2385 hello_check (&bd); 2617 hello_check (&bd);
2386 2618
2387 /* Need to append 'peer' to 'get_path' */ 2619 /* Need to append 'peer' to 'get_path' */
2620 if (tracked)
2388 { 2621 {
2389 struct GNUNET_DHT_PathElement xget_path[get_path_length + 1]; 2622 struct GNUNET_DHT_PathElement xget_path[get_path_length + 1];
2390 struct GNUNET_DHT_PathElement *gp = xget_path; 2623 struct GNUNET_DHT_PathElement *gp = xget_path;
@@ -2394,9 +2627,10 @@ handle_dht_p2p_result (void *cls,
2394 get_path, 2627 get_path,
2395 get_path_length * sizeof(struct GNUNET_DHT_PathElement)); 2628 get_path_length * sizeof(struct GNUNET_DHT_PathElement));
2396 xget_path[get_path_length].pred = peer->id; 2629 xget_path[get_path_length].pred = peer->id;
2397 memset (&xget_path[get_path_length].sig, 2630 /* use memcpy(), as last_sig may not be aligned */
2398 0, 2631 memcpy (&xget_path[get_path_length].sig,
2399 sizeof (xget_path[get_path_length].sig)); 2632 last_sig,
2633 sizeof (*last_sig));
2400#if SANITY_CHECKS 2634#if SANITY_CHECKS
2401 /* TODO: might want to eventually implement probabilistic 2635 /* TODO: might want to eventually implement probabilistic
2402 load-based path verification, but for now it is all or nothing */ 2636 load-based path verification, but for now it is all or nothing */
@@ -2404,9 +2638,10 @@ handle_dht_p2p_result (void *cls,
2404 = GNUNET_DHT_verify_path (bd.data, 2638 = GNUNET_DHT_verify_path (bd.data,
2405 bd.data_size, 2639 bd.data_size,
2406 bd.expiration_time, 2640 bd.expiration_time,
2407 bd.put_path, 2641 trunc_peer,
2408 bd.put_path_length, 2642 put_path,
2409 xget_path, 2643 put_path_length,
2644 gp,
2410 get_path_length + 1, 2645 get_path_length + 1,
2411 &GDS_my_identity); 2646 &GDS_my_identity);
2412#else 2647#else
@@ -2417,30 +2652,59 @@ handle_dht_p2p_result (void *cls,
2417 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2652 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2418 "Recorded path invalid at offset %u, truncating\n", 2653 "Recorded path invalid at offset %u, truncating\n",
2419 failure_offset); 2654 failure_offset);
2420 GNUNET_assert (failure_offset <= bd.put_path_length + get_path_length); 2655 GNUNET_assert (failure_offset <= bd.put_path_length + get_path_length
2421 if (failure_offset >= bd.put_path_length) 2656 + 1);
2422 { 2657 if (failure_offset < bd.put_path_length)
2423 /* failure on get path */
2424 get_path_length -= (failure_offset - bd.put_path_length);
2425 gp = &xget_path[failure_offset - bd.put_path_length];
2426 bd.put_path_length = 0;
2427 }
2428 else
2429 { 2658 {
2430 /* failure on put path */ 2659 /* failure on put path */
2660 trunc_peer = &bd.put_path[failure_offset - 1].pred;
2661 bd.ro |= GNUNET_DHT_RO_TRUNCATED;
2431 bd.put_path = &bd.put_path[failure_offset]; 2662 bd.put_path = &bd.put_path[failure_offset];
2432 bd.put_path_length -= failure_offset; 2663 bd.put_path_length -= failure_offset;
2664 truncated = true;
2665 }
2666 else
2667 {
2668 /* failure on get path */
2669 failure_offset -= bd.put_path_length;
2670 if (0 == failure_offset)
2671 trunc_peer = &bd.put_path[bd.put_path_length - 1].pred;
2672 else
2673 trunc_peer = &gp[failure_offset - 1].pred;
2674 get_path_length -= failure_offset;
2675 gp = &gp[failure_offset];
2676 bd.put_path_length = 0;
2677 bd.put_path = NULL;
2678 bd.ro |= GNUNET_DHT_RO_TRUNCATED;
2679 truncated = true;
2433 } 2680 }
2434 } 2681 }
2435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2682 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2436 "Extending GET path of length %u with %s\n", 2683 "Extending GET path of length %u with %s\n",
2437 get_path_length, 2684 get_path_length,
2438 GNUNET_i2s (&peer->id)); 2685 GNUNET_i2s (&peer->id));
2686 if (truncated)
2687 {
2688 GNUNET_assert (NULL != trunc_peer);
2689 bd.trunc_peer = *trunc_peer;
2690 }
2439 GNUNET_break (process_reply_with_path (&bd, 2691 GNUNET_break (process_reply_with_path (&bd,
2440 &prm->key, 2692 &prm->key,
2441 get_path_length + 1, 2693 get_path_length + 1,
2442 gp)); 2694 gp));
2443 } 2695 }
2696 else
2697 {
2698 if (truncated)
2699 {
2700 GNUNET_assert (NULL != trunc_peer);
2701 bd.trunc_peer = *trunc_peer;
2702 }
2703 GNUNET_break (process_reply_with_path (&bd,
2704 &prm->key,
2705 0,
2706 NULL));
2707 }
2444} 2708}
2445 2709
2446 2710
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)
455 * @param cls closure 455 * @param cls closure
456 * @param exp when will this value expire 456 * @param exp when will this value expire
457 * @param key key of the result 457 * @param key key of the result
458 * @param trunc_peer peer the path was truncated at, or NULL
458 * @param get_path peers on reply path (or NULL if not recorded) 459 * @param get_path peers on reply path (or NULL if not recorded)
459 * [0] = datastore's first neighbor, [length - 1] = local peer 460 * [0] = datastore's first neighbor, [length - 1] = local peer
460 * @param get_path_length number of entries in @a get_path 461 * @param get_path_length number of entries in @a get_path
@@ -469,12 +470,14 @@ static void
469get_iter (void *cls, 470get_iter (void *cls,
470 struct GNUNET_TIME_Absolute exp, 471 struct GNUNET_TIME_Absolute exp,
471 const struct GNUNET_HashCode *key, 472 const struct GNUNET_HashCode *key,
473 const struct GNUNET_PeerIdentity *trunc_peer,
472 const struct GNUNET_DHT_PathElement *get_path, 474 const struct GNUNET_DHT_PathElement *get_path,
473 unsigned int get_path_length, 475 unsigned int get_path_length,
474 const struct GNUNET_DHT_PathElement *put_path, 476 const struct GNUNET_DHT_PathElement *put_path,
475 unsigned int put_path_length, 477 unsigned int put_path_length,
476 enum GNUNET_BLOCK_Type type, 478 enum GNUNET_BLOCK_Type type,
477 size_t size, const void *data) 479 size_t size,
480 const void *data)
478{ 481{
479 struct ActiveContext *ac = cls; 482 struct ActiveContext *ac = cls;
480 struct ActiveContext *get_ac = ac->get_ac; 483 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
87test_get_iterator (void *cls, 87test_get_iterator (void *cls,
88 struct GNUNET_TIME_Absolute exp, 88 struct GNUNET_TIME_Absolute exp,
89 const struct GNUNET_HashCode *key, 89 const struct GNUNET_HashCode *key,
90 const struct GNUNET_PeerIdentity *trunc_peer,
90 const struct GNUNET_DHT_PathElement *get_path, 91 const struct GNUNET_DHT_PathElement *get_path,
91 unsigned int get_path_length, 92 unsigned int get_path_length,
92 const struct GNUNET_DHT_PathElement *put_path, 93 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)
163 * @param cls closure with our 'struct GetOperation' 163 * @param cls closure with our 'struct GetOperation'
164 * @param exp when will this value expire 164 * @param exp when will this value expire
165 * @param key key of the result 165 * @param key key of the result
166 * @param trunc_peer peer the path was truncated at, or NULL
166 * @param get_path peers on reply path (or NULL if not recorded) 167 * @param get_path peers on reply path (or NULL if not recorded)
167 * @param get_path_length number of entries in get_path 168 * @param get_path_length number of entries in get_path
168 * @param put_path peers on the PUT path (or NULL if not recorded) 169 * @param put_path peers on the PUT path (or NULL if not recorded)
@@ -174,6 +175,7 @@ timeout_task_cb (void *cls)
174static void 175static void
175dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp, 176dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp,
176 const struct GNUNET_HashCode *key, 177 const struct GNUNET_HashCode *key,
178 const struct GNUNET_PeerIdentity *trunc_peer,
177 const struct GNUNET_DHT_PathElement *get_path, 179 const struct GNUNET_DHT_PathElement *get_path,
178 unsigned int get_path_length, 180 unsigned int get_path_length,
179 const struct GNUNET_DHT_PathElement *put_path, 181 const struct GNUNET_DHT_PathElement *put_path,
@@ -189,7 +191,9 @@ dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp,
189 GNUNET_break (0); 191 GNUNET_break (0);
190 return; 192 return;
191 } 193 }
192 GNUNET_CRYPTO_hash (key, sizeof(*key), &want); 194 GNUNET_CRYPTO_hash (key,
195 sizeof(*key),
196 &want);
193 if (0 != memcmp (&want, data, sizeof(want))) 197 if (0 != memcmp (&want, data, sizeof(want)))
194 { 198 {
195 GNUNET_break (0); 199 GNUNET_break (0);
@@ -249,8 +253,6 @@ do_puts (void *cls)
249 * @param options Options, for instance RecordRoute, DemultiplexEverywhere. 253 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
250 * @param type The type of data in the request. 254 * @param type The type of data in the request.
251 * @param hop_count Hop count so far. 255 * @param hop_count Hop count so far.
252 * @param path_length number of entries in path (or 0 if not recorded).
253 * @param path peers on the GET path (or NULL if not recorded).
254 * @param desired_replication_level Desired replication level. 256 * @param desired_replication_level Desired replication level.
255 * @param key Key of the requested data. 257 * @param key Key of the requested data.
256 */ 258 */
@@ -260,8 +262,6 @@ monitor_get_cb (void *cls,
260 enum GNUNET_BLOCK_Type type, 262 enum GNUNET_BLOCK_Type type,
261 uint32_t hop_count, 263 uint32_t hop_count,
262 uint32_t desired_replication_level, 264 uint32_t desired_replication_level,
263 unsigned int path_length,
264 const struct GNUNET_DHT_PathElement *path,
265 const struct GNUNET_HashCode *key) 265 const struct GNUNET_HashCode *key)
266{ 266{
267 unsigned int i; 267 unsigned int i;
@@ -283,6 +283,7 @@ monitor_get_cb (void *cls,
283 * @param options Options, for instance RecordRoute, DemultiplexEverywhere. 283 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
284 * @param type The type of data in the request. 284 * @param type The type of data in the request.
285 * @param hop_count Hop count so far. 285 * @param hop_count Hop count so far.
286 * @param trunc_peer peer the path was truncated at, or NULL
286 * @param path_length number of entries in path (or 0 if not recorded). 287 * @param path_length number of entries in path (or 0 if not recorded).
287 * @param path peers on the PUT path (or NULL if not recorded). 288 * @param path peers on the PUT path (or NULL if not recorded).
288 * @param desired_replication_level Desired replication level. 289 * @param desired_replication_level Desired replication level.
@@ -297,6 +298,7 @@ monitor_put_cb (void *cls,
297 enum GNUNET_BLOCK_Type type, 298 enum GNUNET_BLOCK_Type type,
298 uint32_t hop_count, 299 uint32_t hop_count,
299 uint32_t desired_replication_level, 300 uint32_t desired_replication_level,
301 const struct GNUNET_PeerIdentity *trunc_peer,
300 unsigned int path_length, 302 unsigned int path_length,
301 const struct GNUNET_DHT_PathElement *path, 303 const struct GNUNET_DHT_PathElement *path,
302 struct GNUNET_TIME_Absolute exp, 304 struct GNUNET_TIME_Absolute exp,
@@ -322,6 +324,7 @@ monitor_put_cb (void *cls,
322 * 324 *
323 * @param cls Closure. 325 * @param cls Closure.
324 * @param type The type of data in the result. 326 * @param type The type of data in the result.
327 * @param trunc_peer peer the path was truncated at, or NULL
325 * @param get_path Peers on GET path (or NULL if not recorded). 328 * @param get_path Peers on GET path (or NULL if not recorded).
326 * @param get_path_length number of entries in get_path. 329 * @param get_path_length number of entries in get_path.
327 * @param put_path peers on the PUT path (or NULL if not recorded). 330 * @param put_path peers on the PUT path (or NULL if not recorded).
@@ -334,6 +337,7 @@ monitor_put_cb (void *cls,
334static void 337static void
335monitor_res_cb (void *cls, 338monitor_res_cb (void *cls,
336 enum GNUNET_BLOCK_Type type, 339 enum GNUNET_BLOCK_Type type,
340 const struct GNUNET_PeerIdentity *trunc_peer,
337 const struct GNUNET_DHT_PathElement *get_path, 341 const struct GNUNET_DHT_PathElement *get_path,
338 unsigned int get_path_length, 342 unsigned int get_path_length,
339 const struct GNUNET_DHT_PathElement *put_path, 343 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)
327 * @param cls closure with our 'struct GetOperation' 327 * @param cls closure with our 'struct GetOperation'
328 * @param exp when will this value expire 328 * @param exp when will this value expire
329 * @param query query hash 329 * @param query query hash
330 * @param trunc_peer peer the path was truncated at, or NULL
330 * @param get_path peers on reply path (or NULL if not recorded) 331 * @param get_path peers on reply path (or NULL if not recorded)
331 * @param get_path_length number of entries in @a get_path 332 * @param get_path_length number of entries in @a get_path
332 * @param put_path peers on the PUT path (or NULL if not recorded) 333 * @param put_path peers on the PUT path (or NULL if not recorded)
@@ -339,6 +340,7 @@ static void
339dht_get_handler (void *cls, 340dht_get_handler (void *cls,
340 struct GNUNET_TIME_Absolute exp, 341 struct GNUNET_TIME_Absolute exp,
341 const struct GNUNET_HashCode *query, 342 const struct GNUNET_HashCode *query,
343 const struct GNUNET_PeerIdentity *trunc_peer,
342 const struct GNUNET_DHT_PathElement *get_path, 344 const struct GNUNET_DHT_PathElement *get_path,
343 unsigned int get_path_length, 345 unsigned int get_path_length,
344 const struct GNUNET_DHT_PathElement *put_path, 346 const struct GNUNET_DHT_PathElement *put_path,
@@ -380,6 +382,7 @@ dht_get_handler (void *cls,
380 GNUNET_DHT_verify_path (data, 382 GNUNET_DHT_verify_path (data,
381 size, 383 size,
382 exp, 384 exp,
385 trunc_peer,
383 put_path, 386 put_path,
384 put_path_length, 387 put_path_length,
385 get_path, 388 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)
1077 * @param cls closure 1077 * @param cls closure
1078 * @param exp when will this value expire 1078 * @param exp when will this value expire
1079 * @param key key of the result 1079 * @param key key of the result
1080 * @param trunc_peer truncated peer, NULL for none
1080 * @param get_path peers on reply path (or NULL if not recorded) 1081 * @param get_path peers on reply path (or NULL if not recorded)
1081 * @param get_path_length number of entries in @a get_path 1082 * @param get_path_length number of entries in @a get_path
1082 * @param put_path peers on the PUT path (or NULL if not recorded) 1083 * @param put_path peers on the PUT path (or NULL if not recorded)
@@ -1089,6 +1090,7 @@ static void
1089handle_dht_reply (void *cls, 1090handle_dht_reply (void *cls,
1090 struct GNUNET_TIME_Absolute exp, 1091 struct GNUNET_TIME_Absolute exp,
1091 const struct GNUNET_HashCode *key, 1092 const struct GNUNET_HashCode *key,
1093 const struct GNUNET_PeerIdentity *trunc_peer,
1092 const struct GNUNET_DHT_PathElement *get_path, 1094 const struct GNUNET_DHT_PathElement *get_path,
1093 unsigned int get_path_length, 1095 unsigned int get_path_length,
1094 const struct GNUNET_DHT_PathElement *put_path, 1096 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,
1335} 1335}
1336 1336
1337 1337
1338
1339/** 1338/**
1340 * We encountered a CNAME record during our resolution. 1339 * We encountered a CNAME record during our resolution.
1341 * Merge it into our chain. 1340 * Merge it into our chain.
@@ -1392,7 +1391,6 @@ handle_gns_resolution_result (void *cls,
1392 const struct GNUNET_GNSRECORD_Data *rd); 1391 const struct GNUNET_GNSRECORD_Data *rd);
1393 1392
1394 1393
1395
1396/** 1394/**
1397 * We have resolved one or more of the nameservers for a 1395 * We have resolved one or more of the nameservers for a
1398 * GNS2DNS lookup. Once we have some of them, begin using 1396 * GNS2DNS lookup. Once we have some of them, begin using
@@ -1592,6 +1590,7 @@ handle_gns2dns_ip (void *cls,
1592 ac->authority_info.dns_authority.found = GNUNET_YES; 1590 ac->authority_info.dns_authority.found = GNUNET_YES;
1593} 1591}
1594 1592
1593
1595/** 1594/**
1596 * We found a REDIRECT record, perform recursive resolution on it. 1595 * We found a REDIRECT record, perform recursive resolution on it.
1597 * 1596 *
@@ -2329,7 +2328,7 @@ handle_gns_resolution_result (void *cls,
2329 _ ("Unable to process critical delegation record\n")); 2328 _ ("Unable to process critical delegation record\n"));
2330 break; 2329 break;
2331 } 2330 }
2332 fail: 2331fail:
2333 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2332 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2334 _ ("GNS lookup recursion failed (no delegation record found)\n")); 2333 _ ("GNS lookup recursion failed (no delegation record found)\n"));
2335 fail_resolution (rh); 2334 fail_resolution (rh);
@@ -2370,6 +2369,7 @@ namecache_cache_continuation (void *cls,
2370 * @param cls closure with the `struct GNS_ResolverHandle` 2369 * @param cls closure with the `struct GNS_ResolverHandle`
2371 * @param exp when will this value expire 2370 * @param exp when will this value expire
2372 * @param key key of the result 2371 * @param key key of the result
2372 * @param trunc_peer truncated peer, NULL if not truncated
2373 * @param get_path peers on reply path (or NULL if not recorded) 2373 * @param get_path peers on reply path (or NULL if not recorded)
2374 * [0] = datastore's first neighbor, [length - 1] = local peer 2374 * [0] = datastore's first neighbor, [length - 1] = local peer
2375 * @param get_path_length number of entries in @a get_path 2375 * @param get_path_length number of entries in @a get_path
@@ -2384,6 +2384,7 @@ static void
2384handle_dht_response (void *cls, 2384handle_dht_response (void *cls,
2385 struct GNUNET_TIME_Absolute exp, 2385 struct GNUNET_TIME_Absolute exp,
2386 const struct GNUNET_HashCode *key, 2386 const struct GNUNET_HashCode *key,
2387 const struct GNUNET_PeerIdentity *trunc_peer,
2387 const struct GNUNET_DHT_PathElement *get_path, 2388 const struct GNUNET_DHT_PathElement *get_path,
2388 unsigned int get_path_length, 2389 unsigned int get_path_length,
2389 const struct GNUNET_DHT_PathElement *put_path, 2390 const struct GNUNET_DHT_PathElement *put_path,
@@ -2552,7 +2553,8 @@ handle_namecache_block_response (void *cls,
2552 else 2553 else
2553 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2554 "Got block with expiration %s\n", 2555 "Got block with expiration %s\n",
2555 GNUNET_STRINGS_absolute_time_to_string (GNUNET_GNSRECORD_block_get_expiration (block))); 2556 GNUNET_STRINGS_absolute_time_to_string (
2557 GNUNET_GNSRECORD_block_get_expiration (block)));
2556 if (((GNUNET_GNS_LO_DEFAULT == rh->options) || 2558 if (((GNUNET_GNS_LO_DEFAULT == rh->options) ||
2557 ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) && 2559 ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) &&
2558 (ac != rh->ac_head))) && 2560 (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
@@ -66,6 +66,12 @@ struct GNUNET_DATACACHE_Block
66 struct GNUNET_TIME_Absolute expiration_time; 66 struct GNUNET_TIME_Absolute expiration_time;
67 67
68 /** 68 /**
69 * If the path was truncated, this is the peer
70 * ID at which the path was truncated.
71 */
72 struct GNUNET_PeerIdentity trunc_peer;
73
74 /**
69 * PUT path taken by the block, array of peer identities. 75 * PUT path taken by the block, array of peer identities.
70 */ 76 */
71 const struct GNUNET_DHT_PathElement *put_path; 77 const struct GNUNET_DHT_PathElement *put_path;
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);
268 * @param cls closure 268 * @param cls closure
269 * @param exp when will this value expire 269 * @param exp when will this value expire
270 * @param query_hash key of the query 270 * @param query_hash key of the query
271 * @param trunc_peer peer where the path was truncated, or NULL if the path is complete
271 * @param get_path peers on reply path (or NULL if not recorded) 272 * @param get_path peers on reply path (or NULL if not recorded)
272 * [0] = datastore's first neighbor, [length - 1] = local peer 273 * [0] = datastore's first neighbor, [length - 1] = local peer
273 * @param get_path_length number of entries in @a get_path 274 * @param get_path_length number of entries in @a get_path
@@ -284,6 +285,7 @@ typedef void
284(*GNUNET_DHT_GetIterator) (void *cls, 285(*GNUNET_DHT_GetIterator) (void *cls,
285 struct GNUNET_TIME_Absolute exp, 286 struct GNUNET_TIME_Absolute exp,
286 const struct GNUNET_HashCode *query_hash, 287 const struct GNUNET_HashCode *query_hash,
288 const struct GNUNET_PeerIdentity *trunc_peer,
287 const struct GNUNET_DHT_PathElement *get_path, 289 const struct GNUNET_DHT_PathElement *get_path,
288 unsigned int get_path_length, 290 unsigned int get_path_length,
289 const struct GNUNET_DHT_PathElement *put_path, 291 const struct GNUNET_DHT_PathElement *put_path,
@@ -359,10 +361,6 @@ struct GNUNET_DHT_MonitorHandle;
359 * @param options Options, for instance RecordRoute, DemultiplexEverywhere. 361 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
360 * @param type The type of data in the request. 362 * @param type The type of data in the request.
361 * @param hop_count Hop count so far. 363 * @param hop_count Hop count so far.
362 * @param path_length number of entries in @a path (or 0 if not recorded).
363 * @param path peers on the GET path (or NULL if not recorded).
364 * note that the last signature will be all zeros as
365 * we did not forward and thus did not sign!
366 * @param desired_replication_level Desired replication level. 364 * @param desired_replication_level Desired replication level.
367 * @param key Key of the requested data. 365 * @param key Key of the requested data.
368 */ 366 */
@@ -372,8 +370,6 @@ typedef void
372 enum GNUNET_BLOCK_Type type, 370 enum GNUNET_BLOCK_Type type,
373 uint32_t hop_count, 371 uint32_t hop_count,
374 uint32_t desired_replication_level, 372 uint32_t desired_replication_level,
375 unsigned int path_length,
376 const struct GNUNET_DHT_PathElement *path,
377 const struct GNUNET_HashCode *key); 373 const struct GNUNET_HashCode *key);
378 374
379 375
@@ -382,6 +378,7 @@ typedef void
382 * 378 *
383 * @param cls Closure. 379 * @param cls Closure.
384 * @param type The type of data in the result. 380 * @param type The type of data in the result.
381 * @param trunc_peer peer where the path was truncated, or NULL if the path is complete
385 * @param get_path Peers on GET path (or NULL if not recorded). 382 * @param get_path Peers on GET path (or NULL if not recorded).
386 * note that the last signature will be all zeros as 383 * note that the last signature will be all zeros as
387 * we did not forward and thus did not sign! 384 * we did not forward and thus did not sign!
@@ -396,6 +393,7 @@ typedef void
396typedef void 393typedef void
397(*GNUNET_DHT_MonitorGetRespCB) (void *cls, 394(*GNUNET_DHT_MonitorGetRespCB) (void *cls,
398 enum GNUNET_BLOCK_Type type, 395 enum GNUNET_BLOCK_Type type,
396 const struct GNUNET_PeerIdentity *trunc_peer,
399 const struct GNUNET_DHT_PathElement *get_path, 397 const struct GNUNET_DHT_PathElement *get_path,
400 unsigned int get_path_length, 398 unsigned int get_path_length,
401 const struct GNUNET_DHT_PathElement *put_path, 399 const struct GNUNET_DHT_PathElement *put_path,
@@ -413,11 +411,12 @@ typedef void
413 * @param options Options, for instance RecordRoute, DemultiplexEverywhere. 411 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
414 * @param type The type of data in the request. 412 * @param type The type of data in the request.
415 * @param hop_count Hop count so far. 413 * @param hop_count Hop count so far.
414 * @param desired_replication_level Desired replication level.
415 * @param trunc_peer peer where the path was truncated, or NULL if the path is complete
416 * @param path_length number of entries in @a path (or 0 if not recorded). 416 * @param path_length number of entries in @a path (or 0 if not recorded).
417 * @param path peers on the PUT path (or NULL if not recorded). 417 * @param path peers on the PUT path (or NULL if not recorded).
418 * note that the last signature will be all zeros as 418 * note that the last signature will be all zeros as
419 * we did not forward and thus did not sign! 419 * we did not forward and thus did not sign!
420 * @param desired_replication_level Desired replication level.
421 * @param exp Expiration time of the data. 420 * @param exp Expiration time of the data.
422 * @param key Key under which data is to be stored. 421 * @param key Key under which data is to be stored.
423 * @param data Pointer to the data carried. 422 * @param data Pointer to the data carried.
@@ -429,6 +428,7 @@ typedef void
429 enum GNUNET_BLOCK_Type type, 428 enum GNUNET_BLOCK_Type type,
430 uint32_t hop_count, 429 uint32_t hop_count,
431 uint32_t desired_replication_level, 430 uint32_t desired_replication_level,
431 const struct GNUNET_PeerIdentity *trunc_peer,
432 unsigned int path_length, 432 unsigned int path_length,
433 const struct GNUNET_DHT_PathElement *path, 433 const struct GNUNET_DHT_PathElement *path,
434 struct GNUNET_TIME_Absolute exp, 434 struct GNUNET_TIME_Absolute exp,
@@ -491,6 +491,8 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path,
491 * @param data payload (the block) 491 * @param data payload (the block)
492 * @param data_size number of bytes in @a data 492 * @param data_size number of bytes in @a data
493 * @param exp_time expiration time of @a data 493 * @param exp_time expiration time of @a data
494 * @param trunc_peer peer which signature was broken or where the path was truncated,
495 * NULL if path is not truncated
494 * @param get_path array of path elements to verify 496 * @param get_path array of path elements to verify
495 * @param get_path_len length of the @a get_path array 497 * @param get_path_len length of the @a get_path array
496 * @param put_path array of path elements to verify 498 * @param put_path array of path elements to verify
@@ -498,12 +500,13 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path,
498 * @param me our own peer identity (needed to verify the last element) 500 * @param me our own peer identity (needed to verify the last element)
499 * @return 0 on success, otherwise the index of 501 * @return 0 on success, otherwise the index of
500 * the last path element that succeeded with verification; 502 * the last path element that succeeded with verification;
501 * @a get_path_len + @a put_path_len - 1 if no signature was valid 503 * @a get_path_len + @a put_path_len if no signature was valid
502 */ 504 */
503unsigned int 505unsigned int
504GNUNET_DHT_verify_path (const void *data, 506GNUNET_DHT_verify_path (const void *data,
505 size_t data_size, 507 size_t data_size,
506 struct GNUNET_TIME_Absolute exp_time, 508 struct GNUNET_TIME_Absolute exp_time,
509 const struct GNUNET_PeerIdentity *trunc_peer,
507 const struct GNUNET_DHT_PathElement *put_path, 510 const struct GNUNET_DHT_PathElement *put_path,
508 unsigned int put_path_len, 511 unsigned int put_path_len,
509 const struct GNUNET_DHT_PathElement *get_path, 512 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 ()
1126 * @param cls closure 1126 * @param cls closure
1127 * @param exp when will this value expire 1127 * @param exp when will this value expire
1128 * @param key key of the result 1128 * @param key key of the result
1129 * @param trunc_peer peer that was truncated (or NULL if not truncated)
1129 * @param get_path peers on reply path (or NULL if not recorded) 1130 * @param get_path peers on reply path (or NULL if not recorded)
1130 * [0] = datastore's first neighbor, [length - 1] = local peer 1131 * [0] = datastore's first neighbor, [length - 1] = local peer
1131 * @param get_path_length number of entries in @a get_path 1132 * @param get_path_length number of entries in @a get_path
@@ -1140,6 +1141,7 @@ static void
1140handle_dht_result (void *cls, 1141handle_dht_result (void *cls,
1141 struct GNUNET_TIME_Absolute exp, 1142 struct GNUNET_TIME_Absolute exp,
1142 const struct GNUNET_HashCode *key, 1143 const struct GNUNET_HashCode *key,
1144 const struct GNUNET_PeerIdentity *trunc_peer,
1143 const struct GNUNET_DHT_PathElement *get_path, 1145 const struct GNUNET_DHT_PathElement *get_path,
1144 unsigned int get_path_length, 1146 unsigned int get_path_length,
1145 const struct GNUNET_DHT_PathElement *put_path, 1147 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,
372 * 372 *
373 * @param cls Closure (search context). 373 * @param cls Closure (search context).
374 * @param exp When will this value expire. 374 * @param exp When will this value expire.
375 * @param trunc_peer truncated peer, or NULL if none was truncated
375 * @param key Key of the result. 376 * @param key Key of the result.
376 * @param get_path Path of the get request. 377 * @param get_path Path of the get request.
377 * @param get_path_length Length of get_path. 378 * @param get_path_length Length of get_path.
@@ -384,6 +385,7 @@ regex_next_edge (const struct RegexBlock *block,
384static void 385static void
385dht_get_string_accept_handler (void *cls, struct GNUNET_TIME_Absolute exp, 386dht_get_string_accept_handler (void *cls, struct GNUNET_TIME_Absolute exp,
386 const struct GNUNET_HashCode *key, 387 const struct GNUNET_HashCode *key,
388 const struct GNUNET_PeerIdentity *trunc_peer,
387 const struct GNUNET_DHT_PathElement *get_path, 389 const struct GNUNET_DHT_PathElement *get_path,
388 unsigned int get_path_length, 390 unsigned int get_path_length,
389 const struct GNUNET_DHT_PathElement *put_path, 391 const struct GNUNET_DHT_PathElement *put_path,
@@ -451,6 +453,7 @@ regex_find_path (const struct GNUNET_HashCode *key,
451 * @param cls closure (search context) 453 * @param cls closure (search context)
452 * @param exp when will this value expire 454 * @param exp when will this value expire
453 * @param key key of the result 455 * @param key key of the result
456 * @param trunc_peer NULL if not truncated
454 * @param get_path path of the get request (not used) 457 * @param get_path path of the get request (not used)
455 * @param get_path_length length of @a get_path (not used) 458 * @param get_path_length length of @a get_path (not used)
456 * @param put_path path of the put request (not used) 459 * @param put_path path of the put request (not used)
@@ -464,6 +467,7 @@ regex_find_path (const struct GNUNET_HashCode *key,
464static void 467static void
465dht_get_string_handler (void *cls, struct GNUNET_TIME_Absolute exp, 468dht_get_string_handler (void *cls, struct GNUNET_TIME_Absolute exp,
466 const struct GNUNET_HashCode *key, 469 const struct GNUNET_HashCode *key,
470 const struct GNUNET_PeerIdentity *trunc_peer,
467 const struct GNUNET_DHT_PathElement *get_path, 471 const struct GNUNET_DHT_PathElement *get_path,
468 unsigned int get_path_length, 472 unsigned int get_path_length,
469 const struct GNUNET_DHT_PathElement *put_path, 473 const struct GNUNET_DHT_PathElement *put_path,