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
399 {
400 
401  ch->type = message->type;
402 
403 }
404 
405 
411 int
412 GCCH_is_type_to_drop (struct CadetChannel *ch, const struct
413  GNUNET_MessageHeader *message)
414 {
415 
416  if (ch->type == message->type)
417  {
418  ch->type = 0;
419  return GNUNET_YES;
420  }
421  else
422  return GNUNET_NO;
423 }
424 
425 
433 const char *
434 GCCH_2s (const struct CadetChannel *ch)
435 {
436  static char buf[128];
437 
438  GNUNET_snprintf (buf,
439  sizeof(buf),
440  "Channel %s:%s ctn:%X(%X/%X)",
441  (GNUNET_YES == ch->is_loopback)
442  ? "loopback"
444  GNUNET_h2s (&ch->port),
445  ch->ctn,
446  (NULL == ch->owner)
447  ? 0
448  : ntohl (ch->owner->ccn.channel_of_client),
449  (NULL == ch->dest)
450  ? 0
451  : ntohl (ch->dest->ccn.channel_of_client));
452  return buf;
453 }
454 
455 
465 void
467  const struct GNUNET_HashCode *port,
468  const struct GNUNET_PeerIdentity *listener)
469 {
470  struct GNUNET_HashContext *hc;
471 
473  GNUNET_CRYPTO_hash_context_read (hc, port, sizeof(*port));
474  GNUNET_CRYPTO_hash_context_read (hc, listener, sizeof(*listener));
477  "Calculated port hash %s\n",
478  GNUNET_h2s (h_port));
479 }
480 
481 
490 GCCH_get_id (const struct CadetChannel *ch)
491 {
492  return ch->ctn;
493 }
494 
495 
501 static void
503 {
504  struct CadetOutOfOrderMessage *com;
505 
506  while (NULL != (com = ccc->head_recv))
507  {
509  ccc->num_recv--;
510  GNUNET_MQ_discard (com->env);
511  GNUNET_free (com);
512  }
513  GNUNET_free (ccc);
514 }
515 
516 
522 static void
524 {
525  struct CadetReliableMessage *crm;
526 
527  while (NULL != (crm = ch->head_sent))
528  {
529  GNUNET_assert (ch == crm->ch);
530  if (NULL != crm->qe)
531  {
532  GCT_send_cancel (crm->qe);
533  crm->qe = NULL;
534  }
536  GNUNET_free (crm->data_message);
537  GNUNET_free (crm);
538  }
539  if (CADET_CHANNEL_LOOSE == ch->state)
540  {
541  GSC_drop_loose_channel (&ch->h_port, ch);
542  }
543  if (NULL != ch->owner)
544  {
546  ch->owner = NULL;
547  }
548  if (NULL != ch->dest)
549  {
551  ch->dest = NULL;
552  }
553  if (NULL != ch->last_control_qe)
554  {
556  ch->last_control_qe = NULL;
557  }
558  if (NULL != ch->retry_data_task)
559  {
561  ch->retry_data_task = NULL;
562  }
563  if (NULL != ch->retry_control_task)
564  {
566  ch->retry_control_task = NULL;
567  }
568  if (GNUNET_NO == ch->is_loopback)
569  {
570  GCT_remove_channel (ch->t, ch, ch->ctn);
571  ch->t = NULL;
572  }
573  GNUNET_free (ch);
574 }
575 
576 
582 static void
583 send_channel_open (void *cls);
584 
585 
594 static void
596  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
597 {
598  struct CadetChannel *ch = cls;
599 
600  GNUNET_assert (NULL != ch->last_control_qe);
601  ch->last_control_qe = NULL;
604  "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
605  GCCH_2s (ch),
607  ch->retry_control_task =
609 }
610 
611 
617 static void
618 send_channel_open (void *cls)
619 {
620  struct CadetChannel *ch = cls;
621  struct GNUNET_CADET_ChannelOpenMessage msgcc;
622 
623  ch->retry_control_task = NULL;
625  "Sending CHANNEL_OPEN message for %s\n",
626  GCCH_2s (ch));
627  msgcc.header.size = htons (sizeof(msgcc));
629  // TODO This will be removed in a major release, because this will be a protocol breaking change. We set the deprecated "reliable" bit here that was removed.
630  msgcc.opt = 2;
631  msgcc.h_port = ch->h_port;
632  msgcc.ctn = ch->ctn;
634  if (NULL != ch->last_control_qe)
636  ch->last_control_qe =
637  GCT_send (ch->t, &msgcc.header, &channel_open_sent_cb, ch, &msgcc.ctn);
638  GNUNET_assert (NULL == ch->retry_control_task);
639 }
640 
641 
652 void
654 {
655  GNUNET_assert (NULL == ch->retry_control_task);
657  "Tunnel up, sending CHANNEL_OPEN on %s now\n",
658  GCCH_2s (ch));
660 }
661 
662 
673 struct CadetChannel *
676  struct CadetPeer *destination,
677  const struct GNUNET_HashCode *port,
678  uint32_t options)
679 {
680  struct CadetChannel *ch;
681  struct CadetChannelClient *ccco;
682 
683  ccco = GNUNET_new (struct CadetChannelClient);
684  ccco->c = owner;
685  ccco->ccn = ccn;
686  ccco->client_ready = GNUNET_YES;
687 
688  ch = GNUNET_new (struct CadetChannel);
689  ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */
690  ch->nobuffer = GNUNET_NO;
691  ch->reliable = GNUNET_YES;
692  ch->out_of_order = GNUNET_NO;
694  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
695  ch->owner = ccco;
696  ch->port = *port;
697  GCCH_hash_port (&ch->h_port, port, GCP_get_id (destination));
698  if (0 == GNUNET_memcmp (&my_full_id, GCP_get_id (destination)))
699  {
700  struct OpenPort *op;
701 
702  ch->is_loopback = GNUNET_YES;
704  if (NULL == op)
705  {
706  /* port closed, wait for it to possibly open */
710  &ch->h_port,
711  ch,
714  "Created loose incoming loopback channel to port %s\n",
715  GNUNET_h2s (&ch->port));
716  }
717  else
718  {
719  GCCH_bind (ch, op->c, &op->port);
720  }
721  }
722  else
723  {
724  ch->t = GCP_get_tunnel (destination, GNUNET_YES);
726  ch->ctn = GCT_add_channel (ch->t, ch);
727  }
728  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
730  "Created channel to port %s at peer %s for %s using %s\n",
731  GNUNET_h2s (port),
732  GCP_2s (destination),
733  GSC_2s (owner),
734  (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
735  return ch;
736 }
737 
738 
745 static void
746 timeout_closed_cb (void *cls)
747 {
748  struct CadetChannel *ch = cls;
749 
750  ch->retry_control_task = NULL;
752  "Closing incoming channel to port %s from peer %s due to timeout\n",
753  GNUNET_h2s (&ch->port),
754  GCP_2s (GCT_get_destination (ch->t)));
755  channel_destroy (ch);
756 }
757 
758 
768 struct CadetChannel *
771  const struct GNUNET_HashCode *h_port,
772  uint32_t options)
773 {
774  struct CadetChannel *ch;
775  struct OpenPort *op;
776 
777  ch = GNUNET_new (struct CadetChannel);
778  ch->h_port = *h_port;
779  ch->t = t;
780  ch->ctn = ctn;
782  ch->nobuffer = GNUNET_NO;
783  ch->reliable = GNUNET_YES;
784  ch->out_of_order = GNUNET_NO;
786  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
787  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
788 
790  if (NULL == op)
791  {
792  /* port closed, wait for it to possibly open */
796  &ch->h_port,
797  ch,
799  GNUNET_assert (NULL == ch->retry_control_task);
802  ch);
804  "Created loose incoming channel to port %s from peer %s\n",
805  GNUNET_h2s (&ch->port),
806  GCP_2s (GCT_get_destination (ch->t)));
807  }
808  else
809  {
810  GCCH_bind (ch, op->c, &op->port);
811  }
812  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
813  return ch;
814 }
815 
816 
826 static void
827 send_ack_cb (void *cls,
828  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
829 {
830  struct CadetChannel *ch = cls;
831 
832  GNUNET_assert (NULL != ch->last_control_qe);
833  ch->last_control_qe = NULL;
834 }
835 
836 
842 static void
844 {
846 
847  if (GNUNET_NO == ch->reliable)
848  return; /* no ACKs */
850  msg.header.size = htons (sizeof(msg));
851  msg.ctn = ch->ctn;
852  msg.mid.mid = htonl (ntohl (ch->mid_recv.mid));
853  msg.futures = GNUNET_htonll (ch->mid_futures);
855  "Sending DATA_ACK %u:%llX via %s\n",
856  (unsigned int) ntohl (msg.mid.mid),
857  (unsigned long long) ch->mid_futures,
858  GCCH_2s (ch));
859  if (NULL != ch->last_control_qe)
861  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch,
862  &msg.ctn);
863 }
864 
865 
872 static void
873 send_open_ack (void *cls)
874 {
875  struct CadetChannel *ch = cls;
877 
878  ch->retry_control_task = NULL;
880  "Sending CHANNEL_OPEN_ACK on %s\n",
881  GCCH_2s (ch));
883  msg.header.size = htons (sizeof(msg));
884  msg.reserved = htonl (0);
885  msg.ctn = ch->ctn;
886  msg.port = ch->port;
887  if (NULL != ch->last_control_qe)
889  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch,
890  &msg.ctn);
891 }
892 
893 
902 void
904  struct CadetChannel *ch,
905  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
906 {
907  if (NULL == ch->dest)
908  {
910  "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
911  GCCH_2s (ch));
912  return;
913  }
914  if (NULL != ch->retry_control_task)
915  {
917  "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
918  GCCH_2s (ch));
919  return;
920  }
922  "Retransmitting CHANNEL_OPEN_ACK on %s\n",
923  GCCH_2s (ch));
925 }
926 
927 
935 static void
936 send_ack_to_client (struct CadetChannel *ch, int to_owner)
937 {
938  struct GNUNET_MQ_Envelope *env;
939  struct GNUNET_CADET_LocalAck *ack;
940  struct CadetChannelClient *ccc;
941 
942  ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
943  if (NULL == ccc)
944  {
945  /* This can happen if we are just getting ACKs after
946  our local client already disconnected. */
948  return;
949  }
951  ack->ccn = ccc->ccn;
953  "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X (%u/%u pending)\n",
954  GSC_2s (ccc->c),
955  (GNUNET_YES == to_owner) ? "owner" : "dest",
956  ntohl (ack->ccn.channel_of_client),
957  ch->pending_messages,
959  GSC_send_to_client (ccc->c, env);
960 }
961 
962 
972 void
974  struct CadetClient *c,
975  const struct GNUNET_HashCode *port)
976 {
977  uint32_t options;
978  struct CadetChannelClient *cccd;
979 
981  "Binding %s from %s to port %s of %s\n",
982  GCCH_2s (ch),
983  GCT_2s (ch->t),
984  GNUNET_h2s (&ch->port),
985  GSC_2s (c));
986  if (NULL != ch->retry_control_task)
987  {
988  /* there might be a timeout task here */
990  ch->retry_control_task = NULL;
991  }
992  options = 0;
993  cccd = GNUNET_new (struct CadetChannelClient);
994  GNUNET_assert (NULL == ch->dest);
995  ch->dest = cccd;
996  ch->port = *port;
997  cccd->c = c;
998  cccd->client_ready = GNUNET_YES;
999  cccd->ccn = GSC_bind (c,
1000  ch,
1001  (GNUNET_YES == ch->is_loopback)
1003  : GCT_get_destination (ch->t),
1004  port,
1005  options);
1006  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1008  ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */
1009  if (GNUNET_YES == ch->is_loopback)
1010  {
1012  GCCH_handle_channel_open_ack (ch, NULL, port);
1013  }
1014  else
1015  {
1016  /* notify other peer that we accepted the connection */
1017  ch->state = CADET_CHANNEL_READY;
1019  }
1020  /* give client it's initial supply of ACKs */
1021  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1023  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1025 }
1026 
1027 
1035 static void
1037 {
1038  struct CadetChannel *ch = cls;
1039  struct CadetChannelClient *ccc;
1040 
1041  /* Find which end is left... */
1042  ch->retry_control_task = NULL;
1043  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1044  GSC_handle_remote_channel_destroy (ccc->c, ccc->ccn, ch);
1045  channel_destroy (ch);
1046 }
1047 
1048 
1057 void
1059  struct CadetClient *c,
1061 {
1063  "%s asks for destruction of %s\n",
1064  GSC_2s (c),
1065  GCCH_2s (ch));
1066  GNUNET_assert (NULL != c);
1067  if ((NULL != ch->owner) && (c == ch->owner->c) &&
1069  {
1070  free_channel_client (ch->owner);
1071  ch->owner = NULL;
1072  }
1073  else if ((NULL != ch->dest) && (c == ch->dest->c) &&
1075  {
1076  free_channel_client (ch->dest);
1077  ch->dest = NULL;
1078  }
1079  else
1080  {
1081  GNUNET_assert (0);
1082  }
1083 
1084  if (GNUNET_YES == ch->destroy)
1085  {
1086  /* other end already destroyed, with the local client gone, no need
1087  to finish transmissions, just destroy immediately. */
1088  channel_destroy (ch);
1089  return;
1090  }
1091  if ((NULL != ch->head_sent) && ((NULL != ch->owner) || (NULL != ch->dest)))
1092  {
1093  /* Wait for other end to destroy us as well,
1094  and otherwise allow send queue to be transmitted first */
1095  ch->destroy = GNUNET_YES;
1096  return;
1097  }
1098  if ((GNUNET_YES == ch->is_loopback) &&
1099  ((NULL != ch->owner) || (NULL != ch->dest)))
1100  {
1101  if (NULL != ch->retry_control_task)
1103  ch->retry_control_task =
1105  return;
1106  }
1107  if (GNUNET_NO == ch->is_loopback)
1108  {
1109  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1110  switch (ch->state)
1111  {
1112  case CADET_CHANNEL_NEW:
1113  /* We gave up on a channel that we created as a client to a remote
1114  target, but that never went anywhere. Nothing to do here. */
1115  break;
1116 
1117  case CADET_CHANNEL_LOOSE:
1118  break;
1119 
1120  default:
1121  GCT_send_channel_destroy (ch->t, ch->ctn);
1122  }
1123  }
1124  /* Nothing left to do, just finish destruction */
1125  channel_destroy (ch);
1126 }
1127 
1128 
1138 void
1140  struct CadetChannel *ch,
1141  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1142  const struct GNUNET_HashCode *port)
1143 {
1144  switch (ch->state)
1145  {
1146  case CADET_CHANNEL_NEW:
1147  /* this should be impossible */
1148  GNUNET_break (0);
1149  break;
1150 
1151  case CADET_CHANNEL_LOOSE:
1152  /* This makes no sense. */
1153  GNUNET_break_op (0);
1154  break;
1155 
1157  if (NULL == ch->owner)
1158  {
1159  /* We're not the owner, wrong direction! */
1160  GNUNET_break_op (0);
1161  return;
1162  }
1163  if (0 != GNUNET_memcmp (&ch->port, port))
1164  {
1165  /* Other peer failed to provide the right port,
1166  refuse connection. */
1167  GNUNET_break_op (0);
1168  return;
1169  }
1171  "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1172  GCCH_2s (ch));
1173  if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1174  {
1176  ch->retry_control_task = NULL;
1177  }
1178  ch->state = CADET_CHANNEL_READY;
1179  /* On first connect, send client as many ACKs as we allow messages
1180  to be buffered! */
1181  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1183  break;
1184 
1185  case CADET_CHANNEL_READY:
1186  /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1188  "Received duplicate channel OPEN_ACK for %s\n",
1189  GCCH_2s (ch));
1190  GNUNET_STATISTICS_update (stats, "# duplicate CREATE_ACKs", 1, GNUNET_NO);
1191  break;
1192  }
1193 }
1194 
1195 
1204 static int
1205 is_before (void *cls,
1206  struct CadetOutOfOrderMessage *m1,
1207  struct CadetOutOfOrderMessage *m2)
1208 {
1209  int *duplicate = cls;
1210  uint32_t v1 = ntohl (m1->mid.mid);
1211  uint32_t v2 = ntohl (m2->mid.mid);
1212  uint32_t delta;
1213 
1214  delta = v2 - v1;
1215  if (0 == delta)
1216  *duplicate = GNUNET_YES;
1217  if (delta > (uint32_t) INT_MAX)
1218  {
1219  /* in overflow range, we can safely assume we wrapped around */
1220  return GNUNET_NO;
1221  }
1222  else
1223  {
1224  /* result is small, thus v2 > v1, thus m1 < m2 */
1225  return GNUNET_YES;
1226  }
1227 }
1228 
1229 
1238 void
1240  struct CadetChannel *ch,
1241  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1243 {
1244  struct GNUNET_MQ_Envelope *env;
1245  struct GNUNET_CADET_LocalData *ld;
1246  struct CadetChannelClient *ccc;
1247  size_t payload_size;
1248  struct CadetOutOfOrderMessage *com;
1249  int duplicate;
1250  uint32_t mid_min;
1251  uint32_t mid_max;
1252  uint32_t mid_msg;
1253  uint32_t delta;
1254 
1256  if ((NULL == ch->owner) && (NULL == ch->dest))
1257  {
1258  /* This client is gone, but we still have messages to send to
1259  the other end (which is why @a ch is not yet dead). However,
1260  we cannot pass messages to our client anymore. */
1262  "Dropping incoming payload on %s as this end is already closed\n",
1263  GCCH_2s (ch));
1264  /* send back DESTROY notification to stop further retransmissions! */
1265  if (GNUNET_YES == ch->destroy)
1266  GCT_send_channel_destroy (ch->t, ch->ctn);
1267  return;
1268  }
1269  payload_size = ntohs (msg->header.size) - sizeof(*msg);
1270  env = GNUNET_MQ_msg_extra (ld,
1271  payload_size,
1273  ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1274  GNUNET_memcpy (&ld[1], &msg[1], payload_size);
1275  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1276  if (GNUNET_YES == ccc->client_ready)
1277  {
1278  /*
1279  * We ad-hoc send the message if
1280  * - The channel is out-of-order
1281  * - The channel is reliable and MID matches next expected MID
1282  * - The channel is unreliable and MID is before lowest seen MID
1283  */if ((GNUNET_YES == ch->out_of_order) ||
1284  ((msg->mid.mid == ch->mid_recv.mid) && (GNUNET_YES == ch->reliable)) ||
1285  ((GNUNET_NO == ch->reliable) &&
1286  (ntohl (msg->mid.mid) >= ntohl (ch->mid_recv.mid)) &&
1287  ((NULL == ccc->head_recv) ||
1288  (ntohl (msg->mid.mid) < ntohl (ccc->head_recv->mid.mid)))))
1289  {
1291  "Giving %u bytes of payload with MID %u from %s to client %s\n",
1292  (unsigned int) payload_size,
1293  ntohl (msg->mid.mid),
1294  GCCH_2s (ch),
1295  GSC_2s (ccc->c));
1296  ccc->client_ready = GNUNET_NO;
1297  GSC_send_to_client (ccc->c, env);
1298  if (GNUNET_NO == ch->out_of_order)
1299  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1300  else
1301  ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
1302  ch->mid_futures >>= 1;
1303  if ((GNUNET_YES == ch->out_of_order) && (GNUNET_NO == ch->reliable))
1304  {
1305  /* possibly shift by more if we skipped messages */
1306  uint64_t delta = htonl (msg->mid.mid) - 1 - ntohl (ch->mid_recv.mid);
1307 
1308  if (delta > 63)
1309  ch->mid_futures = 0;
1310  else
1311  ch->mid_futures >>= delta;
1312  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1313  }
1314  send_channel_data_ack (ch);
1315  return;
1316  }
1317  }
1318 
1319  if (GNUNET_YES == ch->reliable)
1320  {
1321  /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1322  mid_min = ntohl (ch->mid_recv.mid);
1323  mid_max = mid_min + ch->max_pending_messages;
1324  mid_msg = ntohl (msg->mid.mid);
1325  if (((uint32_t) (mid_msg - mid_min) > ch->max_pending_messages) ||
1326  ((uint32_t) (mid_max - mid_msg) > ch->max_pending_messages))
1327  {
1329  "%s at %u drops ancient or far-future message %u\n",
1330  GCCH_2s (ch),
1331  (unsigned int) mid_min,
1332  ntohl (msg->mid.mid));
1333 
1335  "# duplicate DATA (ancient or future)",
1336  1,
1337  GNUNET_NO);
1338  GNUNET_MQ_discard (env);
1339  send_channel_data_ack (ch);
1340  return;
1341  }
1342  /* mark bit for future ACKs */
1343  delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1344  if (delta < 64)
1345  {
1346  if (0 != (ch->mid_futures & (1LLU << delta)))
1347  {
1348  /* Duplicate within the queue, drop also */
1350  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1351  (unsigned int) payload_size,
1352  GCCH_2s (ch),
1353  ntohl (msg->mid.mid));
1354  GNUNET_STATISTICS_update (stats, "# duplicate DATA", 1, GNUNET_NO);
1355  GNUNET_MQ_discard (env);
1356  send_channel_data_ack (ch);
1357  return;
1358  }
1359  ch->mid_futures |= (1LLU << delta);
1361  "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1362  (1LLU << delta),
1363  mid_msg,
1364  mid_min,
1365  ch->mid_futures);
1366  }
1367  }
1368  else /* ! ch->reliable */
1369  {
1370  struct CadetOutOfOrderMessage *next_msg;
1371 
1376  if ((NULL != ccc->head_recv) && (GNUNET_YES == ccc->client_ready))
1377  {
1378  next_msg = ccc->head_recv;
1380  "Giving queued MID %u from %s to client %s\n",
1381  ntohl (next_msg->mid.mid),
1382  GCCH_2s (ch),
1383  GSC_2s (ccc->c));
1384  ccc->client_ready = GNUNET_NO;
1385  GSC_send_to_client (ccc->c, next_msg->env);
1386  ch->mid_recv.mid = htonl (1 + ntohl (next_msg->mid.mid));
1387  ch->mid_futures >>= 1;
1388  send_channel_data_ack (ch);
1389  GNUNET_CONTAINER_DLL_remove (ccc->head_recv, ccc->tail_recv, next_msg);
1390  ccc->num_recv--;
1391  /* Do not process duplicate MID */
1392  if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
1393  {
1394  /* Duplicate within the queue, drop */
1396  "Message on %s (mid %u) dropped, duplicate\n",
1397  GCCH_2s (ch),
1398  ntohl (msg->mid.mid));
1399  GNUNET_free (next_msg);
1400  GNUNET_MQ_discard (env);
1401  return;
1402  }
1403  GNUNET_free (next_msg);
1404  }
1405 
1406  if (ntohl (msg->mid.mid) < ntohl (ch->mid_recv.mid)) /* Old */
1407  {
1408  /* Duplicate within the queue, drop */
1410  "Message on %s (mid %u) dropped, old.\n",
1411  GCCH_2s (ch),
1412  ntohl (msg->mid.mid));
1413  GNUNET_MQ_discard (env);
1414  return;
1415  }
1416 
1417  /* Channel is unreliable, so we do not ACK. But we also cannot
1418  allow buffering everything, so check if we have space... */
1419  if (ccc->num_recv >= ch->max_pending_messages)
1420  {
1421  struct CadetOutOfOrderMessage *drop;
1422 
1423  /* Yep, need to drop. Drop the oldest message in
1424  the buffer. */
1426  "Queue full due slow client on %s, dropping oldest message\n",
1427  GCCH_2s (ch));
1429  "# messages dropped due to slow client",
1430  1,
1431  GNUNET_NO);
1432  drop = ccc->head_recv;
1433  GNUNET_assert (NULL != drop);
1434  GNUNET_CONTAINER_DLL_remove (ccc->head_recv, ccc->tail_recv, drop);
1435  ccc->num_recv--;
1436  GNUNET_MQ_discard (drop->env);
1437  GNUNET_free (drop);
1438  }
1439  }
1440 
1441  /* Insert message into sorted out-of-order queue */
1442  com = GNUNET_new (struct CadetOutOfOrderMessage);
1443  com->mid = msg->mid;
1444  com->env = env;
1445  duplicate = GNUNET_NO;
1447  is_before,
1448  &duplicate,
1449  ccc->head_recv,
1450  ccc->tail_recv,
1451  com);
1452  ccc->num_recv++;
1453  if (GNUNET_YES == duplicate)
1454  {
1455  /* Duplicate within the queue, drop also (this is not covered by
1456  the case above if "delta" >= 64, which could be the case if
1457  max_pending_messages is also >= 64 or if our client is unready
1458  and we are seeing retransmissions of the message our client is
1459  blocked on. */LOG (GNUNET_ERROR_TYPE_DEBUG,
1460  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1461  (unsigned int) payload_size,
1462  GCCH_2s (ch),
1463  ntohl (msg->mid.mid));
1464  GNUNET_STATISTICS_update (stats, "# duplicate DATA", 1, GNUNET_NO);
1466  ccc->num_recv--;
1467  GNUNET_MQ_discard (com->env);
1468  GNUNET_free (com);
1469  send_channel_data_ack (ch);
1470  return;
1471  }
1473  "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1474  (GNUNET_YES == ccc->client_ready) ? "out-of-order" : "client-not-ready",
1475  (unsigned int) payload_size,
1476  GCCH_2s (ch),
1477  ntohl (ccc->ccn.channel_of_client),
1478  ccc,
1479  ntohl (msg->mid.mid),
1480  ntohl (ch->mid_recv.mid));
1481  /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1482  the sender may already be transmitting the previous one. Needs
1483  experimental evaluation to see if/when this ACK helps or
1484  hurts. (We might even want another option.) */
1485  send_channel_data_ack (ch);
1486 }
1487 
1488 
1499 static void
1500 data_sent_cb (void *cls,
1501  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
1502 
1503 
1510 static void
1512 {
1513  struct CadetChannel *ch = cls;
1514  struct CadetReliableMessage *crm = ch->head_sent;
1515 
1516  ch->retry_data_task = NULL;
1517  GNUNET_assert (NULL == crm->qe);
1519  "Retrying transmission on %s of message %u\n",
1520  GCCH_2s (ch),
1521  (unsigned int) ntohl (crm->data_message->mid.mid));
1522  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm,
1523  &crm->data_message->ctn);
1524  GNUNET_assert (NULL == ch->retry_data_task);
1525 }
1526 
1527 
1536 static void
1538  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1539  struct CadetReliableMessage *crm)
1540 {
1542  ch->pending_messages--;
1545  "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1546  GCCH_2s (ch),
1547  (unsigned int) ntohl (crm->data_message->mid.mid),
1548  ch->pending_messages);
1549  if (NULL != crm->qe)
1550  {
1551  GCT_send_cancel (crm->qe);
1552  crm->qe = NULL;
1553  }
1554  if ((1 == crm->num_transmissions) && (NULL != cti))
1555  {
1556  GCC_ack_observed (cti);
1557  if (0 == GNUNET_memcmp (cti, &crm->connection_taken))
1558  {
1559  GCC_latency_observed (cti,
1561  crm->first_transmission_time));
1562  }
1563  }
1564  GNUNET_free (crm->data_message);
1565  GNUNET_free (crm);
1566  send_ack_to_client (ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1567 }
1568 
1569 
1578 void
1580  struct CadetChannel *ch,
1581  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1582  const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1583 {
1584  struct CadetReliableMessage *crm;
1585  struct CadetReliableMessage *crmn;
1586  int found;
1587  uint32_t mid_base;
1588  uint64_t mid_mask;
1589  unsigned int delta;
1590 
1592  if (GNUNET_NO == ch->reliable)
1593  {
1594  /* not expecting ACKs on unreliable channel, odd */
1595  GNUNET_break_op (0);
1596  return;
1597  }
1598  /* mid_base is the MID of the next message that the
1599  other peer expects (i.e. that is missing!), everything
1600  LOWER (but excluding mid_base itself) was received. */
1601  mid_base = ntohl (ack->mid.mid);
1602  mid_mask = GNUNET_htonll (ack->futures);
1603  found = GNUNET_NO;
1604  for (crm = ch->head_sent; NULL != crm; crm = crmn)
1605  {
1606  crmn = crm->next;
1607  delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base);
1608  if (delta >= UINT_MAX - ch->max_pending_messages)
1609  {
1610  /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1612  "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1613  (unsigned int) mid_base,
1614  ntohl (crm->data_message->mid.mid),
1615  GCCH_2s (ch));
1616  handle_matching_ack (ch, cti, crm);
1617  found = GNUNET_YES;
1618  continue;
1619  }
1620  delta--;
1621  if (delta >= 64)
1622  continue;
1624  "Testing bit %llX for mid %u (base: %u)\n",
1625  (1LLU << delta),
1626  ntohl (crm->data_message->mid.mid),
1627  mid_base);
1628  if (0 != (mid_mask & (1LLU << delta)))
1629  {
1631  "Got DATA_ACK with mask for %u on %s\n",
1632  ntohl (crm->data_message->mid.mid),
1633  GCCH_2s (ch));
1634  handle_matching_ack (ch, cti, crm);
1635  found = GNUNET_YES;
1636  }
1637  }
1638  if (GNUNET_NO == found)
1639  {
1640  /* ACK for message we already dropped, might have been a
1641  duplicate ACK? Ignore. */
1643  "Duplicate DATA_ACK on %s, ignoring\n",
1644  GCCH_2s (ch));
1645  GNUNET_STATISTICS_update (stats, "# duplicate DATA_ACKs", 1, GNUNET_NO);
1646  return;
1647  }
1648  if (NULL != ch->retry_data_task)
1649  {
1651  ch->retry_data_task = NULL;
1652  }
1653  if ((NULL != ch->head_sent) && (NULL == ch->head_sent->qe))
1656  ch);
1657 }
1658 
1659 
1669 void
1671  struct CadetChannel *ch,
1672  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
1673 {
1674  struct CadetChannelClient *ccc;
1675 
1678  "Received remote channel DESTROY for %s\n",
1679  GCCH_2s (ch));
1680  if (GNUNET_YES == ch->destroy)
1681  {
1682  /* Local client already gone, this is instant-death. */
1683  channel_destroy (ch);
1684  return;
1685  }
1686  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1687  if ((NULL != ccc) && (NULL != ccc->head_recv))
1688  {
1690  "Lost end of transmission due to remote shutdown on %s\n",
1691  GCCH_2s (ch));
1692  /* FIXME: change API to notify client about truncated transmission! */
1693  }
1694  ch->destroy = GNUNET_YES;
1695  if (NULL != ccc)
1696  GSC_handle_remote_channel_destroy (ccc->c, ccc->ccn, ch);
1697  channel_destroy (ch);
1698 }
1699 
1700 
1709 static int
1711  struct CadetReliableMessage *crm1,
1712  struct CadetReliableMessage *crm2)
1713 {
1714  if (crm1->next_retry.abs_value_us < crm2->next_retry.abs_value_us)
1715  return GNUNET_YES;
1716  return GNUNET_NO;
1717 }
1718 
1719 
1730 static void
1731 data_sent_cb (void *cls,
1732  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1733 {
1734  struct CadetReliableMessage *crm = cls;
1735  struct CadetChannel *ch = crm->ch;
1736 
1738  GNUNET_assert (NULL != crm->qe);
1739  crm->qe = NULL;
1741  if (GNUNET_NO == ch->reliable)
1742  {
1743  GNUNET_free (crm->data_message);
1744  GNUNET_free (crm);
1745  ch->pending_messages--;
1746  send_ack_to_client (ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1747  return;
1748  }
1749  if (NULL == cid)
1750  {
1751  /* There was an error sending. */
1753  }
1754  else if (GNUNET_SYSERR != crm->num_transmissions)
1755  {
1756  /* Increment transmission counter, and possibly store @a cid
1757  if this was the first transmission. */
1758  crm->num_transmissions++;
1759  if (1 == crm->num_transmissions)
1760  {
1762  crm->connection_taken = *cid;
1763  GCC_ack_expected (cid);
1764  }
1765  }
1766  if ((0 == crm->retry_delay.rel_value_us) && (NULL != cid))
1767  {
1768  struct CadetConnection *cc = GCC_lookup (cid);
1769 
1770  if (NULL != cc)
1772  else
1773  crm->retry_delay = ch->retry_time;
1774  }
1778 
1781  NULL,
1782  ch->head_sent,
1783  ch->tail_sent,
1784  crm);
1786  "Message %u sent, next transmission on %s in %s\n",
1787  (unsigned int) ntohl (crm->data_message->mid.mid),
1788  GCCH_2s (ch),
1791  ch->head_sent->next_retry),
1792  GNUNET_YES));
1793  if (NULL == ch->head_sent->qe)
1794  {
1795  if (NULL != ch->retry_data_task)
1799  ch);
1800  }
1801 }
1802 
1803 
1818 int
1820  struct GNUNET_CADET_ClientChannelNumber sender_ccn,
1821  const char *buf,
1822  size_t buf_len)
1823 {
1824  struct CadetReliableMessage *crm;
1825 
1826  if (ch->pending_messages >= ch->max_pending_messages)
1827  {
1828  GNUNET_break (0); /* Fails: #5370 */
1829  return GNUNET_SYSERR;
1830  }
1831  if (GNUNET_YES == ch->destroy)
1832  {
1833  /* we are going down, drop messages */
1834  return GNUNET_OK;
1835  }
1836  ch->pending_messages++;
1837 
1838  if (GNUNET_YES == ch->is_loopback)
1839  {
1840  struct CadetChannelClient *receiver;
1841  struct GNUNET_MQ_Envelope *env;
1842  struct GNUNET_CADET_LocalData *ld;
1843  int ack_to_owner;
1844 
1845  env =
1847  if ((NULL != ch->owner) &&
1848  (sender_ccn.channel_of_client == ch->owner->ccn.channel_of_client))
1849  {
1850  receiver = ch->dest;
1851  ack_to_owner = GNUNET_YES;
1852  }
1853  else if ((NULL != ch->dest) &&
1854  (sender_ccn.channel_of_client == ch->dest->ccn.channel_of_client))
1855  {
1856  receiver = ch->owner;
1857  ack_to_owner = GNUNET_NO;
1858  }
1859  else
1860  {
1861  GNUNET_break (0);
1862  return GNUNET_SYSERR;
1863  }
1864  GNUNET_assert (NULL != receiver);
1865  ld->ccn = receiver->ccn;
1866  GNUNET_memcpy (&ld[1], buf, buf_len);
1867  if (GNUNET_YES == receiver->client_ready)
1868  {
1869  ch->pending_messages--;
1870  GSC_send_to_client (receiver->c, env);
1871  send_ack_to_client (ch, ack_to_owner);
1872  }
1873  else
1874  {
1875  struct CadetOutOfOrderMessage *oom;
1876 
1877  oom = GNUNET_new (struct CadetOutOfOrderMessage);
1878  oom->env = env;
1880  receiver->tail_recv,
1881  oom);
1882  receiver->num_recv++;
1883  }
1884  return GNUNET_OK;
1885  }
1886 
1887  /* Everything is correct, send the message. */
1888  crm = GNUNET_malloc (sizeof(*crm));
1889  crm->ch = ch;
1890  crm->data_message = GNUNET_malloc (
1891  sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1892  crm->data_message->header.size =
1893  htons (sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1894  crm->data_message->header.type =
1896  ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1897  crm->data_message->mid = ch->mid_send;
1898  crm->data_message->ctn = ch->ctn;
1899  GNUNET_memcpy (&crm->data_message[1], buf, buf_len);
1902  "Sending message %u from local client to %s with %u bytes\n",
1903  ntohl (crm->data_message->mid.mid),
1904  GCCH_2s (ch),
1905  buf_len);
1906  if (NULL != ch->retry_data_task)
1907  {
1909  ch->retry_data_task = NULL;
1910  }
1911  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm,
1912  &crm->data_message->ctn);
1913  GNUNET_assert (NULL == ch->retry_data_task);
1914  return GNUNET_OK;
1915 }
1916 
1917 
1925 void
1927  struct GNUNET_CADET_ClientChannelNumber client_ccn)
1928 {
1929  struct CadetChannelClient *ccc;
1930  struct CadetOutOfOrderMessage *com;
1931 
1932  if ((NULL != ch->owner) &&
1933  (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client))
1934  ccc = ch->owner;
1935  else if ((NULL != ch->dest) &&
1936  (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client))
1937  ccc = ch->dest;
1938  else
1939  GNUNET_assert (0);
1940  ccc->client_ready = GNUNET_YES;
1941  com = ccc->head_recv;
1942  if (NULL == com)
1943  {
1945  "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
1946  GSC_2s (ccc->c),
1947  ntohl (client_ccn.channel_of_client),
1948  GCCH_2s (ch),
1949  ntohl (ccc->ccn.channel_of_client),
1950  ccc);
1951  return; /* none pending */
1952  }
1953  if (GNUNET_YES == ch->is_loopback)
1954  {
1955  int to_owner;
1956 
1957  /* Messages are always in-order, just send */
1959  ccc->num_recv--;
1960  GSC_send_to_client (ccc->c, com->env);
1961  /* Notify sender that we can receive more */
1962  if ((NULL != ch->owner) &&
1964  {
1965  to_owner = GNUNET_NO;
1966  }
1967  else
1968  {
1969  GNUNET_assert ((NULL != ch->dest) && (ccc->ccn.channel_of_client ==
1970  ch->dest->ccn.channel_of_client));
1971  to_owner = GNUNET_YES;
1972  }
1973  send_ack_to_client (ch, to_owner);
1974  GNUNET_free (com);
1975  return;
1976  }
1977 
1978  if ((com->mid.mid != ch->mid_recv.mid) && (GNUNET_NO == ch->out_of_order) &&
1979  (GNUNET_YES == ch->reliable))
1980  {
1982  "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
1983  GSC_2s (ccc->c),
1984  ntohl (ccc->ccn.channel_of_client),
1985  ntohl (com->mid.mid),
1986  ntohl (ch->mid_recv.mid));
1987  return; /* missing next one in-order */
1988  }
1989 
1991  "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
1992  ntohl (com->mid.mid),
1993  GSC_2s (ccc->c),
1994  ntohl (ccc->ccn.channel_of_client),
1995  GCCH_2s (ch));
1996 
1997  /* all good, pass next message to client */
1999  ccc->num_recv--;
2000  /* FIXME: if unreliable, this is not aggressive
2001  enough, as it would be OK to have lost some! */
2002 
2003  ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
2004  ch->mid_futures >>= 1; /* equivalent to division by 2 */
2005  ccc->client_ready = GNUNET_NO;
2006  GSC_send_to_client (ccc->c, com->env);
2007  GNUNET_free (com);
2008  send_channel_data_ack (ch);
2009  if (NULL != ccc->head_recv)
2010  return;
2011  if (GNUNET_NO == ch->destroy)
2012  return;
2013  GCT_send_channel_destroy (ch->t, ch->ctn);
2014  channel_destroy (ch);
2015 }
2016 
2017 
2018 #define LOG2(level, ...) \
2019  GNUNET_log_from_nocheck (level, "cadet-chn", __VA_ARGS__)
2020 
2021 
2028 void
2030 {
2031 #if ! defined(GNUNET_CULL_LOGGING)
2032  int do_log;
2033 
2035  "cadet-chn",
2036  __FILE__,
2037  __FUNCTION__,
2038  __LINE__);
2039  if (0 == do_log)
2040  return;
2041 
2042  if (NULL == ch)
2043  {
2044  LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
2045  return;
2046  }
2047  LOG2 (level, "CHN %s:%X (%p)\n", GCT_2s (ch->t), ch->ctn, ch);
2048  if (NULL != ch->owner)
2049  {
2050  LOG2 (level,
2051  "CHN origin %s ready %s local-id: %u\n",
2052  GSC_2s (ch->owner->c),
2053  ch->owner->client_ready ? "YES" : "NO",
2054  ntohl (ch->owner->ccn.channel_of_client));
2055  }
2056  if (NULL != ch->dest)
2057  {
2058  LOG2 (level,
2059  "CHN destination %s ready %s local-id: %u\n",
2060  GSC_2s (ch->dest->c),
2061  ch->dest->client_ready ? "YES" : "NO",
2062  ntohl (ch->dest->ccn.channel_of_client));
2063  }
2064  LOG2 (level,
2065  "CHN Message IDs recv: %d (%LLX), send: %d\n",
2066  ntohl (ch->mid_recv.mid),
2067  (unsigned long long) ch->mid_futures,
2068  ntohl (ch->mid_send.mid));
2069 #endif
2070 }
2071 
2072 
2073 /* 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:702
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.