GNUnet 0.28.0-dev.2-27-gc87478450
 
Loading...
Searching...
No Matches
gnunet-service-cadet_peer.c File Reference

Information we track per peer. More...

Include dependency graph for gnunet-service-cadet_peer.c:

Go to the source code of this file.

Data Structures

struct  GCP_MessageQueueManager
 Data structure used to track whom we have to notify about changes to our message queue. More...
 
struct  CadetPeer
 Struct containing all information regarding a given peer. More...
 

Macros

#define LOG(level, ...)   GNUNET_log_from (level, "cadet-per", __VA_ARGS__)
 
#define IDLE_PEER_TIMEOUT
 How long do we wait until tearing down an idle peer?
 
#define IDLE_PATH_TIMEOUT
 How long do we keep paths around if we no longer care about the peer?
 
#define MAX_OOO_QUEUE_SIZE   100
 Queue size when we start dropping OOO messages.
 

Functions

const char * GCP_2s (const struct CadetPeer *cp)
 Get the static string for a peer ID.
 
double GCP_get_desirability_of_path (struct CadetPeer *cp, unsigned int off)
 Calculate how desirable a path is for cp if cp is at offset off in the path.
 
static void destroy_peer (void *cls)
 This peer is no longer be needed, clean it up now.
 
static void consider_peer_activate (struct CadetPeer *cp)
 This peer is now on more "active" duty, activate processes related to it.
 
static void consider_peer_destroy (struct CadetPeer *cp)
 This peer may no longer be needed, consider cleaning it up.
 
static void drop_paths (void *cls)
 We really no longere care about a peer, stop hogging memory with paths to it.
 
void GCP_set_mq (struct CadetPeer *cp, struct GNUNET_MQ_Handle *mq)
 Set the message queue to mq for peer cp and notify watchers.
 
static int should_I_drop (void)
 Debug function should NEVER return true in production code, useful to simulate losses for testcases.
 
static void mqm_send_done (void *cls)
 Function called when CORE took one of the messages from a message queue manager and transmitted it.
 
static void mqm_execute (struct GCP_MessageQueueManager *mqm)
 Transmit current envelope from this mqm.
 
static void send_next_ready (struct CadetPeer *cp)
 Find the next ready message in the queue (starting the search from the cp->mqm_ready_ptr) and if possible execute the transmission.
 
void GCP_send (struct GCP_MessageQueueManager *mqm, struct GNUNET_MQ_Envelope *env)
 Send the message in env to cp.
 
static int destroy_iterator_cb (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 Function called to destroy a peer now.
 
void GCP_destroy_all_peers ()
 Clean up all entries about all peers.
 
void GCP_drop_owned_paths (struct CadetPeer *cp)
 Drop all paths owned by this peer, and do not allow new ones to be added: We are shutting down.
 
void GCP_path_entry_add (struct CadetPeer *cp, struct CadetPeerPathEntry *entry, unsigned int off)
 Add an entry to the DLL of all of the paths that this peer is on.
 
void GCP_path_entry_remove (struct CadetPeer *cp, struct CadetPeerPathEntry *entry, unsigned int off)
 Remove an entry from the DLL of all of the paths that this peer is on.
 
static void path_heap_cleanup (void *cls)
 Prune down the number of paths to this peer, we seem to have way too many.
 
struct GNUNET_CONTAINER_HeapNodeGCP_attach_path (struct CadetPeer *cp, struct CadetPeerPath *path, unsigned int off, int force)
 Try adding a path to this cp.
 
void GCP_detach_path (struct CadetPeer *cp, struct CadetPeerPath *path, struct GNUNET_CONTAINER_HeapNode *hn)
 This peer can no longer own path as the path has been extended and a peer further down the line is now the new owner.
 
void GCP_add_connection (struct CadetPeer *cp, struct CadetConnection *cc)
 Add a connection to this cp.
 
void GCP_remove_connection (struct CadetPeer *cp, struct CadetConnection *cc)
 Remove a connection that went via this cp.
 
struct CadetPeerGCP_get (const struct GNUNET_PeerIdentity *peer_id, int create)
 Retrieve the CadetPeer structure associated with the peer.
 
const struct GNUNET_PeerIdentityGCP_get_id (struct CadetPeer *cp)
 Obtain the peer identity for a struct CadetPeer.
 
void GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls)
 Iterate over all known peers.
 
unsigned int GCP_count_paths (const struct CadetPeer *cp)
 Count the number of known paths toward the peer.
 
