diff options
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 1259 |
1 files changed, 792 insertions, 467 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index d903e7584..edbad550a 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -90,65 +90,134 @@ mesh_debug (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
90 | GNUNET_TIME_UNIT_SECONDS,\ | 90 | GNUNET_TIME_UNIT_SECONDS,\ |
91 | 5) | 91 | 5) |
92 | 92 | ||
93 | |||
94 | |||
95 | /******************************************************************************/ | 93 | /******************************************************************************/ |
96 | /************************ DATA STRUCTURES ****************************/ | 94 | /************************ ENUMERATIONS ****************************/ |
97 | /******************************************************************************/ | 95 | /******************************************************************************/ |
98 | 96 | ||
99 | /** | 97 | /** |
100 | * Information regarding a path | 98 | * All the states a peer participating in a tunnel can be in. |
101 | */ | 99 | */ |
102 | struct MeshPath | 100 | enum MeshPeerState |
103 | { | 101 | { |
102 | /** | ||
103 | * Peer only retransmits traffic, is not a final destination | ||
104 | */ | ||
105 | MESH_PEER_RELAY, | ||
104 | 106 | ||
105 | /** | 107 | /** |
106 | * Linked list | 108 | * Path to the peer not known yet |
107 | */ | 109 | */ |
108 | struct MeshPath *next; | 110 | MESH_PEER_SEARCHING, |
109 | struct MeshPath *prev; | ||
110 | 111 | ||
111 | /** | 112 | /** |
112 | * Whether the path is serving traffic in a tunnel or is a backup | 113 | * Request sent, not yet answered. |
113 | */ | 114 | */ |
114 | int in_use; | 115 | MESH_PEER_WAITING, |
115 | 116 | ||
116 | /** | 117 | /** |
117 | * List of all the peers that form the path from origin to target | 118 | * Peer connected and ready to accept data |
118 | */ | 119 | */ |
119 | GNUNET_PEER_Id *peers; | 120 | MESH_PEER_READY, |
120 | 121 | ||
121 | /** | 122 | /** |
122 | * Number of peers (hops) in the path | 123 | * Peer connected previosly but not responding |
123 | */ | 124 | */ |
124 | unsigned int length; | 125 | MESH_PEER_RECONNECTING |
125 | }; | 126 | }; |
126 | 127 | ||
127 | 128 | ||
129 | /******************************************************************************/ | ||
130 | /************************ DATA STRUCTURES ****************************/ | ||
131 | /******************************************************************************/ | ||
132 | |||
128 | /** | 133 | /** |
129 | * All the states a peer participating in a tunnel can be in. | 134 | * Information regarding a possible path to reach a single peer |
130 | */ | 135 | */ |
131 | enum MeshPeerState | 136 | struct MeshPeerPath |
132 | { | 137 | { |
138 | |||
133 | /** | 139 | /** |
134 | * Path to the peer not known yet | 140 | * Linked list |
135 | */ | 141 | */ |
136 | MESH_PEER_SEARCHING, | 142 | struct MeshPeerPath *next; |
143 | struct MeshPeerPath *prev; | ||
137 | 144 | ||
138 | /** | 145 | /** |
139 | * Request sent, not yet answered. | 146 | * List of all the peers that form the path from origin to target. |
140 | */ | 147 | */ |
141 | MESH_PEER_WAITING, | 148 | GNUNET_PEER_Id *peers; |
142 | 149 | ||
143 | /** | 150 | /** |
144 | * Peer connected and ready to accept data | 151 | * Number of peers (hops) in the path |
145 | */ | 152 | */ |
146 | MESH_PEER_READY, | 153 | unsigned int length; |
154 | |||
155 | }; | ||
156 | |||
157 | |||
158 | /** | ||
159 | * Node of path tree for a tunnel | ||
160 | */ | ||
161 | struct MeshTunnelPathNode | ||
162 | { | ||
163 | /** | ||
164 | * Tunnel this node belongs to (and therefore tree) | ||
165 | */ | ||
166 | struct MeshTunnel *t; | ||
167 | |||
168 | /** | ||
169 | * Peer this node describes | ||
170 | */ | ||
171 | struct MeshPeerInfo *peer; | ||
172 | |||
173 | /** | ||
174 | * Parent node in the tree | ||
175 | */ | ||
176 | struct MeshTunnelPathNode *parent; | ||
177 | |||
178 | /** | ||
179 | * Array of children | ||
180 | */ | ||
181 | struct MeshTunnelPathNode *children; | ||
182 | |||
183 | /** | ||
184 | * Number of children | ||
185 | */ | ||
186 | unsigned int nchildren; | ||
147 | 187 | ||
148 | /** | 188 | /** |
149 | * Peer connected previosly but not responding | 189 | * Status of the peer in the tunnel |
150 | */ | 190 | */ |
151 | MESH_PEER_RECONNECTING | 191 | enum MeshPeerState status; |
192 | }; | ||
193 | |||
194 | |||
195 | /** | ||
196 | * Tree to reach all peers in the tunnel | ||
197 | */ | ||
198 | struct MeshTunnelPath | ||
199 | { | ||
200 | /** | ||
201 | * Tunnel this path belongs to | ||
202 | */ | ||
203 | struct MeshTunnel *t; | ||
204 | |||
205 | /** | ||
206 | * Root node of peer tree | ||
207 | */ | ||
208 | struct MeshTunnelPathNode *root; | ||
209 | |||
210 | /** | ||
211 | * Node that represents our position in the tree (for non local tunnels) | ||
212 | */ | ||
213 | struct MeshTunnelPathNode *me; | ||
214 | |||
215 | /** | ||
216 | * Cache of all peers and the first hop to them. | ||
217 | * Indexed by Peer_Identity, contains a pointer to the PeerInfo of 1st hop. | ||
218 | */ | ||
219 | struct GNUNET_CONTAINER_MultiHashMap *first_hops; | ||
220 | |||
152 | }; | 221 | }; |
153 | 222 | ||
154 | 223 | ||
@@ -197,11 +266,6 @@ struct MeshPeerInfo | |||
197 | GNUNET_PEER_Id id; | 266 | GNUNET_PEER_Id id; |
198 | 267 | ||
199 | /** | 268 | /** |
200 | * Is the peer reachable? Is the peer even connected? | ||
201 | */ | ||
202 | enum MeshPeerState state; | ||
203 | |||
204 | /** | ||
205 | * Last time we heard from this peer | 269 | * Last time we heard from this peer |
206 | */ | 270 | */ |
207 | struct GNUNET_TIME_Absolute last_contact; | 271 | struct GNUNET_TIME_Absolute last_contact; |
@@ -212,10 +276,14 @@ struct MeshPeerInfo | |||
212 | int n_reconnect_attempts; | 276 | int n_reconnect_attempts; |
213 | 277 | ||
214 | /** | 278 | /** |
215 | * Paths to reach the peer | 279 | * Paths to reach the peer, ordered by ascending hop count |
216 | */ | 280 | */ |
217 | struct MeshPath *path; | 281 | struct MeshPeerPath *path_head; |
218 | struct MeshPath *path_tail; | 282 | |
283 | /** | ||
284 | * Paths to reach the peer, ordered by ascending hop count | ||
285 | */ | ||
286 | struct MeshPeerPath *path_tail; | ||
219 | 287 | ||
220 | /** | 288 | /** |
221 | * Handle to stop the DHT search for a path to this peer | 289 | * Handle to stop the DHT search for a path to this peer |
@@ -233,9 +301,17 @@ struct MeshPeerInfo | |||
233 | struct MeshDataDescriptor *infos[CORE_QUEUE_SIZE]; | 301 | struct MeshDataDescriptor *infos[CORE_QUEUE_SIZE]; |
234 | 302 | ||
235 | /** | 303 | /** |
236 | * Task to send keepalive packets over the current active path | 304 | * Array of tunnels this peer participates in |
305 | * (most probably a small amount, therefore not a hashmap) | ||
306 | * When the path to the peer changes, notify these tunnels to let them | ||
307 | * re-adjust their path trees. | ||
237 | */ | 308 | */ |
238 | GNUNET_SCHEDULER_TaskIdentifier path_refresh_task; | 309 | struct MeshTunnel **tunnels; |
310 | |||
311 | /** | ||
312 | * Number of tunnels above | ||
313 | */ | ||
314 | unsigned int ntunnels; | ||
239 | }; | 315 | }; |
240 | 316 | ||
241 | 317 | ||
@@ -336,7 +412,6 @@ struct MeshTunnel | |||
336 | */ | 412 | */ |
337 | unsigned int peers_total; | 413 | unsigned int peers_total; |
338 | 414 | ||
339 | |||
340 | /** | 415 | /** |
341 | * Client owner of the tunnel, if any | 416 | * Client owner of the tunnel, if any |
342 | */ | 417 | */ |
@@ -348,8 +423,40 @@ struct MeshTunnel | |||
348 | struct MeshQueue *queue_head; | 423 | struct MeshQueue *queue_head; |
349 | struct MeshQueue *queue_tail; | 424 | struct MeshQueue *queue_tail; |
350 | 425 | ||
426 | /** | ||
427 | * Tunnel paths | ||
428 | */ | ||
429 | struct MeshTunnelPath *paths; | ||
430 | |||
431 | /** | ||
432 | * Task to keep the used paths alive | ||
433 | */ | ||
434 | GNUNET_SCHEDULER_TaskIdentifier path_refresh_task; | ||
435 | }; | ||
436 | |||
437 | |||
438 | /** | ||
439 | * Info needed to work with tunnel paths and peers | ||
440 | */ | ||
441 | struct MeshPathInfo | ||
442 | { | ||
443 | /** | ||
444 | * Tunnel | ||
445 | */ | ||
446 | struct MeshTunnel *t; | ||
447 | |||
448 | /** | ||
449 | * Destination peer | ||
450 | */ | ||
451 | struct MeshPeerInfo *peer; | ||
452 | |||
453 | /** | ||
454 | * Path itself | ||
455 | */ | ||
456 | struct MeshPeerPath *path; | ||
351 | }; | 457 | }; |
352 | 458 | ||
459 | |||
353 | /** | 460 | /** |
354 | * Struct containing information about a client of the service | 461 | * Struct containing information about a client of the service |
355 | */ | 462 | */ |
@@ -382,7 +489,7 @@ struct MeshClient | |||
382 | struct GNUNET_CONTAINER_MultiHashMap *types; | 489 | struct GNUNET_CONTAINER_MultiHashMap *types; |
383 | 490 | ||
384 | /** | 491 | /** |
385 | * Used for seachching peers offering a service | 492 | * Used to search peers offering a service |
386 | */ | 493 | */ |
387 | struct GNUNET_DHT_GetHandle *dht_get_type; | 494 | struct GNUNET_DHT_GetHandle *dht_get_type; |
388 | 495 | ||
@@ -465,17 +572,151 @@ GNUNET_SCHEDULER_TaskIdentifier announce_id_task; | |||
465 | 572 | ||
466 | 573 | ||
467 | /******************************************************************************/ | 574 | /******************************************************************************/ |
575 | /************************ PERIODIC FUNCTIONS ****************************/ | ||
576 | /******************************************************************************/ | ||
577 | |||
578 | /** | ||
579 | * Announce iterator over for each application provided by the peer | ||
580 | * | ||
581 | * @param cls closure | ||
582 | * @param key current key code | ||
583 | * @param value value in the hash map | ||
584 | * @return GNUNET_YES if we should continue to | ||
585 | * iterate, | ||
586 | * GNUNET_NO if not. | ||
587 | */ | ||
588 | static int | ||
589 | announce_application (void *cls, const GNUNET_HashCode * key, void *value) | ||
590 | { | ||
591 | /* FIXME are hashes in multihash map equal on all aquitectures? */ | ||
592 | GNUNET_DHT_put (dht_handle, key, 10U, GNUNET_DHT_RO_RECORD_ROUTE, | ||
593 | GNUNET_BLOCK_TYPE_TEST, sizeof (struct GNUNET_PeerIdentity), | ||
594 | (const char *) &my_full_id, | ||
595 | #if MESH_DEBUG | ||
596 | GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_FOREVER_REL, | ||
597 | &mesh_debug, "DHT_put for app completed"); | ||
598 | #else | ||
599 | GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
600 | APP_ANNOUNCE_TIME), | ||
601 | APP_ANNOUNCE_TIME, | ||
602 | NULL, NULL); | ||
603 | #endif | ||
604 | return GNUNET_OK; | ||
605 | } | ||
606 | |||
607 | |||
608 | /** | ||
609 | * Periodically announce what applications are provided by local clients | ||
610 | * | ||
611 | * @param cls closure | ||
612 | * @param tc task context | ||
613 | */ | ||
614 | static void | ||
615 | announce_applications (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
616 | { | ||
617 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
618 | { | ||
619 | announce_applications_task = GNUNET_SCHEDULER_NO_TASK; | ||
620 | return; | ||
621 | } | ||
622 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Starting PUT for apps\n"); | ||
623 | GNUNET_CONTAINER_multihashmap_iterate (applications, &announce_application, | ||
624 | NULL); | ||
625 | announce_applications_task = | ||
626 | GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME, &announce_applications, | ||
627 | cls); | ||
628 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Finished PUT for apps\n"); | ||
629 | return; | ||
630 | } | ||
631 | |||
632 | |||
633 | /** | ||
634 | * Periodically announce self id in the DHT | ||
635 | * | ||
636 | * @param cls closure | ||
637 | * @param tc task context | ||
638 | */ | ||
639 | static void | ||
640 | announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
641 | { | ||
642 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
643 | { | ||
644 | announce_id_task = GNUNET_SCHEDULER_NO_TASK; | ||
645 | return; | ||
646 | } | ||
647 | /* TODO | ||
648 | * - Set data expiration in function of X | ||
649 | * - Adapt X to churn | ||
650 | */ | ||
651 | GNUNET_DHT_put (dht_handle, /* DHT handle */ | ||
652 | &my_full_id.hashPubKey, /* Key to use */ | ||
653 | 10U, /* Replication level */ | ||
654 | GNUNET_DHT_RO_RECORD_ROUTE, /* DHT options */ | ||
655 | GNUNET_BLOCK_TYPE_TEST, /* Block type */ | ||
656 | 0, /* Size of the data */ | ||
657 | NULL, /* Data itself */ | ||
658 | GNUNET_TIME_absolute_get_forever (), /* Data expiration */ | ||
659 | GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */ | ||
660 | #if MESH_DEBUG | ||
661 | &mesh_debug, "DHT_put for id completed"); | ||
662 | #else | ||
663 | NULL, /* Continuation */ | ||
664 | NULL); /* Continuation closure */ | ||
665 | #endif | ||
666 | announce_id_task = | ||
667 | GNUNET_SCHEDULER_add_delayed (ID_ANNOUNCE_TIME, &announce_id, cls); | ||
668 | } | ||
669 | |||
670 | |||
671 | /** | ||
672 | * Send keepalive packets for a peer | ||
673 | * | ||
674 | * @param cls unused | ||
675 | * @param tc unused | ||
676 | * | ||
677 | * FIXME path | ||
678 | */ | ||
679 | static void | ||
680 | path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
681 | { | ||
682 | struct MeshTunnel *t = cls; | ||
683 | // struct GNUNET_PeerIdentity id; | ||
684 | |||
685 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
686 | { | ||
687 | return; | ||
688 | } | ||
689 | /* FIXME implement multicast keepalive. Just an empty multicast packet? */ | ||
690 | // GNUNET_PEER_resolve (path_get_first_hop (path->t, path->peer)->id, &id); | ||
691 | // GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | ||
692 | // GNUNET_TIME_UNIT_FOREVER_REL, &id, | ||
693 | // sizeof (struct GNUNET_MESH_ManipulatePath) | ||
694 | // + | ||
695 | // (path->path->length * | ||
696 | // sizeof (struct GNUNET_PeerIdentity)), | ||
697 | // &send_core_create_path, | ||
698 | // t); | ||
699 | t->path_refresh_task = | ||
700 | GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh, | ||
701 | t); | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | |||
706 | /******************************************************************************/ | ||
468 | /****************** GENERAL HELPER FUNCTIONS ************************/ | 707 | /****************** GENERAL HELPER FUNCTIONS ************************/ |
469 | /******************************************************************************/ | 708 | /******************************************************************************/ |
470 | 709 | ||
471 | /** | 710 | /** |
472 | * Retrieve the MeshPeerInfo stucture associated with the peer, create one | 711 | * Retrieve the MeshPeerInfo stucture associated with the peer, create one |
473 | * and insert it in the appropiate structures if the peer is not known yet. | 712 | * and insert it in the appropiate structures if the peer is not known yet. |
713 | * | ||
474 | * @param peer Identity of the peer | 714 | * @param peer Identity of the peer |
715 | * | ||
475 | * @return Existing or newly created peer info | 716 | * @return Existing or newly created peer info |
476 | */ | 717 | */ |
477 | static struct MeshPeerInfo * | 718 | static struct MeshPeerInfo * |
478 | get_peer_info (const struct GNUNET_PeerIdentity *peer) | 719 | peer_info_get (const struct GNUNET_PeerIdentity *peer) |
479 | { | 720 | { |
480 | struct MeshPeerInfo *peer_info; | 721 | struct MeshPeerInfo *peer_info; |
481 | 722 | ||
@@ -487,62 +728,84 @@ get_peer_info (const struct GNUNET_PeerIdentity *peer) | |||
487 | GNUNET_CONTAINER_multihashmap_put (peers, &peer->hashPubKey, peer_info, | 728 | GNUNET_CONTAINER_multihashmap_put (peers, &peer->hashPubKey, peer_info, |
488 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 729 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
489 | peer_info->id = GNUNET_PEER_intern (peer); | 730 | peer_info->id = GNUNET_PEER_intern (peer); |
490 | peer_info->state = MESH_PEER_SEARCHING; | ||
491 | } | 731 | } |
492 | 732 | ||
493 | return peer_info; | 733 | return peer_info; |
494 | } | 734 | } |
495 | 735 | ||
736 | |||
737 | #if LATER | ||
496 | /** | 738 | /** |
497 | * Find the first peer whom to send a packet to go down this path | 739 | * Destroy the peer_info and free any allocated resources linked to it |
498 | * @param path The path to use | 740 | * @param t tunnel the path belongs to |
499 | * @return short id of the next peer, myid in case of local delivery, | 741 | * @param pi the peer_info to destroy |
500 | * or 0 in case of error | 742 | * @return GNUNET_OK on success |
501 | */ | 743 | */ |
502 | static GNUNET_PEER_Id | 744 | static int |
503 | get_first_hop (struct MeshPath *path) | 745 | peer_info_destroy (struct MeshPeerInfo *pi) |
504 | { | 746 | { |
505 | unsigned int i; | 747 | GNUNET_HashCode hash; |
748 | struct GNUNET_PeerIdentity id; | ||
506 | 749 | ||
507 | while (NULL != path) | 750 | GNUNET_PEER_resolve (pi->id, &id); |
508 | { | 751 | GNUNET_PEER_change_rc (pi->id, -1); |
509 | if (path->in_use) | 752 | GNUNET_CRYPTO_hash (&id, sizeof (struct GNUNET_PeerIdentity), &hash); |
510 | break; | ||
511 | path = path->next; | ||
512 | } | ||
513 | if (NULL == path) | ||
514 | { | ||
515 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
516 | "tried to get the next hop from an invalid path\n"); | ||
517 | return 0; | ||
518 | } | ||
519 | 753 | ||
520 | for (i = 0; i < path->length; i++) | 754 | GNUNET_CONTAINER_multihashmap_remove (peers, &hash, pi); |
521 | { | 755 | GNUNET_SCHEDULER_cancel (pi->path_refresh_task); |
522 | if (path->peers[i] == myid) | 756 | GNUNET_free (pi); |
523 | { | 757 | return GNUNET_OK; |
524 | if (i < path->length - 1) | ||
525 | { | ||
526 | return path->peers[i + 1]; | ||
527 | } | ||
528 | else | ||
529 | { | ||
530 | return myid; | ||
531 | } | ||
532 | } | ||
533 | } | ||
534 | return 0; | ||
535 | } | 758 | } |
759 | #endif | ||
536 | 760 | ||
537 | 761 | ||
538 | /** | 762 | /** |
539 | * Get the cost of the path. | 763 | * Destroy the path and free any allocated resources linked to it |
540 | * @param path The path to analyze | 764 | * |
541 | * @return Number of hops to reach destination, UINT_MAX in case the peer is not | 765 | * @param p the path to destroy |
542 | * in the path | 766 | * |
767 | * @return GNUNET_OK on success | ||
768 | */ | ||
769 | static int | ||
770 | path_destroy (struct MeshPeerPath *p) | ||
771 | { | ||
772 | GNUNET_PEER_decrement_rcs (p->peers, p->length); | ||
773 | GNUNET_free (p->peers); | ||
774 | GNUNET_free (p); | ||
775 | return GNUNET_OK; | ||
776 | } | ||
777 | |||
778 | |||
779 | /** | ||
780 | * Find the first peer whom to send a packet to go down this path | ||
781 | * | ||
782 | * @param t The tunnel to use | ||
783 | * @param peer The peerinfo of the peer we are trying to reach | ||
784 | * | ||
785 | * @return peerinfo of the peer who is the first hop in the tunnel | ||
786 | * NULL on error | ||
787 | */ | ||
788 | static struct MeshPeerInfo * | ||
789 | path_get_first_hop (struct MeshTunnel *t, struct MeshPeerInfo *peer) | ||
790 | { | ||
791 | struct GNUNET_PeerIdentity id; | ||
792 | |||
793 | GNUNET_PEER_resolve(peer->id, &id); | ||
794 | return GNUNET_CONTAINER_multihashmap_get(t->paths->first_hops, | ||
795 | &id.hashPubKey); | ||
796 | } | ||
797 | |||
798 | |||
799 | /** | ||
800 | * Get the length of a path | ||
801 | * | ||
802 | * @param path The path to measure, with the local peer at any point of it | ||
803 | * | ||
804 | * @return Number of hops to reach destination | ||
805 | * UINT_MAX in case the peer is not in the path | ||
543 | */ | 806 | */ |
544 | static unsigned int | 807 | static unsigned int |
545 | get_path_cost (struct MeshPath *path) | 808 | path_get_length (struct MeshPeerPath *path) |
546 | { | 809 | { |
547 | unsigned int i; | 810 | unsigned int i; |
548 | 811 | ||
@@ -560,61 +823,136 @@ get_path_cost (struct MeshPath *path) | |||
560 | 823 | ||
561 | 824 | ||
562 | /** | 825 | /** |
826 | * Get the cost of the path relative to the already built tunnel tree | ||
827 | * | ||
828 | * @param t The tunnel to which compare | ||
829 | * @param path The individual path to reach a peer | ||
830 | * | ||
831 | * @return Number of hops to reach destination, UINT_MAX in case the peer is not | ||
832 | * in the path | ||
833 | * | ||
834 | * TODO: remove dummy implementation, look into the tunnel tree | ||
835 | */ | ||
836 | static unsigned int | ||
837 | path_get_cost (struct MeshTunnel *t, struct MeshPeerPath *path) | ||
838 | { | ||
839 | return path_get_length(path); | ||
840 | } | ||
841 | |||
842 | |||
843 | /** | ||
563 | * Add the path to the peer and update the path used to reach it in case this | 844 | * Add the path to the peer and update the path used to reach it in case this |
564 | * is the shortest. | 845 | * is the shortest. |
846 | * | ||
565 | * @param peer_info Destination peer to add the path to. | 847 | * @param peer_info Destination peer to add the path to. |
566 | * @param path New path to add. Last peer must be the peer in arg 1. | 848 | * @param path New path to add. Last peer must be the peer in arg 1. |
849 | * | ||
850 | * TODO: trim the part from origin to us? Add it as path to origin? | ||
567 | */ | 851 | */ |
568 | static void | 852 | static void |
569 | add_path_to_peer (struct MeshPeerInfo *peer_info, struct MeshPath *path) | 853 | path_add_to_peer (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path) |
570 | { | 854 | { |
571 | unsigned int i; | 855 | unsigned int l; |
572 | unsigned int new_cost; | 856 | struct MeshPeerPath *aux; |
573 | unsigned int best_cost; | ||
574 | struct MeshPath *aux; | ||
575 | struct MeshPath *best; | ||
576 | 857 | ||
577 | if (NULL == peer_info || NULL == path) | 858 | if (NULL == peer_info || NULL == path) |
859 | { | ||
860 | GNUNET_break (0); | ||
578 | return; | 861 | return; |
862 | } | ||
579 | 863 | ||
580 | new_cost = get_path_cost (path); | 864 | l = path_get_length (path); |
581 | best_cost = UINT_MAX; | 865 | |
582 | best = NULL; | 866 | for (aux = peer_info->path_head; aux != NULL; aux = aux->next) |
583 | for (aux = peer_info->path; aux != NULL; aux = aux->next) | ||
584 | { | 867 | { |
585 | if ((i = get_path_cost (aux)) < best_cost) | 868 | if (path_get_length (aux) > l) |
586 | { | 869 | { |
587 | best = aux; | 870 | GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head, |
588 | best_cost = i; | 871 | peer_info->path_tail, |
872 | aux, | ||
873 | path); | ||
589 | } | 874 | } |
590 | } | 875 | } |
591 | if (best_cost < new_cost) | 876 | GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, |
877 | peer_info->path_tail, | ||
878 | path); | ||
879 | return; | ||
880 | } | ||
881 | |||
882 | |||
883 | /** | ||
884 | * Notify a tunnel that a connection has broken that affects at least | ||
885 | * some of its peers. | ||
886 | * | ||
887 | * @param t Tunnel affected | ||
888 | * @param peer Peer that (at least) has been affected by the disconnection | ||
889 | * @param p1 Peer that got disconnected from p2 | ||
890 | * @param p2 Peer that got disconnected from p1 | ||
891 | */ | ||
892 | static void | ||
893 | tunnel_notify_connection_broken(struct MeshTunnel *t, | ||
894 | struct MeshPeerInfo *peer, | ||
895 | GNUNET_PEER_Id p1, | ||
896 | GNUNET_PEER_Id p2); | ||
897 | |||
898 | |||
899 | /** | ||
900 | * Remove all paths that rely on a direct connection between p1 and p2 | ||
901 | * from the peer itself and notify all tunnels about it. | ||
902 | * | ||
903 | * @param pi PeerInfo of affected peer | ||
904 | * @param p1 GNUNET_PEER_Id of one peer. | ||
905 | * @param p2 GNUNET_PEER_Id of another peer that was connected to the first and | ||
906 | * no longer is. | ||
907 | */ | ||
908 | static void | ||
909 | path_remove_from_peer (struct MeshPeerInfo *peer, | ||
910 | GNUNET_PEER_Id p1, | ||
911 | GNUNET_PEER_Id p2) | ||
912 | { | ||
913 | struct MeshPeerPath *p; | ||
914 | struct MeshPeerPath *aux; | ||
915 | unsigned int destroyed; | ||
916 | unsigned int i; | ||
917 | |||
918 | destroyed = 0; | ||
919 | p = peer->path_head; | ||
920 | while (NULL != p) | ||
592 | { | 921 | { |
593 | path->in_use = 0; | 922 | aux = p->next; |
594 | GNUNET_CONTAINER_DLL_insert_tail (peer_info->path, peer_info->path_tail, | 923 | for (i = 0; i < (p->length - 1); i++) |
595 | path); | 924 | { |
925 | if ((p->peers[i] == p1 && p->peers[i + 1] == p2) || | ||
926 | (p->peers[i] == p2 && p->peers[i + 1] == p1)) | ||
927 | { | ||
928 | path_destroy(p); | ||
929 | destroyed++; | ||
930 | break; | ||
931 | } | ||
932 | } | ||
933 | p = aux; | ||
596 | } | 934 | } |
597 | else | 935 | if (0 == destroyed) |
936 | return; | ||
937 | |||
938 | for (i = 0; i < peer->ntunnels; i++) | ||
598 | { | 939 | { |
599 | if (NULL != best) | 940 | tunnel_notify_connection_broken(peer->tunnels[i], peer, p1, p2); |
600 | best->in_use = 0; | ||
601 | path->in_use = 1; | ||
602 | GNUNET_CONTAINER_DLL_insert (peer_info->path, peer_info->path_tail, path); | ||
603 | } | 941 | } |
604 | return; | ||
605 | } | 942 | } |
606 | 943 | ||
607 | 944 | ||
608 | /** | 945 | /** |
609 | * Add the path to the peer and update the path used to reach it in case this | 946 | * Add the path to the origin peer and update the path used to reach it in case |
610 | * is the shortest. The path is given in reverse, the destination peer is | 947 | * this is the shortest. |
611 | * path[0]. The function modifies the path, inverting it to use the origin as | 948 | * The path is given in peer_info -> destination, therefore we turn the path |
612 | * destination. | 949 | * upside down first. |
613 | * @param peer_info Destination peer to add the path to. | 950 | * |
614 | * @param path New path to add. First peer must be the peer in arg 1. | 951 | * @param peer_info Peer to add the path to, being the origin of the path. |
952 | * @param path New path to add after being inversed. | ||
615 | */ | 953 | */ |
616 | static void | 954 | static void |
617 | add_path_to_origin (struct MeshPeerInfo *peer_info, struct MeshPath *path) | 955 | path_add_to_origin (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path) |
618 | { | 956 | { |
619 | GNUNET_PEER_Id aux; | 957 | GNUNET_PEER_Id aux; |
620 | unsigned int i; | 958 | unsigned int i; |
@@ -625,17 +963,138 @@ add_path_to_origin (struct MeshPeerInfo *peer_info, struct MeshPath *path) | |||
625 | path->peers[i] = path->peers[path->length - i - 1]; | 963 | path->peers[i] = path->peers[path->length - i - 1]; |
626 | path->peers[path->length - i - 1] = aux; | 964 | path->peers[path->length - i - 1] = aux; |
627 | } | 965 | } |
628 | add_path_to_peer (peer_info, path); | 966 | path_add_to_peer (peer_info, path); |
967 | } | ||
968 | |||
969 | /** | ||
970 | * Integrate a stand alone path into the tunnel tree. | ||
971 | * | ||
972 | * @param t Tunnel where to add the new path. | ||
973 | * @param p Path to be integrated. | ||
974 | * | ||
975 | * @return GNUNET_OK in case of success. | ||
976 | * GNUNET_SYSERR in case of error. | ||
977 | * | ||
978 | * FIXME path: remove old path to the same peer if needed | ||
979 | */ | ||
980 | static int | ||
981 | path_add_to_tunnel(struct MeshTunnel *t, struct MeshPeerPath *p) | ||
982 | { | ||
983 | struct MeshTunnelPathNode *parent; | ||
984 | struct MeshTunnelPathNode *n; | ||
985 | struct GNUNET_PeerIdentity id; | ||
986 | struct GNUNET_PeerIdentity hop; | ||
987 | int me; | ||
988 | unsigned int i; | ||
989 | unsigned int j; | ||
990 | |||
991 | n = t->paths->root; | ||
992 | if (n->peer->id != p->peers[0]) | ||
993 | { | ||
994 | GNUNET_break (0); | ||
995 | return GNUNET_SYSERR; | ||
996 | } | ||
997 | /* Assuming that the tree is somewhat balanced, O((log n * log N). | ||
998 | * - Length of the path is expected to be log N (size of whole network). | ||
999 | * - Each level of the tree is expected to have log n children (size of tree). | ||
1000 | */ | ||
1001 | for (i = 1, me = -1; i < p->length; i++) | ||
1002 | { | ||
1003 | parent = n; | ||
1004 | if (p->peers[i] == myid) | ||
1005 | me = i; | ||
1006 | for (j = 0; j < n->nchildren; j++) | ||
1007 | { | ||
1008 | if (n->children[j].peer->id == p->peers[i]) | ||
1009 | { | ||
1010 | n = &n->children[j]; | ||
1011 | break; | ||
1012 | } | ||
1013 | } | ||
1014 | /* If we couldn't find a child equal to path[i], we have reached the end | ||
1015 | * of the common path. */ | ||
1016 | if (parent == n) | ||
1017 | break; | ||
1018 | } | ||
1019 | if (-1 == me) | ||
1020 | { | ||
1021 | GNUNET_break (0); | ||
1022 | return GNUNET_SYSERR; | ||
1023 | } | ||
1024 | /* Add the rest of the path as a branch from parent. */ | ||
1025 | while (i < p->length) | ||
1026 | { | ||
1027 | parent->children = GNUNET_realloc(parent->children, parent->nchildren); | ||
1028 | parent->nchildren++; | ||
1029 | GNUNET_PEER_resolve(p->peers[i], &id); | ||
1030 | n->peer = peer_info_get(&id); | ||
1031 | n->parent = parent; | ||
1032 | n->t = t; | ||
1033 | i++; | ||
1034 | } | ||
1035 | /* Add info about first hop into hashmap. */ | ||
1036 | if (me < p->length - 1) | ||
1037 | { | ||
1038 | GNUNET_PEER_resolve(p->peers[p->length - 1], &id); | ||
1039 | GNUNET_PEER_resolve(p->peers[me + 1], &hop); | ||
1040 | GNUNET_CONTAINER_multihashmap_put( | ||
1041 | t->paths->first_hops, | ||
1042 | &id.hashPubKey, | ||
1043 | peer_info_get(&hop), | ||
1044 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
1045 | } | ||
1046 | return GNUNET_OK; | ||
1047 | } | ||
1048 | |||
1049 | |||
1050 | /** | ||
1051 | * Build a PeerPath from the paths returned from the DHT, reversing the paths | ||
1052 | * to obtain a local peer -> destination path and interning the peer ids. | ||
1053 | * | ||
1054 | * @param get_path NULL-terminated array of pointers | ||
1055 | * to the peers on reverse GET path (or NULL if not recorded) | ||
1056 | * @param put_path NULL-terminated array of pointers | ||
1057 | * to the peers on the PUT path (or NULL if not recorded) | ||
1058 | * | ||
1059 | * @return Newly allocated and created path | ||
1060 | */ | ||
1061 | static struct MeshPeerPath * | ||
1062 | path_build_from_dht(const struct GNUNET_PeerIdentity *const *get_path, | ||
1063 | const struct GNUNET_PeerIdentity *const *put_path) | ||
1064 | { | ||
1065 | struct MeshPeerPath *p; | ||
1066 | int i; | ||
1067 | |||
1068 | p = GNUNET_malloc (sizeof (struct MeshPeerPath)); | ||
1069 | for (i = 0; get_path[i] != NULL; i++) ; | ||
1070 | for (i--; i >= 0; i--) | ||
1071 | { | ||
1072 | p->peers = | ||
1073 | GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1)); | ||
1074 | p->peers[p->length] = GNUNET_PEER_intern (get_path[i]); | ||
1075 | p->length++; | ||
1076 | } | ||
1077 | for (i = 0; put_path[i] != NULL; i++) ; | ||
1078 | for (i--; i >= 0; i--) | ||
1079 | { | ||
1080 | p->peers = | ||
1081 | GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1)); | ||
1082 | p->peers[p->length] = GNUNET_PEER_intern (put_path[i]); | ||
1083 | p->length++; | ||
1084 | } | ||
1085 | return p; | ||
629 | } | 1086 | } |
630 | 1087 | ||
631 | 1088 | ||
632 | /** | 1089 | /** |
633 | * Check if client has registered with the service and has not disconnected | 1090 | * Check if client has registered with the service and has not disconnected |
1091 | * | ||
634 | * @param client the client to check | 1092 | * @param client the client to check |
1093 | * | ||
635 | * @return non-NULL if client exists in the global DLL | 1094 | * @return non-NULL if client exists in the global DLL |
636 | */ | 1095 | */ |
637 | static struct MeshClient * | 1096 | static struct MeshClient * |
638 | retrieve_client (struct GNUNET_SERVER_Client *client) | 1097 | client_get (struct GNUNET_SERVER_Client *client) |
639 | { | 1098 | { |
640 | struct MeshClient *c; | 1099 | struct MeshClient *c; |
641 | 1100 | ||
@@ -652,12 +1111,16 @@ retrieve_client (struct GNUNET_SERVER_Client *client) | |||
652 | 1111 | ||
653 | /** | 1112 | /** |
654 | * Checks if a given client has subscribed to certain message type | 1113 | * Checks if a given client has subscribed to certain message type |
1114 | * | ||
655 | * @param message_type Type of message to check | 1115 | * @param message_type Type of message to check |
656 | * @param c Client to check | 1116 | * @param c Client to check |
1117 | * | ||
657 | * @return GNUNET_YES or GNUNET_NO, depending on subscription status | 1118 | * @return GNUNET_YES or GNUNET_NO, depending on subscription status |
1119 | * | ||
1120 | * TODO inline? | ||
658 | */ | 1121 | */ |
659 | static int /* FIXME inline? */ | 1122 | static int |
660 | is_client_subscribed (uint16_t message_type, struct MeshClient *c) | 1123 | client_is_subscribed (uint16_t message_type, struct MeshClient *c) |
661 | { | 1124 | { |
662 | GNUNET_HashCode hc; | 1125 | GNUNET_HashCode hc; |
663 | 1126 | ||
@@ -668,12 +1131,14 @@ is_client_subscribed (uint16_t message_type, struct MeshClient *c) | |||
668 | 1131 | ||
669 | /** | 1132 | /** |
670 | * Search for a tunnel among the tunnels for a client | 1133 | * Search for a tunnel among the tunnels for a client |
1134 | * | ||
671 | * @param c the client whose tunnels to search in | 1135 | * @param c the client whose tunnels to search in |
672 | * @param tid the local id of the tunnel | 1136 | * @param tid the local id of the tunnel |
1137 | * | ||
673 | * @return tunnel handler, NULL if doesn't exist | 1138 | * @return tunnel handler, NULL if doesn't exist |
674 | */ | 1139 | */ |
675 | static struct MeshTunnel * | 1140 | static struct MeshTunnel * |
676 | retrieve_tunnel_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid) | 1141 | tunnel_get_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid) |
677 | { | 1142 | { |
678 | GNUNET_HashCode hash; | 1143 | GNUNET_HashCode hash; |
679 | 1144 | ||
@@ -681,14 +1146,17 @@ retrieve_tunnel_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid) | |||
681 | return GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); | 1146 | return GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); |
682 | } | 1147 | } |
683 | 1148 | ||
1149 | |||
684 | /** | 1150 | /** |
685 | * Search for a tunnel by global ID using PEER_ID | 1151 | * Search for a tunnel by global ID using PEER_ID |
1152 | * | ||
686 | * @param pi owner of the tunnel | 1153 | * @param pi owner of the tunnel |
687 | * @param tid global tunnel number | 1154 | * @param tid global tunnel number |
1155 | * | ||
688 | * @return tunnel handler, NULL if doesn't exist | 1156 | * @return tunnel handler, NULL if doesn't exist |
689 | */ | 1157 | */ |
690 | static struct MeshTunnel * | 1158 | static struct MeshTunnel * |
691 | retrieve_tunnel_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid) | 1159 | tunnel_get_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid) |
692 | { | 1160 | { |
693 | struct MESH_TunnelID id; | 1161 | struct MESH_TunnelID id; |
694 | GNUNET_HashCode hash; | 1162 | GNUNET_HashCode hash; |
@@ -704,63 +1172,84 @@ retrieve_tunnel_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid) | |||
704 | 1172 | ||
705 | /** | 1173 | /** |
706 | * Search for a tunnel by global ID using full PeerIdentities | 1174 | * Search for a tunnel by global ID using full PeerIdentities |
1175 | * | ||
707 | * @param oid owner of the tunnel | 1176 | * @param oid owner of the tunnel |
708 | * @param tid global tunnel number | 1177 | * @param tid global tunnel number |
1178 | * | ||
709 | * @return tunnel handler, NULL if doesn't exist | 1179 | * @return tunnel handler, NULL if doesn't exist |
710 | */ | 1180 | */ |
711 | static struct MeshTunnel * | 1181 | static struct MeshTunnel * |
712 | retrieve_tunnel (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid) | 1182 | tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid) |
713 | { | 1183 | { |
714 | return retrieve_tunnel_by_pi (GNUNET_PEER_search (oid), tid); | 1184 | return tunnel_get_by_pi (GNUNET_PEER_search (oid), tid); |
715 | } | 1185 | } |
716 | 1186 | ||
717 | 1187 | ||
718 | /** | 1188 | /** |
719 | * Destroy the path and free any allocated resources linked to it | 1189 | * Add a peer to a tunnel, accomodating paths accordingly and initializing all |
720 | * @param p the path to destroy | 1190 | * needed rescources. |
721 | * @return GNUNET_OK on success | 1191 | * |
1192 | * @param t Tunnel we want to add a new peer to | ||
1193 | * @param peer PeerInfo of the peer being added | ||
1194 | * | ||
722 | */ | 1195 | */ |
723 | static int | 1196 | static void |
724 | destroy_path (struct MeshPath *p) | 1197 | tunnel_add_peer(struct MeshTunnel *t, struct MeshPeerInfo *peer) |
725 | { | 1198 | { |
726 | GNUNET_PEER_decrement_rcs (p->peers, p->length); | 1199 | struct MeshPeerPath *p; |
727 | GNUNET_free (p->peers); | 1200 | struct MeshPeerPath *best_p; |
728 | GNUNET_free (p); | 1201 | unsigned int best_cost; |
729 | return GNUNET_OK; | 1202 | unsigned int cost; |
1203 | |||
1204 | GNUNET_array_append(peer->tunnels, peer->ntunnels, t); | ||
1205 | if (NULL == (p = peer->path_head)) | ||
1206 | return; | ||
1207 | |||
1208 | best_p = p; | ||
1209 | best_cost = UINT_MAX; | ||
1210 | while (NULL != p) | ||
1211 | { | ||
1212 | if ((cost = path_get_cost(t, p)) < best_cost) | ||
1213 | { | ||
1214 | best_cost = cost; | ||
1215 | best_p = p; | ||
1216 | } | ||
1217 | p = p->next; | ||
1218 | } | ||
1219 | path_add_to_tunnel(t, best_p); | ||
1220 | if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task) | ||
1221 | t->path_refresh_task = GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, | ||
1222 | &path_refresh, t); | ||
730 | } | 1223 | } |
731 | 1224 | ||
732 | #if LATER | 1225 | |
733 | /** | 1226 | /** |
734 | * Destroy the peer_info and free any allocated resources linked to it | 1227 | * Notify a tunnel that a connection has broken that affects at least |
735 | * @param t tunnel the path belongs to | 1228 | * some of its peers. |
736 | * @param pi the peer_info to destroy | 1229 | * |
737 | * @return GNUNET_OK on success | 1230 | * @param t Tunnel affected |
1231 | * @param peer Peer that (at least) has been affected by the disconnection | ||
1232 | * @param p1 Peer that got disconnected from p2 | ||
1233 | * @param p2 Peer that got disconnected from p1 | ||
738 | */ | 1234 | */ |
739 | static int | 1235 | static void |
740 | destroy_peer_info (struct MeshPeerInfo *pi) | 1236 | tunnel_notify_connection_broken(struct MeshTunnel *t, |
1237 | struct MeshPeerInfo *peer, | ||
1238 | GNUNET_PEER_Id p1, | ||
1239 | GNUNET_PEER_Id p2) | ||
741 | { | 1240 | { |
742 | GNUNET_HashCode hash; | ||
743 | struct GNUNET_PeerIdentity id; | ||
744 | |||
745 | GNUNET_PEER_resolve (pi->id, &id); | ||
746 | GNUNET_PEER_change_rc (pi->id, -1); | ||
747 | GNUNET_CRYPTO_hash (&id, sizeof (struct GNUNET_PeerIdentity), &hash); | ||
748 | |||
749 | GNUNET_CONTAINER_multihashmap_remove (peers, &hash, pi); | ||
750 | GNUNET_SCHEDULER_cancel (pi->path_refresh_task); | ||
751 | GNUNET_free (pi); | ||
752 | return GNUNET_OK; | ||
753 | } | 1241 | } |
754 | #endif | ||
755 | 1242 | ||
756 | 1243 | ||
757 | /** | 1244 | /** |
758 | * Destroy the tunnel and free any allocated resources linked to it | 1245 | * Destroy the tunnel and free any allocated resources linked to it |
1246 | * | ||
759 | * @param t the tunnel to destroy | 1247 | * @param t the tunnel to destroy |
1248 | * | ||
760 | * @return GNUNET_OK on success | 1249 | * @return GNUNET_OK on success |
761 | */ | 1250 | */ |
762 | static int | 1251 | static int |
763 | destroy_tunnel (struct MeshTunnel *t) | 1252 | tunnel_destroy (struct MeshTunnel *t) |
764 | { | 1253 | { |
765 | struct MeshClient *c; | 1254 | struct MeshClient *c; |
766 | struct MeshQueue *q; | 1255 | struct MeshQueue *q; |
@@ -799,106 +1288,12 @@ destroy_tunnel (struct MeshTunnel *t) | |||
799 | return r; | 1288 | return r; |
800 | } | 1289 | } |
801 | 1290 | ||
802 | /******************************************************************************/ | ||
803 | /************************ PERIODIC FUNCTIONS ****************************/ | ||
804 | /******************************************************************************/ | ||
805 | |||
806 | /** | ||
807 | * Announce iterator over for each application provided by the peer | ||
808 | * | ||
809 | * @param cls closure | ||
810 | * @param key current key code | ||
811 | * @param value value in the hash map | ||
812 | * @return GNUNET_YES if we should continue to | ||
813 | * iterate, | ||
814 | * GNUNET_NO if not. | ||
815 | */ | ||
816 | static int | ||
817 | announce_application (void *cls, const GNUNET_HashCode * key, void *value) | ||
818 | { | ||
819 | /* FIXME are hashes in multihash map equal on all aquitectures? */ | ||
820 | GNUNET_DHT_put (dht_handle, key, 10U, GNUNET_DHT_RO_RECORD_ROUTE, | ||
821 | GNUNET_BLOCK_TYPE_TEST, sizeof (struct GNUNET_PeerIdentity), | ||
822 | (const char *) &my_full_id, | ||
823 | // GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), | ||
824 | // APP_ANNOUNCE_TIME), FIXME | ||
825 | // APP_ANNOUNCE_TIME, | ||
826 | GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_FOREVER_REL, | ||
827 | #if MESH_DEBUG | ||
828 | &mesh_debug, "DHT_put for app completed"); | ||
829 | #else | ||
830 | NULL, NULL); | ||
831 | #endif | ||
832 | return GNUNET_OK; | ||
833 | } | ||
834 | |||
835 | |||
836 | /** | ||
837 | * Periodically announce what applications are provided by local clients | ||
838 | * | ||
839 | * @param cls closure | ||
840 | * @param tc task context | ||
841 | */ | ||
842 | static void | ||
843 | announce_applications (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
844 | { | ||
845 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
846 | { | ||
847 | announce_applications_task = GNUNET_SCHEDULER_NO_TASK; | ||
848 | return; | ||
849 | } | ||
850 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Starting PUT for apps\n"); | ||
851 | GNUNET_CONTAINER_multihashmap_iterate (applications, &announce_application, | ||
852 | NULL); | ||
853 | announce_applications_task = | ||
854 | GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME, &announce_applications, | ||
855 | cls); | ||
856 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Finished PUT for apps\n"); | ||
857 | return; | ||
858 | } | ||
859 | |||
860 | |||
861 | /** | ||
862 | * Periodically announce self id in the DHT | ||
863 | * | ||
864 | * @param cls closure | ||
865 | * @param tc task context | ||
866 | */ | ||
867 | static void | ||
868 | announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
869 | { | ||
870 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
871 | { | ||
872 | announce_id_task = GNUNET_SCHEDULER_NO_TASK; | ||
873 | return; | ||
874 | } | ||
875 | /* TODO | ||
876 | * - Set data expiration in function of X | ||
877 | * - Adapt X to churn | ||
878 | */ | ||
879 | GNUNET_DHT_put (dht_handle, /* DHT handle */ | ||
880 | &my_full_id.hashPubKey, /* Key to use */ | ||
881 | 10U, /* Replication level */ | ||
882 | GNUNET_DHT_RO_RECORD_ROUTE, /* DHT options */ | ||
883 | GNUNET_BLOCK_TYPE_TEST, /* Block type */ | ||
884 | 0, /* Size of the data */ | ||
885 | NULL, /* Data itself */ | ||
886 | GNUNET_TIME_absolute_get_forever (), /* Data expiration */ | ||
887 | GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */ | ||
888 | #if MESH_DEBUG | ||
889 | &mesh_debug, "DHT_put for id completed"); | ||
890 | #else | ||
891 | NULL, /* Continuation */ | ||
892 | NULL); /* Continuation closure */ | ||
893 | #endif | ||
894 | announce_id_task = | ||
895 | GNUNET_SCHEDULER_add_delayed (ID_ANNOUNCE_TIME, &announce_id, cls); | ||
896 | } | ||
897 | 1291 | ||
898 | /******************************************************************************/ | 1292 | /******************************************************************************/ |
899 | /**************** MESH NETWORK HANDLER HELPERS ***********************/ | 1293 | /**************** MESH NETWORK HANDLER HELPERS ***********************/ |
900 | /******************************************************************************/ | 1294 | /******************************************************************************/ |
901 | 1295 | ||
1296 | |||
902 | /** | 1297 | /** |
903 | * Function called to notify a client about the socket | 1298 | * Function called to notify a client about the socket |
904 | * being ready to queue more data. "buf" will be | 1299 | * being ready to queue more data. "buf" will be |
@@ -911,64 +1306,37 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
911 | * @return number of bytes written to buf | 1306 | * @return number of bytes written to buf |
912 | */ | 1307 | */ |
913 | static size_t | 1308 | static size_t |
914 | send_core_create_path_for_peer (void *cls, size_t size, void *buf) | 1309 | send_core_create_path (void *cls, size_t size, void *buf) |
915 | { | 1310 | { |
916 | struct MeshPeerInfo *peer_info = cls; | 1311 | struct MeshPathInfo *info = cls; |
917 | struct GNUNET_MESH_ManipulatePath *msg; | 1312 | struct GNUNET_MESH_ManipulatePath *msg; |
918 | struct MeshPath *p; | ||
919 | struct GNUNET_PeerIdentity *peer_ptr; | 1313 | struct GNUNET_PeerIdentity *peer_ptr; |
920 | struct GNUNET_PeerIdentity id; | 1314 | struct GNUNET_PeerIdentity id; |
1315 | struct MeshPeerInfo *peer = info->peer; | ||
1316 | struct MeshTunnel *t = info->t; | ||
1317 | struct MeshPeerPath *p = info->path; | ||
921 | size_t size_needed; | 1318 | size_t size_needed; |
922 | int i; | 1319 | int i; |
923 | 1320 | ||
924 | if (0 == size && NULL == buf) | ||
925 | { | ||
926 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Retransmitting create path\n"); | ||
927 | GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id); | ||
928 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | ||
929 | GNUNET_TIME_UNIT_FOREVER_REL, &id, | ||
930 | sizeof (struct | ||
931 | GNUNET_MESH_ManipulatePath) + | ||
932 | (peer_info->path->length * | ||
933 | sizeof (struct GNUNET_PeerIdentity)), | ||
934 | &send_core_create_path_for_peer, | ||
935 | peer_info); | ||
936 | return 0; | ||
937 | } | ||
938 | p = peer_info->path; | ||
939 | while (NULL != p) | ||
940 | { | ||
941 | if (p->in_use) | ||
942 | { | ||
943 | break; | ||
944 | } | ||
945 | p = p->next; | ||
946 | } | ||
947 | if (p == NULL) | ||
948 | return 0; // TODO Notify ERROR Path not found | ||
949 | |||
950 | size_needed = | 1321 | size_needed = |
951 | sizeof (struct GNUNET_MESH_ManipulatePath) + | 1322 | sizeof (struct GNUNET_MESH_ManipulatePath) + |
952 | p->length * sizeof (struct GNUNET_PeerIdentity); | 1323 | p->length * sizeof (struct GNUNET_PeerIdentity); |
953 | if (size < size_needed) | 1324 | |
1325 | if (size < size_needed || NULL == buf) | ||
954 | { | 1326 | { |
955 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Retransmitting create path\n"); | 1327 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Retransmitting create path\n"); |
956 | GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id); | 1328 | GNUNET_PEER_resolve (path_get_first_hop (t, peer)->id, &id); |
957 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | 1329 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, |
958 | GNUNET_TIME_UNIT_FOREVER_REL, &id, | 1330 | GNUNET_TIME_UNIT_FOREVER_REL, &id, |
959 | sizeof (struct | 1331 | size_needed, &send_core_create_path, |
960 | GNUNET_MESH_ManipulatePath) + | 1332 | info); |
961 | (peer_info->path->length * | ||
962 | sizeof (struct GNUNET_PeerIdentity)), | ||
963 | &send_core_create_path_for_peer, | ||
964 | peer_info); | ||
965 | return 0; | 1333 | return 0; |
966 | } | 1334 | } |
967 | 1335 | ||
968 | msg = (struct GNUNET_MESH_ManipulatePath *) buf; | 1336 | msg = (struct GNUNET_MESH_ManipulatePath *) buf; |
969 | msg->header.size = htons (size_needed); | 1337 | msg->header.size = htons (size_needed); |
970 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE); | 1338 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE); |
971 | msg->tid = 0; /* FIXME */ | 1339 | msg->tid = ntohl(t->id.tid); |
972 | 1340 | ||
973 | peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1]; | 1341 | peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1]; |
974 | for (i = 0; i < p->length; i++) | 1342 | for (i = 0; i < p->length; i++) |
@@ -976,7 +1344,8 @@ send_core_create_path_for_peer (void *cls, size_t size, void *buf) | |||
976 | GNUNET_PEER_resolve (p->peers[i], peer_ptr++); | 1344 | GNUNET_PEER_resolve (p->peers[i], peer_ptr++); |
977 | } | 1345 | } |
978 | 1346 | ||
979 | peer_info->state = MESH_PEER_WAITING; | 1347 | path_destroy(p); |
1348 | GNUNET_free (info); | ||
980 | 1349 | ||
981 | return size_needed; | 1350 | return size_needed; |
982 | } | 1351 | } |
@@ -1215,7 +1584,7 @@ send_p2p_tunnel_destroy (void *cls, size_t size, void *buf) | |||
1215 | htons (sizeof (struct GNUNET_MESH_TunnelMessage)); | 1584 | htons (sizeof (struct GNUNET_MESH_TunnelMessage)); |
1216 | msg->tunnel_id = htonl (t->id.tid); | 1585 | msg->tunnel_id = htonl (t->id.tid); |
1217 | 1586 | ||
1218 | destroy_tunnel (c, t); | 1587 | tunnel_destroy (c, t); |
1219 | return sizeof (struct GNUNET_MESH_TunnelMessage); | 1588 | return sizeof (struct GNUNET_MESH_TunnelMessage); |
1220 | } | 1589 | } |
1221 | #endif | 1590 | #endif |
@@ -1237,7 +1606,7 @@ send_subscribed_clients (struct GNUNET_MessageHeader *msg) | |||
1237 | type = ntohs (msg->type); | 1606 | type = ntohs (msg->type); |
1238 | for (count = 0, c = clients; c != NULL; c = c->next) | 1607 | for (count = 0, c = clients; c != NULL; c = c->next) |
1239 | { | 1608 | { |
1240 | if (is_client_subscribed (type, c)) | 1609 | if (client_is_subscribed (type, c)) |
1241 | { | 1610 | { |
1242 | count++; | 1611 | count++; |
1243 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, msg, | 1612 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, msg, |
@@ -1261,23 +1630,22 @@ static int | |||
1261 | iterate_collect_neighbors (void *cls, const GNUNET_HashCode * key, void *value) | 1630 | iterate_collect_neighbors (void *cls, const GNUNET_HashCode * key, void *value) |
1262 | { | 1631 | { |
1263 | struct MeshPeerInfo *peer_info = value; | 1632 | struct MeshPeerInfo *peer_info = value; |
1264 | GNUNET_PEER_Id **neighbors = cls; | 1633 | struct MeshPathInfo *neighbors = cls; |
1265 | GNUNET_PEER_Id id; | ||
1266 | unsigned int i; | 1634 | unsigned int i; |
1267 | 1635 | ||
1268 | if (peer_info->id == myid) | 1636 | if (peer_info->id == myid) |
1269 | { | 1637 | { |
1270 | return GNUNET_YES; | 1638 | return GNUNET_YES; |
1271 | } | 1639 | } |
1272 | id = get_first_hop (peer_info->path); | 1640 | peer_info = path_get_first_hop (neighbors->t, peer_info); |
1273 | for (i = 0; *neighbors[i] != 0; i++) | 1641 | for (i = 0; i < neighbors->path->length; i++) |
1274 | { | 1642 | { |
1275 | if (*neighbors[i] == id) | 1643 | if (neighbors->path->peers[i] == peer_info->id) |
1276 | return GNUNET_YES; | 1644 | return GNUNET_YES; |
1277 | } | 1645 | } |
1278 | *neighbors = GNUNET_realloc (*neighbors, (i + 2) * sizeof (GNUNET_PEER_Id)); | 1646 | GNUNET_array_append(neighbors->path->peers, |
1279 | *neighbors[i] = id; | 1647 | neighbors->path->length, |
1280 | *neighbors[i + 1] = 0; | 1648 | peer_info->id); |
1281 | 1649 | ||
1282 | return GNUNET_YES; | 1650 | return GNUNET_YES; |
1283 | } | 1651 | } |
@@ -1313,7 +1681,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1313 | struct GNUNET_PeerIdentity *pi; | 1681 | struct GNUNET_PeerIdentity *pi; |
1314 | struct GNUNET_PeerIdentity id; | 1682 | struct GNUNET_PeerIdentity id; |
1315 | GNUNET_HashCode hash; | 1683 | GNUNET_HashCode hash; |
1316 | struct MeshPath *path; | 1684 | struct MeshPeerPath *path; |
1317 | struct MeshPeerInfo *dest_peer_info; | 1685 | struct MeshPeerInfo *dest_peer_info; |
1318 | struct MeshPeerInfo *orig_peer_info; | 1686 | struct MeshPeerInfo *orig_peer_info; |
1319 | struct MeshTunnel *t; | 1687 | struct MeshTunnel *t; |
@@ -1323,30 +1691,27 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1323 | size = ntohs (message->size); | 1691 | size = ntohs (message->size); |
1324 | if (size < sizeof (struct GNUNET_MESH_ManipulatePath)) | 1692 | if (size < sizeof (struct GNUNET_MESH_ManipulatePath)) |
1325 | { | 1693 | { |
1326 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1694 | GNUNET_break_op (0); |
1327 | "received create path message too short\n"); | ||
1328 | return GNUNET_OK; | 1695 | return GNUNET_OK; |
1329 | } | 1696 | } |
1330 | 1697 | ||
1331 | size -= sizeof (struct GNUNET_MESH_ManipulatePath); | 1698 | size -= sizeof (struct GNUNET_MESH_ManipulatePath); |
1332 | if (size < 2 * sizeof (struct GNUNET_PeerIdentity)) | 1699 | if (size % sizeof (struct GNUNET_PeerIdentity)) |
1333 | { | 1700 | { |
1334 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1701 | GNUNET_break_op (0); |
1335 | "create path message lacks enough peers\n"); | ||
1336 | return GNUNET_OK; | 1702 | return GNUNET_OK; |
1337 | } | 1703 | } |
1338 | if (size % sizeof (struct GNUNET_PeerIdentity)) | 1704 | size /= sizeof (struct GNUNET_PeerIdentity); |
1705 | if (size < 2) | ||
1339 | { | 1706 | { |
1340 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1707 | GNUNET_break_op (0); |
1341 | "create path message of wrong size\n"); | ||
1342 | return GNUNET_OK; | 1708 | return GNUNET_OK; |
1343 | } | 1709 | } |
1344 | msg = (struct GNUNET_MESH_ManipulatePath *) message; | 1710 | msg = (struct GNUNET_MESH_ManipulatePath *) message; |
1345 | size /= sizeof (struct GNUNET_PeerIdentity); | ||
1346 | 1711 | ||
1347 | tid = ntohl (msg->tid); | 1712 | tid = ntohl (msg->tid); |
1348 | pi = (struct GNUNET_PeerIdentity *) &msg[1]; | 1713 | pi = (struct GNUNET_PeerIdentity *) &msg[1]; |
1349 | t = retrieve_tunnel (pi, tid); | 1714 | t = tunnel_get (pi, tid); |
1350 | 1715 | ||
1351 | if (NULL == t) | 1716 | if (NULL == t) |
1352 | { | 1717 | { |
@@ -1358,8 +1723,9 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1358 | 1723 | ||
1359 | GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash); | 1724 | GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash); |
1360 | if (GNUNET_OK != | 1725 | if (GNUNET_OK != |
1361 | GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t, | 1726 | GNUNET_CONTAINER_multihashmap_put ( |
1362 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | 1727 | tunnels, &hash, t, |
1728 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
1363 | { | 1729 | { |
1364 | GNUNET_break (0); | 1730 | GNUNET_break (0); |
1365 | return GNUNET_OK; | 1731 | return GNUNET_OK; |
@@ -1372,23 +1738,25 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1372 | { | 1738 | { |
1373 | dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo)); | 1739 | dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo)); |
1374 | dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]); | 1740 | dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]); |
1375 | dest_peer_info->state = MESH_PEER_WAITING; | 1741 | GNUNET_CONTAINER_multihashmap_put ( |
1376 | GNUNET_CONTAINER_multihashmap_put (peers, &pi[size - 1].hashPubKey, | 1742 | peers, |
1377 | dest_peer_info, | 1743 | &pi[size - 1].hashPubKey, |
1378 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1744 | dest_peer_info, |
1745 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1379 | } | 1746 | } |
1380 | orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey); | 1747 | orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey); |
1381 | if (NULL == orig_peer_info) | 1748 | if (NULL == orig_peer_info) |
1382 | { | 1749 | { |
1383 | orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo)); | 1750 | orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo)); |
1384 | orig_peer_info->id = GNUNET_PEER_intern (pi); | 1751 | orig_peer_info->id = GNUNET_PEER_intern (pi); |
1385 | orig_peer_info->state = MESH_PEER_WAITING; | 1752 | GNUNET_CONTAINER_multihashmap_put ( |
1386 | GNUNET_CONTAINER_multihashmap_put (peers, &pi->hashPubKey, orig_peer_info, | 1753 | peers, |
1387 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1754 | &pi->hashPubKey, |
1755 | orig_peer_info, | ||
1756 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1388 | } | 1757 | } |
1389 | 1758 | ||
1390 | 1759 | path = GNUNET_malloc (sizeof (struct MeshPeerPath)); | |
1391 | path = GNUNET_malloc (sizeof (struct MeshPath)); | ||
1392 | path->length = size; | 1760 | path->length = size; |
1393 | path->peers = GNUNET_malloc (size * sizeof (GNUNET_PEER_Id)); | 1761 | path->peers = GNUNET_malloc (size * sizeof (GNUNET_PEER_Id)); |
1394 | own_pos = 0; | 1762 | own_pos = 0; |
@@ -1402,17 +1770,17 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1402 | { /* cannot be self, must be 'not found' */ | 1770 | { /* cannot be self, must be 'not found' */ |
1403 | /* create path: self not found in path through self */ | 1771 | /* create path: self not found in path through self */ |
1404 | GNUNET_break_op (0); | 1772 | GNUNET_break_op (0); |
1405 | destroy_path (path); | 1773 | path_destroy (path); |
1406 | /* FIXME error. destroy tunnel? leave for timeout? */ | 1774 | /* FIXME error. destroy tunnel? leave for timeout? */ |
1407 | return 0; | 1775 | return 0; |
1408 | } | 1776 | } |
1409 | if (own_pos == size - 1) | 1777 | if (own_pos == size - 1) |
1410 | { /* it is for us! */ | 1778 | { |
1779 | /* It is for us! Send ack. */ | ||
1411 | struct MeshDataDescriptor *info; | 1780 | struct MeshDataDescriptor *info; |
1412 | unsigned int j; | 1781 | unsigned int j; |
1413 | 1782 | ||
1414 | add_path_to_origin (orig_peer_info, path); /* inverts path! */ | 1783 | path_add_to_origin (orig_peer_info, path); /* inverts path! */ |
1415 | GNUNET_PEER_resolve (get_first_hop (path), &id); /* path is inverted :) */ | ||
1416 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor)); | 1784 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor)); |
1417 | info->origin = &t->id; | 1785 | info->origin = &t->id; |
1418 | info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey); | 1786 | info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey); |
@@ -1428,19 +1796,27 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1428 | info->handler_n = j; | 1796 | info->handler_n = j; |
1429 | info->peer->core_transmit[j] = | 1797 | info->peer->core_transmit[j] = |
1430 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 100, | 1798 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 100, |
1431 | GNUNET_TIME_UNIT_FOREVER_REL, &id, | 1799 | GNUNET_TIME_UNIT_FOREVER_REL, peer, |
1432 | sizeof (struct GNUNET_MessageHeader), | 1800 | sizeof (struct GNUNET_MessageHeader), |
1433 | &send_core_path_ack, info); | 1801 | &send_core_path_ack, info); |
1434 | } | 1802 | } |
1435 | else | 1803 | else |
1436 | { | 1804 | { |
1437 | add_path_to_peer (dest_peer_info, path); | 1805 | /* It's for somebody else! Retransmit. */ |
1438 | GNUNET_PEER_resolve (get_first_hop (path), &id); | 1806 | struct MeshPathInfo *path_info; |
1807 | |||
1808 | path_info = GNUNET_malloc (sizeof(struct MeshPathInfo)); | ||
1809 | path_info->t = t; | ||
1810 | path_info->path = path; | ||
1811 | path_info->peer = dest_peer_info; | ||
1812 | |||
1813 | path_add_to_peer (dest_peer_info, path); | ||
1814 | GNUNET_PEER_resolve (path->peers[own_pos + 1], &id); | ||
1439 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | 1815 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, |
1440 | GNUNET_TIME_UNIT_FOREVER_REL, &id, | 1816 | GNUNET_TIME_UNIT_FOREVER_REL, &id, |
1441 | sizeof (struct GNUNET_MessageHeader), | 1817 | sizeof (struct GNUNET_MessageHeader), |
1442 | &send_core_create_path_for_peer, | 1818 | &send_core_create_path, |
1443 | dest_peer_info); | 1819 | path_info); |
1444 | } | 1820 | } |
1445 | return GNUNET_OK; | 1821 | return GNUNET_OK; |
1446 | } | 1822 | } |
@@ -1476,7 +1852,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1476 | return GNUNET_OK; | 1852 | return GNUNET_OK; |
1477 | } | 1853 | } |
1478 | msg = (struct GNUNET_MESH_Unicast *) message; | 1854 | msg = (struct GNUNET_MESH_Unicast *) message; |
1479 | t = retrieve_tunnel (&msg->oid, ntohl (msg->tid)); | 1855 | t = tunnel_get (&msg->oid, ntohl (msg->tid)); |
1480 | if (NULL == t) | 1856 | if (NULL == t) |
1481 | { | 1857 | { |
1482 | /* TODO notify back: we don't know this tunnel */ | 1858 | /* TODO notify back: we don't know this tunnel */ |
@@ -1494,7 +1870,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1494 | send_subscribed_clients ((struct GNUNET_MessageHeader *) &msg[1]); | 1870 | send_subscribed_clients ((struct GNUNET_MessageHeader *) &msg[1]); |
1495 | return GNUNET_OK; | 1871 | return GNUNET_OK; |
1496 | } | 1872 | } |
1497 | GNUNET_PEER_resolve (get_first_hop (pi->path), &id); | 1873 | GNUNET_PEER_resolve (path_get_first_hop (t, pi)->id, &id); |
1498 | msg = GNUNET_malloc (size); | 1874 | msg = GNUNET_malloc (size); |
1499 | memcpy (msg, message, size); | 1875 | memcpy (msg, message, size); |
1500 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | 1876 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, |
@@ -1521,9 +1897,9 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1521 | { | 1897 | { |
1522 | struct GNUNET_MESH_Multicast *msg; | 1898 | struct GNUNET_MESH_Multicast *msg; |
1523 | struct GNUNET_PeerIdentity id; | 1899 | struct GNUNET_PeerIdentity id; |
1524 | struct MeshTunnel *t; | ||
1525 | struct MeshDataDescriptor *info; | 1900 | struct MeshDataDescriptor *info; |
1526 | GNUNET_PEER_Id *neighbors; | 1901 | struct MeshPathInfo neighbors; |
1902 | struct MeshTunnel *t; | ||
1527 | size_t size; | 1903 | size_t size; |
1528 | uint16_t i; | 1904 | uint16_t i; |
1529 | uint16_t j; | 1905 | uint16_t j; |
@@ -1538,7 +1914,7 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1538 | return GNUNET_OK; | 1914 | return GNUNET_OK; |
1539 | } | 1915 | } |
1540 | msg = (struct GNUNET_MESH_Multicast *) message; | 1916 | msg = (struct GNUNET_MESH_Multicast *) message; |
1541 | t = retrieve_tunnel (&msg->oid, ntohl (msg->tid)); | 1917 | t = tunnel_get (&msg->oid, ntohl (msg->tid)); |
1542 | 1918 | ||
1543 | if (NULL == t) | 1919 | if (NULL == t) |
1544 | { | 1920 | { |
@@ -1552,29 +1928,30 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1552 | send_subscribed_clients ((struct GNUNET_MessageHeader *) &msg[1]); | 1928 | send_subscribed_clients ((struct GNUNET_MessageHeader *) &msg[1]); |
1553 | } | 1929 | } |
1554 | 1930 | ||
1555 | /* Retransmit to other peers */ | 1931 | /* Retransmit to other peers. |
1556 | neighbors = GNUNET_malloc (sizeof (GNUNET_PEER_Id)); | 1932 | * Using path here as just a collection of peers, not a path per se. |
1557 | neighbors[0] = 0; | 1933 | */ |
1934 | neighbors.t = t; | ||
1935 | neighbors.path = GNUNET_malloc (sizeof(struct MeshPeerPath)); | ||
1558 | GNUNET_CONTAINER_multihashmap_iterate (t->peers, &iterate_collect_neighbors, | 1936 | GNUNET_CONTAINER_multihashmap_iterate (t->peers, &iterate_collect_neighbors, |
1559 | &neighbors); | 1937 | &neighbors); |
1560 | if (!neighbors[0]) | 1938 | if (0 == neighbors.path->length) |
1561 | { | 1939 | { |
1940 | GNUNET_free(neighbors.path); | ||
1562 | return GNUNET_OK; | 1941 | return GNUNET_OK; |
1563 | } | 1942 | } |
1564 | size -= sizeof (struct GNUNET_MESH_Multicast); | 1943 | size -= sizeof (struct GNUNET_MESH_Multicast); |
1565 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor) + size); | 1944 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor) + size); |
1566 | info->origin = &t->id; | 1945 | info->origin = &t->id; |
1567 | info->copies = 0; | 1946 | info->copies = neighbors.path->length; |
1568 | for (i = 0; 0 != neighbors[i]; i++) | 1947 | for (i = 0; i < info->copies; i++) |
1569 | { | 1948 | { |
1570 | GNUNET_PEER_resolve (neighbors[i], &id); | 1949 | GNUNET_PEER_resolve (neighbors.path->peers[i], &id); |
1571 | info->copies++; | ||
1572 | info->destination = neighbors[i]; | ||
1573 | info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey); | 1950 | info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey); |
1574 | GNUNET_assert (info->peer); | 1951 | GNUNET_assert (NULL != info->peer); |
1575 | for (j = 0; info->peer->core_transmit[j]; j++) | 1952 | for (j = 0; 0 != info->peer->core_transmit[j]; j++) |
1576 | { | 1953 | { |
1577 | if (j == 9) | 1954 | if (j == (CORE_QUEUE_SIZE - 1)) |
1578 | { | 1955 | { |
1579 | GNUNET_break (0); | 1956 | GNUNET_break (0); |
1580 | return GNUNET_OK; | 1957 | return GNUNET_OK; |
@@ -1588,6 +1965,8 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1588 | ntohs (msg->header.size), | 1965 | ntohs (msg->header.size), |
1589 | &send_core_data_multicast, info); | 1966 | &send_core_data_multicast, info); |
1590 | } | 1967 | } |
1968 | GNUNET_free(neighbors.path->peers); | ||
1969 | GNUNET_free(neighbors.path); | ||
1591 | return GNUNET_OK; | 1970 | return GNUNET_OK; |
1592 | } | 1971 | } |
1593 | 1972 | ||
@@ -1601,12 +1980,14 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1601 | * @param atsi performance data | 1980 | * @param atsi performance data |
1602 | * @return GNUNET_OK to keep the connection open, | 1981 | * @return GNUNET_OK to keep the connection open, |
1603 | * GNUNET_SYSERR to close it (signal serious error) | 1982 | * GNUNET_SYSERR to close it (signal serious error) |
1983 | * | ||
1984 | * FIXME path | ||
1604 | */ | 1985 | */ |
1605 | static int | 1986 | static int |
1606 | handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | 1987 | handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, |
1607 | const struct GNUNET_MessageHeader *message, | 1988 | const struct GNUNET_MessageHeader *message, |
1608 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) | 1989 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) |
1609 | { | 1990 | { |
1610 | struct GNUNET_MESH_ToOrigin *msg; | 1991 | struct GNUNET_MESH_ToOrigin *msg; |
1611 | struct GNUNET_PeerIdentity id; | 1992 | struct GNUNET_PeerIdentity id; |
1612 | struct MeshTunnel *t; | 1993 | struct MeshTunnel *t; |
@@ -1622,7 +2003,7 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1622 | return GNUNET_OK; | 2003 | return GNUNET_OK; |
1623 | } | 2004 | } |
1624 | msg = (struct GNUNET_MESH_ToOrigin *) message; | 2005 | msg = (struct GNUNET_MESH_ToOrigin *) message; |
1625 | t = retrieve_tunnel (&msg->oid, ntohl (msg->tid)); | 2006 | t = tunnel_get (&msg->oid, ntohl (msg->tid)); |
1626 | 2007 | ||
1627 | if (NULL == t) | 2008 | if (NULL == t) |
1628 | { | 2009 | { |
@@ -1642,14 +2023,14 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1642 | GNUNET_YES); | 2023 | GNUNET_YES); |
1643 | return GNUNET_OK; | 2024 | return GNUNET_OK; |
1644 | } | 2025 | } |
1645 | peer_info = get_peer_info (&msg->oid); | 2026 | peer_info = peer_info_get (&msg->oid); |
1646 | if (NULL == peer_info) | 2027 | if (NULL == peer_info) |
1647 | { | 2028 | { |
1648 | /* unknown origin of tunnel */ | 2029 | /* unknown origin of tunnel */ |
1649 | GNUNET_break (0); | 2030 | GNUNET_break (0); |
1650 | return GNUNET_OK; | 2031 | return GNUNET_OK; |
1651 | } | 2032 | } |
1652 | GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id); | 2033 | GNUNET_PEER_resolve (path_get_first_hop (t, peer_info)->id, &id); |
1653 | msg = GNUNET_malloc (size); | 2034 | msg = GNUNET_malloc (size); |
1654 | memcpy (msg, message, size); | 2035 | memcpy (msg, message, size); |
1655 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | 2036 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, |
@@ -1667,8 +2048,11 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1667 | * @param message message | 2048 | * @param message message |
1668 | * @param peer peer identity this notification is about | 2049 | * @param peer peer identity this notification is about |
1669 | * @param atsi performance data | 2050 | * @param atsi performance data |
2051 | * | ||
1670 | * @return GNUNET_OK to keep the connection open, | 2052 | * @return GNUNET_OK to keep the connection open, |
1671 | * GNUNET_SYSERR to close it (signal serious error) | 2053 | * GNUNET_SYSERR to close it (signal serious error) |
2054 | * | ||
2055 | * FIXME path change state | ||
1672 | */ | 2056 | */ |
1673 | static int | 2057 | static int |
1674 | handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | 2058 | handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, |
@@ -1681,7 +2065,7 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1681 | struct MeshPeerInfo *peer_info; | 2065 | struct MeshPeerInfo *peer_info; |
1682 | 2066 | ||
1683 | msg = (struct GNUNET_MESH_PathACK *) message; | 2067 | msg = (struct GNUNET_MESH_PathACK *) message; |
1684 | t = retrieve_tunnel (&msg->oid, msg->tid); | 2068 | t = tunnel_get (&msg->oid, msg->tid); |
1685 | if (NULL == t) | 2069 | if (NULL == t) |
1686 | { | 2070 | { |
1687 | /* TODO notify that we don't know the tunnel */ | 2071 | /* TODO notify that we don't know the tunnel */ |
@@ -1698,13 +2082,13 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1698 | GNUNET_break (0); | 2082 | GNUNET_break (0); |
1699 | return GNUNET_OK; | 2083 | return GNUNET_OK; |
1700 | } | 2084 | } |
1701 | peer_info = get_peer_info (&msg->peer_id); | 2085 | peer_info = peer_info_get (&msg->peer_id); |
1702 | if (NULL == peer_info) | 2086 | if (NULL == peer_info) |
1703 | { | 2087 | { |
1704 | GNUNET_break_op (0); | 2088 | GNUNET_break_op (0); |
1705 | return GNUNET_OK; | 2089 | return GNUNET_OK; |
1706 | } | 2090 | } |
1707 | peer_info->state = MESH_PEER_READY; | 2091 | /* FIXME change state of peer */ |
1708 | pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD); | 2092 | pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD); |
1709 | pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl)); | 2093 | pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl)); |
1710 | pc.tunnel_id = htonl (t->local_tid); | 2094 | pc.tunnel_id = htonl (t->local_tid); |
@@ -1714,14 +2098,14 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
1714 | return GNUNET_OK; | 2098 | return GNUNET_OK; |
1715 | } | 2099 | } |
1716 | 2100 | ||
1717 | peer_info = get_peer_info (&msg->oid); | 2101 | peer_info = peer_info_get (&msg->oid); |
1718 | if (NULL == peer_info) | 2102 | if (NULL == peer_info) |
1719 | { | 2103 | { |
1720 | /* If we know the tunnel, we should DEFINITELY know the peer */ | 2104 | /* If we know the tunnel, we should DEFINITELY know the peer */ |
1721 | GNUNET_break (0); | 2105 | GNUNET_break (0); |
1722 | return GNUNET_OK; | 2106 | return GNUNET_OK; |
1723 | } | 2107 | } |
1724 | GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id); | 2108 | GNUNET_PEER_resolve (path_get_first_hop (t, peer_info)->id, &id); |
1725 | msg = GNUNET_malloc (sizeof (struct GNUNET_MESH_PathACK)); | 2109 | msg = GNUNET_malloc (sizeof (struct GNUNET_MESH_PathACK)); |
1726 | memcpy (msg, message, sizeof (struct GNUNET_MESH_PathACK)); | 2110 | memcpy (msg, message, sizeof (struct GNUNET_MESH_PathACK)); |
1727 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | 2111 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, |
@@ -1764,7 +2148,7 @@ delete_tunnel_entry (void *cls, const GNUNET_HashCode * key, void *value) | |||
1764 | { | 2148 | { |
1765 | int r; | 2149 | int r; |
1766 | 2150 | ||
1767 | r = destroy_tunnel ((struct MeshTunnel *) value); | 2151 | r = tunnel_destroy ((struct MeshTunnel *) value); |
1768 | return r; | 2152 | return r; |
1769 | } | 2153 | } |
1770 | 2154 | ||
@@ -1824,36 +2208,6 @@ notify_client_connection_failure (void *cls, size_t size, void *buf) | |||
1824 | 2208 | ||
1825 | 2209 | ||
1826 | /** | 2210 | /** |
1827 | * Send keepalive packets for a peer | ||
1828 | * | ||
1829 | * @param cls unused | ||
1830 | * @param tc unused | ||
1831 | */ | ||
1832 | static void | ||
1833 | path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1834 | { | ||
1835 | struct MeshPeerInfo *peer_info = cls; | ||
1836 | struct GNUNET_PeerIdentity id; | ||
1837 | |||
1838 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
1839 | return; | ||
1840 | GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id); | ||
1841 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | ||
1842 | GNUNET_TIME_UNIT_FOREVER_REL, &id, | ||
1843 | sizeof (struct GNUNET_MESH_ManipulatePath) | ||
1844 | + | ||
1845 | (peer_info->path->length * | ||
1846 | sizeof (struct GNUNET_PeerIdentity)), | ||
1847 | &send_core_create_path_for_peer, | ||
1848 | peer_info); | ||
1849 | peer_info->path_refresh_task = | ||
1850 | GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh, | ||
1851 | peer_info); | ||
1852 | return; | ||
1853 | } | ||
1854 | |||
1855 | |||
1856 | /** | ||
1857 | * Function to process paths received for a new peer addition. The recorded | 2211 | * Function to process paths received for a new peer addition. The recorded |
1858 | * paths form the initial tunnel, which can be optimized later. | 2212 | * paths form the initial tunnel, which can be optimized later. |
1859 | * Called on each result obtained for the DHT search. | 2213 | * Called on each result obtained for the DHT search. |
@@ -1868,6 +2222,8 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1868 | * @param type type of the result | 2222 | * @param type type of the result |
1869 | * @param size number of bytes in data | 2223 | * @param size number of bytes in data |
1870 | * @param data pointer to the result data | 2224 | * @param data pointer to the result data |
2225 | * | ||
2226 | * FIXME path | ||
1871 | */ | 2227 | */ |
1872 | static void | 2228 | static void |
1873 | dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, | 2229 | dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, |
@@ -1876,60 +2232,42 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, | |||
1876 | const struct GNUNET_PeerIdentity *const *put_path, | 2232 | const struct GNUNET_PeerIdentity *const *put_path, |
1877 | enum GNUNET_BLOCK_Type type, size_t size, const void *data) | 2233 | enum GNUNET_BLOCK_Type type, size_t size, const void *data) |
1878 | { | 2234 | { |
1879 | struct MeshPeerInfo *peer_info = cls; | 2235 | struct MeshPathInfo *path_info = cls; |
1880 | struct MeshPath *p; | 2236 | struct MeshPeerPath *p; |
1881 | struct GNUNET_PeerIdentity pi; | 2237 | struct GNUNET_PeerIdentity pi; |
1882 | int i; | 2238 | int i; |
1883 | 2239 | ||
1884 | if ((NULL == get_path || NULL == put_path) && NULL == peer_info->path) | 2240 | if (NULL == get_path || NULL == put_path) |
1885 | { | 2241 | { |
1886 | // Find ourselves some alternate initial path to the destination: retry | 2242 | if (NULL == path_info->peer->path_head) |
1887 | GNUNET_DHT_get_stop (peer_info->dhtget); | 2243 | { |
1888 | GNUNET_PEER_resolve (peer_info->id, &pi); | 2244 | // Find ourselves some alternate initial path to the destination: retry |
1889 | peer_info->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */ | 2245 | GNUNET_DHT_get_stop (path_info->peer->dhtget); |
1890 | GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_BLOCK_TYPE_TEST, /* type */ | 2246 | GNUNET_PEER_resolve (path_info->peer->id, &pi); |
1891 | &pi.hashPubKey, /*key to search */ | 2247 | path_info->peer->dhtget = GNUNET_DHT_get_start ( |
1892 | 4, /* replication level */ | 2248 | dht_handle, /* handle */ |
1893 | GNUNET_DHT_RO_RECORD_ROUTE, NULL, /* bloom filter */ | 2249 | GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */ |
1894 | 0, /* mutator */ | 2250 | GNUNET_BLOCK_TYPE_TEST, /* type */ |
1895 | NULL, /* xquery */ | 2251 | &pi.hashPubKey, /*key to search */ |
1896 | 0, /* xquery bits */ | 2252 | 4, /* replication level */ |
1897 | dht_get_id_handler, | 2253 | GNUNET_DHT_RO_RECORD_ROUTE, NULL, /* bloom filter */ |
1898 | (void *) peer_info); | 2254 | 0, /* mutator */ |
2255 | NULL, /* xquery */ | ||
2256 | 0, /* xquery bits */ | ||
2257 | dht_get_id_handler, | ||
2258 | (void *) path_info); | ||
2259 | return; | ||
2260 | } | ||
1899 | } | 2261 | } |
1900 | 2262 | ||
1901 | p = GNUNET_malloc (sizeof (struct MeshPath)); | 2263 | p = path_build_from_dht(get_path, put_path); |
1902 | for (i = 0; get_path[i] != NULL; i++) ; | 2264 | path_add_to_peer (path_info->peer, p); |
1903 | for (i--; i >= 0; i--) | 2265 | for (i = 0; i < path_info->peer->ntunnels; i++) |
1904 | { | ||
1905 | p->peers = | ||
1906 | GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1)); | ||
1907 | p->peers[p->length] = GNUNET_PEER_intern (get_path[i]); | ||
1908 | p->length++; | ||
1909 | } | ||
1910 | for (i = 0; put_path[i] != NULL; i++) ; | ||
1911 | for (i--; i >= 0; i--) | ||
1912 | { | 2266 | { |
1913 | p->peers = | 2267 | tunnel_add_peer(path_info->peer->tunnels[i], path_info->peer); |
1914 | GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1)); | ||
1915 | p->peers[p->length] = GNUNET_PEER_intern (put_path[i]); | ||
1916 | p->length++; | ||
1917 | } | ||
1918 | add_path_to_peer (peer_info, p); | ||
1919 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | ||
1920 | GNUNET_TIME_UNIT_FOREVER_REL, get_path[1], | ||
1921 | sizeof (struct GNUNET_MESH_ManipulatePath) | ||
1922 | + | ||
1923 | (p->length * | ||
1924 | sizeof (struct GNUNET_PeerIdentity)), | ||
1925 | &send_core_create_path_for_peer, | ||
1926 | peer_info); | ||
1927 | if (0 == peer_info->path_refresh_task) | ||
1928 | { | ||
1929 | peer_info->path_refresh_task = | ||
1930 | GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh, | ||
1931 | peer_info); | ||
1932 | } | 2268 | } |
2269 | GNUNET_free(path_info); | ||
2270 | |||
1933 | return; | 2271 | return; |
1934 | } | 2272 | } |
1935 | 2273 | ||
@@ -1962,7 +2300,7 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp, | |||
1962 | struct GNUNET_PeerIdentity id; | 2300 | struct GNUNET_PeerIdentity id; |
1963 | struct MeshTunnel *t = cls; | 2301 | struct MeshTunnel *t = cls; |
1964 | struct MeshPeerInfo *peer_info; | 2302 | struct MeshPeerInfo *peer_info; |
1965 | struct MeshPath *p; | 2303 | struct MeshPeerPath *p; |
1966 | int i; | 2304 | int i; |
1967 | 2305 | ||
1968 | if (size != sizeof (struct GNUNET_PeerIdentity)) | 2306 | if (size != sizeof (struct GNUNET_PeerIdentity)) |
@@ -1973,12 +2311,12 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp, | |||
1973 | GNUNET_assert (NULL != t->client); | 2311 | GNUNET_assert (NULL != t->client); |
1974 | GNUNET_DHT_get_stop (t->client->dht_get_type); | 2312 | GNUNET_DHT_get_stop (t->client->dht_get_type); |
1975 | t->client->dht_get_type = NULL; | 2313 | t->client->dht_get_type = NULL; |
1976 | peer_info = get_peer_info (pi); | 2314 | peer_info = peer_info_get (pi); |
1977 | GNUNET_CONTAINER_multihashmap_put (t->peers, &pi->hashPubKey, peer_info, | 2315 | GNUNET_CONTAINER_multihashmap_put (t->peers, &pi->hashPubKey, peer_info, |
1978 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 2316 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
1979 | 2317 | ||
1980 | if ((NULL == get_path || NULL == put_path) && | 2318 | if ((NULL == get_path || NULL == put_path) && |
1981 | NULL == peer_info->path && | 2319 | NULL == peer_info->path_head && |
1982 | NULL == peer_info->dhtget) | 2320 | NULL == peer_info->dhtget) |
1983 | { | 2321 | { |
1984 | /* we don't have a route to the peer, let's try a direct lookup */ | 2322 | /* we don't have a route to the peer, let's try a direct lookup */ |
@@ -1997,24 +2335,8 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp, | |||
1997 | peer_info); /* closure */ | 2335 | peer_info); /* closure */ |
1998 | } | 2336 | } |
1999 | 2337 | ||
2000 | p = GNUNET_malloc (sizeof (struct MeshPath)); | 2338 | p = path_build_from_dht(get_path, put_path); |
2001 | for (i = 0; get_path[i] != NULL; i++) ; | 2339 | path_add_to_peer (peer_info, p); |
2002 | for (i--; i >= 0; i--) | ||
2003 | { | ||
2004 | p->peers = | ||
2005 | GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1)); | ||
2006 | p->peers[p->length] = GNUNET_PEER_intern (get_path[i]); | ||
2007 | p->length++; | ||
2008 | } | ||
2009 | for (i = 0; put_path[i] != NULL; i++) ; | ||
2010 | for (i--; i >= 0; i--) | ||
2011 | { | ||
2012 | p->peers = | ||
2013 | GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1)); | ||
2014 | p->peers[p->length] = GNUNET_PEER_intern (put_path[i]); | ||
2015 | p->length++; | ||
2016 | } | ||
2017 | add_path_to_peer (peer_info, p); | ||
2018 | #if MESH_DEBUG | 2340 | #if MESH_DEBUG |
2019 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 2341 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
2020 | "MESH: new route for tunnel 0x%x found, has %u hops\n", | 2342 | "MESH: new route for tunnel 0x%x found, has %u hops\n", |
@@ -2039,7 +2361,7 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp, | |||
2039 | &id, /* target */ | 2361 | &id, /* target */ |
2040 | sizeof (struct GNUNET_MESH_ManipulatePath) + | 2362 | sizeof (struct GNUNET_MESH_ManipulatePath) + |
2041 | (p->length * sizeof (struct GNUNET_PeerIdentity)), /*size */ | 2363 | (p->length * sizeof (struct GNUNET_PeerIdentity)), /*size */ |
2042 | &send_core_create_path_for_peer, /* callback */ | 2364 | &send_core_create_path, /* callback */ |
2043 | peer_info); /* cls */ | 2365 | peer_info); /* cls */ |
2044 | } | 2366 | } |
2045 | 2367 | ||
@@ -2217,7 +2539,7 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
2217 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: new tunnel requested\n"); | 2539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: new tunnel requested\n"); |
2218 | 2540 | ||
2219 | /* Sanity check for client registration */ | 2541 | /* Sanity check for client registration */ |
2220 | if (NULL == (c = retrieve_client (client))) | 2542 | if (NULL == (c = client_get (client))) |
2221 | { | 2543 | { |
2222 | GNUNET_break (0); | 2544 | GNUNET_break (0); |
2223 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 2545 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -2241,7 +2563,7 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
2241 | return; | 2563 | return; |
2242 | } | 2564 | } |
2243 | /* Sanity check for duplicate tunnel IDs */ | 2565 | /* Sanity check for duplicate tunnel IDs */ |
2244 | if (NULL != retrieve_tunnel_by_local_id (c, ntohl (t_msg->tunnel_id))) | 2566 | if (NULL != tunnel_get_by_local_id (c, ntohl (t_msg->tunnel_id))) |
2245 | { | 2567 | { |
2246 | GNUNET_break (0); | 2568 | GNUNET_break (0); |
2247 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 2569 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -2249,7 +2571,7 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
2249 | } | 2571 | } |
2250 | 2572 | ||
2251 | t = GNUNET_malloc (sizeof (struct MeshTunnel)); | 2573 | t = GNUNET_malloc (sizeof (struct MeshTunnel)); |
2252 | while (NULL != retrieve_tunnel_by_pi (myid, next_tid)) | 2574 | while (NULL != tunnel_get_by_pi (myid, next_tid)) |
2253 | next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI; | 2575 | next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI; |
2254 | t->id.tid = next_tid++; | 2576 | t->id.tid = next_tid++; |
2255 | t->id.oid = myid; | 2577 | t->id.oid = myid; |
@@ -2302,7 +2624,7 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
2302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: destroying tunnel\n"); | 2624 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: destroying tunnel\n"); |
2303 | 2625 | ||
2304 | /* Sanity check for client registration */ | 2626 | /* Sanity check for client registration */ |
2305 | if (NULL == (c = retrieve_client (client))) | 2627 | if (NULL == (c = client_get (client))) |
2306 | { | 2628 | { |
2307 | GNUNET_break (0); | 2629 | GNUNET_break (0); |
2308 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 2630 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -2342,6 +2664,8 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
2342 | * @param cls closure | 2664 | * @param cls closure |
2343 | * @param client identification of the client | 2665 | * @param client identification of the client |
2344 | * @param message the actual message (PeerControl) | 2666 | * @param message the actual message (PeerControl) |
2667 | * | ||
2668 | * FIXME path | ||
2345 | */ | 2669 | */ |
2346 | static void | 2670 | static void |
2347 | handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client, | 2671 | handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client, |
@@ -2355,7 +2679,7 @@ handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client, | |||
2355 | 2679 | ||
2356 | 2680 | ||
2357 | /* Sanity check for client registration */ | 2681 | /* Sanity check for client registration */ |
2358 | if (NULL == (c = retrieve_client (client))) | 2682 | if (NULL == (c = client_get (client))) |
2359 | { | 2683 | { |
2360 | GNUNET_break (0); | 2684 | GNUNET_break (0); |
2361 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 2685 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -2373,7 +2697,7 @@ handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client, | |||
2373 | 2697 | ||
2374 | /* Tunnel exists? */ | 2698 | /* Tunnel exists? */ |
2375 | tid = ntohl (peer_msg->tunnel_id); | 2699 | tid = ntohl (peer_msg->tunnel_id); |
2376 | t = retrieve_tunnel_by_local_id (c, tid); | 2700 | t = tunnel_get_by_local_id (c, tid); |
2377 | if (NULL == t) | 2701 | if (NULL == t) |
2378 | { | 2702 | { |
2379 | GNUNET_break (0); | 2703 | GNUNET_break (0); |
@@ -2390,10 +2714,10 @@ handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client, | |||
2390 | } | 2714 | } |
2391 | 2715 | ||
2392 | t->peers_total++; | 2716 | t->peers_total++; |
2393 | peer_info = get_peer_info (&peer_msg->peer); | 2717 | peer_info = peer_info_get (&peer_msg->peer); |
2394 | 2718 | ||
2395 | /* Start DHT search if needed */ | 2719 | /* Start DHT search if needed FIXME: if not already connected */ |
2396 | if (MESH_PEER_READY != peer_info->state && NULL == peer_info->dhtget) | 2720 | if (NULL == peer_info->dhtget) |
2397 | { | 2721 | { |
2398 | peer_info->dhtget = GNUNET_DHT_get_start (dht_handle, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_BLOCK_TYPE_TEST, &peer_msg->peer.hashPubKey, 4, /* replication level */ | 2722 | peer_info->dhtget = GNUNET_DHT_get_start (dht_handle, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_BLOCK_TYPE_TEST, &peer_msg->peer.hashPubKey, 4, /* replication level */ |
2399 | GNUNET_DHT_RO_RECORD_ROUTE, NULL, /* bloom filter */ | 2723 | GNUNET_DHT_RO_RECORD_ROUTE, NULL, /* bloom filter */ |
@@ -2426,7 +2750,7 @@ handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client, | |||
2426 | MESH_TunnelNumber tid; | 2750 | MESH_TunnelNumber tid; |
2427 | 2751 | ||
2428 | /* Sanity check for client registration */ | 2752 | /* Sanity check for client registration */ |
2429 | if (NULL == (c = retrieve_client (client))) | 2753 | if (NULL == (c = client_get (client))) |
2430 | { | 2754 | { |
2431 | GNUNET_break (0); | 2755 | GNUNET_break (0); |
2432 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 2756 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -2443,7 +2767,7 @@ handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client, | |||
2443 | 2767 | ||
2444 | /* Tunnel exists? */ | 2768 | /* Tunnel exists? */ |
2445 | tid = ntohl (peer_msg->tunnel_id); | 2769 | tid = ntohl (peer_msg->tunnel_id); |
2446 | t = retrieve_tunnel_by_local_id (c, tid); | 2770 | t = tunnel_get_by_local_id (c, tid); |
2447 | if (NULL == t) | 2771 | if (NULL == t) |
2448 | { | 2772 | { |
2449 | GNUNET_break (0); | 2773 | GNUNET_break (0); |
@@ -2488,7 +2812,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client, | |||
2488 | 2812 | ||
2489 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: got connect by type request\n"); | 2813 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: got connect by type request\n"); |
2490 | /* Sanity check for client registration */ | 2814 | /* Sanity check for client registration */ |
2491 | if (NULL == (c = retrieve_client (client))) | 2815 | if (NULL == (c = client_get (client))) |
2492 | { | 2816 | { |
2493 | GNUNET_break (0); | 2817 | GNUNET_break (0); |
2494 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 2818 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -2507,7 +2831,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client, | |||
2507 | 2831 | ||
2508 | /* Tunnel exists? */ | 2832 | /* Tunnel exists? */ |
2509 | tid = ntohl (connect_msg->tunnel_id); | 2833 | tid = ntohl (connect_msg->tunnel_id); |
2510 | t = retrieve_tunnel_by_local_id (c, tid); | 2834 | t = tunnel_get_by_local_id (c, tid); |
2511 | if (NULL == t) | 2835 | if (NULL == t) |
2512 | { | 2836 | { |
2513 | GNUNET_break (0); | 2837 | GNUNET_break (0); |
@@ -2538,7 +2862,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client, | |||
2538 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: available locally\n"); | 2862 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: available locally\n"); |
2539 | pc.peer = my_full_id; | 2863 | pc.peer = my_full_id; |
2540 | GNUNET_CONTAINER_multihashmap_put (t->peers, &pc.peer.hashPubKey, | 2864 | GNUNET_CONTAINER_multihashmap_put (t->peers, &pc.peer.hashPubKey, |
2541 | get_peer_info (&pc.peer), | 2865 | peer_info_get (&pc.peer), |
2542 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 2866 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
2543 | pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl)); | 2867 | pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl)); |
2544 | pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD); | 2868 | pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD); |
@@ -2591,7 +2915,7 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client, | |||
2591 | size_t data_size; | 2915 | size_t data_size; |
2592 | 2916 | ||
2593 | /* Sanity check for client registration */ | 2917 | /* Sanity check for client registration */ |
2594 | if (NULL == (c = retrieve_client (client))) | 2918 | if (NULL == (c = client_get (client))) |
2595 | { | 2919 | { |
2596 | GNUNET_break (0); | 2920 | GNUNET_break (0); |
2597 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 2921 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -2609,7 +2933,7 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client, | |||
2609 | 2933 | ||
2610 | /* Tunnel exists? */ | 2934 | /* Tunnel exists? */ |
2611 | tid = ntohl (data_msg->tid); | 2935 | tid = ntohl (data_msg->tid); |
2612 | t = retrieve_tunnel_by_local_id (c, tid); | 2936 | t = tunnel_get_by_local_id (c, tid); |
2613 | if (NULL == t) | 2937 | if (NULL == t) |
2614 | { | 2938 | { |
2615 | GNUNET_break (0); | 2939 | GNUNET_break (0); |
@@ -2645,7 +2969,7 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client, | |||
2645 | handle_mesh_data_unicast (NULL, &my_full_id, ©.header, NULL); | 2969 | handle_mesh_data_unicast (NULL, &my_full_id, ©.header, NULL); |
2646 | return; | 2970 | return; |
2647 | } | 2971 | } |
2648 | GNUNET_PEER_resolve (get_first_hop (pi->path), &next_hop); | 2972 | GNUNET_PEER_resolve (path_get_first_hop (t, pi)->id, &next_hop); |
2649 | data_size = ntohs (message->size) - sizeof (struct GNUNET_MESH_Unicast); | 2973 | data_size = ntohs (message->size) - sizeof (struct GNUNET_MESH_Unicast); |
2650 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor) + data_size); | 2974 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor) + data_size); |
2651 | memcpy (&info[1], &data_msg[1], data_size); | 2975 | memcpy (&info[1], &data_msg[1], data_size); |
@@ -2679,7 +3003,7 @@ handle_local_multicast (void *cls, struct GNUNET_SERVER_Client *client, | |||
2679 | MESH_TunnelNumber tid; | 3003 | MESH_TunnelNumber tid; |
2680 | 3004 | ||
2681 | /* Sanity check for client registration */ | 3005 | /* Sanity check for client registration */ |
2682 | if (NULL == (c = retrieve_client (client))) | 3006 | if (NULL == (c = client_get (client))) |
2683 | { | 3007 | { |
2684 | GNUNET_break (0); | 3008 | GNUNET_break (0); |
2685 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 3009 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
@@ -2696,7 +3020,7 @@ handle_local_multicast (void *cls, struct GNUNET_SERVER_Client *client, | |||
2696 | 3020 | ||
2697 | /* Tunnel exists? */ | 3021 | /* Tunnel exists? */ |
2698 | tid = ntohl (data_msg->tid); | 3022 | tid = ntohl (data_msg->tid); |
2699 | t = retrieve_tunnel_by_local_id (c, tid); | 3023 | t = tunnel_get_by_local_id (c, tid); |
2700 | if (NULL == t) | 3024 | if (NULL == t) |
2701 | { | 3025 | { |
2702 | GNUNET_break (0); | 3026 | GNUNET_break (0); |
@@ -2782,20 +3106,20 @@ core_connect (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2782 | { | 3106 | { |
2783 | // GNUNET_PEER_Id pid; | 3107 | // GNUNET_PEER_Id pid; |
2784 | struct MeshPeerInfo *peer_info; | 3108 | struct MeshPeerInfo *peer_info; |
2785 | struct MeshPath *path; | 3109 | struct MeshPeerPath *path; |
2786 | 3110 | ||
2787 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Peer connected\n"); | 3111 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Peer connected\n"); |
2788 | peer_info = get_peer_info (peer); | 3112 | peer_info = peer_info_get (peer); |
2789 | if (myid == peer_info->id) | 3113 | if (myid == peer_info->id) |
2790 | { | 3114 | { |
2791 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: (self)\n"); | 3115 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: (self)\n"); |
2792 | } | 3116 | } |
2793 | path = GNUNET_malloc (sizeof (struct MeshPath)); | 3117 | path = GNUNET_malloc (sizeof (struct MeshPeerPath)); |
2794 | path->length = 2; | 3118 | path->length = 2; |
2795 | path->peers = GNUNET_malloc (sizeof (GNUNET_PEER_Id) * 2); | 3119 | path->peers = GNUNET_malloc (sizeof (GNUNET_PEER_Id) * 2); |
2796 | path->peers[0] = myid; | 3120 | path->peers[0] = myid; |
2797 | path->peers[1] = peer_info->id; | 3121 | path->peers[1] = peer_info->id; |
2798 | add_path_to_peer (peer_info, path); | 3122 | path_add_to_peer (peer_info, path); |
2799 | return; | 3123 | return; |
2800 | } | 3124 | } |
2801 | 3125 | ||
@@ -2827,6 +3151,7 @@ core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | |||
2827 | GNUNET_free (pi->infos[i]); | 3151 | GNUNET_free (pi->infos[i]); |
2828 | } | 3152 | } |
2829 | } | 3153 | } |
3154 | path_remove_from_peer (pi, pi->id, myid); | ||
2830 | if (myid == pi->id) | 3155 | if (myid == pi->id) |
2831 | { | 3156 | { |
2832 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: (self)\n"); | 3157 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: (self)\n"); |