GNUnet  0.17.6
gnunet-service-cadet_core.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 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 
32 #include "platform.h"
38 #include "gnunet_core_service.h"
40 #include "cadet_protocol.h"
41 
42 #define LOG(level, ...) GNUNET_log_from (level, "cadet-cor", __VA_ARGS__)
43 
47 struct RouteDirection;
48 
55 struct Rung
56 {
60  struct Rung *next;
61 
65  struct Rung *prev;
66 
71 
76 
80  unsigned int num_routes;
81 
86  unsigned int rung_off;
87 };
88 
89 
94 {
99 
104 
108  struct Rung *rung;
109 
114 
119 
123  struct CadetPeer *hop;
124 
129 
134 
138  int is_ready;
139 };
140 
141 
143 {
147  struct RouteDirection next;
148 
152  struct RouteDirection prev;
153 
158 
163 
168 };
169 
170 
174 static struct GNUNET_CORE_Handle *core;
175 
180 
185 
189 static struct Rung rung_zero;
190 
195 static struct Rung *rung_head = &rung_zero;
196 
200 static struct Rung *rung_tail = &rung_zero;
201 
205 static unsigned long long max_routes;
206 
210 static unsigned long long max_buffers;
211 
215 static unsigned long long cur_buffers;
216 
221 
227 static struct CadetRoute *
229 {
232 }
233 
234 
240 static void
242 {
243  struct Rung *rung = dir->rung;
244  struct Rung *prev;
245 
247  prev = rung->prev;
248  GNUNET_assert (NULL != prev);
249  if (prev->rung_off != rung->rung_off - 1)
250  {
251  prev = GNUNET_new (struct Rung);
252  prev->rung_off = rung->rung_off - 1;
254  }
255  GNUNET_assert (NULL != prev);
257  dir->rung = prev;
258 }
259 
260 
268 static void
270 {
271  GNUNET_MQ_dll_remove (&dir->env_head, &dir->env_tail, env);
272  cur_buffers--;
274  lower_rung (dir);
275  GNUNET_STATISTICS_set (stats, "# buffer use", cur_buffers, GNUNET_NO);
276 }
277 
278 
282 static void
284 {
285  struct Rung *tail = rung_tail;
286  struct RouteDirection *dir;
287 
288  while (NULL != (dir = tail->rd_head))
289  {
291  "Queue full due new message on connection %s, dropping old message\n",
292  GNUNET_sh2s (&dir->my_route->cid.connection_of_tunnel));
294  "# messages dropped due to full buffer",
295  1,
296  GNUNET_NO);
297  discard_buffer (dir, dir->env_head);
298  }
300  GNUNET_free (tail);
301 }
302 
303 
313 static void
315  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
316  const struct GNUNET_MessageHeader *msg,
317  const enum GNUNET_MQ_PriorityPreferences priority)
318 {
319  struct CadetRoute *route;
320  struct RouteDirection *dir;
321  struct Rung *rung;
322  struct Rung *nxt;
323  struct GNUNET_MQ_Envelope *env;
324 
325  route = get_route (cid);
326  if (NULL == route)
327  {
328  struct GNUNET_MQ_Envelope *env;
330 
332  "Failed to route message of type %u from %s on connection %s: no route\n",
333  ntohs (msg->type),
334  GCP_2s (prev),
336  switch (ntohs (msg->type))
337  {
340  /* No need to respond to these! */
341  return;
342  }
344  bm->cid = *cid;
345  bm->peer1 = my_full_id;
346  GCP_send_ooo (prev, env);
347  return;
348  }
351  dir = (prev == route->prev.hop) ? &route->next : &route->prev;
352  if (GNUNET_YES == dir->is_ready)
353  {
355  "Routing message of type %u from %s to %s on connection %s\n",
356  ntohs (msg->type),
357  GCP_2s (prev),
358  GNUNET_i2s (GCP_get_id (dir->hop)),
360  dir->is_ready = GNUNET_NO;
362  return;
363  }
364  /* Check if low latency is required and if the previous message was
365  unreliable; if so, make sure we only queue one message per
366  direction (no buffering). */
367  if ((0 != (priority & GNUNET_MQ_PREF_LOW_LATENCY)) &&
368  (NULL != dir->env_head) &&
369  (0 ==
371  discard_buffer (dir, dir->env_head);
372  /* Check for duplicates */
373  for (const struct GNUNET_MQ_Envelope *env = dir->env_head; NULL != env;
375  {
376  const struct GNUNET_MessageHeader *hdr = GNUNET_MQ_env_get_msg (env);
377 
378  if ((hdr->size == msg->size) && (0 == memcmp (hdr, msg, ntohs (msg->size))))
379  {
381  "Received duplicate of message already in buffer, dropping\n");
383  "# messages dropped due to duplicate in buffer",
384  1,
385  GNUNET_NO);
386  return;
387  }
388  }
389 
390  rung = dir->rung;
391  if (cur_buffers == max_buffers)
392  {
393  /* Need to make room. */
394  if (NULL != rung->next)
395  {
396  /* Easy case, drop messages from route directions in highest rung */
398  }
399  else
400  {
401  /* We are in the highest rung, drop our own! */
403  "Queue full due new message on connection %s, dropping old message\n",
404  GNUNET_sh2s (&dir->my_route->cid.connection_of_tunnel));
406  "# messages dropped due to full buffer",
407  1,
408  GNUNET_NO);
409  discard_buffer (dir, dir->env_head);
410  rung = dir->rung;
411  }
412  }
413  /* remove 'dir' from current rung */
415  /* make 'nxt' point to the next higher rung, create if necessary */
416  nxt = rung->next;
417  if ((NULL == nxt) || (rung->rung_off + 1 != nxt->rung_off))
418  {
419  nxt = GNUNET_new (struct Rung);
420  nxt->rung_off = rung->rung_off + 1;
422  }
423  /* insert 'dir' into next higher rung */
425  dir->rung = nxt;
426 
427  /* add message into 'dir' buffer */
429  "Queueing new message of type %u from %s to %s on connection %s\n",
430  ntohs (msg->type),
431  GCP_2s (prev),
432  GNUNET_i2s (GCP_get_id (dir->hop)),
435  GNUNET_MQ_env_set_options (env, priority);
436  if ((0 != (priority & GNUNET_MQ_PREF_LOW_LATENCY)) &&
437  (0 != (priority & GNUNET_MQ_PREF_OUT_OF_ORDER)) &&
438  (NULL != dir->env_head) &&
439  (0 == (GNUNET_MQ_env_get_options (dir->env_head)
441  GNUNET_MQ_dll_insert_head (&dir->env_head, &dir->env_tail, env);
442  else
443  GNUNET_MQ_dll_insert_tail (&dir->env_head, &dir->env_tail, env);
444  cur_buffers++;
445  GNUNET_STATISTICS_set (stats, "# buffer use", cur_buffers, GNUNET_NO);
446  /* Clean up 'rung' if now empty (and not head) */
447  if ((NULL == rung->rd_head) && (rung != rung_head))
448  {
450  GNUNET_free (rung);
451  }
452 }
453 
454 
463 static int
466 {
467  uint16_t size = ntohs (msg->header.size) - sizeof(*msg);
468 
469  if (0 != (size % sizeof(struct GNUNET_PeerIdentity)))
470  {
471  GNUNET_break_op (0);
472  return GNUNET_NO;
473  }
474  return GNUNET_YES;
475 }
476 
477 
483 static void
485 {
486  struct GNUNET_MQ_Envelope *env;
487 
488  while (NULL != (env = dir->env_head))
489  {
491  "# messages dropped due to route destruction",
492  1,
493  GNUNET_NO);
495  }
496  if (NULL != dir->mqm)
497  {
498  GCP_request_mq_cancel (dir->mqm, NULL);
499  dir->mqm = NULL;
500  }
502 }
503 
504 
510 static void
511 destroy_route (struct CadetRoute *route)
512 {
514  "Destroying route from %s to %s of connection %s\n",
515  GNUNET_i2s (GCP_get_id (route->prev.hop)),
516  GNUNET_i2s2 (GCP_get_id (route->next.hop)),
519  GNUNET_assert (
520  GNUNET_YES ==
522  &route->cid.connection_of_tunnel,
523  route));
525  "# routes",
527  GNUNET_NO);
528  destroy_direction (&route->prev);
529  destroy_direction (&route->next);
530  GNUNET_free (route);
531 }
532 
533 
542 static void
543 send_broken (struct RouteDirection *target,
544  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
545  const struct GNUNET_PeerIdentity *peer1,
546  const struct GNUNET_PeerIdentity *peer2)
547 {
548  struct GNUNET_MQ_Envelope *env;
550 
551  if (NULL == target->mqm)
552  return; /* Can't send notification, connection is down! */
554  "Notifying %s about BROKEN route at %s-%s of connection %s\n",
555  GCP_2s (target->hop),
556  GNUNET_i2s (peer1),
557  GNUNET_i2s2 (peer2),
559 
561  bm->cid = *cid;
562  if (NULL != peer1)
563  bm->peer1 = *peer1;
564  if (NULL != peer2)
565  bm->peer2 = *peer2;
566  GCP_request_mq_cancel (target->mqm, env);
567  target->mqm = NULL;
568 }
569 
570 
578 static void
579 timeout_cb (void *cls)
580 {
581  struct CadetRoute *r;
582  struct GNUNET_TIME_Relative linger;
583  struct GNUNET_TIME_Absolute exp;
584 
585  timeout_task = NULL;
587  while (NULL != (r = GNUNET_CONTAINER_heap_peek (route_heap)))
588  {
589  exp = GNUNET_TIME_absolute_add (r->last_use, linger);
590  if (0 != GNUNET_TIME_absolute_get_remaining (exp).rel_value_us)
591  {
592  /* Route not yet timed out, wait until it does. */
594  return;
595  }
597  "Sending BROKEN due to timeout (%s was last use, %s linger)\n",
600  send_broken (&r->prev, &r->cid, NULL, NULL);
601  send_broken (&r->next, &r->cid, NULL, NULL);
602  destroy_route (r);
603  }
604  /* No more routes left, so no need for a #timeout_task */
605 }
606 
607 
620 static void
621 dir_ready_cb (void *cls, int ready)
622 {
623  struct RouteDirection *dir = cls;
624  struct CadetRoute *route = dir->my_route;
625  struct RouteDirection *odir;
626 
627  if (GNUNET_YES == ready)
628  {
629  struct GNUNET_MQ_Envelope *env;
630 
631  dir->is_ready = GNUNET_YES;
632  if (NULL != (env = dir->env_head))
633  {
634  GNUNET_MQ_dll_remove (&dir->env_head, &dir->env_tail, env);
635  cur_buffers--;
636  GNUNET_STATISTICS_set (stats, "# buffer use", cur_buffers, GNUNET_NO);
637  lower_rung (dir);
638  dir->is_ready = GNUNET_NO;
639  GCP_send (dir->mqm, env);
640  }
641  return;
642  }
643  odir = (dir == &route->next) ? &route->prev : &route->next;
644  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending BROKEN due to MQ going down\n");
645  send_broken (&route->next, &route->cid, GCP_get_id (odir->hop), &my_full_id);
646  destroy_route (route);
647 }
648 
649 
657 static void
659  struct CadetRoute *route,
660  struct CadetPeer *hop)
661 {
662  dir->hop = hop;
663  dir->my_route = route;
664  dir->mqm = GCP_request_mq (hop, &dir_ready_cb, dir);
666  dir->rung = rung_head;
667  GNUNET_assert (GNUNET_YES == dir->is_ready);
668 }
669 
670 
681 static void
683  struct CadetPeer *target,
684  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
685  const struct GNUNET_PeerIdentity *failure_at)
686 {
687  struct GNUNET_MQ_Envelope *env;
689 
691  bm->cid = *cid;
692  bm->peer1 = my_full_id;
693  if (NULL != failure_at)
694  bm->peer2 = *failure_at;
695  GCP_send_ooo (target, env);
696 }
697 
698 
705 static void
707  void *cls,
709 {
710  struct CadetPeer *sender = cls;
711  struct CadetPeer *next;
712  const struct GNUNET_PeerIdentity *pids =
713  (const struct GNUNET_PeerIdentity *) &msg[1];
714  struct CadetRoute *route;
715  uint16_t size = ntohs (msg->header.size) - sizeof(*msg);
716  unsigned int path_length;
717  unsigned int off;
718  struct CadetTunnel *t;
719 
720  path_length = size / sizeof(struct GNUNET_PeerIdentity);
721  if (0 == path_length)
722  {
724  "Dropping CADET_CONNECTION_CREATE with empty path\n");
725  GNUNET_break_op (0);
726  return;
727  }
729  "Handling CADET_CONNECTION_CREATE from %s for CID %s with %u hops\n",
730  GCP_2s (sender),
731  GNUNET_sh2s (&msg->cid.connection_of_tunnel),
732  path_length);
733  /* Check for loops */
734  {
736 
738  GNUNET_assert (NULL != map);
739  for (unsigned int i = 0; i < path_length; i++)
740  {
742  "CADET_CONNECTION_CREATE has peer %s at offset %u\n",
743  GNUNET_i2s (&pids[i]),
744  i);
746  map,
747  &pids[i],
748  NULL,
750  {
751  /* bogus request */
754  "Dropping CADET_CONNECTION_CREATE with cyclic path\n");
755  GNUNET_break_op (0);
756  return;
757  }
758  }
760  }
761  /* Initiator is at offset 0, find us */
762  for (off = 1; off < path_length; off++)
763  if (0 == GNUNET_memcmp (&my_full_id, &pids[off]))
764  break;
765  if (off == path_length)
766  {
768  "Dropping CADET_CONNECTION_CREATE without us in the path\n");
769  GNUNET_break_op (0);
770  return;
771  }
772  /* Check previous hop */
773  if (sender != GCP_get (&pids[off - 1], GNUNET_NO))
774  {
776  "Dropping CADET_CONNECTION_CREATE without sender at previous hop in the path\n");
777  GNUNET_break_op (0);
778  return;
779  }
780  if (NULL != (route = get_route (&msg->cid)))
781  {
782  /* Duplicate CREATE, pass it on, previous one might have been lost! */
783 
785  "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n",
786  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
787  route_message (sender,
788  &msg->cid,
789  &msg->header,
792  return;
793  }
794  if (off == path_length - 1)
795  {
796  /* We are the destination, create connection */
797  struct CadetConnection *cc;
798  struct CadetPeerPath *path;
799  struct CadetPeer *origin;
800 
801  cc = GCC_lookup (&msg->cid);
802  if (NULL != cc)
803  {
805  "Received duplicate CADET_CONNECTION_CREATE message on connection %s\n",
806  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
808  return;
809  }
810 
811  origin = GCP_get (&pids[0], GNUNET_YES);
813  "I am destination for CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n",
814  GCP_2s (origin),
815  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
816  path = GCPP_get_path_from_route (path_length - 1, pids);
817  t = GCP_get_tunnel (origin, GNUNET_YES);
818 
819  // Check for CADET state in case the other side has lost the tunnel (xrs,t3ss)
820  if ((GNUNET_YES == msg->has_monotime) &&
821  (GNUNET_YES == GCP_check_and_update_monotime (origin, msg->monotime)) &&
822  (GNUNET_OK == GCP_check_monotime_sig (origin, msg)) &&
824  {
826  }
827 
828  if (GNUNET_OK !=
830  &msg->cid,
831  path))
832  {
833  /* Send back BROKEN: duplicate connection on the same path,
834  we will use the other one. */
836  "Received CADET_CONNECTION_CREATE from %s for %s, but %s already has a connection. Sending BROKEN\n",
837  GCP_2s (sender),
838  GNUNET_sh2s (&msg->cid.connection_of_tunnel),
839  GCPP_2s (path));
840  send_broken_without_mqm (sender, &msg->cid, NULL);
841  return;
842  }
843  return;
844  }
845  /* We are merely a hop on the way, check if we can support the route */
846  next = GCP_get (&pids[off + 1], GNUNET_NO);
847  if ((NULL == next) || (GNUNET_NO == GCP_has_core_connection (next)))
848  {
849  /* unworkable, send back BROKEN notification */
851  "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. Sending BROKEN\n",
852  GCP_2s (sender),
853  GNUNET_sh2s (&msg->cid.connection_of_tunnel),
854  GNUNET_i2s (&pids[off + 1]),
855  off + 1);
856  send_broken_without_mqm (sender, &msg->cid, &pids[off + 1]);
857  return;
858  }
860  {
862  "Received CADET_CONNECTION_CREATE from %s for %s. We have reached our route limit. Sending BROKEN\n",
863  GCP_2s (sender),
864  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
865  send_broken_without_mqm (sender, &msg->cid, &pids[off - 1]);
866  return;
867  }
868 
869  /* Workable route, create routing entry */
871  "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is up. Creating route\n",
872  GCP_2s (sender),
873  GNUNET_sh2s (&msg->cid.connection_of_tunnel),
874  GNUNET_i2s (&pids[off + 1]),
875  off + 1);
876  route = GNUNET_new (struct CadetRoute);
877  route->cid = msg->cid;
879  dir_init (&route->prev, route, sender);
880  dir_init (&route->next, route, next);
883  routes,
884  &route->cid.connection_of_tunnel,
885  route,
888  "# routes",
890  GNUNET_NO);
892  route,
893  route->last_use.abs_value_us);
894  if (NULL == timeout_task)
895  timeout_task =
898  3),
899  &timeout_cb,
900  NULL);
901  /* also pass CREATE message along to next hop */
902  route_message (sender,
903  &msg->cid,
904  &msg->header,
906 }
907 
908 
915 static void
917  void *cls,
919 {
920  struct CadetPeer *peer = cls;
921  struct CadetConnection *cc;
922 
923  /* First, check if ACK belongs to a connection that ends here. */
924  cc = GCC_lookup (&msg->cid);
925  if (NULL != cc)
926  {
927  /* verify ACK came from the right direction */
928  unsigned int len;
929  struct CadetPeerPath *path = GCC_get_path (cc, &len);
930 
931  if (peer != GCPP_get_peer_at_offset (path, 0))
932  {
933  /* received ACK from unexpected direction, ignore! */
934  GNUNET_break_op (0);
935  return;
936  }
938  "Received CONNECTION_CREATE_ACK for connection %s.\n",
939  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
941  return;
942  }
943 
944  /* We're just an intermediary peer, route the message along its path */
946  &msg->cid,
947  &msg->header,
949 }
950 
951 
959 static void
961  void *cls,
963 {
964  struct CadetPeer *peer = cls;
965  struct CadetConnection *cc;
966  struct CadetRoute *route;
967 
968  /* First, check if message belongs to a connection that ends here. */
969  cc = GCC_lookup (&msg->cid);
970  if (NULL != cc)
971  {
972  /* verify message came from the right direction */
973  unsigned int len;
974  struct CadetPeerPath *path = GCC_get_path (cc, &len);
975 
976  if (peer != GCPP_get_peer_at_offset (path, 0))
977  {
978  /* received message from unexpected direction, ignore! */
979  GNUNET_break_op (0);
980  return;
981  }
983  "Received CONNECTION_BROKEN for connection %s. Destroying it.\n",
984  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
986 
987  /* FIXME: also destroy the path up to the specified link! */
988  return;
989  }
990 
991  /* We're just an intermediary peer, route the message along its path */
993  &msg->cid,
994  &msg->header,
996  route = get_route (&msg->cid);
997  if (NULL != route)
998  destroy_route (route);
999  /* FIXME: also destroy paths we MAY have up to the specified link! */
1000 }
1001 
1002 
1009 static void
1011  void *cls,
1013 {
1014  struct CadetPeer *peer = cls;
1015  struct CadetConnection *cc;
1016  struct CadetRoute *route;
1017 
1018  /* First, check if message belongs to a connection that ends here. */
1019  cc = GCC_lookup (&msg->cid);
1020  if (NULL != cc)
1021  {
1022  /* verify message came from the right direction */
1023  unsigned int len;
1024  struct CadetPeerPath *path = GCC_get_path (cc, &len);
1025 
1026  if (peer != GCPP_get_peer_at_offset (path, 0))
1027  {
1028  /* received message from unexpected direction, ignore! */
1029  GNUNET_break_op (0);
1030  return;
1031  }
1033  "Received CONNECTION_DESTROY for connection %s. Destroying connection.\n",
1034  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1035 
1037  return;
1038  }
1039 
1040  /* We're just an intermediary peer, route the message along its path */
1042  "Received CONNECTION_DESTROY for connection %s. Destroying route.\n",
1043  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1045  &msg->cid,
1046  &msg->header,
1048  route = get_route (&msg->cid);
1049  if (NULL != route)
1050  destroy_route (route);
1051 }
1052 
1053 
1060 static void
1061 handle_tunnel_kx (void *cls,
1063 {
1064  struct CadetPeer *peer = cls;
1065  struct CadetConnection *cc;
1066 
1067  /* First, check if message belongs to a connection that ends here. */
1069  "Routing KX with ephemeral %s on CID %s\n",
1070  GNUNET_e2s (&msg->ephemeral_key),
1071  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1072 
1073 
1074  cc = GCC_lookup (&msg->cid);
1075  if (NULL != cc)
1076  {
1077  /* verify message came from the right direction */
1078  unsigned int len;
1079  struct CadetPeerPath *path = GCC_get_path (cc, &len);
1080 
1081  if (peer != GCPP_get_peer_at_offset (path, 0))
1082  {
1083  /* received message from unexpected direction, ignore! */
1084  GNUNET_break_op (0);
1085  return;
1086  }
1087  GCC_handle_kx (cc, msg);
1088  return;
1089  }
1090 
1091  /* We're just an intermediary peer, route the message along its path */
1093  &msg->cid,
1094  &msg->header,
1096 }
1097 
1098 
1105 static void
1107  void *cls,
1109 {
1110  struct CadetPeer *peer = cls;
1111  struct CadetConnection *cc;
1112 
1113  /* First, check if message belongs to a connection that ends here. */
1114  cc = GCC_lookup (&msg->kx.cid);
1115  if (NULL != cc)
1116  {
1117  /* verify message came from the right direction */
1118  unsigned int len;
1119  struct CadetPeerPath *path = GCC_get_path (cc, &len);
1120 
1121  if (peer != GCPP_get_peer_at_offset (path, 0))
1122  {
1123  /* received message from unexpected direction, ignore! */
1124  GNUNET_break_op (0);
1125  return;
1126  }
1127  GCC_handle_kx_auth (cc, msg);
1128  return;
1129  }
1130 
1131  /* We're just an intermediary peer, route the message along its path */
1133  &msg->kx.cid,
1134  &msg->kx.header,
1136 }
1137 
1138 
1147 static int
1150 {
1151  return GNUNET_YES;
1152 }
1153 
1154 
1161 static void
1164 {
1165  struct CadetPeer *peer = cls;
1166  struct CadetConnection *cc;
1167 
1168  /* First, check if message belongs to a connection that ends here. */
1169  cc = GCC_lookup (&msg->cid);
1170  if (NULL != cc)
1171  {
1172  /* verify message came from the right direction */
1173  unsigned int len;
1174  struct CadetPeerPath *path = GCC_get_path (cc, &len);
1175 
1176  if (peer != GCPP_get_peer_at_offset (path, 0))
1177  {
1178  /* received message from unexpected direction, ignore! */
1179  GNUNET_break_op (0);
1180  return;
1181  }
1182  GCC_handle_encrypted (cc, msg);
1183  return;
1184  }
1185  /* We're just an intermediary peer, route the message along its path */
1186  route_message (peer, &msg->cid, &msg->header, GNUNET_MQ_PRIO_BEST_EFFORT);
1187 }
1188 
1189 
1202 static void
1204 {
1205  if (NULL == my_identity)
1206  {
1207  GNUNET_break (0);
1208  return;
1209  }
1211 }
1212 
1213 
1220 static void *
1221 core_connect_cb (void *cls,
1222  const struct GNUNET_PeerIdentity *peer,
1223  struct GNUNET_MQ_Handle *mq)
1224 {
1225  struct CadetPeer *cp;
1226 
1228  "CORE connection to peer %s was established.\n",
1229  GNUNET_i2s (peer));
1230  cp = GCP_get (peer, GNUNET_YES);
1231  GCP_set_mq (cp, mq);
1232  return cp;
1233 }
1234 
1235 
1242 static void
1244  const struct GNUNET_PeerIdentity *peer,
1245  void *peer_cls)
1246 {
1247  struct CadetPeer *cp = peer_cls;
1248 
1250  "CORE connection to peer %s went down.\n",
1251  GNUNET_i2s (peer));
1252  GCP_set_mq (cp, NULL);
1253 }
1254 
1255 
1261 void
1263 {
1268  NULL),
1269  GNUNET_MQ_hd_fixed_size (connection_create_ack,
1272  NULL),
1273  GNUNET_MQ_hd_fixed_size (connection_broken,
1276  NULL),
1277  GNUNET_MQ_hd_fixed_size (connection_destroy,
1280  NULL),
1281  GNUNET_MQ_hd_fixed_size (tunnel_kx,
1284  NULL),
1285  GNUNET_MQ_hd_fixed_size (tunnel_kx_auth,
1288  NULL),
1289  GNUNET_MQ_hd_var_size (tunnel_encrypted,
1292  NULL),
1293  GNUNET_MQ_handler_end () };
1294 
1296  "CADET",
1297  "MAX_ROUTES",
1298  &max_routes))
1299  max_routes = 5000;
1301  "CADET",
1302  "MAX_MSGS_QUEUE",
1303  &max_buffers))
1304  max_buffers = 10000;
1308  NULL,
1309  &core_init_cb,
1310  &core_connect_cb,
1312  handlers);
1313 }
1314 
1315 
1316 void
1318 {
1319  if (NULL != core)
1320  {
1322  core = NULL;
1323  }
1326  routes = NULL;
1328  route_heap = NULL;
1329  if (NULL != timeout_task)
1330  {
1332  timeout_task = NULL;
1333  }
1334 }
1335 
1336 
1337 /* end of gnunet-cadet-service_core.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
P2P messages used by CADET.
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:89
static struct PendingResolutions * tail
Tail of list of pending resolution requests.
Definition: gnunet-ats.c:235
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_CONTAINER_MultiPeerMap * map
Handle to the map used to store old latency values for peers.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
struct GNUNET_TIME_Relative keepalive_period
How frequently do we send KEEPALIVE messages on idle connections?
void GCC_handle_encrypted(struct CadetConnection *cc, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle encrypted message.
void GCC_handle_connection_create_ack(struct CadetConnection *cc)
A GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection,...
void GCC_handle_kx(struct CadetConnection *cc, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Handle KX message.
void GCC_destroy_without_core(struct CadetConnection *cc)
Destroy a connection, called when the CORE layer is already done (i.e.
void GCC_handle_kx_auth(struct CadetConnection *cc, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle KX_AUTH message.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
struct CadetConnection * GCC_lookup(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Lookup a connection by its identifier.
void GCC_handle_duplicate_create(struct CadetConnection *cc)
We got a GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a connection that we already have.
static struct CadetConnection * connection_create(struct CadetPeer *destination, struct CadetPeerPath *path, unsigned int off, struct CadetTConnection *ct, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, enum CadetConnectionState init_state, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
A connection is a live end-to-end messaging mechanism where the peers are identified by a path and kn...
static void dir_ready_cb(void *cls, int ready)
Function called when the message queue to the previous hop becomes available/unavailable.
void GCO_shutdown()
Shut down the CORE subsystem.
static struct GNUNET_CORE_Handle * core
Handle to the CORE service.
static unsigned long long cur_buffers
Current number of envelopes we have buffered at this peer.
static void destroy_direction(struct RouteDirection *dir)
Free internal data of a route direction.
static struct Rung * rung_tail
Tail of the rung_head DLL.
static int check_connection_create(void *cls, const struct GNUNET_CADET_ConnectionCreateMessage *msg)
Check if the create_connection message has the appropriate size.
static void dir_init(struct RouteDirection *dir, struct CadetRoute *route, struct CadetPeer *hop)
Initialize one of the directions of a route.
static void handle_tunnel_kx(void *cls, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX.
static struct Rung rung_zero
Rung zero (always pointed to by rung_head).
static void handle_tunnel_encrypted(void *cls, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED.
static void discard_buffer(struct RouteDirection *dir, struct GNUNET_MQ_Envelope *env)
Discard the buffer env from the route direction dir and move dir down a rung.
static void discard_all_from_rung_tail()
Discard all messages from the highest rung, to make space.
static void * core_connect_cb(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
static struct Rung * rung_head
DLL of rungs, with the head always point to a rung of route directions with no messages in the queue.
static void route_message(struct CadetPeer *prev, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, const struct GNUNET_MessageHeader *msg, const enum GNUNET_MQ_PriorityPreferences priority)
We message msg from prev.
void GCO_init(const struct GNUNET_CONFIGURATION_Handle *c)
Initialize the CORE subsystem.
static int check_tunnel_encrypted(void *cls, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Check if the encrypted message has the appropriate size.
static void send_broken_without_mqm(struct CadetPeer *target, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, const struct GNUNET_PeerIdentity *failure_at)
We could not create the desired route.
static void handle_connection_create(void *cls, const struct GNUNET_CADET_ConnectionCreateMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE.
static void timeout_cb(void *cls)
Function called to check if any routes have timed out, and if so, to clean them up.
static void destroy_route(struct CadetRoute *route)
Destroy our state for route.
static struct GNUNET_CONTAINER_Heap * route_heap
Heap of routes, MIN-sorted by last activity.
static unsigned long long max_routes
Maximum number of concurrent routes this peer will support.
static void core_disconnect_cb(void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
Method called whenever a peer disconnects.
static void handle_tunnel_kx_auth(void *cls, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH.
static struct GNUNET_CONTAINER_MultiShortmap * routes
Routes on which this peer is an intermediate.
static void send_broken(struct RouteDirection *target, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, const struct GNUNET_PeerIdentity *peer1, const struct GNUNET_PeerIdentity *peer2)
Send message that a route is broken between peer1 and peer2.
static void lower_rung(struct RouteDirection *dir)
Lower the rung in which dir is by 1.
static void handle_connection_broken(void *cls, const struct GNUNET_CADET_ConnectionBrokenMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN.
static void handle_connection_destroy(void *cls, const struct GNUNET_CADET_ConnectionDestroyMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY.
static struct GNUNET_SCHEDULER_Task * timeout_task
Task to timeout routes.
#define LOG(level,...)
static struct CadetRoute * get_route(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Get the route corresponding to a hash.
static void handle_connection_create_ack(void *cls, const struct GNUNET_CADET_ConnectionCreateAckMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK.
static unsigned long long max_buffers
Maximum number of envelopes we will buffer at this peer.
static void core_init_cb(void *cls, const struct GNUNET_PeerIdentity *my_identity)
Function called after GNUNET_CORE_connect has succeeded (or failed for good).
cadet service; interaction with CORE service
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.
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.
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.
int GCP_has_core_connection(struct CadetPeer *cp)
Test if cp has a core-level connection.
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.
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.
void GCP_set_mq(struct CadetPeer *cp, struct GNUNET_MQ_Handle *mq)
Set the message queue to mq for peer cp and notify watchers.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer structure associated with the peer.
void GCP_send(struct GCP_MessageQueueManager *mqm, struct GNUNET_MQ_Envelope *env)
Send the message in env to cp.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
struct GCP_MessageQueueManager * GCP_request_mq(struct CadetPeer *cp, GCP_MessageQueueNotificationCallback cb, void *cb_cls)
Start message queue change notifications.
Information we track per peer.
void GCT_change_estate(struct CadetTunnel *t, enum CadetTunnelEState state)
Change the tunnel encryption state.
int GCT_add_inbound_connection(struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
Add a connection to the tunnel.
enum CadetTunnelEState GCT_get_estate(struct CadetTunnel *t)
Get the encryption state of a tunnel.
Information we track per tunnel.
@ CADET_TUNNEL_KEY_UNINITIALIZED
Uninitialized status, we need to send KX.
@ CADET_TUNNEL_KEY_OK
Handshake completed: session key available.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static struct GNUNET_SCHEDULER_Task * t
Main task.
Core service; the main API for encrypted P2P communications.
API to create, modify and access statistics.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
struct GNUNET_CORE_Handle * GNUNET_CORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Connect to the core service.
Definition: core_api.c:692
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:730
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash 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_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
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_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *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.
@ 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_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
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.
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.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
@ 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_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
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_i2s2(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_dll_remove(struct GNUNET_MQ_Envelope **env_head, struct GNUNET_MQ_Envelope **env_tail, struct GNUNET_MQ_Envelope *env)
Remove env from the envelope DLL starting at env_head.
Definition: mq.c:948
void GNUNET_MQ_env_set_options(struct GNUNET_MQ_Envelope *env, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this envelope.
Definition: mq.c:832
const struct GNUNET_MQ_Envelope * GNUNET_MQ_env_next(const struct GNUNET_MQ_Envelope *env)
Return next envelope in queue.
Definition: mq.c:888
void GNUNET_MQ_dll_insert_head(struct GNUNET_MQ_Envelope **env_head, struct GNUNET_MQ_Envelope **env_tail, struct GNUNET_MQ_Envelope *env)
Insert env into the envelope DLL starting at env_head Note that env must not be in any MQ while this ...
Definition: mq.c:926
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:283
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:71
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition: mq.c:535
enum GNUNET_MQ_PriorityPreferences GNUNET_MQ_env_get_options(struct GNUNET_MQ_Envelope *env)
Get performance preferences set for this envelope.
Definition: mq.c:841
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_dll_insert_tail(struct GNUNET_MQ_Envelope **env_head, struct GNUNET_MQ_Envelope **env_tail, struct GNUNET_MQ_Envelope *env)
Insert env into the envelope DLL starting at env_head Note that env must not be in any MQ while this ...
Definition: mq.c:937
const struct GNUNET_MessageHeader * GNUNET_MQ_env_get_msg(const struct GNUNET_MQ_Envelope *env)
Obtain message contained in envelope.
Definition: mq.c:881
@ GNUNET_MQ_PREF_OUT_OF_ORDER
Flag to indicate that out-of-order delivery is OK.
@ GNUNET_MQ_PRIO_CRITICAL_CONTROL
Highest priority, control traffic (e.g.
@ GNUNET_MQ_PREF_UNRELIABLE
Flag to indicate that unreliable delivery is acceptable.
@ GNUNET_MQ_PREF_LOW_LATENCY
Flag to indicate that low latency is important.
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK
Send origin an ACK that the connection is complete.
#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
Notify that a connection is no longer valid.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
Request the destruction of a connection.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
Axolotl key exchange response with authentication.
#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
Request the creation of a connection.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
Axolotl encrypted data.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition: scheduler.c:1231
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
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
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_get(void)
Get the current time.
Definition: time.c:110
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
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:483
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:449
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:570
static unsigned int size
Size of the "table".
Definition: peer.c:67
Low-level connection to a destination.
Information regarding a possible path to reach a peer.
Peer description.
struct RouteDirection prev
Information about the previous hop on this route.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
Unique identifier for the connection that uses this route.
struct GNUNET_CONTAINER_HeapNode * hn
Position of this route in the route_heap.
struct RouteDirection next
Information about the next hop on this route.
struct GNUNET_TIME_Absolute last_use
When was this route last in use?
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.
Message for notifying a disconnection in a path.
struct GNUNET_PeerIdentity peer1
ID of the endpoint.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
struct GNUNET_PeerIdentity peer2
ID of the endpoint.
Message for ack'ing a connection.
Message for cadet connection creation.
Message to destroy a connection.
Hash uniquely identifying a connection below a tunnel.
struct GNUNET_ShortHashCode connection_of_tunnel
Axolotl-encrypted tunnel message with application payload.
Message for a Key eXchange for a tunnel, with authentication.
Message for a Key eXchange for a tunnel.
Handle to a node in a heap.
Internal representation of the hash map.
Internal representation of the hash map.
Context for the core service connection.
Definition: core_api.c:78
Handle to a message queue.
Definition: mq.c:86
Message handler for a specific message type.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:135
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.
Information we keep per direction for a route.
struct Rung * rung
Rung of this route direction (matches length of the buffer DLL).
int is_ready
Is mqm currently ready for transmission?
struct RouteDirection * next
DLL of other route directions within the same struct Rung.
struct GNUNET_MQ_Envelope * env_tail
Tail of DLL of envelopes we have in the buffer for this direction.
struct GCP_MessageQueueManager * mqm
Message queue manager for hop.
struct GNUNET_MQ_Envelope * env_head
Head of DLL of envelopes we have in the buffer for this direction.
struct CadetRoute * my_route
Route this direction is part of.
struct CadetPeer * hop
Target peer.
struct RouteDirection * prev
DLL of other route directions within the same struct Rung.
Set of CadetRoutes that have exactly the same number of messages in their buffer.
struct RouteDirection * rd_head
DLL of route directions with a number of buffer entries matching this rung.
unsigned int num_routes
Total number of route directions in this rung.
struct RouteDirection * rd_tail
DLL of route directions with a number of buffer entries matching this rung.
struct Rung * prev
Rung of RouteDirections with one less buffer entry each.
struct Rung * next
Rung of RouteDirections with one more buffer entry each.
unsigned int rung_off
Number of messages route directions at this rung have in their buffer.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.