unsigned int GCP_iterate_paths (struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
 Iterate over the paths to a peer.
 
unsigned int GCP_iterate_indirect_paths (struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
 Iterate over the paths to a peer without direct link.
 
unsigned int GCP_iterate_paths_at (struct CadetPeer *cp, unsigned int dist, GCP_PathIterator callback, void *callback_cls)
 Iterate over the paths to peer where peer is at distance dist from us.
 
struct CadetTunnelGCP_get_tunnel (struct CadetPeer *cp, int create)
 Get the tunnel towards a peer.
 
void GCP_set_hello (struct CadetPeer *cp, const struct GNUNET_MessageHeader *hello)
 We got a HELLO for a cp, remember it, and possibly trigger adequate actions (like trying to connect).
 
void GCP_drop_tunnel (struct CadetPeer *cp, struct CadetTunnel *t)
 The tunnel to the given peer no longer exists, remove it from our data structures, and possibly clean up the peer itself.
 
int GCP_has_core_connection (struct CadetPeer *cp)
 Test if cp has a core-level connection.
 
struct GCP_MessageQueueManagerGCP_request_mq (struct CadetPeer *cp, GCP_MessageQueueNotificationCallback cb, void *cb_cls)
 Start message queue change notifications.
 
void GCP_request_mq_cancel (struct GCP_MessageQueueManager *mqm, struct GNUNET_MQ_Envelope *last_env)
 Stops message queue change notifications.
 
void GCP_send_ooo (struct CadetPeer *cp, struct GNUNET_MQ_Envelope *env)
 Send the message in env to cp, overriding queueing logic.
 
int GCP_check_and_update_monotime (struct CadetPeer *peer, struct GNUNET_TIME_AbsoluteNBO monotime)
 Checking if a monotime value is newer than the last monotime value received from a peer.
 
int GCP_check_monotime_sig (struct CadetPeer *peer, const struct GNUNET_CADET_ConnectionCreateMessage *msg)
 Checking the signature for a monotime of a GNUNET_CADET_ConnectionCreateMessage.
 

Detailed Description

Information we track per peer.

Author
Bartlomiej Polot
Christian Grothoff

TODO:

  • optimize stopping/restarting DHT search to situations where we actually need it (i.e. not if we have a direct connection, or if we already have plenty of good short ones, or maybe even to take a break if we have some connections and have searched a lot (?))

Definition in file gnunet-service-cadet_peer.c.

Macro Definition Documentation

◆ LOG

#define LOG (   level,
  ... 
)    GNUNET_log_from (level, "cadet-per", __VA_ARGS__)

Definition at line 49 of file gnunet-service-cadet_peer.c.

◆ IDLE_PEER_TIMEOUT

#define IDLE_PEER_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486

How long do we wait until tearing down an idle peer?

Definition at line 55 of file gnunet-service-cadet_peer.c.

73{
78
83
88
92 void *cb_cls;
93
97 struct CadetPeer *cp;
98
102 struct GNUNET_MQ_Envelope *env;
103};
104
105
109struct CadetPeer
110{
115
120
126
132
137
142
147
153
158
163
168
172 struct CadetTunnel *t;
173
178
183
188
192 struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer;
193
198
202 unsigned int queue_n;
203
207 unsigned int num_paths;
208
213 unsigned int off_sum;
214
222 unsigned int mqm_ready_counter;
223
228 unsigned int path_dll_length;
229};
230
231
232const char *
233GCP_2s (const struct CadetPeer *cp)
234{
235 static char buf[5];
236 char *ret;
237
238 if ((NULL == cp) ||
240 return "NULL";
241
243 if (NULL == ret)
244 return "NULL";
245
246 GNUNET_strlcpy (buf,
247 ret,
248 sizeof(buf));
250 return buf;
251}
252
253
254double
256 unsigned int off)
257{
258 unsigned int num_alts = cp->num_paths;
259 unsigned int off_sum;
260 double avg_sum;
261 double path_delta;
262 double weight_alts;
263
264 GNUNET_assert (num_alts >= 1); /* 'path' should be in there! */
266
267 /* We maintain 'off_sum' in 'peer' and thereby
268 avoid the SLOW recalculation each time. Kept here
269 just to document what is going on. */
270#if SLOW
271 off_sum = 0;
272 for (unsigned int j = 0; j < cp->path_dll_length; j++)
273 for (struct CadetPeerPathEntry *pe = cp->path_heads[j];
274 NULL != pe;
275 pe = pe->next)
276 off_sum += j;
277 GNUNET_assert (off_sum == cp->off_sum);
278#else
279 off_sum = cp->off_sum;
280#endif
281 avg_sum = off_sum * 1.0 / cp->path_dll_length;
282 path_delta = off - avg_sum;
283 /* path_delta positive: path off of peer above average (bad path for peer),
284 path_delta negative: path off of peer below average (good path for peer) */
285 if (path_delta <= -1.0)
286 weight_alts = -num_alts / path_delta; /* discount alternative paths */
287 else if (path_delta >= 1.0)
288 weight_alts = num_alts * path_delta; /* overcount alternative paths */
289 else
290 weight_alts = num_alts; /* count alternative paths normally */
291
292
293 /* off+1: long paths are generally harder to find and thus count
294 a bit more as they get longer. However, above-average paths
295 still need to count less, hence the squaring of that factor. */
296 return (off + 1.0) / (weight_alts * weight_alts);
297}
298
299
305static void
306destroy_peer (void *cls)
307{
308 struct CadetPeer *cp = cls;
309
311 "Destroying state about peer %s\n",
312 GCP_2s (cp));
313 cp->destroy_task = NULL;
314 GNUNET_assert (NULL == cp->t);
315 GNUNET_assert (NULL == cp->core_mq);
316 GNUNET_assert (0 == cp->num_paths);
317 for (unsigned int i = 0; i < cp->path_dll_length; i++)
318 GNUNET_assert (NULL == cp->path_heads[i]);
322 &cp->pid,
323 cp));
326 cp->path_dll_length = 0;
327 if (NULL != cp->search_h)
328 {
330 cp->search_h = NULL;
331 }
332 /* FIXME: clean up search_delayedXXX! */
333
334
335 if (NULL != cp->ash)
336 {
338 cp->ash = NULL;
339 }
341 if (NULL != cp->path_heap)
342 {
344 cp->path_heap = NULL;
345 }
346 if (NULL != cp->heap_cleanup_task)
347 {
349 cp->heap_cleanup_task = NULL;
350 }
351 GNUNET_free (cp->hello);
352 /* Peer should not be freed if paths exist; if there are no paths,
353 there ought to be no connections, and without connections, no
354 notifications. Thus we can assert that mqm_head is empty at this
355 point. */
356 GNUNET_assert (NULL == cp->mqm_head);
357 GNUNET_assert (NULL == cp->mqm_ready_ptr);
358 GNUNET_free (cp);
359}
360
361
367static void
369{
371
373 "Updating peer %s activation state (%u connections)%s%s\n",
374 GCP_2s (cp),
376 (NULL == cp->t) ? "" : " with tunnel",
377 (NULL == cp->core_mq) ? "" : " with CORE link");
378 if (NULL != cp->destroy_task)
379 {
380 /* It's active, do not destroy! */
382 cp->destroy_task = NULL;
383 }
385 (NULL == cp->t))
386 {
387 /* We're just on a path or directly connected; don't bother too much */
388 if (NULL != cp->ash)
389 {
391 cp->ash = NULL;
392 }
393 if (NULL != cp->search_h)
394 {
396 cp->search_h = NULL;
397 }
398 return;
399 }
400 if (NULL == cp->core_mq)
401 {
402 /* Lacks direct connection, try to create one by querying the DHT */
403 if ((NULL == cp->search_h) &&
405 cp->search_h
406 = GCD_search (&cp->pid);
407 }
408 else
409 {
410 /* Have direct connection, stop DHT search if active */
411 if (NULL != cp->search_h)
412 {
414 cp->search_h = NULL;
415 }
416 }
417
418 if (NULL != cp->ash)
420 bw.value__ = 0;
421 cp->ash
423 &cp->pid,
425 bw);
426}
427
428
434static void
436
437
444static void
445drop_paths (void *cls)
446{
447 struct CadetPeer *cp = cls;
448 struct CadetPeerPath *path;
449
450 cp->destroy_task = NULL;
451 while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
452 GCPP_release (path);
454}
455
456
462static void
464{
465 struct GNUNET_TIME_Relative exp;
466
467 if (NULL != cp->destroy_task)
468 {
470 cp->destroy_task = NULL;
471 }
472 if (NULL != cp->t)
473 return; /* still relevant! */
474 if (NULL != cp->core_mq)
475 return; /* still relevant! */
477 return; /* still relevant! */
478 if ((NULL != cp->path_heap) &&
480 {
482 &drop_paths,
483 cp);
484 return;
485 }
486 if (0 != cp->num_paths)
487 return; /* still relevant! */
488 if (NULL != cp->hello)
489 {
490 /* relevant only until HELLO expires */
495 cp);
496 return;
497 }
500 cp);
501}
502
503
510void
511GCP_set_mq (struct CadetPeer *cp,
512 struct GNUNET_MQ_Handle *mq)
513{
515 "Message queue for peer %s is now %p\n",
516 GCP_2s (cp),
517 mq);
518 cp->core_mq = mq;
519 for (struct GCP_MessageQueueManager *mqm = cp->mqm_head, *next;
520 NULL != mqm;
521 mqm = next)
522 {
523 /* Save next pointer in case mqm gets freed by the callback */
524 next = mqm->next;
525 if (NULL == mq)
526 {
527 if (NULL != mqm->env)
528 {
529 GNUNET_MQ_discard (mqm->env);
530 mqm->env = NULL;
531 mqm->cb (mqm->cb_cls,
533 }
534 else
535 {
536 mqm->cb (mqm->cb_cls,
537 GNUNET_NO);
538 }
539 }
540 else
541 {
542 GNUNET_assert (NULL == mqm->env);
543 mqm->cb (mqm->cb_cls,
544 GNUNET_YES);
545 }
546 }
547 if ((NULL != mq) ||
548 (NULL != cp->t))
550 else
552
553 if ((NULL != mq) &&
554 (NULL != cp->t))
555 {
556 /* have a new, direct path to the target, notify tunnel */
557 struct CadetPeerPath *path;
558
559 path = GCPP_get_path_from_route (1,
560 &cp->pid);
561 GCT_consider_path (cp->t,
562 path,
563 0);
564 }
565}
566
567
574static int
575should_I_drop (void)
576{
577 if (0 == drop_percent)
578 return GNUNET_NO;
580 return GNUNET_YES;
581 return GNUNET_NO;
582}
583
584
591static void
592mqm_send_done (void *cls);
593
594
600static void
602{
603 struct CadetPeer *cp = mqm->cp;
604
605 /* Move ready pointer to the next entry that might be ready. */
606 if ((mqm == cp->mqm_ready_ptr) &&
607 (NULL != mqm->next))
608 cp->mqm_ready_ptr = mqm->next;
609 /* Move entry to the end of the DLL, to be fair. */
610 if (mqm != cp->mqm_tail)
611 {
613 cp->mqm_tail,
614 mqm);
616 cp->mqm_tail,
617 mqm);
618 }
619 cp->mqm_ready_counter--;
620 if (GNUNET_YES == should_I_drop ())
621 {
623 "DROPPING message to peer %s from MQM %p\n",
624 GCP_2s (cp),
625 mqm);
626 GNUNET_MQ_discard (mqm->env);
627 mqm->env = NULL;
628 mqm_send_done (cp);
629 }
630 else
631 {
632 {
633 const struct GNUNET_MessageHeader *mh;
634
636 switch (ntohs (mh->type))
637 {
639 {
641 = (const struct GNUNET_CADET_TunnelKeyExchangeMessage *) mh;
643 "P2P forwarding KX with ephemeral %s to %s on CID %s\n",
644 GNUNET_e2s (&msg->ephemeral_key),
645 GCP_2s (cp),
646 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
647 }
648 break;
649
650 default:
651 break;
652 }
653 }
655 "Sending to peer %s from MQM %p\n",
656 GCP_2s (cp),
657 mqm);
659 mqm->env);
660 mqm->env = NULL;
661 }
662 mqm->cb (mqm->cb_cls,
663 GNUNET_YES);
664}
665
666
674static void
675send_next_ready (struct CadetPeer *cp)
676{
677 struct GCP_MessageQueueManager *mqm;
678
679 if (0 == cp->mqm_ready_counter)
680 return;
681 while ((NULL != (mqm = cp->mqm_ready_ptr)) &&
682 (NULL == mqm->env))
683 cp->mqm_ready_ptr = mqm->next;
684 if (NULL == mqm)
685 return; /* nothing to do */
686 mqm_execute (mqm);
687}
688
689
696static void
697mqm_send_done (void *cls)
698{
699 struct CadetPeer *cp = cls;
700
702 "Sending to peer %s completed\n",
703 GCP_2s (cp));
704 send_next_ready (cp);
705}
706
707
715void
717 struct GNUNET_MQ_Envelope *env)
718{
719 struct CadetPeer *cp = mqm->cp;
720
721 GNUNET_assert (NULL != env);
723 "Queueing message to peer %s in MQM %p\n",
724 GCP_2s (cp),
725 mqm);
726 GNUNET_assert (NULL != cp->core_mq);
727 GNUNET_assert (NULL == mqm->env);
730 cp);
731 mqm->env = env;
732 cp->mqm_ready_counter++;
733 if (mqm != cp->mqm_ready_ptr)
734 cp->mqm_ready_ptr = cp->mqm_head;
735 if (1 == cp->mqm_ready_counter)
736 cp->mqm_ready_ptr = mqm;
737 if (0 != GNUNET_MQ_get_length (cp->core_mq))
738 return;
739 send_next_ready (cp);
740}
741
742
751static int
752destroy_iterator_cb (void *cls,
753 const struct GNUNET_PeerIdentity *pid,
754 void *value)
755{
756 struct CadetPeer *cp = value;
757
758 if (NULL != cp->destroy_task)
759 {
761 cp->destroy_task = NULL;
762 }
763 destroy_peer (cp);
764 return GNUNET_OK;
765}
766
767
773void
775{
777 "Destroying all peers now\n");
780 NULL);
781}
782
783
790void
792{
793 struct CadetPeerPath *path;
794
796 "Destroying all paths to %s\n",
797 GCP_2s (cp));
798 while (NULL != (path =
800 GCPP_release (path);
802 cp->path_heap = NULL;
803}
804
805
813void
814GCP_path_entry_add (struct CadetPeer *cp,
815 struct CadetPeerPathEntry *entry,
816 unsigned int off)
817{
819 off));
821 "Discovered that peer %s is on path %s at offset %u\n",
822 GCP_2s (cp),
823 GCPP_2s (entry->path),
824 off);
825 if (off >= cp->path_dll_length)
826 {
827 unsigned int len = cp->path_dll_length;
828
830 len,
831 off + 4);
833 cp->path_dll_length,
834 off + 4);
835 }
837 cp->path_tails[off],
838 entry);
839 cp->off_sum += off;
840 cp->num_paths++;
841
842 /* If we have a tunnel to this peer, tell the tunnel that there is a
843 new path available. */
844 if (NULL != cp->t)
845 GCT_consider_path (cp->t,
846 entry->path,
847 off);
848
849 if ((NULL != cp->search_h) &&
850 (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths))
851 {
852 /* Now I have enough paths, stop search */
854 cp->search_h = NULL;
855 }
856 if (NULL != cp->destroy_task)
857 {
858 /* paths changed, this resets the destroy timeout counter
859 and aborts a destroy task that may no longer be valid
860 to have (as we now have more paths via this peer). */
862 }
863}
864
865
873void
875 struct CadetPeerPathEntry *entry,
876 unsigned int off)
877{
879 "Removing knowledge about peer %s being on path %s at offset %u\n",
880 GCP_2s (cp),
881 GCPP_2s (entry->path),
882 off);
884 cp->path_tails[off],
885 entry);
886 GNUNET_assert (0 < cp->num_paths);
887 cp->off_sum -= off;
888 cp->num_paths--;
889 if ((NULL == cp->core_mq) &&
890 (NULL != cp->t) &&
891 (NULL == cp->search_h) &&
893 cp->search_h
894 = GCD_search (&cp->pid);
895 if (NULL == cp->destroy_task)
896 {
897 /* paths changed, we might now be ready for destruction, check again */
899 }
900}
901
902
909static void
910path_heap_cleanup (void *cls)
911{
912 struct CadetPeer *cp = cls;
913 struct CadetPeerPath *root;
914
915 cp->heap_cleanup_task = NULL;
918 {
919 /* Now we have way too many, drop least desirable UNLESS it is in use!
920 (Note that this intentionally keeps highly desirable, but currently
921 unused paths around in the hope that we might be able to switch, even
922 if the number of paths exceeds the threshold.) */
924 GNUNET_assert (NULL != root);
925 if (NULL !=
927 cp,
928 GCPP_get_length (root) - 1))
929 break; /* can't fix */
930 /* Got plenty of paths to this destination, and this is a low-quality
931 one that we don't care about. Allow it to die. */
932 GNUNET_assert (root ==
934 GCPP_release (root);
935 }
936}
937
938
940GCP_attach_path (struct CadetPeer *cp,
941 struct CadetPeerPath *path,
942 unsigned int off,
943 int force)
944{
946 struct CadetPeerPath *root;
947 GNUNET_CONTAINER_HeapCostType root_desirability;
948 struct GNUNET_CONTAINER_HeapNode *hn;
949
950 GNUNET_assert (off == GCPP_get_length (path) - 1);
952 off));
953 if (NULL == cp->path_heap)
954 {
955 /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */
956 GNUNET_assert (GNUNET_NO == force);
957 return NULL;
958 }
959 desirability = GCPP_get_desirability (path);
960 if (GNUNET_NO == force)
961 {
962 /* FIXME: desirability is not yet initialized; tricky! */
963 if (GNUNET_NO ==
965 (void **) &root,
966 &root_desirability))
967 {
968 root = NULL;
969 root_desirability = 0;
970 }
971
973 (desirability < root_desirability))
974 {
976 "Decided to not attach path %s to peer %s due to undesirability\n",
977 GCPP_2s (path),
978 GCP_2s (cp));
979 return NULL;
980 }
981 }
982
984 "Attaching path %s to peer %s (%s)\n",
985 GCPP_2s (path),
986 GCP_2s (cp),
987 (GNUNET_NO == force) ? "desirable" : "forced");
988
989 /* Yes, we'd like to add this path, add to our heap */
991 path,
992 desirability);
993
994 /* Consider maybe dropping other paths because of the new one */
997 (NULL != cp->heap_cleanup_task))
999 cp);
1000 return hn;
1001}
1002
1003
1013void
1014GCP_detach_path (struct CadetPeer *cp,
1015 struct CadetPeerPath *path,
1016 struct GNUNET_CONTAINER_HeapNode *hn)
1017{
1019 "Detaching path %s from peer %s\n",
1020 GCPP_2s (path),
1021 GCP_2s (cp));
1022 GNUNET_assert (path ==
1024}
1025
1026
1033void
1034GCP_add_connection (struct CadetPeer *cp,
1035 struct CadetConnection *cc)
1036{
1038 "Adding %s to peer %s\n",
1039 GCC_2s (cc),
1040 GCP_2s (cp));
1043 &GCC_get_id (
1044 cc)->connection_of_tunnel
1045 ,
1046 cc,
1048 if (NULL != cp->destroy_task)
1049 {
1051 cp->destroy_task = NULL;
1052 }
1053}
1054
1055
1062void
1064 struct CadetConnection *cc)
1065{
1067 "Removing connection %s from peer %s\n",
1068 GCC_2s (cc),
1069 GCP_2s (cp));
1072 &GCC_get_id (
1073 cc)->
1074 connection_of_tunnel,
1075 cc));
1077}
1078
1079
1091struct CadetPeer *
1092GCP_get (const struct GNUNET_PeerIdentity *peer_id,
1093 int create)
1094{
1095 struct CadetPeer *cp;
1096
1098 peer_id);
1099 if (NULL != cp)
1100 return cp;
1101 if (GNUNET_NO == create)
1102 return NULL;
1103 cp = GNUNET_new (struct CadetPeer);
1104 cp->pid = *peer_id;
1106 GNUNET_YES);
1111 &cp->pid,
1112 cp,
1115 "Creating peer %s\n",
1116 GCP_2s (cp));
1117 return cp;
1118}
1119
1120
1127const struct GNUNET_PeerIdentity *
1128GCP_get_id (struct CadetPeer *cp)
1129{
1130 return &cp->pid;
1131}
1132
1133
1140void
1142 void *cls)
1143{
1145 iter,
1146 cls);
1147}
1148
1149
1156unsigned int
1157GCP_count_paths (const struct CadetPeer *cp)
1158{
1159 return cp->num_paths;
1160}
1161
1162
1171unsigned int
1172GCP_iterate_paths (struct CadetPeer *cp,
1173 GCP_PathIterator callback,
1174 void *callback_cls)
1175{
1176 unsigned int ret = 0;
1177
1179 "Iterating over paths to peer %s%s\n",
1180 GCP_2s (cp),
1181 (NULL == cp->core_mq) ? "" : " including direct link");
1182 if (NULL != cp->core_mq)
1183 {
1184 /* FIXME: this branch seems to duplicate the
1185 i=0 case below (direct link). Leave out!??? -CG */
1186 struct CadetPeerPath *path;
1187
1188 path = GCPP_get_path_from_route (1,
1189 &cp->pid);
1190 ret++;
1191 if (GNUNET_NO ==
1192 callback (callback_cls,
1193 path,
1194 0))
1195 return ret;
1196 }
1197 for (unsigned int i = 0; i < cp->path_dll_length; i++)
1198 {
1199 for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1200 NULL != pe;
1201 pe = pe->next)
1202 {
1203 ret++;
1204 if (GNUNET_NO ==
1205 callback (callback_cls,
1206 pe->path,
1207 i))
1208 return ret;
1209 }
1210 }
1211 return ret;
1212}
1213
1214
1223unsigned int
1225 GCP_PathIterator callback,
1226 void *callback_cls)
1227{
1228 unsigned int ret = 0;
1229
1231 "Iterating over paths to peer %s without direct link\n",
1232 GCP_2s (cp));
1233 for (unsigned int i = 1; i < cp->path_dll_length; i++)
1234 {
1235 for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1236 NULL != pe;
1237 pe = pe->next)
1238 {
1239 ret++;
1240 if (GNUNET_NO ==
1241 callback (callback_cls,
1242 pe->path,
1243 i))
1244 return ret;
1245 }
1246 }
1247 return ret;
1248}
1249
1250
1251unsigned int
1253 unsigned int dist,
1254 GCP_PathIterator callback,
1255 void *callback_cls)
1256{
1257 unsigned int ret = 0;
1258
1259 if (dist >= cp->path_dll_length)
1260 {
1262 "Asked to look for paths at distance %u, but maximum for me is < %u\n",
1263 dist,
1264 cp->path_dll_length);
1265 return 0;
1266 }
1267 for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
1268 NULL != pe;
1269 pe = pe->next)
1270 {
1271 if (GNUNET_NO ==
1272 callback (callback_cls,
1273 pe->path,
1274 dist))
1275 return ret;
1276 ret++;
1277 }
1278 return ret;
1279}
1280
1281
1289struct CadetTunnel *
1290GCP_get_tunnel (struct CadetPeer *cp,
1291 int create)
1292{
1293 if (NULL == cp)
1294 return NULL;
1295 if ((NULL != cp->t) ||
1296 (GNUNET_NO == create))
1297 return cp->t;
1298 cp->t = GCT_create_tunnel (cp);
1300 return cp->t;
1301}
1302
1303
1304void
1305GCP_set_hello (struct CadetPeer *cp,
1306 const struct GNUNET_MessageHeader *hello)
1307{
1309 uint16_t size = ntohs (hello->size);
1310
1312 "Got %u byte HELLO for peer %s\n",
1313 (unsigned int) size,
1314 GCP_2s (cp));
1315 if (NULL != cp->hello)
1316 {
1318
1319 struct GNUNET_TIME_Absolute new_hello_exp =
1321 struct GNUNET_TIME_Absolute old_hello_exp =
1323
1324 if (GNUNET_TIME_absolute_cmp (new_hello_exp, >, now) &&
1325 GNUNET_TIME_absolute_cmp (new_hello_exp, >, old_hello_exp))
1326 {
1327 GNUNET_free (cp->hello);
1328 cp->hello = GNUNET_malloc (size);
1329 GNUNET_memcpy (cp->hello, hello, size);
1330 }
1331 else
1332 {
1333 return;
1334 }
1335 }
1336 else
1337 {
1338 cp->hello = GNUNET_memdup (hello,
1339 size);
1340 }
1341 if (NULL != cp->ash)
1343 bw.value__ = 0;
1344 cp->ash
1346 &cp->pid,
1348 bw);
1349 /* New HELLO means cp's destruction time may change... */
1351}
1352
1353
1361void
1362GCP_drop_tunnel (struct CadetPeer *cp,
1363 struct CadetTunnel *t)
1364{
1366 "Dropping tunnel %s to peer %s\n",
1367 GCT_2s (t),
1368 GCP_2s (cp));
1369 GNUNET_assert (cp->t == t);
1370 cp->t = NULL;
1372}
1373
1374
1381int
1383{
1384 return (NULL != cp->core_mq) ? GNUNET_YES : GNUNET_NO;
1385}
1386
1387
1397GCP_request_mq (struct CadetPeer *cp,
1399 void *cb_cls)
1400{
1401 struct GCP_MessageQueueManager *mqm;
1402
1403 mqm = GNUNET_new (struct GCP_MessageQueueManager);
1404 mqm->cb = cb;
1405 mqm->cb_cls = cb_cls;
1406 mqm->cp = cp;
1408 cp->mqm_tail,
1409 mqm);
1411 "Creating MQM %p for peer %s\n",
1412 mqm,
1413 GCP_2s (cp));
1414 if (NULL != cp->core_mq)
1415 cb (cb_cls,
1416 GNUNET_YES);
1417 return mqm;
1418}
1419
1420
1427void
1429 struct GNUNET_MQ_Envelope *last_env)
1430{
1431 struct CadetPeer *cp = mqm->cp;
1432
1434 "Destroying MQM %p for peer %s%s\n",
1435 mqm,
1436 GCP_2s (cp),
1437 (NULL == last_env) ? "" : " with last ditch transmission");
1438 if (NULL != mqm->env)
1439 GNUNET_MQ_discard (mqm->env);
1440 if (NULL != last_env)
1441 {
1442 if (NULL != cp->core_mq)
1443 {
1444 GNUNET_MQ_notify_sent (last_env,
1446 cp);
1448 last_env);
1449 }
1450 else
1451 {
1452 GNUNET_MQ_discard (last_env);
1453 }
1454 }
1455 if (cp->mqm_ready_ptr == mqm)
1456 cp->mqm_ready_ptr = mqm->next;
1458 cp->mqm_tail,
1459 mqm);
1460 GNUNET_free (mqm);
1461}
1462
1463
1473void
1474GCP_send_ooo (struct CadetPeer *cp,
1475 struct GNUNET_MQ_Envelope *env)
1476{
1478 "Sending message to %s out of management\n",
1479 GCP_2s (cp));
1480 if (NULL == cp->core_mq)
1481 {
1483 return;
1484 }
1486 {
1488 return;
1489 }
1492 cp);
1494 env);
1495}
1496
1497
1505int
1507 struct GNUNET_TIME_AbsoluteNBO monotime)
1508{
1509
1510 struct GNUNET_TIME_Absolute mt = GNUNET_TIME_absolute_ntoh (monotime);
1511
1513 {
1514 peer->last_connection_create = mt;
1515 return GNUNET_YES;
1516 }
1517 return GNUNET_NO;
1518}
1519
1520
1528int
1529GCP_check_monotime_sig (struct CadetPeer *peer,
1531{
1532 struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
1534 .purpose.size = htonl (sizeof(cp)),
1535 .monotonic_time = msg->monotime};
1536
1537 if (GNUNET_OK !=
1540 &cp,
1541 &msg->monotime_sig,
1542 &peer->pid.public_key))
1543 {
1544 GNUNET_break_op (0);
1545 return GNUNET_SYSERR;
1546 }
1547 return GNUNET_OK;
1548}
1549
1550
1551/* end of gnunet-service-cadet-new_peer.c */
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static int ret
Final status code.
Definition gnunet-arm.c:93
static char * peer_id
Option –peer.
static struct GNUNET_CADET_Handle * mh
Cadet handle.
static int create
Create DID Document Flag.
Definition gnunet-did.c:68
static struct GNUNET_SCHEDULER_Task * t
Main task.
static char * value
Value of the record to add/remove.
struct GNUNET_CONTAINER_MultiPeerMap * peers
Map from PIDs to struct CadetPeer entries.
unsigned long long drop_percent
Set to non-zero values to create random drops to test retransmissions.
struct GNUNET_TRANSPORT_ApplicationHandle * transport
Handle to Transport service.
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
const struct GNUNET_CADET_ConnectionTunnelIdentifier * GCC_get_id(struct CadetConnection *cc)
Obtain unique ID for the connection.
void GCD_search_stop(struct GCD_search_handle *h)
Stop DHT search started with GCD_search().
struct GCD_search_handle * GCD_search(const struct GNUNET_PeerIdentity *peer_id)
Search DHT for paths to peeR_id.
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
unsigned int GCPP_get_length(struct CadetPeerPath *path)
Return the length of the path.
struct CadetConnection * GCPP_get_connection(struct CadetPeerPath *path, struct CadetPeer *destination, unsigned int off)
Return connection to destination using path, or return NULL if no such connection exists.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping the path.
void GCPP_release(struct CadetPeerPath *path)
The owning peer of this path is no longer interested in maintaining it, so the path should be discard...
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
struct CadetPeerPath * GCPP_get_path_from_route(unsigned int path_length, const struct GNUNET_PeerIdentity *pids)
We got an incoming connection, obtain the corresponding path.
static void consider_peer_activate(struct CadetPeer *cp)
This peer is now on more "active" duty, activate processes related to it.
int GCP_check_monotime_sig(struct CadetPeer *peer, const struct GNUNET_CADET_ConnectionCreateMessage *msg)
Checking the signature for a monotime of a GNUNET_CADET_ConnectionCreateMessage.
void GCP_add_connection(struct CadetPeer *cp, struct CadetConnection *cc)
Add a connection to this cp.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
void GCP_detach_path(struct CadetPeer *cp, struct CadetPeerPath *path, struct GNUNET_CONTAINER_HeapNode *hn)
This peer can no longer own path as the path has been extended and a peer further down the line is no...
void GCP_path_entry_add(struct CadetPeer *cp, struct CadetPeerPathEntry *entry, unsigned int off)
Add an entry to the DLL of all of the paths that this peer is on.
static void path_heap_cleanup(void *cls)
Prune down the number of paths to this peer, we seem to have way too many.
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer structure associated with the peer.
int GCP_has_core_connection(struct CadetPeer *cp)
Test if cp has a core-level connection.
#define IDLE_PEER_TIMEOUT
How long do we wait until tearing down an idle peer?
static void mqm_send_done(void *cls)
Function called when CORE took one of the messages from a message queue manager and transmitted it.
static void drop_paths(void *cls)
We really no longere care about a peer, stop hogging memory with paths to it.
struct CadetTunnel * GCP_get_tunnel(struct CadetPeer *cp, int create)
Get the tunnel towards a peer.
unsigned int GCP_count_paths(const struct CadetPeer *cp)
Count the number of known paths toward the peer.
void GCP_path_entry_remove(struct CadetPeer *cp, struct CadetPeerPathEntry *entry, unsigned int off)
Remove an entry from the DLL of all of the paths that this peer is on.
void GCP_send_ooo(struct CadetPeer *cp, struct GNUNET_MQ_Envelope *env)
Send the message in env to cp, overriding queueing logic.
static void consider_peer_destroy(struct CadetPeer *cp)
This peer may no longer be needed, consider cleaning it up.
int GCP_check_and_update_monotime(struct CadetPeer *peer, struct GNUNET_TIME_AbsoluteNBO monotime)
Checking if a monotime value is newer than the last monotime value received from a peer.
void GCP_request_mq_cancel(struct GCP_MessageQueueManager *mqm, struct GNUNET_MQ_Envelope *last_env)
Stops message queue change notifications.
static void send_next_ready(struct CadetPeer *cp)
Find the next ready message in the queue (starting the search from the cp->mqm_ready_ptr) and if poss...
#define MAX_OOO_QUEUE_SIZE
Queue size when we start dropping OOO messages.
void GCP_set_hello(struct CadetPeer *cp, const struct GNUNET_MessageHeader *hello)
We got a HELLO for a cp, remember it, and possibly trigger adequate actions (like trying to connect).
static int should_I_drop(void)
Debug function should NEVER return true in production code, useful to simulate losses for testcases.
struct GNUNET_CONTAINER_HeapNode * GCP_attach_path(struct CadetPeer *cp, struct CadetPeerPath *path, unsigned int off, int force)
Try adding a path to this cp.
unsigned int GCP_iterate_paths_at(struct CadetPeer *cp, unsigned int dist, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to peer where peer is at distance dist from us.
double GCP_get_desirability_of_path(struct CadetPeer *cp, unsigned int off)
Calculate how desirable a path is for cp if cp is at offset off in the path.
void GCP_set_mq(struct CadetPeer *cp, struct GNUNET_MQ_Handle *mq)
Set the message queue to mq for peer cp and notify watchers.
static void mqm_execute(struct GCP_MessageQueueManager *mqm)
Transmit current envelope from this mqm.
static void destroy_peer(void *cls)
This peer is no longer be needed, clean it up now.
#define IDLE_PATH_TIMEOUT
How long do we keep paths around if we no longer care about the peer?
void GCP_drop_tunnel(struct CadetPeer *cp, struct CadetTunnel *t)
The tunnel to the given peer no longer exists, remove it from our data structures,...
void GCP_drop_owned_paths(struct CadetPeer *cp)
Drop all paths owned by this peer, and do not allow new ones to be added: We are shutting down.
unsigned int GCP_iterate_indirect_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer without direct link.
#define LOG(level,...)
static int destroy_iterator_cb(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
Function called to destroy a peer now.
void GCP_send(struct GCP_MessageQueueManager *mqm, struct GNUNET_MQ_Envelope *env)
Send the message in env to cp.
void GCP_remove_connection(struct CadetPeer *cp, struct CadetConnection *cc)
Remove a connection that went via this cp.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
unsigned int GCP_iterate_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer.
void GCP_destroy_all_peers()
Clean up all entries about all peers.
struct GCP_MessageQueueManager * GCP_request_mq(struct CadetPeer *cp, GCP_MessageQueueNotificationCallback cb, void *cb_cls)
Start message queue change notifications.
void GCP_iterate_all(GNUNET_CONTAINER_PeerMapIterator iter, void *cls)
Iterate over all known peers.
int(* GCP_PathIterator)(void *cls, struct CadetPeerPath *path, unsigned int off)
Peer path iterator.
void(* GCP_MessageQueueNotificationCallback)(void *cls, int available)
Function to call with updated message queue object.
struct CadetTunnel * GCT_create_tunnel(struct CadetPeer *destination)
Create a tunnel to destination.
void GCT_consider_path(struct CadetTunnel *t, struct CadetPeerPath *p, unsigned int off)
Consider using the path p for the tunnel t.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
#define DESIRED_CONNECTIONS_PER_TUNNEL
How many connections would we like to have per tunnel?
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
#define GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR
Signature by a peer that like to create a connection.
struct GNUNET_TRANSPORT_ApplicationSuggestHandle * GNUNET_TRANSPORT_application_suggest(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_MQ_PriorityPreferences pk, struct GNUNET_BANDWIDTH_Value32NBO bw)
An application would like TRANSPORT to connect to a peer.
void GNUNET_TRANSPORT_application_suggest_cancel(struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh)
We no longer care about being connected to a peer.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
uint32_t GNUNET_CRYPTO_random_u32(uint32_t i)
Produce a random value.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue(* GNUNET_CONTAINER_PeerMapIterator)(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator over hash map entries.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
uint64_t GNUNET_CONTAINER_HeapCostType
Cost by which elements in a heap can be ordered.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_expiration_time_from_msg(const struct GNUNET_MessageHeader *msg)
Get the expiration time for this HELLO.
Definition hello-uri.c:633
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_heap_peek2(const struct GNUNET_CONTAINER_Heap *heap, void **element, GNUNET_CONTAINER_HeapCostType *cost)
Get element and cost stored at the root of heap.
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition crypto_ecc.c:255
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition mq.c:293
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:305
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition mq.c:285
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition mq.c:655
const struct GNUNET_MessageHeader * GNUNET_MQ_env_get_msg(const struct GNUNET_MQ_Envelope *env)
Obtain message contained in envelope.
Definition mq.c:896
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition strings.c:137
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
#define GNUNET_TIME_absolute_cmp(t1, op, t2)
Compare two absolute times.
static unsigned int size
Size of the "table".
Definition peer.c:68
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Purpose for the signature of a monotime.
Low-level connection to a destination.
Entry in a peer path.
struct CadetPeerPath * path
Path this entry belongs to.
Information regarding a possible path to reach a peer.
Struct containing all information regarding a given peer.
struct GCP_MessageQueueManager * mqm_tail
Notifications to call when core_mq changes.
struct GCD_search_handle * search_h
Handle to stop the DHT search for paths to this peer.
struct GNUNET_SCHEDULER_Task * heap_cleanup_task
Task to clean up path_heap asynchronously.
struct GNUNET_MQ_Handle * core_mq
Handle for core transmissions.
unsigned int queue_n
How many messages are in the queue to this peer.
struct GNUNET_TIME_Absolute last_connection_create
Last time we heard from this peer (currently not used!)
struct GNUNET_MessageHeader * hello
Hello message of the peer.
struct GNUNET_TRANSPORT_ApplicationSuggestHandle * ash
Transport suggest handle.
struct GNUNET_CONTAINER_Heap * path_heap
MIN-heap of paths owned by this peer (they also end at this peer).
struct CadetPeerPathEntry ** path_heads
Array of DLLs of paths traversing the peer, organized by the offset of the peer on the larger path.
unsigned int mqm_ready_counter
Number of message queue managers of this peer that have a message in waiting.
unsigned int num_paths
How many paths do we have to this peer (in all path_heads DLLs combined).
struct GNUNET_SCHEDULER_Task * destroy_task
Task to destroy this entry.
unsigned int off_sum
Sum over all of the offsets of all of the paths in the path_heads DLLs.
struct GCP_MessageQueueManager * mqm_head
Notifications to call when core_mq changes.
struct GNUNET_CONTAINER_MultiShortmap * connections
Connections that go through this peer; indexed by tid.
struct GNUNET_TRANSPORT_OfferHelloHandle * hello_offer
Handle to us offering the HELLO to the transport.
struct GNUNET_PeerIdentity pid
ID of the peer.
struct CadetTunnel * t
Tunnel to this peer, if any.
struct GCP_MessageQueueManager * mqm_ready_ptr
Pointer to first "ready" entry in mqm_head.
unsigned int path_dll_length
Current length of the path_heads and path_tails arrays.
struct CadetPeerPathEntry ** path_tails
Array of DLL of paths traversing the peer, organized by the offset of the peer on the larger path.
Struct containing all information regarding a tunnel to a peer.
Data structure used to track whom we have to notify about changes to our message queue.
struct CadetPeer * cp
The peer this is for.
GCP_MessageQueueNotificationCallback cb
Function to call with updated message queue object.
struct GNUNET_MQ_Envelope * env
Envelope this manager would like to transmit once it is its turn.
struct GCP_MessageQueueManager * next
Kept in a DLL.
struct GCP_MessageQueueManager * prev
Kept in a DLL.
32-bit bandwidth used for network exchange by GNUnet, in bytes per second.
Message for cadet connection creation.
Message for a Key eXchange for a tunnel.
Handle to a node in a heap.
Internal representation of the hash map.
Handle to a message queue.
Definition mq.c:87
Header for all communications.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:141
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
Handle for TRANSPORT address suggestion requests.

◆ IDLE_PATH_TIMEOUT

#define IDLE_PATH_TIMEOUT
Value:

How long do we keep paths around if we no longer care about the peer?

Definition at line 61 of file gnunet-service-cadet_peer.c.

◆ MAX_OOO_QUEUE_SIZE

#define MAX_OOO_QUEUE_SIZE   100

Queue size when we start dropping OOO messages.

Definition at line 67 of file gnunet-service-cadet_peer.c.

Function Documentation

◆ GCP_2s()

const char * GCP_2s ( const struct CadetPeer peer)

Get the static string for a peer ID.

Parameters
peerPeer.
Returns
Static string for it's ID.

Definition at line 234 of file gnunet-service-cadet_peer.c.

235{
236 static char buf[5];
237 char *ret;
238
239 if ((NULL == cp) ||
241 return "NULL";
242
244 if (NULL == ret)
245 return "NULL";
246
247 GNUNET_strlcpy (buf,
248 ret,
249 sizeof(buf));
251 return buf;
252}

References GNUNET_CRYPTO_eddsa_public_key_to_string(), GNUNET_free, GNUNET_is_zero, GNUNET_strlcpy(), GNUNET_YES, CadetPeer::pid, GNUNET_PeerIdentity::public_key, and ret.

Referenced by consider_path_cb(), consider_peer_activate(), destroy_peer(), dht_get_id_handler(), GCC_debug(), GCCH_channel_incoming_new(), GCCH_channel_local_new(), GCP_add_connection(), GCP_attach_path(), GCP_detach_path(), GCP_drop_owned_paths(), GCP_drop_tunnel(), GCP_get(), GCP_iterate_indirect_paths(), GCP_iterate_paths(), GCP_path_entry_add(), GCP_path_entry_remove(), GCP_remove_connection(), GCP_request_mq(), GCP_request_mq_cancel(), GCP_send(), GCP_send_ooo(), GCP_set_hello(), GCP_set_mq(), GSC_bind(), handle_connection_create(), mqm_execute(), mqm_send_done(), route_message(), send_broken(), and timeout_closed_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_get_desirability_of_path()

double GCP_get_desirability_of_path ( struct CadetPeer cp,
unsigned int  off 
)

Calculate how desirable a path is for cp if cp is at offset off in the path.

The 'desirability_table.c' program can be used to compute a list of sample outputs for different scenarios. Basically, we score paths lower if there are many alternatives, and higher if they are shorter than average, and very high if they are much shorter than average and without many alternatives.

Parameters
cpa peer reachable via a path
offoffset of cp in a path
Returns
score how useful a path is to reach cp, positive scores mean path is more desirable

Definition at line 256 of file gnunet-service-cadet_peer.c.

258{
259 unsigned int num_alts = cp->num_paths;
260 unsigned int off_sum;
261 double avg_sum;
262 double path_delta;
263 double weight_alts;
264
265 GNUNET_assert (num_alts >= 1); /* 'path' should be in there! */
267
268 /* We maintain 'off_sum' in 'peer' and thereby
269 avoid the SLOW recalculation each time. Kept here
270 just to document what is going on. */
271#if SLOW
272 off_sum = 0;
273 for (unsigned int j = 0; j < cp->path_dll_length; j++)
274 for (struct CadetPeerPathEntry *pe = cp->path_heads[j];
275 NULL != pe;
276 pe = pe->next)
277 off_sum += j;
278 GNUNET_assert (off_sum == cp->off_sum);
279#else
280 off_sum = cp->off_sum;
281#endif
282 avg_sum = off_sum * 1.0 / cp->path_dll_length;
283 path_delta = off - avg_sum;
284 /* path_delta positive: path off of peer above average (bad path for peer),
285 path_delta negative: path off of peer below average (good path for peer) */
286 if (path_delta <= -1.0)
287 weight_alts = -num_alts / path_delta; /* discount alternative paths */
288 else if (path_delta >= 1.0)
289 weight_alts = num_alts * path_delta; /* overcount alternative paths */
290 else
291 weight_alts = num_alts; /* count alternative paths normally */
292
293
294 /* off+1: long paths are generally harder to find and thus count
295 a bit more as they get longer. However, above-average paths
296 still need to count less, hence the squaring of that factor. */
297 return (off + 1.0) / (weight_alts * weight_alts);
298}

References GNUNET_assert, CadetPeer::num_paths, CadetPeer::off_sum, CadetPeer::path_dll_length, and CadetPeer::path_heads.

Referenced by recalculate_path_desirability().

Here is the caller graph for this function:

◆ destroy_peer()

static void destroy_peer ( void *  cls)
static

This peer is no longer be needed, clean it up now.

Parameters
clspeer to clean up

Definition at line 307 of file gnunet-service-cadet_peer.c.

308{
309 struct CadetPeer *cp = cls;
310
312 "Destroying state about peer %s\n",
313 GCP_2s (cp));
314 cp->destroy_task = NULL;
315 GNUNET_assert (NULL == cp->t);
316 GNUNET_assert (NULL == cp->core_mq);
317 GNUNET_assert (0 == cp->num_paths);
318 for (unsigned int i = 0; i < cp->path_dll_length; i++)
319 GNUNET_assert (NULL == cp->path_heads[i]);
323 &cp->pid,
324 cp));
327 cp->path_dll_length = 0;
328 if (NULL != cp->search_h)
329 {
331 cp->search_h = NULL;
332 }
333 /* FIXME: clean up search_delayedXXX! */
334
335
336 if (NULL != cp->ash)
337 {
339 cp->ash = NULL;
340 }
342 if (NULL != cp->path_heap)
343 {
345 cp->path_heap = NULL;
346 }
347 if (NULL != cp->heap_cleanup_task)
348 {
350 cp->heap_cleanup_task = NULL;
351 }
352 GNUNET_free (cp->hello);
353 /* Peer should not be freed if paths exist; if there are no paths,
354 there ought to be no connections, and without connections, no
355 notifications. Thus we can assert that mqm_head is empty at this
356 point. */
357 GNUNET_assert (NULL == cp->mqm_head);
358 GNUNET_assert (NULL == cp->mqm_ready_ptr);
359 GNUNET_free (cp);
360}

References CadetPeer::ash, CadetPeer::connections, CadetPeer::core_mq, CadetPeer::destroy_task, GCD_search_stop(), GCP_2s(), GNUNET_assert, GNUNET_CONTAINER_heap_destroy(), GNUNET_CONTAINER_multipeermap_remove(), GNUNET_CONTAINER_multishortmap_destroy(), GNUNET_CONTAINER_multishortmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_SCHEDULER_cancel(), GNUNET_TRANSPORT_application_suggest_cancel(), GNUNET_YES, CadetPeer::heap_cleanup_task, CadetPeer::hello, LOG, CadetPeer::mqm_head, CadetPeer::mqm_ready_ptr, CadetPeer::num_paths, CadetPeer::path_dll_length, CadetPeer::path_heads, CadetPeer::path_heap, CadetPeer::path_tails, peers, CadetPeer::pid, CadetPeer::search_h, and CadetPeer::t.

Referenced by consider_peer_destroy(), and destroy_iterator_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ consider_peer_activate()

static void consider_peer_activate ( struct CadetPeer cp)
static

This peer is now on more "active" duty, activate processes related to it.

Parameters
cpthe more-active peer

Definition at line 369 of file gnunet-service-cadet_peer.c.

370{
372
374 "Updating peer %s activation state (%u connections)%s%s\n",
375 GCP_2s (cp),
377 (NULL == cp->t) ? "" : " with tunnel",
378 (NULL == cp->core_mq) ? "" : " with CORE link");
379 if (NULL != cp->destroy_task)
380 {
381 /* It's active, do not destroy! */
383 cp->destroy_task = NULL;
384 }
386 (NULL == cp->t))
387 {
388 /* We're just on a path or directly connected; don't bother too much */
389 if (NULL != cp->ash)
390 {
392 cp->ash = NULL;
393 }
394 if (NULL != cp->search_h)
395 {
397 cp->search_h = NULL;
398 }
399 return;
400 }
401 if (NULL == cp->core_mq)
402 {
403 /* Lacks direct connection, try to create one by querying the DHT */
404 if ((NULL == cp->search_h) &&
406 cp->search_h
407 = GCD_search (&cp->pid);
408 }
409 else
410 {
411 /* Have direct connection, stop DHT search if active */
412 if (NULL != cp->search_h)
413 {
415 cp->search_h = NULL;
416 }
417 }
418
419 if (NULL != cp->ash)
421 bw.value__ = 0;
422 cp->ash
424 &cp->pid,
426 bw);
427}

