aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh_peer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/gnunet-service-mesh_peer.c')
-rw-r--r--src/mesh/gnunet-service-mesh_peer.c176
1 files changed, 87 insertions, 89 deletions
diff --git a/src/mesh/gnunet-service-mesh_peer.c b/src/mesh/gnunet-service-mesh_peer.c
index 13dc05c65..75decd3bb 100644
--- a/src/mesh/gnunet-service-mesh_peer.c
+++ b/src/mesh/gnunet-service-mesh_peer.c
@@ -23,6 +23,7 @@
23#include "gnunet_util_lib.h" 23#include "gnunet_util_lib.h"
24 24
25#include "gnunet-service-mesh_peer.h" 25#include "gnunet-service-mesh_peer.h"
26#include "gnunet-service-mesh_dht.h"
26#include "mesh_path.h" 27#include "mesh_path.h"
27 28
28/******************************************************************************/ 29/******************************************************************************/
@@ -393,95 +394,6 @@ peer_get_best_path (const struct MeshPeer *peer)
393} 394}
394 395
395 396
396
397/**
398 * Try to establish a new connection to this peer in the given tunnel.
399 * If the peer doesn't have any path to it yet, try to get one.
400 * If the peer already has some path, send a CREATE CONNECTION towards it.
401 *
402 * @param peer PeerInfo of the peer.
403 */
404static void
405peer_connect (struct MeshPeer *peer)
406{
407 struct MeshTunnel2 *t;
408 struct MeshPeerPath *p;
409 struct MeshConnection *c;
410 int rerun_dhtget;
411
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
413 "peer_connect towards %s\n",
414 peer2s (peer));
415 t = peer->tunnel;
416 c = NULL;
417 rerun_dhtget = GNUNET_NO;
418
419 if (NULL != peer->path_head)
420 {
421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "path exists\n");
422 p = peer_get_best_path (peer);
423 if (NULL != p)
424 {
425 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u hops\n", p->length);
426 c = tunnel_use_path (t, p);
427 if (NULL == c)
428 {
429 /* This case can happen when the path includes a first hop that is
430 * not yet known to be connected.
431 *
432 * This happens quite often during testing when running mesh
433 * under valgrind: core connect notifications come very late and the
434 * DHT result has already come and created a valid path.
435 * In this case, the peer->connections hashmap will be NULL and
436 * tunnel_use_path will not be able to create a connection from that
437 * path.
438 *
439 * Re-running the DHT GET should give core time to callback.
440 */
441 GNUNET_break(0);
442 rerun_dhtget = GNUNET_YES;
443 }
444 else
445 {
446 send_connection_create (c);
447 return;
448 }
449 }
450 }
451
452 if (NULL != peer->dhtget && GNUNET_YES == rerun_dhtget)
453 {
454 GNUNET_DHT_get_stop (peer->dhtget);
455 peer->dhtget = NULL;
456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
457 " Stopping DHT GET for peer %s\n", peer2s (peer));
458 }
459
460 if (NULL == peer->dhtget)
461 {
462 const struct GNUNET_PeerIdentity *id;
463 struct GNUNET_HashCode phash;
464
465 id = GNUNET_PEER_resolve2 (peer->id);
466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
467 " Starting DHT GET for peer %s\n", peer2s (peer));
468 GNUNET_CRYPTO_hash (&id, sizeof (struct GNUNET_PeerIdentity), &phash);
469 peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
470 GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
471 &phash, /* key to search */
472 dht_replication_level, /* replication level */
473 GNUNET_DHT_RO_RECORD_ROUTE |
474 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
475 NULL, /* xquery */
476 0, /* xquery bits */
477 &dht_get_id_handler, peer);
478 if (MESH_TUNNEL_NEW == t->state)
479 tunnel_change_state (t, MESH_TUNNEL_SEARCHING);
480 }
481}
482
483
484
485/** 397/**
486 * Add the path to the peer and update the path used to reach it in case this 398 * Add the path to the peer and update the path used to reach it in case this
487 * is the shortest. 399 * is the shortest.
@@ -622,3 +534,89 @@ GMP_shutdown (void)
622 GNUNET_CONTAINER_multipeermap_iterate (peers, &shutdown_tunnel, NULL); 534 GNUNET_CONTAINER_multipeermap_iterate (peers, &shutdown_tunnel, NULL);
623} 535}
624 536
537
538/**
539 * Try to establish a new connection to this peer in the given tunnel.
540 * If the peer doesn't have any path to it yet, try to get one.
541 * If the peer already has some path, send a CREATE CONNECTION towards it.
542 *
543 * @param peer PeerInfo of the peer.
544 */
545void
546GMP_connect (struct MeshPeer *peer)
547{
548 struct MeshTunnel2 *t;
549 struct MeshPeerPath *p;
550 struct MeshConnection *c;
551 int rerun_dhtget;
552
553 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
554 "peer_connect towards %s\n",
555 peer2s (peer));
556 t = peer->tunnel;
557 c = NULL;
558 rerun_dhtget = GNUNET_NO;
559
560 if (NULL != peer->path_head)
561 {
562 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "path exists\n");
563 p = peer_get_best_path (peer);
564 if (NULL != p)
565 {
566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u hops\n", p->length);
567 c = tunnel_use_path (t, p);
568 if (NULL == c)
569 {
570 /* This case can happen when the path includes a first hop that is
571 * not yet known to be connected.
572 *
573 * This happens quite often during testing when running mesh
574 * under valgrind: core connect notifications come very late and the
575 * DHT result has already come and created a valid path.
576 * In this case, the peer->connections hashmap will be NULL and
577 * tunnel_use_path will not be able to create a connection from that
578 * path.
579 *
580 * Re-running the DHT GET should give core time to callback.
581 */
582 GNUNET_break(0);
583 rerun_dhtget = GNUNET_YES;
584 }
585 else
586 {
587 send_connection_create (c);
588 return;
589 }
590 }
591 }
592
593 if (NULL != peer->dhtget && GNUNET_YES == rerun_dhtget)
594 {
595 GNUNET_DHT_get_stop (peer->dhtget);
596 peer->dhtget = NULL;
597 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
598 " Stopping DHT GET for peer %s\n", peer2s (peer));
599 }
600
601 if (NULL == peer->dhtget)
602 {
603 const struct GNUNET_PeerIdentity *id;
604 struct GNUNET_HashCode phash;
605
606 id = GNUNET_PEER_resolve2 (peer->id);
607 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
608 " Starting DHT GET for peer %s\n", peer2s (peer));
609 GNUNET_CRYPTO_hash (&id, sizeof (struct GNUNET_PeerIdentity), &phash);
610 peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
611 GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
612 &phash, /* key to search */
613 dht_replication_level, /* replication level */
614 GNUNET_DHT_RO_RECORD_ROUTE |
615 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
616 NULL, /* xquery */
617 0, /* xquery bits */
618 &dht_get_id_handler, peer);
619 if (MESH_TUNNEL_NEW == t->state)
620 tunnel_change_state (t, MESH_TUNNEL_SEARCHING);
621 }
622} \ No newline at end of file