GNUnet  0.11.x
gnunet-service-cadet_channel.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2017 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
36 #include "platform.h"
37 #include "cadet.h"
43 
44 #define LOG(level, ...) GNUNET_log_from (level, "cadet-chn", __VA_ARGS__)
45 
49 #define CADET_INITIAL_RETRANSMIT_TIME \
50  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250)
51 
56 #define TIMEOUT_CLOSED_PORT \
57  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
58 
62 #define MIN_RTT_DELAY \
63  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 75)
64 
75 #define MAX_OUT_OF_ORDER_DISTANCE 1024
76 
77 
82 {
87 
93 
98 
103 };
104 
105 
112 {
117 
122 
126  struct CadetChannel *ch;
127 
134 
139 
145 
151 
157 
163 
170 };
171 
172 
177 {
182 
187 
193 
198 };
199 
200 
207 {
214  struct CadetClient *c;
215 
220 
225 
232 
236  unsigned int num_recv;
237 
242 };
243 
244 
249 {
253  struct CadetTunnel *t;
254 
260 
266 
274 
279 
284 
289 
294 
299 
303  struct GNUNET_HashCode port;
304 
308  struct GNUNET_HashCode h_port;
309 
314 
318  uint64_t mid_futures;
319 
324 
329 
333  unsigned int pending_messages;
334 
339  unsigned int max_pending_messages;
340 
345 
350 
355  unsigned int skip_ack_series;
356 
360  int nobuffer;
361 
365  int reliable;
366 
371 
376 
382  int destroy;
383 
387  uint16_t type GNUNET_PACKED;
388 
389 };
390 
396 void
399 {
400 
401  ch->type = message->type;
402 
403 }
404 
405 
411 int
412 GCCH_is_type_to_drop (struct CadetChannel *ch, const struct
413  GNUNET_MessageHeader *message)
414 {
415 
416  if (ch->type == message->type)
417  {
418  ch->type = 0;
419  return GNUNET_YES;
420  }
421  else
422  return GNUNET_NO;
423 }
424 
425 
433 const char *
434 GCCH_2s (const struct CadetChannel *ch)
435 {
436  static char buf[128];
437 
439  sizeof(buf),
440  "Channel %s:%s ctn:%X(%X/%X)",
441  (GNUNET_YES == ch->is_loopback)
442  ? "loopback"
444  GNUNET_h2s (&ch->port),
445  ch->ctn.cn,
446  (NULL == ch->owner)
447  ? 0
448  : ntohl (ch->owner->ccn.channel_of_client),
449  (NULL == ch->dest)
450  ? 0
451  : ntohl (ch->dest->ccn.channel_of_client));
452  return buf;
453 }
454 
455 
465 void
467  const struct GNUNET_HashCode *port,
468  const struct GNUNET_PeerIdentity *listener)
469 {
470  struct GNUNET_HashContext *hc;
471 
473  GNUNET_CRYPTO_hash_context_read (hc, port, sizeof(*port));
474  GNUNET_CRYPTO_hash_context_read (hc, listener, sizeof(*listener));
477  "Calculated port hash %s\n",
478  GNUNET_h2s (h_port));
479 }
480 
481 
490 GCCH_get_id (const struct CadetChannel *ch)
491 {
492  return ch->ctn;
493 }
494 
495 
501 static void
503 {
504  struct CadetOutOfOrderMessage *com;
505 
506  while (NULL != (com = ccc->head_recv))
507  {
509  ccc->num_recv--;
510  GNUNET_MQ_discard (com->env);
511  GNUNET_free (com);
512  }
513  GNUNET_free (ccc);
514 }
515 
516 
522 static void
524 {
525  struct CadetReliableMessage *crm;
526 
527  while (NULL != (crm = ch->head_sent))
528  {
529  GNUNET_assert (ch == crm->ch);
530  if (NULL != crm->qe)
531  {
532  GCT_send_cancel (crm->qe);
533  crm->qe = NULL;
534  }
535  GNUNET_CONTAINER_DLL_remove (ch->head_sent, ch->tail_sent, crm);
536  GNUNET_free (crm->data_message);
537  GNUNET_free (crm);
538  }
539  if (CADET_CHANNEL_LOOSE == ch->state)
540  {
541  GSC_drop_loose_channel (&ch->h_port, ch);
542  }
543  if (NULL != ch->owner)
544  {
545  free_channel_client (ch->owner);
546  ch->owner = NULL;
547  }
548  if (NULL != ch->dest)
549  {
550  free_channel_client (ch->dest);
551  ch->dest = NULL;
552  }
553  if (NULL != ch->last_control_qe)
554  {
555  GCT_send_cancel (ch->last_control_qe);
556  ch->last_control_qe = NULL;
557  }
558  if (NULL != ch->retry_data_task)
559  {
560  GNUNET_SCHEDULER_cancel (ch->retry_data_task);
561  ch->retry_data_task = NULL;
562  }
563  if (NULL != ch->retry_control_task)
564  {
565  GNUNET_SCHEDULER_cancel (ch->retry_control_task);
566  ch->retry_control_task = NULL;
567  }
568  if (GNUNET_NO == ch->is_loopback)
569  {
570  GCT_remove_channel (ch->t, ch, ch->ctn);
571  ch->t = NULL;
572  }
573  GNUNET_free (ch);
574 }
575 
576 
582 static void
583 send_channel_open (void *cls);
584 
585 
594 static void
596  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
597 {
598  struct CadetChannel *ch = cls;
599 
600  GNUNET_assert (NULL != ch->last_control_qe);
601  ch->last_control_qe = NULL;
602  ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time);
604  "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
605  GCCH_2s (ch),
607  ch->retry_control_task =
609 }
610 
611 
617 static void
618 send_channel_open (void *cls)
619 {
620  struct CadetChannel *ch = cls;
621  struct GNUNET_CADET_ChannelOpenMessage msgcc;
622 
623  ch->retry_control_task = NULL;
625  "Sending CHANNEL_OPEN message for %s\n",
626  GCCH_2s (ch));
627  msgcc.header.size = htons (sizeof(msgcc));
629  // TODO This will be removed in a major release, because this will be a protocol breaking change. We set the deprecated "reliable" bit here that was removed.
630  msgcc.opt = 2;
631  msgcc.h_port = ch->h_port;
632  msgcc.ctn = ch->ctn;
633  ch->state = CADET_CHANNEL_OPEN_SENT;
634  if (NULL != ch->last_control_qe)
635  GCT_send_cancel (ch->last_control_qe);
636  ch->last_control_qe =
637  GCT_send (ch->t, &msgcc.header, &channel_open_sent_cb, ch, &msgcc.ctn);
638  GNUNET_assert (NULL == ch->retry_control_task);
639 }
640 
641 
652 void
654 {
655  GNUNET_assert (NULL == ch->retry_control_task);
657  "Tunnel up, sending CHANNEL_OPEN on %s now\n",
658  GCCH_2s (ch));
659  ch->retry_control_task = GNUNET_SCHEDULER_add_now (&send_channel_open, ch);
660 }
661 
662 
673 struct CadetChannel *
676  struct CadetPeer *destination,
677  const struct GNUNET_HashCode *port,
678  uint32_t options)
679 {
680  struct CadetChannel *ch;
681  struct CadetChannelClient *ccco;
682 
683  ccco = GNUNET_new (struct CadetChannelClient);
684  ccco->c = owner;
685  ccco->ccn = ccn;
686  ccco->client_ready = GNUNET_YES;
687 
688  ch = GNUNET_new (struct CadetChannel);
689  ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */
690  ch->nobuffer = GNUNET_NO;
691  ch->reliable = GNUNET_YES;
692  ch->out_of_order = GNUNET_NO;
693  ch->max_pending_messages =
694  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
695  ch->owner = ccco;
696  ch->port = *port;
697  GCCH_hash_port (&ch->h_port, port, GCP_get_id (destination));
698  if (0 == GNUNET_memcmp (&my_full_id, GCP_get_id (destination)))
699  {
700  struct OpenPort *op;
701 
702  ch->is_loopback = GNUNET_YES;
704  if (NULL == op)
705  {
706  /* port closed, wait for it to possibly open */
707  ch->state = CADET_CHANNEL_LOOSE;
710  &ch->h_port,
711  ch,
714  "Created loose incoming loopback channel to port %s\n",
715  GNUNET_h2s (&ch->port));
716  }
717  else
718  {
719  GCCH_bind (ch, op->c, &op->port);
720  }
721  }
722  else
723  {
724  ch->t = GCP_get_tunnel (destination, GNUNET_YES);
725  ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
726  ch->ctn = GCT_add_channel (ch->t, ch);
727  }
728  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
730  "Created channel to port %s at peer %s for %s using %s\n",
731  GNUNET_h2s (port),
732  GCP_2s (destination),
733  GSC_2s (owner),
734  (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
735  return ch;
736 }
737 
738 
745 static void
746 timeout_closed_cb (void *cls)
747 {
748  struct CadetChannel *ch = cls;
749 
750  ch->retry_control_task = NULL;
752  "Closing incoming channel to port %s from peer %s due to timeout\n",
753  GNUNET_h2s (&ch->port),
754  GCP_2s (GCT_get_destination (ch->t)));
756 }
757 
758 
768 struct CadetChannel *
771  const struct GNUNET_HashCode *h_port,
772  uint32_t options)
773 {
774  struct CadetChannel *ch;
775  struct OpenPort *op;
776 
777  ch = GNUNET_new (struct CadetChannel);
778  ch->h_port = *h_port;
779  ch->t = t;
780  ch->ctn = ctn;
781  ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
782  ch->nobuffer = GNUNET_NO;
783  ch->reliable = GNUNET_YES;
784  ch->out_of_order = GNUNET_NO;
785  ch->max_pending_messages =
786  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
787  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
788 
790  if (NULL == op)
791  {
792  /* port closed, wait for it to possibly open */
793  ch->state = CADET_CHANNEL_LOOSE;
796  &ch->h_port,
797  ch,
799  GNUNET_assert (NULL == ch->retry_control_task);
800  ch->retry_control_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT,
802  ch);
804  "Created loose incoming channel to port %s from peer %s\n",
805  GNUNET_h2s (&ch->port),
806  GCP_2s (GCT_get_destination (ch->t)));
807  }
808  else
809  {
810  GCCH_bind (ch, op->c, &op->port);
811  }
812  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
813  return ch;
814 }
815 
816 
826 static void
827 send_ack_cb (void *cls,
828  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
829 {
830  struct CadetChannel *ch = cls;
831 
832  GNUNET_assert (NULL != ch->last_control_qe);
833  ch->last_control_qe = NULL;
834 }
835 
836 
842 static void
844 {
846 
847  if (GNUNET_NO == ch->reliable)
848  return; /* no ACKs */
850  msg.header.size = htons (sizeof(msg));
851  msg.ctn = ch->ctn;
852  msg.mid.mid = htonl (ntohl (ch->mid_recv.mid));
853  msg.futures = GNUNET_htonll (ch->mid_futures);
855  "Sending DATA_ACK %u:%llX via %s\n",
856  (unsigned int) ntohl (msg.mid.mid),
857  (unsigned long long) ch->mid_futures,
858  GCCH_2s (ch));
859  if (NULL != ch->last_control_qe)
860  GCT_send_cancel (ch->last_control_qe);
861  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch,
862  &msg.ctn);
863 }
864 
865 
872 static void
873 send_open_ack (void *cls)
874 {
875  struct CadetChannel *ch = cls;
877 
878  ch->retry_control_task = NULL;
880  "Sending CHANNEL_OPEN_ACK on %s\n",
881  GCCH_2s (ch));
883  msg.header.size = htons (sizeof(msg));
884  msg.reserved = htonl (0);
885  msg.ctn = ch->ctn;
886  msg.port = ch->port;
887  if (NULL != ch->last_control_qe)
888  GCT_send_cancel (ch->last_control_qe);
889  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch,
890  &msg.ctn);
891 }
892 
893 
902 void
904  struct CadetChannel *ch,
905  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
906 {
907  if (NULL == ch->dest)
908  {
910  "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
911  GCCH_2s (ch));
912  return;
913  }
914  if (NULL != ch->retry_control_task)
915  {
917  "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
918  GCCH_2s (ch));
919  return;
920  }
922  "Retransmitting CHANNEL_OPEN_ACK on %s\n",
923  GCCH_2s (ch));
924  ch->retry_control_task = GNUNET_SCHEDULER_add_now (&send_open_ack, ch);
925 }
926 
927 
935 static void
936 send_ack_to_client (struct CadetChannel *ch, int to_owner)
937 {
938  struct GNUNET_MQ_Envelope *env;
939  struct GNUNET_CADET_LocalAck *ack;
940  struct CadetChannelClient *ccc;
941 
942  ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
943  if (NULL == ccc)
944  {
945  /* This can happen if we are just getting ACKs after
946  our local client already disconnected. */
947  GNUNET_assert (GNUNET_YES == ch->destroy);
948  return;
949  }
951  ack->ccn = ccc->ccn;
953  "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X (%u/%u pending)\n",
954  GSC_2s (ccc->c),
955  (GNUNET_YES == to_owner) ? "owner" : "dest",
956  ntohl (ack->ccn.channel_of_client),
957  ch->pending_messages,
958  ch->max_pending_messages);
959  GSC_send_to_client (ccc->c, env);
960 }
961 
962 
972 void
974  struct CadetClient *c,
975  const struct GNUNET_HashCode *port)
976 {
977  uint32_t options;
978  struct CadetChannelClient *cccd;
979 
981  "Binding %s from %s to port %s of %s\n",
982  GCCH_2s (ch),
983  GCT_2s (ch->t),
984  GNUNET_h2s (&ch->port),
985  GSC_2s (c));
986  if (NULL != ch->retry_control_task)
987  {
988  /* there might be a timeout task here */
989  GNUNET_SCHEDULER_cancel (ch->retry_control_task);
990  ch->retry_control_task = NULL;
991  }
992  options = 0;
993  cccd = GNUNET_new (struct CadetChannelClient);
994  GNUNET_assert (NULL == ch->dest);
995  ch->dest = cccd;
996  ch->port = *port;
997  cccd->c = c;
998  cccd->client_ready = GNUNET_YES;
999  cccd->ccn = GSC_bind (c,
1000  ch,
1001  (GNUNET_YES == ch->is_loopback)
1003  : GCT_get_destination (ch->t),
1004  port,
1005  options);
1006  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1008  ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */
1009  if (GNUNET_YES == ch->is_loopback)
1010  {
1011  ch->state = CADET_CHANNEL_OPEN_SENT;
1013  }
1014  else
1015  {
1016  /* notify other peer that we accepted the connection */
1017  ch->state = CADET_CHANNEL_READY;
1018  ch->retry_control_task = GNUNET_SCHEDULER_add_now (&send_open_ack, ch);
1019  }
1020  /* give client it's initial supply of ACKs */
1021  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1023  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1025 }
1026 
1027 
1035 static void
1037 {
1038  struct CadetChannel *ch = cls;
1039  struct CadetChannelClient *ccc;
1040 
1041  /* Find which end is left... */
1042  ch->retry_control_task = NULL;
1043  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1044  GSC_handle_remote_channel_destroy (ccc->c, ccc->ccn, ch);
1045  channel_destroy (ch);
1046 }
1047 
1048 
1057 void
1059  struct CadetClient *c,
1061 {
1063  "%s asks for destruction of %s\n",
1064  GSC_2s (c),
1065  GCCH_2s (ch));
1066  GNUNET_assert (NULL != c);
1067  if ((NULL != ch->owner) && (c == ch->owner->c) &&
1069  {
1070  free_channel_client (ch->owner);
1071  ch->owner = NULL;
1072  }
1073  else if ((NULL != ch->dest) && (c == ch->dest->c) &&
1075  {
1076  free_channel_client (ch->dest);
1077  ch->dest = NULL;
1078  }
1079  else
1080  {
1081  GNUNET_assert (0);
1082  }
1083 
1084  if (GNUNET_YES == ch->destroy)
1085  {
1086  /* other end already destroyed, with the local client gone, no need
1087  to finish transmissions, just destroy immediately. */
1088  channel_destroy (ch);
1089  return;
1090  }
1091  if ((NULL != ch->head_sent) && ((NULL != ch->owner) || (NULL != ch->dest)))
1092  {
1093  /* Wait for other end to destroy us as well,
1094  and otherwise allow send queue to be transmitted first */
1095  ch->destroy = GNUNET_YES;
1096  return;
1097  }
1098  if ((GNUNET_YES == ch->is_loopback) &&
1099  ((NULL != ch->owner) || (NULL != ch->dest)))
1100  {
1101  if (NULL != ch->retry_control_task)
1102  GNUNET_SCHEDULER_cancel (ch->retry_control_task);
1103  ch->retry_control_task =
1105  return;
1106  }
1107  if (GNUNET_NO == ch->is_loopback)
1108  {
1109  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1110  switch (ch->state)
1111  {
1112  case CADET_CHANNEL_NEW:
1113  /* We gave up on a channel that we created as a client to a remote
1114  target, but that never went anywhere. Nothing to do here. */
1115  break;
1116 
1117  case CADET_CHANNEL_LOOSE:
1118  break;
1119 
1120  default:
1121  GCT_send_channel_destroy (ch->t, ch->ctn);
1122  }
1123  }
1124  /* Nothing left to do, just finish destruction */
1125  channel_destroy (ch);
1126 }
1127 
1128 
1138 void
1140  struct CadetChannel *ch,
1141  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1142  const struct GNUNET_HashCode *port)
1143 {
1144  switch (ch->state)
1145  {
1146  case CADET_CHANNEL_NEW:
1147  /* this should be impossible */
1148  GNUNET_break (0);
1149  break;
1150 
1151  case CADET_CHANNEL_LOOSE:
1152  /* This makes no sense. */
1153  GNUNET_break_op (0);
1154  break;
1155 
1157  if (NULL == ch->owner)
1158  {
1159  /* We're not the owner, wrong direction! */
1160  GNUNET_break_op (0);
1161  return;
1162  }
1163  if (0 != GNUNET_memcmp (&ch->port, port))
1164  {
1165  /* Other peer failed to provide the right port,
1166  refuse connection. */
1167  GNUNET_break_op (0);
1168  return;
1169  }
1171  "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1172  GCCH_2s (ch));
1173  if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1174  {
1175  GNUNET_SCHEDULER_cancel (ch->retry_control_task);
1176  ch->retry_control_task = NULL;
1177  }
1178  ch->state = CADET_CHANNEL_READY;
1179  /* On first connect, send client as many ACKs as we allow messages
1180  to be buffered! */
1181  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1183  break;
1184 
1185  case CADET_CHANNEL_READY:
1186  /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1188  "Received duplicate channel OPEN_ACK for %s\n",
1189  GCCH_2s (ch));
1190  GNUNET_STATISTICS_update (stats, "# duplicate CREATE_ACKs", 1, GNUNET_NO);
1191  break;
1192  }
1193 }
1194 
1195 
1204 static int
1205 is_before (void *cls,
1206  struct CadetOutOfOrderMessage *m1,
1207  struct CadetOutOfOrderMessage *m2)
1208 {
1209  int *duplicate = cls;
1210  uint32_t v1 = ntohl (m1->mid.mid);
1211  uint32_t v2 = ntohl (m2->mid.mid);
1212  uint32_t delta;
1213 
1214  delta = v2 - v1;
1215  if (0 == delta)
1216  *duplicate = GNUNET_YES;
1217  if (delta > (uint32_t) INT_MAX)
1218  {
1219  /* in overflow range, we can safely assume we wrapped around */
1220  return GNUNET_NO;
1221  }
1222  else
1223  {
1224  /* result is small, thus v2 > v1, thus m1 < m2 */
1225  return GNUNET_YES;
1226  }
1227 }
1228 
1229 
1238 void
1240  struct CadetChannel *ch,
1241  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1243 {
1244  struct GNUNET_MQ_Envelope *env;
1245  struct GNUNET_CADET_LocalData *ld;
1246  struct CadetChannelClient *ccc;
1247  size_t payload_size;
1248  struct CadetOutOfOrderMessage *com;
1249  int duplicate;
1250  uint32_t mid_min;
1251  uint32_t mid_max;
1252  uint32_t mid_msg;
1253  uint32_t delta;
1254 
1255  GNUNET_assert (GNUNET_NO == ch->is_loopback);
1256  if ((NULL == ch->owner) && (NULL == ch->dest))
1257  {
1258  /* This client is gone, but we still have messages to send to
1259  the other end (which is why @a ch is not yet dead). However,
1260  we cannot pass messages to our client anymore. */
1262  "Dropping incoming payload on %s as this end is already closed\n",
1263  GCCH_2s (ch));
1264  /* send back DESTROY notification to stop further retransmissions! */
1265  if (GNUNET_YES == ch->destroy)
1266  GCT_send_channel_destroy (ch->t, ch->ctn);
1267  return;
1268  }
1269  payload_size = ntohs (msg->header.size) - sizeof(*msg);
1270  env = GNUNET_MQ_msg_extra (ld,
1271  payload_size,
1273  ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1274  GNUNET_memcpy (&ld[1], &msg[1], payload_size);
1275  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1276  if (GNUNET_YES == ccc->client_ready)
1277  {
1278  /*
1279  * We ad-hoc send the message if
1280  * - The channel is out-of-order
1281  * - The channel is reliable and MID matches next expected MID
1282  * - The channel is unreliable and MID is before lowest seen MID
1283  */if ((GNUNET_YES == ch->out_of_order) ||
1284  ((msg->mid.mid == ch->mid_recv.mid) && (GNUNET_YES == ch->reliable)) ||
1285  ((GNUNET_NO == ch->reliable) &&
1286  (ntohl (msg->mid.mid) >= ntohl (ch->mid_recv.mid)) &&
1287  ((NULL == ccc->head_recv) ||
1288  (ntohl (msg->mid.mid) < ntohl (ccc->head_recv->mid.mid)))))
1289  {
1291  "Giving %u bytes of payload with MID %u from %s to client %s\n",
1292  (unsigned int) payload_size,
1293  ntohl (msg->mid.mid),
1294  GCCH_2s (ch),
1295  GSC_2s (ccc->c));
1296  ccc->client_ready = GNUNET_NO;
1297  GSC_send_to_client (ccc->c, env);
1298  if (GNUNET_NO == ch->out_of_order)
1299  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1300  else
1301  ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
1302  ch->mid_futures >>= 1;
1303  if ((GNUNET_YES == ch->out_of_order) && (GNUNET_NO == ch->reliable))
1304  {
1305  /* possibly shift by more if we skipped messages */
1306  uint64_t delta = htonl (msg->mid.mid) - 1 - ntohl (ch->mid_recv.mid);
1307 
1308  if (delta > 63)
1309  ch->mid_futures = 0;
1310  else
1311  ch->mid_futures >>= delta;
1312  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1313  }
1315  return;
1316  }
1317  }
1318 
1319  if (GNUNET_YES == ch->reliable)
1320  {
1321  /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1322  mid_min = ntohl (ch->mid_recv.mid);
1323  mid_max = mid_min + ch->max_pending_messages;
1324  mid_msg = ntohl (msg->mid.mid);
1325  if (((uint32_t) (mid_msg - mid_min) > ch->max_pending_messages) ||
1326  ((uint32_t) (mid_max - mid_msg) > ch->max_pending_messages))
1327  {
1329  "%s at %u drops ancient or far-future message %u\n",
1330  GCCH_2s (ch),
1331  (unsigned int) mid_min,
1332  ntohl (msg->mid.mid));
1333 
1335  "# duplicate DATA (ancient or future)",
1336  1,
1337  GNUNET_NO);
1340  return;
1341  }
1342  /* mark bit for future ACKs */
1343  delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1344  if (delta < 64)
1345  {
1346  if (0 != (ch->mid_futures & (1LLU << delta)))
1347  {
1348  /* Duplicate within the queue, drop also */
1350  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1351  (unsigned int) payload_size,
1352  GCCH_2s (ch),
1353  ntohl (msg->mid.mid));
1354  GNUNET_STATISTICS_update (stats, "# duplicate DATA", 1, GNUNET_NO);
1357  return;
1358  }
1359  ch->mid_futures |= (1LLU << delta);
1361  "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1362  (1LLU << delta),
1363  mid_msg,
1364  mid_min,
1365  (unsigned long long) ch->mid_futures);
1366  }
1367  }
1368  else /* ! ch->reliable */
1369  {
1370  struct CadetOutOfOrderMessage *next_msg;
1371 
1376  if ((NULL != ccc->head_recv) && (GNUNET_YES == ccc->client_ready))
1377  {
1378  next_msg = ccc->head_recv;
1380  "Giving queued MID %u from %s to client %s\n",
1381  ntohl (next_msg->mid.mid),
1382  GCCH_2s (ch),
1383  GSC_2s (ccc->c));
1384  ccc->client_ready = GNUNET_NO;
1385  GSC_send_to_client (ccc->c, next_msg->env);
1386  ch->mid_recv.mid = htonl (1 + ntohl (next_msg->mid.mid));
1387  ch->mid_futures >>= 1;
1389  GNUNET_CONTAINER_DLL_remove (ccc->head_recv, ccc->tail_recv, next_msg);
1390  ccc->num_recv--;
1391  /* Do not process duplicate MID */
1392  if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
1393  {
1394  /* Duplicate within the queue, drop */
1396  "Message on %s (mid %u) dropped, duplicate\n",
1397  GCCH_2s (ch),
1398  ntohl (msg->mid.mid));
1399  GNUNET_free (next_msg);
1401  return;
1402  }
1403  GNUNET_free (next_msg);
1404  }
1405 
1406  if (ntohl (msg->mid.mid) < ntohl (ch->mid_recv.mid)) /* Old */
1407  {
1408  /* Duplicate within the queue, drop */
1410  "Message on %s (mid %u) dropped, old.\n",
1411  GCCH_2s (ch),
1412  ntohl (msg->mid.mid));
1414  return;
1415  }
1416 
1417  /* Channel is unreliable, so we do not ACK. But we also cannot
1418  allow buffering everything, so check if we have space... */
1419  if (ccc->num_recv >= ch->max_pending_messages)
1420  {
1421  struct CadetOutOfOrderMessage *drop;
1422 
1423  /* Yep, need to drop. Drop the oldest message in
1424  the buffer. */
1426  "Queue full due slow client on %s, dropping oldest message\n",
1427  GCCH_2s (ch));
1429  "# messages dropped due to slow client",
1430  1,
1431  GNUNET_NO);
1432  drop = ccc->head_recv;
1433  GNUNET_assert (NULL != drop);
1434  GNUNET_CONTAINER_DLL_remove (ccc->head_recv, ccc->tail_recv, drop);
1435  ccc->num_recv--;
1436  GNUNET_MQ_discard (drop->env);
1437  GNUNET_free (drop);
1438  }
1439  }
1440 
1441  /* Insert message into sorted out-of-order queue */
1442  com = GNUNET_new (struct CadetOutOfOrderMessage);
1443  com->mid = msg->mid;
1444  com->env = env;
1445  duplicate = GNUNET_NO;
1447  is_before,
1448  &duplicate,
1449  ccc->head_recv,
1450  ccc->tail_recv,
1451  com);
1452  ccc->num_recv++;
1453  if (GNUNET_YES == duplicate)
1454  {
1455  /* Duplicate within the queue, drop also (this is not covered by
1456  the case above if "delta" >= 64, which could be the case if
1457  max_pending_messages is also >= 64 or if our client is unready
1458  and we are seeing retransmissions of the message our client is
1459  blocked on. */LOG (GNUNET_ERROR_TYPE_DEBUG,
1460  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1461  (unsigned int) payload_size,
1462  GCCH_2s (ch),
1463  ntohl (msg->mid.mid));
1464  GNUNET_STATISTICS_update (stats, "# duplicate DATA", 1, GNUNET_NO);
1466  ccc->num_recv--;
1467  GNUNET_MQ_discard (com->env);
1468  GNUNET_free (com);
1470  return;
1471  }
1473  "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1474  (GNUNET_YES == ccc->client_ready) ? "out-of-order" : "client-not-ready",
1475  (unsigned int) payload_size,
1476  GCCH_2s (ch),
1477  ntohl (ccc->ccn.channel_of_client),
1478  ccc,
1479  ntohl (msg->mid.mid),
1480  ntohl (ch->mid_recv.mid));
1481  /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1482  the sender may already be transmitting the previous one. Needs
1483  experimental evaluation to see if/when this ACK helps or
1484  hurts. (We might even want another option.) */
1486 }
1487 
1488 
1499 static void
1500 data_sent_cb (void *cls,
1501  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
1502 
1503 
1510 static void
1512 {
1513  struct CadetChannel *ch = cls;
1514  struct CadetReliableMessage *crm = ch->head_sent;
1515 
1516  ch->retry_data_task = NULL;
1517  GNUNET_assert (NULL == crm->qe);
1519  "Retrying transmission on %s of message %u\n",
1520  GCCH_2s (ch),
1521  (unsigned int) ntohl (crm->data_message->mid.mid));
1522  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm,
1523  &crm->data_message->ctn);
1524  GNUNET_assert (NULL == ch->retry_data_task);
1525 }
1526 
1527 
1536 static void
1538  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1539  struct CadetReliableMessage *crm)
1540 {
1541  GNUNET_CONTAINER_DLL_remove (ch->head_sent, ch->tail_sent, crm);
1542  ch->pending_messages--;
1543  GNUNET_assert (ch->pending_messages < ch->max_pending_messages);
1545  "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1546  GCCH_2s (ch),
1547  (unsigned int) ntohl (crm->data_message->mid.mid),
1548  ch->pending_messages);
1549  if (NULL != crm->qe)
1550  {
1551  GCT_send_cancel (crm->qe);
1552  crm->qe = NULL;
1553  }
1554  if ((1 == crm->num_transmissions) && (NULL != cti))
1555  {
1556  GCC_ack_observed (cti);
1557  if (0 == GNUNET_memcmp (cti, &crm->connection_taken))
1558  {
1559  GCC_latency_observed (cti,
1561  crm->first_transmission_time));
1562  }
1563  }
1564  GNUNET_free (crm->data_message);
1565  GNUNET_free (crm);
1566  send_ack_to_client (ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1567 }
1568 
1569 
1578 void
1580  struct CadetChannel *ch,
1581  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1582  const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1583 {
1584  struct CadetReliableMessage *crm;
1585  struct CadetReliableMessage *crmn;
1586  int found;
1587  uint32_t mid_base;
1588  uint64_t mid_mask;
1589  unsigned int delta;
1590 
1591  GNUNET_break (GNUNET_NO == ch->is_loopback);
1592  if (GNUNET_NO == ch->reliable)
1593  {
1594  /* not expecting ACKs on unreliable channel, odd */
1595  GNUNET_break_op (0);
1596  return;
1597  }
1598  /* mid_base is the MID of the next message that the
1599  other peer expects (i.e. that is missing!), everything
1600  LOWER (but excluding mid_base itself) was received. */
1601  mid_base = ntohl (ack->mid.mid);
1602  mid_mask = GNUNET_htonll (ack->futures);
1603  found = GNUNET_NO;
1604  for (crm = ch->head_sent; NULL != crm; crm = crmn)
1605  {
1606  crmn = crm->next;
1607  delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base);
1608  if (delta >= UINT_MAX - ch->max_pending_messages)
1609  {
1610  /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1612  "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1613  (unsigned int) mid_base,
1614  ntohl (crm->data_message->mid.mid),
1615  GCCH_2s (ch));
1616  handle_matching_ack (ch, cti, crm);
1617  found = GNUNET_YES;
1618  continue;
1619  }
1620  delta--;
1621  if (delta >= 64)
1622  continue;
1624  "Testing bit %llX for mid %u (base: %u)\n",
1625  (1LLU << delta),
1626  ntohl (crm->data_message->mid.mid),
1627  mid_base);
1628  if (0 != (mid_mask & (1LLU << delta)))
1629  {
1631  "Got DATA_ACK with mask for %u on %s\n",
1632  ntohl (crm->data_message->mid.mid),
1633  GCCH_2s (ch));
1634  handle_matching_ack (ch, cti, crm);
1635  found = GNUNET_YES;
1636  }
1637  }
1638  if (GNUNET_NO == found)
1639  {
1640  /* ACK for message we already dropped, might have been a
1641  duplicate ACK? Ignore. */
1643  "Duplicate DATA_ACK on %s, ignoring\n",
1644  GCCH_2s (ch));
1645  GNUNET_STATISTICS_update (stats, "# duplicate DATA_ACKs", 1, GNUNET_NO);
1646  return;
1647  }
1648  if (NULL != ch->retry_data_task)
1649  {
1650  GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1651  ch->retry_data_task = NULL;
1652  }
1653  if ((NULL != ch->head_sent) && (NULL == ch->head_sent->qe))
1654  ch->retry_data_task = GNUNET_SCHEDULER_add_at (ch->head_sent->next_retry,
1656  ch);
1657 }
1658 
1659 
1669 void
1671  struct CadetChannel *ch,
1672  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
1673 {
1674  struct CadetChannelClient *ccc;
1675 
1676  GNUNET_assert (GNUNET_NO == ch->is_loopback);
1678  "Received remote channel DESTROY for %s\n",
1679  GCCH_2s (ch));
1680  if (GNUNET_YES == ch->destroy)
1681  {
1682  /* Local client already gone, this is instant-death. */
1683  channel_destroy (ch);
1684  return;
1685  }
1686  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1687  if ((NULL != ccc) && (NULL != ccc->head_recv))
1688  {
1690  "Lost end of transmission due to remote shutdown on %s\n",
1691  GCCH_2s (ch));
1692  /* FIXME: change API to notify client about truncated transmission! */
1693  }
1694  ch->destroy = GNUNET_YES;
1695  if (NULL != ccc)
1696  GSC_handle_remote_channel_destroy (ccc->c, ccc->ccn, ch);
1697  channel_destroy (ch);
1698 }
1699 
1700 
1709 static int
1711  struct CadetReliableMessage *crm1,
1712  struct CadetReliableMessage *crm2)
1713 {
1714  if (crm1->next_retry.abs_value_us < crm2->next_retry.abs_value_us)
1715  return GNUNET_YES;
1716  return GNUNET_NO;
1717 }
1718 
1719 
1730 static void
1731 data_sent_cb (void *cls,
1732  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1733 {
1734  struct CadetReliableMessage *crm = cls;
1735  struct CadetChannel *ch = crm->ch;
1736 
1737  GNUNET_assert (GNUNET_NO == ch->is_loopback);
1738  GNUNET_assert (NULL != crm->qe);
1739  crm->qe = NULL;
1740  GNUNET_CONTAINER_DLL_remove (ch->head_sent, ch->tail_sent, crm);
1741  if (GNUNET_NO == ch->reliable)
1742  {
1743  GNUNET_free (crm->data_message);
1744  GNUNET_free (crm);
1745  ch->pending_messages--;
1746  send_ack_to_client (ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1747  return;
1748  }
1749  if (NULL == cid)
1750  {
1751  /* There was an error sending. */
1753  }
1754  else if (GNUNET_SYSERR != crm->num_transmissions)
1755  {
1756  /* Increment transmission counter, and possibly store @a cid
1757  if this was the first transmission. */
1758  crm->num_transmissions++;
1759  if (1 == crm->num_transmissions)
1760  {
1762  crm->connection_taken = *cid;
1763  GCC_ack_expected (cid);
1764  }
1765  }
1766  if ((0 == crm->retry_delay.rel_value_us) && (NULL != cid))
1767  {
1768  struct CadetConnection *cc = GCC_lookup (cid);
1769 
1770  if (NULL != cc)
1772  else
1773  crm->retry_delay = ch->retry_time;
1774  }
1778 
1781  NULL,
1782  ch->head_sent,
1783  ch->tail_sent,
1784  crm);
1786  "Message %u sent, next transmission on %s in %s\n",
1787  (unsigned int) ntohl (crm->data_message->mid.mid),
1788  GCCH_2s (ch),
1791  ch->head_sent->next_retry),
1792  GNUNET_YES));
1793  if (NULL == ch->head_sent->qe)
1794  {
1795  if (NULL != ch->retry_data_task)
1796  GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1797  ch->retry_data_task = GNUNET_SCHEDULER_add_at (ch->head_sent->next_retry,
1799  ch);
1800  }
1801 }
1802 
1803 
1818 int
1820  struct GNUNET_CADET_ClientChannelNumber sender_ccn,
1821  const char *buf,
1822  size_t buf_len)
1823 {
1824  struct CadetReliableMessage *crm;
1825 
1826  if (ch->pending_messages >= ch->max_pending_messages)
1827  {
1828  GNUNET_break (0); /* Fails: #5370 */
1829  return GNUNET_SYSERR;
1830  }
1831  if (GNUNET_YES == ch->destroy)
1832  {
1833  /* we are going down, drop messages */
1834  return GNUNET_OK;
1835  }
1836  ch->pending_messages++;
1837 
1838  if (GNUNET_YES == ch->is_loopback)
1839  {
1840  struct CadetChannelClient *receiver;
1841  struct GNUNET_MQ_Envelope *env;
1842  struct GNUNET_CADET_LocalData *ld;
1843  int ack_to_owner;
1844 
1845  env =
1847  if ((NULL != ch->owner) &&
1848  (sender_ccn.channel_of_client == ch->owner->ccn.channel_of_client))
1849  {
1850  receiver = ch->dest;
1851  ack_to_owner = GNUNET_YES;
1852  }
1853  else if ((NULL != ch->dest) &&
1854  (sender_ccn.channel_of_client == ch->dest->ccn.channel_of_client))
1855  {
1856  receiver = ch->owner;
1857  ack_to_owner = GNUNET_NO;
1858  }
1859  else
1860  {
1861  GNUNET_free (env);
1862  GNUNET_break (0);
1863  return GNUNET_SYSERR;
1864  }
1865  GNUNET_assert (NULL != receiver);
1866  ld->ccn = receiver->ccn;
1867  GNUNET_memcpy (&ld[1], buf, buf_len);
1868  if (GNUNET_YES == receiver->client_ready)
1869  {
1870  ch->pending_messages--;
1872  send_ack_to_client (ch, ack_to_owner);
1873  }
1874  else
1875  {
1876  struct CadetOutOfOrderMessage *oom;
1877 
1878  oom = GNUNET_new (struct CadetOutOfOrderMessage);
1879  oom->env = env;
1881  receiver->tail_recv,
1882  oom);
1883  receiver->num_recv++;
1884  }
1885  return GNUNET_OK;
1886  }
1887 
1888  /* Everything is correct, send the message. */
1889  crm = GNUNET_malloc (sizeof(*crm));
1890  crm->ch = ch;
1891  crm->data_message = GNUNET_malloc (
1892  sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1893  crm->data_message->header.size =
1894  htons (sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1895  crm->data_message->header.type =
1897  ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1898  crm->data_message->mid = ch->mid_send;
1899  crm->data_message->ctn = ch->ctn;
1900  GNUNET_memcpy (&crm->data_message[1], buf, buf_len);
1901  GNUNET_CONTAINER_DLL_insert_tail (ch->head_sent, ch->tail_sent, crm);
1903  "Sending message %u from local client to %s with %lu bytes\n",
1904  ntohl (crm->data_message->mid.mid),
1905  GCCH_2s (ch),
1906  (unsigned long) buf_len);
1907  if (NULL != ch->retry_data_task)
1908  {
1909  GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1910  ch->retry_data_task = NULL;
1911  }
1912  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm,
1913  &crm->data_message->ctn);
1914  GNUNET_assert (NULL == ch->retry_data_task);
1915  return GNUNET_OK;
1916 }
1917 
1918 
1926 void
1928  struct GNUNET_CADET_ClientChannelNumber client_ccn)
1929 {
1930  struct CadetChannelClient *ccc;
1931  struct CadetOutOfOrderMessage *com;
1932 
1933  if ((NULL != ch->owner) &&
1934  (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client))
1935  ccc = ch->owner;
1936  else if ((NULL != ch->dest) &&
1937  (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client))
1938  ccc = ch->dest;
1939  else
1940  GNUNET_assert (0);
1941  ccc->client_ready = GNUNET_YES;
1942  com = ccc->head_recv;
1943  if (NULL == com)
1944  {
1946  "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
1947  GSC_2s (ccc->c),
1948  ntohl (client_ccn.channel_of_client),
1949  GCCH_2s (ch),
1950  ntohl (ccc->ccn.channel_of_client),
1951  ccc);
1952  return; /* none pending */
1953  }
1954  if (GNUNET_YES == ch->is_loopback)
1955  {
1956  int to_owner;
1957 
1958  /* Messages are always in-order, just send */
1960  ccc->num_recv--;
1961  GSC_send_to_client (ccc->c, com->env);
1962  /* Notify sender that we can receive more */
1963  if ((NULL != ch->owner) &&
1964  (ccc->ccn.channel_of_client == ch->owner->ccn.channel_of_client))
1965  {
1966  to_owner = GNUNET_NO;
1967  }
1968  else
1969  {
1970  GNUNET_assert ((NULL != ch->dest) && (ccc->ccn.channel_of_client ==
1971  ch->dest->ccn.channel_of_client));
1972  to_owner = GNUNET_YES;
1973  }
1974  send_ack_to_client (ch, to_owner);
1975  GNUNET_free (com);
1976  return;
1977  }
1978 
1979  if ((com->mid.mid != ch->mid_recv.mid) && (GNUNET_NO == ch->out_of_order) &&
1980  (GNUNET_YES == ch->reliable))
1981  {
1983  "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
1984  GSC_2s (ccc->c),
1985  ntohl (ccc->ccn.channel_of_client),
1986  ntohl (com->mid.mid),
1987  ntohl (ch->mid_recv.mid));
1988  return; /* missing next one in-order */
1989  }
1990 
1992  "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
1993  ntohl (com->mid.mid),
1994  GSC_2s (ccc->c),
1995  ntohl (ccc->ccn.channel_of_client),
1996  GCCH_2s (ch));
1997 
1998  /* all good, pass next message to client */
2000  ccc->num_recv--;
2001  /* FIXME: if unreliable, this is not aggressive
2002  enough, as it would be OK to have lost some! */
2003 
2004  ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
2005  ch->mid_futures >>= 1; /* equivalent to division by 2 */
2006  ccc->client_ready = GNUNET_NO;
2007  GSC_send_to_client (ccc->c, com->env);
2008  GNUNET_free (com);
2010  if (NULL != ccc->head_recv)
2011  return;
2012  if (GNUNET_NO == ch->destroy)
2013  return;
2014  GCT_send_channel_destroy (ch->t, ch->ctn);
2015  channel_destroy (ch);
2016 }
2017 
2018 
2019 #define LOG2(level, ...) \
2020  GNUNET_log_from_nocheck (level, "cadet-chn", __VA_ARGS__)
2021 
2022 
2029 void
2031 {
2032 #if ! defined(GNUNET_CULL_LOGGING)
2033  int do_log;
2034 
2036  "cadet-chn",
2037  __FILE__,
2038  __FUNCTION__,
2039  __LINE__);
2040  if (0 == do_log)
2041  return;
2042 
2043  if (NULL == ch)
2044  {
2045  LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
2046  return;
2047  }
2048  LOG2 (level, "CHN %s:%X (%p)\n", GCT_2s (ch->t), ch->ctn.cn, ch);
2049  if (NULL != ch->owner)
2050  {
2051  LOG2 (level,
2052  "CHN origin %s ready %s local-id: %u\n",
2053  GSC_2s (ch->owner->c),
2054  ch->owner->client_ready ? "YES" : "NO",
2055  ntohl (ch->owner->ccn.channel_of_client));
2056  }
2057  if (NULL != ch->dest)
2058  {
2059  LOG2 (level,
2060  "CHN destination %s ready %s local-id: %u\n",
2061  GSC_2s (ch->dest->c),
2062  ch->dest->client_ready ? "YES" : "NO",
2063  ntohl (ch->dest->ccn.channel_of_client));
2064  }
2065  LOG2 (level,
2066  "CHN Message IDs recv: %d (%llX), send: %d\n",
2067  ntohl (ch->mid_recv.mid),
2068  (unsigned long long) ch->mid_futures,
2069  ntohl (ch->mid_send.mid));
2070 #endif
2071 }
2072 
2073 
2074 /* end of gnunet-service-cadet_channel.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_CADET_LOCAL_CHANNEL_ID_CLI
Minimum value for channel IDs of local clients.
Definition: cadet.h:71
#define INT_MAX
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static uint16_t port
Port number.
Definition: gnunet-bcd.c:83
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
void GSC_handle_remote_channel_destroy(struct CadetClient *c, struct GNUNET_CADET_ClientChannelNumber ccn, struct CadetChannel *ch)
A channel was destroyed by the other peer.
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
void GSC_send_to_client(struct CadetClient *c, struct GNUNET_MQ_Envelope *env)
Send a message to a client.
struct GNUNET_CONTAINER_MultiHashMap * open_ports
All ports clients of this peer have opened.
struct GNUNET_CADET_ClientChannelNumber GSC_bind(struct CadetClient *c, struct CadetChannel *ch, struct CadetPeer *dest, const struct GNUNET_HashCode *port, uint32_t options)
Bind incoming channel to this client, and notify client about incoming connection.
struct GNUNET_CONTAINER_MultiHashMap * loose_channels
Map from ports to channels where the ports were closed at the time we got the inbound connection.
void GSC_drop_loose_channel(const struct GNUNET_HashCode *h_port, struct CadetChannel *ch)
A client that created a loose channel that was not bound to a port disconnected, drop it from the loo...
void GCCH_handle_channel_plaintext_data_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We got an acknowledgement for payload data for a channel.
static void send_channel_data_ack(struct CadetChannel *ch)
Compute and send the current GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer.
static void handle_matching_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, struct CadetReliableMessage *crm)
We got an PLAINTEXT_DATA_ACK for a message in our queue, remove it from the queue and tell our client...
static void free_channel_client(struct CadetChannelClient *ccc)
Release memory associated with ccc.
static void channel_destroy(struct CadetChannel *ch)
Destroy the given channel.
CadetChannelState
All the states a channel can be in.
@ CADET_CHANNEL_NEW
Uninitialized status, should never appear in operation.
@ CADET_CHANNEL_OPEN_SENT
CHANNEL_OPEN message sent, waiting for CHANNEL_OPEN_ACK.
@ CADET_CHANNEL_READY
Connection confirmed, ready to carry traffic.
@ CADET_CHANNEL_LOOSE
Channel is to a port that is not open, we're waiting for the port to be opened.
#define LOG2(level,...)
static void send_open_ack(void *cls)
Send our initial GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the connect...
int GCCH_handle_local_data(struct CadetChannel *ch, struct GNUNET_CADET_ClientChannelNumber sender_ccn, const char *buf, size_t buf_len)
Handle data given by a client.
static int cmp_crm_by_next_retry(void *cls, struct CadetReliableMessage *crm1, struct CadetReliableMessage *crm2)
Test if element e1 comes before element e2.
static void channel_open_sent_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel confirms that we sent the create message.
static void send_ack_to_client(struct CadetChannel *ch, int to_owner)
Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
void GCCH_bind(struct CadetChannel *ch, struct CadetClient *c, const struct GNUNET_HashCode *port)
A client is bound to the port that we have a channel open to.
void GCCH_handle_duplicate_open(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
We got a GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for this channel.
static void send_ack_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel confirms that we sent the ACK message.
void GCCH_handle_local_ack(struct CadetChannel *ch, struct GNUNET_CADET_ClientChannelNumber client_ccn)
Handle ACK from client on local channel.
void GCCH_channel_local_destroy(struct CadetChannel *ch, struct CadetClient *c, struct GNUNET_CADET_ClientChannelNumber ccn)
Destroy locally created channel.
void GCCH_assign_type_to_drop(struct CadetChannel *ch, const struct GNUNET_CADET_RequestDropCadetMessage *message)
Assign type of message to drop.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
static void timeout_closed_cb(void *cls)
We had an incoming channel to a port that is closed.
#define CADET_INITIAL_RETRANSMIT_TIME
How long do we initially wait before retransmitting?
void GCCH_tunnel_up(struct CadetChannel *ch)
Function called once and only once after a channel was bound to its tunnel via GCT_add_channel() is r...
void GCCH_hash_port(struct GNUNET_HashCode *h_port, const struct GNUNET_HashCode *port, const struct GNUNET_PeerIdentity *listener)
Hash the port and initiator and listener to calculate the "challenge" h_port we send to the other pee...
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
static void send_channel_open(void *cls)
Send a channel create message.
static int is_before(void *cls, struct CadetOutOfOrderMessage *m1, struct CadetOutOfOrderMessage *m2)
Test if element e1 comes before element e2.
#define TIMEOUT_CLOSED_PORT
How long do we wait before dropping state about incoming connection to closed port?
struct CadetChannel * GCCH_channel_local_new(struct CadetClient *owner, struct GNUNET_CADET_ClientChannelNumber ccn, struct CadetPeer *destination, const struct GNUNET_HashCode *port, uint32_t options)
Create a new channel.
#define MIN_RTT_DELAY
How long do we wait at least before retransmitting ever?
#define LOG(level,...)
static void signal_remote_destroy_cb(void *cls)
One of our clients has disconnected, tell the other one that we are finished.
void GCCH_handle_channel_plaintext_data(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We got payload data for a channel.
static void data_sent_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel has sent one of our messages.
struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id(const struct CadetChannel *ch)
Get the channel's public ID.
struct CadetChannel * GCCH_channel_incoming_new(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn, const struct GNUNET_HashCode *h_port, uint32_t options)
Create a new channel based on a request coming in over the network.
static void retry_transmission(void *cls)
We need to retry a transmission, the last one took too long to be acknowledged.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
void GCCH_handle_channel_open_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_HashCode *port)
We got an acknowledgement for the creation of the channel (the port is open on the other side).
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
GNUnet CADET service with encryption.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
void GCC_latency_observed(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct GNUNET_TIME_Relative latency)
We observed some the given latency on the connection identified by cti.
struct CadetConnection * GCC_lookup(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Lookup a connection by its identifier.
void GCC_ack_observed(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
We observed an ACK for a message that was originally sent via the connection identified by cti.
void GCC_ack_expected(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
We sent a message for which we expect to receive an ACK via the connection identified by cti.
A connection is a live end-to-end messaging mechanism where the peers are identified by a path and kn...
struct CadetTunnel * GCP_get_tunnel(struct CadetPeer *cp, int create)
Get the tunnel towards a peer.
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.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
void GCT_remove_channel(struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Remove a channel from a tunnel.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel(struct CadetTunnel *t, struct CadetChannel *ch)
Add a channel to a tunnel, and notify channel that we are ready for transmission if we are already up...
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
Information we track per tunnel.
static char buf[2048]
static struct GNUNET_SCHEDULER_Task * t
Main task.
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_PACKED
gcc-ism to get packed structs.
#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE, comparator, comparator_cls, head, tail, element)
Insertion sort of element into DLL from head to tail sorted by comparator.
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:321
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
Definition: crypto_hash.c:340
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:364
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
GNUNET_ErrorType
Types of errors.
#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).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:323
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:52
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK
Local ACK for data.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA
Payload client <-> service.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1296
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:1246
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
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:1269
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_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:263
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:208
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:232
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:86
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:181
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:557
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
void receiver(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition: socks.c:329
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
Client endpoint of a struct CadetChannel.
struct CadetOutOfOrderMessage * head_recv
Head of DLL of messages received out of order or while client was unready.
struct CadetClient * c
Client handle.
struct CadetOutOfOrderMessage * tail_recv
Tail DLL of messages received out of order or while client was unready.
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
unsigned int num_recv
Number of entries currently in head_recv DLL.
int client_ready
Can we send data to the client?
Struct containing all information regarding a channel to a remote client.
struct CadetTunnel * t
Tunnel this channel is in.
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
unsigned int pending_messages
Total (reliable) messages pending ACK for this channel.
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct GNUNET_TIME_Absolute timestamp
Last time the channel was used.
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
struct CadetReliableMessage * tail_sent
Tail of DLL of messages sent and not yet ACK'd.
struct GNUNET_TIME_Relative retry_time
Counter for exponential backoff.
int nobuffer
Is the tunnel bufferless (minimum latency)?
struct GNUNET_HashCode port
Destination port of the channel.
uint16_t type
Type of message to be dropped.
int destroy
Flag to signal the destruction of the channel.
enum CadetChannelState state
Channel state.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
int reliable
Is the tunnel reliable?
struct ChannelMessageIdentifier mid_send
Next MID to use for outgoing traffic.
uint64_t mid_futures
Bitfield of already-received messages past mid_recv.
int out_of_order
Is the tunnel out-of-order?
struct GNUNET_HashCode h_port
Hash'ed port of the channel with initiator and destination PID.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
struct GNUNET_SCHEDULER_Task * retry_data_task
Task to resend/poll in case no ACK is received.
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
unsigned int skip_ack_series
Count how many ACKs we skipped, used to prevent long sequences of ACK skipping.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK'd.
struct CadetTunnelQueueEntry * last_control_qe
Last entry in the tunnel's queue relating to control messages (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN...
Struct containing information about a client of the service.
struct GNUNET_TIME_Relative aged_latency
Our current best estimate of the latency, based on a weighted average of at least latency_datapoints ...
Low-level connection to a destination.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
List of received out-of-order data messages.
struct ChannelMessageIdentifier mid
ID of the message (messages up to this point needed before we give this one to the client).
struct GNUNET_MQ_Envelope * env
The envelope with the payload of the out-of-order message.
struct CadetOutOfOrderMessage * next
Double linked list, FIFO style.
struct CadetOutOfOrderMessage * prev
Double linked list, FIFO style.
Peer description.
Info needed to retry a message in case it gets lost.
struct CadetTunnelQueueEntry * qe
Entry in the tunnels queue for this message, NULL if it has left the tunnel.
struct GNUNET_TIME_Absolute next_retry
How soon should we retry if we fail to get an ACK? Messages in the queue are sorted by this value.
struct CadetReliableMessage * next
Double linked list, FIFO style.
struct GNUNET_CADET_ChannelAppDataMessage * data_message
Data message we are trying to send.
struct GNUNET_CADET_ConnectionTunnelIdentifier connection_taken
Identifier of the connection that this message took when it was first transmitted.
struct CadetChannel * ch
Which channel is this message in?
struct GNUNET_TIME_Absolute first_transmission_time
Time when we first successfully transmitted the message (that is, set num_transmissions to 1).
struct CadetReliableMessage * prev
Double linked list, FIFO style.
int num_transmissions
How often was this message transmitted? GNUNET_SYSERR if there was an error transmitting the message,...
struct GNUNET_TIME_Relative retry_delay
How long do we wait for an ACK after transmission? Use for the back-off calculation.
Struct used to save messages in a non-ready tunnel to send once connected.
Struct containing all information regarding a tunnel to a peer.
Number used to uniquely identify messages in a CADET Channel.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
Message for cadet data traffic.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
Message to acknowledge end-to-end data.
struct ChannelMessageIdentifier mid
Next message ID expected.
uint64_t futures
Bitfield of already-received newer messages.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
Message to create a Channel.
struct GNUNET_HashCode h_port
Hash of destination port and listener.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel within the tunnel.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN.
uint32_t opt
Channel options.
Number identifying a CADET channel within a tunnel.
struct GNUNET_CADET_ClientChannelNumber ccn
Local ID of the channel, GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
Definition: cadet.h:170
Number uniquely identifying a channel of a client.
Definition: cadet.h:102
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
Hash uniquely identifying a connection below a tunnel.
Message to allow the client send more data to the service (always service -> client).
Definition: cadet.h:281
struct GNUNET_CADET_ClientChannelNumber ccn
ID of the channel allowed to send more data.
Definition: cadet.h:290
Message for cadet data traffic.
Definition: cadet.h:253
struct GNUNET_CADET_ClientChannelNumber ccn
ID of the channel.
Definition: cadet.h:262
Message to drop another message of specific type.
Definition: cadet.h:322
uint16_t type
Type of the message this handler covers, in host byte order.
Definition: cadet.h:332
A 512-bit hashcode.
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.
uint64_t rel_value_us
The actual value.
Port opened by a client.
struct GNUNET_HashCode h_port
Port hashed with our PID (matches incoming OPEN messages).