References CadetPeer::ash, CadetPeer::connections, CadetPeer::core_mq, DESIRED_CONNECTIONS_PER_TUNNEL, CadetPeer::destroy_task, GCD_search(), GCD_search_stop(), GCP_2s(), GNUNET_CONTAINER_multishortmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MQ_PRIO_BEST_EFFORT, GNUNET_SCHEDULER_cancel(), GNUNET_TRANSPORT_application_suggest(), GNUNET_TRANSPORT_application_suggest_cancel(), LOG, CadetPeer::num_paths, CadetPeer::pid, CadetPeer::search_h, CadetPeer::t, transport, and GNUNET_BANDWIDTH_Value32NBO::value__.

Referenced by GCP_get_tunnel(), and GCP_set_mq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ consider_peer_destroy()

static void consider_peer_destroy ( struct CadetPeer cp)
static

This peer may no longer be needed, consider cleaning it up.

Parameters
cppeer to clean up

Definition at line 464 of file gnunet-service-cadet_peer.c.

465{
466 struct GNUNET_TIME_Relative exp;
467
468 if (NULL != cp->destroy_task)
469 {
471 cp->destroy_task = NULL;
472 }
473 if (NULL != cp->t)
474 return; /* still relevant! */
475 if (NULL != cp->core_mq)
476 return; /* still relevant! */
478 return; /* still relevant! */
479 if ((NULL != cp->path_heap) &&
481 {
483 &drop_paths,
484 cp);
485 return;
486 }
487 if (0 != cp->num_paths)
488 return; /* still relevant! */
489 if (NULL != cp->hello)
490 {
491 /* relevant only until HELLO expires */
496 cp);
497 return;
498 }
501 cp);
502}

