aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesh/gnunet-service-mesh.c1259
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 */
102struct MeshPath 100enum 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 */
131enum MeshPeerState 136struct 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 */
161struct 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 */
198struct 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 */
441struct 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 */
588static int
589announce_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 */
614static void
615announce_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 */
639static void
640announce_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 */
679static void
680path_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 */
477static struct MeshPeerInfo * 718static struct MeshPeerInfo *
478get_peer_info (const struct GNUNET_PeerIdentity *peer) 719peer_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 */
502static GNUNET_PEER_Id 744static int
503get_first_hop (struct MeshPath *path) 745peer_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 */
769static int
770path_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 */
788static struct MeshPeerInfo *
789path_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 */
544static unsigned int 807static unsigned int
545get_path_cost (struct MeshPath *path) 808path_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 */
836static unsigned int
837path_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 */
568static void 852static void
569add_path_to_peer (struct MeshPeerInfo *peer_info, struct MeshPath *path) 853path_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 */
892static void
893tunnel_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 */
908static void
909path_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 */
616static void 954static void
617add_path_to_origin (struct MeshPeerInfo *peer_info, struct MeshPath *path) 955path_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 */
980static int
981path_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 */
1061static struct MeshPeerPath *
1062path_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 */
637static struct MeshClient * 1096static struct MeshClient *
638retrieve_client (struct GNUNET_SERVER_Client *client) 1097client_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 */
659static int /* FIXME inline? */ 1122static int
660is_client_subscribed (uint16_t message_type, struct MeshClient *c) 1123client_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 */
675static struct MeshTunnel * 1140static struct MeshTunnel *
676retrieve_tunnel_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid) 1141tunnel_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 */
690static struct MeshTunnel * 1158static struct MeshTunnel *
691retrieve_tunnel_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid) 1159tunnel_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 */
711static struct MeshTunnel * 1181static struct MeshTunnel *
712retrieve_tunnel (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid) 1182tunnel_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 */
723static int 1196static void
724destroy_path (struct MeshPath *p) 1197tunnel_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 */
739static int 1235static void
740destroy_peer_info (struct MeshPeerInfo *pi) 1236tunnel_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 */
762static int 1251static int
763destroy_tunnel (struct MeshTunnel *t) 1252tunnel_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 */
816static int
817announce_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 */
842static void
843announce_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 */
867static void
868announce_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 */
913static size_t 1308static size_t
914send_core_create_path_for_peer (void *cls, size_t size, void *buf) 1309send_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
1261iterate_collect_neighbors (void *cls, const GNUNET_HashCode * key, void *value) 1630iterate_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 */
1605static int 1986static int
1606handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, 1987handle_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 */
1673static int 2057static int
1674handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, 2058handle_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 */
1832static void
1833path_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 */
1872static void 2228static void
1873dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, 2229dht_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 */
2346static void 2670static void
2347handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client, 2671handle_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, &copy.header, NULL); 2969 handle_mesh_data_unicast (NULL, &my_full_id, &copy.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");