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