References CadetPeer::connections, CadetPeer::core_mq, destroy_peer(), CadetPeer::destroy_task, drop_paths(), GNUNET_CONTAINER_heap_get_size(), GNUNET_CONTAINER_multishortmap_size(), GNUNET_HELLO_get_expiration_time_from_msg(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_absolute_get_remaining(), CadetPeer::hello, IDLE_PATH_TIMEOUT, IDLE_PEER_TIMEOUT, CadetPeer::num_paths, CadetPeer::path_heap, and CadetPeer::t.

Referenced by drop_paths(), GCP_drop_tunnel(), GCP_path_entry_add(), GCP_path_entry_remove(), GCP_remove_connection(), GCP_set_hello(), and GCP_set_mq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ drop_paths()

static void drop_paths ( void *  cls)
static

We really no longere care about a peer, stop hogging memory with paths to it.

Afterwards, see if there is more to be cleaned up about this peer.

Parameters
clsa struct CadetPeer.

Definition at line 446 of file gnunet-service-cadet_peer.c.

447{
448 struct CadetPeer *cp = cls;
449 struct CadetPeerPath *path;
450
451 cp->destroy_task = NULL;
452 while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
453 GCPP_release (path);
455}

References consider_peer_destroy(), CadetPeer::destroy_task, GCPP_release(), GNUNET_CONTAINER_heap_remove_root(), and CadetPeer::path_heap.

Referenced by consider_peer_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_set_mq()

void GCP_set_mq ( struct CadetPeer cp,
struct GNUNET_MQ_Handle mq 
)

Set the message queue to mq for peer cp and notify watchers.

Parameters
cppeer to modify
mqmessage queue to set (can be NULL)

Definition at line 512 of file gnunet-service-cadet_peer.c.

514{
516 "Message queue for peer %s is now %p\n",
517 GCP_2s (cp),
518 mq);
519 cp->core_mq = mq;
520 for (struct GCP_MessageQueueManager *mqm = cp->mqm_head, *next;
521 NULL != mqm;
522 mqm = next)
523 {
524 /* Save next pointer in case mqm gets freed by the callback */
525 next = mqm->next;
526 if (NULL == mq)
527 {
528 if (NULL != mqm->env)
529 {
530 GNUNET_MQ_discard (mqm->env);
531 mqm->env = NULL;
532 mqm->cb (mqm->cb_cls,
534 }
535 else
536 {
537 mqm->cb (mqm->cb_cls,
538 GNUNET_NO);
539 }
540 }
541 else
542 {
543 GNUNET_assert (NULL == mqm->env);
544 mqm->cb (mqm->cb_cls,
545 GNUNET_YES);
546 }
547 }
548 if ((NULL != mq) ||
549 (NULL != cp->t))
551 else
553
554 if ((NULL != mq) &&
555 (NULL != cp->t))
556 {
557 /* have a new, direct path to the target, notify tunnel */
558 struct CadetPeerPath *path;
559
560 path = GCPP_get_path_from_route (1,
561 &cp->pid);
562 GCT_consider_path (cp->t,
563 path,
564 0);
565 }
566}

References consider_peer_activate(), consider_peer_destroy(), CadetPeer::core_mq, GCP_2s(), GCPP_get_path_from_route(), GCT_consider_path(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MQ_discard(), GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, LOG, mq, CadetPeer::mqm_head, CadetPeer::pid, and CadetPeer::t.

Referenced by core_connect_cb(), and core_disconnect_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ should_I_drop()

static int should_I_drop ( void  )
static

Debug function should NEVER return true in production code, useful to simulate losses for testcases.

Returns
GNUNET_YES or GNUNET_NO with the decision to drop.

Definition at line 576 of file gnunet-service-cadet_peer.c.

577{
578 if (0 == drop_percent)
579 return GNUNET_NO;
581 return GNUNET_YES;
582 return GNUNET_NO;
583}

References drop_percent, GNUNET_CRYPTO_random_u32(), GNUNET_NO, and GNUNET_YES.

Referenced by mqm_execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mqm_send_done()

static void mqm_send_done ( void *  cls)
static

Function called when CORE took one of the messages from a message queue manager and transmitted it.

Parameters
clsthe struct CadetPeeer where we made progress

Definition at line 698 of file gnunet-service-cadet_peer.c.

699{
700 struct CadetPeer *cp = cls;
701
703 "Sending to peer %s completed\n",
704 GCP_2s (cp));
705 send_next_ready (cp);
706}

References GCP_2s(), GNUNET_ERROR_TYPE_DEBUG, LOG, and send_next_ready().

Referenced by GCP_request_mq_cancel(), GCP_send(), GCP_send_ooo(), and mqm_execute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mqm_execute()

static void mqm_execute ( struct GCP_MessageQueueManager mqm)
static

Transmit current envelope from this mqm.

Parameters
mqmmqm to transmit message for now

Definition at line 602 of file gnunet-service-cadet_peer.c.

603{
604 struct CadetPeer *cp = mqm->cp;
605
606 /* Move ready pointer to the next entry that might be ready. */
607 if ((mqm == cp->mqm_ready_ptr) &&
608 (NULL != mqm->next))
609 cp->mqm_ready_ptr = mqm->next;
610 /* Move entry to the end of the DLL, to be fair. */
611 if (mqm != cp->mqm_tail)
612 {
614 cp->mqm_tail,
615 mqm);
617 cp->mqm_tail,
618 mqm);
619 }
620 cp->mqm_ready_counter--;
621 if (GNUNET_YES == should_I_drop ())
622 {
624 "DROPPING message to peer %s from MQM %p\n",
625 GCP_2s (cp),
626 mqm);
627 GNUNET_MQ_discard (mqm->env);
628 mqm->env = NULL;
629 mqm_send_done (cp);
630 }
631 else
632 {
633 {
634 const struct GNUNET_MessageHeader *mh;
635
637 switch (ntohs (mh->type))
638 {
640 {
642 = (const struct GNUNET_CADET_TunnelKeyExchangeMessage *) mh;
644 "P2P forwarding KX with ephemeral %s to %s on CID %s\n",
645 GNUNET_e2s (&msg->ephemeral_key),
646 GCP_2s (cp),
647 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
648 }
649 break;
650
651 default:
652 break;
653 }
654 }
656 "Sending to peer %s from MQM %p\n",
657 GCP_2s (cp),
658 mqm);
660 mqm->env);
661 mqm->env = NULL;
662 }
663 mqm->cb (mqm->cb_cls,
664 GNUNET_YES);
665}

