aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-02-26 01:57:13 +0100
committerChristian Grothoff <christian@grothoff.org>2022-02-26 01:57:13 +0100
commit8fe9edb11728c34de80242b438cbb0d75e26a04d (patch)
tree00fbb48deb1f4451b864a78b38e3f0bc80fb8f39
parentd4c1c6f32d949ed493ba286d81fc172f57fe0ffe (diff)
downloadgnunet-8fe9edb11728c34de80242b438cbb0d75e26a04d.tar.gz
gnunet-8fe9edb11728c34de80242b438cbb0d75e26a04d.zip
-hack up GET/PUT signatures, still broken by design
m---------contrib/gana0
-rw-r--r--po/POTFILES.in3
-rw-r--r--src/dht/Makefile.am2
-rw-r--r--src/dht/dht_api.c159
-rw-r--r--src/dht/gnunet-service-dht.h3
-rw-r--r--src/dht/gnunet-service-dht_clients.c29
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c177
-rw-r--r--src/dht/gnunet-service-dht_neighbours.h3
-rw-r--r--src/dht/gnunet-service-dht_routing.c10
-rw-r--r--src/dht/test_dht_topo.c26
-rw-r--r--src/include/gnunet_dht_service.h51
11 files changed, 320 insertions, 143 deletions
diff --git a/contrib/gana b/contrib/gana
Subproject ca97ba9b2ba3d47197456dec2ec4a4c9358329f Subproject 887d4485ea88e42e0b339b7a992420bc1e4e1e7
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d2e44dec1..5c1152e7c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -175,7 +175,6 @@ src/gns/nss/nss_gns_query.c
175src/gns/plugin_block_gns.c 175src/gns/plugin_block_gns.c
176src/gns/plugin_gnsrecord_gns.c 176src/gns/plugin_gnsrecord_gns.c
177src/gns/plugin_rest_gns.c 177src/gns/plugin_rest_gns.c
178src/gns/test.c
179src/gnsrecord/gnsrecord.c 178src/gnsrecord/gnsrecord.c
180src/gnsrecord/gnsrecord_crypto.c 179src/gnsrecord/gnsrecord_crypto.c
181src/gnsrecord/gnsrecord_misc.c 180src/gnsrecord/gnsrecord_misc.c
@@ -183,7 +182,6 @@ src/gnsrecord/gnsrecord_serialization.c
183src/gnsrecord/gnunet-gnsrecord-tvg.c 182src/gnsrecord/gnunet-gnsrecord-tvg.c
184src/gnsrecord/json_gnsrecord.c 183src/gnsrecord/json_gnsrecord.c
185src/gnsrecord/plugin_gnsrecord_dns.c 184src/gnsrecord/plugin_gnsrecord_dns.c
186src/gnsrecord/test.c
187src/hello/address.c 185src/hello/address.c
188src/hello/gnunet-hello.c 186src/hello/gnunet-hello.c
189src/hello/hello-ng.c 187src/hello/hello-ng.c
@@ -316,7 +314,6 @@ src/reclaim/plugin_rest_reclaim.c
316src/reclaim/reclaim_api.c 314src/reclaim/reclaim_api.c
317src/reclaim/reclaim_attribute.c 315src/reclaim/reclaim_attribute.c
318src/reclaim/reclaim_credential.c 316src/reclaim/reclaim_credential.c
319src/reclaim/test.c
320src/regex/gnunet-daemon-regexprofiler.c 317src/regex/gnunet-daemon-regexprofiler.c
321src/regex/gnunet-regex-profiler.c 318src/regex/gnunet-regex-profiler.c
322src/regex/gnunet-regex-simulation-profiler.c 319src/regex/gnunet-regex-simulation-profiler.c
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
index f9cd26094..1e14367c8 100644
--- a/src/dht/Makefile.am
+++ b/src/dht/Makefile.am
@@ -90,7 +90,7 @@ gnunet_dht_hello_SOURCES = \
90gnunet_dht_hello_LDADD = \ 90gnunet_dht_hello_LDADD = \
91 libgnunetdht.la \ 91 libgnunetdht.la \
92 $(top_builddir)/src/util/libgnunetutil.la 92 $(top_builddir)/src/util/libgnunetutil.la
93gnunet_dht_get_LDFLAGS = \ 93gnunet_dht_hello_LDFLAGS = \
94 $(GN_LIBINTL) 94 $(GN_LIBINTL)
95 95
96gnunet_dht_put_SOURCES = \ 96gnunet_dht_put_SOURCES = \
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c
index d60653dd4..a16db6d4b 100644
--- a/src/dht/dht_api.c
+++ b/src/dht/dht_api.c
@@ -561,9 +561,10 @@ handle_monitor_get (void *cls,
561 const struct GNUNET_DHT_MonitorGetMessage *msg) 561 const struct GNUNET_DHT_MonitorGetMessage *msg)
562{ 562{
563 struct GNUNET_DHT_Handle *handle = cls; 563 struct GNUNET_DHT_Handle *handle = cls;
564 struct GNUNET_DHT_MonitorHandle *mh;
565 564
566 for (mh = handle->monitor_head; NULL != mh; mh = mh->next) 565 for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
566 NULL != mh;
567 mh = mh->next)
567 { 568 {
568 if (NULL == mh->get_cb) 569 if (NULL == mh->get_cb)
569 continue; 570 continue;
@@ -626,10 +627,12 @@ handle_monitor_get_resp (void *cls,
626 const struct GNUNET_DHT_PathElement *path; 627 const struct GNUNET_DHT_PathElement *path;
627 uint32_t getl = ntohl (msg->get_path_length); 628 uint32_t getl = ntohl (msg->get_path_length);
628 uint32_t putl = ntohl (msg->put_path_length); 629 uint32_t putl = ntohl (msg->put_path_length);
629 struct GNUNET_DHT_MonitorHandle *mh; 630
630 631
631 path = (const struct GNUNET_DHT_PathElement *) &msg[1]; 632 path = (const struct GNUNET_DHT_PathElement *) &msg[1];
632 for (mh = handle->monitor_head; NULL != mh; mh = mh->next) 633 for (struct GNUNET_DHT_MonitorHandle *mh = handle->monitor_head;
634 NULL != mh;
635 mh = mh->next)
633 { 636 {
634 if (NULL == mh->get_resp_cb) 637 if (NULL == mh->get_resp_cb)
635 continue; 638 continue;
@@ -641,9 +644,9 @@ handle_monitor_get_resp (void *cls,
641 sizeof(struct GNUNET_HashCode))))) 644 sizeof(struct GNUNET_HashCode)))))
642 mh->get_resp_cb (mh->cb_cls, 645 mh->get_resp_cb (mh->cb_cls,
643 (enum GNUNET_BLOCK_Type) ntohl (msg->type), 646 (enum GNUNET_BLOCK_Type) ntohl (msg->type),
644 path, 647 &path[putl],
645 getl, 648 getl,
646 &path[getl], 649 path,
647 putl, 650 putl,
648 GNUNET_TIME_absolute_ntoh (msg->expiration_time), 651 GNUNET_TIME_absolute_ntoh (msg->expiration_time),
649 &msg->key, 652 &msg->key,
@@ -773,12 +776,18 @@ process_client_result (void *cls,
773 uint16_t type = ntohl (crm->type); 776 uint16_t type = ntohl (crm->type);
774 uint32_t put_path_length = ntohl (crm->put_path_length); 777 uint32_t put_path_length = ntohl (crm->put_path_length);
775 uint32_t get_path_length = ntohl (crm->get_path_length); 778 uint32_t get_path_length = ntohl (crm->get_path_length);
776 const struct GNUNET_DHT_PathElement *put_path; 779 const struct GNUNET_DHT_PathElement *put_path
777 const struct GNUNET_DHT_PathElement *get_path; 780 = (const struct GNUNET_DHT_PathElement *) &crm[1];
781 const struct GNUNET_DHT_PathElement *get_path
782 = &put_path[put_path_length];
783 const void *data
784 = &get_path[get_path_length];
785 size_t meta_length
786 = sizeof(struct GNUNET_DHT_PathElement) * (get_path_length
787 + put_path_length);
788 size_t data_length
789 = msize - meta_length;
778 struct GNUNET_HashCode hc; 790 struct GNUNET_HashCode hc;
779 size_t data_length;
780 size_t meta_length;
781 const void *data;
782 791
783 if (crm->unique_id != get_handle->unique_id) 792 if (crm->unique_id != get_handle->unique_id)
784 { 793 {
@@ -797,11 +806,7 @@ process_client_result (void *cls,
797 GNUNET_break (0); 806 GNUNET_break (0);
798 return GNUNET_YES; 807 return GNUNET_YES;
799 } 808 }
800 meta_length = 809
801 sizeof(struct GNUNET_DHT_PathElement) * (get_path_length + put_path_length);
802 data_length = msize - meta_length;
803 put_path = (const struct GNUNET_DHT_PathElement *) &crm[1];
804 get_path = &put_path[put_path_length];
805 { 810 {
806 char *pp; 811 char *pp;
807 char *gp; 812 char *gp;
@@ -819,7 +824,6 @@ process_client_result (void *cls,
819 GNUNET_free (gp); 824 GNUNET_free (gp);
820 GNUNET_free (pp); 825 GNUNET_free (pp);
821 } 826 }
822 data = &get_path[get_path_length];
823 /* remember that we've seen this result */ 827 /* remember that we've seen this result */
824 GNUNET_CRYPTO_hash (data, 828 GNUNET_CRYPTO_hash (data,
825 data_length, 829 data_length,
@@ -1296,7 +1300,7 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path,
1296 1300
1297 1301
1298unsigned int 1302unsigned int
1299GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key, 1303GNUNET_DHT_verify_path (const struct GNUNET_HashCode *query_hash,
1300 const void *data, 1304 const void *data,
1301 size_t data_size, 1305 size_t data_size,
1302 struct GNUNET_TIME_Absolute exp_time, 1306 struct GNUNET_TIME_Absolute exp_time,
@@ -1306,50 +1310,125 @@ GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key,
1306 unsigned int get_path_len, 1310 unsigned int get_path_len,
1307 const struct GNUNET_PeerIdentity *me) 1311 const struct GNUNET_PeerIdentity *me)
1308{ 1312{
1309 struct GNUNET_DHT_HopSignature hs = { 1313 struct GNUNET_DHT_PutHopSignature phs = {
1310 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), 1314 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP),
1311 .purpose.size = htonl (sizeof (hs)), 1315 .purpose.size = htonl (sizeof (phs)),
1316 .expiration_time = GNUNET_TIME_absolute_hton (exp_time)
1317 };
1318 struct GNUNET_DHT_ResultHopSignature ghs = {
1319 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP),
1320 .purpose.size = htonl (sizeof (ghs)),
1312 .expiration_time = GNUNET_TIME_absolute_hton (exp_time), 1321 .expiration_time = GNUNET_TIME_absolute_hton (exp_time),
1313 .key = *key,
1314 }; 1322 };
1323 const struct GNUNET_PeerIdentity *pred;
1324 const struct GNUNET_PeerIdentity *succ;
1315 unsigned int i; 1325 unsigned int i;
1316 1326
1317 if (0 == get_path_len + put_path_len) 1327 if (0 == get_path_len + put_path_len)
1318 return 0; 1328 return 0;
1329 if (0 != get_path_len)
1330 {
1331 GNUNET_assert (NULL != query_hash);
1332 ghs.query_hash = *query_hash;
1333 }
1319 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1334 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1320 "%s is verifying signatures for %s with GPL: %u PPL: %u!\n", 1335 "%s is verifying signatures for %s with GPL: %u PPL: %u!\n",
1321 GNUNET_i2s (me), 1336 GNUNET_i2s (me),
1322 GNUNET_h2s (key), 1337 NULL != query_hash ? GNUNET_h2s (query_hash) : "<null>",
1323 get_path_len, 1338 get_path_len,
1324 put_path_len); 1339 put_path_len);
1340 for (unsigned int j = 0; j<put_path_len; j++)
1341 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1342 "PP%u=%s\n",
1343 j,
1344 GNUNET_i2s (&put_path[j].pred));
1345 for (unsigned int j = 0; j<get_path_len; j++)
1346 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1347 "GP%u=%s\n",
1348 j,
1349 GNUNET_i2s (&get_path[j].pred));
1350
1325 i = put_path_len + get_path_len - 1; 1351 i = put_path_len + get_path_len - 1;
1326 GNUNET_CRYPTO_hash (data, 1352 GNUNET_CRYPTO_hash (data,
1327 data_size, 1353 data_size,
1328 &hs.h_data); 1354 &phs.h_data);
1355 ghs.h_data = phs.h_data;
1329 while (i > 0) 1356 while (i > 0)
1330 { 1357 {
1331 hs.pred = (i - 1 >= put_path_len) 1358 pred = (i - 1 >= put_path_len)
1332 ? get_path[i - put_path_len - 1].pred 1359 ? &get_path[i - put_path_len - 1].pred
1333 : put_path[i - 1].pred; 1360 : &put_path[i - 1].pred;
1334 if (i + 1 == get_path_len + put_path_len) 1361 if (i + 1 == get_path_len + put_path_len)
1335 hs.succ = *me; 1362 succ = me;
1336 else 1363 else
1337 hs.succ = (i + 1 >= put_path_len) 1364 succ = (i + 1 >= put_path_len)
1338 ? get_path[i + 1 - put_path_len].pred 1365 ? &get_path[i + 1 - put_path_len].pred
1339 : put_path[i + 1].pred; 1366 : &put_path[i + 1].pred;
1340 if (GNUNET_OK != 1367 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1341 GNUNET_CRYPTO_eddsa_verify ( 1368 "PRED: %s\n",
1342 GNUNET_SIGNATURE_PURPOSE_DHT_HOP, 1369 GNUNET_i2s (pred));
1343 &hs, 1370 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1344 (i - 1 >= put_path_len) 1371 "SUCC: %s\n",
1345 ? &get_path[i - put_path_len - 1].sig 1372 GNUNET_i2s (succ));
1373 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1374 "SIGNER: %s\n",
1375 GNUNET_i2s ((i >= put_path_len)
1376 ? &get_path[i - put_path_len].pred
1377 : &put_path[i].pred));
1378 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1379 "SIG: %s\n",
1380 GNUNET_B2S ((i - 1 >= put_path_len)
1381 ? &get_path[i - put_path_len - 1].sig
1382 : &put_path[i - 1].sig));
1383 if ( (i + 1 >= put_path_len) &&
1384 (0 != get_path_len) )
1385 {
1386 /* NOTE: the last signature inside the 'PUT'
1387 path is from the cross-over point and already
1388 of type RESULT_HOP, but only if we have
1389 a non-empty 'GET' path! */
1390 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1391 "Key: %s offset %u\n",
1392 GNUNET_h2s (query_hash),
1393 i);
1394 ghs.pred = *pred;
1395 ghs.succ = *succ;
1396 if (GNUNET_OK !=
1397 GNUNET_CRYPTO_eddsa_verify (
1398 GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP,
1399 &ghs,
1400 (i - 1 >= put_path_len)
1401 ? &get_path[i - put_path_len - 1].sig
1346 : &put_path[i - 1].sig, 1402 : &put_path[i - 1].sig,
1347 (i >= put_path_len) 1403 (i >= put_path_len)
1348 ? &get_path[i - put_path_len].pred.public_key 1404 ? &get_path[i - put_path_len].pred.public_key
1349 : &put_path[i].pred.public_key)) 1405 : &put_path[i].pred.public_key))
1406 {
1407 GNUNET_break_op (0);
1408 return i;
1409 }
1410 }
1411 else
1350 { 1412 {
1351 GNUNET_break_op (0); 1413 phs.pred = *pred;
1352 return i; 1414 phs.succ = *succ;
1415 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1416 "offset %u\n",
1417 i);
1418 if (GNUNET_OK !=
1419 GNUNET_CRYPTO_eddsa_verify (
1420 GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP,
1421 &phs,
1422 (i - 1 >= put_path_len)
1423 ? &get_path[i - put_path_len - 1].sig
1424 : &put_path[i - 1].sig,
1425 (i >= put_path_len)
1426 ? &get_path[i - put_path_len].pred.public_key
1427 : &put_path[i].pred.public_key))
1428 {
1429 GNUNET_break_op (0);
1430 return i;
1431 }
1353 } 1432 }
1354 i--; 1433 i--;
1355 } 1434 }
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index d3bb39455..a1513fcce 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -146,8 +146,9 @@ GDS_u_hold (struct GDS_Underlay *u,
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 get_path_length number of entries in @a get_path 147 * @param get_path_length number of entries in @a get_path
148 * @param get_path path the reply has taken 148 * @param get_path path the reply has taken
149 * @return true on success, false on failures
149 */ 150 */
150void 151bool
151GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, 152GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd,
152 const struct GNUNET_HashCode *query_hash, 153 const struct GNUNET_HashCode *query_hash,
153 unsigned int get_path_length, 154 unsigned int get_path_length,
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index 049e3d1f1..d6ce97666 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -515,9 +515,9 @@ handle_dht_local_put (void *cls,
515 "CLIENT-PUT %s\n", 515 "CLIENT-PUT %s\n",
516 GNUNET_h2s_full (&dht_msg->key)); 516 GNUNET_h2s_full (&dht_msg->key));
517 /* give to local clients */ 517 /* give to local clients */
518 GDS_CLIENTS_handle_reply (&bd, 518 GNUNET_break (GDS_CLIENTS_handle_reply (&bd,
519 &bd.key, 519 &bd.key,
520 0, NULL /* get path */); 520 0, NULL /* get path */));
521 521
522 { 522 {
523 struct GNUNET_CONTAINER_BloomFilter *peer_bf; 523 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
@@ -568,9 +568,9 @@ handle_local_result (void *cls,
568 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 568 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
569 "Datacache provided result for query key %s\n", 569 "Datacache provided result for query key %s\n",
570 GNUNET_h2s (&bd->key)); 570 GNUNET_h2s (&bd->key));
571 GDS_CLIENTS_handle_reply (bd, 571 GNUNET_break (GDS_CLIENTS_handle_reply (bd,
572 &bd->key, 572 &bd->key,
573 0, NULL /* get_path */); 573 0, NULL /* get_path */));
574} 574}
575 575
576 576
@@ -1002,7 +1002,7 @@ forward_reply (void *cls,
1002 reply->put_path_length = htonl (frc->bd->put_path_length); 1002 reply->put_path_length = htonl (frc->bd->put_path_length);
1003 reply->unique_id = record->unique_id; 1003 reply->unique_id = record->unique_id;
1004 reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time); 1004 reply->expiration = GNUNET_TIME_absolute_hton (frc->bd->expiration_time);
1005 reply->key = frc->bd->key; 1005 reply->key = *query_hash;
1006 paths = (struct GNUNET_DHT_PathElement *) &reply[1]; 1006 paths = (struct GNUNET_DHT_PathElement *) &reply[1];
1007 GNUNET_memcpy (paths, 1007 GNUNET_memcpy (paths,
1008 frc->bd->put_path, 1008 frc->bd->put_path,
@@ -1027,7 +1027,7 @@ forward_reply (void *cls,
1027} 1027}
1028 1028
1029 1029
1030void 1030bool
1031GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, 1031GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd,
1032 const struct GNUNET_HashCode *query_hash, 1032 const struct GNUNET_HashCode *query_hash,
1033 unsigned int get_path_length, 1033 unsigned int get_path_length,
@@ -1042,22 +1042,22 @@ GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd,
1042 if (msize >= GNUNET_MAX_MESSAGE_SIZE) 1042 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1043 { 1043 {
1044 GNUNET_break (0); 1044 GNUNET_break (0);
1045 return; 1045 return false;
1046 } 1046 }
1047#if SANITY_CHECKS 1047#if SANITY_CHECKS
1048 if (0 != 1048 if (0 !=
1049 GNUNET_DHT_verify_path (&bd->key, 1049 GNUNET_DHT_verify_path (query_hash,
1050 bd->data, 1050 bd->data,
1051 bd->data_size, 1051 bd->data_size,
1052 bd->expiration_time, 1052 bd->expiration_time,
1053 get_path,
1054 get_path_length,
1055 bd->put_path, 1053 bd->put_path,
1056 bd->put_path_length, 1054 bd->put_path_length,
1055 get_path,
1056 get_path_length,
1057 &GDS_my_identity)) 1057 &GDS_my_identity))
1058 { 1058 {
1059 GNUNET_break_op (0); 1059 GNUNET_break (0);
1060 return; 1060 return false;
1061 } 1061 }
1062#endif 1062#endif
1063 frc.bd = bd; 1063 frc.bd = bd;
@@ -1082,6 +1082,7 @@ GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd,
1082 1, 1082 1,
1083 GNUNET_NO); 1083 GNUNET_NO);
1084 } 1084 }
1085 return true;
1085} 1086}
1086 1087
1087 1088
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 284380647..f542dd6af 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -519,22 +519,60 @@ do_send (struct PeerInfo *pi,
519 * @param pred predecessor peer ID 519 * @param pred predecessor peer ID
520 * @param succ successor peer ID 520 * @param succ successor peer ID
521 * @param[out] sig where to write the signature 521 * @param[out] sig where to write the signature
522 * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP)
523 */
524static void
525sign_put_path (const void *data,
526 size_t data_size,
527 struct GNUNET_TIME_Absolute exp_time,
528 const struct GNUNET_PeerIdentity *pred,
529 const struct GNUNET_PeerIdentity *succ,
530 struct GNUNET_CRYPTO_EddsaSignature *sig)
531{
532 struct GNUNET_DHT_PutHopSignature hs = {
533 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP),
534 .purpose.size = htonl (sizeof (hs)),
535 .expiration_time = GNUNET_TIME_absolute_hton (exp_time),
536 .pred = *pred,
537 .succ = *succ
538 };
539
540 GNUNET_CRYPTO_hash (data,
541 data_size,
542 &hs.h_data);
543 GNUNET_CRYPTO_eddsa_sign (&GDS_my_private_key,
544 &hs,
545 sig);
546}
547
548
549/**
550 * Sign that we are routing a message from @a pred to @a succ.
551 * (So the route is $PRED->us->$SUCC).
552 *
553 * @param query_hash query being answered
554 * @param data payload (the block)
555 * @param data_size number of bytes in @a data
556 * @param exp_time expiration time of @a data
557 * @param pred predecessor peer ID
558 * @param succ successor peer ID
559 * @param[out] sig where to write the signature
522 * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_HOP) 560 * (of purpose #GNUNET_SIGNATURE_PURPOSE_DHT_HOP)
523 */ 561 */
524static void 562static void
525sign_path (const struct GNUNET_HashCode *key, 563sign_result_path (const struct GNUNET_HashCode *query_hash,
526 const void *data, 564 const void *data,
527 size_t data_size, 565 size_t data_size,
528 struct GNUNET_TIME_Absolute exp_time, 566 struct GNUNET_TIME_Absolute exp_time,
529 const struct GNUNET_PeerIdentity *pred, 567 const struct GNUNET_PeerIdentity *pred,
530 const struct GNUNET_PeerIdentity *succ, 568 const struct GNUNET_PeerIdentity *succ,
531 struct GNUNET_CRYPTO_EddsaSignature *sig) 569 struct GNUNET_CRYPTO_EddsaSignature *sig)
532{ 570{
533 struct GNUNET_DHT_HopSignature hs = { 571 struct GNUNET_DHT_ResultHopSignature hs = {
534 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), 572 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP),
535 .purpose.size = htonl (sizeof (hs)), 573 .purpose.size = htonl (sizeof (hs)),
536 .expiration_time = GNUNET_TIME_absolute_hton (exp_time), 574 .expiration_time = GNUNET_TIME_absolute_hton (exp_time),
537 .key = *key, 575 .query_hash = *query_hash,
538 .pred = *pred, 576 .pred = *pred,
539 .succ = *succ 577 .succ = *succ
540 }; 578 };
@@ -1299,7 +1337,7 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd,
1299 GNUNET_assert (NULL != bf); 1337 GNUNET_assert (NULL != bf);
1300#if SANITY_CHECKS 1338#if SANITY_CHECKS
1301 if (0 != 1339 if (0 !=
1302 GNUNET_DHT_verify_path (&bd->key, 1340 GNUNET_DHT_verify_path (NULL,
1303 bd->data, 1341 bd->data,
1304 bd->data_size, 1342 bd->data_size,
1305 bd->expiration_time, 1343 bd->expiration_time,
@@ -1393,13 +1431,12 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd,
1393 { 1431 {
1394 /* Note that the signature in 'put_path' was not initialized before, 1432 /* Note that the signature in 'put_path' was not initialized before,
1395 so this is crucial to avoid sending garbage. */ 1433 so this is crucial to avoid sending garbage. */
1396 sign_path (&bd->key, 1434 sign_put_path (bd->data,
1397 bd->data, 1435 bd->data_size,
1398 bd->data_size, 1436 bd->expiration_time,
1399 bd->expiration_time, 1437 &pp[put_path_length - 1].pred,
1400 &pp[put_path_length - 1].pred, 1438 &target->id,
1401 &target->id, 1439 &pp[put_path_length - 1].sig);
1402 &pp[put_path_length - 1].sig);
1403 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1404 "Signing PUT PATH %u => %s\n", 1441 "Signing PUT PATH %u => %s\n",
1405 put_path_length, 1442 put_path_length,
@@ -1546,7 +1583,7 @@ GDS_NEIGHBOURS_lookup_peer (const struct GNUNET_PeerIdentity *target)
1546} 1583}
1547 1584
1548 1585
1549void 1586bool
1550GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, 1587GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1551 const struct GDS_DATACACHE_BlockData *bd, 1588 const struct GDS_DATACACHE_BlockData *bd,
1552 const struct GNUNET_HashCode *query_hash, 1589 const struct GNUNET_HashCode *query_hash,
@@ -1559,7 +1596,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1559 1596
1560#if SANITY_CHECKS 1597#if SANITY_CHECKS
1561 if (0 != 1598 if (0 !=
1562 GNUNET_DHT_verify_path (&bd->key, 1599 GNUNET_DHT_verify_path (query_hash,
1563 bd->data, 1600 bd->data,
1564 bd->data_size, 1601 bd->data_size,
1565 bd->expiration_time, 1602 bd->expiration_time,
@@ -1570,8 +1607,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1570 &GDS_my_identity)) 1607 &GDS_my_identity))
1571 { 1608 {
1572 GNUNET_break_op (0); 1609 GNUNET_break_op (0);
1573 get_path_length = 0; 1610 return false;
1574 ppl = 0;
1575 } 1611 }
1576#endif 1612#endif
1577 msize = bd->data_size + (get_path_length + ppl) 1613 msize = bd->data_size + (get_path_length + ppl)
@@ -1596,7 +1632,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1596 (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) 1632 (bd->data_size > GNUNET_MAX_MESSAGE_SIZE))
1597 { 1633 {
1598 GNUNET_break (0); 1634 GNUNET_break (0);
1599 return; 1635 return false;
1600 } 1636 }
1601 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1637 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1602 "Forwarding reply for key %s to peer %s\n", 1638 "Forwarding reply for key %s to peer %s\n",
@@ -1645,13 +1681,13 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1645 { 1681 {
1646 /* Note that the last signature in 'paths' was not initialized before, 1682 /* Note that the last signature in 'paths' was not initialized before,
1647 so this is crucial to avoid sending garbage. */ 1683 so this is crucial to avoid sending garbage. */
1648 sign_path (query_hash, 1684 sign_result_path (query_hash,
1649 bd->data, 1685 bd->data,
1650 bd->data_size, 1686 bd->data_size,
1651 bd->expiration_time, 1687 bd->expiration_time,
1652 &paths[ppl + get_path_length - 1].pred, 1688 &paths[ppl + get_path_length - 1].pred,
1653 &pi->id, 1689 &pi->id,
1654 &paths[ppl + get_path_length - 1].sig); 1690 &paths[ppl + get_path_length - 1].sig);
1655 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1691 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1656 "Signing GET PATH %u/%u of %s => %s\n", 1692 "Signing GET PATH %u/%u of %s => %s\n",
1657 ppl, 1693 ppl,
@@ -1683,7 +1719,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1683 &pi->id)) 1719 &pi->id))
1684 { 1720 {
1685 GNUNET_break (0); 1721 GNUNET_break (0);
1686 return; 1722 return false;
1687 } 1723 }
1688 } 1724 }
1689#endif 1725#endif
@@ -1692,6 +1728,7 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1692 do_send (pi, 1728 do_send (pi,
1693 &prm->header); 1729 &prm->header);
1694 } 1730 }
1731 return true;
1695} 1732}
1696 1733
1697 1734
@@ -1870,9 +1907,9 @@ handle_dht_p2p_put (void *cls,
1870 } 1907 }
1871 1908
1872 /* give to local clients */ 1909 /* give to local clients */
1873 GDS_CLIENTS_handle_reply (&bd, 1910 GNUNET_break (GDS_CLIENTS_handle_reply (&bd,
1874 &bd.key, 1911 &bd.key,
1875 0, NULL /* get path */); 1912 0, NULL /* get path */));
1876 1913
1877 /* store locally */ 1914 /* store locally */
1878 if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || 1915 if ( (0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
@@ -1958,10 +1995,10 @@ handle_find_my_hello (struct PeerInfo *pi,
1958 .data_size = block_size 1995 .data_size = block_size
1959 }; 1996 };
1960 1997
1961 GDS_NEIGHBOURS_handle_reply (pi, 1998 GNUNET_break (GDS_NEIGHBOURS_handle_reply (pi,
1962 &bd, 1999 &bd,
1963 query_hash, 2000 query_hash,
1964 0, NULL /* get path */); 2001 0, NULL /* get path */));
1965 } 2002 }
1966 else 2003 else
1967 { 2004 {
@@ -2013,10 +2050,10 @@ handle_find_local_hello (struct PeerInfo *pi,
2013 .data_size = peer->hello_size 2050 .data_size = peer->hello_size
2014 }; 2051 };
2015 2052
2016 GDS_NEIGHBOURS_handle_reply (pi, 2053 GNUNET_break (GDS_NEIGHBOURS_handle_reply (pi,
2017 &bd, 2054 &bd,
2018 query_hash, 2055 query_hash,
2019 0, NULL /* get path */); 2056 0, NULL /* get path */));
2020 } 2057 }
2021} 2058}
2022 2059
@@ -2033,10 +2070,10 @@ handle_local_result (void *cls,
2033{ 2070{
2034 struct PeerInfo *peer = cls; 2071 struct PeerInfo *peer = cls;
2035 2072
2036 GDS_NEIGHBOURS_handle_reply (peer, 2073 GNUNET_break (GDS_NEIGHBOURS_handle_reply (peer,
2037 bd, 2074 bd,
2038 &bd->key, 2075 &bd->key,
2039 0, NULL /* get path */); 2076 0, NULL /* get path */));
2040} 2077}
2041 2078
2042 2079
@@ -2230,8 +2267,9 @@ handle_dht_p2p_get (void *cls,
2230 * @param query_hash hash of the original query, might not match key in @a bd 2267 * @param query_hash hash of the original query, might not match key in @a bd
2231 * @param get_path_length number of entries in @a get_path 2268 * @param get_path_length number of entries in @a get_path
2232 * @param get_path path the reply has taken 2269 * @param get_path path the reply has taken
2270 * @return true on success
2233 */ 2271 */
2234static void 2272static bool
2235process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd, 2273process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd,
2236 const struct GNUNET_HashCode *query_hash, 2274 const struct GNUNET_HashCode *query_hash,
2237 unsigned int get_path_length, 2275 unsigned int get_path_length,
@@ -2240,10 +2278,14 @@ process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd,
2240 /* forward to local clients */ 2278 /* forward to local clients */
2241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2242 "Forwarding reply to local clients\n"); 2280 "Forwarding reply to local clients\n");
2243 GDS_CLIENTS_handle_reply (bd, 2281 if (! GDS_CLIENTS_handle_reply (bd,
2244 query_hash, 2282 query_hash,
2245 get_path_length, 2283 get_path_length,
2246 get_path); 2284 get_path))
2285 {
2286 GNUNET_break (0);
2287 return false;
2288 }
2247 GDS_CLIENTS_process_get_resp (bd, 2289 GDS_CLIENTS_process_get_resp (bd,
2248 get_path, 2290 get_path,
2249 get_path_length); 2291 get_path_length);
@@ -2268,6 +2310,7 @@ process_reply_with_path (const struct GDS_DATACACHE_BlockData *bd,
2268 query_hash, 2310 query_hash,
2269 get_path_length, 2311 get_path_length,
2270 get_path); 2312 get_path);
2313 return true;
2271} 2314}
2272 2315
2273 2316
@@ -2282,6 +2325,8 @@ static enum GNUNET_GenericReturnValue
2282check_dht_p2p_result (void *cls, 2325check_dht_p2p_result (void *cls,
2283 const struct PeerResultMessage *prm) 2326 const struct PeerResultMessage *prm)
2284{ 2327{
2328 struct Target *t = cls;
2329 struct PeerInfo *peer = t->pi;
2285 uint16_t get_path_length = ntohs (prm->get_path_length); 2330 uint16_t get_path_length = ntohs (prm->get_path_length);
2286 uint16_t put_path_length = ntohs (prm->put_path_length); 2331 uint16_t put_path_length = ntohs (prm->put_path_length);
2287 uint16_t msize = ntohs (prm->header.size); 2332 uint16_t msize = ntohs (prm->header.size);
@@ -2289,8 +2334,8 @@ check_dht_p2p_result (void *cls,
2289 = (const struct GNUNET_DHT_PathElement *) &prm[1]; 2334 = (const struct GNUNET_DHT_PathElement *) &prm[1];
2290 const struct GNUNET_DHT_PathElement *gp 2335 const struct GNUNET_DHT_PathElement *gp
2291 = &pp[put_path_length]; 2336 = &pp[put_path_length];
2337 struct GNUNET_DHT_PathElement gpx[get_path_length + 1];
2292 2338
2293 (void) cls;
2294 if ( (msize < 2339 if ( (msize <
2295 sizeof(struct PeerResultMessage) 2340 sizeof(struct PeerResultMessage)
2296 + (get_path_length + put_path_length) 2341 + (get_path_length + put_path_length)
@@ -2305,6 +2350,14 @@ check_dht_p2p_result (void *cls,
2305 } 2350 }
2306 2351
2307#if SANITY_CHECKS 2352#if SANITY_CHECKS
2353 memcpy (gpx,
2354 gp,
2355 get_path_length
2356 * sizeof (struct GNUNET_DHT_PathElement));
2357 gpx[get_path_length].pred = peer->id;
2358 memset (&gpx[get_path_length].sig,
2359 0,
2360 sizeof (gpx[get_path_length].sig));
2308 if (0 != 2361 if (0 !=
2309 GNUNET_DHT_verify_path (&prm->key, 2362 GNUNET_DHT_verify_path (&prm->key,
2310 &gp[get_path_length], 2363 &gp[get_path_length],
@@ -2314,8 +2367,8 @@ check_dht_p2p_result (void *cls,
2314 GNUNET_TIME_absolute_ntoh (prm->expiration_time), 2367 GNUNET_TIME_absolute_ntoh (prm->expiration_time),
2315 pp, 2368 pp,
2316 put_path_length, 2369 put_path_length,
2317 gp, 2370 gpx,
2318 get_path_length, 2371 get_path_length + 1,
2319 &GDS_my_identity)) 2372 &GDS_my_identity))
2320 { 2373 {
2321 GNUNET_break_op (0); 2374 GNUNET_break_op (0);
@@ -2483,10 +2536,10 @@ handle_dht_p2p_result (void *cls,
2483 "Truncating path at %u/%u\n", 2536 "Truncating path at %u/%u\n",
2484 i, 2537 i,
2485 get_path_length); 2538 get_path_length);
2486 process_reply_with_path (&bd, 2539 GNUNET_break (process_reply_with_path (&bd,
2487 &prm->key, 2540 &prm->key,
2488 i, 2541 i,
2489 get_path); 2542 get_path));
2490 return; 2543 return;
2491 } 2544 }
2492 2545
@@ -2505,10 +2558,10 @@ handle_dht_p2p_result (void *cls,
2505 "Extending GET path of length %u with %s\n", 2558 "Extending GET path of length %u with %s\n",
2506 get_path_length, 2559 get_path_length,
2507 GNUNET_i2s (&peer->id)); 2560 GNUNET_i2s (&peer->id));
2508 process_reply_with_path (&bd, 2561 GNUNET_break (process_reply_with_path (&bd,
2509 &prm->key, 2562 &prm->key,
2510 get_path_length + 1, 2563 get_path_length + 1,
2511 xget_path); 2564 xget_path));
2512 } 2565 }
2513} 2566}
2514 2567
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h
index fdaf655bd..4f4172f71 100644
--- a/src/dht/gnunet-service-dht_neighbours.h
+++ b/src/dht/gnunet-service-dht_neighbours.h
@@ -108,8 +108,9 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
108 * @param query_hash query that was used for the request 108 * @param query_hash query that was used for the request
109 * @param get_path_length number of entries in put_path 109 * @param get_path_length number of entries in put_path
110 * @param get_path peers this reply has traversed so far (if tracked) 110 * @param get_path peers this reply has traversed so far (if tracked)
111 * @return true on success
111 */ 112 */
112void 113bool
113GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi, 114GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
114 const struct GDS_DATACACHE_BlockData *bd, 115 const struct GDS_DATACACHE_BlockData *bd,
115 const struct GNUNET_HashCode *query_hash, 116 const struct GNUNET_HashCode *query_hash,
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c
index c07b06c5e..da9919e82 100644
--- a/src/dht/gnunet-service-dht_routing.c
+++ b/src/dht/gnunet-service-dht_routing.c
@@ -195,11 +195,11 @@ process (void *cls,
195 GNUNET_h2s (query_hash)); 195 GNUNET_h2s (query_hash));
196 return GNUNET_OK; 196 return GNUNET_OK;
197 } 197 }
198 GDS_NEIGHBOURS_handle_reply (pi, 198 GNUNET_break (GDS_NEIGHBOURS_handle_reply (pi,
199 &bdx, 199 &bdx,
200 query_hash, 200 query_hash,
201 get_path_length, 201 get_path_length,
202 pc->get_path); 202 pc->get_path));
203 } 203 }
204 break; 204 break;
205 case GNUNET_BLOCK_REPLY_OK_DUPLICATE: 205 case GNUNET_BLOCK_REPLY_OK_DUPLICATE:
diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c
index 30e7749ca..fa57e13b5 100644
--- a/src/dht/test_dht_topo.c
+++ b/src/dht/test_dht_topo.c
@@ -326,7 +326,7 @@ timeout_cb (void *cls)
326 * 326 *
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 key key of the result 329 * @param query query hash
330 * @param get_path peers on reply path (or NULL if not recorded) 330 * @param get_path peers on reply path (or NULL if not recorded)
331 * @param get_path_length number of entries in @a get_path 331 * @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) 332 * @param put_path peers on the PUT path (or NULL if not recorded)
@@ -338,7 +338,7 @@ timeout_cb (void *cls)
338static void 338static void
339dht_get_handler (void *cls, 339dht_get_handler (void *cls,
340 struct GNUNET_TIME_Absolute exp, 340 struct GNUNET_TIME_Absolute exp,
341 const struct GNUNET_HashCode *key, 341 const struct GNUNET_HashCode *query,
342 const struct GNUNET_DHT_PathElement *get_path, 342 const struct GNUNET_DHT_PathElement *get_path,
343 unsigned int get_path_length, 343 unsigned int get_path_length,
344 const struct GNUNET_DHT_PathElement *put_path, 344 const struct GNUNET_DHT_PathElement *put_path,
@@ -359,8 +359,15 @@ dht_get_handler (void *cls,
359 GNUNET_break (0); 359 GNUNET_break (0);
360 return; 360 return;
361 } 361 }
362 GNUNET_CRYPTO_hash (key, 362 if (0 != GNUNET_memcmp (query,
363 sizeof(*key), 363 &get_op->key))
364 {
365 /* exact search should only yield exact results */
366 GNUNET_break (0);
367 return;
368 }
369 GNUNET_CRYPTO_hash (query,
370 sizeof(*query),
364 &want); 371 &want);
365 if (0 != memcmp (&want, 372 if (0 != memcmp (&want,
366 data, 373 data,
@@ -370,19 +377,22 @@ dht_get_handler (void *cls,
370 return; 377 return;
371 } 378 }
372 if (0 != 379 if (0 !=
373 GNUNET_DHT_verify_path (key, 380 GNUNET_DHT_verify_path (query,
374 data, 381 data,
375 size, 382 size,
376 exp, 383 exp,
377 get_path,
378 get_path_length,
379 put_path, 384 put_path,
380 put_path_length, 385 put_path_length,
386 get_path,
387 get_path_length,
381 &get_op->me)) 388 &get_op->me))
382 { 389 {
383 GNUNET_break (0); 390 GNUNET_break (0);
384 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
385 "Path signature verification failed!\n"); 392 "Path signature (%u/%u) verification failed for peer %s!\n",
393 get_path_length,
394 put_path_length,
395 GNUNET_i2s (&get_op->me));
386 } 396 }
387 else 397 else
388 { 398 {
diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h
index e0f9f6fc3..4e14d981d 100644
--- a/src/include/gnunet_dht_service.h
+++ b/src/include/gnunet_dht_service.h
@@ -118,10 +118,10 @@ GNUNET_NETWORK_STRUCT_BEGIN
118/** 118/**
119 * Message signed by a peer when doing path tracking. 119 * Message signed by a peer when doing path tracking.
120 */ 120 */
121struct GNUNET_DHT_HopSignature 121struct GNUNET_DHT_PutHopSignature
122{ 122{
123 /** 123 /**
124 * Must be #GNUNET_SIGNATURE_PURPOSE_DHT_HOP. 124 * Must be #GNUNET_SIGNATURE_PURPOSE_DHT_PUT_HOP.
125 */ 125 */
126 struct GNUNET_CRYPTO_EccSignaturePurpose purpose; 126 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
127 127
@@ -131,9 +131,43 @@ struct GNUNET_DHT_HopSignature
131 struct GNUNET_TIME_AbsoluteNBO expiration_time; 131 struct GNUNET_TIME_AbsoluteNBO expiration_time;
132 132
133 /** 133 /**
134 * Key of the block. 134 * Hash over the payload of the block.
135 */
136 struct GNUNET_HashCode h_data;
137
138 /**
139 * Previous hop the message was received from. All zeros
140 * if this peer was the initiator.
135 */ 141 */
136 struct GNUNET_HashCode key; 142 struct GNUNET_PeerIdentity pred;
143
144 /**
145 * Next hop the message was forwarded to.
146 */
147 struct GNUNET_PeerIdentity succ;
148};
149
150
151/**
152 * Message signed by a peer when doing path tracking
153 * for RESULT (GET) hops.
154 */
155struct GNUNET_DHT_ResultHopSignature
156{
157 /**
158 * Must be #GNUNET_SIGNATURE_PURPOSE_DHT_RESULT_HOP.
159 */
160 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
161
162 /**
163 * Expiration time of the block.
164 */
165 struct GNUNET_TIME_AbsoluteNBO expiration_time;
166
167 /**
168 * Query hash of the GET that is being answered.
169 */
170 struct GNUNET_HashCode query_hash;
137 171
138 /** 172 /**
139 * Hash over the payload of the block. 173 * Hash over the payload of the block.
@@ -181,6 +215,7 @@ struct GNUNET_DHT_PathElement
181 215
182}; 216};
183 217
218
184GNUNET_NETWORK_STRUCT_END 219GNUNET_NETWORK_STRUCT_END
185 220
186/** 221/**
@@ -266,7 +301,7 @@ GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph);
266 * 301 *
267 * @param cls closure 302 * @param cls closure
268 * @param exp when will this value expire 303 * @param exp when will this value expire
269 * @param key key of the result 304 * @param query_hash key of the query
270 * @param get_path peers on reply path (or NULL if not recorded) 305 * @param get_path peers on reply path (or NULL if not recorded)
271 * [0] = datastore's first neighbor, [length - 1] = local peer 306 * [0] = datastore's first neighbor, [length - 1] = local peer
272 * @param get_path_length number of entries in @a get_path 307 * @param get_path_length number of entries in @a get_path
@@ -282,7 +317,7 @@ GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph);
282typedef void 317typedef void
283(*GNUNET_DHT_GetIterator) (void *cls, 318(*GNUNET_DHT_GetIterator) (void *cls,
284 struct GNUNET_TIME_Absolute exp, 319 struct GNUNET_TIME_Absolute exp,
285 const struct GNUNET_HashCode *key, 320 const struct GNUNET_HashCode *query_hash,
286 const struct GNUNET_DHT_PathElement *get_path, 321 const struct GNUNET_DHT_PathElement *get_path,
287 unsigned int get_path_length, 322 unsigned int get_path_length,
288 const struct GNUNET_DHT_PathElement *put_path, 323 const struct GNUNET_DHT_PathElement *put_path,
@@ -487,7 +522,7 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path,
487 * the last signature on the path is never verified as that is the slot where 522 * the last signature on the path is never verified as that is the slot where
488 * our peer (@a me) would need to sign. 523 * our peer (@a me) would need to sign.
489 * 524 *
490 * @param key key of the data (not necessarily the query hash) 525 * @param query_hash the query hash, not necessarily the key of the block
491 * @param data payload (the block) 526 * @param data payload (the block)
492 * @param data_size number of bytes in @a data 527 * @param data_size number of bytes in @a data
493 * @param exp_time expiration time of @a data 528 * @param exp_time expiration time of @a data
@@ -501,7 +536,7 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path,
501 * @a get_path_len + @a put_path_len - 1 if no signature was valid 536 * @a get_path_len + @a put_path_len - 1 if no signature was valid
502 */ 537 */
503unsigned int 538unsigned int
504GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key, 539GNUNET_DHT_verify_path (const struct GNUNET_HashCode *query_hash,
505 const void *data, 540 const void *data,
506 size_t data_size, 541 size_t data_size,
507 struct GNUNET_TIME_Absolute exp_time, 542 struct GNUNET_TIME_Absolute exp_time,