Merge branch 'master' of gnunet.org:gnunet
[oweals/gnunet.git] / src / cadet / gnunet-service-cadet_peer.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2001-2017 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file cadet/gnunet-service-cadet_peer.c
23  * @brief Information we track per peer.
24  * @author Bartlomiej Polot
25  * @author Christian Grothoff
26  *
27  * TODO:
28  * - optimize stopping/restarting DHT search to situations
29  *   where we actually need it (i.e. not if we have a direct connection,
30  *   or if we already have plenty of good short ones, or maybe even
31  *   to take a break if we have some connections and have searched a lot (?))
32  */
33 #include "platform.h"
34 #include "gnunet_util_lib.h"
35 #include "gnunet_hello_lib.h"
36 #include "gnunet_signatures.h"
37 #include "gnunet_transport_service.h"
38 #include "gnunet_ats_service.h"
39 #include "gnunet_core_service.h"
40 #include "gnunet_statistics_service.h"
41 #include "cadet_protocol.h"
42 #include "gnunet-service-cadet_connection.h"
43 #include "gnunet-service-cadet_dht.h"
44 #include "gnunet-service-cadet_peer.h"
45 #include "gnunet-service-cadet_paths.h"
46 #include "gnunet-service-cadet_tunnels.h"
47
48
49 #define LOG(level, ...) GNUNET_log_from(level,"cadet-per",__VA_ARGS__)
50
51
52 /**
53  * How long do we wait until tearing down an idle peer?
54  */
55 #define IDLE_PEER_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5)
56
57 /**
58  * How long do we keep paths around if we no longer care about the peer?
59  */
60 #define IDLE_PATH_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
61
62 /**
63  * Queue size when we start dropping OOO messages.
64  */
65 #define MAX_OOO_QUEUE_SIZE  100
66
67
68 /**
69  * Data structure used to track whom we have to notify about changes
70  * to our message queue.
71  */
72 struct GCP_MessageQueueManager
73 {
74
75   /**
76    * Kept in a DLL.
77    */
78   struct GCP_MessageQueueManager *next;
79
80   /**
81    * Kept in a DLL.
82    */
83   struct GCP_MessageQueueManager *prev;
84
85   /**
86    * Function to call with updated message queue object.
87    */
88   GCP_MessageQueueNotificationCallback cb;
89
90   /**
91    * Closure for @e cb.
92    */
93   void *cb_cls;
94
95   /**
96    * The peer this is for.
97    */
98   struct CadetPeer *cp;
99
100   /**
101    * Envelope this manager would like to transmit once it is its turn.
102    */
103   struct GNUNET_MQ_Envelope *env;
104
105 };
106
107
108 /**
109  * Struct containing all information regarding a given peer
110  */
111 struct CadetPeer
112 {
113   /**
114    * ID of the peer
115    */
116   struct GNUNET_PeerIdentity pid;
117
118   /**
119    * Last time we heard from this peer (currently not used!)
120    */
121   struct GNUNET_TIME_Absolute last_contactXXX;
122
123   /**
124    * Array of DLLs of paths traversing the peer, organized by the
125    * offset of the peer on the larger path.
126    */
127   struct CadetPeerPathEntry **path_heads;
128
129   /**
130    * Array of DLL of paths traversing the peer, organized by the
131    * offset of the peer on the larger path.
132    */
133   struct CadetPeerPathEntry **path_tails;
134
135   /**
136    * Notifications to call when @e core_mq changes.
137    */
138   struct GCP_MessageQueueManager *mqm_head;
139
140   /**
141    * Notifications to call when @e core_mq changes.
142    */
143   struct GCP_MessageQueueManager *mqm_tail;
144
145   /**
146    * Pointer to first "ready" entry in @e mqm_head.
147    */
148   struct GCP_MessageQueueManager *mqm_ready_ptr;
149
150   /**
151    * MIN-heap of paths owned by this peer (they also end at this
152    * peer).  Ordered by desirability.
153    */
154   struct GNUNET_CONTAINER_Heap *path_heap;
155
156   /**
157    * Handle to stop the DHT search for paths to this peer
158    */
159   struct GCD_search_handle *search_h;
160
161   /**
162    * Task to clean up @e path_heap asynchronously.
163    */
164   struct GNUNET_SCHEDULER_Task *heap_cleanup_task;
165
166   /**
167    * Task to destroy this entry.
168    */
169   struct GNUNET_SCHEDULER_Task *destroy_task;
170
171   /**
172    * Tunnel to this peer, if any.
173    */
174   struct CadetTunnel *t;
175
176   /**
177    * Connections that go through this peer; indexed by tid.
178    */
179   struct GNUNET_CONTAINER_MultiShortmap *connections;
180
181   /**
182    * Handle for core transmissions.
183    */
184   struct GNUNET_MQ_Handle *core_mq;
185
186   /**
187    * Hello message of the peer.
188    */
189   struct GNUNET_HELLO_Message *hello;
190
191   /**
192    * Handle to us offering the HELLO to the transport.
193    */
194   struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer;
195
196   /**
197    * Handle to our ATS request asking ATS to suggest an address
198    * to TRANSPORT for this peer (to establish a direct link).
199    */
200   struct GNUNET_ATS_ConnectivitySuggestHandle *connectivity_suggestion;
201
202   /**
203    * How many messages are in the queue to this peer.
204    */
205   unsigned int queue_n;
206
207   /**
208    * How many paths do we have to this peer (in all @e path_heads DLLs combined).
209    */
210   unsigned int num_paths;
211
212   /**
213    * Sum over all of the offsets of all of the paths in the @a path_heads DLLs.
214    * Used to speed-up @GCP_get_desirability_of_path() calculation.
215    */
216   unsigned int off_sum;
217
218   /**
219    * Number of message queue managers of this peer that have a message in waiting.
220    *
221    * Used to quickly see if we need to bother scanning the @e msm_head DLL.
222    * TODO: could be replaced by another DLL that would then allow us to avoid
223    * the O(n)-scan of the DLL for ready entries!
224    */
225   unsigned int mqm_ready_counter;
226
227   /**
228    * Current length of the @e path_heads and @path_tails arrays.
229    * The arrays should be grown as needed.
230    */
231   unsigned int path_dll_length;
232
233 };
234
235
236 /**
237  * Get the static string for a peer ID.
238  *
239  * @param cp Peer.
240  * @return Static string for it's ID.
241  */
242 const char *
243 GCP_2s (const struct CadetPeer *cp)
244 {
245   static char buf[32];
246
247   GNUNET_snprintf (buf,
248                    sizeof (buf),
249                    "P(%s)",
250                    GNUNET_i2s (&cp->pid));
251   return buf;
252 }
253
254
255 /**
256  * Calculate how desirable a path is for @a cp if @a cp
257  * is at offset @a off.
258  *
259  * The 'desirability_table.c' program can be used to compute a list of
260  * sample outputs for different scenarios.  Basically, we score paths
261  * lower if there are many alternatives, and higher if they are
262  * shorter than average, and very high if they are much shorter than
263  * average and without many alternatives.
264  *
265  * @param cp a peer reachable via a path
266  * @param off offset of @a cp in the path
267  * @return score how useful a path is to reach @a cp,
268  *         positive scores mean path is more desirable
269  */
270 double
271 GCP_get_desirability_of_path (struct CadetPeer *cp,
272                               unsigned int off)
273 {
274   unsigned int num_alts = cp->num_paths;
275   unsigned int off_sum;
276   double avg_sum;
277   double path_delta;
278   double weight_alts;
279
280   GNUNET_assert (num_alts >= 1); /* 'path' should be in there! */
281   GNUNET_assert (0 != cp->path_dll_length);
282
283   /* We maintain 'off_sum' in 'peer' and thereby
284      avoid the SLOW recalculation each time. Kept here
285      just to document what is going on. */
286 #if SLOW
287   off_sum = 0;
288   for (unsigned int j=0;j<cp->path_dll_length;j++)
289     for (struct CadetPeerPathEntry *pe = cp->path_heads[j];
290          NULL != pe;
291          pe = pe->next)
292       off_sum += j;
293   GNUNET_assert (off_sum == cp->off_sum);
294 #else
295   off_sum = cp->off_sum;
296 #endif
297   avg_sum = off_sum * 1.0 / cp->path_dll_length;
298   path_delta = off - avg_sum;
299   /* path_delta positiv: path off of peer above average (bad path for peer),
300      path_delta negativ: path off of peer below average (good path for peer) */
301   if (path_delta <= - 1.0)
302     weight_alts = - num_alts / path_delta; /* discount alternative paths */
303   else if (path_delta >= 1.0)
304     weight_alts = num_alts * path_delta; /* overcount alternative paths */
305   else
306     weight_alts = num_alts; /* count alternative paths normally */
307
308
309   /* off+1: long paths are generally harder to find and thus count
310      a bit more as they get longer.  However, above-average paths
311      still need to count less, hence the squaring of that factor. */
312   return (off + 1.0) / (weight_alts * weight_alts);
313 }
314
315
316 /**
317  * This peer is no longer be needed, clean it up now.
318  *
319  * @param cls peer to clean up
320  */
321 static void
322 destroy_peer (void *cls)
323 {
324   struct CadetPeer *cp = cls;
325
326   LOG (GNUNET_ERROR_TYPE_DEBUG,
327        "Destroying state about peer %s\n",
328        GCP_2s (cp));
329   cp->destroy_task = NULL;
330   GNUNET_assert (NULL == cp->t);
331   GNUNET_assert (NULL == cp->core_mq);
332   GNUNET_assert (0 == cp->num_paths);
333   for (unsigned int i=0;i<cp->path_dll_length;i++)
334     GNUNET_assert (NULL == cp->path_heads[i]);
335   GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections));
336   GNUNET_assert (GNUNET_YES ==
337                  GNUNET_CONTAINER_multipeermap_remove (peers,
338                                                        &cp->pid,
339                                                        cp));
340   GNUNET_free_non_null (cp->path_heads);
341   GNUNET_free_non_null (cp->path_tails);
342   cp->path_dll_length = 0;
343   if (NULL != cp->search_h)
344   {
345     GCD_search_stop (cp->search_h);
346     cp->search_h = NULL;
347   }
348   /* FIXME: clean up search_delayedXXX! */
349
350   if (NULL != cp->hello_offer)
351   {
352     GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer);
353     cp->hello_offer = NULL;
354   }
355   if (NULL != cp->connectivity_suggestion)
356   {
357     GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
358     cp->connectivity_suggestion = NULL;
359   }
360   GNUNET_CONTAINER_multishortmap_destroy (cp->connections);
361   if (NULL != cp->path_heap)
362   {
363     GNUNET_CONTAINER_heap_destroy (cp->path_heap);
364     cp->path_heap = NULL;
365   }
366   if (NULL != cp->heap_cleanup_task)
367   {
368     GNUNET_SCHEDULER_cancel (cp->heap_cleanup_task);
369     cp->heap_cleanup_task = NULL;
370   }
371   GNUNET_free_non_null (cp->hello);
372   /* Peer should not be freed if paths exist; if there are no paths,
373      there ought to be no connections, and without connections, no
374      notifications. Thus we can assert that mqm_head is empty at this
375      point. */
376   GNUNET_assert (NULL == cp->mqm_head);
377   GNUNET_assert (NULL == cp->mqm_ready_ptr);
378   GNUNET_free (cp);
379 }
380
381
382 /**
383  * This peer is now on more "active" duty, activate processes related to it.
384  *
385  * @param cp the more-active peer
386  */
387 static void
388 consider_peer_activate (struct CadetPeer *cp)
389 {
390   uint32_t strength;
391
392   LOG (GNUNET_ERROR_TYPE_DEBUG,
393        "Updating peer %s activation state (%u connections)%s%s\n",
394        GCP_2s (cp),
395        GNUNET_CONTAINER_multishortmap_size (cp->connections),
396        (NULL == cp->t) ? "" : " with tunnel",
397        (NULL == cp->core_mq) ? "" : " with CORE link");
398   if (NULL != cp->destroy_task)
399   {
400     /* It's active, do not destory! */
401     GNUNET_SCHEDULER_cancel (cp->destroy_task);
402     cp->destroy_task = NULL;
403   }
404   if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) &&
405        (NULL == cp->t) )
406   {
407     /* We're just on a path or directly connected; don't bother too much */
408     if (NULL != cp->connectivity_suggestion)
409     {
410       GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
411       cp->connectivity_suggestion = NULL;
412     }
413     if (NULL != cp->search_h)
414     {
415       GCD_search_stop (cp->search_h);
416       cp->search_h = NULL;
417     }
418     return;
419   }
420   if (NULL == cp->core_mq)
421   {
422     /* Lacks direct connection, try to create one by querying the DHT */
423     if ( (NULL == cp->search_h) &&
424          (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
425       cp->search_h
426         = GCD_search (&cp->pid);
427   }
428   else
429   {
430     /* Have direct connection, stop DHT search if active */
431     if (NULL != cp->search_h)
432     {
433       GCD_search_stop (cp->search_h);
434       cp->search_h = NULL;
435     }
436   }
437
438   /* If we have a tunnel, our urge for connections is much bigger */
439   strength = (NULL != cp->t) ? 32 : 1;
440   if (NULL != cp->connectivity_suggestion)
441     GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
442   cp->connectivity_suggestion
443     = GNUNET_ATS_connectivity_suggest (ats_ch,
444                                        &cp->pid,
445                                        strength);
446 }
447
448
449 /**
450  * This peer may no longer be needed, consider cleaning it up.
451  *
452  * @param cp peer to clean up
453  */
454 static void
455 consider_peer_destroy (struct CadetPeer *cp);
456
457
458 /**
459  * We really no longere care about a peer, stop hogging memory with paths to it.
460  * Afterwards, see if there is more to be cleaned up about this peer.
461  *
462  * @param cls a `struct CadetPeer`.
463  */
464 static void
465 drop_paths (void *cls)
466 {
467   struct CadetPeer *cp = cls;
468   struct CadetPeerPath *path;
469
470   cp->destroy_task = NULL;
471   while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
472     GCPP_release (path);
473   consider_peer_destroy (cp);
474 }
475
476
477 /**
478  * This peer may no longer be needed, consider cleaning it up.
479  *
480  * @param cp peer to clean up
481  */
482 static void
483 consider_peer_destroy (struct CadetPeer *cp)
484 {
485   struct GNUNET_TIME_Relative exp;
486
487   if (NULL != cp->destroy_task)
488   {
489     GNUNET_SCHEDULER_cancel (cp->destroy_task);
490     cp->destroy_task = NULL;
491   }
492   if (NULL != cp->t)
493     return; /* still relevant! */
494   if (NULL != cp->core_mq)
495     return; /* still relevant! */
496   if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections))
497     return; /* still relevant! */
498   if ( (NULL != cp->path_heap) &&
499        (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap)) )
500   {
501     cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT,
502                                                      &drop_paths,
503                                                      cp);
504     return;
505   }
506   if (0 != cp->num_paths)
507     return; /* still relevant! */
508   if (NULL != cp->hello)
509   {
510     /* relevant only until HELLO expires */
511     exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello));
512     cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp,
513                                                      &destroy_peer,
514                                                      cp);
515     return;
516   }
517   cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT,
518                                                    &destroy_peer,
519                                                    cp);
520 }
521
522
523 /**
524  * Set the message queue to @a mq for peer @a cp and notify watchers.
525  *
526  * @param cp peer to modify
527  * @param mq message queue to set (can be NULL)
528  */
529 void
530 GCP_set_mq (struct CadetPeer *cp,
531             struct GNUNET_MQ_Handle *mq)
532 {
533   LOG (GNUNET_ERROR_TYPE_DEBUG,
534        "Message queue for peer %s is now %p\n",
535        GCP_2s (cp),
536        mq);
537   cp->core_mq = mq;
538   for (struct GCP_MessageQueueManager *mqm = cp->mqm_head, *next;
539        NULL != mqm;
540        mqm = next)
541   {
542     /* Save next pointer in case mqm gets freed by the callback */
543     next = mqm->next;
544     if (NULL == mq)
545     {
546       if (NULL != mqm->env)
547       {
548         GNUNET_MQ_discard (mqm->env);
549         mqm->env = NULL;
550         mqm->cb (mqm->cb_cls,
551                  GNUNET_SYSERR);
552       }
553       else
554       {
555         mqm->cb (mqm->cb_cls,
556                  GNUNET_NO);
557       }
558     }
559     else
560     {
561       GNUNET_assert (NULL == mqm->env);
562       mqm->cb (mqm->cb_cls,
563                GNUNET_YES);
564     }
565   }
566   if ( (NULL != mq) ||
567        (NULL != cp->t) )
568     consider_peer_activate (cp);
569   else
570     consider_peer_destroy (cp);
571
572   if ( (NULL != mq) &&
573        (NULL != cp->t) )
574   {
575     /* have a new, direct path to the target, notify tunnel */
576     struct CadetPeerPath *path;
577
578     path = GCPP_get_path_from_route (1,
579                                      &cp->pid);
580     GCT_consider_path (cp->t,
581                        path,
582                        0);
583   }
584 }
585
586
587 /**
588  * Debug function should NEVER return true in production code, useful to
589  * simulate losses for testcases.
590  *
591  * @return #GNUNET_YES or #GNUNET_NO with the decision to drop.
592  */
593 static int
594 should_I_drop (void)
595 {
596   if (0 == drop_percent)
597     return GNUNET_NO;
598   if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
599                                 101) < drop_percent)
600     return GNUNET_YES;
601   return GNUNET_NO;
602 }
603
604
605 /**
606  * Function called when CORE took one of the messages from
607  * a message queue manager and transmitted it.
608  *
609  * @param cls the `struct CadetPeeer` where we made progress
610  */
611 static void
612 mqm_send_done (void *cls);
613
614
615 /**
616  * Transmit current envelope from this @a mqm.
617  *
618  * @param mqm mqm to transmit message for now
619  */
620 static void
621 mqm_execute (struct GCP_MessageQueueManager *mqm)
622 {
623   struct CadetPeer *cp = mqm->cp;
624
625   /* Move ready pointer to the next entry that might be ready. */
626   if ( (mqm == cp->mqm_ready_ptr) &&
627        (NULL != mqm->next) )
628     cp->mqm_ready_ptr = mqm->next;
629   /* Move entry to the end of the DLL, to be fair. */
630   if (mqm != cp->mqm_tail)
631   {
632     GNUNET_CONTAINER_DLL_remove (cp->mqm_head,
633                                  cp->mqm_tail,
634                                  mqm);
635     GNUNET_CONTAINER_DLL_insert_tail (cp->mqm_head,
636                                       cp->mqm_tail,
637                                       mqm);
638   }
639   cp->mqm_ready_counter--;
640   if (GNUNET_YES == should_I_drop ())
641   {
642     LOG (GNUNET_ERROR_TYPE_DEBUG,
643          "DROPPING message to peer %s from MQM %p\n",
644          GCP_2s (cp),
645          mqm);
646     GNUNET_MQ_discard (mqm->env);
647     mqm->env = NULL;
648     mqm_send_done (cp);
649   }
650   else
651   {
652     LOG (GNUNET_ERROR_TYPE_DEBUG,
653          "Sending to peer %s from MQM %p\n",
654          GCP_2s (cp),
655          mqm);
656     GNUNET_MQ_send (cp->core_mq,
657                     mqm->env);
658     mqm->env = NULL;
659   }
660   mqm->cb (mqm->cb_cls,
661            GNUNET_YES);
662 }
663
664
665 /**
666  * Find the next ready message in the queue (starting
667  * the search from the `cp->mqm_ready_ptr`) and if possible
668  * execute the transmission.
669  *
670  * @param cp peer to try to send the next ready message to
671  */
672 static void
673 send_next_ready (struct CadetPeer *cp)
674 {
675   struct GCP_MessageQueueManager *mqm;
676
677   if (0 == cp->mqm_ready_counter)
678     return;
679   while ( (NULL != (mqm = cp->mqm_ready_ptr)) &&
680           (NULL == mqm->env) )
681     cp->mqm_ready_ptr = mqm->next;
682   if (NULL == mqm)
683     return; /* nothing to do */
684   mqm_execute (mqm);
685 }
686
687
688 /**
689  * Function called when CORE took one of the messages from
690  * a message queue manager and transmitted it.
691  *
692  * @param cls the `struct CadetPeeer` where we made progress
693  */
694 static void
695 mqm_send_done (void *cls)
696 {
697   struct CadetPeer *cp = cls;
698
699   LOG (GNUNET_ERROR_TYPE_DEBUG,
700        "Sending to peer %s completed\n",
701        GCP_2s (cp));
702   send_next_ready (cp);
703 }
704
705
706 /**
707  * Send the message in @a env to @a cp.
708  *
709  * @param mqm the message queue manager to use for transmission
710  * @param env envelope with the message to send; must NOT
711  *            yet have a #GNUNET_MQ_notify_sent() callback attached to it
712  */
713 void
714 GCP_send (struct GCP_MessageQueueManager *mqm,
715           struct GNUNET_MQ_Envelope *env)
716 {
717   struct CadetPeer *cp = mqm->cp;
718
719   GNUNET_assert (NULL != env);
720   LOG (GNUNET_ERROR_TYPE_DEBUG,
721        "Queueing message to peer %s in MQM %p\n",
722        GCP_2s (cp),
723        mqm);
724   GNUNET_assert (NULL != cp->core_mq);
725   GNUNET_assert (NULL == mqm->env);
726   GNUNET_MQ_notify_sent (env,
727                          &mqm_send_done,
728                          cp);
729   mqm->env = env;
730   cp->mqm_ready_counter++;
731   if (mqm != cp->mqm_ready_ptr)
732     cp->mqm_ready_ptr = cp->mqm_head;
733   if (1 == cp->mqm_ready_counter)
734     cp->mqm_ready_ptr = mqm;
735   if (0 != GNUNET_MQ_get_length (cp->core_mq))
736     return;
737   send_next_ready (cp);
738 }
739
740
741 /**
742  * Function called to destroy a peer now.
743  *
744  * @param cls NULL
745  * @param pid identity of the peer (unused)
746  * @param value the `struct CadetPeer` to clean up
747  * @return #GNUNET_OK (continue to iterate)
748  */
749 static int
750 destroy_iterator_cb (void *cls,
751                      const struct GNUNET_PeerIdentity *pid,
752                      void *value)
753 {
754   struct CadetPeer *cp = value;
755
756   if (NULL != cp->destroy_task)
757   {
758     GNUNET_SCHEDULER_cancel (cp->destroy_task);
759     cp->destroy_task = NULL;
760   }
761   destroy_peer (cp);
762   return GNUNET_OK;
763 }
764
765
766 /**
767  * Clean up all entries about all peers.
768  * Must only be called after all tunnels, CORE-connections and
769  * connections are down.
770  */
771 void
772 GCP_destroy_all_peers ()
773 {
774   LOG (GNUNET_ERROR_TYPE_DEBUG,
775        "Destroying all peers now\n");
776   GNUNET_CONTAINER_multipeermap_iterate (peers,
777                                          &destroy_iterator_cb,
778                                          NULL);
779 }
780
781
782 /**
783  * Drop all paths owned by this peer, and do not
784  * allow new ones to be added: We are shutting down.
785  *
786  * @param cp peer to drop paths to
787  */
788 void
789 GCP_drop_owned_paths (struct CadetPeer *cp)
790 {
791   struct CadetPeerPath *path;
792
793   LOG (GNUNET_ERROR_TYPE_DEBUG,
794        "Destroying all paths to %s\n",
795        GCP_2s (cp));
796   while (NULL != (path =
797                   GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
798     GCPP_release (path);
799   GNUNET_CONTAINER_heap_destroy (cp->path_heap);
800   cp->path_heap = NULL;
801 }
802
803
804 /**
805  * Add an entry to the DLL of all of the paths that this peer is on.
806  *
807  * @param cp peer to modify
808  * @param entry an entry on a path
809  * @param off offset of this peer on the path
810  */
811 void
812 GCP_path_entry_add (struct CadetPeer *cp,
813                     struct CadetPeerPathEntry *entry,
814                     unsigned int off)
815 {
816   GNUNET_assert (cp == GCPP_get_peer_at_offset (entry->path,
817                                                 off));
818   LOG (GNUNET_ERROR_TYPE_DEBUG,
819        "Discovered that peer %s is on path %s at offset %u\n",
820        GCP_2s (cp),
821        GCPP_2s (entry->path),
822        off);
823   if (off >= cp->path_dll_length)
824   {
825     unsigned int len = cp->path_dll_length;
826
827     GNUNET_array_grow (cp->path_heads,
828                        len,
829                        off + 4);
830     GNUNET_array_grow (cp->path_tails,
831                        cp->path_dll_length,
832                        off + 4);
833   }
834   GNUNET_CONTAINER_DLL_insert (cp->path_heads[off],
835                                cp->path_tails[off],
836                                entry);
837   cp->off_sum += off;
838   cp->num_paths++;
839
840   /* If we have a tunnel to this peer, tell the tunnel that there is a
841      new path available. */
842   if (NULL != cp->t)
843     GCT_consider_path (cp->t,
844                        entry->path,
845                        off);
846
847   if ( (NULL != cp->search_h) &&
848        (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths) )
849   {
850     /* Now I have enough paths, stop search */
851     GCD_search_stop (cp->search_h);
852     cp->search_h = NULL;
853   }
854   if (NULL != cp->destroy_task)
855   {
856     /* paths changed, this resets the destroy timeout counter
857        and aborts a destroy task that may no longer be valid
858        to have (as we now have more paths via this peer). */
859     consider_peer_destroy (cp);
860   }
861 }
862
863
864 /**
865  * Remove an entry from the DLL of all of the paths that this peer is on.
866  *
867  * @param cp peer to modify
868  * @param entry an entry on a path
869  * @param off offset of this peer on the path
870  */
871 void
872 GCP_path_entry_remove (struct CadetPeer *cp,
873                        struct CadetPeerPathEntry *entry,
874                        unsigned int off)
875 {
876   LOG (GNUNET_ERROR_TYPE_DEBUG,
877        "Removing knowledge about peer %s beging on path %s at offset %u\n",
878        GCP_2s (cp),
879        GCPP_2s (entry->path),
880        off);
881   GNUNET_CONTAINER_DLL_remove (cp->path_heads[off],
882                                cp->path_tails[off],
883                                entry);
884   GNUNET_assert (0 < cp->num_paths);
885   cp->off_sum -= off;
886   cp->num_paths--;
887   if ( (NULL == cp->core_mq) &&
888        (NULL != cp->t) &&
889        (NULL == cp->search_h) &&
890        (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
891     cp->search_h
892       = GCD_search (&cp->pid);
893   if (NULL == cp->destroy_task)
894   {
895     /* paths changed, we might now be ready for destruction, check again */
896     consider_peer_destroy (cp);
897   }
898 }
899
900
901 /**
902  * Prune down the number of paths to this peer, we seem to
903  * have way too many.
904  *
905  * @param cls the `struct CadetPeer` to maintain the path heap for
906  */
907 static void
908 path_heap_cleanup (void *cls)
909 {
910   struct CadetPeer *cp = cls;
911   struct CadetPeerPath *root;
912
913   cp->heap_cleanup_task = NULL;
914   while (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >=
915          2 * DESIRED_CONNECTIONS_PER_TUNNEL)
916   {
917     /* Now we have way too many, drop least desirable UNLESS it is in use!
918        (Note that this intentionally keeps highly desireable, but currently
919        unused paths around in the hope that we might be able to switch, even
920        if the number of paths exceeds the threshold.) */
921     root = GNUNET_CONTAINER_heap_peek (cp->path_heap);
922     GNUNET_assert (NULL != root);
923     if (NULL !=
924         GCPP_get_connection (root,
925                              cp,
926                              GCPP_get_length (root) - 1))
927       break; /* can't fix */
928     /* Got plenty of paths to this destination, and this is a low-quality
929        one that we don't care about. Allow it to die. */
930     GNUNET_assert (root ==
931                    GNUNET_CONTAINER_heap_remove_root (cp->path_heap));
932     GCPP_release (root);
933   }
934 }
935
936
937 /**
938  * Try adding a @a path to this @a peer.  If the peer already
939  * has plenty of paths, return NULL.
940  *
941  * @param cp peer to which the @a path leads to
942  * @param path a path looking for an owner; may not be fully initialized yet!
943  * @param off offset of @a cp in @a path
944  * @param force force attaching the path
945  * @return NULL if this peer does not care to become a new owner,
946  *         otherwise the node in the peer's path heap for the @a path.
947  */
948 struct GNUNET_CONTAINER_HeapNode *
949 GCP_attach_path (struct CadetPeer *cp,
950                  struct CadetPeerPath *path,
951                  unsigned int off,
952                  int force)
953 {
954   GNUNET_CONTAINER_HeapCostType desirability;
955   struct CadetPeerPath *root;
956   GNUNET_CONTAINER_HeapCostType root_desirability;
957   struct GNUNET_CONTAINER_HeapNode *hn;
958
959   GNUNET_assert (off == GCPP_get_length (path) - 1);
960   GNUNET_assert (cp == GCPP_get_peer_at_offset (path,
961                                                 off));
962   if (NULL == cp->path_heap)
963   {
964     /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */
965     GNUNET_assert (GNUNET_NO == force);
966     return NULL;
967   }
968   desirability = GCPP_get_desirability (path);
969   if (GNUNET_NO == force)
970   {
971     /* FIXME: desirability is not yet initialized; tricky! */
972     if (GNUNET_NO ==
973         GNUNET_CONTAINER_heap_peek2 (cp->path_heap,
974                                      (void **) &root,
975                                      &root_desirability))
976     {
977       root = NULL;
978       root_desirability = 0;
979     }
980
981     if ( (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) &&
982          (desirability < root_desirability) )
983     {
984       LOG (GNUNET_ERROR_TYPE_DEBUG,
985            "Decided to not attach path %s to peer %s due to undesirability\n",
986            GCPP_2s (path),
987            GCP_2s (cp));
988       return NULL;
989     }
990   }
991
992   LOG (GNUNET_ERROR_TYPE_DEBUG,
993        "Attaching path %s to peer %s (%s)\n",
994        GCPP_2s (path),
995        GCP_2s (cp),
996        (GNUNET_NO == force) ? "desirable" : "forced");
997
998   /* Yes, we'd like to add this path, add to our heap */
999   hn = GNUNET_CONTAINER_heap_insert (cp->path_heap,
1000                                      path,
1001                                      desirability);
1002
1003   /* Consider maybe dropping other paths because of the new one */
1004   if ( (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >=
1005         2 * DESIRED_CONNECTIONS_PER_TUNNEL) &&
1006        (NULL != cp->heap_cleanup_task) )
1007     cp->heap_cleanup_task = GNUNET_SCHEDULER_add_now (&path_heap_cleanup,
1008                                                       cp);
1009   return hn;
1010 }
1011
1012
1013 /**
1014  * This peer can no longer own @a path as the path
1015  * has been extended and a peer further down the line
1016  * is now the new owner.
1017  *
1018  * @param cp old owner of the @a path
1019  * @param path path where the ownership is lost
1020  * @param hn note in @a cp's path heap that must be deleted
1021  */
1022 void
1023 GCP_detach_path (struct CadetPeer *cp,
1024                  struct CadetPeerPath *path,
1025                  struct GNUNET_CONTAINER_HeapNode *hn)
1026 {
1027   LOG (GNUNET_ERROR_TYPE_DEBUG,
1028        "Detatching path %s from peer %s\n",
1029        GCPP_2s (path),
1030        GCP_2s (cp));
1031   GNUNET_assert (path ==
1032                  GNUNET_CONTAINER_heap_remove_node (hn));
1033 }
1034
1035
1036 /**
1037  * Add a @a connection to this @a cp.
1038  *
1039  * @param cp peer via which the @a connection goes
1040  * @param cc the connection to add
1041  */
1042 void
1043 GCP_add_connection (struct CadetPeer *cp,
1044                     struct CadetConnection *cc)
1045 {
1046   LOG (GNUNET_ERROR_TYPE_DEBUG,
1047        "Adding connection %s to peer %s\n",
1048        GCC_2s (cc),
1049        GCP_2s (cp));
1050   GNUNET_assert (GNUNET_OK ==
1051                  GNUNET_CONTAINER_multishortmap_put (cp->connections,
1052                                                      &GCC_get_id (cc)->connection_of_tunnel,
1053                                                      cc,
1054                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1055   if (NULL != cp->destroy_task)
1056   {
1057     GNUNET_SCHEDULER_cancel (cp->destroy_task);
1058     cp->destroy_task = NULL;
1059   }
1060 }
1061
1062
1063 /**
1064  * Remove a @a connection that went via this @a cp.
1065  *
1066  * @param cp peer via which the @a connection went
1067  * @param cc the connection to remove
1068  */
1069 void
1070 GCP_remove_connection (struct CadetPeer *cp,
1071                        struct CadetConnection *cc)
1072 {
1073   LOG (GNUNET_ERROR_TYPE_DEBUG,
1074        "Removing connection %s from peer %s\n",
1075        GCC_2s (cc),
1076        GCP_2s (cp));
1077   GNUNET_assert (GNUNET_YES ==
1078                  GNUNET_CONTAINER_multishortmap_remove (cp->connections,
1079                                                         &GCC_get_id (cc)->connection_of_tunnel,
1080                                                         cc));
1081   consider_peer_destroy (cp);
1082 }
1083
1084
1085 /**
1086  * Retrieve the CadetPeer stucture associated with the
1087  * peer. Optionally create one and insert it in the appropriate
1088  * structures if the peer is not known yet.
1089  *
1090  * @param peer_id Full identity of the peer.
1091  * @param create #GNUNET_YES if a new peer should be created if unknown.
1092  *               #GNUNET_NO to return NULL if peer is unknown.
1093  * @return Existing or newly created peer structure.
1094  *         NULL if unknown and not requested @a create
1095  */
1096 struct CadetPeer *
1097 GCP_get (const struct GNUNET_PeerIdentity *peer_id,
1098          int create)
1099 {
1100   struct CadetPeer *cp;
1101
1102   cp = GNUNET_CONTAINER_multipeermap_get (peers,
1103                                           peer_id);
1104   if (NULL != cp)
1105     return cp;
1106   if (GNUNET_NO == create)
1107     return NULL;
1108   cp = GNUNET_new (struct CadetPeer);
1109   cp->pid = *peer_id;
1110   cp->connections = GNUNET_CONTAINER_multishortmap_create (32,
1111                                                            GNUNET_YES);
1112   cp->path_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1113   GNUNET_assert (GNUNET_YES ==
1114                  GNUNET_CONTAINER_multipeermap_put (peers,
1115                                                     &cp->pid,
1116                                                     cp,
1117                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1118   LOG (GNUNET_ERROR_TYPE_DEBUG,
1119        "Creating peer %s\n",
1120        GCP_2s (cp));
1121   return cp;
1122 }
1123
1124
1125 /**
1126  * Obtain the peer identity for a `struct CadetPeer`.
1127  *
1128  * @param cp our peer handle
1129  * @return the peer identity
1130  */
1131 const struct GNUNET_PeerIdentity *
1132 GCP_get_id (struct CadetPeer *cp)
1133 {
1134   return &cp->pid;
1135 }
1136
1137
1138 /**
1139  * Iterate over all known peers.
1140  *
1141  * @param iter Iterator.
1142  * @param cls Closure for @c iter.
1143  */
1144 void
1145 GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
1146                  void *cls)
1147 {
1148   GNUNET_CONTAINER_multipeermap_iterate (peers,
1149                                          iter,
1150                                          cls);
1151 }
1152
1153
1154 /**
1155  * Count the number of known paths toward the peer.
1156  *
1157  * @param cp Peer to get path info.
1158  * @return Number of known paths.
1159  */
1160 unsigned int
1161 GCP_count_paths (const struct CadetPeer *cp)
1162 {
1163   return cp->num_paths;
1164 }
1165
1166
1167 /**
1168  * Iterate over the paths to a peer.
1169  *
1170  * @param cp Peer to get path info.
1171  * @param callback Function to call for every path.
1172  * @param callback_cls Closure for @a callback.
1173  * @return Number of iterated paths.
1174  */
1175 unsigned int
1176 GCP_iterate_paths (struct CadetPeer *cp,
1177                    GCP_PathIterator callback,
1178                    void *callback_cls)
1179 {
1180   unsigned int ret = 0;
1181
1182   LOG (GNUNET_ERROR_TYPE_DEBUG,
1183        "Iterating over paths to peer %s%s\n",
1184        GCP_2s (cp),
1185        (NULL == cp->core_mq) ? "" : " including direct link");
1186   if (NULL != cp->core_mq)
1187   {
1188     struct CadetPeerPath *path;
1189
1190     path = GCPP_get_path_from_route (1,
1191                                      &cp->pid);
1192     ret++;
1193     if (GNUNET_NO ==
1194         callback (callback_cls,
1195                   path,
1196                   0))
1197       return ret;
1198   }
1199   for (unsigned int i=0;i<cp->path_dll_length;i++)
1200   {
1201     for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1202          NULL != pe;
1203          pe = pe->next)
1204     {
1205       ret++;
1206       if (GNUNET_NO ==
1207           callback (callback_cls,
1208                     pe->path,
1209                     i))
1210         return ret;
1211     }
1212   }
1213   return ret;
1214 }
1215
1216
1217 /**
1218  * Iterate over the paths to @a cp where
1219  * @a cp is at distance @a dist from us.
1220  *
1221  * @param cp Peer to get path info.
1222  * @param dist desired distance of @a cp to us on the path
1223  * @param callback Function to call for every path.
1224  * @param callback_cls Closure for @a callback.
1225  * @return Number of iterated paths.
1226  */
1227 unsigned int
1228 GCP_iterate_paths_at (struct CadetPeer *cp,
1229                       unsigned int dist,
1230                       GCP_PathIterator callback,
1231                       void *callback_cls)
1232 {
1233   unsigned int ret = 0;
1234
1235   if (dist >= cp->path_dll_length)
1236   {
1237     LOG (GNUNET_ERROR_TYPE_DEBUG,
1238          "Asked to look for paths at distance %u, but maximum for me is < %u\n",
1239          dist,
1240          cp->path_dll_length);
1241     return 0;
1242   }
1243   for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
1244        NULL != pe;
1245        pe = pe->next)
1246   {
1247     if (GNUNET_NO ==
1248         callback (callback_cls,
1249                   pe->path,
1250                   dist))
1251       return ret;
1252     ret++;
1253   }
1254   return ret;
1255 }
1256
1257
1258 /**
1259  * Get the tunnel towards a peer.
1260  *
1261  * @param cp Peer to get from.
1262  * @param create #GNUNET_YES to create a tunnel if we do not have one
1263  * @return Tunnel towards peer.
1264  */
1265 struct CadetTunnel *
1266 GCP_get_tunnel (struct CadetPeer *cp,
1267                 int create)
1268 {
1269   if (NULL == cp)
1270     return NULL;
1271   if ( (NULL != cp->t) ||
1272        (GNUNET_NO == create) )
1273     return cp->t;
1274   cp->t = GCT_create_tunnel (cp);
1275   consider_peer_activate (cp);
1276   return cp->t;
1277 }
1278
1279
1280 /**
1281  * Hello offer was passed to the transport service. Mark it
1282  * as done.
1283  *
1284  * @param cls the `struct CadetPeer` where the offer completed
1285  */
1286 static void
1287 hello_offer_done (void *cls)
1288 {
1289   struct CadetPeer *cp = cls;
1290
1291   cp->hello_offer = NULL;
1292 }
1293
1294
1295 /**
1296  * We got a HELLO for a @a peer, remember it, and possibly
1297  * trigger adequate actions (like trying to connect).
1298  *
1299  * @param cp the peer we got a HELLO for
1300  * @param hello the HELLO to remember
1301  */
1302 void
1303 GCP_set_hello (struct CadetPeer *cp,
1304                const struct GNUNET_HELLO_Message *hello)
1305 {
1306   struct GNUNET_HELLO_Message *mrg;
1307
1308   LOG (GNUNET_ERROR_TYPE_DEBUG,
1309        "Got %u byte HELLO for peer %s\n",
1310        (unsigned int) GNUNET_HELLO_size (hello),
1311        GCP_2s (cp));
1312   if (NULL != cp->hello_offer)
1313   {
1314     GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer);
1315     cp->hello_offer = NULL;
1316   }
1317   if (NULL != cp->hello)
1318   {
1319     mrg = GNUNET_HELLO_merge (hello,
1320                               cp->hello);
1321     GNUNET_free (cp->hello);
1322     cp->hello = mrg;
1323   }
1324   else
1325   {
1326     cp->hello = GNUNET_memdup (hello,
1327                                GNUNET_HELLO_size (hello));
1328   }
1329   cp->hello_offer
1330     = GNUNET_TRANSPORT_offer_hello (cfg,
1331                                     GNUNET_HELLO_get_header (cp->hello) ,
1332                                     &hello_offer_done,
1333                                     cp);
1334   /* New HELLO means cp's destruction time may change... */
1335   consider_peer_destroy (cp);
1336 }
1337
1338
1339 /**
1340  * The tunnel to the given peer no longer exists, remove it from our
1341  * data structures, and possibly clean up the peer itself.
1342  *
1343  * @param cp the peer affected
1344  * @param t the dead tunnel
1345  */
1346 void
1347 GCP_drop_tunnel (struct CadetPeer *cp,
1348                  struct CadetTunnel *t)
1349 {
1350   LOG (GNUNET_ERROR_TYPE_DEBUG,
1351        "Dropping tunnel %s to peer %s\n",
1352        GCT_2s (t),
1353        GCP_2s (cp));
1354   GNUNET_assert (cp->t == t);
1355   cp->t = NULL;
1356   consider_peer_destroy (cp);
1357 }
1358
1359
1360 /**
1361  * Test if @a cp has a core-level connection
1362  *
1363  * @param cp peer to test
1364  * @return #GNUNET_YES if @a cp has a core-level connection
1365  */
1366 int
1367 GCP_has_core_connection (struct CadetPeer *cp)
1368 {
1369   return (NULL != cp->core_mq) ? GNUNET_YES : GNUNET_NO;
1370 }
1371
1372
1373 /**
1374  * Start message queue change notifications.
1375  *
1376  * @param cp peer to notify for
1377  * @param cb function to call if mq becomes available or unavailable
1378  * @param cb_cls closure for @a cb
1379  * @return handle to cancel request
1380  */
1381 struct GCP_MessageQueueManager *
1382 GCP_request_mq (struct CadetPeer *cp,
1383                 GCP_MessageQueueNotificationCallback cb,
1384                 void *cb_cls)
1385 {
1386   struct GCP_MessageQueueManager *mqm;
1387
1388   mqm = GNUNET_new (struct GCP_MessageQueueManager);
1389   mqm->cb = cb;
1390   mqm->cb_cls = cb_cls;
1391   mqm->cp = cp;
1392   GNUNET_CONTAINER_DLL_insert (cp->mqm_head,
1393                                cp->mqm_tail,
1394                                mqm);
1395   LOG (GNUNET_ERROR_TYPE_DEBUG,
1396        "Creating MQM %p for peer %s\n",
1397        mqm,
1398        GCP_2s (cp));
1399   if (NULL != cp->core_mq)
1400     cb (cb_cls,
1401         GNUNET_YES);
1402   return mqm;
1403 }
1404
1405
1406 /**
1407  * Stops message queue change notifications.
1408  *
1409  * @param mqm handle matching request to cancel
1410  * @param last_env final message to transmit, or NULL
1411  */
1412 void
1413 GCP_request_mq_cancel (struct GCP_MessageQueueManager *mqm,
1414                        struct GNUNET_MQ_Envelope *last_env)
1415 {
1416   struct CadetPeer *cp = mqm->cp;
1417
1418   LOG (GNUNET_ERROR_TYPE_DEBUG,
1419        "Destroying MQM %p for peer %s%s\n",
1420        mqm,
1421        GCP_2s (cp),
1422        (NULL == last_env) ? "" : " with last ditch transmission");
1423   if (NULL != mqm->env)
1424     GNUNET_MQ_discard (mqm->env);
1425   if (NULL != last_env)
1426   {
1427     if (NULL != cp->core_mq)
1428     {
1429       GNUNET_MQ_notify_sent (last_env,
1430                              &mqm_send_done,
1431                              cp);
1432       GNUNET_MQ_send (cp->core_mq,
1433                       last_env);
1434     }
1435     else
1436     {
1437       GNUNET_MQ_discard (last_env);
1438     }
1439   }
1440   if (cp->mqm_ready_ptr == mqm)
1441     cp->mqm_ready_ptr = mqm->next;
1442   GNUNET_CONTAINER_DLL_remove (cp->mqm_head,
1443                                cp->mqm_tail,
1444                                mqm);
1445   GNUNET_free (mqm);
1446 }
1447
1448
1449 /**
1450  * Send the message in @a env to @a cp, overriding queueing logic.
1451  * This function should only be used to send error messages outside
1452  * of flow and congestion control, similar to ICMP.  Note that
1453  * the envelope may be silently discarded as well.
1454  *
1455  * @param cp peer to send the message to
1456  * @param env envelope with the message to send
1457  */
1458 void
1459 GCP_send_ooo (struct CadetPeer *cp,
1460               struct GNUNET_MQ_Envelope *env)
1461 {
1462   LOG (GNUNET_ERROR_TYPE_DEBUG,
1463        "Sending message to %s out of management\n",
1464        GCP_2s (cp));
1465   if (NULL == cp->core_mq)
1466   {
1467     GNUNET_MQ_discard (env);
1468     return;
1469   }
1470   if (GNUNET_MQ_get_length (cp->core_mq) > MAX_OOO_QUEUE_SIZE)
1471   {
1472     GNUNET_MQ_discard (env);
1473     return;
1474   }
1475   GNUNET_MQ_notify_sent (env,
1476                          &mqm_send_done,
1477                          cp);
1478   GNUNET_MQ_send (cp->core_mq,
1479                   env);
1480 }
1481
1482
1483
1484
1485 /* end of gnunet-service-cadet-new_peer.c */