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 
298  struct GNUNET_TIME_Absolute timestamp;
299 
304 
308  struct GNUNET_HashCode h_port;
309 
313  struct GNUNET_TIME_Relative retry_time;
314 
318  uint64_t mid_futures;
319 
323  struct ChannelMessageIdentifier mid_recv;
324 
328  struct ChannelMessageIdentifier mid_send;
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
398 {
399 
400  ch->type = message->type;
401 
402 }
403 
409 int
411 {
412 
413  if (ch->type == message->type)
414  {
415  ch->type = 0;
416  return GNUNET_YES;
417  }
418  else
419  return GNUNET_NO;
420 }
421 
429 const char *
430 GCCH_2s (const struct CadetChannel *ch)
431 {
432  static char buf[128];
433 
434  GNUNET_snprintf (buf,
435  sizeof(buf),
436  "Channel %s:%s ctn:%X(%X/%X)",
437  (GNUNET_YES == ch->is_loopback)
438  ? "loopback"
440  GNUNET_h2s (&ch->port),
441  ch->ctn,
442  (NULL == ch->owner)
443  ? 0
444  : ntohl (ch->owner->ccn.channel_of_client),
445  (NULL == ch->dest)
446  ? 0
447  : ntohl (ch->dest->ccn.channel_of_client));
448  return buf;
449 }
450 
451 
461 void
463  const struct GNUNET_HashCode *port,
464  const struct GNUNET_PeerIdentity *listener)
465 {
466  struct GNUNET_HashContext *hc;
467 
469  GNUNET_CRYPTO_hash_context_read (hc, port, sizeof(*port));
470  GNUNET_CRYPTO_hash_context_read (hc, listener, sizeof(*listener));
473  "Calculated port hash %s\n",
474  GNUNET_h2s (h_port));
475 }
476 
477 
486 GCCH_get_id (const struct CadetChannel *ch)
487 {
488  return ch->ctn;
489 }
490 
491 
497 static void
499 {
500  struct CadetOutOfOrderMessage *com;
501 
502  while (NULL != (com = ccc->head_recv))
503  {
505  ccc->num_recv--;
506  GNUNET_MQ_discard (com->env);
507  GNUNET_free (com);
508  }
509  GNUNET_free (ccc);
510 }
511 
512 
518 static void
520 {
521  struct CadetReliableMessage *crm;
522 
523  while (NULL != (crm = ch->head_sent))
524  {
525  GNUNET_assert (ch == crm->ch);
526  if (NULL != crm->qe)
527  {
528  GCT_send_cancel (crm->qe);
529  crm->qe = NULL;
530  }
532  GNUNET_free (crm->data_message);
533  GNUNET_free (crm);
534  }
535  if (CADET_CHANNEL_LOOSE == ch->state)
536  {
537  GSC_drop_loose_channel (&ch->h_port, ch);
538  }
539  if (NULL != ch->owner)
540  {
542  ch->owner = NULL;
543  }
544  if (NULL != ch->dest)
545  {
547  ch->dest = NULL;
548  }
549  if (NULL != ch->last_control_qe)
550  {
552  ch->last_control_qe = NULL;
553  }
554  if (NULL != ch->retry_data_task)
555  {
557  ch->retry_data_task = NULL;
558  }
559  if (NULL != ch->retry_control_task)
560  {
562  ch->retry_control_task = NULL;
563  }
564  if (GNUNET_NO == ch->is_loopback)
565  {
566  GCT_remove_channel (ch->t, ch, ch->ctn);
567  ch->t = NULL;
568  }
569  GNUNET_free (ch);
570 }
571 
572 
578 static void
579 send_channel_open (void *cls);
580 
581 
590 static void
592  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
593 {
594  struct CadetChannel *ch = cls;
595 
596  GNUNET_assert (NULL != ch->last_control_qe);
597  ch->last_control_qe = NULL;
600  "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
601  GCCH_2s (ch),
603  ch->retry_control_task =
605 }
606 
607 
613 static void
614 send_channel_open (void *cls)
615 {
616  struct CadetChannel *ch = cls;
617  struct GNUNET_CADET_ChannelOpenMessage msgcc;
618 
619  ch->retry_control_task = NULL;
621  "Sending CHANNEL_OPEN message for %s\n",
622  GCCH_2s (ch));
623  msgcc.header.size = htons (sizeof(msgcc));
625  // 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.
626  msgcc.opt = 2;
627  msgcc.h_port = ch->h_port;
628  msgcc.ctn = ch->ctn;
630  if (NULL != ch->last_control_qe)
632  ch->last_control_qe =
633  GCT_send (ch->t, &msgcc.header, &channel_open_sent_cb, ch, &msgcc.ctn);
634  GNUNET_assert (NULL == ch->retry_control_task);
635 }
636 
637 
648 void
650 {
651  GNUNET_assert (NULL == ch->retry_control_task);
653  "Tunnel up, sending CHANNEL_OPEN on %s now\n",
654  GCCH_2s (ch));
656 }
657 
658 
669 struct CadetChannel *
672  struct CadetPeer *destination,
673  const struct GNUNET_HashCode *port,
674  uint32_t options)
675 {
676  struct CadetChannel *ch;
677  struct CadetChannelClient *ccco;
678 
679  ccco = GNUNET_new (struct CadetChannelClient);
680  ccco->c = owner;
681  ccco->ccn = ccn;
682  ccco->client_ready = GNUNET_YES;
683 
684  ch = GNUNET_new (struct CadetChannel);
685  ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */
686  ch->nobuffer = GNUNET_NO;
687  ch->reliable = GNUNET_YES;
688  ch->out_of_order = GNUNET_NO;
690  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
691  ch->owner = ccco;
692  ch->port = *port;
693  GCCH_hash_port (&ch->h_port, port, GCP_get_id (destination));
694  if (0 == GNUNET_memcmp (&my_full_id, GCP_get_id (destination)))
695  {
696  struct OpenPort *op;
697 
698  ch->is_loopback = GNUNET_YES;
700  if (NULL == op)
701  {
702  /* port closed, wait for it to possibly open */
706  &ch->h_port,
707  ch,
710  "Created loose incoming loopback channel to port %s\n",
711  GNUNET_h2s (&ch->port));
712  }
713  else
714  {
715  GCCH_bind (ch, op->c, &op->port);
716  }
717  }
718  else
719  {
720  ch->t = GCP_get_tunnel (destination, GNUNET_YES);
722  ch->ctn = GCT_add_channel (ch->t, ch);
723  }
724  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
726  "Created channel to port %s at peer %s for %s using %s\n",
727  GNUNET_h2s (port),
728  GCP_2s (destination),
729  GSC_2s (owner),
730  (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
731  return ch;
732 }
733 
734 
741 static void
742 timeout_closed_cb (void *cls)
743 {
744  struct CadetChannel *ch = cls;
745 
746  ch->retry_control_task = NULL;
748  "Closing incoming channel to port %s from peer %s due to timeout\n",
749  GNUNET_h2s (&ch->port),
750  GCP_2s (GCT_get_destination (ch->t)));
751  channel_destroy (ch);
752 }
753 
754 
764 struct CadetChannel *
767  const struct GNUNET_HashCode *h_port,
768  uint32_t options)
769 {
770  struct CadetChannel *ch;
771  struct OpenPort *op;
772 
773  ch = GNUNET_new (struct CadetChannel);
774  ch->h_port = *h_port;
775  ch->t = t;
776  ch->ctn = ctn;
778  ch->nobuffer = GNUNET_NO;
779  ch->reliable = GNUNET_YES;
780  ch->out_of_order = GNUNET_NO;
782  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
783  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
784 
786  if (NULL == op)
787  {
788  /* port closed, wait for it to possibly open */
792  &ch->h_port,
793  ch,
795  GNUNET_assert (NULL == ch->retry_control_task);
798  ch);
800  "Created loose incoming channel to port %s from peer %s\n",
801  GNUNET_h2s (&ch->port),
802  GCP_2s (GCT_get_destination (ch->t)));
803  }
804  else
805  {
806  GCCH_bind (ch, op->c, &op->port);
807  }
808  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
809  return ch;
810 }
811 
812 
822 static void
823 send_ack_cb (void *cls,
824  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
825 {
826  struct CadetChannel *ch = cls;
827 
828  GNUNET_assert (NULL != ch->last_control_qe);
829  ch->last_control_qe = NULL;
830 }
831 
832 
838 static void
840 {
842 
843  if (GNUNET_NO == ch->reliable)
844  return; /* no ACKs */
846  msg.header.size = htons (sizeof(msg));
847  msg.ctn = ch->ctn;
848  msg.mid.mid = htonl (ntohl (ch->mid_recv.mid));
849  msg.futures = GNUNET_htonll (ch->mid_futures);
851  "Sending DATA_ACK %u:%llX via %s\n",
852  (unsigned int) ntohl (msg.mid.mid),
853  (unsigned long long) ch->mid_futures,
854  GCCH_2s (ch));
855  if (NULL != ch->last_control_qe)
857  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch, &msg.ctn);
858 }
859 
860 
867 static void
868 send_open_ack (void *cls)
869 {
870  struct CadetChannel *ch = cls;
872 
873  ch->retry_control_task = NULL;
875  "Sending CHANNEL_OPEN_ACK on %s\n",
876  GCCH_2s (ch));
878  msg.header.size = htons (sizeof(msg));
879  msg.reserved = htonl (0);
880  msg.ctn = ch->ctn;
881  msg.port = ch->port;
882  if (NULL != ch->last_control_qe)
884  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch, &msg.ctn);
885 }
886 
887 
896 void
898  struct CadetChannel *ch,
899  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
900 {
901  if (NULL == ch->dest)
902  {
904  "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
905  GCCH_2s (ch));
906  return;
907  }
908  if (NULL != ch->retry_control_task)
909  {
911  "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
912  GCCH_2s (ch));
913  return;
914  }
916  "Retransmitting CHANNEL_OPEN_ACK on %s\n",
917  GCCH_2s (ch));
919 }
920 
921 
929 static void
930 send_ack_to_client (struct CadetChannel *ch, int to_owner)
931 {
932  struct GNUNET_MQ_Envelope *env;
933  struct GNUNET_CADET_LocalAck *ack;
934  struct CadetChannelClient *ccc;
935 
936  ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
937  if (NULL == ccc)
938  {
939  /* This can happen if we are just getting ACKs after
940  our local client already disconnected. */
942  return;
943  }
945  ack->ccn = ccc->ccn;
947  "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X (%u/%u pending)\n",
948  GSC_2s (ccc->c),
949  (GNUNET_YES == to_owner) ? "owner" : "dest",
950  ntohl (ack->ccn.channel_of_client),
951  ch->pending_messages,
953  GSC_send_to_client (ccc->c, env);
954 }
955 
956 
966 void
968  struct CadetClient *c,
969  const struct GNUNET_HashCode *port)
970 {
971  uint32_t options;
972  struct CadetChannelClient *cccd;
973 
975  "Binding %s from %s to port %s of %s\n",
976  GCCH_2s (ch),
977  GCT_2s (ch->t),
978  GNUNET_h2s (&ch->port),
979  GSC_2s (c));
980  if (NULL != ch->retry_control_task)
981  {
982  /* there might be a timeout task here */
984  ch->retry_control_task = NULL;
985  }
986  options = 0;
987  cccd = GNUNET_new (struct CadetChannelClient);
988  GNUNET_assert (NULL == ch->dest);
989  ch->dest = cccd;
990  ch->port = *port;
991  cccd->c = c;
992  cccd->client_ready = GNUNET_YES;
993  cccd->ccn = GSC_bind (c,
994  ch,
995  (GNUNET_YES == ch->is_loopback)
997  : GCT_get_destination (ch->t),
998  port,
999  options);
1000  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1002  ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */
1003  if (GNUNET_YES == ch->is_loopback)
1004  {
1006  GCCH_handle_channel_open_ack (ch, NULL, port);
1007  }
1008  else
1009  {
1010  /* notify other peer that we accepted the connection */
1011  ch->state = CADET_CHANNEL_READY;
1013  }
1014  /* give client it's initial supply of ACKs */
1015  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1017  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1019 }
1020 
1021 
1029 static void
1031 {
1032  struct CadetChannel *ch = cls;
1033  struct CadetChannelClient *ccc;
1034 
1035  /* Find which end is left... */
1036  ch->retry_control_task = NULL;
1037  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1038  GSC_handle_remote_channel_destroy (ccc->c, ccc->ccn, ch);
1039  channel_destroy (ch);
1040 }
1041 
1042 
1051 void
1053  struct CadetClient *c,
1055 {
1057  "%s asks for destruction of %s\n",
1058  GSC_2s (c),
1059  GCCH_2s (ch));
1060  GNUNET_assert (NULL != c);
1061  if ((NULL != ch->owner) && (c == ch->owner->c) &&
1063  {
1064  free_channel_client (ch->owner);
1065  ch->owner = NULL;
1066  }
1067  else if ((NULL != ch->dest) && (c == ch->dest->c) &&
1069  {
1070  free_channel_client (ch->dest);
1071  ch->dest = NULL;
1072  }
1073  else
1074  {
1075  GNUNET_assert (0);
1076  }
1077 
1078  if (GNUNET_YES == ch->destroy)
1079  {
1080  /* other end already destroyed, with the local client gone, no need
1081  to finish transmissions, just destroy immediately. */
1082  channel_destroy (ch);
1083  return;
1084  }
1085  if ((NULL != ch->head_sent) && ((NULL != ch->owner) || (NULL != ch->dest)))
1086  {
1087  /* Wait for other end to destroy us as well,
1088  and otherwise allow send queue to be transmitted first */
1089  ch->destroy = GNUNET_YES;
1090  return;
1091  }
1092  if ((GNUNET_YES == ch->is_loopback) &&
1093  ((NULL != ch->owner) || (NULL != ch->dest)))
1094  {
1095  if (NULL != ch->retry_control_task)
1097  ch->retry_control_task =
1099  return;
1100  }
1101  if (GNUNET_NO == ch->is_loopback)
1102  {
1103  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1104  switch (ch->state)
1105  {
1106  case CADET_CHANNEL_NEW:
1107  /* We gave up on a channel that we created as a client to a remote
1108  target, but that never went anywhere. Nothing to do here. */
1109  break;
1110 
1111  case CADET_CHANNEL_LOOSE:
1112  break;
1113 
1114  default:
1115  GCT_send_channel_destroy (ch->t, ch->ctn);
1116  }
1117  }
1118  /* Nothing left to do, just finish destruction */
1119  channel_destroy (ch);
1120 }
1121 
1122 
1132 void
1134  struct CadetChannel *ch,
1135  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1136  const struct GNUNET_HashCode *port)
1137 {
1138  switch (ch->state)
1139  {
1140  case CADET_CHANNEL_NEW:
1141  /* this should be impossible */
1142  GNUNET_break (0);
1143  break;
1144 
1145  case CADET_CHANNEL_LOOSE:
1146  /* This makes no sense. */
1147  GNUNET_break_op (0);
1148  break;
1149 
1151  if (NULL == ch->owner)
1152  {
1153  /* We're not the owner, wrong direction! */
1154  GNUNET_break_op (0);
1155  return;
1156  }
1157  if (0 != GNUNET_memcmp (&ch->port, port))
1158  {
1159  /* Other peer failed to provide the right port,
1160  refuse connection. */
1161  GNUNET_break_op (0);
1162  return;
1163  }
1165  "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1166  GCCH_2s (ch));
1167  if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1168  {
1170  ch->retry_control_task = NULL;
1171  }
1172  ch->state = CADET_CHANNEL_READY;
1173  /* On first connect, send client as many ACKs as we allow messages
1174  to be buffered! */
1175  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1177  break;
1178 
1179  case CADET_CHANNEL_READY:
1180  /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1182  "Received duplicate channel OPEN_ACK for %s\n",
1183  GCCH_2s (ch));
1184  GNUNET_STATISTICS_update (stats, "# duplicate CREATE_ACKs", 1, GNUNET_NO);
1185  break;
1186  }
1187 }
1188 
1189 
1198 static int
1199 is_before (void *cls,
1200  struct CadetOutOfOrderMessage *m1,
1201  struct CadetOutOfOrderMessage *m2)
1202 {
1203  int *duplicate = cls;
1204  uint32_t v1 = ntohl (m1->mid.mid);
1205  uint32_t v2 = ntohl (m2->mid.mid);
1206  uint32_t delta;
1207 
1208  delta = v2 - v1;
1209  if (0 == delta)
1210  *duplicate = GNUNET_YES;
1211  if (delta > (uint32_t) INT_MAX)
1212  {
1213  /* in overflow range, we can safely assume we wrapped around */
1214  return GNUNET_NO;
1215  }
1216  else
1217  {
1218  /* result is small, thus v2 > v1, thus m1 < m2 */
1219  return GNUNET_YES;
1220  }
1221 }
1222 
1223 
1232 void
1234  struct CadetChannel *ch,
1235  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1237 {
1238  struct GNUNET_MQ_Envelope *env;
1239  struct GNUNET_CADET_LocalData *ld;
1240  struct CadetChannelClient *ccc;
1241  size_t payload_size;
1242  struct CadetOutOfOrderMessage *com;
1243  int duplicate;
1244  uint32_t mid_min;
1245  uint32_t mid_max;
1246  uint32_t mid_msg;
1247  uint32_t delta;
1248 
1250  if ((NULL == ch->owner) && (NULL == ch->dest))
1251  {
1252  /* This client is gone, but we still have messages to send to
1253  the other end (which is why @a ch is not yet dead). However,
1254  we cannot pass messages to our client anymore. */
1256  "Dropping incoming payload on %s as this end is already closed\n",
1257  GCCH_2s (ch));
1258  /* send back DESTROY notification to stop further retransmissions! */
1259  if (GNUNET_YES == ch->destroy)
1260  GCT_send_channel_destroy (ch->t, ch->ctn);
1261  return;
1262  }
1263  payload_size = ntohs (msg->header.size) - sizeof(*msg);
1264  env = GNUNET_MQ_msg_extra (ld,
1265  payload_size,
1267  ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1268  GNUNET_memcpy (&ld[1], &msg[1], payload_size);
1269  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1270  if (GNUNET_YES == ccc->client_ready)
1271  {
1272  /*
1273  * We ad-hoc send the message if
1274  * - The channel is out-of-order
1275  * - The channel is reliable and MID matches next expected MID
1276  * - The channel is unreliable and MID is before lowest seen MID
1277  */if ((GNUNET_YES == ch->out_of_order) ||
1278  ((msg->mid.mid == ch->mid_recv.mid) && (GNUNET_YES == ch->reliable)) ||
1279  ((GNUNET_NO == ch->reliable) &&
1280  (ntohl (msg->mid.mid) >= ntohl (ch->mid_recv.mid)) &&
1281  ((NULL == ccc->head_recv) ||
1282  (ntohl (msg->mid.mid) < ntohl (ccc->head_recv->mid.mid)))))
1283  {
1285  "Giving %u bytes of payload with MID %u from %s to client %s\n",
1286  (unsigned int) payload_size,
1287  ntohl (msg->mid.mid),
1288  GCCH_2s (ch),
1289  GSC_2s (ccc->c));
1290  ccc->client_ready = GNUNET_NO;
1291  GSC_send_to_client (ccc->c, env);
1292  if (GNUNET_NO == ch->out_of_order)
1293  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1294  else
1295  ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
1296  ch->mid_futures >>= 1;
1297  if ((GNUNET_YES == ch->out_of_order) && (GNUNET_NO == ch->reliable))
1298  {
1299  /* possibly shift by more if we skipped messages */
1300  uint64_t delta = htonl (msg->mid.mid) - 1 - ntohl (ch->mid_recv.mid);
1301 
1302  if (delta > 63)
1303  ch->mid_futures = 0;
1304  else
1305  ch->mid_futures >>= delta;
1306  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1307  }
1308  send_channel_data_ack (ch);
1309  return;
1310  }
1311  }
1312 
1313  if (GNUNET_YES == ch->reliable)
1314  {
1315  /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1316  mid_min = ntohl (ch->mid_recv.mid);
1317  mid_max = mid_min + ch->max_pending_messages;
1318  mid_msg = ntohl (msg->mid.mid);
1319  if (((uint32_t) (mid_msg - mid_min) > ch->max_pending_messages) ||
1320  ((uint32_t) (mid_max - mid_msg) > ch->max_pending_messages))
1321  {
1323  "%s at %u drops ancient or far-future message %u\n",
1324  GCCH_2s (ch),
1325  (unsigned int) mid_min,
1326  ntohl (msg->mid.mid));
1327 
1329  "# duplicate DATA (ancient or future)",
1330  1,
1331  GNUNET_NO);
1332  GNUNET_MQ_discard (env);
1333  send_channel_data_ack (ch);
1334  return;
1335  }
1336  /* mark bit for future ACKs */
1337  delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1338  if (delta < 64)
1339  {
1340  if (0 != (ch->mid_futures & (1LLU << delta)))
1341  {
1342  /* Duplicate within the queue, drop also */
1344  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1345  (unsigned int) payload_size,
1346  GCCH_2s (ch),
1347  ntohl (msg->mid.mid));
1348  GNUNET_STATISTICS_update (stats, "# duplicate DATA", 1, GNUNET_NO);
1349  GNUNET_MQ_discard (env);
1350  send_channel_data_ack (ch);
1351  return;
1352  }
1353  ch->mid_futures |= (1LLU << delta);
1355  "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1356  (1LLU << delta),
1357  mid_msg,
1358  mid_min,
1359  ch->mid_futures);
1360  }
1361  }
1362  else /* ! ch->reliable */
1363  {
1364  struct CadetOutOfOrderMessage *next_msg;
1365 
1370  if ((NULL != ccc->head_recv) && (GNUNET_YES == ccc->client_ready))
1371  {
1372  next_msg = ccc->head_recv;
1374  "Giving queued MID %u from %s to client %s\n",
1375  ntohl (next_msg->mid.mid),
1376  GCCH_2s (ch),
1377  GSC_2s (ccc->c));
1378  ccc->client_ready = GNUNET_NO;
1379  GSC_send_to_client (ccc->c, next_msg->env);
1380  ch->mid_recv.mid = htonl (1 + ntohl (next_msg->mid.mid));
1381  ch->mid_futures >>= 1;
1382  send_channel_data_ack (ch);
1383  GNUNET_CONTAINER_DLL_remove (ccc->head_recv, ccc->tail_recv, next_msg);
1384  ccc->num_recv--;
1385  /* Do not process duplicate MID */
1386  if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
1387  {
1388  /* Duplicate within the queue, drop */
1390  "Message on %s (mid %u) dropped, duplicate\n",
1391  GCCH_2s (ch),
1392  ntohl (msg->mid.mid));
1393  GNUNET_free (next_msg);
1394  GNUNET_MQ_discard (env);
1395  return;
1396  }
1397  GNUNET_free (next_msg);
1398  }
1399 
1400  if (ntohl (msg->mid.mid) < ntohl (ch->mid_recv.mid)) /* Old */
1401  {
1402  /* Duplicate within the queue, drop */
1404  "Message on %s (mid %u) dropped, old.\n",
1405  GCCH_2s (ch),
1406  ntohl (msg->mid.mid));
1407  GNUNET_MQ_discard (env);
1408  return;
1409  }
1410 
1411  /* Channel is unreliable, so we do not ACK. But we also cannot
1412  allow buffering everything, so check if we have space... */
1413  if (ccc->num_recv >= ch->max_pending_messages)
1414  {
1415  struct CadetOutOfOrderMessage *drop;
1416 
1417  /* Yep, need to drop. Drop the oldest message in
1418  the buffer. */
1420  "Queue full due slow client on %s, dropping oldest message\n",
1421  GCCH_2s (ch));
1423  "# messages dropped due to slow client",
1424  1,
1425  GNUNET_NO);
1426  drop = ccc->head_recv;
1427  GNUNET_assert (NULL != drop);
1428  GNUNET_CONTAINER_DLL_remove (ccc->head_recv, ccc->tail_recv, drop);
1429  ccc->num_recv--;
1430  GNUNET_MQ_discard (drop->env);
1431  GNUNET_free (drop);
1432  }
1433  }
1434 
1435  /* Insert message into sorted out-of-order queue */
1436  com = GNUNET_new (struct CadetOutOfOrderMessage);
1437  com->mid = msg->mid;
1438  com->env = env;
1439  duplicate = GNUNET_NO;
1441  is_before,
1442  &duplicate,
1443  ccc->head_recv,
1444  ccc->tail_recv,
1445  com);
1446  ccc->num_recv++;
1447  if (GNUNET_YES == duplicate)
1448  {
1449  /* Duplicate within the queue, drop also (this is not covered by
1450  the case above if "delta" >= 64, which could be the case if
1451  max_pending_messages is also >= 64 or if our client is unready
1452  and we are seeing retransmissions of the message our client is
1453  blocked on. */LOG (GNUNET_ERROR_TYPE_DEBUG,
1454  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1455  (unsigned int) payload_size,
1456  GCCH_2s (ch),
1457  ntohl (msg->mid.mid));
1458  GNUNET_STATISTICS_update (stats, "# duplicate DATA", 1, GNUNET_NO);
1460  ccc->num_recv--;
1461  GNUNET_MQ_discard (com->env);
1462  GNUNET_free (com);
1463  send_channel_data_ack (ch);
1464  return;
1465  }
1467  "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1468  (GNUNET_YES == ccc->client_ready) ? "out-of-order" : "client-not-ready",
1469  (unsigned int) payload_size,
1470  GCCH_2s (ch),
1471  ntohl (ccc->ccn.channel_of_client),
1472  ccc,
1473  ntohl (msg->mid.mid),
1474  ntohl (ch->mid_recv.mid));
1475  /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1476  the sender may already be transmitting the previous one. Needs
1477  experimental evaluation to see if/when this ACK helps or
1478  hurts. (We might even want another option.) */
1479  send_channel_data_ack (ch);
1480 }
1481 
1482 
1493 static void
1494 data_sent_cb (void *cls,
1495  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
1496 
1497 
1504 static void
1506 {
1507  struct CadetChannel *ch = cls;
1508  struct CadetReliableMessage *crm = ch->head_sent;
1509 
1510  ch->retry_data_task = NULL;
1511  GNUNET_assert (NULL == crm->qe);
1513  "Retrying transmission on %s of message %u\n",
1514  GCCH_2s (ch),
1515  (unsigned int) ntohl (crm->data_message->mid.mid));
1516  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm, &crm->data_message->ctn);
1517  GNUNET_assert (NULL == ch->retry_data_task);
1518 }
1519 
1520 
1529 static void
1531  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1532  struct CadetReliableMessage *crm)
1533 {
1535  ch->pending_messages--;
1538  "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1539  GCCH_2s (ch),
1540  (unsigned int) ntohl (crm->data_message->mid.mid),
1541  ch->pending_messages);
1542  if (NULL != crm->qe)
1543  {
1544  GCT_send_cancel (crm->qe);
1545  crm->qe = NULL;
1546  }
1547  if ((1 == crm->num_transmissions) && (NULL != cti))
1548  {
1549  GCC_ack_observed (cti);
1550  if (0 == GNUNET_memcmp (cti, &crm->connection_taken))
1551  {
1552  GCC_latency_observed (cti,
1554  crm->first_transmission_time));
1555  }
1556  }
1557  GNUNET_free (crm->data_message);
1558  GNUNET_free (crm);
1559  send_ack_to_client (ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1560 }
1561 
1562 
1571 void
1573  struct CadetChannel *ch,
1574  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1575  const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1576 {
1577  struct CadetReliableMessage *crm;
1578  struct CadetReliableMessage *crmn;
1579  int found;
1580  uint32_t mid_base;
1581  uint64_t mid_mask;
1582  unsigned int delta;
1583 
1585  if (GNUNET_NO == ch->reliable)
1586  {
1587  /* not expecting ACKs on unreliable channel, odd */
1588  GNUNET_break_op (0);
1589  return;
1590  }
1591  /* mid_base is the MID of the next message that the
1592  other peer expects (i.e. that is missing!), everything
1593  LOWER (but excluding mid_base itself) was received. */
1594  mid_base = ntohl (ack->mid.mid);
1595  mid_mask = GNUNET_htonll (ack->futures);
1596  found = GNUNET_NO;
1597  for (crm = ch->head_sent; NULL != crm; crm = crmn)
1598  {
1599  crmn = crm->next;
1600  delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base);
1601  if (delta >= UINT_MAX - ch->max_pending_messages)
1602  {
1603  /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1605  "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1606  (unsigned int) mid_base,
1607  ntohl (crm->data_message->mid.mid),
1608  GCCH_2s (ch));
1609  handle_matching_ack (ch, cti, crm);
1610  found = GNUNET_YES;
1611  continue;
1612  }
1613  delta--;
1614  if (delta >= 64)
1615  continue;
1617  "Testing bit %llX for mid %u (base: %u)\n",
1618  (1LLU << delta),
1619  ntohl (crm->data_message->mid.mid),
1620  mid_base);
1621  if (0 != (mid_mask & (1LLU << delta)))
1622  {
1624  "Got DATA_ACK with mask for %u on %s\n",
1625  ntohl (crm->data_message->mid.mid),
1626  GCCH_2s (ch));
1627  handle_matching_ack (ch, cti, crm);
1628  found = GNUNET_YES;
1629  }
1630  }
1631  if (GNUNET_NO == found)
1632  {
1633  /* ACK for message we already dropped, might have been a
1634  duplicate ACK? Ignore. */
1636  "Duplicate DATA_ACK on %s, ignoring\n",
1637  GCCH_2s (ch));
1638  GNUNET_STATISTICS_update (stats, "# duplicate DATA_ACKs", 1, GNUNET_NO);
1639  return;
1640  }
1641  if (NULL != ch->retry_data_task)
1642  {
1644  ch->retry_data_task = NULL;
1645  }
1646  if ((NULL != ch->head_sent) && (NULL == ch->head_sent->qe))
1649  ch);
1650 }
1651 
1652 
1662 void
1664  struct CadetChannel *ch,
1665  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
1666 {
1667  struct CadetChannelClient *ccc;
1668 
1671  "Received remote channel DESTROY for %s\n",
1672  GCCH_2s (ch));
1673  if (GNUNET_YES == ch->destroy)
1674  {
1675  /* Local client already gone, this is instant-death. */
1676  channel_destroy (ch);
1677  return;
1678  }
1679  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1680  if ((NULL != ccc) && (NULL != ccc->head_recv))
1681  {
1683  "Lost end of transmission due to remote shutdown on %s\n",
1684  GCCH_2s (ch));
1685  /* FIXME: change API to notify client about truncated transmission! */
1686  }
1687  ch->destroy = GNUNET_YES;
1688  if (NULL != ccc)
1689  GSC_handle_remote_channel_destroy (ccc->c, ccc->ccn, ch);
1690  channel_destroy (ch);
1691 }
1692 
1693 
1702 static int
1704  struct CadetReliableMessage *crm1,
1705  struct CadetReliableMessage *crm2)
1706 {
1707  if (crm1->next_retry.abs_value_us < crm2->next_retry.abs_value_us)
1708  return GNUNET_YES;
1709  return GNUNET_NO;
1710 }
1711 
1712 
1723 static void
1724 data_sent_cb (void *cls,
1725  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1726 {
1727  struct CadetReliableMessage *crm = cls;
1728  struct CadetChannel *ch = crm->ch;
1729 
1731  GNUNET_assert (NULL != crm->qe);
1732  crm->qe = NULL;
1734  if (GNUNET_NO == ch->reliable)
1735  {
1736  GNUNET_free (crm->data_message);
1737  GNUNET_free (crm);
1738  ch->pending_messages--;
1739  send_ack_to_client (ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1740  return;
1741  }
1742  if (NULL == cid)
1743  {
1744  /* There was an error sending. */
1746  }
1747  else if (GNUNET_SYSERR != crm->num_transmissions)
1748  {
1749  /* Increment transmission counter, and possibly store @a cid
1750  if this was the first transmission. */
1751  crm->num_transmissions++;
1752  if (1 == crm->num_transmissions)
1753  {
1755  crm->connection_taken = *cid;
1756  GCC_ack_expected (cid);
1757  }
1758  }
1759  if ((0 == crm->retry_delay.rel_value_us) && (NULL != cid))
1760  {
1761  struct CadetConnection *cc = GCC_lookup (cid);
1762 
1763  if (NULL != cc)
1765  else
1766  crm->retry_delay = ch->retry_time;
1767  }
1771 
1774  NULL,
1775  ch->head_sent,
1776  ch->tail_sent,
1777  crm);
1779  "Message %u sent, next transmission on %s in %s\n",
1780  (unsigned int) ntohl (crm->data_message->mid.mid),
1781  GCCH_2s (ch),
1784  ch->head_sent->next_retry),
1785  GNUNET_YES));
1786  if (NULL == ch->head_sent->qe)
1787  {
1788  if (NULL != ch->retry_data_task)
1792  ch);
1793  }
1794 }
1795 
1796 
1811 int
1813  struct GNUNET_CADET_ClientChannelNumber sender_ccn,
1814  const char *buf,
1815  size_t buf_len)
1816 {
1817  struct CadetReliableMessage *crm;
1818 
1819  if (ch->pending_messages >= ch->max_pending_messages)
1820  {
1821  GNUNET_break (0); /* Fails: #5370 */
1822  return GNUNET_SYSERR;
1823  }
1824  if (GNUNET_YES == ch->destroy)
1825  {
1826  /* we are going down, drop messages */
1827  return GNUNET_OK;
1828  }
1829  ch->pending_messages++;
1830 
1831  if (GNUNET_YES == ch->is_loopback)
1832  {
1833  struct CadetChannelClient *receiver;
1834  struct GNUNET_MQ_Envelope *env;
1835  struct GNUNET_CADET_LocalData *ld;
1836  int ack_to_owner;
1837 
1838  env =
1840  if ((NULL != ch->owner) &&
1841  (sender_ccn.channel_of_client == ch->owner->ccn.channel_of_client))
1842  {
1843  receiver = ch->dest;
1844  ack_to_owner = GNUNET_YES;
1845  }
1846  else if ((NULL != ch->dest) &&
1847  (sender_ccn.channel_of_client == ch->dest->ccn.channel_of_client))
1848  {
1849  receiver = ch->owner;
1850  ack_to_owner = GNUNET_NO;
1851  }
1852  else
1853  {
1854  GNUNET_break (0);
1855  return GNUNET_SYSERR;
1856  }
1857  GNUNET_assert (NULL != receiver);
1858  ld->ccn = receiver->ccn;
1859  GNUNET_memcpy (&ld[1], buf, buf_len);
1860  if (GNUNET_YES == receiver->client_ready)
1861  {
1862  ch->pending_messages--;
1863  GSC_send_to_client (receiver->c, env);
1864  send_ack_to_client (ch, ack_to_owner);
1865  }
1866  else
1867  {
1868  struct CadetOutOfOrderMessage *oom;
1869 
1870  oom = GNUNET_new (struct CadetOutOfOrderMessage);
1871  oom->env = env;
1873  receiver->tail_recv,
1874  oom);
1875  receiver->num_recv++;
1876  }
1877  return GNUNET_OK;
1878  }
1879 
1880  /* Everything is correct, send the message. */
1881  crm = GNUNET_malloc (sizeof(*crm));
1882  crm->ch = ch;
1883  crm->data_message = GNUNET_malloc (
1884  sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1885  crm->data_message->header.size =
1886  htons (sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1887  crm->data_message->header.type =
1889  ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1890  crm->data_message->mid = ch->mid_send;
1891  crm->data_message->ctn = ch->ctn;
1892  GNUNET_memcpy (&crm->data_message[1], buf, buf_len);
1895  "Sending message %u from local client to %s with %u bytes\n",
1896  ntohl (crm->data_message->mid.mid),
1897  GCCH_2s (ch),
1898  buf_len);
1899  if (NULL != ch->retry_data_task)
1900  {
1902  ch->retry_data_task = NULL;
1903  }
1904  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm, &crm->data_message->ctn);
1905  GNUNET_assert (NULL == ch->retry_data_task);
1906  return GNUNET_OK;
1907 }
1908 
1909 
1917 void
1919  struct GNUNET_CADET_ClientChannelNumber client_ccn)
1920 {
1921  struct CadetChannelClient *ccc;
1922  struct CadetOutOfOrderMessage *com;
1923 
1924  if ((NULL != ch->owner) &&
1925  (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client))
1926  ccc = ch->owner;
1927  else if ((NULL != ch->dest) &&
1928  (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client))
1929  ccc = ch->dest;
1930  else
1931  GNUNET_assert (0);
1932  ccc->client_ready = GNUNET_YES;
1933  com = ccc->head_recv;
1934  if (NULL == com)
1935  {
1937  "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
1938  GSC_2s (ccc->c),
1939  ntohl (client_ccn.channel_of_client),
1940  GCCH_2s (ch),
1941  ntohl (ccc->ccn.channel_of_client),
1942  ccc);
1943  return; /* none pending */
1944  }
1945  if (GNUNET_YES == ch->is_loopback)
1946  {
1947  int to_owner;
1948 
1949  /* Messages are always in-order, just send */
1951  ccc->num_recv--;
1952  GSC_send_to_client (ccc->c, com->env);
1953  /* Notify sender that we can receive more */
1954  if ((NULL != ch->owner) &&
1956  {
1957  to_owner = GNUNET_NO;
1958  }
1959  else
1960  {
1961  GNUNET_assert ((NULL != ch->dest) && (ccc->ccn.channel_of_client ==
1962  ch->dest->ccn.channel_of_client));
1963  to_owner = GNUNET_YES;
1964  }
1965  send_ack_to_client (ch, to_owner);
1966  GNUNET_free (com);
1967  return;
1968  }
1969 
1970  if ((com->mid.mid != ch->mid_recv.mid) && (GNUNET_NO == ch->out_of_order) &&
1971  (GNUNET_YES == ch->reliable))
1972  {
1974  "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
1975  GSC_2s (ccc->c),
1976  ntohl (ccc->ccn.channel_of_client),
1977  ntohl (com->mid.mid),
1978  ntohl (ch->mid_recv.mid));
1979  return; /* missing next one in-order */
1980  }
1981 
1983  "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
1984  ntohl (com->mid.mid),
1985  GSC_2s (ccc->c),
1986  ntohl (ccc->ccn.channel_of_client),
1987  GCCH_2s (ch));
1988 
1989  /* all good, pass next message to client */
1991  ccc->num_recv--;
1992  /* FIXME: if unreliable, this is not aggressive
1993  enough, as it would be OK to have lost some! */
1994 
1995  ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
1996  ch->mid_futures >>= 1; /* equivalent to division by 2 */
1997  ccc->client_ready = GNUNET_NO;
1998  GSC_send_to_client (ccc->c, com->env);
1999  GNUNET_free (com);
2000  send_channel_data_ack (ch);
2001  if (NULL != ccc->head_recv)
2002  return;
2003  if (GNUNET_NO == ch->destroy)
2004  return;
2005  GCT_send_channel_destroy (ch->t, ch->ctn);
2006  channel_destroy (ch);
2007 }
2008 
2009 
2010 #define LOG2(level, ...) \
2011  GNUNET_log_from_nocheck (level, "cadet-chn", __VA_ARGS__)
2012 
2013 
2020 void
2022 {
2023 #if ! defined(GNUNET_CULL_LOGGING)
2024  int do_log;
2025 
2027  "cadet-chn",
2028  __FILE__,
2029  __FUNCTION__,
2030  __LINE__);
2031  if (0 == do_log)
2032  return;
2033 
2034  if (NULL == ch)
2035  {
2036  LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
2037  return;
2038  }
2039  LOG2 (level, "CHN %s:%X (%p)\n", GCT_2s (ch->t), ch->ctn, ch);
2040  if (NULL != ch->owner)
2041  {
2042  LOG2 (level,
2043  "CHN origin %s ready %s local-id: %u\n",
2044  GSC_2s (ch->owner->c),
2045  ch->owner->client_ready ? "YES" : "NO",
2046  ntohl (ch->owner->ccn.channel_of_client));
2047  }
2048  if (NULL != ch->dest)
2049  {
2050  LOG2 (level,
2051  "CHN destination %s ready %s local-id: %u\n",
2052  GSC_2s (ch->dest->c),
2053  ch->dest->client_ready ? "YES" : "NO",
2054  ntohl (ch->dest->ccn.channel_of_client));
2055  }
2056  LOG2 (level,
2057  "CHN Message IDs recv: %d (%LLX), send: %d\n",
2058  ntohl (ch->mid_recv.mid),
2059  (unsigned long long) ch->mid_futures,
2060  ntohl (ch->mid_send.mid));
2061 #endif
2062 }
2063 
2064 
2065 /* end of gnunet-service-cadet_channel.c */
int out_of_order
Is the tunnel out-of-order?
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static int is_before(void *cls, struct CadetOutOfOrderMessage *m1, struct CadetOutOfOrderMessage *m2)
Test if element e1 comes before element e2.
uint64_t futures
Bitfield of already-received newer messages.
void GCT_remove_channel(struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Remove a channel from a tunnel.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
struct CadetChannel * ch
Which channel is this message in?
struct GNUNET_HashCode h_port
Hash of destination port and listener.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
Connection confirmed, ready to carry traffic.
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK&#39;d.
enum CadetChannelState state
Channel state.
Peer description.
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
Info needed to retry a message in case it gets lost.
void GCCH_assign_type_to_drop(struct CadetChannel *ch, const struct GNUNET_CADET_RequestDropCadetMessage *message)
Assign type of message to drop.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
Message to allow the client send more data to the service (always service -> client).
Definition: cadet.h:280
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK.
GNUnet CADET service with encryption.
Low-level connection to a destination.
uint64_t rel_value_us
The actual value.
static void channel_destroy(struct CadetChannel *ch)
Destroy the given channel.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
struct CadetTunnel * GCP_get_tunnel(struct CadetPeer *cp, int create)
Get the tunnel towards a peer.
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.
#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.
#define MIN_RTT_DELAY
How long do we wait at least before retransmitting ever?
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
A connection is a live end-to-end messaging mechanism where the peers are identified by a path and kn...
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...
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
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:287
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
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:246
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.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it&#39;s in the queue.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
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.
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
Uninitialized status, should never appear in operation.
struct GNUNET_SCHEDULER_Task * retry_data_task
Task to resend/poll in case no ACK is received.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define CADET_INITIAL_RETRANSMIT_TIME
How long do we initially wait before retransmitting?
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
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...
int nobuffer
Is the tunnel bufferless (minimum latency)?
CadetChannelState
All the states a channel can be in.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
Information we track per tunnel.
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:483
GNUNET_ErrorType
Types of errors.
uint32_t opt
Channel options.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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.
static void retry_transmission(void *cls)
We need to retry a transmission, the last one took too long to be acknowledged.
uint16_t type
Type of message to be droped.
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.
List of received out-of-order data messages.
struct CadetReliableMessage * prev
Double linked list, FIFO style.
Context for cummulative hashing.
Definition: crypto_hash.c:468
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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...
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
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_MQ_Envelope * env
The envelope with the payload of the out-of-order message.
uint16_t type
Type of the message this handler covers, in host byte order.
Definition: cadet.h:332
unsigned int num_recv
Number of entries currently in head_recv DLL.
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...
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
void GCCH_handle_local_ack(struct CadetChannel *ch, struct GNUNET_CADET_ClientChannelNumber client_ccn)
Handle ACK from client on local channel.
static void signal_remote_destroy_cb(void *cls)
One of our clients has disconnected, tell the other one that we are finished.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
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.
struct GNUNET_CONTAINER_MultiHashMap * open_ports
All ports clients of this peer have opened.
int reliable
Is the tunnel reliable?
struct GNUNET_CONTAINER_MultiHashMap * loose_channels
Map from ports to channels where the ports were closed at the time we got the inbound connection...
static void free_channel_client(struct CadetChannelClient *ccc)
Release memory associated with ccc.
#define INT_MAX
struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id(const struct CadetChannel *ch)
Get the channel&#39;s public ID.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#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
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
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
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...
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK
Local ACK for data.
struct CadetTunnel * t
Tunnel this channel is in.
enum State state
current state of profiling
unsigned int skip_ack_series
Count how many ACKs we skipped, used to prevent long sequences of ACK skipping.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN.
#define LOG(level,...)
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 CadetOutOfOrderMessage * tail_recv
Tail DLL of messages received out of order or while client was unready.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_HashCode h_port
Port hashed with our PID (matches incoming OPEN messages).
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
Struct containing all information regarding a channel to a remote client.
Channel is to a port that is not open, we&#39;re waiting for the port to be opened.
struct GNUNET_CADET_ConnectionTunnelIdentifier connection_taken
Identifier of the connection that this message took when it was first transmitted.
struct GNUNET_TIME_Relative retry_time
Counter for exponential backoff.
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
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 GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
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:701
static void send_channel_open(void *cls)
Send a channel create message.
struct GNUNET_CADET_ChannelAppDataMessage * data_message
Data message we are trying to send.
static char buf[2048]
struct GNUNET_TIME_Relative aged_latency
Our current best estimate of the latency, based on a weighted average of at least latency_datapoints ...
Message for cadet data traffic.
struct ChannelMessageIdentifier mid
Next message ID expected.
Number uniquely identifying a channel of a client.
Definition: cadet.h:101
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
struct GNUNET_HashCode port
Port number.
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.
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...
#define GNUNET_CADET_LOCAL_CHANNEL_ID_CLI
Minimum value for channel IDs of local clients.
Definition: cadet.h:71
unsigned int pending_messages
Total (reliable) messages pending ACK for this channel.
A 512-bit hashcode.
struct GNUNET_CADET_ClientChannelNumber ccn
ID of the channel.
Definition: cadet.h:262
#define TIMEOUT_CLOSED_PORT
How long do we wait before dropping state about incoming connection to closed port?
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:323
static int cmp_crm_by_next_retry(void *cls, struct CadetReliableMessage *crm1, struct CadetReliableMessage *crm2)
Test if element e1 comes before element e2.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
Struct containing all information regarding a tunnel to a peer.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
Message to acknowledge end-to-end data.
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)...
struct GNUNET_TIME_Absolute first_transmission_time
Time when we first successfully transmitted the message (that is, set num_transmissions to 1)...
Struct containing information about a client of the service.
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.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel within the tunnel.
CHANNEL_OPEN message sent, waiting for CHANNEL_OPEN_ACK.
#define LOG2(level,...)
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:509
int client_ready
Can we send data to the client?
void GCCH_channel_local_destroy(struct CadetChannel *ch, struct CadetClient *c, struct GNUNET_CADET_ClientChannelNumber ccn)
Destroy locally created channel.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Struct used to save messages in a non-ready tunnel to send once connected.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct GNUNET_CADET_ClientChannelNumber ccn
ID of the channel allowed to send more data.
Definition: cadet.h:290
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
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.
Message to create a Channel.
int num_transmissions
How often was this message transmitted? GNUNET_SYSERR if there was an error transmitting the message...
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
struct CadetReliableMessage * next
Double linked list, FIFO style.
Allow multiple values with the same key.
Number used to uniquely identify messages in a CADET Channel.
struct CadetConnection * GCC_lookup(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Lookup a connection by its identifier.
int destroy
Flag to signal the destruction of the channel.
struct CadetReliableMessage * tail_sent
Tail of DLL of messages sent and not yet ACK&#39;d.
struct GNUNET_HashCode h_port
Hash&#39;ed port of the channel with initiator and destination PID.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_HashCode port
Port number of the channel, used to prove to the initiator that the receiver knows the port...
#define GNUNET_PACKED
gcc-ism to get packed structs.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:82
Hash uniquely identifying a connection below a tunnel.
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.
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer stucture associated with 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:375
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA
Payload client <-> service.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
Client endpoint of a struct CadetChannel.
struct GNUNET_TIME_Relative retry_delay
How long do we wait for an ACK after transmission? Use for the back-off calculation.
Number identifying a CADET channel within a tunnel.
Entry in list of pending tasks.
Definition: scheduler.c:134
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct CadetClient * c
Client handle.
void GSC_send_to_client(struct CadetClient *c, struct GNUNET_MQ_Envelope *env)
Send a message to a client.
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 send_channel_data_ack(struct CadetChannel *ch)
Compute and send the current GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer...
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
struct CadetTunnelQueueEntry * qe
Entry in the tunnels queue for this message, NULL if it has left the tunnel.
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
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...
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
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...
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
static void data_sent_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel has sent one of our messages.
Message for cadet data traffic.
Definition: cadet.h:252
static void timeout_closed_cb(void *cls)
We had an incoming channel to a port that is closed.
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...
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct ChannelMessageIdentifier mid
ID of the message (messages up to this point needed before we give this one to the client)...
static void send_open_ack(void *cls)
Send our initial GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the connect...
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
Message to drop another message of specific type.
Definition: cadet.h:321
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
struct ChannelMessageIdentifier mid_send
Next MID to use for outgoing traffic.
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct CadetOutOfOrderMessage * prev
Double linked list, FIFO style.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct CadetClient * c
Client that opened the port.
struct CadetOutOfOrderMessage * head_recv
Head of DLL of messages received out of order or while client was unready.
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.
Port opened by a client.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:526
#define GNUNET_malloc(size)
Wrapper around malloc.
struct CadetTunnelQueueEntry * last_control_qe
Last entry in the tunnel&#39;s queue relating to control messages (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN...
struct CadetOutOfOrderMessage * next
Double linked list, FIFO style.
#define GNUNET_free(ptr)
Wrapper around free.
uint32_t reserved
For alignment.
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.
uint64_t mid_futures
Bitfield of already-received messages past mid_recv.
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.
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.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
struct GNUNET_HashCode port
Destination port of the channel.