References GCP_MessageQueueManager::cb, GCP_MessageQueueManager::cb_cls, CadetPeer::core_mq, GCP_MessageQueueManager::cp, GCP_MessageQueueManager::env, GCP_2s(), GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX, GNUNET_MQ_discard(), GNUNET_MQ_env_get_msg(), GNUNET_MQ_send(), GNUNET_sh2s(), GNUNET_YES, LOG, mh, CadetPeer::mqm_head, CadetPeer::mqm_ready_counter, CadetPeer::mqm_ready_ptr, mqm_send_done(), CadetPeer::mqm_tail, msg, GCP_MessageQueueManager::next, and should_I_drop().

Referenced by send_next_ready().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_next_ready()

static void send_next_ready ( struct CadetPeer cp)
static

Find the next ready message in the queue (starting the search from the cp->mqm_ready_ptr) and if possible execute the transmission.

Parameters
cppeer to try to send the next ready message to

Definition at line 676 of file gnunet-service-cadet_peer.c.

677{
678 struct GCP_MessageQueueManager *mqm;
679
680 if (0 == cp->mqm_ready_counter)
681 return;
682 while ((NULL != (mqm = cp->mqm_ready_ptr)) &&
683 (NULL == mqm->env))
684 cp->mqm_ready_ptr = mqm->next;
685 if (NULL == mqm)
686 return; /* nothing to do */
687 mqm_execute (mqm);
688}

