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