- log checksum error (for #3333)
[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_transport_service.h"
26 #include "gnunet_core_service.h"
27 #include "gnunet_statistics_service.h"
28
29 #include "mesh_protocol.h"
30
31 #include "gnunet-service-mesh_peer.h"
32 #include "gnunet-service-mesh_dht.h"
33 #include "gnunet-service-mesh_connection.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 info about a queued transmission to this peer
45  */
46 struct MeshPeerQueue
47 {
48     /**
49       * DLL next
50       */
51   struct MeshPeerQueue *next;
52
53     /**
54       * DLL previous
55       */
56   struct MeshPeerQueue *prev;
57
58     /**
59      * Peer this transmission is directed to.
60      */
61   struct MeshPeer *peer;
62
63     /**
64      * Connection this message belongs to.
65      */
66   struct MeshConnection *c;
67
68     /**
69      * Is FWD in c?
70      */
71   int fwd;
72
73     /**
74      * Pointer to info stucture used as cls.
75      */
76   void *cls;
77
78     /**
79      * Type of message
80      */
81   uint16_t type;
82
83     /**
84      * Size of the message
85      */
86   size_t size;
87
88     /**
89      * Set when this message starts waiting for CORE.
90      */
91   struct GNUNET_TIME_Absolute start_waiting;
92
93     /**
94      * Function to call on sending.
95      */
96   GMP_sent callback;
97
98     /**
99      * Closure for callback.
100      */
101   void *callback_cls;
102 };
103
104 /**
105  * Struct containing all information regarding a given peer
106  */
107 struct MeshPeer
108 {
109     /**
110      * ID of the peer
111      */
112   GNUNET_PEER_Id id;
113
114     /**
115      * Last time we heard from this peer
116      */
117   struct GNUNET_TIME_Absolute last_contact;
118
119     /**
120      * Paths to reach the peer, ordered by ascending hop count
121      */
122   struct MeshPeerPath *path_head;
123
124     /**
125      * Paths to reach the peer, ordered by ascending hop count
126      */
127   struct MeshPeerPath *path_tail;
128
129     /**
130      * Handle to stop the DHT search for paths to this peer
131      */
132   struct GMD_search_handle *search_h;
133
134     /**
135      * Tunnel to this peer, if any.
136      */
137   struct MeshTunnel3 *tunnel;
138
139     /**
140      * Connections that go through this peer, indexed by tid;
141      */
142   struct GNUNET_CONTAINER_MultiHashMap *connections;
143
144     /**
145      * Handle for queued transmissions
146      */
147   struct GNUNET_CORE_TransmitHandle *core_transmit;
148
149   /**
150    * Transmission queue to core DLL head
151    */
152   struct MeshPeerQueue *queue_head;
153
154   /**
155    * Transmission queue to core DLL tail
156    */
157   struct MeshPeerQueue *queue_tail;
158
159   /**
160    * How many messages are in the queue to this peer.
161    */
162   unsigned int queue_n;
163
164   /**
165    * Hello message.
166    */
167   struct GNUNET_HELLO_Message* hello;
168 };
169
170
171 /******************************************************************************/
172 /*******************************   GLOBALS  ***********************************/
173 /******************************************************************************/
174
175 /**
176  * Global handle to the statistics service.
177  */
178 extern struct GNUNET_STATISTICS_Handle *stats;
179
180 /**
181  * Local peer own ID (full value).
182  */
183 extern struct GNUNET_PeerIdentity my_full_id;
184
185 /**
186  * Local peer own ID (short)
187  */
188 extern GNUNET_PEER_Id myid;
189
190 /**
191  * Peers known, indexed by PeerIdentity (MeshPeer).
192  */
193 static struct GNUNET_CONTAINER_MultiPeerMap *peers;
194
195 /**
196  * How many peers do we want to remember?
197  */
198 static unsigned long long max_peers;
199
200 /**
201  * Percentage of messages that will be dropped (for test purposes only).
202  */
203 static unsigned long long drop_percent;
204
205 /**
206  * Handle to communicate with core.
207  */
208 static struct GNUNET_CORE_Handle *core_handle;
209
210 /**
211  * Handle to try to start new connections.
212  */
213 static struct GNUNET_TRANSPORT_Handle *transport_handle;
214
215 /******************************************************************************/
216 /***************************** CORE CALLBACKS *********************************/
217 /******************************************************************************/
218
219
220 /**
221  * Iterator to notify all connections of a broken link. Mark connections
222  * to destroy after all traffic has been sent.
223  *
224  * @param cls Closure (peer disconnected).
225  * @param key Current key code (peer id).
226  * @param value Value in the hash map (connection).
227  *
228  * @return #GNUNET_YES to continue to iterate.
229  */
230 static int
231 notify_broken (void *cls,
232                const struct GNUNET_HashCode *key,
233                void *value)
234 {
235   struct MeshPeer *peer = cls;
236   struct MeshConnection *c = value;
237
238   LOG (GNUNET_ERROR_TYPE_DEBUG, "  notifying %s due to %s\n",
239        GMC_2s (c), GMP_2s (peer));
240   GMC_notify_broken (c, peer);
241
242   return GNUNET_YES;
243 }
244
245
246 /**
247  * Remove the direct path to the peer.
248  *
249  * @param peer Peer to remove the direct path from.
250  *
251  */
252 static struct MeshPeerPath *
253 pop_direct_path (struct MeshPeer *peer)
254 {
255   struct MeshPeerPath *iter;
256
257   for (iter = peer->path_head; NULL != iter; iter = iter->next)
258   {
259     if (2 <= iter->length)
260     {
261       GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, iter);
262       return iter;
263     }
264   }
265   return NULL;
266 }
267
268
269
270 /**
271  * Method called whenever a given peer connects.
272  *
273  * @param cls closure
274  * @param peer peer identity this notification is about
275  */
276 static void
277 core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
278 {
279   struct MeshPeer *mp;
280   struct MeshPeerPath *path;
281   char own_id[16];
282
283   strncpy (own_id, GNUNET_i2s (&my_full_id), 15);
284   mp = GMP_get (peer);
285   if (myid == mp->id)
286   {
287     LOG (GNUNET_ERROR_TYPE_INFO, "CONNECTED %s (self)\n", own_id);
288     path = path_new (1);
289   }
290   else
291   {
292     LOG (GNUNET_ERROR_TYPE_INFO, "CONNECTED %s <= %s\n",
293          own_id, GNUNET_i2s (peer));
294     path = path_new (2);
295     path->peers[1] = mp->id;
296     GNUNET_PEER_change_rc (mp->id, 1);
297     GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
298   }
299   path->peers[0] = myid;
300   GNUNET_PEER_change_rc (myid, 1);
301   GMP_add_path (mp, path, GNUNET_YES);
302
303   mp->connections = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_YES);
304   return;
305 }
306
307
308 /**
309  * Method called whenever a peer disconnects.
310  *
311  * @param cls closure
312  * @param peer peer identity this notification is about
313  */
314 static void
315 core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
316 {
317   struct MeshPeer *p;
318   struct MeshPeerPath *direct_path;
319   char own_id[16];
320
321   strncpy (own_id, GNUNET_i2s (&my_full_id), 15);
322   p = GNUNET_CONTAINER_multipeermap_get (peers, peer);
323   if (NULL == p)
324   {
325     GNUNET_break (0);
326     return;
327   }
328   if (myid == p->id)
329     LOG (GNUNET_ERROR_TYPE_INFO, "DISCONNECTED %s (self)\n", own_id);
330   else
331     LOG (GNUNET_ERROR_TYPE_DEBUG, "DISCONNECTED %s <= %s\n",
332          own_id, GNUNET_i2s (peer));
333   direct_path = pop_direct_path (p);
334   GNUNET_CONTAINER_multihashmap_iterate (p->connections, &notify_broken, p);
335   GNUNET_CONTAINER_multihashmap_destroy (p->connections);
336   p->connections = NULL;
337   if (NULL != p->core_transmit)
338     {
339       GNUNET_CORE_notify_transmit_ready_cancel (p->core_transmit);
340       p->core_transmit = NULL;
341     }
342   GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
343
344   path_destroy (direct_path);
345   return;
346 }
347
348
349 /**
350  * Functions to handle messages from core
351  */
352 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
353   {&GMC_handle_create, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE, 0},
354   {&GMC_handle_confirm, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK,
355     sizeof (struct GNUNET_MESH_ConnectionACK)},
356   {&GMC_handle_broken, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN,
357     sizeof (struct GNUNET_MESH_ConnectionBroken)},
358   {&GMC_handle_destroy, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY,
359     sizeof (struct GNUNET_MESH_ConnectionDestroy)},
360   {&GMC_handle_ack, GNUNET_MESSAGE_TYPE_MESH_ACK,
361     sizeof (struct GNUNET_MESH_ACK)},
362   {&GMC_handle_poll, GNUNET_MESSAGE_TYPE_MESH_POLL,
363     sizeof (struct GNUNET_MESH_Poll)},
364   {&GMC_handle_encrypted, GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED, 0},
365   {&GMC_handle_kx, GNUNET_MESSAGE_TYPE_MESH_KX, 0},
366   {NULL, 0, 0}
367 };
368
369
370 /**
371  * To be called on core init/fail.
372  *
373  * @param cls Closure (config)
374  * @param identity the public identity of this peer
375  */
376 static void
377 core_init (void *cls,
378            const struct GNUNET_PeerIdentity *identity)
379 {
380   const struct GNUNET_CONFIGURATION_Handle *c = cls;
381   static int i = 0;
382
383   LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
384   if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)))
385   {
386     LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
387     LOG (GNUNET_ERROR_TYPE_ERROR, " core id %s\n", GNUNET_i2s (identity));
388     LOG (GNUNET_ERROR_TYPE_ERROR, " my id %s\n", GNUNET_i2s (&my_full_id));
389     GNUNET_CORE_disconnect (core_handle);
390     core_handle = GNUNET_CORE_connect (c, /* Main configuration */
391                                        NULL,      /* Closure passed to MESH functions */
392                                        &core_init,        /* Call core_init once connected */
393                                        &core_connect,     /* Handle connects */
394                                        &core_disconnect,  /* remove peers on disconnects */
395                                        NULL,      /* Don't notify about all incoming messages */
396                                        GNUNET_NO, /* For header only in notification */
397                                        NULL,      /* Don't notify about all outbound messages */
398                                        GNUNET_NO, /* For header-only out notification */
399                                        core_handlers);    /* Register these handlers */
400     if (10 < i++)
401       GNUNET_abort();
402   }
403   GML_start ();
404   return;
405 }
406
407 /**
408   * Core callback to write a pre-constructed data packet to core buffer
409   *
410   * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
411   * @param size Number of bytes available in buf.
412   * @param buf Where the to write the message.
413   *
414   * @return number of bytes written to buf
415   */
416 static size_t
417 send_core_data_raw (void *cls, size_t size, void *buf)
418 {
419   struct GNUNET_MessageHeader *msg = cls;
420   size_t total_size;
421
422   GNUNET_assert (NULL != msg);
423   total_size = ntohs (msg->size);
424
425   if (total_size > size)
426   {
427     GNUNET_break (0);
428     return 0;
429   }
430   memcpy (buf, msg, total_size);
431   GNUNET_free (cls);
432   return total_size;
433 }
434
435
436 /**
437  * Function to send a create connection message to a peer.
438  *
439  * @param c Connection to create.
440  * @param size number of bytes available in buf
441  * @param buf where the callee should write the message
442  * @return number of bytes written to buf
443  */
444 static size_t
445 send_core_connection_create (struct MeshConnection *c, size_t size, void *buf)
446 {
447   struct GNUNET_MESH_ConnectionCreate *msg;
448   struct GNUNET_PeerIdentity *peer_ptr;
449   const struct MeshPeerPath *p = GMC_get_path (c);
450   size_t size_needed;
451   int i;
452
453   if (NULL == p)
454     return 0;
455
456   LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION CREATE...\n");
457   size_needed =
458       sizeof (struct GNUNET_MESH_ConnectionCreate) +
459       p->length * sizeof (struct GNUNET_PeerIdentity);
460
461   if (size < size_needed || NULL == buf)
462   {
463     GNUNET_break (0);
464     return 0;
465   }
466   msg = (struct GNUNET_MESH_ConnectionCreate *) buf;
467   msg->header.size = htons (size_needed);
468   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE);
469   msg->cid = *GMC_get_id (c);
470
471   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
472   for (i = 0; i < p->length; i++)
473   {
474     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
475   }
476
477   LOG (GNUNET_ERROR_TYPE_DEBUG,
478        "CONNECTION CREATE (%u bytes long) sent!\n",
479        size_needed);
480   return size_needed;
481 }
482
483
484 /**
485  * Creates a path ack message in buf and frees all unused resources.
486  *
487  * @param c Connection to send an ACK on.
488  * @param size number of bytes available in buf
489  * @param buf where the callee should write the message
490  *
491  * @return number of bytes written to buf
492  */
493 static size_t
494 send_core_connection_ack (struct MeshConnection *c, size_t size, void *buf)
495 {
496   struct GNUNET_MESH_ConnectionACK *msg = buf;
497
498   LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION ACK...\n");
499   if (sizeof (struct GNUNET_MESH_ConnectionACK) > size)
500   {
501     GNUNET_break (0);
502     return 0;
503   }
504   msg->header.size = htons (sizeof (struct GNUNET_MESH_ConnectionACK));
505   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK);
506   msg->cid = *GMC_get_id (c);
507
508   LOG (GNUNET_ERROR_TYPE_DEBUG, "CONNECTION ACK sent!\n");
509   return sizeof (struct GNUNET_MESH_ConnectionACK);
510 }
511
512
513 /******************************************************************************/
514 /********************************   STATIC  ***********************************/
515 /******************************************************************************/
516
517
518 /**
519  * Get priority for a queued message.
520  *
521  * @param q Queued message
522  *
523  * @return CORE priority to use.
524  */
525 static enum GNUNET_CORE_Priority
526 get_priority (struct MeshPeerQueue *q)
527 {
528   enum GNUNET_CORE_Priority low;
529   enum GNUNET_CORE_Priority high;
530
531   if (NULL == q)
532   {
533     GNUNET_break (0);
534     return GNUNET_CORE_PRIO_BACKGROUND;
535   }
536
537   /* Relayed traffic has lower priority, our own traffic has higher */
538   if (NULL == q->c || GNUNET_NO == GMC_is_origin (q->c, q->fwd))
539   {
540     low = GNUNET_CORE_PRIO_BEST_EFFORT;
541     high = GNUNET_CORE_PRIO_URGENT;
542   }
543   else
544   {
545     low = GNUNET_CORE_PRIO_URGENT;
546     high = GNUNET_CORE_PRIO_CRITICAL_CONTROL;
547   }
548
549   /* Bulky payload has lower priority, control traffic has higher. */
550   if (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED == q->type)
551     return low;
552   else
553     return high;
554 }
555
556
557 /**
558  * Iterator over tunnel hash map entries to destroy the tunnel during shutdown.
559  *
560  * @param cls closure
561  * @param key current key code
562  * @param value value in the hash map
563  * @return #GNUNET_YES if we should continue to iterate,
564  *         #GNUNET_NO if not.
565  */
566 static int
567 shutdown_tunnel (void *cls,
568                  const struct GNUNET_PeerIdentity *key,
569                  void *value)
570 {
571   struct MeshPeer *p = value;
572   struct MeshTunnel3 *t = p->tunnel;
573
574   if (NULL != t)
575     GMT_destroy (t);
576   return GNUNET_YES;
577 }
578
579
580 /**
581  * Destroy the peer_info and free any allocated resources linked to it
582  *
583  * @param peer The peer_info to destroy.
584  *
585  * @return GNUNET_OK on success
586  */
587 static int
588 peer_destroy (struct MeshPeer *peer)
589 {
590   struct GNUNET_PeerIdentity id;
591   struct MeshPeerPath *p;
592   struct MeshPeerPath *nextp;
593
594   GNUNET_PEER_resolve (peer->id, &id);
595   GNUNET_PEER_change_rc (peer->id, -1);
596
597   LOG (GNUNET_ERROR_TYPE_WARNING, "destroying peer %s\n", GNUNET_i2s (&id));
598
599   if (GNUNET_YES !=
600     GNUNET_CONTAINER_multipeermap_remove (peers, &id, peer))
601   {
602     GNUNET_break (0);
603     LOG (GNUNET_ERROR_TYPE_WARNING, " not in peermap!!\n");
604   }
605   if (NULL != peer->search_h)
606   {
607     GMD_search_stop (peer->search_h);
608   }
609   p = peer->path_head;
610   while (NULL != p)
611   {
612     nextp = p->next;
613     GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, p);
614     path_destroy (p);
615     p = nextp;
616   }
617   GMT_destroy_empty (peer->tunnel);
618   GNUNET_free (peer);
619   return GNUNET_OK;
620 }
621
622
623 /**
624  * Returns if peer is used (has a tunnel or is neighbor).
625  *
626  * @param peer Peer to check.
627  *
628  * @return #GNUNET_YES if peer is in use.
629  */
630 static int
631 peer_is_used (struct MeshPeer *peer)
632 {
633   struct MeshPeerPath *p;
634
635   if (NULL != peer->tunnel)
636     return GNUNET_YES;
637
638   for (p = peer->path_head; NULL != p; p = p->next)
639   {
640     if (p->length < 3)
641       return GNUNET_YES;
642   }
643     return GNUNET_NO;
644 }
645
646
647 /**
648  * Iterator over all the peers to get the oldest timestamp.
649  *
650  * @param cls Closure (unsued).
651  * @param key ID of the peer.
652  * @param value Peer_Info of the peer.
653  */
654 static int
655 peer_get_oldest (void *cls,
656                  const struct GNUNET_PeerIdentity *key,
657                  void *value)
658 {
659   struct MeshPeer *p = value;
660   struct GNUNET_TIME_Absolute *abs = cls;
661
662   /* Don't count active peers */
663   if (GNUNET_YES == peer_is_used (p))
664     return GNUNET_YES;
665
666   if (abs->abs_value_us < p->last_contact.abs_value_us)
667     abs->abs_value_us = p->last_contact.abs_value_us;
668
669   return GNUNET_YES;
670 }
671
672
673 /**
674  * Iterator over all the peers to remove the oldest entry.
675  *
676  * @param cls Closure (unsued).
677  * @param key ID of the peer.
678  * @param value Peer_Info of the peer.
679  */
680 static int
681 peer_timeout (void *cls,
682               const struct GNUNET_PeerIdentity *key,
683               void *value)
684 {
685   struct MeshPeer *p = value;
686   struct GNUNET_TIME_Absolute *abs = cls;
687
688   LOG (GNUNET_ERROR_TYPE_WARNING,
689        "peer %s timeout\n", GNUNET_i2s (key));
690
691   if (p->last_contact.abs_value_us == abs->abs_value_us &&
692       GNUNET_NO == peer_is_used (p))
693   {
694     peer_destroy (p);
695     return GNUNET_NO;
696   }
697     return GNUNET_YES;
698 }
699
700
701 /**
702  * Delete oldest unused peer.
703  */
704 static void
705 peer_delete_oldest (void)
706 {
707   struct GNUNET_TIME_Absolute abs;
708
709   abs = GNUNET_TIME_UNIT_FOREVER_ABS;
710
711   GNUNET_CONTAINER_multipeermap_iterate (peers,
712                                          &peer_get_oldest,
713                                          &abs);
714   GNUNET_CONTAINER_multipeermap_iterate (peers,
715                                          &peer_timeout,
716                                          &abs);
717 }
718
719
720 /**
721  * Choose the best (yet unused) path towards a peer,
722  * considering the tunnel properties.
723  *
724  * @param peer The destination peer.
725  *
726  * @return Best current known path towards the peer, if any.
727  */
728 static struct MeshPeerPath *
729 peer_get_best_path (const struct MeshPeer *peer)
730 {
731   struct MeshPeerPath *best_p;
732   struct MeshPeerPath *p;
733   unsigned int best_cost;
734   unsigned int cost;
735
736   best_cost = UINT_MAX;
737   best_p = NULL;
738   for (p = peer->path_head; NULL != p; p = p->next)
739   {
740     if (GNUNET_YES == GMT_is_path_used (peer->tunnel, p))
741       continue; /* If path is already in use, skip it. */
742
743     if (GNUNET_NO == path_is_valid (p))
744       continue; /* Don't use invalid paths. */
745
746     if ((cost = GMT_get_path_cost (peer->tunnel, p)) < best_cost)
747     {
748       best_cost = cost;
749       best_p = p;
750     }
751   }
752   return best_p;
753 }
754
755
756 static int
757 queue_is_sendable (struct MeshPeerQueue *q)
758 {
759   /* Is PID-independent? */
760   switch (q->type)
761   {
762     case GNUNET_MESSAGE_TYPE_MESH_ACK:
763     case GNUNET_MESSAGE_TYPE_MESH_POLL:
764     case GNUNET_MESSAGE_TYPE_MESH_KX:
765     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
766     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
767     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
768     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
769       return GNUNET_YES;
770
771     case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
772       break;
773
774     default:
775       GNUNET_break (0);
776   }
777
778   return GMC_is_sendable (q->c, q->fwd);
779 }
780
781
782 /**
783  * Get first sendable message.
784  *
785  * @param peer The destination peer.
786  *
787  * @return First transmittable message, if any. Otherwise, NULL.
788  */
789 static struct MeshPeerQueue *
790 peer_get_first_message (const struct MeshPeer *peer)
791 {
792   struct MeshPeerQueue *q;
793
794   for (q = peer->queue_head; NULL != q; q = q->next)
795   {
796     LOG (GNUNET_ERROR_TYPE_DEBUG, "Checking %p towards %s\n", q, GMC_2s (q->c));
797     if (queue_is_sendable (q))
798       return q;
799   }
800
801   return NULL;
802 }
803
804
805 /**
806  * Function to process paths received for a new peer addition. The recorded
807  * paths form the initial tunnel, which can be optimized later.
808  * Called on each result obtained for the DHT search.
809  *
810  * @param cls closure
811  * @param path
812  */
813 static void
814 search_handler (void *cls, const struct MeshPeerPath *path)
815 {
816   struct MeshPeer *peer = cls;
817   unsigned int connection_count;
818
819   GMP_add_path_to_all (path, GNUNET_NO);
820
821   /* Count connections */
822   connection_count = GMT_count_connections (peer->tunnel);
823
824   /* If we already have 3 (or more (?!)) connections, it's enough */
825   if (3 <= connection_count)
826     return;
827
828   if (MESH_TUNNEL3_SEARCHING == GMT_get_cstate (peer->tunnel))
829   {
830     LOG (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
831     GMP_connect (peer);
832   }
833   return;
834 }
835
836
837
838 /**
839  * Core callback to write a queued packet to core buffer
840  *
841  * @param cls Closure (peer info).
842  * @param size Number of bytes available in buf.
843  * @param buf Where the to write the message.
844  *
845  * @return number of bytes written to buf
846  */
847 static size_t
848 queue_send (void *cls, size_t size, void *buf)
849 {
850   struct MeshPeer *peer = cls;
851   struct MeshConnection *c;
852   struct MeshPeerQueue *queue;
853   const struct GNUNET_PeerIdentity *dst_id;
854   size_t data_size;
855
856   peer->core_transmit = NULL;
857   LOG (GNUNET_ERROR_TYPE_DEBUG, "* Queue send towards %s (max %u)\n",
858        GMP_2s (peer), size);
859
860   if (NULL == buf || 0 == size)
861   {
862     LOG (GNUNET_ERROR_TYPE_DEBUG, "* Buffer size 0.\n");
863     return 0;
864   }
865
866   /* Initialize */
867   queue = peer_get_first_message (peer);
868   if (NULL == queue)
869   {
870     GNUNET_assert (0); /* Core tmt_rdy should've been canceled */
871     return 0;
872   }
873   c = queue->c;
874
875   dst_id = GNUNET_PEER_resolve2 (peer->id);
876   LOG (GNUNET_ERROR_TYPE_DEBUG, "*   on connection %s\n", GMC_2s (c));
877   /* Check if buffer size is enough for the message */
878   if (queue->size > size)
879   {
880     LOG (GNUNET_ERROR_TYPE_WARNING, "not enough room (%u vs %u), reissue\n",
881          queue->size, size);
882     peer->core_transmit =
883       GNUNET_CORE_notify_transmit_ready (core_handle,
884                                          GNUNET_NO, get_priority (queue),
885                                          GNUNET_TIME_UNIT_FOREVER_REL,
886                                          dst_id,
887                                          queue->size,
888                                          &queue_send,
889                                          peer);
890     return 0;
891   }
892   LOG (GNUNET_ERROR_TYPE_DEBUG, "*   size %u ok\n", queue->size);
893
894   /* Fill buf */
895   switch (queue->type)
896   {
897     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
898     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
899     case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
900     case GNUNET_MESSAGE_TYPE_MESH_KX:
901     case GNUNET_MESSAGE_TYPE_MESH_ACK:
902     case GNUNET_MESSAGE_TYPE_MESH_POLL:
903       LOG (GNUNET_ERROR_TYPE_DEBUG, "*   raw: %s\n", GM_m2s (queue->type));
904       data_size = send_core_data_raw (queue->cls, size, buf);
905       break;
906     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
907       LOG (GNUNET_ERROR_TYPE_DEBUG, "*   path create\n");
908       if (GMC_is_origin (c, GNUNET_YES))
909         data_size = send_core_connection_create (queue->c, size, buf);
910       else
911         data_size = send_core_data_raw (queue->cls, size, buf);
912       break;
913     case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
914       LOG (GNUNET_ERROR_TYPE_DEBUG, "*   path ack\n");
915       if (GMC_is_origin (c, GNUNET_NO) ||
916           GMC_is_origin (c, GNUNET_YES))
917         data_size = send_core_connection_ack (queue->c, size, buf);
918       else
919         data_size = send_core_data_raw (queue->cls, size, buf);
920       break;
921     case GNUNET_MESSAGE_TYPE_MESH_DATA:
922     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
923     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
924       /* This should be encapsulted */
925       GNUNET_break (0);
926       data_size = 0;
927       break;
928     default:
929       GNUNET_break (0);
930       LOG (GNUNET_ERROR_TYPE_WARNING, "*   type unknown: %u\n", queue->type);
931       data_size = 0;
932   }
933
934   if (0 < drop_percent &&
935       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 101) < drop_percent)
936   {
937     LOG (GNUNET_ERROR_TYPE_WARNING, "DD %s on connection\n",
938          GM_m2s (queue->type), GMC_2s (c));
939     data_size = 0;
940   }
941   else
942   {
943     LOG (GNUNET_ERROR_TYPE_INFO,
944         "ss %s on connection %s (%p) %s (size %u)\n",
945         GM_m2s (queue->type), GMC_2s (c), c, GM_f2s (queue->fwd), data_size);
946   }
947
948   /* Free queue, but cls was freed by send_core_* */
949   GMP_queue_destroy (queue, GNUNET_NO, GNUNET_YES);
950
951   /* If more data in queue, send next */
952   queue = peer_get_first_message (peer);
953   if (NULL != queue)
954   {
955     LOG (GNUNET_ERROR_TYPE_DEBUG, "*   more data!\n");
956     if (NULL == peer->core_transmit)
957     {
958       peer->core_transmit =
959           GNUNET_CORE_notify_transmit_ready (core_handle,
960                                              GNUNET_NO, get_priority (queue),
961                                              GNUNET_TIME_UNIT_FOREVER_REL,
962                                              dst_id,
963                                              queue->size,
964                                              &queue_send,
965                                              peer);
966       queue->start_waiting = GNUNET_TIME_absolute_get ();
967     }
968     else
969     {
970       LOG (GNUNET_ERROR_TYPE_DEBUG,
971                   "*   tmt rdy called somewhere else\n");
972     }
973 //     GMC_start_poll (); FIXME needed?
974   }
975   else
976   {
977 //     GMC_stop_poll(); FIXME needed?
978   }
979
980   LOG (GNUNET_ERROR_TYPE_DEBUG, "*  Return %d\n", data_size);
981   return data_size;
982 }
983
984
985 /******************************************************************************/
986 /********************************    API    ***********************************/
987 /******************************************************************************/
988
989
990 /**
991  * Free a transmission that was already queued with all resources
992  * associated to the request.
993  *
994  * @param queue Queue handler to cancel.
995  * @param clear_cls Is it necessary to free associated cls?
996  * @param sent Was it really sent? (Could have been canceled)
997  */
998 void
999 GMP_queue_destroy (struct MeshPeerQueue *queue, int clear_cls, int sent)
1000 {
1001   struct MeshPeer *peer;
1002
1003   peer = queue->peer;
1004
1005   if (GNUNET_YES == clear_cls)
1006   {
1007     LOG (GNUNET_ERROR_TYPE_DEBUG, "#   queue destroy type %s\n",
1008                 GM_m2s (queue->type));
1009     switch (queue->type)
1010     {
1011       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
1012         LOG (GNUNET_ERROR_TYPE_INFO, "destroying a DESTROY message\n");
1013         /* fall through */
1014       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
1015       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
1016       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
1017       case GNUNET_MESSAGE_TYPE_MESH_KEEPALIVE:
1018       case GNUNET_MESSAGE_TYPE_MESH_KX:
1019       case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
1020       case GNUNET_MESSAGE_TYPE_MESH_ACK:
1021       case GNUNET_MESSAGE_TYPE_MESH_POLL:
1022         GNUNET_free_non_null (queue->cls);
1023         break;
1024
1025       default:
1026         GNUNET_break (0);
1027         LOG (GNUNET_ERROR_TYPE_ERROR, "#   type %s unknown!\n",
1028                     GM_m2s (queue->type));
1029     }
1030   }
1031   GNUNET_CONTAINER_DLL_remove (peer->queue_head, peer->queue_tail, queue);
1032
1033   if (queue->type != GNUNET_MESSAGE_TYPE_MESH_ACK &&
1034       queue->type != GNUNET_MESSAGE_TYPE_MESH_POLL)
1035   {
1036     peer->queue_n--;
1037   }
1038
1039   if (NULL != queue->callback)
1040   {
1041     LOG (GNUNET_ERROR_TYPE_DEBUG, "#   Calling callback\n");
1042     queue->callback (queue->callback_cls,
1043                      queue->c, sent, queue->type,
1044                      queue->fwd, queue->size,
1045                      GNUNET_TIME_absolute_get_duration (queue->start_waiting));
1046   }
1047
1048   if (NULL == peer_get_first_message (peer) && NULL != peer->core_transmit)
1049   {
1050     GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit);
1051     peer->core_transmit = NULL;
1052   }
1053
1054   GNUNET_free (queue);
1055 }
1056
1057
1058 /**
1059  * @brief Queue and pass message to core when possible.
1060  *
1061  * @param peer Peer towards which to queue the message.
1062  * @param cls Closure (@c type dependant). It will be used by queue_send to
1063  *            build the message to be sent if not already prebuilt.
1064  * @param type Type of the message, 0 for a raw message.
1065  * @param size Size of the message.
1066  * @param c Connection this message belongs to (can be NULL).
1067  * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!)
1068  * @param cont Continuation to be called once CORE has taken the message.
1069  * @param cont_cls Closure for @c cont.
1070  *
1071  * @return Handle to cancel the message before it is sent. Once cont is called
1072  *         message has been sent and therefore the handle is no longer valid.
1073  */
1074 struct MeshPeerQueue *
1075 GMP_queue_add (struct MeshPeer *peer, void *cls, uint16_t type, size_t size,
1076                struct MeshConnection *c, int fwd,
1077                GMP_sent cont, void *cont_cls)
1078 {
1079   struct MeshPeerQueue *queue;
1080   int priority;
1081   int call_core;
1082
1083   LOG (GNUNET_ERROR_TYPE_INFO, "qq %s on connection %s (%p) %s towards %s (size %u)\n",
1084        GM_m2s (type), GMC_2s (c), c, GM_f2s (fwd), GMP_2s(peer), size);
1085
1086   if (NULL == peer->connections)
1087   {
1088     /* We are not connected to this peer, ignore request. */
1089     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING %s not a neighbor\n", GMP_2s (peer));
1090     GNUNET_STATISTICS_update (stats, "# messages dropped due to wrong hop", 1,
1091                               GNUNET_NO);
1092     return NULL;
1093   }
1094
1095   priority = 0;
1096
1097   if (GNUNET_MESSAGE_TYPE_MESH_POLL == type ||
1098       GNUNET_MESSAGE_TYPE_MESH_ACK == type)
1099   {
1100     priority = 100;
1101   }
1102
1103   LOG (GNUNET_ERROR_TYPE_DEBUG, "priority %d\n", priority);
1104
1105   call_core = NULL == c ? GNUNET_YES : GMC_is_sendable (c, fwd);
1106   queue = GNUNET_new (struct MeshPeerQueue);
1107   queue->cls = cls;
1108   queue->type = type;
1109   queue->size = size;
1110   queue->peer = peer;
1111   queue->c = c;
1112   queue->fwd = fwd;
1113   queue->callback = cont;
1114   queue->callback_cls = cont_cls;
1115   if (100 > priority)
1116   {
1117     GNUNET_CONTAINER_DLL_insert_tail (peer->queue_head, peer->queue_tail, queue);
1118     peer->queue_n++;
1119   }
1120   else
1121   {
1122     GNUNET_CONTAINER_DLL_insert (peer->queue_head, peer->queue_tail, queue);
1123     call_core = GNUNET_YES;
1124   }
1125
1126   if (NULL == peer->core_transmit && GNUNET_YES == call_core)
1127   {
1128     LOG (GNUNET_ERROR_TYPE_DEBUG,
1129                 "calling core tmt rdy towards %s for %u bytes\n",
1130                 GMP_2s (peer), size);
1131     peer->core_transmit =
1132         GNUNET_CORE_notify_transmit_ready (core_handle,
1133                                            GNUNET_NO, get_priority (queue),
1134                                            GNUNET_TIME_UNIT_FOREVER_REL,
1135                                            GNUNET_PEER_resolve2 (peer->id),
1136                                            size,
1137                                            &queue_send,
1138                                            peer);
1139     queue->start_waiting = GNUNET_TIME_absolute_get ();
1140   }
1141   else if (GNUNET_NO == call_core)
1142   {
1143     LOG (GNUNET_ERROR_TYPE_DEBUG, "core tmt rdy towards %s not needed\n",
1144          GMP_2s (peer));
1145
1146   }
1147   else
1148   {
1149     LOG (GNUNET_ERROR_TYPE_DEBUG, "core tmt rdy towards %s already called\n",
1150          GMP_2s (peer));
1151
1152   }
1153   return queue;
1154 }
1155
1156
1157 /**
1158  * Cancel all queued messages to a peer that belong to a certain connection.
1159  *
1160  * @param peer Peer towards whom to cancel.
1161  * @param c Connection whose queued messages to cancel. Might be destroyed by
1162  *          the sent continuation call.
1163  */
1164 void
1165 GMP_queue_cancel (struct MeshPeer *peer, struct MeshConnection *c)
1166 {
1167   struct MeshPeerQueue *q;
1168   struct MeshPeerQueue *next;
1169   struct MeshPeerQueue *prev;
1170
1171   for (q = peer->queue_head; NULL != q; q = next)
1172   {
1173     prev = q->prev;
1174     if (q->c == c)
1175     {
1176       LOG (GNUNET_ERROR_TYPE_DEBUG, "GMP_cancel_queue %s\n", GM_m2s (q->type));
1177       GMP_queue_destroy (q, GNUNET_YES, GNUNET_NO);
1178
1179       /* Get next from prev, q->next might be already freed:
1180        * queue destroy -> callback -> GMC_destroy -> cancel_queues -> here
1181        */
1182       if (NULL == prev)
1183         next = peer->queue_head;
1184       else
1185         next = prev->next;
1186     }
1187     else
1188     {
1189       next = q->next;
1190     }
1191   }
1192   if (NULL == peer->queue_head)
1193   {
1194     if (NULL != peer->core_transmit)
1195     {
1196       GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit);
1197       peer->core_transmit = NULL;
1198     }
1199   }
1200 }
1201
1202
1203 /**
1204  * Get the first transmittable message for a connection.
1205  *
1206  * @param peer Neighboring peer.
1207  * @param c Connection.
1208  *
1209  * @return First transmittable message.
1210  */
1211 static struct MeshPeerQueue *
1212 connection_get_first_message (struct MeshPeer *peer, struct MeshConnection *c)
1213 {
1214   struct MeshPeerQueue *q;
1215
1216   for (q = peer->queue_head; NULL != q; q = q->next)
1217   {
1218     if (q->c != c)
1219       continue;
1220     if (queue_is_sendable (q))
1221     {
1222       LOG (GNUNET_ERROR_TYPE_DEBUG, "  sendable!!\n");
1223       return q;
1224     }
1225     LOG (GNUNET_ERROR_TYPE_DEBUG, "  not sendable\n");
1226   }
1227
1228   return NULL;
1229 }
1230
1231
1232 /**
1233  * Get the first message for a connection and unqueue it.
1234  *
1235  * @param peer Neighboring peer.
1236  * @param c Connection.
1237  *
1238  * @return First message for this connection.
1239  */
1240 struct GNUNET_MessageHeader *
1241 GMP_connection_pop (struct MeshPeer *peer, struct MeshConnection *c)
1242 {
1243   struct MeshPeerQueue *q;
1244   struct GNUNET_MessageHeader *msg;
1245
1246   LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection pop on %s\n", GMC_2s (c));
1247   for (q = peer->queue_head; NULL != q; q = q->next)
1248   {
1249     if (q->c != c)
1250       continue;
1251     switch (q->type)
1252     {
1253       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
1254       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
1255       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY:
1256       case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN:
1257       case GNUNET_MESSAGE_TYPE_MESH_ACK:
1258       case GNUNET_MESSAGE_TYPE_MESH_POLL:
1259         GMP_queue_destroy (q, GNUNET_YES, GNUNET_NO);
1260         continue;
1261
1262       case GNUNET_MESSAGE_TYPE_MESH_KX:
1263       case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
1264         msg = (struct GNUNET_MessageHeader *) q->cls;
1265         GMP_queue_destroy (q, GNUNET_NO, GNUNET_NO);
1266         return msg;
1267
1268       default:
1269         GNUNET_break (0);
1270     }
1271   }
1272
1273   return NULL;
1274 }
1275
1276
1277 void
1278 GMP_queue_unlock (struct MeshPeer *peer, struct MeshConnection *c)
1279 {
1280   struct MeshPeerQueue *q;
1281   size_t size;
1282
1283   if (NULL != peer->core_transmit)
1284   {
1285     LOG (GNUNET_ERROR_TYPE_DEBUG, "  already unlocked!\n");
1286     return; /* Already unlocked */
1287   }
1288
1289   q = connection_get_first_message (peer, c);
1290   if (NULL == q)
1291   {
1292     LOG (GNUNET_ERROR_TYPE_DEBUG, "  queue empty!\n");
1293     return; /* Nothing to transmit */
1294   }
1295
1296   size = q->size;
1297   peer->core_transmit =
1298       GNUNET_CORE_notify_transmit_ready (core_handle,
1299                                          GNUNET_NO, get_priority (q),
1300                                          GNUNET_TIME_UNIT_FOREVER_REL,
1301                                          GNUNET_PEER_resolve2 (peer->id),
1302                                          size,
1303                                          &queue_send,
1304                                          peer);
1305 }
1306
1307
1308 /**
1309  * Initialize the peer subsystem.
1310  *
1311  * @param c Configuration.
1312  */
1313 void
1314 GMP_init (const struct GNUNET_CONFIGURATION_Handle *c)
1315 {
1316   LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
1317   peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
1318   if (GNUNET_OK !=
1319       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_PEERS",
1320                                              &max_peers))
1321   {
1322     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1323                                "MESH", "MAX_PEERS", "USING DEFAULT");
1324     max_peers = 1000;
1325   }
1326
1327   if (GNUNET_OK !=
1328       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DROP_PERCENT",
1329                                              &drop_percent))
1330   {
1331     drop_percent = 0;
1332   }
1333   else
1334   {
1335     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1336     LOG (GNUNET_ERROR_TYPE_WARNING, "Mesh is running with DROP enabled.\n");
1337     LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1338     LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1339     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1340   }
1341
1342   core_handle = GNUNET_CORE_connect (c, /* Main configuration */
1343                                      NULL,      /* Closure passed to MESH functions */
1344                                      &core_init,        /* Call core_init once connected */
1345                                      &core_connect,     /* Handle connects */
1346                                      &core_disconnect,  /* remove peers on disconnects */
1347                                      NULL,      /* Don't notify about all incoming messages */
1348                                      GNUNET_NO, /* For header only in notification */
1349                                      NULL,      /* Don't notify about all outbound messages */
1350                                      GNUNET_NO, /* For header-only out notification */
1351                                      core_handlers);    /* Register these handlers */
1352   if (GNUNET_YES !=
1353     GNUNET_CONFIGURATION_get_value_yesno (c, "MESH", "DISABLE_TRY_CONNECT"))
1354   {
1355     transport_handle = GNUNET_TRANSPORT_connect (c, &my_full_id, NULL, /* cls */
1356                                                  /* Notify callbacks */
1357                                                  NULL, NULL, NULL);
1358   }
1359   else
1360   {
1361     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1362     LOG (GNUNET_ERROR_TYPE_WARNING, "*  DISABLE TRYING CONNECT in config  *\n");
1363     LOG (GNUNET_ERROR_TYPE_WARNING, "*  Use this only for test purposes.  *\n");
1364     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1365   }
1366
1367
1368
1369   if (NULL == core_handle)
1370   {
1371     GNUNET_break (0);
1372     GNUNET_SCHEDULER_shutdown ();
1373     return;
1374   }
1375
1376 }
1377
1378 /**
1379  * Shut down the peer subsystem.
1380  */
1381 void
1382 GMP_shutdown (void)
1383 {
1384   GNUNET_CONTAINER_multipeermap_iterate (peers, &shutdown_tunnel, NULL);
1385
1386   if (core_handle != NULL)
1387   {
1388     GNUNET_CORE_disconnect (core_handle);
1389     core_handle = NULL;
1390   }
1391   if (transport_handle != NULL)
1392   {
1393     GNUNET_TRANSPORT_disconnect (transport_handle);
1394     transport_handle = NULL;
1395   }
1396   GNUNET_PEER_change_rc (myid, -1);
1397 }
1398
1399 /**
1400  * Retrieve the MeshPeer stucture associated with the peer, create one
1401  * and insert it in the appropriate structures if the peer is not known yet.
1402  *
1403  * @param peer_id Full identity of the peer.
1404  *
1405  * @return Existing or newly created peer structure.
1406  */
1407 struct MeshPeer *
1408 GMP_get (const struct GNUNET_PeerIdentity *peer_id)
1409 {
1410   struct MeshPeer *peer;
1411
1412   peer = GNUNET_CONTAINER_multipeermap_get (peers, peer_id);
1413   if (NULL == peer)
1414   {
1415     peer = GNUNET_new (struct MeshPeer);
1416     if (GNUNET_CONTAINER_multipeermap_size (peers) > max_peers)
1417     {
1418       peer_delete_oldest ();
1419     }
1420         GNUNET_CONTAINER_multipeermap_put (peers, peer_id, peer,
1421                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1422         peer->id = GNUNET_PEER_intern (peer_id);
1423   }
1424   peer->last_contact = GNUNET_TIME_absolute_get();
1425
1426   return peer;
1427 }
1428
1429
1430 /**
1431  * Retrieve the MeshPeer stucture associated with the peer, create one
1432  * and insert it in the appropriate structures if the peer is not known yet.
1433  *
1434  * @param peer Short identity of the peer.
1435  *
1436  * @return Existing or newly created peer structure.
1437  */
1438 struct MeshPeer *
1439 GMP_get_short (const GNUNET_PEER_Id peer)
1440 {
1441   return GMP_get (GNUNET_PEER_resolve2 (peer));
1442 }
1443
1444
1445 /**
1446  * Try to connect to a peer on transport level.
1447  *
1448  * @param cls Closure (peer).
1449  * @param tc TaskContext.
1450  */
1451 static void
1452 try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1453 {
1454   struct MeshPeer *peer = cls;
1455
1456   if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1457     return;
1458
1459   GNUNET_TRANSPORT_try_connect (transport_handle,
1460                                 GNUNET_PEER_resolve2 (peer->id), NULL, NULL);
1461 }
1462
1463
1464 /**
1465  * Try to establish a new connection to this peer (in its tunnel).
1466  * If the peer doesn't have any path to it yet, try to get one.
1467  * If the peer already has some path, send a CREATE CONNECTION towards it.
1468  *
1469  * @param peer Peer to connect to.
1470  */
1471 void
1472 GMP_connect (struct MeshPeer *peer)
1473 {
1474   struct MeshTunnel3 *t;
1475   struct MeshPeerPath *p;
1476   struct MeshConnection *c;
1477   int rerun_search;
1478
1479   LOG (GNUNET_ERROR_TYPE_DEBUG, "peer_connect towards %s\n", GMP_2s (peer));
1480
1481   /* If we have a current hello, try to connect using it. */
1482   GMP_try_connect (peer);
1483
1484   t = peer->tunnel;
1485   c = NULL;
1486   rerun_search = GNUNET_NO;
1487
1488   if (NULL != peer->path_head)
1489   {
1490     LOG (GNUNET_ERROR_TYPE_DEBUG, "  some path exists\n");
1491     p = peer_get_best_path (peer);
1492     if (NULL != p)
1493     {
1494       char *s;
1495
1496       s = path_2s (p);
1497       LOG (GNUNET_ERROR_TYPE_DEBUG, "  path to use: %s\n", s);
1498       GNUNET_free (s);
1499
1500       c = GMT_use_path (t, p);
1501       if (NULL == c)
1502       {
1503         /* This case can happen when the path includes a first hop that is
1504          * not yet known to be connected.
1505          *
1506          * This happens quite often during testing when running mesh
1507          * under valgrind: core connect notifications come very late and the
1508          * DHT result has already come and created a valid path.
1509          * In this case, the peer->connections hashmap will be NULL and
1510          * tunnel_use_path will not be able to create a connection from that
1511          * path.
1512          *
1513          * Re-running the DHT GET should give core time to callback.
1514          *
1515          * GMT_use_path -> GMC_new -> register_neighbors takes care of
1516          * updating statistics about this issue.
1517          */
1518         rerun_search = GNUNET_YES;
1519       }
1520       else
1521       {
1522         GMC_send_create (c);
1523         return;
1524       }
1525     }
1526     else
1527     {
1528       LOG (GNUNET_ERROR_TYPE_DEBUG, "  but is NULL, all paths are in use\n");
1529     }
1530   }
1531
1532   if (NULL != peer->search_h && GNUNET_YES == rerun_search)
1533   {
1534     GMD_search_stop (peer->search_h);
1535     peer->search_h = NULL;
1536     LOG (GNUNET_ERROR_TYPE_DEBUG,
1537          "  Stopping DHT GET for peer %s\n",
1538          GMP_2s (peer));
1539   }
1540
1541   if (NULL == peer->search_h)
1542   {
1543     const struct GNUNET_PeerIdentity *id;
1544
1545     id = GNUNET_PEER_resolve2 (peer->id);
1546     LOG (GNUNET_ERROR_TYPE_DEBUG,
1547                 "  Starting DHT GET for peer %s\n", GMP_2s (peer));
1548     peer->search_h = GMD_search (id, &search_handler, peer);
1549     if (MESH_TUNNEL3_NEW == GMT_get_cstate (t))
1550       GMT_change_cstate (t, MESH_TUNNEL3_SEARCHING);
1551   }
1552 }
1553
1554
1555 /**
1556  * Chech whether there is a direct (core level)  connection to peer.
1557  *
1558  * @param peer Peer to check.
1559  *
1560  * @return #GNUNET_YES if there is a direct connection.
1561  */
1562 int
1563 GMP_is_neighbor (const struct MeshPeer *peer)
1564 {
1565   struct MeshPeerPath *path;
1566
1567   if (NULL == peer->connections)
1568     return GNUNET_NO;
1569
1570   for (path = peer->path_head; NULL != path; path = path->next)
1571   {
1572     if (3 > path->length)
1573       return GNUNET_YES;
1574   }
1575
1576   /* Is not a neighbor but connections is not NULL, probably disconnecting */
1577   return GNUNET_NO;
1578 }
1579
1580
1581 /**
1582  * Create and initialize a new tunnel towards a peer, in case it has none.
1583  * In case the peer already has a tunnel, nothing is done.
1584  *
1585  * Does not generate any traffic, just creates the local data structures.
1586  *
1587  * @param peer Peer towards which to create the tunnel.
1588  */
1589 void
1590 GMP_add_tunnel (struct MeshPeer *peer)
1591 {
1592   if (NULL != peer->tunnel)
1593     return;
1594   peer->tunnel = GMT_new (peer);
1595 }
1596
1597
1598 /**
1599  * Add a connection to a neighboring peer.
1600  *
1601  * Store that the peer is the first hop of the connection in one
1602  * direction and that on peer disconnect the connection must be
1603  * notified and destroyed, for it will no longer be valid.
1604  *
1605  * @param peer Peer to add connection to.
1606  * @param c Connection to add.
1607  *
1608  * @return GNUNET_OK on success.
1609  */
1610 int
1611 GMP_add_connection (struct MeshPeer *peer,
1612                     struct MeshConnection *c)
1613 {
1614   int result;
1615   LOG (GNUNET_ERROR_TYPE_DEBUG, "adding connection %s\n", GMC_2s (c));
1616   LOG (GNUNET_ERROR_TYPE_DEBUG, "to peer %s\n", GMP_2s (peer));
1617
1618   if (NULL == peer->connections)
1619   {
1620     GNUNET_break (0);
1621     LOG (GNUNET_ERROR_TYPE_DEBUG,
1622          "Peer %s is not a neighbor!\n",
1623          GMP_2s (peer));
1624     return GNUNET_SYSERR;
1625   }
1626   LOG (GNUNET_ERROR_TYPE_DEBUG,
1627        "peer %s ok, has %u connections.\n",
1628        GMP_2s (peer), GNUNET_CONTAINER_multihashmap_size (peer->connections));
1629   result = GNUNET_CONTAINER_multihashmap_put (peer->connections,
1630                                               GMC_get_h (c),
1631                                               c,
1632                                               GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1633   LOG (GNUNET_ERROR_TYPE_DEBUG,
1634        " now has %u connections.\n",
1635        GNUNET_CONTAINER_multihashmap_size (peer->connections));
1636   LOG (GNUNET_ERROR_TYPE_DEBUG, "result %u\n", result);
1637
1638   return result;
1639 }
1640
1641
1642 /**
1643  * Add the path to the peer and update the path used to reach it in case this
1644  * is the shortest.
1645  *
1646  * @param peer Destination peer to add the path to.
1647  * @param path New path to add. Last peer must be the peer in arg 1.
1648  *             Path will be either used of freed if already known.
1649  * @param trusted Do we trust that this path is real?
1650  *
1651  * @return path if path was taken, pointer to existing duplicate if exists
1652  *         NULL on error.
1653  */
1654 struct MeshPeerPath *
1655 GMP_add_path (struct MeshPeer *peer, struct MeshPeerPath *path,
1656               int trusted)
1657 {
1658   struct MeshPeerPath *aux;
1659   unsigned int l;
1660   unsigned int l2;
1661
1662   LOG (GNUNET_ERROR_TYPE_DEBUG, "adding path [%u] to peer %s\n",
1663        path->length, GMP_2s (peer));
1664
1665   if ((NULL == peer) || (NULL == path))
1666   {
1667     GNUNET_break (0);
1668     path_destroy (path);
1669     return NULL;
1670   }
1671   if (path->peers[path->length - 1] != peer->id)
1672   {
1673     GNUNET_break (0);
1674     path_destroy (path);
1675     return NULL;
1676   }
1677
1678   for (l = 1; l < path->length; l++)
1679   {
1680     if (path->peers[l] == myid)
1681     {
1682       LOG (GNUNET_ERROR_TYPE_DEBUG, " shortening path by %u\n", l);
1683       for (l2 = 0; l2 < path->length - l; l2++)
1684       {
1685         path->peers[l2] = path->peers[l + l2];
1686       }
1687       path->length -= l;
1688       l = 1;
1689       path->peers = GNUNET_realloc (path->peers,
1690                                     path->length * sizeof (GNUNET_PEER_Id));
1691     }
1692   }
1693
1694   LOG (GNUNET_ERROR_TYPE_DEBUG, " final length: %u\n", path->length);
1695
1696   if (2 >= path->length && GNUNET_NO == trusted)
1697   {
1698     /* Only allow CORE to tell us about direct paths */
1699     path_destroy (path);
1700     return NULL;
1701   }
1702
1703   l = path_get_length (path);
1704   if (0 == l)
1705   {
1706     path_destroy (path);
1707     return NULL;
1708   }
1709
1710   GNUNET_assert (peer->id == path->peers[path->length - 1]);
1711   for (aux = peer->path_head; aux != NULL; aux = aux->next)
1712   {
1713     l2 = path_get_length (aux);
1714     if (l2 > l)
1715     {
1716       LOG (GNUNET_ERROR_TYPE_DEBUG, "  added\n");
1717       GNUNET_CONTAINER_DLL_insert_before (peer->path_head,
1718                                           peer->path_tail, aux, path);
1719       if (NULL != peer->tunnel && 3 < GMT_count_connections (peer->tunnel))
1720       {
1721         GMP_connect (peer);
1722       }
1723       return path;
1724     }
1725     else
1726     {
1727       if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
1728       {
1729         LOG (GNUNET_ERROR_TYPE_DEBUG, "  already known\n");
1730         path_destroy (path);
1731         return aux;
1732       }
1733     }
1734   }
1735   GNUNET_CONTAINER_DLL_insert_tail (peer->path_head, peer->path_tail,
1736                                     path);
1737   LOG (GNUNET_ERROR_TYPE_DEBUG, "  added last\n");
1738   if (NULL != peer->tunnel && 3 < GMT_count_connections (peer->tunnel))
1739   {
1740     GMP_connect (peer);
1741   }
1742   return path;
1743 }
1744
1745
1746 /**
1747  * Add the path to the origin peer and update the path used to reach it in case
1748  * this is the shortest.
1749  * The path is given in peer_info -> destination, therefore we turn the path
1750  * upside down first.
1751  *
1752  * @param peer Peer to add the path to, being the origin of the path.
1753  * @param path New path to add after being inversed.
1754  *             Path will be either used or freed.
1755  * @param trusted Do we trust that this path is real?
1756  *
1757  * @return path if path was taken, pointer to existing duplicate if exists
1758  *         NULL on error.
1759  */
1760 struct MeshPeerPath *
1761 GMP_add_path_to_origin (struct MeshPeer *peer,
1762                         struct MeshPeerPath *path,
1763                         int trusted)
1764 {
1765   if (NULL == path)
1766     return NULL;
1767   path_invert (path);
1768   return GMP_add_path (peer, path, trusted);
1769 }
1770
1771
1772 /**
1773  * Adds a path to the info of all the peers in the path
1774  *
1775  * @param p Path to process.
1776  * @param confirmed Whether we know if the path works or not.
1777  */
1778 void
1779 GMP_add_path_to_all (const struct MeshPeerPath *p, int confirmed)
1780 {
1781   unsigned int i;
1782
1783   /* TODO: invert and add */
1784   for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
1785   for (i++; i < p->length; i++)
1786   {
1787     struct MeshPeer *aux;
1788     struct MeshPeerPath *copy;
1789
1790     aux = GMP_get_short (p->peers[i]);
1791     copy = path_duplicate (p);
1792     copy->length = i + 1;
1793     GMP_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
1794   }
1795 }
1796
1797
1798 /**
1799  * Remove any path to the peer that has the extact same peers as the one given.
1800  *
1801  * @param peer Peer to remove the path from.
1802  * @param path Path to remove. Is always destroyed .
1803  */
1804 void
1805 GMP_remove_path (struct MeshPeer *peer, struct MeshPeerPath *path)
1806 {
1807   struct MeshPeerPath *iter;
1808   struct MeshPeerPath *next;
1809
1810   GNUNET_assert (myid == path->peers[0]);
1811   GNUNET_assert (peer->id == path->peers[path->length - 1]);
1812
1813   for (iter = peer->path_head; NULL != iter; iter = next)
1814   {
1815     next = iter->next;
1816     if (0 == memcmp (path->peers, iter->peers,
1817                      sizeof (GNUNET_PEER_Id) * path->length))
1818     {
1819       GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, iter);
1820       if (iter != path)
1821         path_destroy (iter);
1822     }
1823   }
1824   path_destroy (path);
1825 }
1826
1827
1828 /**
1829  * Remove a connection from a neighboring peer.
1830  *
1831  * @param peer Peer to remove connection from.
1832  * @param c Connection to remove.
1833  *
1834  * @return GNUNET_OK on success.
1835  */
1836 int
1837 GMP_remove_connection (struct MeshPeer *peer,
1838                        const struct MeshConnection *c)
1839 {
1840   LOG (GNUNET_ERROR_TYPE_DEBUG, "removing connection %s\n", GMC_2s (c));
1841   LOG (GNUNET_ERROR_TYPE_DEBUG, "from peer %s\n", GMP_2s (peer));
1842
1843   if (NULL == peer || NULL == peer->connections)
1844   {
1845     LOG (GNUNET_ERROR_TYPE_DEBUG,
1846          "Peer %s is not a neighbor!\n",
1847          GMP_2s (peer));
1848     return GNUNET_SYSERR;
1849   }
1850   LOG (GNUNET_ERROR_TYPE_DEBUG,
1851        "peer %s ok, has %u connections.\n",
1852        GMP_2s (peer), GNUNET_CONTAINER_multihashmap_size (peer->connections));
1853
1854   return GNUNET_CONTAINER_multihashmap_remove (peer->connections,
1855                                                GMC_get_h (c),
1856                                                c);
1857 }
1858
1859 /**
1860  * Start the DHT search for new paths towards the peer: we don't have
1861  * enough good connections.
1862  *
1863  * @param peer Destination peer.
1864  */
1865 void
1866 GMP_start_search (struct MeshPeer *peer)
1867 {
1868   if (NULL != peer->search_h)
1869   {
1870     GNUNET_break (0);
1871     return;
1872   }
1873
1874   peer->search_h = GMD_search (GMP_get_id (peer), &search_handler, peer);
1875 }
1876
1877
1878 /**
1879  * Stop the DHT search for new paths towards the peer: we already have
1880  * enough good connections.
1881  *
1882  * @param peer Destination peer.
1883  */
1884 void
1885 GMP_stop_search (struct MeshPeer *peer)
1886 {
1887   if (NULL == peer->search_h)
1888   {
1889     GNUNET_break (0);
1890     return;
1891   }
1892
1893   GMD_search_stop (peer->search_h);
1894   peer->search_h = NULL;
1895 }
1896
1897
1898 /**
1899  * Get the Full ID of a peer.
1900  *
1901  * @param peer Peer to get from.
1902  *
1903  * @return Full ID of peer.
1904  */
1905 const struct GNUNET_PeerIdentity *
1906 GMP_get_id (const struct MeshPeer *peer)
1907 {
1908   return GNUNET_PEER_resolve2 (peer->id);
1909 }
1910
1911
1912 /**
1913  * Get the Short ID of a peer.
1914  *
1915  * @param peer Peer to get from.
1916  *
1917  * @return Short ID of peer.
1918  */
1919 GNUNET_PEER_Id
1920 GMP_get_short_id (const struct MeshPeer *peer)
1921 {
1922   return peer->id;
1923 }
1924
1925
1926 /**
1927  * Set tunnel.
1928  *
1929  * @param peer Peer.
1930  * @param t Tunnel.
1931  */
1932 void
1933 GMP_set_tunnel (struct MeshPeer *peer, struct MeshTunnel3 *t)
1934 {
1935   peer->tunnel = t;
1936   if (NULL == t && NULL != peer->search_h)
1937   {
1938     GMP_stop_search (peer);
1939   }
1940 }
1941
1942
1943 /**
1944  * Get the tunnel towards a peer.
1945  *
1946  * @param peer Peer to get from.
1947  *
1948  * @return Tunnel towards peer.
1949  */
1950 struct MeshTunnel3 *
1951 GMP_get_tunnel (const struct MeshPeer *peer)
1952 {
1953   return peer->tunnel;
1954 }
1955
1956
1957 /**
1958  * Set the hello message.
1959  *
1960  * @param peer Peer whose message to set.
1961  * @param hello Hello message.
1962  */
1963 void
1964 GMP_set_hello (struct MeshPeer *peer, const struct GNUNET_HELLO_Message *hello)
1965 {
1966   struct GNUNET_HELLO_Message *old;
1967   size_t size;
1968
1969   LOG (GNUNET_ERROR_TYPE_DEBUG, "set hello for %s\n", GMP_2s (peer));
1970   if (NULL == hello)
1971     return;
1972
1973   old = GMP_get_hello (peer);
1974   if (NULL == old)
1975   {
1976     size = GNUNET_HELLO_size (hello);
1977     LOG (GNUNET_ERROR_TYPE_DEBUG, " new (%u bytes)\n", size);
1978     peer->hello = GNUNET_malloc (size);
1979     memcpy (peer->hello, hello, size);
1980   }
1981   else
1982   {
1983     peer->hello = GNUNET_HELLO_merge (old, hello);
1984     LOG (GNUNET_ERROR_TYPE_DEBUG, " merge into %p (%u bytes)\n",
1985          peer->hello, GNUNET_HELLO_size (hello));
1986     GNUNET_free (old);
1987   }
1988 }
1989
1990
1991 /**
1992  * Get the hello message.
1993  *
1994  * @param peer Peer whose message to get.
1995  *
1996  * @return Hello message.
1997  */
1998 struct GNUNET_HELLO_Message *
1999 GMP_get_hello (struct MeshPeer *peer)
2000 {
2001   struct GNUNET_TIME_Absolute expiration;
2002   struct GNUNET_TIME_Relative remaining;
2003
2004   if (NULL == peer->hello)
2005     return NULL;
2006
2007   expiration = GNUNET_HELLO_get_last_expiration (peer->hello);
2008   remaining = GNUNET_TIME_absolute_get_remaining (expiration);
2009   if (0 == remaining.rel_value_us)
2010   {
2011     LOG (GNUNET_ERROR_TYPE_DEBUG, " get - hello expired on %s\n",
2012          GNUNET_STRINGS_absolute_time_to_string (expiration));
2013     GNUNET_free (peer->hello);
2014     peer->hello = NULL;
2015   }
2016   return peer->hello;
2017 }
2018
2019
2020 /**
2021  * Try to connect to a peer on TRANSPORT level.
2022  *
2023  * @param peer Peer to whom to connect.
2024  */
2025 void
2026 GMP_try_connect (struct MeshPeer *peer)
2027 {
2028   struct GNUNET_HELLO_Message *hello;
2029   struct GNUNET_MessageHeader *mh;
2030
2031   if (NULL == transport_handle)
2032     return;
2033
2034   hello = GMP_get_hello (peer);
2035   if (NULL == hello)
2036     return;
2037
2038   mh = GNUNET_HELLO_get_header (hello);
2039   GNUNET_TRANSPORT_offer_hello (transport_handle, mh, try_connect, peer);
2040 }
2041
2042
2043 /**
2044  * Notify a peer that a link between two other peers is broken. If any path
2045  * used that link, eliminate it.
2046  *
2047  * @param peer Peer affected by the change.
2048  * @param peer1 Peer whose link is broken.
2049  * @param peer2 Peer whose link is broken.
2050  */
2051 void
2052 GMP_notify_broken_link (struct MeshPeer *peer,
2053                         struct GNUNET_PeerIdentity *peer1,
2054                         struct GNUNET_PeerIdentity *peer2)
2055 {
2056   struct MeshPeerPath *iter;
2057   struct MeshPeerPath *next;
2058   unsigned int i;
2059   GNUNET_PEER_Id p1;
2060   GNUNET_PEER_Id p2;
2061
2062   p1 = GNUNET_PEER_search (peer1);
2063   p2 = GNUNET_PEER_search (peer2);
2064
2065   LOG (GNUNET_ERROR_TYPE_DEBUG, "Link %u-%u broken\n", p1, p2);
2066   if (0 == p1 || 0 == p2)
2067   {
2068     /* We don't even know them */
2069     return;
2070   }
2071
2072   for (iter = peer->path_head; NULL != iter; iter = next)
2073   {
2074     next = iter->next;
2075     for (i = 0; i < iter->length - 1; i++)
2076     {
2077       if ((iter->peers[i] == p1 && iter->peers[i + 1] == p2)
2078           || (iter->peers[i] == p2 && iter->peers[i + 1] == p1))
2079       {
2080         char *s;
2081
2082         s = path_2s (iter);
2083         LOG (GNUNET_ERROR_TYPE_DEBUG, " - invalidating %s\n", s);
2084         GNUNET_free (s);
2085
2086         path_invalidate (iter);
2087       }
2088     }
2089   }
2090 }
2091
2092
2093 /**
2094  * Count the number of known paths toward the peer.
2095  *
2096  * @param peer Peer to get path info.
2097  *
2098  * @return Number of known paths.
2099  */
2100 unsigned int
2101 GMP_count_paths (const struct MeshPeer *peer)
2102 {
2103   struct MeshPeerPath *iter;
2104   unsigned int i;
2105
2106   for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next)
2107     i++;
2108
2109   return i;
2110 }
2111
2112
2113 /**
2114  * Iterate all known peers.
2115  *
2116  * @param iter Iterator.
2117  * @param cls Closure for @c iter.
2118  */
2119 void
2120 GMP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls)
2121 {
2122   GNUNET_CONTAINER_multipeermap_iterate (peers, iter, cls);
2123 }
2124
2125
2126 /**
2127  * Get the static string for a peer ID.
2128  *
2129  * @param peer Peer.
2130  *
2131  * @return Static string for it's ID.
2132  */
2133 const char *
2134 GMP_2s (const struct MeshPeer *peer)
2135 {
2136   if (NULL == peer)
2137     return "(NULL)";
2138   return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
2139 }