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