References GCP_MessageQueueManager::cp, GCP_MessageQueueManager::env, mqm_execute(), CadetPeer::mqm_ready_counter, CadetPeer::mqm_ready_ptr, and GCP_MessageQueueManager::next.

Referenced by GCP_send(), and mqm_send_done().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_send()

void GCP_send ( struct GCP_MessageQueueManager mqm,
struct GNUNET_MQ_Envelope env 
)

Send the message in env to cp.

Send the message in env via a mqm.

Parameters
mqmthe message queue manager to use for transmission
envenvelope with the message to send; must NOT yet have a GNUNET_MQ_notify_sent() callback attached to it

Definition at line 717 of file gnunet-service-cadet_peer.c.

719{
720 struct CadetPeer *cp = mqm->cp;
721
722 GNUNET_assert (NULL != env);
724 "Queueing message to peer %s in MQM %p\n",
725 GCP_2s (cp),
726 mqm);
727 GNUNET_assert (NULL != cp->core_mq);
728 GNUNET_assert (NULL == mqm->env);
731 cp);
732 mqm->env = env;
733 cp->mqm_ready_counter++;
734 if (mqm != cp->mqm_ready_ptr)
735 cp->mqm_ready_ptr = cp->mqm_head;
736 if (1 == cp->mqm_ready_counter)
737 cp->mqm_ready_ptr = mqm;
738 if (0 != GNUNET_MQ_get_length (cp->core_mq))
739 return;
740 send_next_ready (cp);
741}

References CadetPeer::core_mq, GCP_MessageQueueManager::cp, env, GCP_MessageQueueManager::env, GCP_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MQ_get_length(), GNUNET_MQ_notify_sent(), LOG, CadetPeer::mqm_head, CadetPeer::mqm_ready_counter, CadetPeer::mqm_ready_ptr, mqm_send_done(), and send_next_ready().

Referenced by cont_send_create(), dir_ready_cb(), GCC_transmit(), route_message(), and send_create_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_iterator_cb()

static int destroy_iterator_cb ( void *  cls,
const struct GNUNET_PeerIdentity pid,
void *  value 
)
static

Function called to destroy a peer now.

Parameters
clsNULL
pididentity of the peer (unused)
valuethe struct CadetPeer to clean up
Returns
GNUNET_OK (continue to iterate)

Definition at line 753 of file gnunet-service-cadet_peer.c.

756{
757 struct CadetPeer *cp = value;
758
759 if (NULL != cp->destroy_task)
760 {
762 cp->destroy_task = NULL;
763 }
764 destroy_peer (cp);
765 return GNUNET_OK;
766}

References destroy_peer(), CadetPeer::destroy_task, GNUNET_OK, GNUNET_SCHEDULER_cancel(), and value.

Referenced by GCP_destroy_all_peers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_destroy_all_peers()

void GCP_destroy_all_peers ( void  )

Clean up all entries about all peers.

Must only be called after all tunnels, CORE-connections and connections are down.

Definition at line 775 of file gnunet-service-cadet_peer.c.

776{
778 "Destroying all peers now\n");
781 NULL);
782}

References destroy_iterator_cb(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_ERROR_TYPE_DEBUG, LOG, and peers.

Referenced by shutdown_rest().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_drop_owned_paths()

void GCP_drop_owned_paths ( struct CadetPeer cp)

Drop all paths owned by this peer, and do not allow new ones to be added: We are shutting down.

Parameters
cppeer to drop paths to

Definition at line 792 of file gnunet-service-cadet_peer.c.

793{
794 struct CadetPeerPath *path;
795
797 "Destroying all paths to %s\n",
798 GCP_2s (cp));
799 while (NULL != (path =
801 GCPP_release (path);
803 cp->path_heap = NULL;
804}

References GCP_2s(), GCPP_release(), GNUNET_CONTAINER_heap_destroy(), GNUNET_CONTAINER_heap_remove_root(), GNUNET_ERROR_TYPE_DEBUG, LOG, and CadetPeer::path_heap.

Referenced by destroy_paths_now().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_path_entry_add()

void GCP_path_entry_add ( struct CadetPeer cp,
struct CadetPeerPathEntry entry,
unsigned int  off 
)

Add an entry to the DLL of all of the paths that this peer is on.

Parameters
cppeer to modify
entryan entry on a path
offoffset of this peer on the path

Definition at line 815 of file gnunet-service-cadet_peer.c.

818{
820 off));
822 "Discovered that peer %s is on path %s at offset %u\n",
823 GCP_2s (cp),
824 GCPP_2s (entry->path),
825 off);
826 if (off >= cp->path_dll_length)
827 {
828 unsigned int len = cp->path_dll_length;
829
831 len,
832 off + 4);
834 cp->path_dll_length,
835 off + 4);
836 }
838 cp->path_tails[off],
839 entry);
840 cp->off_sum += off;
841 cp->num_paths++;
842
843 /* If we have a tunnel to this peer, tell the tunnel that there is a
844 new path available. */
845 if (NULL != cp->t)
846 GCT_consider_path (cp->t,
847 entry->path,
848 off);
849
850 if ((NULL != cp->search_h) &&
851 (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths))
852 {
853 /* Now I have enough paths, stop search */
855 cp->search_h = NULL;
856 }
857 if (NULL != cp->destroy_task)
858 {
859 /* paths changed, this resets the destroy timeout counter
860 and aborts a destroy task that may no longer be valid
861 to have (as we now have more paths via this peer). */
863 }
864}

References consider_peer_destroy(), CadetPeer::destroy_task, GCD_search_stop(), GCP_2s(), GCPP_2s(), GCPP_get_peer_at_offset(), GCT_consider_path(), GNUNET_array_grow, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, LOG, CadetPeer::num_paths, CadetPeer::off_sum, CadetPeerPathEntry::path, CadetPeer::path_dll_length, CadetPeer::path_heads, CadetPeer::path_tails, CadetPeer::search_h, and CadetPeer::t.

Referenced by extend_path(), GCPP_get_path_from_route(), and GCPP_try_path_from_dht().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_path_entry_remove()

void GCP_path_entry_remove ( struct CadetPeer cp,
struct CadetPeerPathEntry entry,
unsigned int  off 
)

Remove an entry from the DLL of all of the paths that this peer is on.

Parameters
cppeer to modify
entryan entry on a path
offoffset of this peer on the path

Definition at line 875 of file gnunet-service-cadet_peer.c.

878{
880 "Removing knowledge about peer %s being on path %s at offset %u\n",
881 GCP_2s (cp),
882 GCPP_2s (entry->path),
883 off);
885 cp->path_tails[off],
886 entry);
887 GNUNET_assert (0 < cp->num_paths);
888 cp->off_sum -= off;
889 cp->num_paths--;
890 if ((NULL == cp->core_mq) &&
891 (NULL != cp->t) &&
892 (NULL == cp->search_h) &&
894 cp->search_h
895 = GCD_search (&cp->pid);
896 if (NULL == cp->destroy_task)
897 {
898 /* paths changed, we might now be ready for destruction, check again */
900 }
901}

