GNUnet  0.10.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 
86 
92 
97 
102 };
103 
104 
115 
120 
124  struct CadetChannel *ch;
125 
132 
137 
143 
149 
155 
161 
168 };
169 
170 
179 
184 
190 
195 };
196 
197 
210  struct CadetClient *c;
211 
216 
221 
228 
232  unsigned int num_recv;
233 
238 };
239 
240 
244 struct CadetChannel {
248  struct CadetTunnel *t;
249 
255 
261 
269 
274 
279 
284 
289 
293  struct GNUNET_TIME_Absolute timestamp;
294 
299 
303  struct GNUNET_HashCode h_port;
304 
308  struct GNUNET_TIME_Relative retry_time;
309 
313  uint64_t mid_futures;
314 
318  struct ChannelMessageIdentifier mid_recv;
319 
323  struct ChannelMessageIdentifier mid_send;
324 
328  unsigned int pending_messages;
329 
334  unsigned int max_pending_messages;
335 
340 
345 
350  unsigned int skip_ack_series;
351 
355  int nobuffer;
356 
360  int reliable;
361 
366 
371 
377  int destroy;
378 };
379 
380 
388 const char *
389 GCCH_2s(const struct CadetChannel *ch)
390 {
391  static char buf[128];
392 
393  GNUNET_snprintf(buf,
394  sizeof(buf),
395  "Channel %s:%s ctn:%X(%X/%X)",
396  (GNUNET_YES == ch->is_loopback)
397  ? "loopback"
399  GNUNET_h2s(&ch->port),
400  ch->ctn,
401  (NULL == ch->owner)
402  ? 0
403  : ntohl(ch->owner->ccn.channel_of_client),
404  (NULL == ch->dest)
405  ? 0
406  : ntohl(ch->dest->ccn.channel_of_client));
407  return buf;
408 }
409 
410 
420 void
422  const struct GNUNET_HashCode *port,
423  const struct GNUNET_PeerIdentity *listener)
424 {
425  struct GNUNET_HashContext *hc;
426 
428  GNUNET_CRYPTO_hash_context_read(hc, port, sizeof(*port));
429  GNUNET_CRYPTO_hash_context_read(hc, listener, sizeof(*listener));
432  "Calculated port hash %s\n",
433  GNUNET_h2s(h_port));
434 }
435 
436 
446 {
447  return ch->ctn;
448 }
449 
450 
456 static void
458 {
459  struct CadetOutOfOrderMessage *com;
460 
461  while (NULL != (com = ccc->head_recv))
462  {
464  ccc->num_recv--;
465  GNUNET_MQ_discard(com->env);
466  GNUNET_free(com);
467  }
468  GNUNET_free(ccc);
469 }
470 
471 
477 static void
479 {
480  struct CadetReliableMessage *crm;
481 
482  while (NULL != (crm = ch->head_sent))
483  {
484  GNUNET_assert(ch == crm->ch);
485  if (NULL != crm->qe)
486  {
487  GCT_send_cancel(crm->qe);
488  crm->qe = NULL;
489  }
492  GNUNET_free(crm);
493  }
494  if (CADET_CHANNEL_LOOSE == ch->state)
495  {
496  GSC_drop_loose_channel(&ch->h_port, ch);
497  }
498  if (NULL != ch->owner)
499  {
501  ch->owner = NULL;
502  }
503  if (NULL != ch->dest)
504  {
506  ch->dest = NULL;
507  }
508  if (NULL != ch->last_control_qe)
509  {
511  ch->last_control_qe = NULL;
512  }
513  if (NULL != ch->retry_data_task)
514  {
516  ch->retry_data_task = NULL;
517  }
518  if (NULL != ch->retry_control_task)
519  {
521  ch->retry_control_task = NULL;
522  }
523  if (GNUNET_NO == ch->is_loopback)
524  {
525  GCT_remove_channel(ch->t, ch, ch->ctn);
526  ch->t = NULL;
527  }
528  GNUNET_free(ch);
529 }
530 
531 
537 static void
538 send_channel_open(void *cls);
539 
540 
549 static void
551  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
552 {
553  struct CadetChannel *ch = cls;
554 
555  GNUNET_assert(NULL != ch->last_control_qe);
556  ch->last_control_qe = NULL;
559  "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
560  GCCH_2s(ch),
562  ch->retry_control_task =
564 }
565 
566 
572 static void
574 {
575  struct CadetChannel *ch = cls;
576  struct GNUNET_CADET_ChannelOpenMessage msgcc;
577 
578  ch->retry_control_task = NULL;
580  "Sending CHANNEL_OPEN message for %s\n",
581  GCCH_2s(ch));
582  msgcc.header.size = htons(sizeof(msgcc));
584  //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.
585  msgcc.opt = 2;
586  msgcc.h_port = ch->h_port;
587  msgcc.ctn = ch->ctn;
589  if (NULL != ch->last_control_qe)
591  ch->last_control_qe =
592  GCT_send(ch->t, &msgcc.header, &channel_open_sent_cb, ch);
593  GNUNET_assert(NULL == ch->retry_control_task);
594 }
595 
596 
607 void
609 {
610  GNUNET_assert(NULL == ch->retry_control_task);
612  "Tunnel up, sending CHANNEL_OPEN on %s now\n",
613  GCCH_2s(ch));
615 }
616 
617 
628 struct CadetChannel *
631  struct CadetPeer *destination,
632  const struct GNUNET_HashCode *port,
633  uint32_t options)
634 {
635  struct CadetChannel *ch;
636  struct CadetChannelClient *ccco;
637 
638  ccco = GNUNET_new(struct CadetChannelClient);
639  ccco->c = owner;
640  ccco->ccn = ccn;
641  ccco->client_ready = GNUNET_YES;
642 
643  ch = GNUNET_new(struct CadetChannel);
644  ch->mid_recv.mid = htonl(1); /* The OPEN_ACK counts as message 0! */
645  ch->nobuffer = GNUNET_NO;
646  ch->reliable = GNUNET_YES;
647  ch->out_of_order = GNUNET_NO;
649  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
650  ch->owner = ccco;
651  ch->port = *port;
652  GCCH_hash_port(&ch->h_port, port, GCP_get_id(destination));
653  if (0 == GNUNET_memcmp(&my_full_id, GCP_get_id(destination)))
654  {
655  struct OpenPort *op;
656 
657  ch->is_loopback = GNUNET_YES;
659  if (NULL == op)
660  {
661  /* port closed, wait for it to possibly open */
665  &ch->h_port,
666  ch,
669  "Created loose incoming loopback channel to port %s\n",
670  GNUNET_h2s(&ch->port));
671  }
672  else
673  {
674  GCCH_bind(ch, op->c, &op->port);
675  }
676  }
677  else
678  {
679  ch->t = GCP_get_tunnel(destination, GNUNET_YES);
681  ch->ctn = GCT_add_channel(ch->t, ch);
682  }
683  GNUNET_STATISTICS_update(stats, "# channels", 1, GNUNET_NO);
685  "Created channel to port %s at peer %s for %s using %s\n",
686  GNUNET_h2s(port),
687  GCP_2s(destination),
688  GSC_2s(owner),
689  (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s(ch->t));
690  return ch;
691 }
692 
693 
700 static void
702 {
703  struct CadetChannel *ch = cls;
704 
705  ch->retry_control_task = NULL;
707  "Closing incoming channel to port %s from peer %s due to timeout\n",
708  GNUNET_h2s(&ch->port),
710  channel_destroy(ch);
711 }
712 
713 
723 struct CadetChannel *
726  const struct GNUNET_HashCode *h_port,
727  uint32_t options)
728 {
729  struct CadetChannel *ch;
730  struct OpenPort *op;
731 
732  ch = GNUNET_new(struct CadetChannel);
733  ch->h_port = *h_port;
734  ch->t = t;
735  ch->ctn = ctn;
737  ch->nobuffer = GNUNET_NO;
738  ch->reliable = GNUNET_YES;
739  ch->out_of_order = GNUNET_NO;
741  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
742  GNUNET_STATISTICS_update(stats, "# channels", 1, GNUNET_NO);
743 
745  if (NULL == op)
746  {
747  /* port closed, wait for it to possibly open */
751  &ch->h_port,
752  ch,
754  GNUNET_assert(NULL == ch->retry_control_task);
757  ch);
759  "Created loose incoming channel to port %s from peer %s\n",
760  GNUNET_h2s(&ch->port),
762  }
763  else
764  {
765  GCCH_bind(ch, op->c, &op->port);
766  }
767  GNUNET_STATISTICS_update(stats, "# channels", 1, GNUNET_NO);
768  return ch;
769 }
770 
771 
781 static void
782 send_ack_cb(void *cls,
783  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
784 {
785  struct CadetChannel *ch = cls;
786 
787  GNUNET_assert(NULL != ch->last_control_qe);
788  ch->last_control_qe = NULL;
789 }
790 
791 
797 static void
799 {
801 
802  if (GNUNET_NO == ch->reliable)
803  return; /* no ACKs */
805  msg.header.size = htons(sizeof(msg));
806  msg.ctn = ch->ctn;
807  msg.mid.mid = htonl(ntohl(ch->mid_recv.mid));
808  msg.futures = GNUNET_htonll(ch->mid_futures);
810  "Sending DATA_ACK %u:%llX via %s\n",
811  (unsigned int)ntohl(msg.mid.mid),
812  (unsigned long long)ch->mid_futures,
813  GCCH_2s(ch));
814  if (NULL != ch->last_control_qe)
816  ch->last_control_qe = GCT_send(ch->t, &msg.header, &send_ack_cb, ch);
817 }
818 
819 
826 static void
827 send_open_ack(void *cls)
828 {
829  struct CadetChannel *ch = cls;
831 
832  ch->retry_control_task = NULL;
834  "Sending CHANNEL_OPEN_ACK on %s\n",
835  GCCH_2s(ch));
837  msg.header.size = htons(sizeof(msg));
838  msg.reserved = htonl(0);
839  msg.ctn = ch->ctn;
840  msg.port = ch->port;
841  if (NULL != ch->last_control_qe)
843  ch->last_control_qe = GCT_send(ch->t, &msg.header, &send_ack_cb, ch);
844 }
845 
846 
855 void
857  struct CadetChannel *ch,
858  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
859 {
860  if (NULL == ch->dest)
861  {
863  "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
864  GCCH_2s(ch));
865  return;
866  }
867  if (NULL != ch->retry_control_task)
868  {
870  "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
871  GCCH_2s(ch));
872  return;
873  }
875  "Retransmitting CHANNEL_OPEN_ACK on %s\n",
876  GCCH_2s(ch));
878 }
879 
880 
888 static void
889 send_ack_to_client(struct CadetChannel *ch, int to_owner)
890 {
891  struct GNUNET_MQ_Envelope *env;
892  struct GNUNET_CADET_LocalAck *ack;
893  struct CadetChannelClient *ccc;
894 
895  ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
896  if (NULL == ccc)
897  {
898  /* This can happen if we are just getting ACKs after
899  our local client already disconnected. */
901  return;
902  }
904  ack->ccn = ccc->ccn;
906  "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X (%u/%u pending)\n",
907  GSC_2s(ccc->c),
908  (GNUNET_YES == to_owner) ? "owner" : "dest",
909  ntohl(ack->ccn.channel_of_client),
910  ch->pending_messages,
912  GSC_send_to_client(ccc->c, env);
913 }
914 
915 
925 void
927  struct CadetClient *c,
928  const struct GNUNET_HashCode *port)
929 {
930  uint32_t options;
931  struct CadetChannelClient *cccd;
932 
934  "Binding %s from %s to port %s of %s\n",
935  GCCH_2s(ch),
936  GCT_2s(ch->t),
937  GNUNET_h2s(&ch->port),
938  GSC_2s(c));
939  if (NULL != ch->retry_control_task)
940  {
941  /* there might be a timeout task here */
943  ch->retry_control_task = NULL;
944  }
945  options = 0;
946  cccd = GNUNET_new(struct CadetChannelClient);
947  GNUNET_assert(NULL == ch->dest);
948  ch->dest = cccd;
949  ch->port = *port;
950  cccd->c = c;
951  cccd->client_ready = GNUNET_YES;
952  cccd->ccn = GSC_bind(c,
953  ch,
954  (GNUNET_YES == ch->is_loopback)
956  : GCT_get_destination(ch->t),
957  port,
958  options);
959  GNUNET_assert(ntohl(cccd->ccn.channel_of_client) <
961  ch->mid_recv.mid = htonl(1); /* The OPEN counts as message 0! */
962  if (GNUNET_YES == ch->is_loopback)
963  {
965  GCCH_handle_channel_open_ack(ch, NULL, port);
966  }
967  else
968  {
969  /* notify other peer that we accepted the connection */
972  }
973  /* give client it's initial supply of ACKs */
974  GNUNET_assert(ntohl(cccd->ccn.channel_of_client) <
976  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
978 }
979 
980 
988 static void
990 {
991  struct CadetChannel *ch = cls;
992  struct CadetChannelClient *ccc;
993 
994  /* Find which end is left... */
995  ch->retry_control_task = NULL;
996  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
997  GSC_handle_remote_channel_destroy(ccc->c, ccc->ccn, ch);
998  channel_destroy(ch);
999 }
1000 
1001 
1010 void
1012  struct CadetClient *c,
1014 {
1016  "%s asks for destruction of %s\n",
1017  GSC_2s(c),
1018  GCCH_2s(ch));
1019  GNUNET_assert(NULL != c);
1020  if ((NULL != ch->owner) && (c == ch->owner->c) &&
1022  {
1024  ch->owner = NULL;
1025  }
1026  else if ((NULL != ch->dest) && (c == ch->dest->c) &&
1028  {
1030  ch->dest = NULL;
1031  }
1032  else
1033  {
1034  GNUNET_assert(0);
1035  }
1036 
1037  if (GNUNET_YES == ch->destroy)
1038  {
1039  /* other end already destroyed, with the local client gone, no need
1040  to finish transmissions, just destroy immediately. */
1041  channel_destroy(ch);
1042  return;
1043  }
1044  if ((NULL != ch->head_sent) && ((NULL != ch->owner) || (NULL != ch->dest)))
1045  {
1046  /* Wait for other end to destroy us as well,
1047  and otherwise allow send queue to be transmitted first */
1048  ch->destroy = GNUNET_YES;
1049  return;
1050  }
1051  if ((GNUNET_YES == ch->is_loopback) &&
1052  ((NULL != ch->owner) || (NULL != ch->dest)))
1053  {
1054  if (NULL != ch->retry_control_task)
1056  ch->retry_control_task =
1058  return;
1059  }
1060  if (GNUNET_NO == ch->is_loopback)
1061  {
1062  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1063  switch (ch->state)
1064  {
1065  case CADET_CHANNEL_NEW:
1066  /* We gave up on a channel that we created as a client to a remote
1067  target, but that never went anywhere. Nothing to do here. */
1068  break;
1069 
1070  case CADET_CHANNEL_LOOSE:
1071  break;
1072 
1073  default:
1074  GCT_send_channel_destroy(ch->t, ch->ctn);
1075  }
1076  }
1077  /* Nothing left to do, just finish destruction */
1078  channel_destroy(ch);
1079 }
1080 
1081 
1091 void
1093  struct CadetChannel *ch,
1094  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1095  const struct GNUNET_HashCode *port)
1096 {
1097  switch (ch->state)
1098  {
1099  case CADET_CHANNEL_NEW:
1100  /* this should be impossible */
1101  GNUNET_break(0);
1102  break;
1103 
1104  case CADET_CHANNEL_LOOSE:
1105  /* This makes no sense. */
1106  GNUNET_break_op(0);
1107  break;
1108 
1110  if (NULL == ch->owner)
1111  {
1112  /* We're not the owner, wrong direction! */
1113  GNUNET_break_op(0);
1114  return;
1115  }
1116  if (0 != GNUNET_memcmp(&ch->port, port))
1117  {
1118  /* Other peer failed to provide the right port,
1119  refuse connection. */
1120  GNUNET_break_op(0);
1121  return;
1122  }
1124  "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1125  GCCH_2s(ch));
1126  if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1127  {
1129  ch->retry_control_task = NULL;
1130  }
1131  ch->state = CADET_CHANNEL_READY;
1132  /* On first connect, send client as many ACKs as we allow messages
1133  to be buffered! */
1134  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1136  break;
1137 
1138  case CADET_CHANNEL_READY:
1139  /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1141  "Received duplicate channel OPEN_ACK for %s\n",
1142  GCCH_2s(ch));
1143  GNUNET_STATISTICS_update(stats, "# duplicate CREATE_ACKs", 1, GNUNET_NO);
1144  break;
1145  }
1146 }
1147 
1148 
1157 static int
1158 is_before(void *cls,
1159  struct CadetOutOfOrderMessage *m1,
1160  struct CadetOutOfOrderMessage *m2)
1161 {
1162  int *duplicate = cls;
1163  uint32_t v1 = ntohl(m1->mid.mid);
1164  uint32_t v2 = ntohl(m2->mid.mid);
1165  uint32_t delta;
1166 
1167  delta = v2 - v1;
1168  if (0 == delta)
1169  *duplicate = GNUNET_YES;
1170  if (delta > (uint32_t)INT_MAX)
1171  {
1172  /* in overflow range, we can safely assume we wrapped around */
1173  return GNUNET_NO;
1174  }
1175  else
1176  {
1177  /* result is small, thus v2 > v1, thus m1 < m2 */
1178  return GNUNET_YES;
1179  }
1180 }
1181 
1182 
1191 void
1193  struct CadetChannel *ch,
1194  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1196 {
1197  struct GNUNET_MQ_Envelope *env;
1198  struct GNUNET_CADET_LocalData *ld;
1199  struct CadetChannelClient *ccc;
1200  size_t payload_size;
1201  struct CadetOutOfOrderMessage *com;
1202  int duplicate;
1203  uint32_t mid_min;
1204  uint32_t mid_max;
1205  uint32_t mid_msg;
1206  uint32_t delta;
1207 
1209  if ((NULL == ch->owner) && (NULL == ch->dest))
1210  {
1211  /* This client is gone, but we still have messages to send to
1212  the other end (which is why @a ch is not yet dead). However,
1213  we cannot pass messages to our client anymore. */
1215  "Dropping incoming payload on %s as this end is already closed\n",
1216  GCCH_2s(ch));
1217  /* send back DESTROY notification to stop further retransmissions! */
1218  if (GNUNET_YES == ch->destroy)
1219  GCT_send_channel_destroy(ch->t, ch->ctn);
1220  return;
1221  }
1222  payload_size = ntohs(msg->header.size) - sizeof(*msg);
1223  env = GNUNET_MQ_msg_extra(ld,
1224  payload_size,
1226  ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1227  GNUNET_memcpy(&ld[1], &msg[1], payload_size);
1228  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1229  if (GNUNET_YES == ccc->client_ready)
1230  {
1231  /*
1232  * We ad-hoc send the message if
1233  * - The channel is out-of-order
1234  * - The channel is reliable and MID matches next expected MID
1235  * - The channel is unreliable and MID is before lowest seen MID
1236  */
1237  if ((GNUNET_YES == ch->out_of_order) ||
1238  ((msg->mid.mid == ch->mid_recv.mid) && (GNUNET_YES == ch->reliable)) ||
1239  ((GNUNET_NO == ch->reliable) &&
1240  (ntohl(msg->mid.mid) >= ntohl(ch->mid_recv.mid)) &&
1241  ((NULL == ccc->head_recv) ||
1242  (ntohl(msg->mid.mid) < ntohl(ccc->head_recv->mid.mid)))))
1243  {
1245  "Giving %u bytes of payload with MID %u from %s to client %s\n",
1246  (unsigned int)payload_size,
1247  ntohl(msg->mid.mid),
1248  GCCH_2s(ch),
1249  GSC_2s(ccc->c));
1250  ccc->client_ready = GNUNET_NO;
1251  GSC_send_to_client(ccc->c, env);
1252  if (GNUNET_NO == ch->out_of_order)
1253  ch->mid_recv.mid = htonl(1 + ntohl(msg->mid.mid));
1254  else
1255  ch->mid_recv.mid = htonl(1 + ntohl(ch->mid_recv.mid));
1256  ch->mid_futures >>= 1;
1257  if ((GNUNET_YES == ch->out_of_order) && (GNUNET_NO == ch->reliable))
1258  {
1259  /* possibly shift by more if we skipped messages */
1260  uint64_t delta = htonl(msg->mid.mid) - 1 - ntohl(ch->mid_recv.mid);
1261 
1262  if (delta > 63)
1263  ch->mid_futures = 0;
1264  else
1265  ch->mid_futures >>= delta;
1266  ch->mid_recv.mid = htonl(1 + ntohl(msg->mid.mid));
1267  }
1269  return;
1270  }
1271  }
1272 
1273  if (GNUNET_YES == ch->reliable)
1274  {
1275  /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1276  mid_min = ntohl(ch->mid_recv.mid);
1277  mid_max = mid_min + ch->max_pending_messages;
1278  mid_msg = ntohl(msg->mid.mid);
1279  if (((uint32_t)(mid_msg - mid_min) > ch->max_pending_messages) ||
1280  ((uint32_t)(mid_max - mid_msg) > ch->max_pending_messages))
1281  {
1283  "%s at %u drops ancient or far-future message %u\n",
1284  GCCH_2s(ch),
1285  (unsigned int)mid_min,
1286  ntohl(msg->mid.mid));
1287 
1289  "# duplicate DATA (ancient or future)",
1290  1,
1291  GNUNET_NO);
1292  GNUNET_MQ_discard(env);
1294  return;
1295  }
1296  /* mark bit for future ACKs */
1297  delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1298  if (delta < 64)
1299  {
1300  if (0 != (ch->mid_futures & (1LLU << delta)))
1301  {
1302  /* Duplicate within the queue, drop also */
1304  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1305  (unsigned int)payload_size,
1306  GCCH_2s(ch),
1307  ntohl(msg->mid.mid));
1308  GNUNET_STATISTICS_update(stats, "# duplicate DATA", 1, GNUNET_NO);
1309  GNUNET_MQ_discard(env);
1311  return;
1312  }
1313  ch->mid_futures |= (1LLU << delta);
1315  "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1316  (1LLU << delta),
1317  mid_msg,
1318  mid_min,
1319  ch->mid_futures);
1320  }
1321  }
1322  else /* ! ch->reliable */
1323  {
1324  struct CadetOutOfOrderMessage *next_msg;
1325 
1330  if ((NULL != ccc->head_recv) && (GNUNET_YES == ccc->client_ready))
1331  {
1332  next_msg = ccc->head_recv;
1334  "Giving queued MID %u from %s to client %s\n",
1335  ntohl(next_msg->mid.mid),
1336  GCCH_2s(ch),
1337  GSC_2s(ccc->c));
1338  ccc->client_ready = GNUNET_NO;
1339  GSC_send_to_client(ccc->c, next_msg->env);
1340  ch->mid_recv.mid = htonl(1 + ntohl(next_msg->mid.mid));
1341  ch->mid_futures >>= 1;
1343  GNUNET_CONTAINER_DLL_remove(ccc->head_recv, ccc->tail_recv, next_msg);
1344  ccc->num_recv--;
1345  /* Do not process duplicate MID */
1346  if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
1347  {
1348  /* Duplicate within the queue, drop */
1350  "Message on %s (mid %u) dropped, duplicate\n",
1351  GCCH_2s(ch),
1352  ntohl(msg->mid.mid));
1353  GNUNET_free(next_msg);
1354  GNUNET_MQ_discard(env);
1355  return;
1356  }
1357  GNUNET_free(next_msg);
1358  }
1359 
1360  if (ntohl(msg->mid.mid) < ntohl(ch->mid_recv.mid)) /* Old */
1361  {
1362  /* Duplicate within the queue, drop */
1364  "Message on %s (mid %u) dropped, old.\n",
1365  GCCH_2s(ch),
1366  ntohl(msg->mid.mid));
1367  GNUNET_MQ_discard(env);
1368  return;
1369  }
1370 
1371  /* Channel is unreliable, so we do not ACK. But we also cannot
1372  allow buffering everything, so check if we have space... */
1373  if (ccc->num_recv >= ch->max_pending_messages)
1374  {
1375  struct CadetOutOfOrderMessage *drop;
1376 
1377  /* Yep, need to drop. Drop the oldest message in
1378  the buffer. */
1380  "Queue full due slow client on %s, dropping oldest message\n",
1381  GCCH_2s(ch));
1383  "# messages dropped due to slow client",
1384  1,
1385  GNUNET_NO);
1386  drop = ccc->head_recv;
1387  GNUNET_assert(NULL != drop);
1389  ccc->num_recv--;
1390  GNUNET_MQ_discard(drop->env);
1391  GNUNET_free(drop);
1392  }
1393  }
1394 
1395  /* Insert message into sorted out-of-order queue */
1396  com = GNUNET_new(struct CadetOutOfOrderMessage);
1397  com->mid = msg->mid;
1398  com->env = env;
1399  duplicate = GNUNET_NO;
1401  is_before,
1402  &duplicate,
1403  ccc->head_recv,
1404  ccc->tail_recv,
1405  com);
1406  ccc->num_recv++;
1407  if (GNUNET_YES == duplicate)
1408  {
1409  /* Duplicate within the queue, drop also (this is not covered by
1410  the case above if "delta" >= 64, which could be the case if
1411  max_pending_messages is also >= 64 or if our client is unready
1412  and we are seeing retransmissions of the message our client is
1413  blocked on. */
1415  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1416  (unsigned int)payload_size,
1417  GCCH_2s(ch),
1418  ntohl(msg->mid.mid));
1419  GNUNET_STATISTICS_update(stats, "# duplicate DATA", 1, GNUNET_NO);
1421  ccc->num_recv--;
1422  GNUNET_MQ_discard(com->env);
1423  GNUNET_free(com);
1425  return;
1426  }
1428  "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1429  (GNUNET_YES == ccc->client_ready) ? "out-of-order" : "client-not-ready",
1430  (unsigned int)payload_size,
1431  GCCH_2s(ch),
1432  ntohl(ccc->ccn.channel_of_client),
1433  ccc,
1434  ntohl(msg->mid.mid),
1435  ntohl(ch->mid_recv.mid));
1436  /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1437  the sender may already be transmitting the previous one. Needs
1438  experimental evaluation to see if/when this ACK helps or
1439  hurts. (We might even want another option.) */
1441 }
1442 
1443 
1454 static void
1455 data_sent_cb(void *cls,
1456  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
1457 
1458 
1465 static void
1467 {
1468  struct CadetChannel *ch = cls;
1469  struct CadetReliableMessage *crm = ch->head_sent;
1470 
1471  ch->retry_data_task = NULL;
1472  GNUNET_assert(NULL == crm->qe);
1474  "Retrying transmission on %s of message %u\n",
1475  GCCH_2s(ch),
1476  (unsigned int)ntohl(crm->data_message->mid.mid));
1477  crm->qe = GCT_send(ch->t, &crm->data_message->header, &data_sent_cb, crm);
1478  GNUNET_assert(NULL == ch->retry_data_task);
1479 }
1480 
1481 
1490 static void
1492  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1493  struct CadetReliableMessage *crm)
1494 {
1496  ch->pending_messages--;
1499  "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1500  GCCH_2s(ch),
1501  (unsigned int)ntohl(crm->data_message->mid.mid),
1502  ch->pending_messages);
1503  if (NULL != crm->qe)
1504  {
1505  GCT_send_cancel(crm->qe);
1506  crm->qe = NULL;
1507  }
1508  if ((1 == crm->num_transmissions) && (NULL != cti))
1509  {
1510  GCC_ack_observed(cti);
1511  if (0 == GNUNET_memcmp(cti, &crm->connection_taken))
1512  {
1515  crm->first_transmission_time));
1516  }
1517  }
1518  GNUNET_free(crm->data_message);
1519  GNUNET_free(crm);
1520  send_ack_to_client(ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1521 }
1522 
1523 
1532 void
1534  struct CadetChannel *ch,
1535  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1536  const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1537 {
1538  struct CadetReliableMessage *crm;
1539  struct CadetReliableMessage *crmn;
1540  int found;
1541  uint32_t mid_base;
1542  uint64_t mid_mask;
1543  unsigned int delta;
1544 
1546  if (GNUNET_NO == ch->reliable)
1547  {
1548  /* not expecting ACKs on unreliable channel, odd */
1549  GNUNET_break_op(0);
1550  return;
1551  }
1552  /* mid_base is the MID of the next message that the
1553  other peer expects (i.e. that is missing!), everything
1554  LOWER (but excluding mid_base itself) was received. */
1555  mid_base = ntohl(ack->mid.mid);
1556  mid_mask = GNUNET_htonll(ack->futures);
1557  found = GNUNET_NO;
1558  for (crm = ch->head_sent; NULL != crm; crm = crmn)
1559  {
1560  crmn = crm->next;
1561  delta = (unsigned int)(ntohl(crm->data_message->mid.mid) - mid_base);
1562  if (delta >= UINT_MAX - ch->max_pending_messages)
1563  {
1564  /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1566  "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1567  (unsigned int)mid_base,
1568  ntohl(crm->data_message->mid.mid),
1569  GCCH_2s(ch));
1570  handle_matching_ack(ch, cti, crm);
1571  found = GNUNET_YES;
1572  continue;
1573  }
1574  delta--;
1575  if (delta >= 64)
1576  continue;
1578  "Testing bit %llX for mid %u (base: %u)\n",
1579  (1LLU << delta),
1580  ntohl(crm->data_message->mid.mid),
1581  mid_base);
1582  if (0 != (mid_mask & (1LLU << delta)))
1583  {
1585  "Got DATA_ACK with mask for %u on %s\n",
1586  ntohl(crm->data_message->mid.mid),
1587  GCCH_2s(ch));
1588  handle_matching_ack(ch, cti, crm);
1589  found = GNUNET_YES;
1590  }
1591  }
1592  if (GNUNET_NO == found)
1593  {
1594  /* ACK for message we already dropped, might have been a
1595  duplicate ACK? Ignore. */
1597  "Duplicate DATA_ACK on %s, ignoring\n",
1598  GCCH_2s(ch));
1599  GNUNET_STATISTICS_update(stats, "# duplicate DATA_ACKs", 1, GNUNET_NO);
1600  return;
1601  }
1602  if (NULL != ch->retry_data_task)
1603  {
1605  ch->retry_data_task = NULL;
1606  }
1607  if ((NULL != ch->head_sent) && (NULL == ch->head_sent->qe))
1610  ch);
1611 }
1612 
1613 
1623 void
1625  struct CadetChannel *ch,
1626  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
1627 {
1628  struct CadetChannelClient *ccc;
1629 
1632  "Received remote channel DESTROY for %s\n",
1633  GCCH_2s(ch));
1634  if (GNUNET_YES == ch->destroy)
1635  {
1636  /* Local client already gone, this is instant-death. */
1637  channel_destroy(ch);
1638  return;
1639  }
1640  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1641  if ((NULL != ccc) && (NULL != ccc->head_recv))
1642  {
1644  "Lost end of transmission due to remote shutdown on %s\n",
1645  GCCH_2s(ch));
1646  /* FIXME: change API to notify client about truncated transmission! */
1647  }
1648  ch->destroy = GNUNET_YES;
1649  if (NULL != ccc)
1650  GSC_handle_remote_channel_destroy(ccc->c, ccc->ccn, ch);
1651  channel_destroy(ch);
1652 }
1653 
1654 
1663 static int
1665  struct CadetReliableMessage *crm1,
1666  struct CadetReliableMessage *crm2)
1667 {
1668  if (crm1->next_retry.abs_value_us < crm2->next_retry.abs_value_us)
1669  return GNUNET_YES;
1670  return GNUNET_NO;
1671 }
1672 
1673 
1684 static void
1685 data_sent_cb(void *cls,
1686  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1687 {
1688  struct CadetReliableMessage *crm = cls;
1689  struct CadetChannel *ch = crm->ch;
1690 
1692  GNUNET_assert(NULL != crm->qe);
1693  crm->qe = NULL;
1695  if (GNUNET_NO == ch->reliable)
1696  {
1697  GNUNET_free(crm->data_message);
1698  GNUNET_free(crm);
1699  ch->pending_messages--;
1700  send_ack_to_client(ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1701  return;
1702  }
1703  if (NULL == cid)
1704  {
1705  /* There was an error sending. */
1707  }
1708  else if (GNUNET_SYSERR != crm->num_transmissions)
1709  {
1710  /* Increment transmission counter, and possibly store @a cid
1711  if this was the first transmission. */
1712  crm->num_transmissions++;
1713  if (1 == crm->num_transmissions)
1714  {
1716  crm->connection_taken = *cid;
1717  GCC_ack_expected(cid);
1718  }
1719  }
1720  if ((0 == crm->retry_delay.rel_value_us) && (NULL != cid))
1721  {
1722  struct CadetConnection *cc = GCC_lookup(cid);
1723 
1724  if (NULL != cc)
1726  else
1727  crm->retry_delay = ch->retry_time;
1728  }
1732 
1735  NULL,
1736  ch->head_sent,
1737  ch->tail_sent,
1738  crm);
1740  "Message %u sent, next transmission on %s in %s\n",
1741  (unsigned int)ntohl(crm->data_message->mid.mid),
1742  GCCH_2s(ch),
1744  ch->head_sent->next_retry),
1745  GNUNET_YES));
1746  if (NULL == ch->head_sent->qe)
1747  {
1748  if (NULL != ch->retry_data_task)
1752  ch);
1753  }
1754 }
1755 
1756 
1771 int
1773  struct GNUNET_CADET_ClientChannelNumber sender_ccn,
1774  const char *buf,
1775  size_t buf_len)
1776 {
1777  struct CadetReliableMessage *crm;
1778 
1779  if (ch->pending_messages >= ch->max_pending_messages)
1780  {
1781  GNUNET_break(0); /* Fails: #5370 */
1782  return GNUNET_SYSERR;
1783  }
1784  if (GNUNET_YES == ch->destroy)
1785  {
1786  /* we are going down, drop messages */
1787  return GNUNET_OK;
1788  }
1789  ch->pending_messages++;
1790 
1791  if (GNUNET_YES == ch->is_loopback)
1792  {
1793  struct CadetChannelClient *receiver;
1794  struct GNUNET_MQ_Envelope *env;
1795  struct GNUNET_CADET_LocalData *ld;
1796  int ack_to_owner;
1797 
1798  env =
1800  if ((NULL != ch->owner) &&
1801  (sender_ccn.channel_of_client == ch->owner->ccn.channel_of_client))
1802  {
1803  receiver = ch->dest;
1804  ack_to_owner = GNUNET_YES;
1805  }
1806  else if ((NULL != ch->dest) &&
1807  (sender_ccn.channel_of_client == ch->dest->ccn.channel_of_client))
1808  {
1809  receiver = ch->owner;
1810  ack_to_owner = GNUNET_NO;
1811  }
1812  else
1813  {
1814  GNUNET_break(0);
1815  return GNUNET_SYSERR;
1816  }
1817  GNUNET_assert(NULL != receiver);
1818  ld->ccn = receiver->ccn;
1819  GNUNET_memcpy(&ld[1], buf, buf_len);
1820  if (GNUNET_YES == receiver->client_ready)
1821  {
1822  ch->pending_messages--;
1823  GSC_send_to_client(receiver->c, env);
1824  send_ack_to_client(ch, ack_to_owner);
1825  }
1826  else
1827  {
1828  struct CadetOutOfOrderMessage *oom;
1829 
1830  oom = GNUNET_new(struct CadetOutOfOrderMessage);
1831  oom->env = env;
1833  receiver->tail_recv,
1834  oom);
1835  receiver->num_recv++;
1836  }
1837  return GNUNET_OK;
1838  }
1839 
1840  /* Everything is correct, send the message. */
1841  crm = GNUNET_malloc(sizeof(*crm));
1842  crm->ch = ch;
1843  crm->data_message = GNUNET_malloc(
1844  sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1845  crm->data_message->header.size =
1846  htons(sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1847  crm->data_message->header.type =
1849  ch->mid_send.mid = htonl(ntohl(ch->mid_send.mid) + 1);
1850  crm->data_message->mid = ch->mid_send;
1851  crm->data_message->ctn = ch->ctn;
1852  GNUNET_memcpy(&crm->data_message[1], buf, buf_len);
1855  "Sending message %u from local client to %s with %u bytes\n",
1856  ntohl(crm->data_message->mid.mid),
1857  GCCH_2s(ch),
1858  buf_len);
1859  if (NULL != ch->retry_data_task)
1860  {
1862  ch->retry_data_task = NULL;
1863  }
1864  crm->qe = GCT_send(ch->t, &crm->data_message->header, &data_sent_cb, crm);
1865  GNUNET_assert(NULL == ch->retry_data_task);
1866  return GNUNET_OK;
1867 }
1868 
1869 
1877 void
1879  struct GNUNET_CADET_ClientChannelNumber client_ccn)
1880 {
1881  struct CadetChannelClient *ccc;
1882  struct CadetOutOfOrderMessage *com;
1883 
1884  if ((NULL != ch->owner) &&
1885  (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client))
1886  ccc = ch->owner;
1887  else if ((NULL != ch->dest) &&
1888  (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client))
1889  ccc = ch->dest;
1890  else
1891  GNUNET_assert(0);
1892  ccc->client_ready = GNUNET_YES;
1893  com = ccc->head_recv;
1894  if (NULL == com)
1895  {
1897  "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
1898  GSC_2s(ccc->c),
1899  ntohl(client_ccn.channel_of_client),
1900  GCCH_2s(ch),
1901  ntohl(ccc->ccn.channel_of_client),
1902  ccc);
1903  return; /* none pending */
1904  }
1905  if (GNUNET_YES == ch->is_loopback)
1906  {
1907  int to_owner;
1908 
1909  /* Messages are always in-order, just send */
1911  ccc->num_recv--;
1912  GSC_send_to_client(ccc->c, com->env);
1913  /* Notify sender that we can receive more */
1914  if ((NULL != ch->owner) &&
1916  {
1917  to_owner = GNUNET_NO;
1918  }
1919  else
1920  {
1921  GNUNET_assert((NULL != ch->dest) && (ccc->ccn.channel_of_client ==
1922  ch->dest->ccn.channel_of_client));
1923  to_owner = GNUNET_YES;
1924  }
1925  send_ack_to_client(ch, to_owner);
1926  GNUNET_free(com);
1927  return;
1928  }
1929 
1930  if ((com->mid.mid != ch->mid_recv.mid) && (GNUNET_NO == ch->out_of_order) &&
1931  (GNUNET_YES == ch->reliable))
1932  {
1934  "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
1935  GSC_2s(ccc->c),
1936  ntohl(ccc->ccn.channel_of_client),
1937  ntohl(com->mid.mid),
1938  ntohl(ch->mid_recv.mid));
1939  return; /* missing next one in-order */
1940  }
1941 
1943  "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
1944  ntohl(com->mid.mid),
1945  GSC_2s(ccc->c),
1946  ntohl(ccc->ccn.channel_of_client),
1947  GCCH_2s(ch));
1948 
1949  /* all good, pass next message to client */
1951  ccc->num_recv--;
1952  /* FIXME: if unreliable, this is not aggressive
1953  enough, as it would be OK to have lost some! */
1954 
1955  ch->mid_recv.mid = htonl(1 + ntohl(com->mid.mid));
1956  ch->mid_futures >>= 1; /* equivalent to division by 2 */
1957  ccc->client_ready = GNUNET_NO;
1958  GSC_send_to_client(ccc->c, com->env);
1959  GNUNET_free(com);
1961  if (NULL != ccc->head_recv)
1962  return;
1963  if (GNUNET_NO == ch->destroy)
1964  return;
1965  GCT_send_channel_destroy(ch->t, ch->ctn);
1966  channel_destroy(ch);
1967 }
1968 
1969 
1970 #define LOG2(level, ...) \
1971  GNUNET_log_from_nocheck(level, "cadet-chn", __VA_ARGS__)
1972 
1973 
1980 void
1982 {
1983 #if !defined(GNUNET_CULL_LOGGING)
1984  int do_log;
1985 
1987  "cadet-chn",
1988  __FILE__,
1989  __FUNCTION__,
1990  __LINE__);
1991  if (0 == do_log)
1992  return;
1993 
1994  if (NULL == ch)
1995  {
1996  LOG2(level, "CHN *** DEBUG NULL CHANNEL ***\n");
1997  return;
1998  }
1999  LOG2(level, "CHN %s:%X (%p)\n", GCT_2s(ch->t), ch->ctn, ch);
2000  if (NULL != ch->owner)
2001  {
2002  LOG2(level,
2003  "CHN origin %s ready %s local-id: %u\n",
2004  GSC_2s(ch->owner->c),
2005  ch->owner->client_ready ? "YES" : "NO",
2006  ntohl(ch->owner->ccn.channel_of_client));
2007  }
2008  if (NULL != ch->dest)
2009  {
2010  LOG2(level,
2011  "CHN destination %s ready %s local-id: %u\n",
2012  GSC_2s(ch->dest->c),
2013  ch->dest->client_ready ? "YES" : "NO",
2014  ntohl(ch->dest->ccn.channel_of_client));
2015  }
2016  LOG2(level,
2017  "CHN Message IDs recv: %d (%LLX), send: %d\n",
2018  ntohl(ch->mid_recv.mid),
2019  (unsigned long long)ch->mid_futures,
2020  ntohl(ch->mid_send.mid));
2021 #endif
2022 }
2023 
2024 
2025 /* end of gnunet-service-cadet-new_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.
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
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.
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:212
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 CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
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.
int nobuffer
Is the tunnel bufferless (minimum latency)?
#define GNUNET_NO
Definition: gnunet_common.h:78
CadetChannelState
All the states a channel can be in.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:445
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.
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:431
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.
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:1237
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 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:1264
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:686
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:102
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:194
#define TIMEOUT_CLOSED_PORT
How long do we wait before dropping state about incoming connection to closed port?
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:319
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:35
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.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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:471
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:221
#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...
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
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:373
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:131
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...
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...
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.
#define GNUNET_YES
Definition: gnunet_common.h:77
Message for cadet data traffic.
Definition: cadet.h:185
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:139
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:1214
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:488
#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:956
struct GNUNET_HashCode port
Destination port of the channel.