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