References consider_peer_destroy(), CadetPeer::core_mq, DESIRED_CONNECTIONS_PER_TUNNEL, CadetPeer::destroy_task, GCD_search(), GCP_2s(), GCPP_2s(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, LOG, CadetPeer::num_paths, CadetPeer::off_sum, CadetPeerPathEntry::path, CadetPeer::path_heads, CadetPeer::path_tails, CadetPeer::pid, CadetPeer::search_h, and CadetPeer::t.

Referenced by attach_path(), and GCPP_release().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ path_heap_cleanup()

static void path_heap_cleanup ( void *  cls)
static

Prune down the number of paths to this peer, we seem to have way too many.

Parameters
clsthe struct CadetPeer to maintain the path heap for

Definition at line 911 of file gnunet-service-cadet_peer.c.

912{
913 struct CadetPeer *cp = cls;
914 struct CadetPeerPath *root;
915
916 cp->heap_cleanup_task = NULL;
919 {
920 /* Now we have way too many, drop least desirable UNLESS it is in use!
921 (Note that this intentionally keeps highly desirable, but currently
922 unused paths around in the hope that we might be able to switch, even
923 if the number of paths exceeds the threshold.) */
925 GNUNET_assert (NULL != root);
926 if (NULL !=
928 cp,
929 GCPP_get_length (root) - 1))
930 break; /* can't fix */
931 /* Got plenty of paths to this destination, and this is a low-quality
932 one that we don't care about. Allow it to die. */
933 GNUNET_assert (root ==
935 GCPP_release (root);
936 }
937}

References DESIRED_CONNECTIONS_PER_TUNNEL, GCPP_get_connection(), GCPP_get_length(), GCPP_release(), GNUNET_assert, GNUNET_CONTAINER_heap_get_size(), GNUNET_CONTAINER_heap_peek(), GNUNET_CONTAINER_heap_remove_root(), CadetPeer::heap_cleanup_task, and CadetPeer::path_heap.

Referenced by GCP_attach_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_attach_path()

struct GNUNET_CONTAINER_HeapNode * GCP_attach_path ( struct CadetPeer cp,
struct CadetPeerPath path,
unsigned int  off,
int  force 
)

Try adding a path to this cp.

If the peer already has plenty of paths, return NULL.

Parameters
cppeer to which the path leads to
patha path looking for an owner; may not be fully initialized yet!
offoffset of cp in path
forceforce attaching the path
Returns
NULL if this peer does not care to become a new owner, otherwise the node in the peer's path heap for the path.

Definition at line 941 of file gnunet-service-cadet_peer.c.

945{
947 struct CadetPeerPath *root;
948 GNUNET_CONTAINER_HeapCostType root_desirability;
949 struct GNUNET_CONTAINER_HeapNode *hn;
950
951 GNUNET_assert (off == GCPP_get_length (path) - 1);
953 off));
954 if (NULL == cp->path_heap)
955 {
956 /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */
957 GNUNET_assert (GNUNET_NO == force);
958 return NULL;
959 }
960 desirability = GCPP_get_desirability (path);
961 if (GNUNET_NO == force)
962 {
963 /* FIXME: desirability is not yet initialized; tricky! */
964 if (GNUNET_NO ==
966 (void **) &root,
967 &root_desirability))
968 {
969 root = NULL;
970 root_desirability = 0;
971 }
972
974 (desirability < root_desirability))
975 {
977 "Decided to not attach path %s to peer %s due to undesirability\n",
978 GCPP_2s (path),
979 GCP_2s (cp));
980 return NULL;
981 }
982 }
983
985 "Attaching path %s to peer %s (%s)\n",
986 GCPP_2s (path),
987 GCP_2s (cp),
988 (GNUNET_NO == force) ? "desirable" : "forced");
989
990 /* Yes, we'd like to add this path, add to our heap */
992 path,
993 desirability);
994
995 /* Consider maybe dropping other paths because of the new one */
998 (NULL != cp->heap_cleanup_task))
1000 cp);
1001 return hn;
1002}

References DESIRED_CONNECTIONS_PER_TUNNEL, GCP_2s(), GCPP_2s(), GCPP_get_desirability(), GCPP_get_length(), GCPP_get_peer_at_offset(), GNUNET_assert, GNUNET_CONTAINER_heap_get_size(), GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_heap_peek2(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SCHEDULER_add_now(), CadetPeer::heap_cleanup_task, LOG, CadetPeer::num_paths, CadetPeer::path_heap, and path_heap_cleanup().

Referenced by attach_path(), extend_path(), and GCPP_get_path_from_route().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_detach_path()

void GCP_detach_path ( struct CadetPeer cp,
struct CadetPeerPath path,
struct GNUNET_CONTAINER_HeapNode hn 
)

This peer can no longer own path as the path has been extended and a peer further down the line is now the new owner.

Parameters
cpold owner of the path
pathpath where the ownership is lost
hnnote in cp's path heap that must be deleted

Definition at line 1015 of file gnunet-service-cadet_peer.c.

1018{
1020 "Detaching path %s from peer %s\n",
1021 GCPP_2s (path),
1022 GCP_2s (cp));
1023 GNUNET_assert (path ==
1025}

References GCP_2s(), GCPP_2s(), GNUNET_assert, GNUNET_CONTAINER_heap_remove_node(), GNUNET_ERROR_TYPE_DEBUG, and LOG.

Referenced by extend_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_add_connection()

void GCP_add_connection ( struct CadetPeer cp,
struct CadetConnection cc 
)

Add a connection to this cp.

Parameters
cppeer via which the connection goes
ccthe connection to add

Definition at line 1035 of file gnunet-service-cadet_peer.c.

1037{
1039 "Adding %s to peer %s\n",
1040 GCC_2s (cc),
1041 GCP_2s (cp));
1044 &GCC_get_id (
1045 cc)->connection_of_tunnel
1046 ,
1047 cc,
1049 if (NULL != cp->destroy_task)
1050 {
1052 cp->destroy_task = NULL;
1053 }
1054}

References CadetPeer::connections, CadetPeer::destroy_task, GCC_2s(), GCC_get_id(), GCP_2s(), GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multishortmap_put(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_OK, GNUNET_SCHEDULER_cancel(), and LOG.

Referenced by connection_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_remove_connection()

void GCP_remove_connection ( struct CadetPeer cp,
struct CadetConnection cc 
)

Remove a connection that went via this cp.

Parameters
cppeer via which the connection went
ccthe connection to remove

Definition at line 1064 of file gnunet-service-cadet_peer.c.

1066{
1068 "Removing connection %s from peer %s\n",
1069 GCC_2s (cc),
1070 GCP_2s (cp));
1073 &GCC_get_id (
1074 cc)->
1075 connection_of_tunnel,
1076 cc));
1078}

References CadetPeer::connections, consider_peer_destroy(), GCC_2s(), GCC_get_id(), GCP_2s(), GNUNET_assert, GNUNET_CONTAINER_multishortmap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_YES, and LOG.

Referenced by GCC_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_get()

struct CadetPeer * GCP_get ( const struct GNUNET_PeerIdentity peer_id,
int  create 
)

Retrieve the CadetPeer structure associated with the peer.

Optionally create one and insert it in the appropriate structures if the peer is not known yet.

Parameters
peer_idFull identity of the peer.
createGNUNET_YES if a new peer should be created if unknown. GNUNET_NO to return NULL if peer is unknown.
Returns
Existing or newly created peer structure. NULL if unknown and not requested create

Definition at line 1093 of file gnunet-service-cadet_peer.c.

1095{
1096 struct CadetPeer *cp;
1097
1099 peer_id);
1100 if (NULL != cp)
1101 return cp;
1102 if (GNUNET_NO == create)
1103 return NULL;
1104 cp = GNUNET_new (struct CadetPeer);
1105 cp->pid = *peer_id;
1107 GNUNET_YES);
1112 &cp->pid,
1113 cp,
1116 "Creating peer %s\n",
1117 GCP_2s (cp));
1118 return cp;
1119}

References CadetPeer::connections, create, GCP_2s(), GNUNET_assert, GNUNET_CONTAINER_heap_create(), GNUNET_CONTAINER_HEAP_ORDER_MIN, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_get(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multishortmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_new, GNUNET_NO, GNUNET_YES, LOG, CadetPeer::path_heap, peer_id, peers, and CadetPeer::pid.

Referenced by core_connect_cb(), dht_get_id_handler(), GCCH_bind(), GCPP_get_path_from_route(), GCPP_try_path_from_dht(), got_hello(), handle_channel_create(), handle_connection_create(), and handle_show_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_get_id()

const struct GNUNET_PeerIdentity * GCP_get_id ( struct CadetPeer cp)

Obtain the peer identity for a struct CadetPeer.

Parameters
cpour peer handle
Returns
the peer identity

Definition at line 1129 of file gnunet-service-cadet_peer.c.

1130{
1131 return &cp->pid;
1132}

References CadetPeer::pid.

Referenced by cont_GCT_handle_kx(), cont_send_create(), destroy_route(), dir_ready_cb(), GCCH_2s(), GCCH_channel_local_new(), GCPP_2s(), GCT_2s(), GCT_handle_kx(), GCT_handle_kx_auth(), get_next_free_ctn(), GSC_bind(), path_info_iterator(), route_message(), send_create(), and send_kx().

Here is the caller graph for this function:

◆ GCP_iterate_all()

void GCP_iterate_all ( GNUNET_CONTAINER_PeerMapIterator  iter,
void *  cls 
)

Iterate over all known peers.

Parameters
iterIterator.
clsClosure for iter.

Definition at line 1142 of file gnunet-service-cadet_peer.c.

1144{
1146 iter,
1147 cls);
1148}

References GNUNET_CONTAINER_multipeermap_iterate(), and peers.

Referenced by handle_get_peers(), handle_info_tunnels(), and shutdown_rest().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_count_paths()

unsigned int GCP_count_paths ( const struct CadetPeer cp)

Count the number of known paths toward the peer.

Parameters
cpPeer to get path info.
Returns
Number of known paths.

Definition at line 1158 of file gnunet-service-cadet_peer.c.

1159{
1160 return cp->num_paths;
1161}

References CadetPeer::num_paths.

Referenced by get_all_peers_iterator().

Here is the caller graph for this function:

◆ GCP_iterate_paths()

unsigned int GCP_iterate_paths ( struct CadetPeer cp,
GCP_PathIterator  callback,
void *  callback_cls 
)

Iterate over the paths to a peer.

Parameters
cpPeer to get path info.
callbackFunction to call for every path.
callback_clsClosure for callback.
Returns
Number of iterated paths.

Definition at line 1173 of file gnunet-service-cadet_peer.c.

1176{
1177 unsigned int ret = 0;
1178
1180 "Iterating over paths to peer %s%s\n",
1181 GCP_2s (cp),
1182 (NULL == cp->core_mq) ? "" : " including direct link");
1183 if (NULL != cp->core_mq)
1184 {
1185 /* FIXME: this branch seems to duplicate the
1186 i=0 case below (direct link). Leave out!??? -CG */
1187 struct CadetPeerPath *path;
1188
1189 path = GCPP_get_path_from_route (1,
1190 &cp->pid);
1191 ret++;
1192 if (GNUNET_NO ==
1193 callback (callback_cls,
1194 path,
1195 0))
1196 return ret;
1197 }
1198 for (unsigned int i = 0; i < cp->path_dll_length; i++)
1199 {
1200 for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1201 NULL != pe;
1202 pe = pe->next)
1203 {
1204 ret++;
1205 if (GNUNET_NO ==
1206 callback (callback_cls,
1207 pe->path,
1208 i))
1209 return ret;
1210 }
1211 }
1212 return ret;
1213}

References CadetPeer::core_mq, GCP_2s(), GCPP_get_path_from_route(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, LOG, CadetPeer::path_dll_length, CadetPeer::path_heads, CadetPeer::pid, and ret.

Referenced by maintain_connections_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_iterate_indirect_paths()

unsigned int GCP_iterate_indirect_paths ( struct CadetPeer cp,
GCP_PathIterator  callback,
void *  callback_cls 
)

Iterate over the paths to a peer without direct link.

Parameters
cpPeer to get path info.
callbackFunction to call for every path.
callback_clsClosure for callback.
Returns
Number of iterated paths.

Definition at line 1225 of file gnunet-service-cadet_peer.c.

1228{
1229 unsigned int ret = 0;
1230
1232 "Iterating over paths to peer %s without direct link\n",
1233 GCP_2s (cp));
1234 for (unsigned int i = 1; i < cp->path_dll_length; i++)
1235 {
1236 for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1237 NULL != pe;
1238 pe = pe->next)
1239 {
1240 ret++;
1241 if (GNUNET_NO ==
1242 callback (callback_cls,
1243 pe->path,
1244 i))
1245 return ret;
1246 }
1247 }
1248 return ret;
1249}

References GCP_2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, LOG, CadetPeer::path_dll_length, CadetPeer::path_heads, and ret.

Referenced by handle_show_path().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_iterate_paths_at()

unsigned int GCP_iterate_paths_at ( struct CadetPeer cp,
unsigned int  dist,
GCP_PathIterator  callback,
void *  callback_cls 
)

