GNUnet  0.17.6
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 
241 const char *
242 GCP_2s (const struct CadetPeer *cp)
243 {
244  static char buf[5];
245  char *ret;
246 
247  if ((NULL == cp) ||
249  return "NULL";
250 
252  if (NULL == ret)
253  return "NULL";
254 
256  ret,
257  sizeof(buf));
258  GNUNET_free (ret);
259  return buf;
260 }
261 
262 
263 double
265  unsigned int off)
266 {
267  unsigned int num_alts = cp->num_paths;
268  unsigned int off_sum;
269  double avg_sum;
270  double path_delta;
271  double weight_alts;
272 
273  GNUNET_assert (num_alts >= 1); /* 'path' should be in there! */
274  GNUNET_assert (0 != cp->path_dll_length);
275 
276  /* We maintain 'off_sum' in 'peer' and thereby
277  avoid the SLOW recalculation each time. Kept here
278  just to document what is going on. */
279 #if SLOW
280  off_sum = 0;
281  for (unsigned int j = 0; j < cp->path_dll_length; j++)
282  for (struct CadetPeerPathEntry *pe = cp->path_heads[j];
283  NULL != pe;
284  pe = pe->next)
285  off_sum += j;
286  GNUNET_assert (off_sum == cp->off_sum);
287 #else
288  off_sum = cp->off_sum;
289 #endif
290  avg_sum = off_sum * 1.0 / cp->path_dll_length;
291  path_delta = off - avg_sum;
292  /* path_delta positive: path off of peer above average (bad path for peer),
293  path_delta negative: path off of peer below average (good path for peer) */
294  if (path_delta <= -1.0)
295  weight_alts = -num_alts / path_delta; /* discount alternative paths */
296  else if (path_delta >= 1.0)
297  weight_alts = num_alts * path_delta; /* overcount alternative paths */
298  else
299  weight_alts = num_alts; /* count alternative paths normally */
300 
301 
302  /* off+1: long paths are generally harder to find and thus count
303  a bit more as they get longer. However, above-average paths
304  still need to count less, hence the squaring of that factor. */
305  return (off + 1.0) / (weight_alts * weight_alts);
306 }
307 
308 
314 static void
315 destroy_peer (void *cls)
316 {
317  struct CadetPeer *cp = cls;
318 
320  "Destroying state about peer %s\n",
321  GCP_2s (cp));
322  cp->destroy_task = NULL;
323  GNUNET_assert (NULL == cp->t);
324  GNUNET_assert (NULL == cp->core_mq);
325  GNUNET_assert (0 == cp->num_paths);
326  for (unsigned int i = 0; i < cp->path_dll_length; i++)
327  GNUNET_assert (NULL == cp->path_heads[i]);
331  &cp->pid,
332  cp));
333  GNUNET_free (cp->path_heads);
334  GNUNET_free (cp->path_tails);
335  cp->path_dll_length = 0;
336  if (NULL != cp->search_h)
337  {
339  cp->search_h = NULL;
340  }
341  /* FIXME: clean up search_delayedXXX! */
342 
343  if (NULL != cp->hello_offer)
344  {
346  cp->hello_offer = NULL;
347  }
348  if (NULL != cp->connectivity_suggestion)
349  {
351  cp->connectivity_suggestion = NULL;
352  }
354  if (NULL != cp->path_heap)
355  {
357  cp->path_heap = NULL;
358  }
359  if (NULL != cp->heap_cleanup_task)
360  {
362  cp->heap_cleanup_task = NULL;
363  }
364  GNUNET_free (cp->hello);
365  /* Peer should not be freed if paths exist; if there are no paths,
366  there ought to be no connections, and without connections, no
367  notifications. Thus we can assert that mqm_head is empty at this
368  point. */
369  GNUNET_assert (NULL == cp->mqm_head);
370  GNUNET_assert (NULL == cp->mqm_ready_ptr);
371  GNUNET_free (cp);
372 }
373 
374 
380 static void
382 {
383  uint32_t strength;
384 
386  "Updating peer %s activation state (%u connections)%s%s\n",
387  GCP_2s (cp),
389  (NULL == cp->t) ? "" : " with tunnel",
390  (NULL == cp->core_mq) ? "" : " with CORE link");
391  if (NULL != cp->destroy_task)
392  {
393  /* It's active, do not destroy! */
395  cp->destroy_task = NULL;
396  }
398  (NULL == cp->t))
399  {
400  /* We're just on a path or directly connected; don't bother too much */
401  if (NULL != cp->connectivity_suggestion)
402  {
404  cp->connectivity_suggestion = NULL;
405  }
406  if (NULL != cp->search_h)
407  {
409  cp->search_h = NULL;
410  }
411  return;
412  }
413  if (NULL == cp->core_mq)
414  {
415  /* Lacks direct connection, try to create one by querying the DHT */
416  if ((NULL == cp->search_h) &&
418  cp->search_h
419  = GCD_search (&cp->pid);
420  }
421  else
422  {
423  /* Have direct connection, stop DHT search if active */
424  if (NULL != cp->search_h)
425  {
427  cp->search_h = NULL;
428  }
429  }
430 
431  /* If we have a tunnel, our urge for connections is much bigger */
432  strength = (NULL != cp->t) ? 32 : 1;
433  if (NULL != cp->connectivity_suggestion)
437  &cp->pid,
438  strength);
439 }
440 
441 
447 static void
448 consider_peer_destroy (struct CadetPeer *cp);
449 
450 
457 static void
458 drop_paths (void *cls)
459 {
460  struct CadetPeer *cp = cls;
461  struct CadetPeerPath *path;
462 
463  cp->destroy_task = NULL;
464  while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
465  GCPP_release (path);
467 }
468 
469 
475 static void
477 {
478  struct GNUNET_TIME_Relative exp;
479 
480  if (NULL != cp->destroy_task)
481  {
483  cp->destroy_task = NULL;
484  }
485  if (NULL != cp->t)
486  return; /* still relevant! */
487  if (NULL != cp->core_mq)
488  return; /* still relevant! */
490  return; /* still relevant! */
491  if ((NULL != cp->path_heap) &&
493  {
495  &drop_paths,
496  cp);
497  return;
498  }
499  if (0 != cp->num_paths)
500  return; /* still relevant! */
501  if (NULL != cp->hello)
502  {
503  /* relevant only until HELLO expires */
505  cp->hello));
507  &destroy_peer,
508  cp);
509  return;
510  }
512  &destroy_peer,
513  cp);
514 }
515 
516 
523 void
524 GCP_set_mq (struct CadetPeer *cp,
525  struct GNUNET_MQ_Handle *mq)
526 {
528  "Message queue for peer %s is now %p\n",
529  GCP_2s (cp),
530  mq);
531  cp->core_mq = mq;
532  for (struct GCP_MessageQueueManager *mqm = cp->mqm_head, *next;
533  NULL != mqm;
534  mqm = next)
535  {
536  /* Save next pointer in case mqm gets freed by the callback */
537  next = mqm->next;
538  if (NULL == mq)
539  {
540  if (NULL != mqm->env)
541  {
542  GNUNET_MQ_discard (mqm->env);
543  mqm->env = NULL;
544  mqm->cb (mqm->cb_cls,
545  GNUNET_SYSERR);
546  }
547  else
548  {
549  mqm->cb (mqm->cb_cls,
550  GNUNET_NO);
551  }
552  }
553  else
554  {
555  GNUNET_assert (NULL == mqm->env);
556  mqm->cb (mqm->cb_cls,
557  GNUNET_YES);
558  }
559  }
560  if ((NULL != mq) ||
561  (NULL != cp->t))
563  else
565 
566  if ((NULL != mq) &&
567  (NULL != cp->t))
568  {
569  /* have a new, direct path to the target, notify tunnel */
570  struct CadetPeerPath *path;
571 
572  path = GCPP_get_path_from_route (1,
573  &cp->pid);
574  GCT_consider_path (cp->t,
575  path,
576  0);
577  }
578 }
579 
580 
587 static int
589 {
590  if (0 == drop_percent)
591  return GNUNET_NO;
593  101) < drop_percent)
594  return GNUNET_YES;
595  return GNUNET_NO;
596 }
597 
598 
605 static void
606 mqm_send_done (void *cls);
607 
608 
614 static void
616 {
617  struct CadetPeer *cp = mqm->cp;
618 
619  /* Move ready pointer to the next entry that might be ready. */
620  if ((mqm == cp->mqm_ready_ptr) &&
621  (NULL != mqm->next))
622  cp->mqm_ready_ptr = mqm->next;
623  /* Move entry to the end of the DLL, to be fair. */
624  if (mqm != cp->mqm_tail)
625  {
627  cp->mqm_tail,
628  mqm);
630  cp->mqm_tail,
631  mqm);
632  }
633  cp->mqm_ready_counter--;
634  if (GNUNET_YES == should_I_drop ())
635  {
637  "DROPPING message to peer %s from MQM %p\n",
638  GCP_2s (cp),
639  mqm);
640  GNUNET_MQ_discard (mqm->env);
641  mqm->env = NULL;
642  mqm_send_done (cp);
643  }
644  else
645  {
646  {
647  const struct GNUNET_MessageHeader *mh;
648 
649  mh = GNUNET_MQ_env_get_msg (mqm->env);
650  switch (ntohs (mh->type))
651  {
653  {
655  = (const struct GNUNET_CADET_TunnelKeyExchangeMessage *) mh;
657  "P2P forwarding KX with ephemeral %s to %s on CID %s\n",
658  GNUNET_e2s (&msg->ephemeral_key),
659  GCP_2s (cp),
660  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
661  }
662  break;
663 
664  default:
665  break;
666  }
667  }
669  "Sending to peer %s from MQM %p\n",
670  GCP_2s (cp),
671  mqm);
672  GNUNET_MQ_send (cp->core_mq,
673  mqm->env);
674  mqm->env = NULL;
675  }
676  mqm->cb (mqm->cb_cls,
677  GNUNET_YES);
678 }
679 
680 
688 static void
690 {
691  struct GCP_MessageQueueManager *mqm;
692 
693  if (0 == cp->mqm_ready_counter)
694  return;
695  while ((NULL != (mqm = cp->mqm_ready_ptr)) &&
696  (NULL == mqm->env))
697  cp->mqm_ready_ptr = mqm->next;
698  if (NULL == mqm)
699  return; /* nothing to do */
700  mqm_execute (mqm);
701 }
702 
703 
710 static void
711 mqm_send_done (void *cls)
712 {
713  struct CadetPeer *cp = cls;
714 
716  "Sending to peer %s completed\n",
717  GCP_2s (cp));
718  send_next_ready (cp);
719 }
720 
721 
729 void
731  struct GNUNET_MQ_Envelope *env)
732 {
733  struct CadetPeer *cp = mqm->cp;
734 
735  GNUNET_assert (NULL != env);
737  "Queueing message to peer %s in MQM %p\n",
738  GCP_2s (cp),
739  mqm);
740  GNUNET_assert (NULL != cp->core_mq);
741  GNUNET_assert (NULL == mqm->env);
743  &mqm_send_done,
744  cp);
745  mqm->env = env;
746  cp->mqm_ready_counter++;
747  if (mqm != cp->mqm_ready_ptr)
748  cp->mqm_ready_ptr = cp->mqm_head;
749  if (1 == cp->mqm_ready_counter)
750  cp->mqm_ready_ptr = mqm;
751  if (0 != GNUNET_MQ_get_length (cp->core_mq))
752  return;
753  send_next_ready (cp);
754 }
755 
756 
765 static int
767  const struct GNUNET_PeerIdentity *pid,
768  void *value)
769 {
770  struct CadetPeer *cp = value;
771 
772  if (NULL != cp->destroy_task)
773  {
775  cp->destroy_task = NULL;
776  }
777  destroy_peer (cp);
778  return GNUNET_OK;
779 }
780 
781 
787 void
789 {
791  "Destroying all peers now\n");
794  NULL);
795 }
796 
797 
804 void
806 {
807  struct CadetPeerPath *path;
808 
810  "Destroying all paths to %s\n",
811  GCP_2s (cp));
812  while (NULL != (path =
814  GCPP_release (path);
816  cp->path_heap = NULL;
817 }
818 
819 
827 void
829  struct CadetPeerPathEntry *entry,
830  unsigned int off)
831 {
833  off));
835  "Discovered that peer %s is on path %s at offset %u\n",
836  GCP_2s (cp),
837  GCPP_2s (entry->path),
838  off);
839  if (off >= cp->path_dll_length)
840  {
841  unsigned int len = cp->path_dll_length;
842 
844  len,
845  off + 4);
847  cp->path_dll_length,
848  off + 4);
849  }
851  cp->path_tails[off],
852  entry);
853  cp->off_sum += off;
854  cp->num_paths++;
855 
856  /* If we have a tunnel to this peer, tell the tunnel that there is a
857  new path available. */
858  if (NULL != cp->t)
859  GCT_consider_path (cp->t,
860  entry->path,
861  off);
862 
863  if ((NULL != cp->search_h) &&
864  (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths))
865  {
866  /* Now I have enough paths, stop search */
868  cp->search_h = NULL;
869  }
870  if (NULL != cp->destroy_task)
871  {
872  /* paths changed, this resets the destroy timeout counter
873  and aborts a destroy task that may no longer be valid
874  to have (as we now have more paths via this peer). */
876  }
877 }
878 
879 
887 void
889  struct CadetPeerPathEntry *entry,
890  unsigned int off)
891 {
893  "Removing knowledge about peer %s beging on path %s at offset %u\n",
894  GCP_2s (cp),
895  GCPP_2s (entry->path),
896  off);
898  cp->path_tails[off],
899  entry);
900  GNUNET_assert (0 < cp->num_paths);
901  cp->off_sum -= off;
902  cp->num_paths--;
903  if ((NULL == cp->core_mq) &&
904  (NULL != cp->t) &&
905  (NULL == cp->search_h) &&
907  cp->search_h
908  = GCD_search (&cp->pid);
909  if (NULL == cp->destroy_task)
910  {
911  /* paths changed, we might now be ready for destruction, check again */
913  }
914 }
915 
916 
923 static void
924 path_heap_cleanup (void *cls)
925 {
926  struct CadetPeer *cp = cls;
927  struct CadetPeerPath *root;
928 
929  cp->heap_cleanup_task = NULL;
932  {
933  /* Now we have way too many, drop least desirable UNLESS it is in use!
934  (Note that this intentionally keeps highly desirable, but currently
935  unused paths around in the hope that we might be able to switch, even
936  if the number of paths exceeds the threshold.) */
938  GNUNET_assert (NULL != root);
939  if (NULL !=
940  GCPP_get_connection (root,
941  cp,
942  GCPP_get_length (root) - 1))
943  break; /* can't fix */
944  /* Got plenty of paths to this destination, and this is a low-quality
945  one that we don't care about. Allow it to die. */
946  GNUNET_assert (root ==
948  GCPP_release (root);
949  }
950 }
951 
952 
955  struct CadetPeerPath *path,
956  unsigned int off,
957  int force)
958 {
959  GNUNET_CONTAINER_HeapCostType desirability;
960  struct CadetPeerPath *root;
961  GNUNET_CONTAINER_HeapCostType root_desirability;
962  struct GNUNET_CONTAINER_HeapNode *hn;
963 
964  GNUNET_assert (off == GCPP_get_length (path) - 1);
966  off));
967  if (NULL == cp->path_heap)
968  {
969  /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */
970  GNUNET_assert (GNUNET_NO == force);
971  return NULL;
972  }
973  desirability = GCPP_get_desirability (path);
974  if (GNUNET_NO == force)
975  {
976  /* FIXME: desirability is not yet initialized; tricky! */
977  if (GNUNET_NO ==
979  (void **) &root,
980  &root_desirability))
981  {
982  root = NULL;
983  root_desirability = 0;
984  }
985 
987  (desirability < root_desirability))
988  {
990  "Decided to not attach path %s to peer %s due to undesirability\n",
991  GCPP_2s (path),
992  GCP_2s (cp));
993  return NULL;
994  }
995  }
996 
998  "Attaching path %s to peer %s (%s)\n",
999  GCPP_2s (path),
1000  GCP_2s (cp),
1001  (GNUNET_NO == force) ? "desirable" : "forced");
1002 
1003  /* Yes, we'd like to add this path, add to our heap */
1005  path,
1006  desirability);
1007 
1008  /* Consider maybe dropping other paths because of the new one */
1011  (NULL != cp->heap_cleanup_task))
1013  cp);
1014  return hn;
1015 }
1016 
1017 
1027 void
1029  struct CadetPeerPath *path,
1030  struct GNUNET_CONTAINER_HeapNode *hn)
1031 {
1033  "Detaching path %s from peer %s\n",
1034  GCPP_2s (path),
1035  GCP_2s (cp));
1036  GNUNET_assert (path ==
1038 }
1039 
1040 
1047 void
1049  struct CadetConnection *cc)
1050 {
1052  "Adding %s to peer %s\n",
1053  GCC_2s (cc),
1054  GCP_2s (cp));
1057  &GCC_get_id (
1058  cc)->connection_of_tunnel,
1059  cc,
1061  if (NULL != cp->destroy_task)
1062  {
1064  cp->destroy_task = NULL;
1065  }
1066 }
1067 
1068 
1075 void
1077  struct CadetConnection *cc)
1078 {
1080  "Removing connection %s from peer %s\n",
1081  GCC_2s (cc),
1082  GCP_2s (cp));
1085  &GCC_get_id (
1086  cc)->
1087  connection_of_tunnel,
1088  cc));
1089  consider_peer_destroy (cp);
1090 }
1091 
1092 
1104 struct CadetPeer *
1106  int create)
1107 {
1108  struct CadetPeer *cp;
1109 
1111  peer_id);
1112  if (NULL != cp)
1113  return cp;
1114  if (GNUNET_NO == create)
1115  return NULL;
1116  cp = GNUNET_new (struct CadetPeer);
1117  cp->pid = *peer_id;
1119  GNUNET_YES);
1124  &cp->pid,
1125  cp,
1128  "Creating peer %s\n",
1129  GCP_2s (cp));
1130  return cp;
1131 }
1132 
1133 
1140 const struct GNUNET_PeerIdentity *
1141 GCP_get_id (struct CadetPeer *cp)
1142 {
1143  return &cp->pid;
1144 }
1145 
1146 
1153 void
1155  void *cls)
1156 {
1158  iter,
1159  cls);
1160 }
1161 
1162 
1169 unsigned int
1170 GCP_count_paths (const struct CadetPeer *cp)
1171 {
1172  return cp->num_paths;
1173 }
1174 
1175 
1184 unsigned int
1186  GCP_PathIterator callback,
1187  void *callback_cls)
1188 {
1189  unsigned int ret = 0;
1190 
1192  "Iterating over paths to peer %s%s\n",
1193  GCP_2s (cp),
1194  (NULL == cp->core_mq) ? "" : " including direct link");
1195  if (NULL != cp->core_mq)
1196  {
1197  /* FIXME: this branch seems to duplicate the
1198  i=0 case below (direct link). Leave out!??? -CG */
1199  struct CadetPeerPath *path;
1200 
1201  path = GCPP_get_path_from_route (1,
1202  &cp->pid);
1203  ret++;
1204  if (GNUNET_NO ==
1205  callback (callback_cls,
1206  path,
1207  0))
1208  return ret;
1209  }
1210  for (unsigned int i = 0; i < cp->path_dll_length; i++)
1211  {
1212  for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1213  NULL != pe;
1214  pe = pe->next)
1215  {
1216  ret++;
1217  if (GNUNET_NO ==
1218  callback (callback_cls,
1219  pe->path,
1220  i))
1221  return ret;
1222  }
1223  }
1224  return ret;
1225 }
1226 
1227 
1236 unsigned int
1238  GCP_PathIterator callback,
1239  void *callback_cls)
1240 {
1241  unsigned int ret = 0;
1242 
1244  "Iterating over paths to peer %s without direct link\n",
1245  GCP_2s (cp));
1246  for (unsigned int i = 1; i < cp->path_dll_length; i++)
1247  {
1248  for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1249  NULL != pe;
1250  pe = pe->next)
1251  {
1252  ret++;
1253  if (GNUNET_NO ==
1254  callback (callback_cls,
1255  pe->path,
1256  i))
1257  return ret;
1258  }
1259  }
1260  return ret;
1261 }
1262 
1263 
1264 unsigned int
1266  unsigned int dist,
1267  GCP_PathIterator callback,
1268  void *callback_cls)
1269 {
1270  unsigned int ret = 0;
1271 
1272  if (dist >= cp->path_dll_length)
1273  {
1275  "Asked to look for paths at distance %u, but maximum for me is < %u\n",
1276  dist,
1277  cp->path_dll_length);
1278  return 0;
1279  }
1280  for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
1281  NULL != pe;
1282  pe = pe->next)
1283  {
1284  if (GNUNET_NO ==
1285  callback (callback_cls,
1286  pe->path,
1287  dist))
1288  return ret;
1289  ret++;
1290  }
1291  return ret;
1292 }
1293 
1294 
1302 struct CadetTunnel *
1304  int create)
1305 {
1306  if (NULL == cp)
1307  return NULL;
1308  if ((NULL != cp->t) ||
1309  (GNUNET_NO == create))
1310  return cp->t;
1311  cp->t = GCT_create_tunnel (cp);
1313  return cp->t;
1314 }
1315 
1316 
1323 static void
1324 hello_offer_done (void *cls)
1325 {
1326  struct CadetPeer *cp = cls;
1327 
1328  cp->hello_offer = NULL;
1329 }
1330 
1331 
1332 void
1334  const struct GNUNET_HELLO_Message *hello)
1335 {
1336  struct GNUNET_HELLO_Message *mrg;
1337 
1339  "Got %u byte HELLO for peer %s\n",
1340  (unsigned int) GNUNET_HELLO_size (hello),
1341  GCP_2s (cp));
1342  if (NULL != cp->hello_offer)
1343  {
1345  cp->hello_offer = NULL;
1346  }
1347  if (NULL != cp->hello)
1348  {
1349  mrg = GNUNET_HELLO_merge (hello,
1350  cp->hello);
1351  GNUNET_free (cp->hello);
1352  cp->hello = mrg;
1353  }
1354  else
1355  {
1356  cp->hello = GNUNET_memdup (hello,
1357  GNUNET_HELLO_size (hello));
1358  }
1359  cp->hello_offer
1363  cp);
1364  /* New HELLO means cp's destruction time may change... */
1365  consider_peer_destroy (cp);
1366 }
1367 
1368 
1376 void
1378  struct CadetTunnel *t)
1379 {
1381  "Dropping tunnel %s to peer %s\n",
1382  GCT_2s (t),
1383  GCP_2s (cp));
1384  GNUNET_assert (cp->t == t);
1385  cp->t = NULL;
1386  consider_peer_destroy (cp);
1387 }
1388 
1389 
1396 int
1398 {
1399  return (NULL != cp->core_mq) ? GNUNET_YES : GNUNET_NO;
1400 }
1401 
1402 
1411 struct GCP_MessageQueueManager *
1414  void *cb_cls)
1415 {
1416  struct GCP_MessageQueueManager *mqm;
1417 
1418  mqm = GNUNET_new (struct GCP_MessageQueueManager);
1419  mqm->cb = cb;
1420  mqm->cb_cls = cb_cls;
1421  mqm->cp = cp;
1423  cp->mqm_tail,
1424  mqm);
1426  "Creating MQM %p for peer %s\n",
1427  mqm,
1428  GCP_2s (cp));
1429  if (NULL != cp->core_mq)
1430  cb (cb_cls,
1431  GNUNET_YES);
1432  return mqm;
1433 }
1434 
1435 
1442 void
1444  struct GNUNET_MQ_Envelope *last_env)
1445 {
1446  struct CadetPeer *cp = mqm->cp;
1447 
1449  "Destroying MQM %p for peer %s%s\n",
1450  mqm,
1451  GCP_2s (cp),
1452  (NULL == last_env) ? "" : " with last ditch transmission");
1453  if (NULL != mqm->env)
1454  GNUNET_MQ_discard (mqm->env);
1455  if (NULL != last_env)
1456  {
1457  if (NULL != cp->core_mq)
1458  {
1459  GNUNET_MQ_notify_sent (last_env,
1460  &mqm_send_done,
1461  cp);
1462  GNUNET_MQ_send (cp->core_mq,
1463  last_env);
1464  }
1465  else
1466  {
1467  GNUNET_MQ_discard (last_env);
1468  }
1469  }
1470  if (cp->mqm_ready_ptr == mqm)
1471  cp->mqm_ready_ptr = mqm->next;
1473  cp->mqm_tail,
1474  mqm);
1475  GNUNET_free (mqm);
1476 }
1477 
1478 
1488 void
1490  struct GNUNET_MQ_Envelope *env)
1491 {
1493  "Sending message to %s out of management\n",
1494  GCP_2s (cp));
1495  if (NULL == cp->core_mq)
1496  {
1498  return;
1499  }
1501  {
1503  return;
1504  }
1506  &mqm_send_done,
1507  cp);
1508  GNUNET_MQ_send (cp->core_mq,
1509  env);
1510 }
1511 
1512 
1520 int
1522  struct GNUNET_TIME_AbsoluteNBO monotime)
1523 {
1524 
1525  struct GNUNET_TIME_Absolute mt = GNUNET_TIME_absolute_ntoh (monotime);
1526 
1527  if (mt.abs_value_us > *(&peer->last_connection_create.abs_value_us))
1528  {
1529  peer->last_connection_create = mt;
1530  return GNUNET_YES;
1531  }
1532  return GNUNET_NO;
1533 }
1534 
1535 
1543 int
1546 {
1547  struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
1549  .purpose.size = htonl (sizeof(cp)),
1550  .monotonic_time = msg->monotime};
1551 
1552  if (GNUNET_OK !=
1555  &cp,
1556  &msg->monotime_sig,
1557  &peer->pid.public_key))
1558  {
1559  GNUNET_break_op (0);
1560  return GNUNET_SYSERR;
1561  }
1562  return GNUNET_OK;
1563 }
1564 
1565 
1566 /* 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:652
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:892
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:524
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:693
#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
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#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:291
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:302
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:283
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:640
const struct GNUNET_MessageHeader * GNUNET_MQ_env_get_msg(const struct GNUNET_MQ_Envelope *env)
Obtain message contained in envelope.
Definition: mq.c:881
#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:1281
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:139
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:404
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:736
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:86
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:135
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.