GNUnet  0.19.4
gnunet-service-cadet_peer.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2017 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
33 #include "platform.h"
34 #include "gnunet_time_lib.h"
35 #include "gnunet_util_lib.h"
36 #include "gnunet_hello_lib.h"
37 #include "gnunet_signatures.h"
39 #include "gnunet_ats_service.h"
40 #include "gnunet_core_service.h"
43 #include "gnunet-service-cadet.h"
48 
49 
50 #define LOG(level, ...) GNUNET_log_from (level, "cadet-per", __VA_ARGS__)
51 
52 
56 #define IDLE_PEER_TIMEOUT GNUNET_TIME_relative_multiply ( \
57  GNUNET_TIME_UNIT_MINUTES, 5)
58 
62 #define IDLE_PATH_TIMEOUT GNUNET_TIME_relative_multiply ( \
63  GNUNET_TIME_UNIT_MINUTES, 2)
64 
68 #define MAX_OOO_QUEUE_SIZE 100
69 
75 {
80 
85 
90 
94  void *cb_cls;
95 
99  struct CadetPeer *cp;
100 
105 };
106 
107 
111 struct CadetPeer
112 {
116  struct GNUNET_PeerIdentity pid;
117 
122 
128 
134 
139 
144 
149 
155 
160 
165 
170 
174  struct CadetTunnel *t;
175 
180 
185 
190 
195 
201 
205  unsigned int queue_n;
206 
210  unsigned int num_paths;
211 
216  unsigned int off_sum;
217 
225  unsigned int mqm_ready_counter;
226 
231  unsigned int path_dll_length;
232 };
233 
234 
235 const char *
236 GCP_2s (const struct CadetPeer *cp)
237 {
238  static char buf[5];
239  char *ret;
240 
241  if ((NULL == cp) ||
243  return "NULL";
244 
246  if (NULL == ret)
247  return "NULL";
248 
250  ret,
251  sizeof(buf));
252  GNUNET_free (ret);
253  return buf;
254 }
255 
256 
257 double
259  unsigned int off)
260 {
261  unsigned int num_alts = cp->num_paths;
262  unsigned int off_sum;
263  double avg_sum;
264  double path_delta;
265  double weight_alts;
266 
267  GNUNET_assert (num_alts >= 1); /* 'path' should be in there! */
268  GNUNET_assert (0 != cp->path_dll_length);
269 
270  /* We maintain 'off_sum' in 'peer' and thereby
271  avoid the SLOW recalculation each time. Kept here
272  just to document what is going on. */
273 #if SLOW
274  off_sum = 0;
275  for (unsigned int j = 0; j < cp->path_dll_length; j++)
276  for (struct CadetPeerPathEntry *pe = cp->path_heads[j];
277  NULL != pe;
278  pe = pe->next)
279  off_sum += j;
280  GNUNET_assert (off_sum == cp->off_sum);
281 #else
282  off_sum = cp->off_sum;
283 #endif
284  avg_sum = off_sum * 1.0 / cp->path_dll_length;
285  path_delta = off - avg_sum;
286  /* path_delta positive: path off of peer above average (bad path for peer),
287  path_delta negative: path off of peer below average (good path for peer) */
288  if (path_delta <= -1.0)
289  weight_alts = -num_alts / path_delta; /* discount alternative paths */
290  else if (path_delta >= 1.0)
291  weight_alts = num_alts * path_delta; /* overcount alternative paths */
292  else
293  weight_alts = num_alts; /* count alternative paths normally */
294 
295 
296  /* off+1: long paths are generally harder to find and thus count
297  a bit more as they get longer. However, above-average paths
298  still need to count less, hence the squaring of that factor. */
299  return (off + 1.0) / (weight_alts * weight_alts);
300 }
301 
302 
308 static void
309 destroy_peer (void *cls)
310 {
311  struct CadetPeer *cp = cls;
312 
314  "Destroying state about peer %s\n",
315  GCP_2s (cp));
316  cp->destroy_task = NULL;
317  GNUNET_assert (NULL == cp->t);
318  GNUNET_assert (NULL == cp->core_mq);
319  GNUNET_assert (0 == cp->num_paths);
320  for (unsigned int i = 0; i < cp->path_dll_length; i++)
321  GNUNET_assert (NULL == cp->path_heads[i]);
325  &cp->pid,
326  cp));
327  GNUNET_free (cp->path_heads);
328  GNUNET_free (cp->path_tails);
329  cp->path_dll_length = 0;
330  if (NULL != cp->search_h)
331  {
333  cp->search_h = NULL;
334  }
335  /* FIXME: clean up search_delayedXXX! */
336 
337  if (NULL != cp->hello_offer)
338  {
340  cp->hello_offer = NULL;
341  }
342  if (NULL != cp->connectivity_suggestion)
343  {
345  cp->connectivity_suggestion = NULL;
346  }
348  if (NULL != cp->path_heap)
349  {
351  cp->path_heap = NULL;
352  }
353  if (NULL != cp->heap_cleanup_task)
354  {
356  cp->heap_cleanup_task = NULL;
357  }
358  GNUNET_free (cp->hello);
359  /* Peer should not be freed if paths exist; if there are no paths,
360  there ought to be no connections, and without connections, no
361  notifications. Thus we can assert that mqm_head is empty at this
362  point. */
363  GNUNET_assert (NULL == cp->mqm_head);
364  GNUNET_assert (NULL == cp->mqm_ready_ptr);
365  GNUNET_free (cp);
366 }
367 
368 
374 static void
376 {
377  uint32_t strength;
378 
380  "Updating peer %s activation state (%u connections)%s%s\n",
381  GCP_2s (cp),
383  (NULL == cp->t) ? "" : " with tunnel",
384  (NULL == cp->core_mq) ? "" : " with CORE link");
385  if (NULL != cp->destroy_task)
386  {
387  /* It's active, do not destroy! */
389  cp->destroy_task = NULL;
390  }
392  (NULL == cp->t))
393  {
394  /* We're just on a path or directly connected; don't bother too much */
395  if (NULL != cp->connectivity_suggestion)
396  {
398  cp->connectivity_suggestion = NULL;
399  }
400  if (NULL != cp->search_h)
401  {
403  cp->search_h = NULL;
404  }
405  return;
406  }
407  if (NULL == cp->core_mq)
408  {
409  /* Lacks direct connection, try to create one by querying the DHT */
410  if ((NULL == cp->search_h) &&
412  cp->search_h
413  = GCD_search (&cp->pid);
414  }
415  else
416  {
417  /* Have direct connection, stop DHT search if active */
418  if (NULL != cp->search_h)
419  {
421  cp->search_h = NULL;
422  }
423  }
424 
425  /* If we have a tunnel, our urge for connections is much bigger */
426  strength = (NULL != cp->t) ? 32 : 1;
427  if (NULL != cp->connectivity_suggestion)
431  &cp->pid,
432  strength);
433 }
434 
435 
441 static void
442 consider_peer_destroy (struct CadetPeer *cp);
443 
444 
451 static void
452 drop_paths (void *cls)
453 {
454  struct CadetPeer *cp = cls;
455  struct CadetPeerPath *path;
456 
457  cp->destroy_task = NULL;
458  while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
459  GCPP_release (path);
461 }
462 
463 
469 static void
471 {
472  struct GNUNET_TIME_Relative exp;
473 
474  if (NULL != cp->destroy_task)
475  {
477  cp->destroy_task = NULL;
478  }
479  if (NULL != cp->t)
480  return; /* still relevant! */
481  if (NULL != cp->core_mq)
482  return; /* still relevant! */
484  return; /* still relevant! */
485  if ((NULL != cp->path_heap) &&
487  {
489  &drop_paths,
490  cp);
491  return;
492  }
493  if (0 != cp->num_paths)
494  return; /* still relevant! */
495  if (NULL != cp->hello)
496  {
497  /* relevant only until HELLO expires */
499  cp->hello));
501  &destroy_peer,
502  cp);
503  return;
504  }
506  &destroy_peer,
507  cp);
508 }
509 
510 
517 void
518 GCP_set_mq (struct CadetPeer *cp,
519  struct GNUNET_MQ_Handle *mq)
520 {
522  "Message queue for peer %s is now %p\n",
523  GCP_2s (cp),
524  mq);
525  cp->core_mq = mq;
526  for (struct GCP_MessageQueueManager *mqm = cp->mqm_head, *next;
527  NULL != mqm;
528  mqm = next)
529  {
530  /* Save next pointer in case mqm gets freed by the callback */
531  next = mqm->next;
532  if (NULL == mq)
533  {
534  if (NULL != mqm->env)
535  {
536  GNUNET_MQ_discard (mqm->env);
537  mqm->env = NULL;
538  mqm->cb (mqm->cb_cls,
539  GNUNET_SYSERR);
540  }
541  else
542  {
543  mqm->cb (mqm->cb_cls,
544  GNUNET_NO);
545  }
546  }
547  else
548  {
549  GNUNET_assert (NULL == mqm->env);
550  mqm->cb (mqm->cb_cls,
551  GNUNET_YES);
552  }
553  }
554  if ((NULL != mq) ||
555  (NULL != cp->t))
557  else
559 
560  if ((NULL != mq) &&
561  (NULL != cp->t))
562  {
563  /* have a new, direct path to the target, notify tunnel */
564  struct CadetPeerPath *path;
565 
566  path = GCPP_get_path_from_route (1,
567  &cp->pid);
568  GCT_consider_path (cp->t,
569  path,
570  0);
571  }
572 }
573 
574 
581 static int
583 {
584  if (0 == drop_percent)
585  return GNUNET_NO;
587  101) < drop_percent)
588  return GNUNET_YES;
589  return GNUNET_NO;
590 }
591 
592 
599 static void
600 mqm_send_done (void *cls);
601 
602 
608 static void
610 {
611  struct CadetPeer *cp = mqm->cp;
612 
613  /* Move ready pointer to the next entry that might be ready. */
614  if ((mqm == cp->mqm_ready_ptr) &&
615  (NULL != mqm->next))
616  cp->mqm_ready_ptr = mqm->next;
617  /* Move entry to the end of the DLL, to be fair. */
618  if (mqm != cp->mqm_tail)
619  {
621  cp->mqm_tail,
622  mqm);
624  cp->mqm_tail,
625  mqm);
626  }
627  cp->mqm_ready_counter--;
628  if (GNUNET_YES == should_I_drop ())
629  {
631  "DROPPING message to peer %s from MQM %p\n",
632  GCP_2s (cp),
633  mqm);
634  GNUNET_MQ_discard (mqm->env);
635  mqm->env = NULL;
636  mqm_send_done (cp);
637  }
638  else
639  {
640  {
641  const struct GNUNET_MessageHeader *mh;
642 
643  mh = GNUNET_MQ_env_get_msg (mqm->env);
644  switch (ntohs (mh->type))
645  {
647  {
649  = (const struct GNUNET_CADET_TunnelKeyExchangeMessage *) mh;
651  "P2P forwarding KX with ephemeral %s to %s on CID %s\n",
652  GNUNET_e2s (&msg->ephemeral_key),
653  GCP_2s (cp),
654  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
655  }
656  break;
657 
658  default:
659  break;
660  }
661  }
663  "Sending to peer %s from MQM %p\n",
664  GCP_2s (cp),
665  mqm);
666  GNUNET_MQ_send (cp->core_mq,
667  mqm->env);
668  mqm->env = NULL;
669  }
670  mqm->cb (mqm->cb_cls,
671  GNUNET_YES);
672 }
673 
674 
682 static void
684 {
685  struct GCP_MessageQueueManager *mqm;
686 
687  if (0 == cp->mqm_ready_counter)
688  return;
689  while ((NULL != (mqm = cp->mqm_ready_ptr)) &&
690  (NULL == mqm->env))
691  cp->mqm_ready_ptr = mqm->next;
692  if (NULL == mqm)
693  return; /* nothing to do */
694  mqm_execute (mqm);
695 }
696 
697 
704 static void
705 mqm_send_done (void *cls)
706 {
707  struct CadetPeer *cp = cls;
708 
710  "Sending to peer %s completed\n",
711  GCP_2s (cp));
712  send_next_ready (cp);
713 }
714 
715 
723 void
725  struct GNUNET_MQ_Envelope *env)
726 {
727  struct CadetPeer *cp = mqm->cp;
728 
729  GNUNET_assert (NULL != env);
731  "Queueing message to peer %s in MQM %p\n",
732  GCP_2s (cp),
733  mqm);
734  GNUNET_assert (NULL != cp->core_mq);
735  GNUNET_assert (NULL == mqm->env);
737  &mqm_send_done,
738  cp);
739  mqm->env = env;
740  cp->mqm_ready_counter++;
741  if (mqm != cp->mqm_ready_ptr)
742  cp->mqm_ready_ptr = cp->mqm_head;
743  if (1 == cp->mqm_ready_counter)
744  cp->mqm_ready_ptr = mqm;
745  if (0 != GNUNET_MQ_get_length (cp->core_mq))
746  return;
747  send_next_ready (cp);
748 }
749 
750 
759 static int
761  const struct GNUNET_PeerIdentity *pid,
762  void *value)
763 {
764  struct CadetPeer *cp = value;
765 
766  if (NULL != cp->destroy_task)
767  {
769  cp->destroy_task = NULL;
770  }
771  destroy_peer (cp);
772  return GNUNET_OK;
773 }
774 
775 
781 void
783 {
785  "Destroying all peers now\n");
788  NULL);
789 }
790 
791 
798 void
800 {
801  struct CadetPeerPath *path;
802 
804  "Destroying all paths to %s\n",
805  GCP_2s (cp));
806  while (NULL != (path =
808  GCPP_release (path);
810  cp->path_heap = NULL;
811 }
812 
813 
821 void
823  struct CadetPeerPathEntry *entry,
824  unsigned int off)
825 {
827  off));
829  "Discovered that peer %s is on path %s at offset %u\n",
830  GCP_2s (cp),
831  GCPP_2s (entry->path),
832  off);
833  if (off >= cp->path_dll_length)
834  {
835  unsigned int len = cp->path_dll_length;
836 
838  len,
839  off + 4);
841  cp->path_dll_length,
842  off + 4);
843  }
845  cp->path_tails[off],
846  entry);
847  cp->off_sum += off;
848  cp->num_paths++;
849 
850  /* If we have a tunnel to this peer, tell the tunnel that there is a
851  new path available. */
852  if (NULL != cp->t)
853  GCT_consider_path (cp->t,
854  entry->path,
855  off);
856 
857  if ((NULL != cp->search_h) &&
858  (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths))
859  {
860  /* Now I have enough paths, stop search */
862  cp->search_h = NULL;
863  }
864  if (NULL != cp->destroy_task)
865  {
866  /* paths changed, this resets the destroy timeout counter
867  and aborts a destroy task that may no longer be valid
868  to have (as we now have more paths via this peer). */
870  }
871 }
872 
873 
881 void
883  struct CadetPeerPathEntry *entry,
884  unsigned int off)
885 {
887  "Removing knowledge about peer %s beging on path %s at offset %u\n",
888  GCP_2s (cp),
889  GCPP_2s (entry->path),
890  off);
892  cp->path_tails[off],
893  entry);
894  GNUNET_assert (0 < cp->num_paths);
895  cp->off_sum -= off;
896  cp->num_paths--;
897  if ((NULL == cp->core_mq) &&
898  (NULL != cp->t) &&
899  (NULL == cp->search_h) &&
901  cp->search_h
902  = GCD_search (&cp->pid);
903  if (NULL == cp->destroy_task)
904  {
905  /* paths changed, we might now be ready for destruction, check again */
907  }
908 }
909 
910 
917 static void
918 path_heap_cleanup (void *cls)
919 {
920  struct CadetPeer *cp = cls;
921  struct CadetPeerPath *root;
922 
923  cp->heap_cleanup_task = NULL;
926  {
927  /* Now we have way too many, drop least desirable UNLESS it is in use!
928  (Note that this intentionally keeps highly desirable, but currently
929  unused paths around in the hope that we might be able to switch, even
930  if the number of paths exceeds the threshold.) */
932  GNUNET_assert (NULL != root);
933  if (NULL !=
934  GCPP_get_connection (root,
935  cp,
936  GCPP_get_length (root) - 1))
937  break; /* can't fix */
938  /* Got plenty of paths to this destination, and this is a low-quality
939  one that we don't care about. Allow it to die. */
940  GNUNET_assert (root ==
942  GCPP_release (root);
943  }
944 }
945 
946 
949  struct CadetPeerPath *path,
950  unsigned int off,
951  int force)
952 {
953  GNUNET_CONTAINER_HeapCostType desirability;
954  struct CadetPeerPath *root;
955  GNUNET_CONTAINER_HeapCostType root_desirability;
956  struct GNUNET_CONTAINER_HeapNode *hn;
957 
958  GNUNET_assert (off == GCPP_get_length (path) - 1);
960  off));
961  if (NULL == cp->path_heap)
962  {
963  /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */
964  GNUNET_assert (GNUNET_NO == force);
965  return NULL;
966  }
967  desirability = GCPP_get_desirability (path);
968  if (GNUNET_NO == force)
969  {
970  /* FIXME: desirability is not yet initialized; tricky! */
971  if (GNUNET_NO ==
973  (void **) &root,
974  &root_desirability))
975  {
976  root = NULL;
977  root_desirability = 0;
978  }
979 
981  (desirability < root_desirability))
982  {
984  "Decided to not attach path %s to peer %s due to undesirability\n",
985  GCPP_2s (path),
986  GCP_2s (cp));
987  return NULL;
988  }
989  }
990 
992  "Attaching path %s to peer %s (%s)\n",
993  GCPP_2s (path),
994  GCP_2s (cp),
995  (GNUNET_NO == force) ? "desirable" : "forced");
996 
997  /* Yes, we'd like to add this path, add to our heap */
999  path,
1000  desirability);
1001 
1002  /* Consider maybe dropping other paths because of the new one */
1005  (NULL != cp->heap_cleanup_task))
1007  cp);
1008  return hn;
1009 }
1010 
1011 
1021 void
1023  struct CadetPeerPath *path,
1024  struct GNUNET_CONTAINER_HeapNode *hn)
1025 {
1027  "Detaching path %s from peer %s\n",
1028  GCPP_2s (path),
1029  GCP_2s (cp));
1030  GNUNET_assert (path ==
1032 }
1033 
1034 
1041 void
1043  struct CadetConnection *cc)
1044 {
1046  "Adding %s to peer %s\n",
1047  GCC_2s (cc),
1048  GCP_2s (cp));
1051  &GCC_get_id (
1052  cc)->connection_of_tunnel,
1053  cc,
1055  if (NULL != cp->destroy_task)
1056  {
1058  cp->destroy_task = NULL;
1059  }
1060 }
1061 
1062 
1069 void
1071  struct CadetConnection *cc)
1072 {
1074  "Removing connection %s from peer %s\n",
1075  GCC_2s (cc),
1076  GCP_2s (cp));
1079  &GCC_get_id (
1080  cc)->
1081  connection_of_tunnel,
1082  cc));
1083  consider_peer_destroy (cp);
1084 }
1085 
1086 
1098 struct CadetPeer *
1100  int create)
1101 {
1102  struct CadetPeer *cp;
1103 
1105  peer_id);
1106  if (NULL != cp)
1107  return cp;
1108  if (GNUNET_NO == create)
1109  return NULL;
1110  cp = GNUNET_new (struct CadetPeer);
1111  cp->pid = *peer_id;
1113  GNUNET_YES);
1118  &cp->pid,
1119  cp,
1122  "Creating peer %s\n",
1123  GCP_2s (cp));
1124  return cp;
1125 }
1126 
1127 
1134 const struct GNUNET_PeerIdentity *
1135 GCP_get_id (struct CadetPeer *cp)
1136 {
1137  return &cp->pid;
1138 }
1139 
1140 
1147 void
1149  void *cls)
1150 {
1152  iter,
1153  cls);
1154 }
1155 
1156 
1163 unsigned int
1164 GCP_count_paths (const struct CadetPeer *cp)
1165 {
1166  return cp->num_paths;
1167 }
1168 
1169 
1178 unsigned int
1180  GCP_PathIterator callback,
1181  void *callback_cls)
1182 {
1183  unsigned int ret = 0;
1184 
1186  "Iterating over paths to peer %s%s\n",
1187  GCP_2s (cp),
1188  (NULL == cp->core_mq) ? "" : " including direct link");
1189  if (NULL != cp->core_mq)
1190  {
1191  /* FIXME: this branch seems to duplicate the
1192  i=0 case below (direct link). Leave out!??? -CG */
1193  struct CadetPeerPath *path;
1194 
1195  path = GCPP_get_path_from_route (1,
1196  &cp->pid);
1197  ret++;
1198  if (GNUNET_NO ==
1199  callback (callback_cls,
1200  path,
1201  0))
1202  return ret;
1203  }
1204  for (unsigned int i = 0; i < cp->path_dll_length; i++)
1205  {
1206  for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1207  NULL != pe;
1208  pe = pe->next)
1209  {
1210  ret++;
1211  if (GNUNET_NO ==
1212  callback (callback_cls,
1213  pe->path,
1214  i))
1215  return ret;
1216  }
1217  }
1218  return ret;
1219 }
1220 
1221 
1230 unsigned int
1232  GCP_PathIterator callback,
1233  void *callback_cls)
1234 {
1235  unsigned int ret = 0;
1236 
1238  "Iterating over paths to peer %s without direct link\n",
1239  GCP_2s (cp));
1240  for (unsigned int i = 1; i < cp->path_dll_length; i++)
1241  {
1242  for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1243  NULL != pe;
1244  pe = pe->next)
1245  {
1246  ret++;
1247  if (GNUNET_NO ==
1248  callback (callback_cls,
1249  pe->path,
1250  i))
1251  return ret;
1252  }
1253  }
1254  return ret;
1255 }
1256 
1257 
1258 unsigned int
1260  unsigned int dist,
1261  GCP_PathIterator callback,
1262  void *callback_cls)
1263 {
1264  unsigned int ret = 0;
1265 
1266  if (dist >= cp->path_dll_length)
1267  {
1269  "Asked to look for paths at distance %u, but maximum for me is < %u\n",
1270  dist,
1271  cp->path_dll_length);
1272  return 0;
1273  }
1274  for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
1275  NULL != pe;
1276  pe = pe->next)
1277  {
1278  if (GNUNET_NO ==
1279  callback (callback_cls,
1280  pe->path,
1281  dist))
1282  return ret;
1283  ret++;
1284  }
1285  return ret;
1286 }
1287 
1288 
1296 struct CadetTunnel *
1298  int create)
1299 {
1300  if (NULL == cp)
1301  return NULL;
1302  if ((NULL != cp->t) ||
1303  (GNUNET_NO == create))
1304  return cp->t;
1305  cp->t = GCT_create_tunnel (cp);
1307  return cp->t;
1308 }
1309 
1310 
1317 static void
1318 hello_offer_done (void *cls)
1319 {
1320  struct CadetPeer *cp = cls;
1321 
1322  cp->hello_offer = NULL;
1323 }
1324 
1325 
1326 void
1328  const struct GNUNET_HELLO_Message *hello)
1329 {
1330  struct GNUNET_HELLO_Message *mrg;
1331 
1333  "Got %u byte HELLO for peer %s\n",
1334  (unsigned int) GNUNET_HELLO_size (hello),
1335  GCP_2s (cp));
1336  if (NULL != cp->hello_offer)
1337  {
1339  cp->hello_offer = NULL;
1340  }
1341  if (NULL != cp->hello)
1342  {
1343  mrg = GNUNET_HELLO_merge (hello,
1344  cp->hello);
1345  GNUNET_free (cp->hello);
1346  cp->hello = mrg;
1347  }
1348  else
1349  {
1350  cp->hello = GNUNET_memdup (hello,
1351  GNUNET_HELLO_size (hello));
1352  }
1353  cp->hello_offer
1357  cp);
1358  /* New HELLO means cp's destruction time may change... */
1359  consider_peer_destroy (cp);
1360 }
1361 
1362 
1370 void
1372  struct CadetTunnel *t)
1373 {
1375  "Dropping tunnel %s to peer %s\n",
1376  GCT_2s (t),
1377  GCP_2s (cp));
1378  GNUNET_assert (cp->t == t);
1379  cp->t = NULL;
1380  consider_peer_destroy (cp);
1381 }
1382 
1383 
1390 int
1392 {
1393  return (NULL != cp->core_mq) ? GNUNET_YES : GNUNET_NO;
1394 }
1395 
1396 
1405 struct GCP_MessageQueueManager *
1408  void *cb_cls)
1409 {
1410  struct GCP_MessageQueueManager *mqm;
1411 
1412  mqm = GNUNET_new (struct GCP_MessageQueueManager);
1413  mqm->cb = cb;
1414  mqm->cb_cls = cb_cls;
1415  mqm->cp = cp;
1417  cp->mqm_tail,
1418  mqm);
1420  "Creating MQM %p for peer %s\n",
1421  mqm,
1422  GCP_2s (cp));
1423  if (NULL != cp->core_mq)
1424  cb (cb_cls,
1425  GNUNET_YES);
1426  return mqm;
1427 }
1428 
1429 
1436 void
1438  struct GNUNET_MQ_Envelope *last_env)
1439 {
1440  struct CadetPeer *cp = mqm->cp;
1441 
1443  "Destroying MQM %p for peer %s%s\n",
1444  mqm,
1445  GCP_2s (cp),
1446  (NULL == last_env) ? "" : " with last ditch transmission");
1447  if (NULL != mqm->env)
1448  GNUNET_MQ_discard (mqm->env);
1449  if (NULL != last_env)
1450  {
1451  if (NULL != cp->core_mq)
1452  {
1453  GNUNET_MQ_notify_sent (last_env,
1454  &mqm_send_done,
1455  cp);
1456  GNUNET_MQ_send (cp->core_mq,
1457  last_env);
1458  }
1459  else
1460  {
1461  GNUNET_MQ_discard (last_env);
1462  }
1463  }
1464  if (cp->mqm_ready_ptr == mqm)
1465  cp->mqm_ready_ptr = mqm->next;
1467  cp->mqm_tail,
1468  mqm);
1469  GNUNET_free (mqm);
1470 }
1471 
1472 
1482 void
1484  struct GNUNET_MQ_Envelope *env)
1485 {
1487  "Sending message to %s out of management\n",
1488  GCP_2s (cp));
1489  if (NULL == cp->core_mq)
1490  {
1492  return;
1493  }
1495  {
1497  return;
1498  }
1500  &mqm_send_done,
1501  cp);
1502  GNUNET_MQ_send (cp->core_mq,
1503  env);
1504 }
1505 
1506 
1514 int
1516  struct GNUNET_TIME_AbsoluteNBO monotime)
1517 {
1518 
1519  struct GNUNET_TIME_Absolute mt = GNUNET_TIME_absolute_ntoh (monotime);
1520 
1521  if (mt.abs_value_us > *(&peer->last_connection_create.abs_value_us))
1522  {
1523  peer->last_connection_create = mt;
1524  return GNUNET_YES;
1525  }
1526  return GNUNET_NO;
1527 }
1528 
1529 
1537 int
1540 {
1541  struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
1543  .purpose.size = htonl (sizeof(cp)),
1544  .monotonic_time = msg->monotime};
1545 
1546  if (GNUNET_OK !=
1549  &cp,
1550  &msg->monotime_sig,
1551  &peer->pid.public_key))
1552  {
1553  GNUNET_break_op (0);
1554  return GNUNET_SYSERR;
1555  }
1556  return GNUNET_OK;
1557 }
1558 
1559 
1560 /* end of gnunet-service-cadet-new_peer.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR
Signature by a peer that like to create a connection.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_ATS_ConnectivityHandle * ats_ch
Our connectivity handle.
Definition: gnunet-ats.c:121
static struct CadetPeer * peers
Operation to get peer ids.
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
static int create
Create DID Document Flag.
Definition: gnunet-did.c:71
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * value
Value of the record to add/remove.
unsigned long long drop_percent
Set to non-zero values to create random drops to test retransmissions.
Information we track per peer.
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.
A connection is a live end-to-end messaging mechanism where the peers are identified by a path and kn...
struct GCD_search_handle * GCD_search(const struct GNUNET_PeerIdentity *peer_id)
Search DHT for paths to peeR_id.
void GCD_search_stop(struct GCD_search_handle *h)
Stop DHT search started with GCD_search().
cadet service; dealing with DHT requests and results
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
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 CadetPeerPath * GCPP_get_path_from_route(unsigned int path_length, const struct GNUNET_PeerIdentity *pids)
We got an incoming connection, obtain the corresponding path.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping 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.
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...
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.
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.
void GCP_set_hello(struct CadetPeer *cp, const struct GNUNET_HELLO_Message *hello)
We got a HELLO for a cp, remember it, and possibly trigger adequate actions (like trying to connect).
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 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_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.
struct CadetTunnel * GCP_get_tunnel(struct CadetPeer *cp, int create)
Get the tunnel towards 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.
static int should_I_drop(void)
Debug function should NEVER return true in production code, useful to simulate losses for testcases.
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.
static void hello_offer_done(void *cls)
Hello offer was passed to the transport service.
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.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
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.
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer structure associated with the 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.
#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.
Information we track per peer.
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.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
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.
Information we track per tunnel.
#define DESIRED_CONNECTIONS_PER_TUNNEL
How many connections would we like to have per tunnel?
static char buf[2048]
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_SCHEDULER_Task * t
Main task.
Automatic transport selection and outbound bandwidth determination.
Core service; the main API for encrypted P2P communications.
Helper library for handling HELLOs.
API to create, modify and access statistics.
Functions related to time.
struct GNUNET_ATS_ConnectivitySuggestHandle * GNUNET_ATS_connectivity_suggest(struct GNUNET_ATS_ConnectivityHandle *ch, const struct GNUNET_PeerIdentity *peer, uint32_t strength)
We would like to receive address suggestions for a peer.
void GNUNET_ATS_connectivity_suggest_cancel(struct GNUNET_ATS_ConnectivitySuggestHandle *sh)
We no longer care about being connected to a peer.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#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.
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.
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.
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).
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
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.
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_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from 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.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of 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.
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:630
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_last_expiration(const struct GNUNET_HELLO_Message *msg)
When does the last address in the given HELLO expire?
Definition: hello.c:870
struct GNUNET_HELLO_Message * GNUNET_HELLO_merge(const struct GNUNET_HELLO_Message *h1, const struct GNUNET_HELLO_Message *h2)
Construct a HELLO message by merging the addresses in two existing HELLOs (which must be for the same...
Definition: hello.c:515
struct GNUNET_MessageHeader * GNUNET_HELLO_get_header(struct GNUNET_HELLO_Message *hello)
Get the header from a HELLO message, used so other code can correctly send HELLO messages.
Definition: hello.c:671
#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:251
@ 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_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:304
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:638
const struct GNUNET_MessageHeader * GNUNET_MQ_env_get_msg(const struct GNUNET_MQ_Envelope *env)
Obtain message contained in envelope.
Definition: mq.c:879
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
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:1299
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1272
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:138
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:405
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
void GNUNET_TRANSPORT_offer_hello_cancel(struct GNUNET_TRANSPORT_OfferHelloHandle *ohh)
Cancel the request to transport to offer the HELLO message.
struct GNUNET_TRANSPORT_OfferHelloHandle * GNUNET_TRANSPORT_offer_hello(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_MessageHeader *hello, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Offer the transport service the HELLO of another peer.
Purpose for the signature of a monotime.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose is GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR.
Low-level connection to a destination.
Entry in a peer path.
struct CadetPeerPathEntry * next
DLL of paths where the same peer is at the same offset.
struct CadetPeerPath * path
Path this entry belongs to.
Information regarding a possible path to reach a peer.
Peer description.
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_CONTAINER_Heap * path_heap
MIN-heap of paths owned by this peer (they also end at this peer).
struct GNUNET_ATS_ConnectivitySuggestHandle * connectivity_suggestion
Handle to our ATS request asking ATS to suggest an address to TRANSPORT for this peer (to establish a...
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 GNUNET_HELLO_Message * hello
Hello message of the peer.
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.
Handle for ATS address suggestion requests.
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.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
A HELLO message is used to exchange information about transports with other peers.
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:136
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.
Entry in linked list for all offer-HELLO requests.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.