Iterate over the paths to peer where peer is at distance dist from us.

Parameters
cpPeer to get path info.
distdesired distance of peer to us on the path
callbackFunction to call for every path.
callback_clsClosure for callback.
Returns
Number of iterated paths.

Definition at line 1253 of file gnunet-service-cadet_peer.c.

1257{
1258 unsigned int ret = 0;
1259
1260 if (dist >= cp->path_dll_length)
1261 {
1263 "Asked to look for paths at distance %u, but maximum for me is < %u\n",
1264 dist,
1265 cp->path_dll_length);
1266 return 0;
1267 }
1268 for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
1269 NULL != pe;
1270 pe = pe->next)
1271 {
1272 if (GNUNET_NO ==
1273 callback (callback_cls,
1274 pe->path,
1275 dist))
1276 return ret;
1277 ret++;
1278 }
1279 return ret;
1280}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, LOG, CadetPeer::path_dll_length, CadetPeer::path_heads, and ret.

Referenced by GCPP_get_path_from_route(), and GCPP_try_path_from_dht().

Here is the caller graph for this function:

◆ GCP_get_tunnel()

struct CadetTunnel * GCP_get_tunnel ( struct CadetPeer cp,
int  create 
)

Get the tunnel towards a peer.

Parameters
cpPeer to get from.
createGNUNET_YES to create a tunnel if we do not have one
Returns
Tunnel towards peer.

Definition at line 1291 of file gnunet-service-cadet_peer.c.

1293{
1294 if (NULL == cp)
1295 return NULL;
1296 if ((NULL != cp->t) ||
1297 (GNUNET_NO == create))
1298 return cp->t;
1299 cp->t = GCT_create_tunnel (cp);
1301 return cp->t;
1302}

References consider_peer_activate(), create, GCT_create_tunnel(), GNUNET_NO, and CadetPeer::t.

Referenced by destroy_tunnels_now(), GCCH_channel_local_new(), get_all_peers_iterator(), get_all_tunnels_iterator(), handle_connection_create(), and send_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_set_hello()

void GCP_set_hello ( struct CadetPeer cp,
const struct GNUNET_MessageHeader hello 
)

We got a HELLO for a cp, remember it, and possibly trigger adequate actions (like trying to connect).

Parameters
cpthe peer we got a HELLO for
hellothe HELLO to remember

Definition at line 1306 of file gnunet-service-cadet_peer.c.

1308{
1310 uint16_t size = ntohs (hello->size);
1311
1313 "Got %u byte HELLO for peer %s\n",
1314 (unsigned int) size,
1315 GCP_2s (cp));
1316 if (NULL != cp->hello)
1317 {
1319
1320 struct GNUNET_TIME_Absolute new_hello_exp =
1322 struct GNUNET_TIME_Absolute old_hello_exp =
1324
1325 if (GNUNET_TIME_absolute_cmp (new_hello_exp, >, now) &&
1326 GNUNET_TIME_absolute_cmp (new_hello_exp, >, old_hello_exp))
1327 {
1328 GNUNET_free (cp->hello);
1329 cp->hello = GNUNET_malloc (size);
1330 GNUNET_memcpy (cp->hello, hello, size);
1331 }
1332 else
1333 {
1334 return;
1335 }
1336 }
1337 else
1338 {
1339 cp->hello = GNUNET_memdup (hello,
1340 size);
1341 }
1342 if (NULL != cp->ash)
1344 bw.value__ = 0;
1345 cp->ash
1347 &cp->pid,
1349 bw);
1350 /* New HELLO means cp's destruction time may change... */
1352}

References CadetPeer::ash, consider_peer_destroy(), GCP_2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_get_expiration_time_from_msg(), GNUNET_malloc, GNUNET_memcpy, GNUNET_memdup, GNUNET_MQ_PRIO_BEST_EFFORT, GNUNET_TIME_absolute_cmp, GNUNET_TIME_absolute_get(), GNUNET_TRANSPORT_application_suggest(), GNUNET_TRANSPORT_application_suggest_cancel(), CadetPeer::hello, LOG, CadetPeer::pid, GNUNET_MessageHeader::size, size, transport, and GNUNET_BANDWIDTH_Value32NBO::value__.

Referenced by dht_get_id_handler(), and got_hello().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_drop_tunnel()

void GCP_drop_tunnel ( struct CadetPeer cp,
struct CadetTunnel t 
)

The tunnel to the given peer no longer exists, remove it from our data structures, and possibly clean up the peer itself.

Parameters
cpthe peer affected
tthe dead tunnel

Definition at line 1363 of file gnunet-service-cadet_peer.c.

1365{
1367 "Dropping tunnel %s to peer %s\n",
1368 GCT_2s (t),
1369 GCP_2s (cp));
1370 GNUNET_assert (cp->t == t);
1371 cp->t = NULL;
1373}

References consider_peer_destroy(), GCP_2s(), GCT_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, LOG, t, and CadetPeer::t.

Referenced by destroy_tunnel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_has_core_connection()

int GCP_has_core_connection ( struct CadetPeer cp)

Test if cp has a core-level connection.

Parameters
cppeer to test
Returns
GNUNET_YES if cp has a core-level connection

Definition at line 1383 of file gnunet-service-cadet_peer.c.

1384{
1385 return (NULL != cp->core_mq) ? GNUNET_YES : GNUNET_NO;
1386}

References CadetPeer::core_mq, GNUNET_NO, and GNUNET_YES.

Referenced by handle_connection_create().

Here is the caller graph for this function:

◆ GCP_request_mq()

struct GCP_MessageQueueManager * GCP_request_mq ( struct CadetPeer cp,
GCP_MessageQueueNotificationCallback  cb,
void *  cb_cls 
)

Start message queue change notifications.

Parameters
cppeer to notify for
cbfunction to call if mq becomes available or unavailable
cb_clsclosure for cb
Returns
handle to cancel request

Definition at line 1398 of file gnunet-service-cadet_peer.c.

1401{
1402 struct GCP_MessageQueueManager *mqm;
1403
1404 mqm = GNUNET_new (struct GCP_MessageQueueManager);
1405 mqm->cb = cb;
1406 mqm->cb_cls = cb_cls;
1407 mqm->cp = cp;
1409 cp->mqm_tail,
1410 mqm);
1412 "Creating MQM %p for peer %s\n",
1413 mqm,
1414 GCP_2s (cp));
1415 if (NULL != cp->core_mq)
1416 cb (cb_cls,
1417 GNUNET_YES);
1418 return mqm;
1419}

References GCP_MessageQueueManager::cb, GCP_MessageQueueManager::cb_cls, CadetPeer::core_mq, GCP_MessageQueueManager::cp, GCP_2s(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_new, GNUNET_YES, LOG, CadetPeer::mqm_head, and CadetPeer::mqm_tail.

Referenced by connection_create(), and dir_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_request_mq_cancel()

void GCP_request_mq_cancel ( struct GCP_MessageQueueManager mqm,
struct GNUNET_MQ_Envelope last_env 
)

Stops message queue change notifications.

Stops message queue change notifications and sends a last message.

Parameters
mqmhandle matching request to cancel
last_envfinal message to transmit, or NULL

Definition at line 1429 of file gnunet-service-cadet_peer.c.

1431{
1432 struct CadetPeer *cp = mqm->cp;
1433
1435 "Destroying MQM %p for peer %s%s\n",
1436 mqm,
1437 GCP_2s (cp),
1438 (NULL == last_env) ? "" : " with last ditch transmission");
1439 if (NULL != mqm->env)
1440 GNUNET_MQ_discard (mqm->env);
1441 if (NULL != last_env)
1442 {
1443 if (NULL != cp->core_mq)
1444 {
1445 GNUNET_MQ_notify_sent (last_env,
1447 cp);
1449 last_env);
1450 }
1451 else
1452 {
1453 GNUNET_MQ_discard (last_env);
1454 }
1455 }
1456 if (cp->mqm_ready_ptr == mqm)
1457 cp->mqm_ready_ptr = mqm->next;
1459 cp->mqm_tail,
1460 mqm);
1461 GNUNET_free (mqm);
1462}

References CadetPeer::core_mq, GCP_MessageQueueManager::cp, GCP_MessageQueueManager::env, GCP_2s(), GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_MQ_discard(), GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), LOG, CadetPeer::mqm_head, CadetPeer::mqm_ready_ptr, mqm_send_done(), CadetPeer::mqm_tail, and GCP_MessageQueueManager::next.

Referenced by destroy_direction(), GCC_destroy(), GCC_destroy_without_tunnel(), and send_broken().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_send_ooo()

void GCP_send_ooo ( struct CadetPeer cp,
struct GNUNET_MQ_Envelope env 
)

Send the message in env to cp, overriding queueing logic.

This function should only be used to send error messages outside of flow and congestion control, similar to ICMP. Note that the envelope may be silently discarded as well.

Parameters
cppeer to send the message to
envenvelope with the message to send

Definition at line 1475 of file gnunet-service-cadet_peer.c.

1477{
1479 "Sending message to %s out of management\n",
1480 GCP_2s (cp));
1481 if (NULL == cp->core_mq)
1482 {
1484 return;
1485 }
1487 {
1489 return;
1490 }
1493 cp);
1495 env);
1496}

References CadetPeer::core_mq, env, GCP_2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MQ_discard(), GNUNET_MQ_get_length(), GNUNET_MQ_notify_sent(), GNUNET_MQ_send(), LOG, MAX_OOO_QUEUE_SIZE, and mqm_send_done().

Referenced by route_message(), and send_broken_without_mqm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_check_and_update_monotime()

int GCP_check_and_update_monotime ( struct CadetPeer peer,
struct GNUNET_TIME_AbsoluteNBO  monotime 
)

Checking if a monotime value is newer than the last monotime value received from a peer.

If the time value is newer it will be stored at the peer.

Parameters
peerThe peer we received a new time value from.
monotimeTime value we check against the last time value we received from a peer.
Returns
GNUNET_YES if monotime is newer than the last received time value, GNUNET_NO if monotime is not newer.

Definition at line 1507 of file gnunet-service-cadet_peer.c.

1509{
1510
1511 struct GNUNET_TIME_Absolute mt = GNUNET_TIME_absolute_ntoh (monotime);
1512
1514 {
1515 peer->last_connection_create = mt;
1516 return GNUNET_YES;
1517 }
1518 return GNUNET_NO;
1519}

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_NO, GNUNET_TIME_absolute_ntoh(), GNUNET_YES, and CadetPeer::last_connection_create.

Referenced by handle_connection_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCP_check_monotime_sig()

int GCP_check_monotime_sig ( struct CadetPeer peer,
const struct GNUNET_CADET_ConnectionCreateMessage msg 
)

Checking the signature for a monotime of a GNUNET_CADET_ConnectionCreateMessage.

Parameters
peerThe peer that signed the monotime value.
msgThe GNUNET_CADET_ConnectionCreateMessage with the monotime value.
Returns
GNUNET_OK if the signature is good, GNUNET_SYSERR if not.

Definition at line 1530 of file gnunet-service-cadet_peer.c.

1532{
1533 struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
1535 .purpose.size = htonl (sizeof(cp)),
1536 .monotonic_time = msg->monotime};
1537
1538 if (GNUNET_OK !=
1541 &cp,
1542 &msg->monotime_sig,
1543 &peer->pid.public_key))
1544 {
1545 GNUNET_break_op (0);
1546 return GNUNET_SYSERR;
1547 }
1548 return GNUNET_OK;
1549}
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose is GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...

References GNUNET_break_op, GNUNET_CRYPTO_eddsa_verify, GNUNET_OK, GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR, GNUNET_SYSERR, msg, CadetPeer::pid, GNUNET_PeerIdentity::public_key, GNUNET_CRYPTO_SignaturePurpose::purpose, and CadetConnectionCreatePS::purpose.

Referenced by handle_connection_create().

Here is the caller graph for this function: