aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-01-10 14:22:35 +0100
committerChristian Grothoff <christian@grothoff.org>2022-01-10 14:22:35 +0100
commit8ee3c5121e87d8f25193ae6044d5818f4629fa1e (patch)
treeeb0dd0250f11fb5f9bc788cef8ba55da90160698
parentd4641d36b885ba764945d6353ed71b7bc485c6ac (diff)
downloadgnunet-8ee3c5121e87d8f25193ae6044d5818f4629fa1e.tar.gz
gnunet-8ee3c5121e87d8f25193ae6044d5818f4629fa1e.zip
-DHT: add path signature verification logic; tests pass, but logic remains dead
-rw-r--r--src/dht/Makefile.am1
-rw-r--r--src/dht/dht_api.c42
-rw-r--r--src/dht/dht_test_lib.c15
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c74
-rw-r--r--src/dht/test_dht_topo.c190
-rw-r--r--src/include/gnunet_dht_service.h22
-rw-r--r--src/testbed/gnunet-service-testbed_connectionpool.c33
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c44
-rw-r--r--src/testbed/testbed_api_topology.c2
9 files changed, 309 insertions, 114 deletions
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
index 69e34000c..be48fab02 100644
--- a/src/dht/Makefile.am
+++ b/src/dht/Makefile.am
@@ -63,6 +63,7 @@ gnunet_service_dht_SOURCES = \
63 gnunet-service-dht_neighbours.c gnunet-service-dht_neighbours.h \ 63 gnunet-service-dht_neighbours.c gnunet-service-dht_neighbours.h \
64 gnunet-service-dht_routing.c gnunet-service-dht_routing.h 64 gnunet-service-dht_routing.c gnunet-service-dht_routing.h
65gnunet_service_dht_LDADD = \ 65gnunet_service_dht_LDADD = \
66 libgnunetdht.la \
66 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 67 $(top_builddir)/src/statistics/libgnunetstatistics.la \
67 $(top_builddir)/src/core/libgnunetcore.la \ 68 $(top_builddir)/src/core/libgnunetcore.la \
68 $(top_builddir)/src/nse/libgnunetnse.la \ 69 $(top_builddir)/src/nse/libgnunetnse.la \
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c
index af3c7d685..8389bbb95 100644
--- a/src/dht/dht_api.c
+++ b/src/dht/dht_api.c
@@ -1198,31 +1198,51 @@ GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key,
1198 const void *data, 1198 const void *data,
1199 size_t data_size, 1199 size_t data_size,
1200 struct GNUNET_TIME_Absolute exp_time, 1200 struct GNUNET_TIME_Absolute exp_time,
1201 const struct GNUNET_DHT_PathElement *path, 1201 const struct GNUNET_DHT_PathElement *put_path,
1202 unsigned int path_len, 1202 unsigned int put_path_len,
1203 const struct GNUNET_DHT_PathElement *get_path,
1204 unsigned int get_path_len,
1203 const struct GNUNET_PeerIdentity *me) 1205 const struct GNUNET_PeerIdentity *me)
1204{ 1206{
1205
1206 struct GNUNET_DHT_HopSignature hs = { 1207 struct GNUNET_DHT_HopSignature hs = {
1207 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP), 1208 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_DHT_HOP),
1208 .purpose.size = htonl (sizeof (hs)), 1209 .purpose.size = htonl (sizeof (hs)),
1209 .expiration_time = GNUNET_TIME_absolute_hton (exp_time), 1210 .expiration_time = GNUNET_TIME_absolute_hton (exp_time),
1210 .key = *key, 1211 .key = *key,
1211 }; 1212 };
1212 unsigned int i = path_len - 1; 1213 unsigned int i;
1213 1214
1215 if (0 == get_path_len + put_path_len)
1216 return 0;
1217 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1218 "Verifying signatures with GPL: %u PPL: %u!\n",
1219 get_path_len,
1220 put_path_len);
1221 i = put_path_len + get_path_len - 1;
1214 GNUNET_CRYPTO_hash (data, 1222 GNUNET_CRYPTO_hash (data,
1215 data_size, 1223 data_size,
1216 &hs.h_data); 1224 &hs.h_data);
1217 while (i > 0) 1225 while (i > 0)
1218 { 1226 {
1219 hs.pred = path[i - 1].pred; 1227 hs.pred = (i - 1 >= put_path_len)
1220 hs.succ = (path_len == i + 1) ? *me : path[i + 1].pred; 1228 ? get_path[i - put_path_len - 1].pred
1229 : put_path[i - 1].pred;
1230 if (i + 1 == get_path_len + put_path_len)
1231 hs.succ = *me;
1232 else
1233 hs.succ = (i + 1 >= put_path_len)
1234 ? get_path[i + 1 - put_path_len].pred
1235 : put_path[i + 1].pred;
1221 if (GNUNET_OK != 1236 if (GNUNET_OK !=
1222 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_DHT_HOP, 1237 GNUNET_CRYPTO_eddsa_verify (
1223 &hs, 1238 GNUNET_SIGNATURE_PURPOSE_DHT_HOP,
1224 &path[i - 1].sig, 1239 &hs,
1225 &path[i].pred.public_key)) 1240 (i - 1 >= put_path_len)
1241 ? &get_path[i - put_path_len - 1].sig
1242 : &put_path[i - 1].sig,
1243 (i >= put_path_len)
1244 ? &get_path[i - put_path_len].pred.public_key
1245 : &put_path[i].pred.public_key))
1226 return i; 1246 return i;
1227 i--; 1247 i--;
1228 } 1248 }
diff --git a/src/dht/dht_test_lib.c b/src/dht/dht_test_lib.c
index 0d382cd74..29c5088d1 100644
--- a/src/dht/dht_test_lib.c
+++ b/src/dht/dht_test_lib.c
@@ -138,11 +138,6 @@ dht_connect_cb (void *cls,
138} 138}
139 139
140 140
141/**
142 * Clean up the testbed.
143 *
144 * @param ctx handle for the testbed
145 */
146void 141void
147GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx) 142GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx)
148{ 143{
@@ -179,16 +174,6 @@ dht_test_run (void *cls,
179} 174}
180 175
181 176
182/**
183 * Run a test using the given name, configuration file and number of
184 * peers.
185 *
186 * @param testname name of the test (for logging)
187 * @param cfgname name of the configuration file
188 * @param num_peers number of peers to start
189 * @param tmain main function to run once the testbed is ready
190 * @param tmain_cls closure for 'tmain'
191 */
192void 177void
193GNUNET_DHT_TEST_run (const char *testname, 178GNUNET_DHT_TEST_run (const char *testname,
194 const char *cfgname, 179 const char *cfgname,
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 95d8bb032..cf150ea0c 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -1308,6 +1308,21 @@ GDS_NEIGHBOURS_handle_put (const struct GDS_DATACACHE_BlockData *bd,
1308 unsigned int put_path_length = bd->put_path_length; 1308 unsigned int put_path_length = bd->put_path_length;
1309 1309
1310 GNUNET_assert (NULL != bf); 1310 GNUNET_assert (NULL != bf);
1311#if SANITY_CHECKS
1312 if (0 !=
1313 GNUNET_DHT_verify_path (&bd->key,
1314 bd->data,
1315 bd->data_size,
1316 bd->expiration_time,
1317 bd->put_path,
1318 bd->put_path_length,
1319 NULL, 0, /* get_path */
1320 &my_identity))
1321 {
1322 GNUNET_break_op (0);
1323 put_path_length = 0;
1324 }
1325#endif
1311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1326 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1312 "Adding myself (%s) to PUT bloomfilter for %s\n", 1327 "Adding myself (%s) to PUT bloomfilter for %s\n",
1313 GNUNET_i2s (&my_identity), 1328 GNUNET_i2s (&my_identity),
@@ -1564,13 +1579,43 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1564 struct PeerResultMessage *prm; 1579 struct PeerResultMessage *prm;
1565 struct GNUNET_DHT_PathElement *paths; 1580 struct GNUNET_DHT_PathElement *paths;
1566 size_t msize; 1581 size_t msize;
1582 unsigned int ppl = bd->put_path_length;
1567 1583
1568 msize = bd->data_size + (get_path_length + bd->put_path_length) 1584#if SANITY_CHECKS
1585 if (0 !=
1586 GNUNET_DHT_verify_path (&bd->key,
1587 bd->data,
1588 bd->data_size,
1589 bd->expiration_time,
1590 bd->put_path,
1591 bd->put_path_length,
1592 get_path,
1593 get_path_length,
1594 &my_identity))
1595 {
1596 GNUNET_break_op (0);
1597 get_path_length = 0;
1598 ppl = 0;
1599 }
1600#endif
1601 msize = bd->data_size + (get_path_length + ppl)
1569 * sizeof(struct GNUNET_DHT_PathElement); 1602 * sizeof(struct GNUNET_DHT_PathElement);
1570 if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) || 1603 if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
1571 (get_path_length > 1604 (get_path_length >
1572 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) || 1605 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1573 (bd->put_path_length > 1606 (ppl >
1607 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1608 (bd->data_size > GNUNET_MAX_MESSAGE_SIZE))
1609 {
1610 ppl = 0;
1611 get_path_length = 0;
1612 msize = bd->data_size + (get_path_length + ppl)
1613 * sizeof(struct GNUNET_DHT_PathElement);
1614 }
1615 if ( (msize + sizeof(struct PeerResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
1616 (get_path_length >
1617 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1618 (ppl >
1574 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) || 1619 GNUNET_MAX_MESSAGE_SIZE / sizeof(struct GNUNET_DHT_PathElement)) ||
1575 (bd->data_size > GNUNET_MAX_MESSAGE_SIZE)) 1620 (bd->data_size > GNUNET_MAX_MESSAGE_SIZE))
1576 { 1621 {
@@ -1602,15 +1647,15 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1602 msize, 1647 msize,
1603 GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT); 1648 GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT);
1604 prm->type = htonl (bd->type); 1649 prm->type = htonl (bd->type);
1605 prm->put_path_length = htonl (bd->put_path_length); 1650 prm->put_path_length = htonl (ppl);
1606 prm->get_path_length = htonl (get_path_length); 1651 prm->get_path_length = htonl (get_path_length);
1607 prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time); 1652 prm->expiration_time = GNUNET_TIME_absolute_hton (bd->expiration_time);
1608 prm->key = *query_hash; 1653 prm->key = *query_hash;
1609 paths = (struct GNUNET_DHT_PathElement *) &prm[1]; 1654 paths = (struct GNUNET_DHT_PathElement *) &prm[1];
1610 GNUNET_memcpy (paths, 1655 GNUNET_memcpy (paths,
1611 bd->put_path, 1656 bd->put_path,
1612 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement)); 1657 ppl * sizeof(struct GNUNET_DHT_PathElement));
1613 GNUNET_memcpy (&paths[bd->put_path_length], 1658 GNUNET_memcpy (&paths[ppl],
1614 get_path, 1659 get_path,
1615 get_path_length * sizeof(struct GNUNET_DHT_PathElement)); 1660 get_path_length * sizeof(struct GNUNET_DHT_PathElement));
1616 /* 0 == get_path_length means path is not being tracked */ 1661 /* 0 == get_path_length means path is not being tracked */
@@ -1622,11 +1667,11 @@ GDS_NEIGHBOURS_handle_reply (struct PeerInfo *pi,
1622 bd->data, 1667 bd->data,
1623 bd->data_size, 1668 bd->data_size,
1624 bd->expiration_time, 1669 bd->expiration_time,
1625 &paths[bd->put_path_length + get_path_length - 1].pred, 1670 &paths[ppl + get_path_length - 1].pred,
1626 pi->id, 1671 pi->id,
1627 &paths[bd->put_path_length + get_path_length - 1].sig); 1672 &paths[ppl + get_path_length - 1].sig);
1628 } 1673 }
1629 GNUNET_memcpy (&paths[bd->put_path_length + get_path_length], 1674 GNUNET_memcpy (&paths[ppl + get_path_length],
1630 bd->data, 1675 bd->data,
1631 bd->data_size); 1676 bd->data_size);
1632 GNUNET_MQ_send (pi->mq, 1677 GNUNET_MQ_send (pi->mq,
@@ -1798,6 +1843,19 @@ handle_dht_p2p_put (void *cls,
1798 GNUNET_memcmp (&pp[i].pred, 1843 GNUNET_memcmp (&pp[i].pred,
1799 peer->id)); 1844 peer->id));
1800 } 1845 }
1846 if (0 !=
1847 GNUNET_DHT_verify_path (&bd.key,
1848 bd.data,
1849 bd.data_size,
1850 bd.expiration_time,
1851 bd.put_path,
1852 putlen,
1853 NULL, 0, /* get_path */
1854 &my_identity))
1855 {
1856 GNUNET_break_op (0);
1857 putlen = 0;
1858 }
1801#endif 1859#endif
1802 GNUNET_memcpy (pp, 1860 GNUNET_memcpy (pp,
1803 put_path, 1861 put_path,
diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c
index dfe969bb9..9f4b1b034 100644
--- a/src/dht/test_dht_topo.c
+++ b/src/dht/test_dht_topo.c
@@ -58,16 +58,36 @@ struct GetOperation
58 struct GetOperation *prev; 58 struct GetOperation *prev;
59 59
60 /** 60 /**
61 * Operation to fetch @a me.
62 */
63 struct GNUNET_TESTBED_Operation *to;
64
65 /**
61 * Handle for the operation. 66 * Handle for the operation.
62 */ 67 */
63 struct GNUNET_DHT_GetHandle *get; 68 struct GNUNET_DHT_GetHandle *get;
69
70 /**
71 * DHT used by this operation.
72 */
73 struct GNUNET_DHT_Handle *dht;
74
75 /**
76 * Key we are looking up.
77 */
78 struct GNUNET_HashCode key;
79
80 /**
81 * At which peer is this operation being performed?
82 */
83 struct GNUNET_PeerIdentity me;
64}; 84};
65 85
66 86
67/** 87/**
68 * Result of the test. 88 * Result of the test.
69 */ 89 */
70static int ok = 1; 90static int ok;
71 91
72/** 92/**
73 * Task to do DHT_puts 93 * Task to do DHT_puts
@@ -154,7 +174,7 @@ static struct
154 174
155 175
156static struct GNUNET_DHT_TEST_Context * 176static struct GNUNET_DHT_TEST_Context *
157stop_ops () 177stop_ops (void)
158{ 178{
159 struct GetOperation *get_op; 179 struct GetOperation *get_op;
160 struct GNUNET_DHT_TEST_Context *ctx = NULL; 180 struct GNUNET_DHT_TEST_Context *ctx = NULL;
@@ -176,7 +196,16 @@ stop_ops ()
176 } 196 }
177 while (NULL != (get_op = get_tail)) 197 while (NULL != (get_op = get_tail))
178 { 198 {
179 GNUNET_DHT_get_stop (get_op->get); 199 if (NULL != get_op->to)
200 {
201 GNUNET_TESTBED_operation_done (get_op->to);
202 get_op->to = NULL;
203 }
204 if (NULL != get_op->get)
205 {
206 GNUNET_DHT_get_stop (get_op->get);
207 get_op->get = NULL;
208 }
180 GNUNET_CONTAINER_DLL_remove (get_head, 209 GNUNET_CONTAINER_DLL_remove (get_head,
181 get_tail, 210 get_tail,
182 get_op); 211 get_op);
@@ -199,7 +228,6 @@ stats_finished (void *cls,
199 const char *emsg) 228 const char *emsg)
200{ 229{
201 struct GNUNET_DHT_TEST_Context *ctx = cls; 230 struct GNUNET_DHT_TEST_Context *ctx = cls;
202 unsigned int i;
203 231
204 if (NULL != op) 232 if (NULL != op)
205 GNUNET_TESTBED_operation_done (op); 233 GNUNET_TESTBED_operation_done (op);
@@ -212,7 +240,7 @@ stats_finished (void *cls,
212 GNUNET_DHT_TEST_cleanup (ctx); 240 GNUNET_DHT_TEST_cleanup (ctx);
213 return; 241 return;
214 } 242 }
215 for (i = 0; NULL != stats[i].name; i++) 243 for (unsigned int i = 0; NULL != stats[i].name; i++)
216 fprintf (stderr, 244 fprintf (stderr,
217 "%6s/%60s = %12llu\n", 245 "%6s/%60s = %12llu\n",
218 stats[i].subsystem, 246 stats[i].subsystem,
@@ -234,7 +262,7 @@ stats_finished (void *cls,
234 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not 262 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
235 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration 263 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
236 */ 264 */
237static int 265static enum GNUNET_GenericReturnValue
238handle_stats (void *cls, 266handle_stats (void *cls,
239 const struct GNUNET_TESTBED_Peer *peer, 267 const struct GNUNET_TESTBED_Peer *peer,
240 const char *subsystem, 268 const char *subsystem,
@@ -242,9 +270,7 @@ handle_stats (void *cls,
242 uint64_t value, 270 uint64_t value,
243 int is_persistent) 271 int is_persistent)
244{ 272{
245 unsigned int i; 273 for (unsigned int i = 0; NULL != stats[i].name; i++)
246
247 for (i = 0; NULL != stats[i].name; i++)
248 if ((0 == strcasecmp (subsystem, 274 if ((0 == strcasecmp (subsystem,
249 stats[i].subsystem)) && 275 stats[i].subsystem)) &&
250 (0 == strcasecmp (name, 276 (0 == strcasecmp (name,
@@ -263,7 +289,14 @@ handle_stats (void *cls,
263static void 289static void
264shutdown_task (void *cls) 290shutdown_task (void *cls)
265{ 291{
266 (void) stop_ops (); 292 struct GNUNET_DHT_TEST_Context *ctx;
293
294 (void) cls;
295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
296 "Performing shutdown\n");
297 ctx = stop_ops ();
298 if (NULL != ctx)
299 GNUNET_DHT_TEST_cleanup (ctx);
267} 300}
268 301
269 302
@@ -276,7 +309,11 @@ shutdown_task (void *cls)
276static void 309static void
277timeout_cb (void *cls) 310timeout_cb (void *cls)
278{ 311{
279 timeout_task = NULL; 312 struct GNUNET_DHT_TEST_Context *ctx = cls;
313
314 timeout_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT,
315 &timeout_cb,
316 ctx);
280 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 317 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
281 "Timeout\n"); 318 "Timeout\n");
282 GNUNET_SCHEDULER_shutdown (); 319 GNUNET_SCHEDULER_shutdown ();
@@ -314,6 +351,13 @@ dht_get_handler (void *cls,
314 struct GNUNET_HashCode want; 351 struct GNUNET_HashCode want;
315 struct GNUNET_DHT_TEST_Context *ctx; 352 struct GNUNET_DHT_TEST_Context *ctx;
316 353
354 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
355 "Handling reply with GPL: %u PPL: %u!\n",
356 get_path_len,
357 put_path_len);
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
359 "GET HANDLER called on PID %s\n",
360 GNUNET_i2s (&get_op->me));
317 if (sizeof(struct GNUNET_HashCode) != size) 361 if (sizeof(struct GNUNET_HashCode) != size)
318 { 362 {
319 GNUNET_break (0); 363 GNUNET_break (0);
@@ -329,26 +373,26 @@ dht_get_handler (void *cls,
329 GNUNET_break (0); 373 GNUNET_break (0);
330 return; 374 return;
331 } 375 }
332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 376 if (0 !=
333 "Get successful\n"); 377 GNUNET_DHT_verify_path (key,
334#if 0 378 data,
379 size,
380 exp,
381 get_path,
382 get_path_length,
383 put_path,
384 put_path_length,
385 &get_op->me))
386 {
387 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
388 "Path signature verification failed!\n");
389 }
390 else
335 { 391 {
336 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
337 "PATH: (get %u, put %u)\n", 393 "Get successful\n");
338 get_path_length, 394 ok--;
339 put_path_length);
340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
341 " LOCAL\n");
342 for (int i = get_path_length - 1; i >= 0; i--)
343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
344 " %s\n",
345 GNUNET_i2s (&get_path[i]));
346 for (int i = put_path_length - 1; i >= 0; i--)
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
348 " %s\n",
349 GNUNET_i2s (&put_path[i]));
350 } 395 }
351#endif
352 GNUNET_DHT_get_stop (get_op->get); 396 GNUNET_DHT_get_stop (get_op->get);
353 GNUNET_CONTAINER_DLL_remove (get_head, 397 GNUNET_CONTAINER_DLL_remove (get_head,
354 get_tail, 398 get_tail,
@@ -359,7 +403,6 @@ dht_get_handler (void *cls,
359 /* all DHT GET operations successful; get stats! */ 403 /* all DHT GET operations successful; get stats! */
360 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 404 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
361 "All DHT operations successful. Obtaining stats!\n"); 405 "All DHT operations successful. Obtaining stats!\n");
362 ok = 0;
363 ctx = stop_ops (); 406 ctx = stop_ops ();
364 GNUNET_assert (NULL != ctx); 407 GNUNET_assert (NULL != ctx);
365 (void) GNUNET_TESTBED_get_statistics (NUM_PEERS, 408 (void) GNUNET_TESTBED_get_statistics (NUM_PEERS,
@@ -386,7 +429,8 @@ do_puts (void *cls)
386 429
387 put_task = NULL; 430 put_task = NULL;
388 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
389 "Putting values into DHT\n"); 432 "Putting %u values into DHT\n",
433 NUM_PEERS);
390 for (unsigned int i = 0; i < NUM_PEERS; i++) 434 for (unsigned int i = 0; i < NUM_PEERS; i++)
391 { 435 {
392 GNUNET_CRYPTO_hash (&i, 436 GNUNET_CRYPTO_hash (&i,
@@ -414,37 +458,86 @@ do_puts (void *cls)
414 458
415 459
416/** 460/**
461 * Callback to be called when the requested peer information is available
462 * The peer information in the callback is valid until the operation 'op' is canceled.
463 *
464 * @param cls a `struct GetOperation *`
465 * @param op the operation this callback corresponds to
466 * @param pinfo the result; will be NULL if the operation has failed
467 * @param emsg error message if the operation has failed; will be NULL if the
468 * operation is successful
469 */
470static void
471pid_cb (void *cls,
472 struct GNUNET_TESTBED_Operation *op,
473 const struct GNUNET_TESTBED_PeerInformation *pinfo,
474 const char *emsg)
475{
476 struct GetOperation *get_op = cls;
477
478 if (NULL != emsg)
479 {
480 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
481 "Testbed failure: %s\n",
482 emsg);
483 GNUNET_TESTBED_operation_done (get_op->to);
484 get_op->to = NULL;
485 GNUNET_SCHEDULER_shutdown ();
486 return;
487 }
488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
489 "Testbed provided PID %s\n",
490 GNUNET_i2s (pinfo->result.id));
491 get_op->me = *pinfo->result.id;
492 GNUNET_TESTBED_operation_done (get_op->to);
493 get_op->to = NULL;
494 get_op->get = GNUNET_DHT_get_start (get_op->dht,
495 GNUNET_BLOCK_TYPE_TEST,
496 &get_op->key,
497 4U, /* replication level */
498 GNUNET_DHT_RO_RECORD_ROUTE
499 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
500 NULL, /* xquery */
501 0, /* xquery bits */
502 &dht_get_handler,
503 get_op);
504}
505
506
507/**
417 * Start GET operations. 508 * Start GET operations.
418 */ 509 */
419static void 510static void
420start_get (void *cls) 511start_get (void *cls)
421{ 512{
422 struct GNUNET_DHT_Handle **dhts = cls; 513 struct GNUNET_DHT_Handle **dhts = cls;
423 unsigned int i;
424 unsigned int j;
425 struct GNUNET_HashCode key;
426 struct GetOperation *get_op;
427 514
428 get_task = NULL; 515 get_task = NULL;
429 for (i = 0; i < NUM_PEERS; i++) 516 for (unsigned int i = 0; i < NUM_PEERS; i++)
430 { 517 {
431 GNUNET_CRYPTO_hash (&i, sizeof(i), &key); 518 struct GNUNET_HashCode key;
432 for (j = 0; j < NUM_PEERS; j++) 519
520 GNUNET_CRYPTO_hash (&i,
521 sizeof(i),
522 &key);
523 for (unsigned int j = 0; j < NUM_PEERS; j++)
433 { 524 {
525 struct GetOperation *get_op;
526
434 get_op = GNUNET_new (struct GetOperation); 527 get_op = GNUNET_new (struct GetOperation);
528 ok++;
529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
530 "Starting GET %p\n",
531 get_op);
532 get_op->key = key;
533 get_op->dht = dhts[j];
534 get_op->to = GNUNET_TESTBED_peer_get_information (my_peers[j],
535 GNUNET_TESTBED_PIT_IDENTITY,
536 &pid_cb,
537 get_op);
435 GNUNET_CONTAINER_DLL_insert (get_head, 538 GNUNET_CONTAINER_DLL_insert (get_head,
436 get_tail, 539 get_tail,
437 get_op); 540 get_op);
438 get_op->get = GNUNET_DHT_get_start (dhts[j],
439 GNUNET_BLOCK_TYPE_TEST, /* type */
440 &key, /*key to search */
441 4U, /* replication level */
442 GNUNET_DHT_RO_RECORD_ROUTE
443 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
444 NULL, /* xquery */
445 0, /* xquery bits */
446 &dht_get_handler,
447 get_op);
448 } 541 }
449 } 542 }
450} 543}
@@ -492,6 +585,9 @@ main (int xargc, char *xargv[])
492 const char *cfg_filename; 585 const char *cfg_filename;
493 const char *test_name; 586 const char *test_name;
494 587
588 unsetenv ("XDG_DATA_HOME");
589 unsetenv ("XDG_CONFIG_HOME");
590 unsetenv ("XDG_CACHE_HOME");
495 if (NULL != strstr (xargv[0], "test_dht_2dtorus")) 591 if (NULL != strstr (xargv[0], "test_dht_2dtorus"))
496 { 592 {
497 cfg_filename = "test_dht_2dtorus.conf"; 593 cfg_filename = "test_dht_2dtorus.conf";
diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h
index 5c365639a..768b19fb1 100644
--- a/src/include/gnunet_dht_service.h
+++ b/src/include/gnunet_dht_service.h
@@ -482,29 +482,33 @@ GNUNET_DHT_pp2s (const struct GNUNET_DHT_PathElement *path,
482 482
483 483
484/** 484/**
485 * Verify signatures on a @a path, in reverse order (starting at 485 * Verify signatures on a path consisting of @a put_path and @a get_path in
486 * the last element of the path). Note that the last signature 486 * reverse order (starting at the last element of the @a get_path). Note that
487 * on the path is never verified as that is the slot where our 487 * the last signature on the path is never verified as that is the slot where
488 * peer (@a me) would need to sign. 488 * our peer (@a me) would need to sign.
489 * 489 *
490 * @param key key of the data (not necessarily the query hash) 490 * @param key key of the data (not necessarily the query hash)
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 path array of path elements to verify 494 * @param get_path array of path elements to verify
495 * @param path_len length of the @a path array 495 * @param get_path_len length of the @a get_path array
496 * @param put_path array of path elements to verify
497 * @param put_path_len length of the @a put_path array
496 * @param me our own peer identity (needed to verify the last element) 498 * @param me our own peer identity (needed to verify the last element)
497 * @return 0 on success, otherwise the index of 499 * @return 0 on success, otherwise the index of
498 * the last path element that succeeded with verification; 500 * the last path element that succeeded with verification;
499 * @a path_len -1 if no signature was valid 501 * @a get_path_len + @a put_path_len - 1 if no signature was valid
500 */ 502 */
501unsigned int 503unsigned int
502GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key, 504GNUNET_DHT_verify_path (const struct GNUNET_HashCode *key,
503 const void *data, 505 const void *data,
504 size_t data_size, 506 size_t data_size,
505 struct GNUNET_TIME_Absolute exp_time, 507 struct GNUNET_TIME_Absolute exp_time,
506 const struct GNUNET_DHT_PathElement *path, 508 const struct GNUNET_DHT_PathElement *put_path,
507 unsigned int path_len, 509 unsigned int put_path_len,
510 const struct GNUNET_DHT_PathElement *get_path,
511 unsigned int get_path_len,
508 const struct GNUNET_PeerIdentity *me); 512 const struct GNUNET_PeerIdentity *me);
509 513
510 514
diff --git a/src/testbed/gnunet-service-testbed_connectionpool.c b/src/testbed/gnunet-service-testbed_connectionpool.c
index 7318971b3..59780e6c1 100644
--- a/src/testbed/gnunet-service-testbed_connectionpool.c
+++ b/src/testbed/gnunet-service-testbed_connectionpool.c
@@ -445,10 +445,13 @@ connection_ready (void *cls)
445 gh_next = NULL; 445 gh_next = NULL;
446 if (NULL != gh->next) 446 if (NULL != gh->next)
447 gh_next = search_waiting (entry, gh->next); 447 gh_next = search_waiting (entry, gh->next);
448 GNUNET_CONTAINER_DLL_remove (entry->head_waiting, entry->tail_waiting, gh); 448 GNUNET_CONTAINER_DLL_remove (entry->head_waiting,
449 entry->tail_waiting,
450 gh);
449 gh->connection_ready_called = 1; 451 gh->connection_ready_called = 1;
450 if (NULL != gh_next) 452 if (NULL != gh_next)
451 entry->notify_task = GNUNET_SCHEDULER_add_now (&connection_ready, entry); 453 entry->notify_task = GNUNET_SCHEDULER_add_now (&connection_ready,
454 entry);
452 if ((NULL != gh->target) && (NULL != gh->connect_notify_cb)) 455 if ((NULL != gh->target) && (NULL != gh->connect_notify_cb))
453 { 456 {
454 GNUNET_CONTAINER_DLL_insert_tail (entry->head_notify, 457 GNUNET_CONTAINER_DLL_insert_tail (entry->head_notify,
@@ -456,7 +459,9 @@ connection_ready (void *cls)
456 gh); 459 gh);
457 gh->notify_waiting = 1; 460 gh->notify_waiting = 1;
458 } 461 }
459 LOG_DEBUG ("Connection ready for handle type %u\n", gh->service); 462 LOG_DEBUG ("Connection ready to %u for handle type %u\n",
463 (unsigned int) entry->index,
464 gh->service);
460 gh->cb (gh->cb_cls, 465 gh->cb (gh->cb_cls,
461 entry->handle_core, 466 entry->handle_core,
462 entry->handle_transport, 467 entry->handle_transport,
@@ -625,7 +630,8 @@ core_peer_connect_cb (void *cls,
625 * @param my_identity ID of this peer, NULL if we failed 630 * @param my_identity ID of this peer, NULL if we failed
626 */ 631 */
627static void 632static void
628core_startup_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity) 633core_startup_cb (void *cls,
634 const struct GNUNET_PeerIdentity *my_identity)
629{ 635{
630 struct PooledConnection *entry = cls; 636 struct PooledConnection *entry = cls;
631 637
@@ -637,6 +643,10 @@ core_startup_cb (void *cls, const struct GNUNET_PeerIdentity *my_identity)
637 GNUNET_assert (NULL == entry->peer_identity); 643 GNUNET_assert (NULL == entry->peer_identity);
638 entry->peer_identity = GNUNET_new (struct GNUNET_PeerIdentity); 644 entry->peer_identity = GNUNET_new (struct GNUNET_PeerIdentity);
639 *entry->peer_identity = *my_identity; 645 *entry->peer_identity = *my_identity;
646 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
647 "Established CORE connection for peer %s (%u)\n",
648 GNUNET_i2s (my_identity),
649 (unsigned int) entry->index);
640 if (0 == entry->demand) 650 if (0 == entry->demand)
641 return; 651 return;
642 if (NULL != entry->notify_task) 652 if (NULL != entry->notify_task)
@@ -857,19 +867,20 @@ GST_connection_pool_get_handle (
857 case GST_CONNECTIONPOOL_SERVICE_TRANSPORT: 867 case GST_CONNECTIONPOOL_SERVICE_TRANSPORT:
858 handle = entry->handle_transport; 868 handle = entry->handle_transport;
859 if (NULL != handle) 869 if (NULL != handle)
860 LOG_DEBUG ("Found TRANSPORT handle for peer %u\n", entry->index); 870 LOG_DEBUG ("Found TRANSPORT handle for peer %u\n",
871 entry->index);
861 break; 872 break;
862
863 case GST_CONNECTIONPOOL_SERVICE_CORE: 873 case GST_CONNECTIONPOOL_SERVICE_CORE:
864 handle = entry->handle_core; 874 handle = entry->handle_core;
865 if (NULL != handle) 875 if (NULL != handle)
866 LOG_DEBUG ("Found CORE handle for peer %u\n", entry->index); 876 LOG_DEBUG ("Found CORE handle for peer %u\n",
877 entry->index);
867 break; 878 break;
868
869 case GST_CONNECTIONPOOL_SERVICE_ATS_CONNECTIVITY: 879 case GST_CONNECTIONPOOL_SERVICE_ATS_CONNECTIVITY:
870 handle = entry->handle_ats_connectivity; 880 handle = entry->handle_ats_connectivity;
871 if (NULL != handle) 881 if (NULL != handle)
872 LOG_DEBUG ("Found ATS CONNECTIVITY handle for peer %u\n", entry->index); 882 LOG_DEBUG ("Found ATS CONNECTIVITY handle for peer %u\n",
883 entry->index);
873 break; 884 break;
874 } 885 }
875 } 886 }
@@ -905,7 +916,9 @@ GST_connection_pool_get_handle (
905 gh->connect_notify_cb = connect_notify_cb; 916 gh->connect_notify_cb = connect_notify_cb;
906 gh->connect_notify_cb_cls = connect_notify_cb_cls; 917 gh->connect_notify_cb_cls = connect_notify_cb_cls;
907 gh->service = service; 918 gh->service = service;
908 GNUNET_CONTAINER_DLL_insert (entry->head_waiting, entry->tail_waiting, gh); 919 GNUNET_CONTAINER_DLL_insert (entry->head_waiting,
920 entry->tail_waiting,
921 gh);
909 if (NULL != handle) 922 if (NULL != handle)
910 { 923 {
911 if (NULL == entry->notify_task) 924 if (NULL == entry->notify_task)
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c
index 4fe7c20b3..b13a3b7e0 100644
--- a/src/testbed/gnunet-service-testbed_oc.c
+++ b/src/testbed/gnunet-service-testbed_oc.c
@@ -685,15 +685,14 @@ overlay_connect_notify (void *cls,
685 685
686 LOG_DEBUG ("Overlay connect notify\n"); 686 LOG_DEBUG ("Overlay connect notify\n");
687 if (0 == 687 if (0 ==
688 memcmp (new_peer, &occ->peer_identity, 688 GNUNET_memcmp (new_peer,
689 sizeof(struct GNUNET_PeerIdentity))) 689 &occ->peer_identity))
690 return; 690 return;
691 new_peer_str = GNUNET_strdup (GNUNET_i2s (new_peer)); 691 new_peer_str = GNUNET_strdup (GNUNET_i2s (new_peer));
692 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity)); 692 other_peer_str = GNUNET_strdup (GNUNET_i2s (&occ->other_peer_identity));
693 if (0 != 693 if (0 !=
694 memcmp (new_peer, 694 GNUNET_memcmp (new_peer,
695 &occ->other_peer_identity, 695 &occ->other_peer_identity))
696 sizeof(struct GNUNET_PeerIdentity)))
697 { 696 {
698 LOG_DEBUG ("Unexpected peer %s connected when expecting peer %s\n", 697 LOG_DEBUG ("Unexpected peer %s connected when expecting peer %s\n",
699 new_peer_str, 698 new_peer_str,
@@ -1180,19 +1179,23 @@ occ_cache_get_handle_core_cb (void *cls,
1180 return; 1179 return;
1181 } 1180 }
1182 occ->emsg = NULL; 1181 occ->emsg = NULL;
1182 occ->peer_identity = *my_identity;
1183 if (NULL != 1183 if (NULL !=
1184 GNUNET_CORE_get_mq (ch, 1184 GNUNET_CORE_get_mq (ch,
1185 &occ->other_peer_identity)) 1185 &occ->other_peer_identity))
1186 { 1186 {
1187 LOG_DEBUG ("0x%llx: Target peer already connected\n", 1187 LOG_DEBUG ("0x%llx: Target peer %s already connected\n",
1188 (unsigned long long) occ->op_id); 1188 (unsigned long long) occ->op_id,
1189 GNUNET_i2s (&occ->other_peer_identity));
1190 LOG_DEBUG ("0x%llx: Target peer %s connected\n",
1191 (unsigned long long) occ->op_id,
1192 GNUNET_i2s (&occ->peer_identity));
1189 GNUNET_SCHEDULER_cancel (occ->timeout_task); 1193 GNUNET_SCHEDULER_cancel (occ->timeout_task);
1190 occ->timeout_task = NULL; 1194 occ->timeout_task = NULL;
1191 send_overlay_connect_success_msg (occ); 1195 send_overlay_connect_success_msg (occ);
1192 occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ); 1196 occ->cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup_occ, occ);
1193 return; 1197 return;
1194 } 1198 }
1195 occ->peer_identity = *my_identity;
1196 LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n", 1199 LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n",
1197 (unsigned long long) occ->op_id, 1200 (unsigned long long) occ->op_id,
1198 GNUNET_i2s (&occ->peer_identity)); 1201 GNUNET_i2s (&occ->peer_identity));
@@ -1259,12 +1262,11 @@ overlay_connect_get_config (void *cls,
1259 GST_connection_pool_get_handle (occ->peer->id, 1262 GST_connection_pool_get_handle (occ->peer->id,
1260 occ->peer->details.local.cfg, 1263 occ->peer->details.local.cfg,
1261 GST_CONNECTIONPOOL_SERVICE_CORE, 1264 GST_CONNECTIONPOOL_SERVICE_CORE,
1262 occ_cache_get_handle_core_cb, 1265 &occ_cache_get_handle_core_cb,
1263 occ, 1266 occ,
1264 &occ->other_peer_identity, 1267 &occ->other_peer_identity,
1265 &overlay_connect_notify, 1268 &overlay_connect_notify,
1266 occ); 1269 occ);
1267 return;
1268} 1270}
1269 1271
1270 1272
@@ -1540,6 +1542,12 @@ handle_overlay_connect (void *cls,
1540 1542
1541 p1 = ntohl (msg->peer1); 1543 p1 = ntohl (msg->peer1);
1542 p2 = ntohl (msg->peer2); 1544 p2 = ntohl (msg->peer2);
1545 if (p1 == p2)
1546 {
1547 GNUNET_break (0);
1548 GNUNET_SERVICE_client_drop (client);
1549 return;
1550 }
1543 if (! VALID_PEER_ID (p1)) 1551 if (! VALID_PEER_ID (p1))
1544 { 1552 {
1545 GNUNET_break (0); 1553 GNUNET_break (0);
@@ -1620,12 +1628,10 @@ handle_overlay_connect (void *cls,
1620 &p2_controller_connect_cb, 1628 &p2_controller_connect_cb,
1621 occ); 1629 occ);
1622 break; 1630 break;
1623
1624 case OCC_TYPE_REMOTE_SLAVE: 1631 case OCC_TYPE_REMOTE_SLAVE:
1625 p2_controller_connect_cb (occ, 1632 p2_controller_connect_cb (occ,
1626 occ->p2ctx.remote.p2c); 1633 occ->p2ctx.remote.p2c);
1627 break; 1634 break;
1628
1629 case OCC_TYPE_LOCAL: 1635 case OCC_TYPE_LOCAL:
1630 peer2 = GST_peer_list[occ->other_peer_id]; 1636 peer2 = GST_peer_list[occ->other_peer_id];
1631 peer2->reference_cnt++; 1637 peer2->reference_cnt++;
@@ -1636,11 +1642,23 @@ handle_overlay_connect (void *cls,
1636 "id: %u", 1642 "id: %u",
1637 (unsigned long long) occ->op_id, 1643 (unsigned long long) occ->op_id,
1638 occ->peer->id); 1644 occ->peer->id);
1645 LOG_DEBUG ("Peer %u has PID %s\n",
1646 occ->other_peer_id,
1647 GNUNET_i2s (&occ->other_peer_identity));
1648 {
1649 struct GNUNET_PeerIdentity lpid;
1650
1651 GNUNET_TESTING_peer_get_identity (peer->details.local.peer,
1652 &lpid);
1653 LOG_DEBUG ("Peer %u has PID %s\n",
1654 p1,
1655 GNUNET_i2s (&lpid));
1656 }
1639 occ->cgh_ch = 1657 occ->cgh_ch =
1640 GST_connection_pool_get_handle (occ->peer->id, 1658 GST_connection_pool_get_handle (occ->peer->id,
1641 occ->peer->details.local.cfg, 1659 occ->peer->details.local.cfg,
1642 GST_CONNECTIONPOOL_SERVICE_CORE, 1660 GST_CONNECTIONPOOL_SERVICE_CORE,
1643 occ_cache_get_handle_core_cb, occ, 1661 &occ_cache_get_handle_core_cb, occ,
1644 &occ->other_peer_identity, 1662 &occ->other_peer_identity,
1645 &overlay_connect_notify, occ); 1663 &overlay_connect_notify, occ);
1646 break; 1664 break;
diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c
index 0f7c0b15c..e68e449ad 100644
--- a/src/testbed/testbed_api_topology.c
+++ b/src/testbed/testbed_api_topology.c
@@ -1441,7 +1441,7 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
1441 (c->opq_parallel_topology_config_operations, op); 1441 (c->opq_parallel_topology_config_operations, op);
1442 GNUNET_TESTBED_operation_begin_wait_ (op); 1442 GNUNET_TESTBED_operation_begin_wait_ (op);
1443 LOG (GNUNET_ERROR_TYPE_DEBUG, 1443 LOG (GNUNET_ERROR_TYPE_DEBUG,
1444 "Generated %u connections\n", 1444 "Generated topology with %u connections\n",
1445 tc->link_array_size); 1445 tc->link_array_size);
1446 if (NULL != max_connections) 1446 if (NULL != max_connections)
1447 *max_connections = tc->link_array_size; 1447 *max_connections = tc->link_array_size;