aboutsummaryrefslogtreecommitdiff
path: root/src/dv
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-03-13 15:00:37 +0000
committerChristian Grothoff <christian@grothoff.org>2013-03-13 15:00:37 +0000
commit2c42856d3abf2be3a299583baf8ed18b06dbefd0 (patch)
treec454ff315c704188672262876707706fce0da05f /src/dv
parentd7fde87aac5d2d9842f167a40f793ca798cf06e0 (diff)
downloadgnunet-2c42856d3abf2be3a299583baf8ed18b06dbefd0.tar.gz
gnunet-2c42856d3abf2be3a299583baf8ed18b06dbefd0.zip
-more dv bookkeeping work
Diffstat (limited to 'src/dv')
-rw-r--r--src/dv/dv.h4
-rw-r--r--src/dv/gnunet-service-dv.c225
2 files changed, 202 insertions, 27 deletions
diff --git a/src/dv/dv.h b/src/dv/dv.h
index cfa09409e..ea5215a10 100644
--- a/src/dv/dv.h
+++ b/src/dv/dv.h
@@ -69,9 +69,9 @@ struct GNUNET_DV_DisconnectMessage
69 struct GNUNET_MessageHeader header; 69 struct GNUNET_MessageHeader header;
70 70
71 /** 71 /**
72 * The distance to the peer that we used to have 72 * Always zero.
73 */ 73 */
74 uint32_t distance GNUNET_PACKED; 74 uint32_t reserved GNUNET_PACKED;
75 75
76 /** 76 /**
77 * The peer that is no longer available. 77 * The peer that is no longer available.
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c
index c9b45b4e0..e6eb32778 100644
--- a/src/dv/gnunet-service-dv.c
+++ b/src/dv/gnunet-service-dv.c
@@ -249,12 +249,11 @@ struct ConsensusSet
249{ 249{
250 250
251 /** 251 /**
252 * Array of targets in the set, may include NULL 252 * Array of targets in the set, may include NULL entries if a
253 * entries if a neighbor has disconnected; the 253 * neighbor has disconnected; the targets are allocated with the
254 * targets are allocated with the respective 254 * respective container (i.e. 'struct RoutingNeighbor'), not here.
255 * 'struct Route', not here.
256 */ 255 */
257 struct Target **targets; 256 struct Route **targets;
258 257
259 /** 258 /**
260 * Size of the 'targets' array. 259 * Size of the 'targets' array.
@@ -461,38 +460,30 @@ send_data_to_plugin (const struct GNUNET_MessageHeader *message,
461 460
462 461
463/** 462/**
464 * Give an ACK message to the plugin, we transmitted a message for it. 463 * Forward a control message to the plugin.
465 * 464 *
466 * @param target peer that received the message 465 * @param message the message to send to the plugin
467 * @param uid plugin-chosen UID for the message 466 * @param distant_neighbor the original sender of the message
467 * @param distnace distance to the original sender of the message
468 */ 468 */
469static void 469static void
470send_ack_to_plugin (struct GNUNET_PeerIdentity *target, 470send_control_to_plugin (const struct GNUNET_MessageHeader *message)
471 uint32_t uid)
472{ 471{
473 struct GNUNET_DV_AckMessage *ack_msg;
474 struct PendingMessage *pending_message; 472 struct PendingMessage *pending_message;
475 size_t size; 473 size_t size;
476 474
477 if (NULL == client_handle) 475 if (NULL == client_handle)
478 { 476 {
479 GNUNET_STATISTICS_update (stats, 477 GNUNET_STATISTICS_update (stats,
480 "# acks discarded (no plugin)", 478 "# control messages discarded (no plugin)",
481 1, GNUNET_NO); 479 1, GNUNET_NO);
482 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 480 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
483 _("Refusing to queue messages, DV plugin not active.\n")); 481 _("Refusing to queue messages, DV plugin not active.\n"));
484 return; 482 return;
485 } 483 }
486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 484 size = ntohs (message->size);
487 "Delivering ACK for message to peer `%s'\n",
488 GNUNET_i2s (target));
489 size = sizeof (struct GNUNET_DV_AckMessage);
490 pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + size); 485 pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + size);
491 ack_msg = (struct GNUNET_DV_AckMessage *) &pending_message[1]; 486 memcpy (&pending_message[1], message, size);
492 ack_msg->header.size = htons (size);
493 ack_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DV_SEND_ACK);
494 ack_msg->uid = htonl (uid);
495 ack_msg->target = *target;
496 GNUNET_CONTAINER_DLL_insert_tail (plugin_pending_head, 487 GNUNET_CONTAINER_DLL_insert_tail (plugin_pending_head,
497 plugin_pending_tail, 488 plugin_pending_tail,
498 pending_message); 489 pending_message);
@@ -505,6 +496,77 @@ send_ack_to_plugin (struct GNUNET_PeerIdentity *target,
505 496
506 497
507/** 498/**
499 * Give an ACK message to the plugin, we transmitted a message for it.
500 *
501 * @param target peer that received the message
502 * @param uid plugin-chosen UID for the message
503 */
504static void
505send_ack_to_plugin (struct GNUNET_PeerIdentity *target,
506 uint32_t uid)
507{
508 struct GNUNET_DV_AckMessage ack_msg;
509
510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
511 "Delivering ACK for message to peer `%s'\n",
512 GNUNET_i2s (target));
513 ack_msg.header.size = htons (sizeof (ack_msg));
514 ack_msg.header.type = htons (GNUNET_MESSAGE_TYPE_DV_SEND_ACK);
515 ack_msg.uid = htonl (uid);
516 ack_msg.target = *target;
517 send_control_to_plugin (&ack_msg.header);
518}
519
520
521/**
522 * Give a CONNECT message to the plugin.
523 *
524 * @param target peer that connected
525 * @param distance distance to the target
526 */
527static void
528send_connect_to_plugin (const struct GNUNET_PeerIdentity *target,
529 uint32_t distance)
530{
531 struct GNUNET_DV_ConnectMessage cm;
532
533 if (NULL == client_handle)
534 return;
535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
536 "Delivering CONNECT about peer `%s'\n",
537 GNUNET_i2s (target));
538 cm.header.size = htons (sizeof (cm));
539 cm.header.type = htons (GNUNET_MESSAGE_TYPE_DV_CONNECT);
540 cm.distance = htonl (distance);
541 cm.peer = *target;
542 send_control_to_plugin (&cm.header);
543}
544
545
546/**
547 * Give a DISCONNECT message to the plugin.
548 *
549 * @param target peer that disconnected
550 */
551static void
552send_disconnect_to_plugin (const struct GNUNET_PeerIdentity *target)
553{
554 struct GNUNET_DV_DisconnectMessage dm;
555
556 if (NULL == client_handle)
557 return;
558 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
559 "Delivering DISCONNECT about peer `%s'\n",
560 GNUNET_i2s (target));
561 dm.header.size = htons (sizeof (dm));
562 dm.header.type = htons (GNUNET_MESSAGE_TYPE_DV_DISCONNECT);
563 dm.reserved = htonl (0);
564 dm.peer = *target;
565 send_control_to_plugin (&dm.header);
566}
567
568
569/**
508 * Function called to transfer a message to another peer 570 * Function called to transfer a message to another peer
509 * via core. 571 * via core.
510 * 572 *
@@ -557,6 +619,108 @@ core_transmit_notify (void *cls, size_t size, void *buf)
557 619
558 620
559/** 621/**
622 * Begin exchanging routing information with 'rn', updating
623 * our respective neighbor table in the process.
624 *
625 * @param rn neighbor with whom we should exchange the information
626 */
627static void
628exchange_routing_information (struct RoutingNeighbor *rn)
629{
630 GNUNET_break (0);
631 // FIXME
632}
633
634
635/**
636 * Find a free slot for storing a 'route' in the 'consensi'
637 * set at the given distance.
638 *
639 * @param distance distance to use for the set slot
640 */
641static unsigned int
642get_consensus_slot (uint32_t distance)
643{
644 struct ConsensusSet *cs;
645 unsigned int i;
646
647 cs = &consensi[distance];
648 i = 0;
649 while ( (i < cs->array_length) &&
650 (NULL != cs->targets[i]) ) i++;
651 if (i == cs->array_length)
652 GNUNET_array_grow (cs->targets,
653 cs->array_length,
654 cs->array_length * 2 + 2);
655 return i;
656}
657
658
659/**
660 * Setup an entry in the 'routing neighbor' table and begin the
661 * exchange with the new routing neighbor. Note that a routing
662 * neighbor can be a direct neighbor at the same time, in which case
663 * the peer identity of 'target' and 'next_hop->peer' will be the same
664 * (and the distance will be 1).
665 *
666 * If a routing neighbor already exists, ignore the update if
667 * the distance is not smaller; otherwise if the distance
668 * is smaller, replace the existing entry with the new route.
669 *
670 * @param next_hop first routing hop towards the routing neighbor
671 * @param target peer identity of the routing neighbor
672 * @param distance number of hops to the routing neighbor
673 */
674static void
675create_routing_neighbor (struct DirectNeighbor *next_hop,
676 const struct GNUNET_PeerIdentity *target,
677 uint32_t distance)
678{
679 struct RoutingNeighbor *rn;
680 unsigned int i;
681
682 rn = GNUNET_CONTAINER_multihashmap_get (routing_neighbors,
683 &target->hashPubKey);
684 if (NULL != rn)
685 {
686 /* update the entry, instead of creating a new one */
687 if (distance >= rn->route.target.distance)
688 return; /* ignore, distance is not better */
689 rn->route.next_hop = next_hop;
690 if (distance < rn->route.target.distance)
691 {
692 /* move to alternative consensi slot */
693 consensi[rn->route.target.distance].targets[rn->route.set_offset] = NULL;
694 rn->route.target.distance = distance;
695 i = get_consensus_slot (distance);
696 rn->route.set_offset = i;
697 consensi[distance].targets[i] = &rn->route;
698 }
699 if (DIRECT_NEIGHBOR_COST == distance)
700 {
701 /* we're now a direct neighbor, remove from set reachable via DV! */
702 send_disconnect_to_plugin (target);
703 }
704 return;
705 }
706 GNUNET_assert (distance < DEFAULT_FISHEYE_DEPTH - 1);
707 i = get_consensus_slot (distance);
708 rn = GNUNET_malloc (sizeof (struct RoutingNeighbor));
709 rn->route.next_hop = next_hop;
710 rn->route.target.peer = *target;
711 rn->route.target.distance = distance;
712 rn->route.set_offset = i;
713 consensi[distance].targets[i] = &rn->route;
714 exchange_routing_information (rn);
715 GNUNET_assert (GNUNET_YES ==
716 GNUNET_CONTAINER_multihashmap_put (direct_neighbors,
717 &target->hashPubKey,
718 rn,
719 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
720}
721
722
723/**
560 * Method called whenever a peer connects. 724 * Method called whenever a peer connects.
561 * 725 *
562 * @param cls closure 726 * @param cls closure
@@ -570,6 +734,7 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
570 unsigned int atsi_count) 734 unsigned int atsi_count)
571{ 735{
572 struct DirectNeighbor *neighbor; 736 struct DirectNeighbor *neighbor;
737 struct RoutingNeighbor *rn;
573 uint32_t distance; 738 uint32_t distance;
574 739
575 /* Check for connect to self message */ 740 /* Check for connect to self message */
@@ -585,14 +750,20 @@ handle_core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
585 } 750 }
586 if (DIRECT_NEIGHBOR_COST != distance) 751 if (DIRECT_NEIGHBOR_COST != distance)
587 return; /* is a DV-neighbor */ 752 return; /* is a DV-neighbor */
588 753 neighbor = GNUNET_malloc (sizeof (struct DirectNeighbor));
589 GNUNET_break (0); // FIXME... 754 neighbor->peer = *peer;
755 GNUNET_assert (GNUNET_YES ==
756 GNUNET_CONTAINER_multihashmap_put (direct_neighbors,
757 &peer->hashPubKey,
758 neighbor,
759 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
760 create_routing_neighbor (neighbor, peer, DIRECT_NEIGHBOR_COST);
590} 761}
591 762
592 763
593 764
594/** 765/**
595 * Core handler for dv data messages. Whatever this message 766 * Core handler for DV data messages. Whatever this message
596 * contains all we really have to do is rip it out of its 767 * contains all we really have to do is rip it out of its
597 * DV layering and give it to our pal the DV plugin to report 768 * DV layering and give it to our pal the DV plugin to report
598 * in with. 769 * in with.
@@ -816,6 +987,8 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
816 GNUNET_CONTAINER_multihashmap_destroy (all_routes); 987 GNUNET_CONTAINER_multihashmap_destroy (all_routes);
817 GNUNET_CORE_disconnect (core_api); 988 GNUNET_CORE_disconnect (core_api);
818 core_api = NULL; 989 core_api = NULL;
990 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
991 stats = NULL;
819 while (NULL != (pending = plugin_pending_head)) 992 while (NULL != (pending = plugin_pending_head))
820 { 993 {
821 GNUNET_CONTAINER_DLL_remove (plugin_pending_head, 994 GNUNET_CONTAINER_DLL_remove (plugin_pending_head,
@@ -911,7 +1084,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
911 1084
912 if (NULL == core_api) 1085 if (NULL == core_api)
913 return; 1086 return;
914 // FIXME: stats 1087 stats = GNUNET_STATISTICS_create ("dv", cfg);
915 GNUNET_SERVER_add_handlers (server, plugin_handlers); 1088 GNUNET_SERVER_add_handlers (server, plugin_handlers);
916 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 1089 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
917 &shutdown_task, NULL); 1090 &shutdown_task, NULL);
@@ -932,3 +1105,5 @@ main (int argc, char *const *argv)
932 GNUNET_SERVICE_run (argc, argv, "dv", GNUNET_SERVICE_OPTION_NONE, 1105 GNUNET_SERVICE_run (argc, argv, "dv", GNUNET_SERVICE_OPTION_NONE,
933 &run, NULL)) ? 0 : 1; 1106 &run, NULL)) ? 0 : 1;
934} 1107}
1108
1109/* end of gnunet-service-dv.c */