-bump name to 97
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh_peer.c
1 /*
2      This file is part of GNUnet.
3      (C) 2013 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21
22 #include "platform.h"
23 #include "gnunet_util_lib.h"
24
25 #include "gnunet_core_service.h"
26 #include "gnunet_statistics_service.h"
27
28 #include "mesh_protocol_enc.h"
29
30 #include "gnunet-service-mesh_peer.h"
31 #include "gnunet-service-mesh_dht.h"
32 #include "gnunet-service-mesh_connection.h"
33 #include "gnunet-service-mesh_local.h"
34 #include "gnunet-service-mesh_tunnel.h"
35 #include "mesh_path.h"
36
37 #define LOG(level, ...) GNUNET_log_from (level,"mesh-p2p",__VA_ARGS__)
38
39 /******************************************************************************/
40 /********************************   STRUCTS  **********************************/
41 /******************************************************************************/
42
43 /**
44  * Struct containing all information regarding a given peer
45  */
46 struct MeshPeer
47 {
48     /**
49      * ID of the peer
50      */
51   GNUNET_PEER_Id id;
52
53     /**
54      * Last time we heard from this peer
55      */
56   struct GNUNET_TIME_Absolute last_contact;
57
58     /**
59      * Paths to reach the peer, ordered by ascending hop count
60      */
61   struct MeshPeerPath *path_head;
62
63     /**
64      * Paths to reach the peer, ordered by ascending hop count
65      */
66   struct MeshPeerPath *path_tail;
67
68     /**
69      * Handle to stop the DHT search for paths to this peer
70      */
71   struct GMD_search_handle *search_h;
72
73     /**
74      * Tunnel to this peer, if any.
75      */
76   struct MeshTunnel2 *tunnel;
77
78     /**
79      * Connections that go through this peer, indexed by tid;
80      */
81   struct GNUNET_CONTAINER_MultiHashMap *connections;
82
83     /**
84      * Handle for queued transmissions
85      */
86   struct GNUNET_CORE_TransmitHandle *core_transmit;
87
88   /**
89    * Transmission queue to core DLL head
90    */
91   struct MeshPeerQueue *queue_head;
92
93   /**
94    * Transmission queue to core DLL tail
95    */
96   struct MeshPeerQueue *queue_tail;
97
98   /**
99    * How many messages are in the queue to this peer.
100    */
101   unsigned int queue_n;
102 };
103
104
105 /******************************************************************************/
106 /*******************************   GLOBALS  ***********************************/
107 /******************************************************************************/
108
109 /**
110  * Global handle to the statistics service.
111  */
112 extern struct GNUNET_STATISTICS_Handle *stats;
113
114 /**
115  * Peers known, indexed by PeerIdentity (MeshPeer).
116  */
117 static struct GNUNET_CONTAINER_MultiPeerMap *peers;
118
119 /**
120  * How many peers do we want to remember?
121  */
122 static unsigned long long max_peers;
123
124 /**
125  * Percentage of messages that will be dropped (for test purposes only).
126  */
127 static unsigned long long drop_percent;
128
129 /**
130  * Handle to communicate with core.
131  */
132 static struct GNUNET_CORE_Handle *core_handle;
133
134 /**
135  * Local peer own ID (full value).
136  */
137 const static struct GNUNET_PeerIdentity *my_full_id;
138
139 /******************************************************************************/
140 /***************************** CORE CALLBACKS *********************************/
141 /******************************************************************************/
142
143
144 /**
145  * Iterator to notify all connections of a broken link. Mark connections
146  * to destroy after all traffic has been sent.
147  *
148  * @param cls Closure (peer disconnected).
149  * @param key Current key code (peer id).
150  * @param value Value in the hash map (connection).
151  *
152  * @return GNUNET_YES if we should continue to iterate,
153  *         GNUNET_NO if not.
154  */
155 static int
156 notify_broken (void *cls,
157                const struct GNUNET_HashCode *key,
158                void *value)
159 {
160   struct MeshPeer *peer = cls;
161   struct MeshConnection *c = value;
162
163   GMC_notify_broken (c, peer, my_full_id);
164
165   return GNUNET_YES;
166 }
167
168
169 /**
170  * Method called whenever a given peer connects.
171  *
172  * @param cls closure
173  * @param peer peer identity this notification is about
174  */
175 static void
176 core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
177 {
178   struct MeshPeer *pi;
179   struct MeshPeerPath *path;
180
181   LOG ("Peer connected\n");
182   LOG ("     %s\n", GNUNET_i2s (&my_full_id));
183   pi = peer_get (peer);
184   if (myid == pi->id)
185   {
186     LOG ("     (self)\n");
187     path = path_new (1);
188   }
189   else
190   {
191     LOG ("     %s\n", GNUNET_i2s (peer));
192     path = path_new (2);
193     path->peers[1] = pi->id;
194     GNUNET_PEER_change_rc (pi->id, 1);
195     GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
196   }
197   path->peers[0] = myid;
198   GNUNET_PEER_change_rc (myid, 1);
199   peer_add_path (pi, path, GNUNET_YES);
200
201   pi->connections = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_YES);
202   return;
203 }
204
205
206 /**
207  * Method called whenever a peer disconnects.
208  *
209  * @param cls closure
210  * @param peer peer identity this notification is about
211  */
212 static void
213 core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
214 {
215   struct MeshPeer *pi;
216
217   LOG ("Peer disconnected\n");
218   pi = GNUNET_CONTAINER_multipeermap_get (peers, peer);
219   if (NULL == pi)
220   {
221     GNUNET_break (0);
222     return;
223   }
224
225   GNUNET_CONTAINER_multihashmap_iterate (pi->connections, &notify_broken, pi);
226   GNUNET_CONTAINER_multihashmap_destroy (pi->connections);
227   pi->connections = NULL;
228   if (NULL != pi->core_transmit)
229     {
230       GNUNET_CORE_notify_transmit_ready_cancel (pi->core_transmit);
231       pi->core_transmit = NULL;
232     }
233   if (myid == pi->id)
234   {
235     LOG ("     (self)\n");
236   }
237   GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
238
239   return;
240 }
241
242
243 /**
244  * Functions to handle messages from core
245  */
246 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
247   {&GMC_handle_create, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE,
248     0},
249   {&GMC_handle_confirm, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK,
250     sizeof (struct GNUNET_MESH_ConnectionACK)},
251   {&GMC_handle_broken, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN,
252     sizeof (struct GNUNET_MESH_ConnectionBroken)},
253   {&GMC_handle_destroy, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY,
254     sizeof (struct GNUNET_MESH_ConnectionDestroy)},
255   {&GMC_handle_keepalive, GNUNET_MESSAGE_TYPE_MESH_FWD_KEEPALIVE,
256     sizeof (struct GNUNET_MESH_ConnectionKeepAlive)},
257   {&GMC_handle_keepalive, GNUNET_MESSAGE_TYPE_MESH_BCK_KEEPALIVE,
258     sizeof (struct GNUNET_MESH_ConnectionKeepAlive)},
259   {&GMC_handle_ack, GNUNET_MESSAGE_TYPE_MESH_ACK,
260     sizeof (struct GNUNET_MESH_ACK)},
261   {&GMC_handle_poll, GNUNET_MESSAGE_TYPE_MESH_POLL,
262     sizeof (struct GNUNET_MESH_Poll)},
263   {&GMC_handle_fwd, GNUNET_MESSAGE_TYPE_MESH_FWD, 0},
264   {&GMC_handle_bck, GNUNET_MESSAGE_TYPE_MESH_BCK, 0},
265   {NULL, 0, 0}
266 };
267
268
269 /**
270  * To be called on core init/fail.
271  *
272  * @param cls Closure (config)
273  * @param identity the public identity of this peer
274  */
275 static void
276 core_init (void *cls,
277            const struct GNUNET_PeerIdentity *identity)
278 {
279   const struct GNUNET_CONFIGURATION_Handle *c = cls;
280   static int i = 0;
281
282   LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
283   if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)))
284   {
285     LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
286     LOG (GNUNET_ERROR_TYPE_ERROR, " core id %s\n", GNUNET_i2s (identity));
287     LOG (GNUNET_ERROR_TYPE_ERROR, " my id %s\n", GNUNET_i2s (&my_full_id));
288     GNUNET_CORE_disconnect (core_handle);
289     core_handle = GNUNET_CORE_connect (c, /* Main configuration */
290                                        NULL,      /* Closure passed to MESH functions */
291                                        &core_init,        /* Call core_init once connected */
292                                        &core_connect,     /* Handle connects */
293                                        &core_disconnect,  /* remove peers on disconnects */
294                                        NULL,      /* Don't notify about all incoming messages */
295                                        GNUNET_NO, /* For header only in notification */
296                                        NULL,      /* Don't notify about all outbound messages */
297                                        GNUNET_NO, /* For header-only out notification */
298                                        core_handlers);    /* Register these handlers */
299     if (10 < i++)
300       GNUNET_abort();
301   }
302   GML_start ();
303   return;
304 }
305
306 /**
307   * Core callback to write a pre-constructed data packet to core buffer
308   *
309   * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
310   * @param size Number of bytes available in buf.
311   * @param buf Where the to write the message.
312   *
313   * @return number of bytes written to buf
314   */
315 static size_t
316 send_core_data_raw (void *cls, size_t size, void *buf)
317 {
318   struct GNUNET_MessageHeader *msg = cls;
319   size_t total_size;
320
321   GNUNET_assert (NULL != msg);
322   total_size = ntohs (msg->size);
323
324   if (total_size > size)
325   {
326     GNUNET_break (0);
327     return 0;
328   }
329   memcpy (buf, msg, total_size);
330   GNUNET_free (cls);
331   return total_size;
332 }
333
334
335 /**
336  * Function to send a create connection message to a peer.
337  *
338  * @param c Connection to create.
339  * @param size number of bytes available in buf
340  * @param buf where the callee should write the message
341  * @return number of bytes written to buf
342  */
343 static size_t
344 send_core_connection_create (struct MeshConnection *c, size_t size, void *buf)
345 {
346   struct GNUNET_MESH_ConnectionCreate *msg;
347   struct GNUNET_PeerIdentity *peer_ptr;
348   struct MeshPeerPath *p = c->path;
349   size_t size_needed;
350   int i;
351
352   LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION CREATE...\n");
353   size_needed =
354       sizeof (struct GNUNET_MESH_ConnectionCreate) +
355       p->length * sizeof (struct GNUNET_PeerIdentity);
356
357   if (size < size_needed || NULL == buf)
358   {
359     GNUNET_break (0);
360     return 0;
361   }
362   msg = (struct GNUNET_MESH_ConnectionCreate *) buf;
363   msg->header.size = htons (size_needed);
364   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE);
365   msg->cid = c->id;
366
367   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
368   for (i = 0; i < p->length; i++)
369   {
370     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
371   }
372
373   LOG (GNUNET_ERROR_TYPE_DEBUG,
374               "CONNECTION CREATE (%u bytes long) sent!\n", size_needed);
375   return size_needed;
376 }
377
378
379 /**
380  * Creates a path ack message in buf and frees all unused resources.
381  *
382  * @param c Connection to send an ACK on.
383  * @param size number of bytes available in buf
384  * @param buf where the callee should write the message
385  *
386  * @return number of bytes written to buf
387  */
388 static size_t
389 send_core_connection_ack (struct MeshConnection *c, size_t size, void *buf)
390 {
391   struct GNUNET_MESH_ConnectionACK *msg = buf;
392   struct MeshTunnel2 *t = c->t;
393
394   LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION ACK...\n");
395   GNUNET_assert (NULL != t);
396   if (sizeof (struct GNUNET_MESH_ConnectionACK) > size)
397   {
398     GNUNET_break (0);
399     return 0;
400   }
401   msg->header.size = htons (sizeof (struct GNUNET_MESH_ConnectionACK));
402   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK);
403   msg->cid = c->id;
404   msg->reserved = 0;
405
406   /* TODO add signature */
407
408   LOG (GNUNET_ERROR_TYPE_DEBUG, "CONNECTION ACK sent!\n");
409   return sizeof (struct GNUNET_MESH_ConnectionACK);
410 }
411
412
413 /******************************************************************************/
414 /********************************   STATIC  ***********************************/
415 /******************************************************************************/
416
417 /**
418  * Iterator over tunnel hash map entries to destroy the tunnel during shutdown.
419  *
420  * @param cls closure
421  * @param key current key code
422  * @param value value in the hash map
423  * @return #GNUNET_YES if we should continue to iterate,
424  *         #GNUNET_NO if not.
425  */
426 static int
427 shutdown_tunnel (void *cls,
428                  const struct GNUNET_PeerIdentity *key,
429                  void *value)
430 {
431   struct MeshPeer *p = value;
432   struct MeshTunnel2 *t = p->tunnel;
433
434   if (NULL != t)
435     GMT_destroy (t);
436   return GNUNET_YES;
437 }
438
439
440
441 /**
442  * Destroy the peer_info and free any allocated resources linked to it
443  *
444  * @param peer The peer_info to destroy.
445  *
446  * @return GNUNET_OK on success
447  */
448 static int
449 peer_destroy (struct MeshPeer *peer)
450 {
451   struct GNUNET_PeerIdentity id;
452   struct MeshPeerPath *p;
453   struct MeshPeerPath *nextp;
454
455   GNUNET_PEER_resolve (peer->id, &id);
456   GNUNET_PEER_change_rc (peer->id, -1);
457
458   if (GNUNET_YES !=
459     GNUNET_CONTAINER_multipeermap_remove (peers, &id, peer))
460   {
461     GNUNET_break (0);
462     LOG (GNUNET_ERROR_TYPE_WARNING,
463                 "removing peer %s, not in peermap\n", GNUNET_i2s (&id));
464   }
465     if (NULL != peer->search_h)
466     {
467       GMD_search_stop (peer->search_h);
468     }
469       p = peer->path_head;
470       while (NULL != p)
471       {
472         nextp = p->next;
473         GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, p);
474         path_destroy (p);
475         p = nextp;
476       }
477         tunnel_destroy_empty (peer->tunnel);
478         GNUNET_free (peer);
479         return GNUNET_OK;
480 }
481
482
483 /**
484  * Returns if peer is used (has a tunnel, is neighbor).
485  *
486  * @peer Peer to check.
487  *
488  * @return GNUNET_YES if peer is in use.
489  */
490 static int
491 peer_is_used (struct MeshPeer *peer)
492 {
493   struct MeshPeerPath *p;
494
495   if (NULL != peer->tunnel)
496     return GNUNET_YES;
497
498   for (p = peer->path_head; NULL != p; p = p->next)
499   {
500     if (p->length < 3)
501       return GNUNET_YES;
502   }
503     return GNUNET_NO;
504 }
505
506
507 /**
508  * Iterator over all the peers to get the oldest timestamp.
509  *
510  * @param cls Closure (unsued).
511  * @param key ID of the peer.
512  * @param value Peer_Info of the peer.
513  */
514 static int
515 peer_get_oldest (void *cls,
516                  const struct GNUNET_PeerIdentity *key,
517                  void *value)
518 {
519   struct MeshPeer *p = value;
520   struct GNUNET_TIME_Absolute *abs = cls;
521
522   /* Don't count active peers */
523   if (GNUNET_YES == peer_is_used (p))
524     return GNUNET_YES;
525
526   if (abs->abs_value_us < p->last_contact.abs_value_us)
527     abs->abs_value_us = p->last_contact.abs_value_us;
528
529   return GNUNET_YES;
530 }
531
532
533 /**
534  * Iterator over all the peers to remove the oldest entry.
535  *
536  * @param cls Closure (unsued).
537  * @param key ID of the peer.
538  * @param value Peer_Info of the peer.
539  */
540 static int
541 peer_timeout (void *cls,
542               const struct GNUNET_PeerIdentity *key,
543               void *value)
544 {
545   struct MeshPeer *p = value;
546   struct GNUNET_TIME_Absolute *abs = cls;
547
548   if (p->last_contact.abs_value_us == abs->abs_value_us &&
549     GNUNET_NO == peer_is_used (p))
550   {
551     peer_destroy (p);
552     return GNUNET_NO;
553   }
554     return GNUNET_YES;
555 }
556
557
558 /**
559  * Delete oldest unused peer.
560  */
561 static void
562 peer_delete_oldest (void)
563 {
564   struct GNUNET_TIME_Absolute abs;
565
566   abs = GNUNET_TIME_UNIT_FOREVER_ABS;
567
568   GNUNET_CONTAINER_multipeermap_iterate (peers,
569                                          &peer_get_oldest,
570                                          &abs);
571   GNUNET_CONTAINER_multipeermap_iterate (peers,
572                                          &peer_timeout,
573                                          &abs);
574 }
575
576
577 /**
578  * Retrieve the MeshPeer stucture associated with the peer, create one
579  * and insert it in the appropriate structures if the peer is not known yet.
580  *
581  * @param peer Full identity of the peer.
582  *
583  * @return Existing or newly created peer info.
584  */
585 static struct MeshPeer *
586 peer_get (const struct GNUNET_PeerIdentity *peer_id)
587 {
588   struct MeshPeer *peer;
589
590   peer = GNUNET_CONTAINER_multipeermap_get (peers, peer_id);
591   if (NULL == peer)
592   {
593     peer = GNUNET_new (struct MeshPeer);
594     if (GNUNET_CONTAINER_multipeermap_size (peers) > max_peers)
595     {
596       peer_delete_oldest ();
597     }
598         GNUNET_CONTAINER_multipeermap_put (peers, peer_id, peer,
599                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
600         peer->id = GNUNET_PEER_intern (peer_id);
601   }
602     peer->last_contact = GNUNET_TIME_absolute_get();
603
604     return peer;
605 }
606
607
608 /**
609  * Retrieve the MeshPeer stucture associated with the peer, create one
610  * and insert it in the appropriate structures if the peer is not known yet.
611  *
612  * @param peer Short identity of the peer.
613  *
614  * @return Existing or newly created peer info.
615  */
616 static struct MeshPeer *
617 peer_get_short (const GNUNET_PEER_Id peer)
618 {
619   return peer_get (GNUNET_PEER_resolve2 (peer));
620 }
621
622
623 /**
624  * Get a cost of a path for a peer considering existing tunnel connections.
625  *
626  * @param peer Peer towards which the path is considered.
627  * @param path Candidate path.
628  *
629  * @return Cost of the path (path length + number of overlapping nodes)
630  */
631 static unsigned int
632 peer_get_path_cost (const struct MeshPeer *peer,
633                     const struct MeshPeerPath *path)
634 {
635   struct MeshConnection *c;
636   unsigned int overlap;
637   unsigned int i;
638   unsigned int j;
639
640   if (NULL == path)
641     return 0;
642
643   overlap = 0;
644   GNUNET_assert (NULL != peer->tunnel);
645
646   for (i = 0; i < path->length; i++)
647   {
648     for (c = peer->tunnel->connection_head; NULL != c; c = c->next)
649     {
650       for (j = 0; j < c->path->length; j++)
651       {
652         if (path->peers[i] == c->path->peers[j])
653         {
654           overlap++;
655           break;
656         }
657       }
658     }
659   }
660   return (path->length + overlap) * (path->score * -1);
661 }
662
663
664 /**
665  * Choose the best path towards a peer considering the tunnel properties.
666  *
667  * @param peer The destination peer.
668  *
669  * @return Best current known path towards the peer, if any.
670  */
671 static struct MeshPeerPath *
672 peer_get_best_path (const struct MeshPeer *peer)
673 {
674   struct MeshPeerPath *best_p;
675   struct MeshPeerPath *p;
676   struct MeshConnection *c;
677   unsigned int best_cost;
678   unsigned int cost;
679
680   best_cost = UINT_MAX;
681   best_p = NULL;
682   for (p = peer->path_head; NULL != p; p = p->next)
683   {
684     for (c = peer->tunnel->connection_head; NULL != c; c = c->next)
685       if (c->path == p)
686         break;
687       if (NULL != c)
688         continue; /* If path is in use in a connection, skip it. */
689
690             if ((cost = peer_get_path_cost (peer, p)) < best_cost)
691             {
692               best_cost = cost;
693               best_p = p;
694             }
695   }
696     return best_p;
697 }
698
699
700 /**
701  * Add the path to the peer and update the path used to reach it in case this
702  * is the shortest.
703  *
704  * @param peer_info Destination peer to add the path to.
705  * @param path New path to add. Last peer must be the peer in arg 1.
706  *             Path will be either used of freed if already known.
707  * @param trusted Do we trust that this path is real?
708  */
709 void
710 peer_add_path (struct MeshPeer *peer_info, struct MeshPeerPath *path,
711                int trusted)
712 {
713   struct MeshPeerPath *aux;
714   unsigned int l;
715   unsigned int l2;
716
717   if ((NULL == peer_info) || (NULL == path))
718   {
719     GNUNET_break (0);
720     path_destroy (path);
721     return;
722   }
723     if (path->peers[path->length - 1] != peer_info->id)
724     {
725       GNUNET_break (0);
726       path_destroy (path);
727       return;
728     }
729       if (2 >= path->length && GNUNET_NO == trusted)
730       {
731         /* Only allow CORE to tell us about direct paths */
732         path_destroy (path);
733         return;
734       }
735         for (l = 1; l < path->length; l++)
736         {
737           if (path->peers[l] == myid)
738           {
739             LOG (GNUNET_ERROR_TYPE_DEBUG, "shortening path by %u\n", l);
740             for (l2 = 0; l2 < path->length - l; l2++)
741             {
742               path->peers[l2] = path->peers[l + l2];
743             }
744                   path->length -= l;
745                   l = 1;
746                   path->peers =
747                             GNUNET_realloc (path->peers, path->length * sizeof (GNUNET_PEER_Id));
748           }
749         }
750
751           LOG (GNUNET_ERROR_TYPE_DEBUG, "adding path [%u] to peer %s\n",
752                       path->length, peer2s (peer_info));
753
754           l = path_get_length (path);
755           if (0 == l)
756           {
757             path_destroy (path);
758             return;
759           }
760
761             GNUNET_assert (peer_info->id == path->peers[path->length - 1]);
762             for (aux = peer_info->path_head; aux != NULL; aux = aux->next)
763             {
764               l2 = path_get_length (aux);
765               if (l2 > l)
766               {
767                 GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head,
768                                                     peer_info->path_tail, aux, path);
769                 return;
770               }
771                   else
772                   {
773                     if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
774                     {
775                       path_destroy (path);
776                       return;
777                     }
778                   }
779             }
780               GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, peer_info->path_tail,
781                                                 path);
782               return;
783 }
784
785
786 /**
787  * Add the path to the origin peer and update the path used to reach it in case
788  * this is the shortest.
789  * The path is given in peer_info -> destination, therefore we turn the path
790  * upside down first.
791  *
792  * @param peer_info Peer to add the path to, being the origin of the path.
793  * @param path New path to add after being inversed.
794  *             Path will be either used or freed.
795  * @param trusted Do we trust that this path is real?
796  */
797 static void
798 peer_add_path_to_origin (struct MeshPeer *peer_info,
799                          struct MeshPeerPath *path, int trusted)
800 {
801   if (NULL == path)
802     return;
803   path_invert (path);
804   peer_add_path (peer_info, path, trusted);
805 }
806
807
808 /**
809  * Adds a path to the peer_infos of all the peers in the path
810  *
811  * @param p Path to process.
812  * @param confirmed Whether we know if the path works or not.
813  */
814 static void
815 path_add_to_peers (struct MeshPeerPath *p, int confirmed)
816 {
817   unsigned int i;
818
819   /* TODO: invert and add */
820   for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
821   for (i++; i < p->length; i++)
822   {
823     struct MeshPeer *aux;
824     struct MeshPeerPath *copy;
825     
826     aux = peer_get_short (p->peers[i]);
827     copy = path_duplicate (p);
828     copy->length = i + 1;
829     peer_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
830   }
831 }
832
833
834 /**
835  * Function to process paths received for a new peer addition. The recorded
836  * paths form the initial tunnel, which can be optimized later.
837  * Called on each result obtained for the DHT search.
838  *
839  * @param cls closure
840  * @param path
841  */
842 static void
843 search_handler (void *cls, struct MeshPeerPath *path)
844 {
845   struct MeshPeer *peer = cls;
846   unsigned int connection_count;
847
848   path_add_to_peers (path, GNUNET_NO);
849
850   /* Count connections */
851   connection_count = GMC_count (peer->tunnel->connection_head);
852
853   /* If we already have 3 (or more (?!)) connections, it's enough */
854   if (3 <= connection_count)
855     return;
856
857   if (peer->tunnel->state == MESH_TUNNEL_SEARCHING)
858   {
859     LOG (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
860     GMP_connect (peer);
861   }
862   return;
863 }
864
865
866 /**
867  * Core callback to write a queued packet to core buffer
868  *
869  * @param cls Closure (peer info).
870  * @param size Number of bytes available in buf.
871  * @param buf Where the to write the message.
872  *
873  * @return number of bytes written to buf
874  */
875 static size_t
876 queue_send (void *cls, size_t size, void *buf)
877 {
878   struct MeshPeer *peer = cls;
879   struct MeshFlowControl *fc;
880   struct MeshConnection *c;
881   struct GNUNET_MessageHeader *msg;
882   struct MeshPeerQueue *queue;
883   struct MeshTunnel2 *t;
884   struct MeshChannel *ch;
885   const struct GNUNET_PeerIdentity *dst_id;
886   size_t data_size;
887   uint32_t pid;
888   uint16_t type;
889   int fwd;
890
891   peer->core_transmit = NULL;
892   LOG (GNUNET_ERROR_TYPE_DEBUG, "* Queue send (max %u)\n", size);
893
894   if (NULL == buf || 0 == size)
895   {
896     LOG (GNUNET_ERROR_TYPE_DEBUG, "* Buffer size 0.\n");
897     return 0;
898   }
899
900   /* Initialize */
901   queue = peer_get_first_message (peer);
902   if (NULL == queue)
903   {
904     GNUNET_break (0); /* Core tmt_rdy should've been canceled */
905     return 0;
906   }
907   c = queue->c;
908   fwd = queue->fwd;
909   fc = fwd ? &c->fwd_fc : &c->bck_fc;
910
911   dst_id = GNUNET_PEER_resolve2 (peer->id);
912   LOG (GNUNET_ERROR_TYPE_DEBUG, "*   towards %s\n", GNUNET_i2s (dst_id));
913   /* Check if buffer size is enough for the message */
914   if (queue->size > size)
915   {
916       LOG (GNUNET_ERROR_TYPE_DEBUG, "*   not enough room, reissue\n");
917       peer->core_transmit =
918           GNUNET_CORE_notify_transmit_ready (core_handle,
919                                              GNUNET_NO,
920                                              0,
921                                              GNUNET_TIME_UNIT_FOREVER_REL,
922                                              dst_id,
923                                              queue->size,
924                                              &queue_send,
925                                              peer);
926       return 0;
927   }
928   LOG (GNUNET_ERROR_TYPE_DEBUG, "*   size %u ok\n", queue->size);
929
930   t = (NULL != c) ? c->t : NULL;
931   type = 0;
932
933   /* Fill buf */
934   switch (queue->type)
935   {
936     case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
937     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
938     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
939     case GNUNET_MESSAGE_TYPE_MESH_FWD:
940     case GNUNET_MESSAGE_TYPE_MESH_BCK:
941     case GNUNET_MESSAGE_TYPE_MESH_ACK:
942     case GNUNET_MESSAGE_TYPE_MESH_POLL:
943       LOG (GNUNET_ERROR_TYPE_DEBUG,
944                   "*   raw: %s\n",
945                   GNUNET_MESH_DEBUG_M2S (queue->type));
946       data_size = send_core_data_raw (queue->cls, size, buf);
947       msg = (struct GNUNET_MessageHeader *) buf;
948       type = ntohs (msg->type);
949       break;
950     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
951       LOG (GNUNET_ERROR_TYPE_DEBUG, "*   path create\n");
952       if (GMC_is_origin (c, GNUNET_YES))
953         data_size = send_core_connection_create (queue->c, size, buf);
954       else
955         data_size = send_core_data_raw (queue->cls, size, buf);
956       break;
957     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
958       LOG (GNUNET_ERROR_TYPE_DEBUG, "*   path ack\n");
959       if (GMC_is_origin (c, GNUNET_NO) ||
960           GMC_is_origin (c, GNUNET_YES))
961         data_size = send_core_connection_ack (queue->c, size, buf);
962       else
963         data_size = send_core_data_raw (queue->cls, size, buf);
964       break;
965     case GNUNET_MESSAGE_TYPE_MESH_DATA:
966     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
967     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
968       /* This should be encapsulted */
969       GNUNET_break (0);
970       data_size = 0;
971       break;
972     default:
973       GNUNET_break (0);
974       LOG (GNUNET_ERROR_TYPE_WARNING, "*   type unknown: %u\n",
975                   queue->type);
976       data_size = 0;
977   }
978
979   if (0 < drop_percent &&
980       GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 101) < drop_percent)
981   {
982     LOG (GNUNET_ERROR_TYPE_WARNING,
983                 "Dropping message of type %s\n",
984                 GNUNET_MESH_DEBUG_M2S (queue->type));
985     data_size = 0;
986   }
987
988   /* Free queue, but cls was freed by send_core_* */
989   ch = queue->ch;
990   queue_destroy (queue, GNUNET_NO);
991
992   /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
993   switch (type)
994   {
995     case GNUNET_MESSAGE_TYPE_MESH_FWD:
996     case GNUNET_MESSAGE_TYPE_MESH_BCK:
997       pid = ntohl ( ((struct GNUNET_MESH_Encrypted *) buf)->pid );
998       LOG (GNUNET_ERROR_TYPE_DEBUG, "*   accounting pid %u\n", pid);
999       fc->last_pid_sent = pid;
1000       send_ack (c, ch, fwd);
1001       break;
1002     default:
1003       break;
1004   }
1005
1006   /* If more data in queue, send next */
1007   queue = peer_get_first_message (peer);
1008   if (NULL != queue)
1009   {
1010     LOG (GNUNET_ERROR_TYPE_DEBUG, "*   more data!\n");
1011     if (NULL == peer->core_transmit) {
1012       peer->core_transmit =
1013           GNUNET_CORE_notify_transmit_ready(core_handle,
1014                                             0,
1015                                             0,
1016                                             GNUNET_TIME_UNIT_FOREVER_REL,
1017                                             dst_id,
1018                                             queue->size,
1019                                             &queue_send,
1020                                             peer);
1021     }
1022     else
1023     {
1024       LOG (GNUNET_ERROR_TYPE_DEBUG,
1025                   "*   tmt rdy called somewhere else\n");
1026     }
1027     if (GNUNET_SCHEDULER_NO_TASK == fc->poll_task)
1028     {
1029       LOG (GNUNET_ERROR_TYPE_DEBUG, "*   starting poll timeout\n");
1030       fc->poll_task =
1031           GNUNET_SCHEDULER_add_delayed (fc->poll_time, &connection_poll, fc);
1032     }
1033   }
1034   else
1035   {
1036     if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task)
1037     {
1038       GNUNET_SCHEDULER_cancel (fc->poll_task);
1039       fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
1040     }
1041   }
1042   if (NULL != c)
1043   {
1044     c->pending_messages--;
1045     if (GNUNET_YES == c->destroy && 0 == c->pending_messages)
1046     {
1047       LOG (GNUNET_ERROR_TYPE_DEBUG, "*  destroying connection!\n");
1048       GMC_destroy (c);
1049     }
1050   }
1051
1052   if (NULL != t)
1053   {
1054     t->pending_messages--;
1055     if (GNUNET_YES == t->destroy && 0 == t->pending_messages)
1056     {
1057 //       LOG (GNUNET_ERROR_TYPE_DEBUG, "*  destroying tunnel!\n");
1058       tunnel_destroy (t);
1059     }
1060   }
1061   LOG (GNUNET_ERROR_TYPE_DEBUG, "*  Return %d\n", data_size);
1062   return data_size;
1063 }
1064
1065
1066
1067 /**
1068  * Get first sendable message.
1069  *
1070  * @param peer The destination peer.
1071  *
1072  * @return Best current known path towards the peer, if any.
1073  */
1074 static struct MeshPeerQueue *
1075 peer_get_first_message (const struct MeshPeer *peer)
1076 {
1077   struct MeshPeerQueue *q;
1078
1079   for (q = peer->queue_head; NULL != q; q = q->next)
1080   {
1081     if (queue_is_sendable (q))
1082       return q;
1083   }
1084
1085   return NULL;
1086 }
1087
1088
1089 static int
1090 queue_is_sendable (struct MeshPeerQueue *q)
1091 {
1092   struct MeshFlowControl *fc;
1093
1094   /* Is PID-independent? */
1095   switch (q->type)
1096   {
1097     case GNUNET_MESSAGE_TYPE_MESH_ACK:
1098     case GNUNET_MESSAGE_TYPE_MESH_POLL:
1099       return GNUNET_YES;
1100   }
1101
1102   /* Is PID allowed? */
1103   fc = q->fwd ? &q->c->fwd_fc : &q->c->bck_fc;
1104   if (GMC_is_pid_bigger (fc->last_ack_recv, fc->last_pid_sent))
1105     return GNUNET_YES;
1106
1107   return GNUNET_NO;
1108 }
1109
1110
1111 /******************************************************************************/
1112 /********************************    API    ***********************************/
1113 /******************************************************************************/
1114
1115
1116 /**
1117  * Free a transmission that was already queued with all resources
1118  * associated to the request.
1119  *
1120  * @param queue Queue handler to cancel.
1121  * @param clear_cls Is it necessary to free associated cls?
1122  */
1123 void
1124 GMP_queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
1125 {
1126   struct MeshPeer *peer;
1127   struct MeshFlowControl *fc;
1128   int fwd;
1129
1130   fwd = queue->fwd;
1131   peer = queue->peer;
1132   GNUNET_assert (NULL != queue->c);
1133   fc = fwd ? &queue->c->fwd_fc : &queue->c->bck_fc;
1134
1135   if (GNUNET_YES == clear_cls)
1136   {
1137     LOG (GNUNET_ERROR_TYPE_DEBUG, "   queue destroy type %s\n",
1138                 GNUNET_MESH_DEBUG_M2S (queue->type));
1139     switch (queue->type)
1140     {
1141       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
1142       case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
1143         LOG (GNUNET_ERROR_TYPE_INFO, "destroying a DESTROY message\n");
1144         GNUNET_break (GNUNET_YES == queue->c->destroy);
1145         /* fall through */
1146       case GNUNET_MESSAGE_TYPE_MESH_FWD:
1147       case GNUNET_MESSAGE_TYPE_MESH_BCK:
1148       case GNUNET_MESSAGE_TYPE_MESH_ACK:
1149       case GNUNET_MESSAGE_TYPE_MESH_POLL:
1150       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
1151       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
1152       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
1153         LOG (GNUNET_ERROR_TYPE_DEBUG, "   prebuilt message\n");;
1154         GNUNET_free_non_null (queue->cls);
1155         break;
1156
1157       default:
1158         GNUNET_break (0);
1159         LOG (GNUNET_ERROR_TYPE_ERROR, "   type %s unknown!\n",
1160                     GNUNET_MESH_DEBUG_M2S (queue->type));
1161     }
1162
1163   }
1164   GNUNET_CONTAINER_DLL_remove (peer->queue_head, peer->queue_tail, queue);
1165
1166   if (queue->type != GNUNET_MESSAGE_TYPE_MESH_ACK &&
1167       queue->type != GNUNET_MESSAGE_TYPE_MESH_POLL)
1168   {
1169     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Q_N- %p %u\n", fc, fc->queue_n);
1170     fc->queue_n--;
1171     peer->queue_n--;
1172   }
1173   if (NULL != queue->c)
1174   {
1175     queue->c->pending_messages--;
1176     if (NULL != queue->c->t)
1177     {
1178       queue->c->t->pending_messages--;
1179     }
1180   }
1181
1182   GNUNET_free (queue);
1183 }
1184
1185
1186 /**
1187  * @brief Queue and pass message to core when possible.
1188  *
1189  * @param cls Closure (@c type dependant). It will be used by queue_send to
1190  *            build the message to be sent if not already prebuilt.
1191  * @param type Type of the message, 0 for a raw message.
1192  * @param size Size of the message.
1193  * @param c Connection this message belongs to (cannot be NULL).
1194  * @param ch Channel this message belongs to, if applicable (otherwise NULL).
1195  * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!)
1196  */
1197 void
1198 GMP_queue_add (void *cls, uint16_t type, size_t size, 
1199                struct MeshConnection *c,
1200                struct MeshChannel *ch,
1201                int fwd)
1202 {
1203   struct MeshPeerQueue *queue;
1204   struct MeshFlowControl *fc;
1205   struct MeshPeer *peer;
1206   int priority;
1207   int call_core;
1208
1209   LOG (GNUNET_ERROR_TYPE_DEBUG,
1210               "queue add %s %s (%u) on c %p, ch %p\n",
1211               fwd ? "FWD" : "BCK",  GNUNET_MESH_DEBUG_M2S (type), size, c, ch);
1212   GNUNET_assert (NULL != c);
1213
1214   fc   = fwd ? &c->fwd_fc : &c->bck_fc;
1215   peer = fwd ? connection_get_next_hop (c) : connection_get_prev_hop (c);
1216
1217   if (NULL == fc)
1218   {
1219     GNUNET_break (0);
1220     return;
1221   }
1222
1223   if (NULL == peer->connections)
1224   {
1225     /* We are not connected to this peer, ignore request. */
1226     GNUNET_break_op (0);
1227     return;
1228   }
1229
1230   priority = 0;
1231
1232   if (GNUNET_MESSAGE_TYPE_MESH_POLL == type ||
1233       GNUNET_MESSAGE_TYPE_MESH_ACK == type)
1234   {
1235     priority = 100;
1236   }
1237
1238   LOG (GNUNET_ERROR_TYPE_DEBUG, "priority %d\n", priority);
1239   LOG (GNUNET_ERROR_TYPE_DEBUG, "fc %p\n", fc);
1240   if (fc->queue_n >= fc->queue_max && 0 == priority)
1241   {
1242     GNUNET_STATISTICS_update (stats, "# messages dropped (buffer full)",
1243                               1, GNUNET_NO);
1244     GNUNET_break (0);
1245     LOG (GNUNET_ERROR_TYPE_DEBUG,
1246                 "queue full: %u/%u\n",
1247                 fc->queue_n, fc->queue_max);
1248     return; /* Drop this message */
1249   }
1250
1251   LOG (GNUNET_ERROR_TYPE_DEBUG, "last pid %u\n", fc->last_pid_sent);
1252   LOG (GNUNET_ERROR_TYPE_DEBUG, "     ack %u\n", fc->last_ack_recv);
1253   if (GMC_is_pid_bigger (fc->last_pid_sent + 1, fc->last_ack_recv))
1254   {
1255     call_core = GNUNET_NO;
1256     if (GNUNET_SCHEDULER_NO_TASK == fc->poll_task &&
1257         GNUNET_MESSAGE_TYPE_MESH_POLL != type)
1258     {
1259       LOG (GNUNET_ERROR_TYPE_DEBUG,
1260                   "no buffer space (%u > %u): starting poll\n",
1261                   fc->last_pid_sent + 1, fc->last_ack_recv);
1262       fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
1263                                                     &connection_poll,
1264                                                     fc);
1265     }
1266   }
1267   else
1268     call_core = GNUNET_YES;
1269   queue = GNUNET_malloc (sizeof (struct MeshPeerQueue));
1270   queue->cls = cls;
1271   queue->type = type;
1272   queue->size = size;
1273   queue->peer = peer;
1274   queue->c = c;
1275   queue->ch = ch;
1276   queue->fwd = fwd;
1277   if (100 <= priority)
1278   {
1279     struct MeshPeerQueue *copy;
1280     struct MeshPeerQueue *next;
1281
1282     for (copy = peer->queue_head; NULL != copy; copy = next)
1283     {
1284       next = copy->next;
1285       if (copy->type == type && copy->c == c && copy->fwd == fwd)
1286       {
1287         /* Example: also a FWD ACK for connection XYZ */
1288         queue_destroy (copy, GNUNET_YES);
1289       }
1290     }
1291     GNUNET_CONTAINER_DLL_insert (peer->queue_head, peer->queue_tail, queue);
1292   }
1293   else
1294   {
1295     GNUNET_CONTAINER_DLL_insert_tail (peer->queue_head, peer->queue_tail, queue);
1296     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Q_N+ %p %u\n", fc, fc->queue_n);
1297     fc->queue_n++;
1298     peer->queue_n++;
1299   }
1300
1301   if (NULL == peer->core_transmit && GNUNET_YES == call_core)
1302   {
1303     LOG (GNUNET_ERROR_TYPE_DEBUG,
1304                 "calling core tmt rdy towards %s for %u bytes\n",
1305                 peer2s (peer), size);
1306     peer->core_transmit =
1307         GNUNET_CORE_notify_transmit_ready (core_handle,
1308                                            0,
1309                                            0,
1310                                            GNUNET_TIME_UNIT_FOREVER_REL,
1311                                            GNUNET_PEER_resolve2 (peer->id),
1312                                            size,
1313                                            &queue_send,
1314                                            peer);
1315   }
1316   else
1317   {
1318     LOG (GNUNET_ERROR_TYPE_DEBUG,
1319                 "core tmt rdy towards %s already called\n",
1320                 peer2s (peer));
1321
1322   }
1323   c->pending_messages++;
1324   if (NULL != c->t)
1325     c->t->pending_messages++;
1326 }
1327
1328
1329
1330 /**
1331  * Initialize the peer subsystem.
1332  *
1333  * @param c Configuration.
1334  * @param id Peer identity
1335  */
1336 void
1337 GMP_init (const struct GNUNET_CONFIGURATION_Handle *c,
1338           const struct GNUNET_PeerIdentity *id)
1339 {
1340   my_full_id = id;
1341   peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
1342   if (GNUNET_OK !=
1343       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_PEERS",
1344                                              &max_peers))
1345   {
1346     LOG_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1347                                "MESH", "MAX_PEERS", "USING DEFAULT");
1348     max_peers = 1000;
1349   }
1350
1351   if (GNUNET_OK !=
1352       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DROP_PERCENT",
1353                                              &drop_percent))
1354   {
1355     drop_percent = 0;
1356   }
1357   else
1358   {
1359     LOG (GNUNET_ERROR_TYPE_WARNING,
1360                 "\n***************************************\n"
1361                 "Mesh is running with drop mode enabled.\n"
1362                 "This is NOT a good idea!\n"
1363                 "Remove the DROP_PERCENT option from your configuration.\n"
1364                 "***************************************\n");
1365   }
1366
1367   core_handle = GNUNET_CORE_connect (c, /* Main configuration */
1368                                      NULL,      /* Closure passed to MESH functions */
1369                                      &core_init,        /* Call core_init once connected */
1370                                      &core_connect,     /* Handle connects */
1371                                      &core_disconnect,  /* remove peers on disconnects */
1372                                      NULL,      /* Don't notify about all incoming messages */
1373                                      GNUNET_NO, /* For header only in notification */
1374                                      NULL,      /* Don't notify about all outbound messages */
1375                                      GNUNET_NO, /* For header-only out notification */
1376                                      core_handlers);    /* Register these handlers */
1377   if (NULL == core_handle)
1378   {
1379     GNUNET_break (0);
1380     GNUNET_SCHEDULER_shutdown ();
1381     return;
1382   }
1383 }
1384
1385 /**
1386  * Shut down the peer subsystem.
1387  */
1388 void
1389 GMP_shutdown (void)
1390 {
1391   GNUNET_CONTAINER_multipeermap_iterate (peers, &shutdown_tunnel, NULL);
1392
1393   if (core_handle != NULL)
1394   {
1395     GNUNET_CORE_disconnect (core_handle);
1396     core_handle = NULL;
1397   }
1398 }
1399
1400
1401 /**
1402  * Try to establish a new connection to this peer in the given tunnel.
1403  * If the peer doesn't have any path to it yet, try to get one.
1404  * If the peer already has some path, send a CREATE CONNECTION towards it.
1405  *
1406  * @param peer PeerInfo of the peer.
1407  */
1408 void
1409 GMP_connect (struct MeshPeer *peer)
1410 {
1411   struct MeshTunnel2 *t;
1412   struct MeshPeerPath *p;
1413   struct MeshConnection *c;
1414   int rerun_search;
1415
1416   LOG (GNUNET_ERROR_TYPE_DEBUG,
1417               "peer_connect towards %s\n",
1418               peer2s (peer));
1419   t = peer->tunnel;
1420   c = NULL;
1421   rerun_search = GNUNET_NO;
1422
1423   if (NULL != peer->path_head)
1424   {
1425     LOG (GNUNET_ERROR_TYPE_DEBUG, "path exists\n");
1426     p = peer_get_best_path (peer);
1427     if (NULL != p)
1428     {
1429       LOG (GNUNET_ERROR_TYPE_DEBUG, "  %u hops\n", p->length);
1430       c = tunnel_use_path (t, p);
1431       if (NULL == c)
1432       {
1433         /* This case can happen when the path includes a first hop that is
1434          * not yet known to be connected.
1435          *
1436          * This happens quite often during testing when running mesh
1437          * under valgrind: core connect notifications come very late and the
1438          * DHT result has already come and created a valid path.
1439          * In this case, the peer->connections hashmap will be NULL and
1440          * tunnel_use_path will not be able to create a connection from that
1441          * path.
1442          *
1443          * Re-running the DHT GET should give core time to callback.
1444          */
1445         GNUNET_break(0);
1446                 rerun_search = GNUNET_YES;
1447       }
1448       else
1449       {
1450         send_connection_create (c);
1451         return;
1452       }
1453     }
1454   }
1455
1456   if (NULL != peer->search_h && GNUNET_YES == rerun_search)
1457   {
1458     GMD_search_stop (peer->search_h);
1459     peer->search_h = NULL;
1460     LOG (GNUNET_ERROR_TYPE_DEBUG,
1461                 "  Stopping DHT GET for peer %s\n", peer2s (peer));
1462   }
1463
1464   if (NULL == peer->search_h)
1465   {
1466     const struct GNUNET_PeerIdentity *id;
1467
1468     id = GNUNET_PEER_resolve2 (peer->id);
1469     LOG (GNUNET_ERROR_TYPE_DEBUG,
1470                 "  Starting DHT GET for peer %s\n", peer2s (peer));
1471     peer->search_h = GMD_search (id, &search_handler, peer);
1472     if (MESH_TUNNEL_NEW == t->state)
1473       GMT_change_state (t, MESH_TUNNEL_SEARCHING);
1474   }
1475 }
1476
1477
1478 /**
1479  * Set tunnel.
1480  *
1481  * @param peer Peer.
1482  * @param t Tunnel.
1483  */
1484 void
1485 GMP_set_tunnel (struct MeshPeer *peer, struct MeshTunnel2 *t)
1486 {
1487   peer->tunnel = t;
1488 }
1489
1490
1491 /**
1492  * Chech whether there is a direct (core level)  connection to peer.
1493  *
1494  * @param peer Peer to check.
1495  *
1496  * @return GNUNET_YES if there is a direct connection.
1497  */
1498 int
1499 GMP_is_neighbor (const struct MeshPeer *peer)
1500 {
1501   struct MeshPeerPath *path;
1502
1503   if (NULL == peer->connections)
1504     return GNUNET_NO;
1505
1506   for (path = peer->path_head; NULL != path; path = path->next)
1507   {
1508     if (3 > path->length)
1509       return GNUNET_YES;
1510   }
1511
1512   GNUNET_break (0); /* Is not a neighbor but connections is not NULL */
1513   return GNUNET_NO;
1514 }
1515
1516
1517 /**
1518  * Add a connection to a neighboring peer.
1519  *
1520  * Store that the peer is the first hop of the connection in one
1521  * direction and that on peer disconnect the connection must be
1522  * notified and destroyed, for it will no longer be valid.
1523  *
1524  * @param peer Peer to add connection to.
1525  * @param c Connection to add.
1526  *
1527  * @return GNUNET_OK on success.
1528  */
1529 int
1530 GMP_add_connection (struct MeshPeer *peer,
1531                     const struct MeshConnection *c)
1532 {
1533   if (NULL == peer->connections)
1534   {
1535     GNUNET_break (0);
1536     return GNUNET_SYSERR;
1537   }
1538   return GNUNET_CONTAINER_multihashmap_put (peer->connections,
1539                                             GMC_get_id (c),
1540                                             c,
1541                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1542 }
1543
1544 /**
1545  * Get the static string for a peer ID.
1546  *
1547  * @param peer Peer.
1548  *
1549  * @return Static string for it's ID.
1550  */
1551 const char *
1552 GMP_2s (const struct MeshPeer *peer)
1553 {
1554   if (NULL == peer)
1555     return "(NULL)";
1556   return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
1557 }