GNUnet  0.10.x
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 {
59  struct Rung *next;
60 
64  struct Rung *prev;
65 
70 
75 
79  unsigned int num_routes;
80 
85  unsigned int rung_off;
86 };
87 
88 
97 
102 
106  struct Rung *rung;
107 
112 
117 
121  struct CadetPeer *hop;
122 
127 
132 
136  int is_ready;
137 };
138 
139 
148 struct CadetRoute {
153 
158 
163 
167  struct GNUNET_TIME_Absolute last_use;
168 
173 };
174 
175 
179 static struct GNUNET_CORE_Handle *core;
180 
185 
190 
194 static struct Rung rung_zero;
195 
200 static struct Rung *rung_head = &rung_zero;
201 
205 static struct Rung *rung_tail = &rung_zero;
206 
210 static unsigned long long max_routes;
211 
215 static unsigned long long max_buffers;
216 
220 static unsigned long long cur_buffers;
221 
226 
227 
233 static struct CadetRoute *
235 {
237  &cid->connection_of_tunnel);
238 }
239 
240 
246 static void
248 {
249  struct Rung *rung = dir->rung;
250  struct Rung *prev;
251 
252  GNUNET_CONTAINER_DLL_remove(rung->rd_head, rung->rd_tail, dir);
253  prev = rung->prev;
254  GNUNET_assert(NULL != prev);
255  if (prev->rung_off != rung->rung_off - 1)
256  {
257  prev = GNUNET_new(struct Rung);
258  prev->rung_off = rung->rung_off - 1;
259  GNUNET_CONTAINER_DLL_insert_after(rung_head, rung_tail, rung->prev, prev);
260  }
261  GNUNET_assert(NULL != prev);
262  GNUNET_CONTAINER_DLL_insert(prev->rd_head, prev->rd_tail, dir);
263  dir->rung = prev;
264 }
265 
266 
274 static void
276 {
277  GNUNET_MQ_dll_remove(&dir->env_head, &dir->env_tail, env);
278  cur_buffers--;
279  GNUNET_MQ_discard(env);
280  lower_rung(dir);
282 }
283 
284 
288 static void
290 {
291  struct Rung *tail = rung_tail;
292  struct RouteDirection *dir;
293 
294  while (NULL != (dir = tail->rd_head))
295  {
297  "Queue full due new message %s on connection %s, dropping old message\n",
300  "# messages dropped due to full buffer",
301  1,
302  GNUNET_NO);
303  discard_buffer(dir, dir->env_head);
304  }
305  GNUNET_CONTAINER_DLL_remove(rung_head, rung_tail, tail);
306  GNUNET_free(tail);
307 }
308 
309 
319 static void
321  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
322  const struct GNUNET_MessageHeader *msg,
323  const enum GNUNET_MQ_PriorityPreferences priority)
324 {
325  struct CadetRoute *route;
326  struct RouteDirection *dir;
327  struct Rung *rung;
328  struct Rung *nxt;
329  struct GNUNET_MQ_Envelope *env;
330 
331  route = get_route(cid);
332  if (NULL == route)
333  {
334  struct GNUNET_MQ_Envelope *env;
336 
338  "Failed to route message of type %u from %s on connection %s: no route\n",
339  ntohs(msg->type),
340  GCP_2s(prev),
342  switch (ntohs(msg->type))
343  {
346  /* No need to respond to these! */
347  return;
348  }
350  bm->cid = *cid;
351  bm->peer1 = my_full_id;
352  GCP_send_ooo(prev, env);
353  return;
354  }
357  dir = (prev == route->prev.hop) ? &route->next : &route->prev;
358  if (GNUNET_YES == dir->is_ready)
359  {
361  "Routing message of type %u from %s to %s on connection %s\n",
362  ntohs(msg->type),
363  GCP_2s(prev),
364  GNUNET_i2s(GCP_get_id(dir->hop)),
366  dir->is_ready = GNUNET_NO;
367  GCP_send(dir->mqm, GNUNET_MQ_msg_copy(msg));
368  return;
369  }
370  /* Check if low latency is required and if the previous message was
371  unreliable; if so, make sure we only queue one message per
372  direction (no buffering). */
373  if ((0 != (priority & GNUNET_MQ_PREF_LOW_LATENCY)) &&
374  (NULL != dir->env_head) &&
375  (0 ==
377  discard_buffer(dir, dir->env_head);
378  /* Check for duplicates */
379  for (const struct GNUNET_MQ_Envelope *env = dir->env_head; NULL != env;
380  env = GNUNET_MQ_env_next(env))
381  {
382  const struct GNUNET_MessageHeader *hdr = GNUNET_MQ_env_get_msg(env);
383 
384  if ((hdr->size == msg->size) && (0 == memcmp(hdr, msg, ntohs(msg->size))))
385  {
387  "Received duplicate of message already in buffer, dropping\n");
389  "# messages dropped due to duplicate in buffer",
390  1,
391  GNUNET_NO);
392  return;
393  }
394  }
395 
396  rung = dir->rung;
397  if (cur_buffers == max_buffers)
398  {
399  /* Need to make room. */
400  if (NULL != rung->next)
401  {
402  /* Easy case, drop messages from route directions in highest rung */
404  }
405  else
406  {
407  /* We are in the highest rung, drop our own! */
409  "Queue full due new message %s on connection %s, dropping old message\n",
412  "# messages dropped due to full buffer",
413  1,
414  GNUNET_NO);
415  discard_buffer(dir, dir->env_head);
416  rung = dir->rung;
417  }
418  }
419  /* remove 'dir' from current rung */
420  GNUNET_CONTAINER_DLL_remove(rung->rd_head, rung->rd_tail, dir);
421  /* make 'nxt' point to the next higher rung, create if necessary */
422  nxt = rung->next;
423  if ((NULL == nxt) || (rung->rung_off + 1 != nxt->rung_off))
424  {
425  nxt = GNUNET_new(struct Rung);
426  nxt->rung_off = rung->rung_off + 1;
427  GNUNET_CONTAINER_DLL_insert_after(rung_head, rung_tail, rung, nxt);
428  }
429  /* insert 'dir' into next higher rung */
431  dir->rung = nxt;
432 
433  /* add message into 'dir' buffer */
435  "Queueing new message of type %u from %s to %s on connection %s\n",
436  ntohs(msg->type),
437  GCP_2s(prev),
438  GNUNET_i2s(GCP_get_id(dir->hop)),
440  env = GNUNET_MQ_msg_copy(msg);
441  GNUNET_MQ_env_set_options(env, priority);
442  if ((0 != (priority & GNUNET_MQ_PREF_LOW_LATENCY)) &&
443  (0 != (priority & GNUNET_MQ_PREF_OUT_OF_ORDER)) &&
444  (NULL != dir->env_head) &&
445  (0 == (GNUNET_MQ_env_get_options(dir->env_head) &
446  GNUNET_MQ_PREF_LOW_LATENCY)))
447  GNUNET_MQ_dll_insert_head(&dir->env_head, &dir->env_tail, env);
448  else
449  GNUNET_MQ_dll_insert_tail(&dir->env_head, &dir->env_tail, env);
450  cur_buffers++;
452  /* Clean up 'rung' if now empty (and not head) */
453  if ((NULL == rung->rd_head) && (rung != rung_head))
454  {
455  GNUNET_CONTAINER_DLL_remove(rung_head, rung_tail, rung);
456  GNUNET_free(rung);
457  }
458 }
459 
460 
469 static int
472 {
473  uint16_t size = ntohs(msg->header.size) - sizeof(*msg);
474 
475  if (0 != (size % sizeof(struct GNUNET_PeerIdentity)))
476  {
477  GNUNET_break_op(0);
478  return GNUNET_NO;
479  }
480  return GNUNET_YES;
481 }
482 
483 
489 static void
491 {
492  struct GNUNET_MQ_Envelope *env;
493 
494  while (NULL != (env = dir->env_head))
495  {
497  "# messages dropped due to route destruction",
498  1,
499  GNUNET_NO);
500  discard_buffer(dir, env);
501  }
502  if (NULL != dir->mqm)
503  {
504  GCP_request_mq_cancel(dir->mqm, NULL);
505  dir->mqm = NULL;
506  }
507  GNUNET_CONTAINER_DLL_remove(rung_head->rd_head, rung_head->rd_tail, dir);
508 }
509 
510 
516 static void
517 destroy_route(struct CadetRoute *route)
518 {
520  "Destroying route from %s to %s of connection %s\n",
521  GNUNET_i2s(GCP_get_id(route->prev.hop)),
522  GNUNET_i2s2(GCP_get_id(route->next.hop)),
526  GNUNET_YES ==
528  &route->cid.connection_of_tunnel,
529  route));
531  "# routes",
533  GNUNET_NO);
534  destroy_direction(&route->prev);
535  destroy_direction(&route->next);
536  GNUNET_free(route);
537 }
538 
539 
548 static void
550  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
551  const struct GNUNET_PeerIdentity *peer1,
552  const struct GNUNET_PeerIdentity *peer2)
553 {
554  struct GNUNET_MQ_Envelope *env;
556 
557  if (NULL == target->mqm)
558  return; /* Can't send notification, connection is down! */
560  "Notifying %s about BROKEN route at %s-%s of connection %s\n",
561  GCP_2s(target->hop),
562  GNUNET_i2s(peer1),
563  GNUNET_i2s2(peer2),
565 
567  bm->cid = *cid;
568  if (NULL != peer1)
569  bm->peer1 = *peer1;
570  if (NULL != peer2)
571  bm->peer2 = *peer2;
572  GCP_request_mq_cancel(target->mqm, env);
573  target->mqm = NULL;
574 }
575 
576 
584 static void
585 timeout_cb(void *cls)
586 {
587  struct CadetRoute *r;
588  struct GNUNET_TIME_Relative linger;
589  struct GNUNET_TIME_Absolute exp;
590 
591  timeout_task = NULL;
593  while (NULL != (r = GNUNET_CONTAINER_heap_peek(route_heap)))
594  {
595  exp = GNUNET_TIME_absolute_add(r->last_use, linger);
596  if (0 != GNUNET_TIME_absolute_get_remaining(exp).rel_value_us)
597  {
598  /* Route not yet timed out, wait until it does. */
599  timeout_task = GNUNET_SCHEDULER_add_at(exp, &timeout_cb, NULL);
600  return;
601  }
603  "Sending BROKEN due to timeout (%s was last use, %s linger)\n",
606  send_broken(&r->prev, &r->cid, NULL, NULL);
607  send_broken(&r->next, &r->cid, NULL, NULL);
608  destroy_route(r);
609  }
610  /* No more routes left, so no need for a #timeout_task */
611 }
612 
613 
626 static void
627 dir_ready_cb(void *cls, int ready)
628 {
629  struct RouteDirection *dir = cls;
630  struct CadetRoute *route = dir->my_route;
631  struct RouteDirection *odir;
632 
633  if (GNUNET_YES == ready)
634  {
635  struct GNUNET_MQ_Envelope *env;
636 
637  dir->is_ready = GNUNET_YES;
638  if (NULL != (env = dir->env_head))
639  {
640  GNUNET_MQ_dll_remove(&dir->env_head, &dir->env_tail, env);
641  cur_buffers--;
643  lower_rung(dir);
644  dir->is_ready = GNUNET_NO;
645  GCP_send(dir->mqm, env);
646  }
647  return;
648  }
649  odir = (dir == &route->next) ? &route->prev : &route->next;
650  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending BROKEN due to MQ going down\n");
651  send_broken(&route->next, &route->cid, GCP_get_id(odir->hop), &my_full_id);
652  destroy_route(route);
653 }
654 
655 
663 static void
665  struct CadetRoute *route,
666  struct CadetPeer *hop)
667 {
668  dir->hop = hop;
669  dir->my_route = route;
670  dir->mqm = GCP_request_mq(hop, &dir_ready_cb, dir);
671  GNUNET_CONTAINER_DLL_insert(rung_head->rd_head, rung_head->rd_tail, dir);
672  dir->rung = rung_head;
674 }
675 
676 
687 static void
689  struct CadetPeer *target,
690  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
691  const struct GNUNET_PeerIdentity *failure_at)
692 {
693  struct GNUNET_MQ_Envelope *env;
695 
697  bm->cid = *cid;
698  bm->peer1 = my_full_id;
699  if (NULL != failure_at)
700  bm->peer2 = *failure_at;
701  GCP_send_ooo(target, env);
702 }
703 
704 
711 static void
713  void *cls,
715 {
716  struct CadetPeer *sender = cls;
717  struct CadetPeer *next;
718  const struct GNUNET_PeerIdentity *pids =
719  (const struct GNUNET_PeerIdentity *)&msg[1];
720  struct CadetRoute *route;
721  uint16_t size = ntohs(msg->header.size) - sizeof(*msg);
722  unsigned int path_length;
723  unsigned int off;
724 
725  path_length = size / sizeof(struct GNUNET_PeerIdentity);
726  if (0 == path_length)
727  {
729  "Dropping CADET_CONNECTION_CREATE with empty path\n");
730  GNUNET_break_op(0);
731  return;
732  }
734  "Handling CADET_CONNECTION_CREATE from %s for CID %s with %u hops\n",
735  GCP_2s(sender),
737  path_length);
738  /* Check for loops */
739  {
741 
742  map = GNUNET_CONTAINER_multipeermap_create(path_length * 2, GNUNET_YES);
743  GNUNET_assert(NULL != map);
744  for (unsigned int i = 0; i < path_length; i++)
745  {
747  "CADET_CONNECTION_CREATE has peer %s at offset %u\n",
748  GNUNET_i2s(&pids[i]),
749  i);
751  map,
752  &pids[i],
753  NULL,
755  {
756  /* bogus request */
759  "Dropping CADET_CONNECTION_CREATE with cyclic path\n");
760  GNUNET_break_op(0);
761  return;
762  }
763  }
765  }
766  /* Initiator is at offset 0, find us */
767  for (off = 1; off < path_length; off++)
768  if (0 == GNUNET_memcmp(&my_full_id, &pids[off]))
769  break;
770  if (off == path_length)
771  {
773  "Dropping CADET_CONNECTION_CREATE without us in the path\n");
774  GNUNET_break_op(0);
775  return;
776  }
777  /* Check previous hop */
778  if (sender != GCP_get(&pids[off - 1], GNUNET_NO))
779  {
781  "Dropping CADET_CONNECTION_CREATE without sender at previous hop in the path\n");
782  GNUNET_break_op(0);
783  return;
784  }
785  if (NULL != (route = get_route(&msg->cid)))
786  {
787  /* Duplicate CREATE, pass it on, previous one might have been lost! */
788 
790  "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n",
792  route_message(sender,
793  &msg->cid,
794  &msg->header,
797  return;
798  }
799  if (off == path_length - 1)
800  {
801  /* We are the destination, create connection */
802  struct CadetConnection *cc;
803  struct CadetPeerPath *path;
804  struct CadetPeer *origin;
805 
806  cc = GCC_lookup(&msg->cid);
807  if (NULL != cc)
808  {
810  "Received duplicate CADET_CONNECTION_CREATE message on connection %s\n",
813  return;
814  }
815 
816  origin = GCP_get(&pids[0], GNUNET_YES);
818  "I am destination for CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n",
819  GCP_2s(origin),
821  path = GCPP_get_path_from_route(path_length - 1, pids);
822  if (GNUNET_OK !=
824  &msg->cid,
825  path))
826  {
827  /* Send back BROKEN: duplicate connection on the same path,
828  we will use the other one. */
830  "Received CADET_CONNECTION_CREATE from %s for %s, but %s already has a connection. Sending BROKEN\n",
831  GCP_2s(sender),
833  GCPP_2s(path));
834  send_broken_without_mqm(sender, &msg->cid, NULL);
835  return;
836  }
837  return;
838  }
839  /* We are merely a hop on the way, check if we can support the route */
840  next = GCP_get(&pids[off + 1], GNUNET_NO);
841  if ((NULL == next) || (GNUNET_NO == GCP_has_core_connection(next)))
842  {
843  /* unworkable, send back BROKEN notification */
845  "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. Sending BROKEN\n",
846  GCP_2s(sender),
848  GNUNET_i2s(&pids[off + 1]),
849  off + 1);
850  send_broken_without_mqm(sender, &msg->cid, &pids[off + 1]);
851  return;
852  }
854  {
856  "Received CADET_CONNECTION_CREATE from %s for %s. We have reached our route limit. Sending BROKEN\n",
857  GCP_2s(sender),
859  send_broken_without_mqm(sender, &msg->cid, &pids[off - 1]);
860  return;
861  }
862 
863  /* Workable route, create routing entry */
865  "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is up. Creating route\n",
866  GCP_2s(sender),
868  GNUNET_i2s(&pids[off + 1]),
869  off + 1);
870  route = GNUNET_new(struct CadetRoute);
871  route->cid = msg->cid;
873  dir_init(&route->prev, route, sender);
874  dir_init(&route->next, route, next);
877  routes,
878  &route->cid.connection_of_tunnel,
879  route,
882  "# routes",
884  GNUNET_NO);
885  route->hn = GNUNET_CONTAINER_heap_insert(route_heap,
886  route,
887  route->last_use.abs_value_us);
888  if (NULL == timeout_task)
889  timeout_task =
891  3),
892  &timeout_cb,
893  NULL);
894  /* also pass CREATE message along to next hop */
895  route_message(sender,
896  &msg->cid,
897  &msg->header,
899 }
900 
901 
908 static void
910  void *cls,
912 {
913  struct CadetPeer *peer = cls;
914  struct CadetConnection *cc;
915 
916  /* First, check if ACK belongs to a connection that ends here. */
917  cc = GCC_lookup(&msg->cid);
918  if (NULL != cc)
919  {
920  /* verify ACK came from the right direction */
921  unsigned int len;
922  struct CadetPeerPath *path = GCC_get_path(cc, &len);
923 
924  if (peer != GCPP_get_peer_at_offset(path, 0))
925  {
926  /* received ACK from unexpected direction, ignore! */
927  GNUNET_break_op(0);
928  return;
929  }
931  "Received CONNECTION_CREATE_ACK for connection %s.\n",
934  return;
935  }
936 
937  /* We're just an intermediary peer, route the message along its path */
938  route_message(peer,
939  &msg->cid,
940  &msg->header,
942 }
943 
944 
952 static void
954  void *cls,
956 {
957  struct CadetPeer *peer = cls;
958  struct CadetConnection *cc;
959  struct CadetRoute *route;
960 
961  /* First, check if message belongs to a connection that ends here. */
962  cc = GCC_lookup(&msg->cid);
963  if (NULL != cc)
964  {
965  /* verify message came from the right direction */
966  unsigned int len;
967  struct CadetPeerPath *path = GCC_get_path(cc, &len);
968 
969  if (peer != GCPP_get_peer_at_offset(path, 0))
970  {
971  /* received message from unexpected direction, ignore! */
972  GNUNET_break_op(0);
973  return;
974  }
976  "Received CONNECTION_BROKEN for connection %s. Destroying it.\n",
979 
980  /* FIXME: also destroy the path up to the specified link! */
981  return;
982  }
983 
984  /* We're just an intermediary peer, route the message along its path */
985  route_message(peer,
986  &msg->cid,
987  &msg->header,
989  route = get_route(&msg->cid);
990  if (NULL != route)
991  destroy_route(route);
992  /* FIXME: also destroy paths we MAY have up to the specified link! */
993 }
994 
995 
1002 static void
1004  void *cls,
1006 {
1007  struct CadetPeer *peer = cls;
1008  struct CadetConnection *cc;
1009  struct CadetRoute *route;
1010 
1011  /* First, check if message belongs to a connection that ends here. */
1012  cc = GCC_lookup(&msg->cid);
1013  if (NULL != cc)
1014  {
1015  /* verify message came from the right direction */
1016  unsigned int len;
1017  struct CadetPeerPath *path = GCC_get_path(cc, &len);
1018 
1019  if (peer != GCPP_get_peer_at_offset(path, 0))
1020  {
1021  /* received message from unexpected direction, ignore! */
1022  GNUNET_break_op(0);
1023  return;
1024  }
1026  "Received CONNECTION_DESTROY for connection %s. Destroying connection.\n",
1028 
1030  return;
1031  }
1032 
1033  /* We're just an intermediary peer, route the message along its path */
1035  "Received CONNECTION_DESTROY for connection %s. Destroying route.\n",
1037  route_message(peer,
1038  &msg->cid,
1039  &msg->header,
1041  route = get_route(&msg->cid);
1042  if (NULL != route)
1043  destroy_route(route);
1044 }
1045 
1046 
1053 static void
1056 {
1057  struct CadetPeer *peer = cls;
1058  struct CadetConnection *cc;
1059 
1060  /* First, check if message belongs to a connection that ends here. */
1062  "Routing KX with ephemeral %s on CID %s\n",
1063  GNUNET_e2s(&msg->ephemeral_key),
1065 
1066 
1067  cc = GCC_lookup(&msg->cid);
1068  if (NULL != cc)
1069  {
1070  /* verify message came from the right direction */
1071  unsigned int len;
1072  struct CadetPeerPath *path = GCC_get_path(cc, &len);
1073 
1074  if (peer != GCPP_get_peer_at_offset(path, 0))
1075  {
1076  /* received message from unexpected direction, ignore! */
1077  GNUNET_break_op(0);
1078  return;
1079  }
1080  GCC_handle_kx(cc, msg);
1081  return;
1082  }
1083 
1084  /* We're just an intermediary peer, route the message along its path */
1085  route_message(peer,
1086  &msg->cid,
1087  &msg->header,
1089 }
1090 
1091 
1098 static void
1100  void *cls,
1102 {
1103  struct CadetPeer *peer = cls;
1104  struct CadetConnection *cc;
1105 
1106  /* First, check if message belongs to a connection that ends here. */
1107  cc = GCC_lookup(&msg->kx.cid);
1108  if (NULL != cc)
1109  {
1110  /* verify message came from the right direction */
1111  unsigned int len;
1112  struct CadetPeerPath *path = GCC_get_path(cc, &len);
1113 
1114  if (peer != GCPP_get_peer_at_offset(path, 0))
1115  {
1116  /* received message from unexpected direction, ignore! */
1117  GNUNET_break_op(0);
1118  return;
1119  }
1120  GCC_handle_kx_auth(cc, msg);
1121  return;
1122  }
1123 
1124  /* We're just an intermediary peer, route the message along its path */
1125  route_message(peer,
1126  &msg->kx.cid,
1127  &msg->kx.header,
1129 }
1130 
1131 
1140 static int
1143 {
1144  return GNUNET_YES;
1145 }
1146 
1147 
1154 static void
1157 {
1158  struct CadetPeer *peer = cls;
1159  struct CadetConnection *cc;
1160 
1161  /* First, check if message belongs to a connection that ends here. */
1162  cc = GCC_lookup(&msg->cid);
1163  if (NULL != cc)
1164  {
1165  /* verify message came from the right direction */
1166  unsigned int len;
1167  struct CadetPeerPath *path = GCC_get_path(cc, &len);
1168 
1169  if (peer != GCPP_get_peer_at_offset(path, 0))
1170  {
1171  /* received message from unexpected direction, ignore! */
1172  GNUNET_break_op(0);
1173  return;
1174  }
1175  GCC_handle_encrypted(cc, msg);
1176  return;
1177  }
1178  /* We're just an intermediary peer, route the message along its path */
1179  route_message(peer, &msg->cid, &msg->header, GNUNET_MQ_PRIO_BEST_EFFORT);
1180 }
1181 
1182 
1195 static void
1197 {
1198  if (NULL == my_identity)
1199  {
1200  GNUNET_break(0);
1201  return;
1202  }
1203  GNUNET_break(0 == GNUNET_memcmp(my_identity, &my_full_id));
1204 }
1205 
1206 
1213 static void *
1215  const struct GNUNET_PeerIdentity *peer,
1216  struct GNUNET_MQ_Handle *mq)
1217 {
1218  struct CadetPeer *cp;
1219 
1221  "CORE connection to peer %s was established.\n",
1222  GNUNET_i2s(peer));
1223  cp = GCP_get(peer, GNUNET_YES);
1224  GCP_set_mq(cp, mq);
1225  return cp;
1226 }
1227 
1228 
1235 static void
1237  const struct GNUNET_PeerIdentity *peer,
1238  void *peer_cls)
1239 {
1240  struct CadetPeer *cp = peer_cls;
1241 
1243  "CORE connection to peer %s went down.\n",
1244  GNUNET_i2s(peer));
1245  GCP_set_mq(cp, NULL);
1246 }
1247 
1248 
1254 void
1256 {
1257  struct GNUNET_MQ_MessageHandler handlers[] =
1261  NULL),
1262  GNUNET_MQ_hd_fixed_size(connection_create_ack,
1265  NULL),
1266  GNUNET_MQ_hd_fixed_size(connection_broken,
1269  NULL),
1270  GNUNET_MQ_hd_fixed_size(connection_destroy,
1273  NULL),
1274  GNUNET_MQ_hd_fixed_size(tunnel_kx,
1277  NULL),
1278  GNUNET_MQ_hd_fixed_size(tunnel_kx_auth,
1281  NULL),
1282  GNUNET_MQ_hd_var_size(tunnel_encrypted,
1285  NULL),
1287 
1289  "CADET",
1290  "MAX_ROUTES",
1291  &max_routes))
1292  max_routes = 5000;
1294  "CADET",
1295  "MAX_MSGS_QUEUE",
1296  &max_buffers))
1297  max_buffers = 10000;
1300  core = GNUNET_CORE_connect(c,
1301  NULL,
1302  &core_init_cb,
1303  &core_connect_cb,
1305  handlers);
1306 }
1307 
1308 
1312 void
1314 {
1315  if (NULL != core)
1316  {
1317  GNUNET_CORE_disconnect(core);
1318  core = NULL;
1319  }
1322  routes = NULL;
1323  GNUNET_CONTAINER_heap_destroy(route_heap);
1324  route_heap = NULL;
1325  if (NULL != timeout_task)
1326  {
1327  GNUNET_SCHEDULER_cancel(timeout_task);
1328  timeout_task = NULL;
1329  }
1330 }
1331 
1332 /* end of gnunet-cadet-service_core.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
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:1171
Axolotl-encrypted tunnel message with application payload.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
Axolotl encrypted data.
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
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:1150
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:84
static void handle_tunnel_kx(void *cls, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX.
static unsigned long long max_buffers
Maximum number of envelopes we will buffer at this peer.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
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.
unsigned int num_routes
Total number of route directions in this rung.
static void dir_init(struct RouteDirection *dir, struct CadetRoute *route, struct CadetPeer *hop)
Initialize one of the directions of a route.
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:651
Peer description.
const char * GNUNET_i2s2(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env_head
Head of DLL of envelopes we have in the buffer for this direction.
struct RouteDirection * next
DLL of other route directions within the same struct Rung.
Low-level connection to a destination.
int 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.
const struct GNUNET_MessageHeader * GNUNET_MQ_env_get_msg(const struct GNUNET_MQ_Envelope *env)
Obtain message contained in envelope.
Definition: mq.c:1077
Message to destroy a connection.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct CadetTunnel * GCP_get_tunnel(struct CadetPeer *cp, int create)
Get the tunnel towards a peer.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
Context for the core service connection.
Definition: core_api.c:76
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.
static void handle_tunnel_kx_auth(void *cls, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH.
Information we keep per direction for a route.
A connection is a live end-to-end messaging mechanism where the peers are identified by a path and kn...
struct GNUNET_CONTAINER_HeapNode * hn
Position of this route in the route_heap.
static unsigned long long max_routes
Maximum number of concurrent routes this peer will support.
#define LOG(level,...)
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE.
Data structure used to track whom we have to notify about changes to our message queue.
struct GNUNET_CADET_TunnelKeyExchangeMessage kx
Message header with key material.
static void core_disconnect_cb(void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
Method called whenever a peer disconnects.
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
void GCC_destroy_without_core(struct CadetConnection *cc)
Destroy a connection, called when the CORE layer is already done (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Message for ack&#39;ing a connection.
static unsigned long long cur_buffers
Current number of envelopes we have buffered at this peer.
void GCC_handle_kx(struct CadetConnection *cc, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Handle KX message.
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:1002
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.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
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...
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
void GCC_handle_connection_create_ack(struct CadetConnection *cc)
A GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection, implying that the end-to-end connection is up.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_PeerIdentity peer2
ID of the endpoint.
void GCP_set_mq(struct CadetPeer *cp, struct GNUNET_MQ_Handle *mq)
Set the message queue to mq for peer cp and notify watchers.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
Information we track per tunnel.
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:393
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GCP_send(struct GCP_MessageQueueManager *mqm, struct GNUNET_MQ_Envelope *env)
Send the message in env to cp.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static void * core_connect_cb(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
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_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).
Set of CadetRoutes that have exactly the same number of messages in their buffer. ...
struct Rung * prev
Rung of RouteDirections with one less buffer entry each.
static int check_tunnel_encrypted(void *cls, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Check if the encrypted message has the appropriate size.
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const struct GNUNET_MQ_Envelope * GNUNET_MQ_env_next(const struct GNUNET_MQ_Envelope *env)
Return next envelope in queue.
Definition: mq.c:1090
struct Rung * next
Rung of RouteDirections with one more buffer entry each.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
static void destroy_direction(struct RouteDirection *dir)
Free internal data of a route direction.
static struct GNUNET_CONTAINER_MultiPeerMap * map
Handle to the map used to store old latency values for peers.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
static void handle_connection_create_ack(void *cls, const struct GNUNET_CADET_ConnectionCreateAckMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK.
Flag to indicate that low latency is important.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
Unique identifier for the connection that uses this route.
enum GNUNET_MQ_PriorityPreferences GNUNET_MQ_env_get_options(struct GNUNET_MQ_Envelope *env)
Get performance preferences set for this envelope.
Definition: mq.c:1017
Best-effort traffic (i.e.
struct CadetRoute * my_route
Route this direction is part of.
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK.
struct RouteDirection * rd_head
DLL of route directions with a number of buffer entries matching this rung.
static void destroy_route(struct CadetRoute *route)
Destroy our state for route.
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:1237
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static struct CadetRoute * get_route(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Get the route corresponding to a hash.
Information we track per peer.
static struct Rung rung_zero
Rung zero (always pointed to by rung_head).
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.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED.
int GCT_add_inbound_connection(struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
Add a connection to the tunnel.
Message for a Key eXchange for a tunnel, with authentication.
struct RouteDirection prev
Information about the previous hop on this route.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
void GCP_send_ooo(struct CadetPeer *cp, struct GNUNET_MQ_Envelope *env)
Send the message in env to cp, overriding queueing logic.
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:686
Description of a segment of a struct CadetConnection at the intermediate peers.
struct CadetPeer * hop
Target peer.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
struct GNUNET_TIME_Absolute last_use
When was this route last in use?
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...
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
int 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.
#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
Request the creation of a connection.
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:440
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
Message for notifying a disconnection in a path.
Handle to a node in a heap.
static void dir_ready_cb(void *cls, int ready)
Function called when the message queue to the previous hop becomes available/unavailable.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK
Send origin an ACK that the connection is complete.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
Internal representation of the hash 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).
Heap with the minimum cost at the root.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
struct RouteDirection next
Information about the next hop on this route.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
Message handler for a specific message type.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
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:1192
static void lower_rung(struct RouteDirection *dir)
Lower the rung in which dir is by 1.
void GCC_handle_duplicate_create(struct CadetConnection *cc)
We got a GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a connection that we already have...
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:319
Node in the heap.
void GCO_shutdown()
Shut down the CORE subsystem.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
Internal representation of the hash map.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct RouteDirection * rd_tail
DLL of route directions with a number of buffer entries matching this rung.
static unsigned int size
Size of the "table".
Definition: peer.c:66
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).
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.
unsigned int rung_off
Number of messages route directions at this rung have in their buffer.
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:690
struct GNUNET_PeerIdentity peer1
ID of the endpoint.
void GNUNET_CORE_disconnect(struct GNUNET_CORE_Handle *handle)
Disconnect from the core service.
Definition: core_api.c:728
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
struct GCP_MessageQueueManager * mqm
Message queue manager for hop.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
P2P messages used by CADET.
int GCP_has_core_connection(struct CadetPeer *cp)
Test if cp has a core-level connection.
Handle to a message queue.
Definition: mq.c:84
struct CadetConnection * GCC_lookup(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Lookup a connection by its identifier.
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.
static void handle_tunnel_encrypted(void *cls, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED.
The identity of the host (wraps the signing key of the peer).
Hash uniquely identifying a connection below a tunnel.
static struct GNUNET_CONTAINER_Heap * route_heap
Heap of routes, MIN-sorted by last activity.
static struct GNUNET_SCHEDULER_Task * timeout_task
Task to timeout routes.
configuration data
Definition: configuration.c:83
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.
void GCC_handle_encrypted(struct CadetConnection *cc, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle encrypted message.
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer stucture associated with the peer.
#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
Request the destuction of a connection.
void GCP_request_mq_cancel(struct GCP_MessageQueueManager *mqm, struct GNUNET_MQ_Envelope *last_env)
Stops message queue change notifications.
Message for a Key eXchange for a tunnel.
static void handle_connection_create(void *cls, const struct GNUNET_CADET_ConnectionCreateMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX or GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH as part of stru...
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
Flag to indicate that out-of-order delivery is OK.
static void handle_connection_broken(void *cls, const struct GNUNET_CADET_ConnectionBrokenMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN.
static struct PendingResolutions * tail
Tail of list of pending resolution requests.
Definition: gnunet-ats.c:233
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
struct GNUNET_TIME_Relative keepalive_period
How frequently do we send KEEPALIVE messages on idle connections?
struct Rung * rung
Rung of this route direction (matches length of the buffer DLL).
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
Axolotl key exchange response with authentication.
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:331
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.
Header for all communications.
void GCC_handle_kx_auth(struct CadetConnection *cc, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle KX_AUTH message.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GCO_init(const struct GNUNET_CONFIGURATION_Handle *c)
Initialize the CORE subsystem.
int is_ready
Is mqm currently ready for transmission?
Flag to indicate that unreliable delivery is acceptable.
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 timeout_cb(void *cls)
Function called to check if any routes have timed out, and if so, to clean them up.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:741
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Sender&#39;s ephemeral public ECC key encoded in a format suitable for network transmission, as created using &#39;gcry_sexp_sprint&#39;.
Highest priority, control traffic (i.e.
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
static void discard_all_from_rung_tail()
Discard all messages from the highest rung, to make space.
static int check_connection_create(void *cls, const struct GNUNET_CADET_ConnectionCreateMessage *msg)
Check if the create_connection message has the appropriate size.
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:1214
cadet service; interaction with CORE service
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.
struct RouteDirection * prev
DLL of other route directions within the same struct Rung.
Information regarding a possible path to reach a peer.
struct GNUNET_ShortHashCode connection_of_tunnel
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
static void handle_connection_destroy(void *cls, const struct GNUNET_CADET_ConnectionDestroyMessage *msg)
Handle for GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN.
static struct Rung * rung_tail
Tail of the rung_head DLL.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
Notify that a connection is no longer valid.
Message for cadet connection creation.
struct GNUNET_MQ_Envelope * env_tail
Tail of DLL of envelopes we have in the buffer for this direction.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static struct GNUNET_CORE_Handle * core
Handle to the CORE service.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
#define GNUNET_free(ptr)
Wrapper around free.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
Time for relative time used by GNUnet, in microseconds.
struct GCP_MessageQueueManager * GCP_request_mq(struct CadetPeer *cp, GCP_MessageQueueNotificationCallback cb, void *cb_cls)
Start message queue change notifications.
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_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY.
static struct GNUNET_CONTAINER_MultiShortmap * routes
Routes on which this peer is an intermediate.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956