Exponential backoff for find finger trail task
[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 %p towards %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  *
1408  * @return First message for this connection.
1409  */
1410 struct GNUNET_MessageHeader *
1411 GCP_connection_pop (struct CadetPeer *peer,
1412                     struct CadetConnection *c,
1413                     int *destroyed)
1414 {
1415   struct CadetPeerQueue *q;
1416   struct CadetPeerQueue *next;
1417   struct GNUNET_MessageHeader *msg;
1418   int dest;
1419
1420   LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection pop on connection %p\n", c);
1421   for (q = peer->queue_head; NULL != q; q = next)
1422   {
1423     GNUNET_break (NULL == destroyed || GNUNET_NO == *destroyed);
1424     next = q->next;
1425     if (q->c != c)
1426       continue;
1427     LOG (GNUNET_ERROR_TYPE_DEBUG, " - queued: %s (%s %u), callback: %p\n",
1428          GC_m2s (q->type), GC_m2s (q->payload_type), q->payload_id,
1429          q->callback);
1430     switch (q->type)
1431     {
1432       case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
1433       case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK:
1434       case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
1435       case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
1436       case GNUNET_MESSAGE_TYPE_CADET_ACK:
1437       case GNUNET_MESSAGE_TYPE_CADET_POLL:
1438         dest = GCP_queue_destroy (q, GNUNET_YES, GNUNET_NO, 0);
1439         if (NULL != destroyed && GNUNET_YES == dest)
1440           *destroyed = GNUNET_YES;
1441         continue;
1442
1443       case GNUNET_MESSAGE_TYPE_CADET_KX:
1444       case GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED:
1445         msg = (struct GNUNET_MessageHeader *) q->cls;
1446         dest = GCP_queue_destroy (q, GNUNET_NO, GNUNET_NO, 0);
1447         if (NULL != destroyed && GNUNET_YES == dest)
1448           *destroyed = GNUNET_YES;
1449         return msg;
1450
1451       default:
1452         GNUNET_break (0);
1453         LOG (GNUNET_ERROR_TYPE_DEBUG, "Unknown message %s\n", GC_m2s (q->type));
1454     }
1455   }
1456
1457   return NULL;
1458 }
1459
1460 /**
1461  * Unlock a possibly locked queue for a connection.
1462  *
1463  * If there is a message that can be sent on this connection, call core for it.
1464  * Otherwise (if core transmit is already called or there is no sendable
1465  * message) do nothing.
1466  *
1467  * @param peer Peer who keeps the queue.
1468  * @param c Connection whose messages to unlock.
1469  */
1470 void
1471 GCP_queue_unlock (struct CadetPeer *peer, struct CadetConnection *c)
1472 {
1473   struct CadetPeerQueue *q;
1474   size_t size;
1475
1476   if (NULL != peer->core_transmit)
1477   {
1478     LOG (GNUNET_ERROR_TYPE_DEBUG, "  already unlocked!\n");
1479     return; /* Already unlocked */
1480   }
1481
1482   q = connection_get_first_message (peer, c);
1483   if (NULL == q)
1484   {
1485     LOG (GNUNET_ERROR_TYPE_DEBUG, "  queue empty!\n");
1486     return; /* Nothing to transmit */
1487   }
1488
1489   size = q->size;
1490   peer->core_transmit =
1491       GNUNET_CORE_notify_transmit_ready (core_handle,
1492                                          GNUNET_NO, get_priority (q),
1493                                          GNUNET_TIME_UNIT_FOREVER_REL,
1494                                          GNUNET_PEER_resolve2 (peer->id),
1495                                          size,
1496                                          &queue_send,
1497                                          peer);
1498 }
1499
1500
1501 /**
1502  * Initialize the peer subsystem.
1503  *
1504  * @param c Configuration.
1505  */
1506 void
1507 GCP_init (const struct GNUNET_CONFIGURATION_Handle *c)
1508 {
1509   LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
1510   peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
1511   if (GNUNET_OK !=
1512       GNUNET_CONFIGURATION_get_value_number (c, "CADET", "MAX_PEERS",
1513                                              &max_peers))
1514   {
1515     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1516                                "CADET", "MAX_PEERS", "USING DEFAULT");
1517     max_peers = 1000;
1518   }
1519
1520   if (GNUNET_OK !=
1521       GNUNET_CONFIGURATION_get_value_number (c, "CADET", "DROP_PERCENT",
1522                                              &drop_percent))
1523   {
1524     drop_percent = 0;
1525   }
1526   else
1527   {
1528     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1529     LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n");
1530     LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1531     LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1532     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1533   }
1534
1535   core_handle = GNUNET_CORE_connect (c, /* Main configuration */
1536                                      NULL,      /* Closure passed to CADET functions */
1537                                      &core_init,        /* Call core_init once connected */
1538                                      &core_connect,     /* Handle connects */
1539                                      &core_disconnect,  /* remove peers on disconnects */
1540                                      NULL,      /* Don't notify about all incoming messages */
1541                                      GNUNET_NO, /* For header only in notification */
1542                                      NULL,      /* Don't notify about all outbound messages */
1543                                      GNUNET_NO, /* For header-only out notification */
1544                                      core_handlers);    /* Register these handlers */
1545   if (GNUNET_YES !=
1546       GNUNET_CONFIGURATION_get_value_yesno (c, "CADET", "DISABLE_TRY_CONNECT"))
1547   {
1548     transport_handle = GNUNET_TRANSPORT_connect (c, &my_full_id, NULL, /* cls */
1549                                                  /* Notify callbacks */
1550                                                  NULL, NULL, NULL);
1551   }
1552   else
1553   {
1554     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1555     LOG (GNUNET_ERROR_TYPE_WARNING, "*  DISABLE TRYING CONNECT in config  *\n");
1556     LOG (GNUNET_ERROR_TYPE_WARNING, "*  Use this only for test purposes.  *\n");
1557     LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1558     transport_handle = NULL;
1559   }
1560
1561
1562
1563   if (NULL == core_handle)
1564   {
1565     GNUNET_break (0);
1566     GNUNET_SCHEDULER_shutdown ();
1567     return;
1568   }
1569
1570 }
1571
1572
1573 /**
1574  * Shut down the peer subsystem.
1575  */
1576 void
1577 GCP_shutdown (void)
1578 {
1579   GNUNET_CONTAINER_multipeermap_iterate (peers, &shutdown_tunnel, NULL);
1580
1581   if (core_handle != NULL)
1582   {
1583     GNUNET_CORE_disconnect (core_handle);
1584     core_handle = NULL;
1585   }
1586   if (transport_handle != NULL)
1587   {
1588     GNUNET_TRANSPORT_disconnect (transport_handle);
1589     transport_handle = NULL;
1590   }
1591   GNUNET_PEER_change_rc (myid, -1);
1592 }
1593
1594
1595 /**
1596  * Retrieve the CadetPeer stucture associated with the peer, create one
1597  * and insert it in the appropriate structures if the peer is not known yet.
1598  *
1599  * @param peer_id Full identity of the peer.
1600  *
1601  * @return Existing or newly created peer structure.
1602  */
1603 struct CadetPeer *
1604 GCP_get (const struct GNUNET_PeerIdentity *peer_id)
1605 {
1606   struct CadetPeer *peer;
1607
1608   peer = GNUNET_CONTAINER_multipeermap_get (peers, peer_id);
1609   if (NULL == peer)
1610   {
1611     peer = GNUNET_new (struct CadetPeer);
1612     if (GNUNET_CONTAINER_multipeermap_size (peers) > max_peers)
1613     {
1614       peer_delete_oldest ();
1615     }
1616         GNUNET_CONTAINER_multipeermap_put (peers, peer_id, peer,
1617                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1618         peer->id = GNUNET_PEER_intern (peer_id);
1619   }
1620   peer->last_contact = GNUNET_TIME_absolute_get ();
1621
1622   return peer;
1623 }
1624
1625
1626 /**
1627  * Retrieve the CadetPeer stucture associated with the peer, create one
1628  * and insert it in the appropriate structures if the peer is not known yet.
1629  *
1630  * @param peer Short identity of the peer.
1631  *
1632  * @return Existing or newly created peer structure.
1633  */
1634 struct CadetPeer *
1635 GCP_get_short (const GNUNET_PEER_Id peer)
1636 {
1637   return GCP_get (GNUNET_PEER_resolve2 (peer));
1638 }
1639
1640
1641 /**
1642  * Try to connect to a peer on transport level.
1643  *
1644  * @param cls Closure (peer).
1645  * @param tc TaskContext.
1646  */
1647 static void
1648 try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1649 {
1650   struct CadetPeer *peer = cls;
1651
1652   if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1653     return;
1654
1655   GNUNET_TRANSPORT_try_connect (transport_handle,
1656                                 GNUNET_PEER_resolve2 (peer->id), NULL, NULL);
1657 }
1658
1659
1660 /**
1661  * Try to establish a new connection to this peer (in its tunnel).
1662  * If the peer doesn't have any path to it yet, try to get one.
1663  * If the peer already has some path, send a CREATE CONNECTION towards it.
1664  *
1665  * @param peer Peer to connect to.
1666  */
1667 void
1668 GCP_connect (struct CadetPeer *peer)
1669 {
1670   struct CadetTunnel *t;
1671   struct CadetPeerPath *p;
1672   struct CadetConnection *c;
1673   int rerun_search;
1674
1675   LOG (GNUNET_ERROR_TYPE_DEBUG, "peer_connect towards %s\n", GCP_2s (peer));
1676
1677   /* If we have a current hello, try to connect using it. */
1678   GCP_try_connect (peer);
1679
1680   t = peer->tunnel;
1681   c = NULL;
1682   rerun_search = GNUNET_NO;
1683
1684   if (NULL != peer->path_head)
1685   {
1686     LOG (GNUNET_ERROR_TYPE_DEBUG, "  some path exists\n");
1687     p = peer_get_best_path (peer);
1688     if (NULL != p)
1689     {
1690       char *s;
1691
1692       s = path_2s (p);
1693       LOG (GNUNET_ERROR_TYPE_DEBUG, "  path to use: %s\n", s);
1694       GNUNET_free (s);
1695
1696       c = GCT_use_path (t, p);
1697       if (NULL == c)
1698       {
1699         /* This case can happen when the path includes a first hop that is
1700          * not yet known to be connected.
1701          *
1702          * This happens quite often during testing when running cadet
1703          * under valgrind: core connect notifications come very late and the
1704          * DHT result has already come and created a valid path.
1705          * In this case, the peer->connections hashmap will be NULL and
1706          * tunnel_use_path will not be able to create a connection from that
1707          * path.
1708          *
1709          * Re-running the DHT GET should give core time to callback.
1710          *
1711          * GCT_use_path -> GCC_new -> register_neighbors takes care of
1712          * updating statistics about this issue.
1713          */
1714         rerun_search = GNUNET_YES;
1715       }
1716       else
1717       {
1718         GCC_send_create (c);
1719         return;
1720       }
1721     }
1722     else
1723     {
1724       LOG (GNUNET_ERROR_TYPE_DEBUG, "  but is NULL, all paths are in use\n");
1725     }
1726   }
1727
1728   if (NULL != peer->search_h && GNUNET_YES == rerun_search)
1729   {
1730     GCD_search_stop (peer->search_h);
1731     peer->search_h = NULL;
1732     LOG (GNUNET_ERROR_TYPE_DEBUG, "  Stopping DHT GET for peer %s\n",
1733          GCP_2s (peer));
1734   }
1735
1736   if (NULL == peer->search_h)
1737   {
1738     const struct GNUNET_PeerIdentity *id;
1739
1740     id = GNUNET_PEER_resolve2 (peer->id);
1741     LOG (GNUNET_ERROR_TYPE_DEBUG,
1742                 "  Starting DHT GET for peer %s\n", GCP_2s (peer));
1743     peer->search_h = GCD_search (id, &search_handler, peer);
1744     if (CADET_TUNNEL_NEW == GCT_get_cstate (t)
1745         || 0 == GCT_count_any_connections (t))
1746       GCT_change_cstate (t, CADET_TUNNEL_SEARCHING);
1747   }
1748 }
1749
1750
1751 /**
1752  * Chech whether there is a direct (core level)  connection to peer.
1753  *
1754  * @param peer Peer to check.
1755  *
1756  * @return #GNUNET_YES if there is a direct connection.
1757  */
1758 int
1759 GCP_is_neighbor (const struct CadetPeer *peer)
1760 {
1761   struct CadetPeerPath *path;
1762
1763   if (NULL == peer->connections)
1764     return GNUNET_NO;
1765
1766   for (path = peer->path_head; NULL != path; path = path->next)
1767   {
1768     if (3 > path->length)
1769       return GNUNET_YES;
1770   }
1771
1772   /* Is not a neighbor but connections is not NULL, probably disconnecting */
1773   return GNUNET_NO;
1774 }
1775
1776
1777 /**
1778  * Create and initialize a new tunnel towards a peer, in case it has none.
1779  * In case the peer already has a tunnel, nothing is done.
1780  *
1781  * Does not generate any traffic, just creates the local data structures.
1782  *
1783  * @param peer Peer towards which to create the tunnel.
1784  */
1785 void
1786 GCP_add_tunnel (struct CadetPeer *peer)
1787 {
1788   if (NULL != peer->tunnel)
1789     return;
1790   peer->tunnel = GCT_new (peer);
1791 }
1792
1793
1794 /**
1795  * Add a connection to a neighboring peer.
1796  *
1797  * Store that the peer is the first hop of the connection in one
1798  * direction and that on peer disconnect the connection must be
1799  * notified and destroyed, for it will no longer be valid.
1800  *
1801  * @param peer Peer to add connection to.
1802  * @param c Connection to add.
1803  *
1804  * @return GNUNET_OK on success.
1805  */
1806 int
1807 GCP_add_connection (struct CadetPeer *peer,
1808                     struct CadetConnection *c)
1809 {
1810   int result;
1811   LOG (GNUNET_ERROR_TYPE_DEBUG, "adding connection %s\n", GCC_2s (c));
1812   LOG (GNUNET_ERROR_TYPE_DEBUG, "to peer %s\n", GCP_2s (peer));
1813
1814   if (NULL == peer->connections)
1815   {
1816     GNUNET_break (0);
1817     LOG (GNUNET_ERROR_TYPE_DEBUG,
1818          "Peer %s is not a neighbor!\n",
1819          GCP_2s (peer));
1820     return GNUNET_SYSERR;
1821   }
1822   LOG (GNUNET_ERROR_TYPE_DEBUG,
1823        "peer %s ok, has %u connections.\n",
1824        GCP_2s (peer), GNUNET_CONTAINER_multihashmap_size (peer->connections));
1825   result = GNUNET_CONTAINER_multihashmap_put (peer->connections,
1826                                               GCC_get_h (c),
1827                                               c,
1828                                               GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1829   LOG (GNUNET_ERROR_TYPE_DEBUG,
1830        " now has %u connections.\n",
1831        GNUNET_CONTAINER_multihashmap_size (peer->connections));
1832   LOG (GNUNET_ERROR_TYPE_DEBUG, "result %u\n", result);
1833
1834   return result;
1835 }
1836
1837
1838 /**
1839  * Add the path to the peer and update the path used to reach it in case this
1840  * is the shortest.
1841  *
1842  * @param peer Destination peer to add the path to.
1843  * @param path New path to add. Last peer must be the peer in arg 1.
1844  *             Path will be either used of freed if already known.
1845  * @param trusted Do we trust that this path is real?
1846  *
1847  * @return path if path was taken, pointer to existing duplicate if exists
1848  *         NULL on error.
1849  */
1850 struct CadetPeerPath *
1851 GCP_add_path (struct CadetPeer *peer, struct CadetPeerPath *path,
1852               int trusted)
1853 {
1854   struct CadetPeerPath *aux;
1855   unsigned int l;
1856   unsigned int l2;
1857
1858   LOG (GNUNET_ERROR_TYPE_DEBUG, "adding path [%u] to peer %s\n",
1859        path->length, GCP_2s (peer));
1860
1861   if ((NULL == peer) || (NULL == path))
1862   {
1863     GNUNET_break (0);
1864     path_destroy (path);
1865     return NULL;
1866   }
1867   if (path->peers[path->length - 1] != peer->id)
1868   {
1869     GNUNET_break (0);
1870     path_destroy (path);
1871     return NULL;
1872   }
1873
1874   for (l = 1; l < path->length; l++)
1875   {
1876     if (path->peers[l] == myid)
1877     {
1878       LOG (GNUNET_ERROR_TYPE_DEBUG, " shortening path by %u\n", l);
1879       for (l2 = 0; l2 < path->length - l; l2++)
1880       {
1881         path->peers[l2] = path->peers[l + l2];
1882       }
1883       path->length -= l;
1884       l = 1;
1885       path->peers = GNUNET_realloc (path->peers,
1886                                     path->length * sizeof (GNUNET_PEER_Id));
1887     }
1888   }
1889
1890   LOG (GNUNET_ERROR_TYPE_DEBUG, " final length: %u\n", path->length);
1891
1892   if (2 >= path->length && GNUNET_NO == trusted)
1893   {
1894     /* Only allow CORE to tell us about direct paths */
1895     path_destroy (path);
1896     return NULL;
1897   }
1898
1899   l = path_get_length (path);
1900   if (0 == l)
1901   {
1902     path_destroy (path);
1903     return NULL;
1904   }
1905
1906   GNUNET_assert (peer->id == path->peers[path->length - 1]);
1907   for (aux = peer->path_head; aux != NULL; aux = aux->next)
1908   {
1909     l2 = path_get_length (aux);
1910     if (l2 > l)
1911     {
1912       LOG (GNUNET_ERROR_TYPE_DEBUG, "  added\n");
1913       GNUNET_CONTAINER_DLL_insert_before (peer->path_head,
1914                                           peer->path_tail, aux, path);
1915       if (NULL != peer->tunnel && 3 < GCT_count_connections (peer->tunnel))
1916       {
1917         GCP_connect (peer);
1918       }
1919       return path;
1920     }
1921     else
1922     {
1923       if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
1924       {
1925         LOG (GNUNET_ERROR_TYPE_DEBUG, "  already known\n");
1926         path_destroy (path);
1927         return aux;
1928       }
1929     }
1930   }
1931   GNUNET_CONTAINER_DLL_insert_tail (peer->path_head, peer->path_tail,
1932                                     path);
1933   LOG (GNUNET_ERROR_TYPE_DEBUG, "  added last\n");
1934   if (NULL != peer->tunnel && 3 < GCT_count_connections (peer->tunnel))
1935   {
1936     GCP_connect (peer);
1937   }
1938   return path;
1939 }
1940
1941
1942 /**
1943  * Add the path to the origin peer and update the path used to reach it in case
1944  * this is the shortest.
1945  * The path is given in peer_info -> destination, therefore we turn the path
1946  * upside down first.
1947  *
1948  * @param peer Peer to add the path to, being the origin of the path.
1949  * @param path New path to add after being inversed.
1950  *             Path will be either used or freed.
1951  * @param trusted Do we trust that this path is real?
1952  *
1953  * @return path if path was taken, pointer to existing duplicate if exists
1954  *         NULL on error.
1955  */
1956 struct CadetPeerPath *
1957 GCP_add_path_to_origin (struct CadetPeer *peer,
1958                         struct CadetPeerPath *path,
1959                         int trusted)
1960 {
1961   if (NULL == path)
1962     return NULL;
1963   path_invert (path);
1964   return GCP_add_path (peer, path, trusted);
1965 }
1966
1967
1968 /**
1969  * Adds a path to the info of all the peers in the path
1970  *
1971  * @param p Path to process.
1972  * @param confirmed Whether we know if the path works or not.
1973  */
1974 void
1975 GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed)
1976 {
1977   unsigned int i;
1978
1979   /* TODO: invert and add */
1980   for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
1981   for (i++; i < p->length; i++)
1982   {
1983     struct CadetPeer *aux;
1984     struct CadetPeerPath *copy;
1985
1986     aux = GCP_get_short (p->peers[i]);
1987     copy = path_duplicate (p);
1988     copy->length = i + 1;
1989     GCP_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
1990   }
1991 }
1992
1993
1994 /**
1995  * Remove any path to the peer that has the extact same peers as the one given.
1996  *
1997  * @param peer Peer to remove the path from.
1998  * @param path Path to remove. Is always destroyed .
1999  */
2000 void
2001 GCP_remove_path (struct CadetPeer *peer, struct CadetPeerPath *path)
2002 {
2003   struct CadetPeerPath *iter;
2004   struct CadetPeerPath *next;
2005
2006   GNUNET_assert (myid == path->peers[0]);
2007   GNUNET_assert (peer->id == path->peers[path->length - 1]);
2008
2009   for (iter = peer->path_head; NULL != iter; iter = next)
2010   {
2011     next = iter->next;
2012     if (0 == memcmp (path->peers, iter->peers,
2013                      sizeof (GNUNET_PEER_Id) * path->length))
2014     {
2015       GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, iter);
2016       if (iter != path)
2017         path_destroy (iter);
2018     }
2019   }
2020   path_destroy (path);
2021 }
2022
2023
2024 /**
2025  * Remove a connection from a neighboring peer.
2026  *
2027  * @param peer Peer to remove connection from.
2028  * @param c Connection to remove.
2029  *
2030  * @return GNUNET_OK on success.
2031  */
2032 int
2033 GCP_remove_connection (struct CadetPeer *peer,
2034                        const struct CadetConnection *c)
2035 {
2036   LOG (GNUNET_ERROR_TYPE_DEBUG, "removing connection %s\n", GCC_2s (c));
2037   LOG (GNUNET_ERROR_TYPE_DEBUG, "from peer %s\n", GCP_2s (peer));
2038
2039   if (NULL == peer || NULL == peer->connections)
2040   {
2041     LOG (GNUNET_ERROR_TYPE_DEBUG,
2042          "Peer %s is not a neighbor!\n",
2043          GCP_2s (peer));
2044     return GNUNET_SYSERR;
2045   }
2046   LOG (GNUNET_ERROR_TYPE_DEBUG,
2047        "peer %s ok, has %u connections.\n",
2048        GCP_2s (peer), GNUNET_CONTAINER_multihashmap_size (peer->connections));
2049
2050   return GNUNET_CONTAINER_multihashmap_remove (peer->connections,
2051                                                GCC_get_h (c),
2052                                                c);
2053 }
2054
2055 /**
2056  * Start the DHT search for new paths towards the peer: we don't have
2057  * enough good connections.
2058  *
2059  * @param peer Destination peer.
2060  */
2061 void
2062 GCP_start_search (struct CadetPeer *peer)
2063 {
2064   if (NULL != peer->search_h)
2065   {
2066     GNUNET_break (0);
2067     return;
2068   }
2069
2070   peer->search_h = GCD_search (GCP_get_id (peer), &search_handler, peer);
2071 }
2072
2073
2074 /**
2075  * Stop the DHT search for new paths towards the peer: we already have
2076  * enough good connections.
2077  *
2078  * @param peer Destination peer.
2079  */
2080 void
2081 GCP_stop_search (struct CadetPeer *peer)
2082 {
2083   if (NULL == peer->search_h)
2084   {
2085     return;
2086   }
2087
2088   GCD_search_stop (peer->search_h);
2089   peer->search_h = NULL;
2090 }
2091
2092
2093 /**
2094  * Get the Full ID of a peer.
2095  *
2096  * @param peer Peer to get from.
2097  *
2098  * @return Full ID of peer.
2099  */
2100 const struct GNUNET_PeerIdentity *
2101 GCP_get_id (const struct CadetPeer *peer)
2102 {
2103   return GNUNET_PEER_resolve2 (peer->id);
2104 }
2105
2106
2107 /**
2108  * Get the Short ID of a peer.
2109  *
2110  * @param peer Peer to get from.
2111  *
2112  * @return Short ID of peer.
2113  */
2114 GNUNET_PEER_Id
2115 GCP_get_short_id (const struct CadetPeer *peer)
2116 {
2117   return peer->id;
2118 }
2119
2120
2121 /**
2122  * Set tunnel.
2123  *
2124  * @param peer Peer.
2125  * @param t Tunnel.
2126  */
2127 void
2128 GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t)
2129 {
2130   peer->tunnel = t;
2131   if (NULL == t && NULL != peer->search_h)
2132   {
2133     GCP_stop_search (peer);
2134   }
2135 }
2136
2137
2138 /**
2139  * Get the tunnel towards a peer.
2140  *
2141  * @param peer Peer to get from.
2142  *
2143  * @return Tunnel towards peer.
2144  */
2145 struct CadetTunnel *
2146 GCP_get_tunnel (const struct CadetPeer *peer)
2147 {
2148   return peer->tunnel;
2149 }
2150
2151
2152 /**
2153  * Set the hello message.
2154  *
2155  * @param peer Peer whose message to set.
2156  * @param hello Hello message.
2157  */
2158 void
2159 GCP_set_hello (struct CadetPeer *peer, const struct GNUNET_HELLO_Message *hello)
2160 {
2161   struct GNUNET_HELLO_Message *old;
2162   size_t size;
2163
2164   LOG (GNUNET_ERROR_TYPE_DEBUG, "set hello for %s\n", GCP_2s (peer));
2165   if (NULL == hello)
2166     return;
2167
2168   old = GCP_get_hello (peer);
2169   if (NULL == old)
2170   {
2171     size = GNUNET_HELLO_size (hello);
2172     LOG (GNUNET_ERROR_TYPE_DEBUG, " new (%u bytes)\n", size);
2173     peer->hello = GNUNET_malloc (size);
2174     memcpy (peer->hello, hello, size);
2175   }
2176   else
2177   {
2178     peer->hello = GNUNET_HELLO_merge (old, hello);
2179     LOG (GNUNET_ERROR_TYPE_DEBUG, " merge into %p (%u bytes)\n",
2180          peer->hello, GNUNET_HELLO_size (hello));
2181     GNUNET_free (old);
2182   }
2183 }
2184
2185
2186 /**
2187  * Get the hello message.
2188  *
2189  * @param peer Peer whose message to get.
2190  *
2191  * @return Hello message.
2192  */
2193 struct GNUNET_HELLO_Message *
2194 GCP_get_hello (struct CadetPeer *peer)
2195 {
2196   struct GNUNET_TIME_Absolute expiration;
2197   struct GNUNET_TIME_Relative remaining;
2198
2199   if (NULL == peer->hello)
2200     return NULL;
2201
2202   expiration = GNUNET_HELLO_get_last_expiration (peer->hello);
2203   remaining = GNUNET_TIME_absolute_get_remaining (expiration);
2204   if (0 == remaining.rel_value_us)
2205   {
2206     LOG (GNUNET_ERROR_TYPE_DEBUG, " get - hello expired on %s\n",
2207          GNUNET_STRINGS_absolute_time_to_string (expiration));
2208     GNUNET_free (peer->hello);
2209     peer->hello = NULL;
2210   }
2211   return peer->hello;
2212 }
2213
2214
2215 /**
2216  * Try to connect to a peer on TRANSPORT level.
2217  *
2218  * @param peer Peer to whom to connect.
2219  */
2220 void
2221 GCP_try_connect (struct CadetPeer *peer)
2222 {
2223   struct GNUNET_HELLO_Message *hello;
2224   struct GNUNET_MessageHeader *mh;
2225
2226   if (NULL == transport_handle)
2227     return;
2228
2229   hello = GCP_get_hello (peer);
2230   if (NULL == hello)
2231     return;
2232
2233   mh = GNUNET_HELLO_get_header (hello);
2234   GNUNET_TRANSPORT_offer_hello (transport_handle, mh, try_connect, peer);
2235 }
2236
2237
2238 /**
2239  * Notify a peer that a link between two other peers is broken. If any path
2240  * used that link, eliminate it.
2241  *
2242  * @param peer Peer affected by the change.
2243  * @param peer1 Peer whose link is broken.
2244  * @param peer2 Peer whose link is broken.
2245  */
2246 void
2247 GCP_notify_broken_link (struct CadetPeer *peer,
2248                         struct GNUNET_PeerIdentity *peer1,
2249                         struct GNUNET_PeerIdentity *peer2)
2250 {
2251   struct CadetPeerPath *iter;
2252   struct CadetPeerPath *next;
2253   unsigned int i;
2254   GNUNET_PEER_Id p1;
2255   GNUNET_PEER_Id p2;
2256
2257   p1 = GNUNET_PEER_search (peer1);
2258   p2 = GNUNET_PEER_search (peer2);
2259
2260   LOG (GNUNET_ERROR_TYPE_DEBUG, "Link %u-%u broken\n", p1, p2);
2261   if (0 == p1 || 0 == p2)
2262   {
2263     /* We don't even know them */
2264     return;
2265   }
2266
2267   for (iter = peer->path_head; NULL != iter; iter = next)
2268   {
2269     next = iter->next;
2270     for (i = 0; i < iter->length - 1; i++)
2271     {
2272       if ((iter->peers[i] == p1 && iter->peers[i + 1] == p2)
2273           || (iter->peers[i] == p2 && iter->peers[i + 1] == p1))
2274       {
2275         char *s;
2276
2277         s = path_2s (iter);
2278         LOG (GNUNET_ERROR_TYPE_DEBUG, " - invalidating %s\n", s);
2279         GNUNET_free (s);
2280
2281         path_invalidate (iter);
2282       }
2283     }
2284   }
2285 }
2286
2287
2288 /**
2289  * Count the number of known paths toward the peer.
2290  *
2291  * @param peer Peer to get path info.
2292  *
2293  * @return Number of known paths.
2294  */
2295 unsigned int
2296 GCP_count_paths (const struct CadetPeer *peer)
2297 {
2298   struct CadetPeerPath *iter;
2299   unsigned int i;
2300
2301   for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next)
2302     i++;
2303
2304   return i;
2305 }
2306
2307
2308 /**
2309  * Iterate all known peers.
2310  *
2311  * @param iter Iterator.
2312  * @param cls Closure for @c iter.
2313  */
2314 void
2315 GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls)
2316 {
2317   GNUNET_CONTAINER_multipeermap_iterate (peers, iter, cls);
2318 }
2319
2320
2321 /**
2322  * Get the static string for a peer ID.
2323  *
2324  * @param peer Peer.
2325  *
2326  * @return Static string for it's ID.
2327  */
2328 const char *
2329 GCP_2s (const struct CadetPeer *peer)
2330 {
2331   if (NULL == peer)
2332     return "(NULL)";
2333   return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
2334 }