diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-13 15:00:37 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-13 15:00:37 +0000 |
commit | 2c42856d3abf2be3a299583baf8ed18b06dbefd0 (patch) | |
tree | c454ff315c704188672262876707706fce0da05f /src/dv | |
parent | d7fde87aac5d2d9842f167a40f793ca798cf06e0 (diff) | |
download | gnunet-2c42856d3abf2be3a299583baf8ed18b06dbefd0.tar.gz gnunet-2c42856d3abf2be3a299583baf8ed18b06dbefd0.zip |
-more dv bookkeeping work
Diffstat (limited to 'src/dv')
-rw-r--r-- | src/dv/dv.h | 4 | ||||
-rw-r--r-- | src/dv/gnunet-service-dv.c | 225 |
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 | */ |
469 | static void | 469 | static void |
470 | send_ack_to_plugin (struct GNUNET_PeerIdentity *target, | 470 | send_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 | */ | ||
504 | static void | ||
505 | send_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 | */ | ||
527 | static void | ||
528 | send_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 | */ | ||
551 | static void | ||
552 | send_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 | */ | ||
627 | static void | ||
628 | exchange_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 | */ | ||
641 | static unsigned int | ||
642 | get_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 | */ | ||
674 | static void | ||
675 | create_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 */ | ||