aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-09-16 15:23:32 +0000
committerBart Polot <bart@net.in.tum.de>2011-09-16 15:23:32 +0000
commitc8dce9e10f91f76095eb9620f9e85af6dcd2b1d3 (patch)
treef65c47b3aa2401543a6b21027f1f038ff9b95db8 /src
parentc90957f078692b28d99b330a485a3f2becfa89bb (diff)
downloadgnunet-c8dce9e10f91f76095eb9620f9e85af6dcd2b1d3.tar.gz
gnunet-c8dce9e10f91f76095eb9620f9e85af6dcd2b1d3.zip
Changed path management
- Peers now have a set of individual paths to reach them - Tunnels have a tree of the paths in the tunnel to reach all peers in the tunnel in an efficent way, allowing to add peers efficiently taking in account existing paths and having each tunnel reach a peer on a different path. - Adapted helper functions, periodic announcements, etc to new structure Added initial support for link disconnection notification and readjustment
Diffstat (limited to 'src')
-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");