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 };
384 
385 
393 const char *
394 GCCH_2s (const struct CadetChannel *ch)
395 {
396  static char buf[128];
397 
398  GNUNET_snprintf (buf,
399  sizeof(buf),
400  "Channel %s:%s ctn:%X(%X/%X)",
401  (GNUNET_YES == ch->is_loopback)
402  ? "loopback"
404  GNUNET_h2s (&ch->port),
405  ch->ctn,
406  (NULL == ch->owner)
407  ? 0
408  : ntohl (ch->owner->ccn.channel_of_client),
409  (NULL == ch->dest)
410  ? 0
411  : ntohl (ch->dest->ccn.channel_of_client));
412  return buf;
413 }
414 
415 
425 void
427  const struct GNUNET_HashCode *port,
428  const struct GNUNET_PeerIdentity *listener)
429 {
430  struct GNUNET_HashContext *hc;
431 
433  GNUNET_CRYPTO_hash_context_read (hc, port, sizeof(*port));
434  GNUNET_CRYPTO_hash_context_read (hc, listener, sizeof(*listener));
437  "Calculated port hash %s\n",
438  GNUNET_h2s (h_port));
439 }
440 
441 
450 GCCH_get_id (const struct CadetChannel *ch)
451 {
452  return ch->ctn;
453 }
454 
455 
461 static void
463 {
464  struct CadetOutOfOrderMessage *com;
465 
466  while (NULL != (com = ccc->head_recv))
467  {
469  ccc->num_recv--;
470  GNUNET_MQ_discard (com->env);
471  GNUNET_free (com);
472  }
473  GNUNET_free (ccc);
474 }
475 
476 
482 static void
484 {
485  struct CadetReliableMessage *crm;
486 
487  while (NULL != (crm = ch->head_sent))
488  {
489  GNUNET_assert (ch == crm->ch);
490  if (NULL != crm->qe)
491  {
492  GCT_send_cancel (crm->qe);
493  crm->qe = NULL;
494  }
496  GNUNET_free (crm->data_message);
497  GNUNET_free (crm);
498  }
499  if (CADET_CHANNEL_LOOSE == ch->state)
500  {
501  GSC_drop_loose_channel (&ch->h_port, ch);
502  }
503  if (NULL != ch->owner)
504  {
506  ch->owner = NULL;
507  }
508  if (NULL != ch->dest)
509  {
511  ch->dest = NULL;
512  }
513  if (NULL != ch->last_control_qe)
514  {
516  ch->last_control_qe = NULL;
517  }
518  if (NULL != ch->retry_data_task)
519  {
521  ch->retry_data_task = NULL;
522  }
523  if (NULL != ch->retry_control_task)
524  {
526  ch->retry_control_task = NULL;
527  }
528  if (GNUNET_NO == ch->is_loopback)
529  {
530  GCT_remove_channel (ch->t, ch, ch->ctn);
531  ch->t = NULL;
532  }
533  GNUNET_free (ch);
534 }
535 
536 
542 static void
543 send_channel_open (void *cls);
544 
545 
554 static void
556  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
557 {
558  struct CadetChannel *ch = cls;
559 
560  GNUNET_assert (NULL != ch->last_control_qe);
561  ch->last_control_qe = NULL;
564  "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
565  GCCH_2s (ch),
567  ch->retry_control_task =
569 }
570 
571 
577 static void
578 send_channel_open (void *cls)
579 {
580  struct CadetChannel *ch = cls;
581  struct GNUNET_CADET_ChannelOpenMessage msgcc;
582 
583  ch->retry_control_task = NULL;
585  "Sending CHANNEL_OPEN message for %s\n",
586  GCCH_2s (ch));
587  msgcc.header.size = htons (sizeof(msgcc));
589  // 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.
590  msgcc.opt = 2;
591  msgcc.h_port = ch->h_port;
592  msgcc.ctn = ch->ctn;
594  if (NULL != ch->last_control_qe)
596  ch->last_control_qe =
597  GCT_send (ch->t, &msgcc.header, &channel_open_sent_cb, ch);
598  GNUNET_assert (NULL == ch->retry_control_task);
599 }
600 
601 
612 void
614 {
615  GNUNET_assert (NULL == ch->retry_control_task);
617  "Tunnel up, sending CHANNEL_OPEN on %s now\n",
618  GCCH_2s (ch));
620 }
621 
622 
633 struct CadetChannel *
636  struct CadetPeer *destination,
637  const struct GNUNET_HashCode *port,
638  uint32_t options)
639 {
640  struct CadetChannel *ch;
641  struct CadetChannelClient *ccco;
642 
643  ccco = GNUNET_new (struct CadetChannelClient);
644  ccco->c = owner;
645  ccco->ccn = ccn;
646  ccco->client_ready = GNUNET_YES;
647 
648  ch = GNUNET_new (struct CadetChannel);
649  ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */
650  ch->nobuffer = GNUNET_NO;
651  ch->reliable = GNUNET_YES;
652  ch->out_of_order = GNUNET_NO;
654  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
655  ch->owner = ccco;
656  ch->port = *port;
657  GCCH_hash_port (&ch->h_port, port, GCP_get_id (destination));
658  if (0 == GNUNET_memcmp (&my_full_id, GCP_get_id (destination)))
659  {
660  struct OpenPort *op;
661 
662  ch->is_loopback = GNUNET_YES;
664  if (NULL == op)
665  {
666  /* port closed, wait for it to possibly open */
670  &ch->h_port,
671  ch,
674  "Created loose incoming loopback channel to port %s\n",
675  GNUNET_h2s (&ch->port));
676  }
677  else
678  {
679  GCCH_bind (ch, op->c, &op->port);
680  }
681  }
682  else
683  {
684  ch->t = GCP_get_tunnel (destination, GNUNET_YES);
686  ch->ctn = GCT_add_channel (ch->t, ch);
687  }
688  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
690  "Created channel to port %s at peer %s for %s using %s\n",
691  GNUNET_h2s (port),
692  GCP_2s (destination),
693  GSC_2s (owner),
694  (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
695  return ch;
696 }
697 
698 
705 static void
706 timeout_closed_cb (void *cls)
707 {
708  struct CadetChannel *ch = cls;
709 
710  ch->retry_control_task = NULL;
712  "Closing incoming channel to port %s from peer %s due to timeout\n",
713  GNUNET_h2s (&ch->port),
714  GCP_2s (GCT_get_destination (ch->t)));
715  channel_destroy (ch);
716 }
717 
718 
728 struct CadetChannel *
731  const struct GNUNET_HashCode *h_port,
732  uint32_t options)
733 {
734  struct CadetChannel *ch;
735  struct OpenPort *op;
736 
737  ch = GNUNET_new (struct CadetChannel);
738  ch->h_port = *h_port;
739  ch->t = t;
740  ch->ctn = ctn;
742  ch->nobuffer = GNUNET_NO;
743  ch->reliable = GNUNET_YES;
744  ch->out_of_order = GNUNET_NO;
746  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
747  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
748 
750  if (NULL == op)
751  {
752  /* port closed, wait for it to possibly open */
756  &ch->h_port,
757  ch,
759  GNUNET_assert (NULL == ch->retry_control_task);
762  ch);
764  "Created loose incoming channel to port %s from peer %s\n",
765  GNUNET_h2s (&ch->port),
766  GCP_2s (GCT_get_destination (ch->t)));
767  }
768  else
769  {
770  GCCH_bind (ch, op->c, &op->port);
771  }
772  GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
773  return ch;
774 }
775 
776 
786 static void
787 send_ack_cb (void *cls,
788  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
789 {
790  struct CadetChannel *ch = cls;
791 
792  GNUNET_assert (NULL != ch->last_control_qe);
793  ch->last_control_qe = NULL;
794 }
795 
796 
802 static void
804 {
806 
807  if (GNUNET_NO == ch->reliable)
808  return; /* no ACKs */
810  msg.header.size = htons (sizeof(msg));
811  msg.ctn = ch->ctn;
812  msg.mid.mid = htonl (ntohl (ch->mid_recv.mid));
813  msg.futures = GNUNET_htonll (ch->mid_futures);
815  "Sending DATA_ACK %u:%llX via %s\n",
816  (unsigned int) ntohl (msg.mid.mid),
817  (unsigned long long) ch->mid_futures,
818  GCCH_2s (ch));
819  if (NULL != ch->last_control_qe)
821  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch);
822 }
823 
824 
831 static void
832 send_open_ack (void *cls)
833 {
834  struct CadetChannel *ch = cls;
836 
837  ch->retry_control_task = NULL;
839  "Sending CHANNEL_OPEN_ACK on %s\n",
840  GCCH_2s (ch));
842  msg.header.size = htons (sizeof(msg));
843  msg.reserved = htonl (0);
844  msg.ctn = ch->ctn;
845  msg.port = ch->port;
846  if (NULL != ch->last_control_qe)
848  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch);
849 }
850 
851 
860 void
862  struct CadetChannel *ch,
863  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
864 {
865  if (NULL == ch->dest)
866  {
868  "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
869  GCCH_2s (ch));
870  return;
871  }
872  if (NULL != ch->retry_control_task)
873  {
875  "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
876  GCCH_2s (ch));
877  return;
878  }
880  "Retransmitting CHANNEL_OPEN_ACK on %s\n",
881  GCCH_2s (ch));
883 }
884 
885 
893 static void
894 send_ack_to_client (struct CadetChannel *ch, int to_owner)
895 {
896  struct GNUNET_MQ_Envelope *env;
897  struct GNUNET_CADET_LocalAck *ack;
898  struct CadetChannelClient *ccc;
899 
900  ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
901  if (NULL == ccc)
902  {
903  /* This can happen if we are just getting ACKs after
904  our local client already disconnected. */
906  return;
907  }
909  ack->ccn = ccc->ccn;
911  "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X (%u/%u pending)\n",
912  GSC_2s (ccc->c),
913  (GNUNET_YES == to_owner) ? "owner" : "dest",
914  ntohl (ack->ccn.channel_of_client),
915  ch->pending_messages,
917  GSC_send_to_client (ccc->c, env);
918 }
919 
920 
930 void
932  struct CadetClient *c,
933  const struct GNUNET_HashCode *port)
934 {
935  uint32_t options;
936  struct CadetChannelClient *cccd;
937 
939  "Binding %s from %s to port %s of %s\n",
940  GCCH_2s (ch),
941  GCT_2s (ch->t),
942  GNUNET_h2s (&ch->port),
943  GSC_2s (c));
944  if (NULL != ch->retry_control_task)
945  {
946  /* there might be a timeout task here */
948  ch->retry_control_task = NULL;
949  }
950  options = 0;
951  cccd = GNUNET_new (struct CadetChannelClient);
952  GNUNET_assert (NULL == ch->dest);
953  ch->dest = cccd;
954  ch->port = *port;
955  cccd->c = c;
956  cccd->client_ready = GNUNET_YES;
957  cccd->ccn = GSC_bind (c,
958  ch,
959  (GNUNET_YES == ch->is_loopback)
961  : GCT_get_destination (ch->t),
962  port,
963  options);
964  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
966  ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */
967  if (GNUNET_YES == ch->is_loopback)
968  {
970  GCCH_handle_channel_open_ack (ch, NULL, port);
971  }
972  else
973  {
974  /* notify other peer that we accepted the connection */
977  }
978  /* give client it's initial supply of ACKs */
979  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
981  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
983 }
984 
985 
993 static void
995 {
996  struct CadetChannel *ch = cls;
997  struct CadetChannelClient *ccc;
998 
999  /* Find which end is left... */
1000  ch->retry_control_task = NULL;
1001  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1002  GSC_handle_remote_channel_destroy (ccc->c, ccc->ccn, ch);
1003  channel_destroy (ch);
1004 }
1005 
1006 
1015 void
1017  struct CadetClient *c,
1019 {
1021  "%s asks for destruction of %s\n",
1022  GSC_2s (c),
1023  GCCH_2s (ch));
1024  GNUNET_assert (NULL != c);
1025  if ((NULL != ch->owner) && (c == ch->owner->c) &&
1027  {
1028  free_channel_client (ch->owner);
1029  ch->owner = NULL;
1030  }
1031  else if ((NULL != ch->dest) && (c == ch->dest->c) &&
1033  {
1034  free_channel_client (ch->dest);
1035  ch->dest = NULL;
1036  }
1037  else
1038  {
1039  GNUNET_assert (0);
1040  }
1041 
1042  if (GNUNET_YES == ch->destroy)
1043  {
1044  /* other end already destroyed, with the local client gone, no need
1045  to finish transmissions, just destroy immediately. */
1046  channel_destroy (ch);
1047  return;
1048  }
1049  if ((NULL != ch->head_sent) && ((NULL != ch->owner) || (NULL != ch->dest)))
1050  {
1051  /* Wait for other end to destroy us as well,
1052  and otherwise allow send queue to be transmitted first */
1053  ch->destroy = GNUNET_YES;
1054  return;
1055  }
1056  if ((GNUNET_YES == ch->is_loopback) &&
1057  ((NULL != ch->owner) || (NULL != ch->dest)))
1058  {
1059  if (NULL != ch->retry_control_task)
1061  ch->retry_control_task =
1063  return;
1064  }
1065  if (GNUNET_NO == ch->is_loopback)
1066  {
1067  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1068  switch (ch->state)
1069  {
1070  case CADET_CHANNEL_NEW:
1071  /* We gave up on a channel that we created as a client to a remote
1072  target, but that never went anywhere. Nothing to do here. */
1073  break;
1074 
1075  case CADET_CHANNEL_LOOSE:
1076  break;
1077 
1078  default:
1079  GCT_send_channel_destroy (ch->t, ch->ctn);
1080  }
1081  }
1082  /* Nothing left to do, just finish destruction */
1083  channel_destroy (ch);
1084 }
1085 
1086 
1096 void
1098  struct CadetChannel *ch,
1099  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1100  const struct GNUNET_HashCode *port)
1101 {
1102  switch (ch->state)
1103  {
1104  case CADET_CHANNEL_NEW:
1105  /* this should be impossible */
1106  GNUNET_break (0);
1107  break;
1108 
1109  case CADET_CHANNEL_LOOSE:
1110  /* This makes no sense. */
1111  GNUNET_break_op (0);
1112  break;
1113 
1115  if (NULL == ch->owner)
1116  {
1117  /* We're not the owner, wrong direction! */
1118  GNUNET_break_op (0);
1119  return;
1120  }
1121  if (0 != GNUNET_memcmp (&ch->port, port))
1122  {
1123  /* Other peer failed to provide the right port,
1124  refuse connection. */
1125  GNUNET_break_op (0);
1126  return;
1127  }
1129  "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1130  GCCH_2s (ch));
1131  if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1132  {
1134  ch->retry_control_task = NULL;
1135  }
1136  ch->state = CADET_CHANNEL_READY;
1137  /* On first connect, send client as many ACKs as we allow messages
1138  to be buffered! */
1139  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1141  break;
1142 
1143  case CADET_CHANNEL_READY:
1144  /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1146  "Received duplicate channel OPEN_ACK for %s\n",
1147  GCCH_2s (ch));
1148  GNUNET_STATISTICS_update (stats, "# duplicate CREATE_ACKs", 1, GNUNET_NO);
1149  break;
1150  }
1151 }
1152 
1153 
1162 static int
1163 is_before (void *cls,
1164  struct CadetOutOfOrderMessage *m1,
1165  struct CadetOutOfOrderMessage *m2)
1166 {
1167  int *duplicate = cls;
1168  uint32_t v1 = ntohl (m1->mid.mid);
1169  uint32_t v2 = ntohl (m2->mid.mid);
1170  uint32_t delta;
1171 
1172  delta = v2 - v1;
1173  if (0 == delta)
1174  *duplicate = GNUNET_YES;
1175  if (delta > (uint32_t) INT_MAX)
1176  {
1177  /* in overflow range, we can safely assume we wrapped around */
1178  return GNUNET_NO;
1179  }
1180  else
1181  {
1182  /* result is small, thus v2 > v1, thus m1 < m2 */
1183  return GNUNET_YES;
1184  }
1185 }
1186 
1187 
1196 void
1198  struct CadetChannel *ch,
1199  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1201 {
1202  struct GNUNET_MQ_Envelope *env;
1203  struct GNUNET_CADET_LocalData *ld;
1204  struct CadetChannelClient *ccc;
1205  size_t payload_size;
1206  struct CadetOutOfOrderMessage *com;
1207  int duplicate;
1208  uint32_t mid_min;
1209  uint32_t mid_max;
1210  uint32_t mid_msg;
1211  uint32_t delta;
1212 
1214  if ((NULL == ch->owner) && (NULL == ch->dest))
1215  {
1216  /* This client is gone, but we still have messages to send to
1217  the other end (which is why @a ch is not yet dead). However,
1218  we cannot pass messages to our client anymore. */
1220  "Dropping incoming payload on %s as this end is already closed\n",
1221  GCCH_2s (ch));
1222  /* send back DESTROY notification to stop further retransmissions! */
1223  if (GNUNET_YES == ch->destroy)
1224  GCT_send_channel_destroy (ch->t, ch->ctn);
1225  return;
1226  }
1227  payload_size = ntohs (msg->header.size) - sizeof(*msg);
1228  env = GNUNET_MQ_msg_extra (ld,
1229  payload_size,
1231  ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1232  GNUNET_memcpy (&ld[1], &msg[1], payload_size);
1233  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1234  if (GNUNET_YES == ccc->client_ready)
1235  {
1236  /*
1237  * We ad-hoc send the message if
1238  * - The channel is out-of-order
1239  * - The channel is reliable and MID matches next expected MID
1240  * - The channel is unreliable and MID is before lowest seen MID
1241  */if ((GNUNET_YES == ch->out_of_order) ||
1242  ((msg->mid.mid == ch->mid_recv.mid) && (GNUNET_YES == ch->reliable)) ||
1243  ((GNUNET_NO == ch->reliable) &&
1244  (ntohl (msg->mid.mid) >= ntohl (ch->mid_recv.mid)) &&
1245  ((NULL == ccc->head_recv) ||
1246  (ntohl (msg->mid.mid) < ntohl (ccc->head_recv->mid.mid)))))
1247  {
1249  "Giving %u bytes of payload with MID %u from %s to client %s\n",
1250  (unsigned int) payload_size,
1251  ntohl (msg->mid.mid),
1252  GCCH_2s (ch),
1253  GSC_2s (ccc->c));
1254  ccc->client_ready = GNUNET_NO;
1255  GSC_send_to_client (ccc->c, env);
1256  if (GNUNET_NO == ch->out_of_order)
1257  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1258  else
1259  ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
1260  ch->mid_futures >>= 1;
1261  if ((GNUNET_YES == ch->out_of_order) && (GNUNET_NO == ch->reliable))
1262  {
1263  /* possibly shift by more if we skipped messages */
1264  uint64_t delta = htonl (msg->mid.mid) - 1 - ntohl (ch->mid_recv.mid);
1265 
1266  if (delta > 63)
1267  ch->mid_futures = 0;
1268  else
1269  ch->mid_futures >>= delta;
1270  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1271  }
1272  send_channel_data_ack (ch);
1273  return;
1274  }
1275  }
1276 
1277  if (GNUNET_YES == ch->reliable)
1278  {
1279  /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1280  mid_min = ntohl (ch->mid_recv.mid);
1281  mid_max = mid_min + ch->max_pending_messages;
1282  mid_msg = ntohl (msg->mid.mid);
1283  if (((uint32_t) (mid_msg - mid_min) > ch->max_pending_messages) ||
1284  ((uint32_t) (mid_max - mid_msg) > ch->max_pending_messages))
1285  {
1287  "%s at %u drops ancient or far-future message %u\n",
1288  GCCH_2s (ch),
1289  (unsigned int) mid_min,
1290  ntohl (msg->mid.mid));
1291 
1293  "# duplicate DATA (ancient or future)",
1294  1,
1295  GNUNET_NO);
1296  GNUNET_MQ_discard (env);
1297  send_channel_data_ack (ch);
1298  return;
1299  }
1300  /* mark bit for future ACKs */
1301  delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1302  if (delta < 64)
1303  {
1304  if (0 != (ch->mid_futures & (1LLU << delta)))
1305  {
1306  /* Duplicate within the queue, drop also */
1308  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1309  (unsigned int) payload_size,
1310  GCCH_2s (ch),
1311  ntohl (msg->mid.mid));
1312  GNUNET_STATISTICS_update (stats, "# duplicate DATA", 1, GNUNET_NO);
1313  GNUNET_MQ_discard (env);
1314  send_channel_data_ack (ch);
1315  return;
1316  }
1317  ch->mid_futures |= (1LLU << delta);
1319  "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1320  (1LLU << delta),
1321  mid_msg,
1322  mid_min,
1323  ch->mid_futures);
1324  }
1325  }
1326  else /* ! ch->reliable */
1327  {
1328  struct CadetOutOfOrderMessage *next_msg;
1329 
1334  if ((NULL != ccc->head_recv) && (GNUNET_YES == ccc->client_ready))
1335  {
1336  next_msg = ccc->head_recv;
1338  "Giving queued MID %u from %s to client %s\n",
1339  ntohl (next_msg->mid.mid),
1340  GCCH_2s (ch),
1341  GSC_2s (ccc->c));
1342  ccc->client_ready = GNUNET_NO;
1343  GSC_send_to_client (ccc->c, next_msg->env);
1344  ch->mid_recv.mid = htonl (1 + ntohl (next_msg->mid.mid));
1345  ch->mid_futures >>= 1;
1346  send_channel_data_ack (ch);
1347  GNUNET_CONTAINER_DLL_remove (ccc->head_recv, ccc->tail_recv, next_msg);
1348  ccc->num_recv--;
1349  /* Do not process duplicate MID */
1350  if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
1351  {
1352  /* Duplicate within the queue, drop */
1354  "Message on %s (mid %u) dropped, duplicate\n",
1355  GCCH_2s (ch),
1356  ntohl (msg->mid.mid));
1357  GNUNET_free (next_msg);
1358  GNUNET_MQ_discard (env);
1359  return;
1360  }
1361  GNUNET_free (next_msg);
1362  }
1363 
1364  if (ntohl (msg->mid.mid) < ntohl (ch->mid_recv.mid)) /* Old */
1365  {
1366  /* Duplicate within the queue, drop */
1368  "Message on %s (mid %u) dropped, old.\n",
1369  GCCH_2s (ch),
1370  ntohl (msg->mid.mid));
1371  GNUNET_MQ_discard (env);
1372  return;
1373  }
1374 
1375  /* Channel is unreliable, so we do not ACK. But we also cannot
1376  allow buffering everything, so check if we have space... */
1377  if (ccc->num_recv >= ch->max_pending_messages)
1378  {
1379  struct CadetOutOfOrderMessage *drop;
1380 
1381  /* Yep, need to drop. Drop the oldest message in
1382  the buffer. */
1384  "Queue full due slow client on %s, dropping oldest message\n",
1385  GCCH_2s (ch));
1387  "# messages dropped due to slow client",
1388  1,
1389  GNUNET_NO);
1390  drop = ccc->head_recv;
1391  GNUNET_assert (NULL != drop);
1392  GNUNET_CONTAINER_DLL_remove (ccc->head_recv, ccc->tail_recv, drop);
1393  ccc->num_recv--;
1394  GNUNET_MQ_discard (drop->env);
1395  GNUNET_free (drop);
1396  }
1397  }
1398 
1399  /* Insert message into sorted out-of-order queue */
1400  com = GNUNET_new (struct CadetOutOfOrderMessage);
1401  com->mid = msg->mid;
1402  com->env = env;
1403  duplicate = GNUNET_NO;
1405  is_before,
1406  &duplicate,
1407  ccc->head_recv,
1408  ccc->tail_recv,
1409  com);
1410  ccc->num_recv++;
1411  if (GNUNET_YES == duplicate)
1412  {
1413  /* Duplicate within the queue, drop also (this is not covered by
1414  the case above if "delta" >= 64, which could be the case if
1415  max_pending_messages is also >= 64 or if our client is unready
1416  and we are seeing retransmissions of the message our client is
1417  blocked on. */LOG (GNUNET_ERROR_TYPE_DEBUG,
1418  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1419  (unsigned int) payload_size,
1420  GCCH_2s (ch),
1421  ntohl (msg->mid.mid));
1422  GNUNET_STATISTICS_update (stats, "# duplicate DATA", 1, GNUNET_NO);
1424  ccc->num_recv--;
1425  GNUNET_MQ_discard (com->env);
1426  GNUNET_free (com);
1427  send_channel_data_ack (ch);
1428  return;
1429  }
1431  "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1432  (GNUNET_YES == ccc->client_ready) ? "out-of-order" : "client-not-ready",
1433  (unsigned int) payload_size,
1434  GCCH_2s (ch),
1435  ntohl (ccc->ccn.channel_of_client),
1436  ccc,
1437  ntohl (msg->mid.mid),
1438  ntohl (ch->mid_recv.mid));
1439  /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1440  the sender may already be transmitting the previous one. Needs
1441  experimental evaluation to see if/when this ACK helps or
1442  hurts. (We might even want another option.) */
1443  send_channel_data_ack (ch);
1444 }
1445 
1446 
1457 static void
1458 data_sent_cb (void *cls,
1459  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
1460 
1461 
1468 static void
1470 {
1471  struct CadetChannel *ch = cls;
1472  struct CadetReliableMessage *crm = ch->head_sent;
1473 
1474  ch->retry_data_task = NULL;
1475  GNUNET_assert (NULL == crm->qe);
1477  "Retrying transmission on %s of message %u\n",
1478  GCCH_2s (ch),
1479  (unsigned int) ntohl (crm->data_message->mid.mid));
1480  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm);
1481  GNUNET_assert (NULL == ch->retry_data_task);
1482 }
1483 
1484 
1493 static void
1495  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1496  struct CadetReliableMessage *crm)
1497 {
1499  ch->pending_messages--;
1502  "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1503  GCCH_2s (ch),
1504  (unsigned int) ntohl (crm->data_message->mid.mid),
1505  ch->pending_messages);
1506  if (NULL != crm->qe)
1507  {
1508  GCT_send_cancel (crm->qe);
1509  crm->qe = NULL;
1510  }
1511  if ((1 == crm->num_transmissions) && (NULL != cti))
1512  {
1513  GCC_ack_observed (cti);
1514  if (0 == GNUNET_memcmp (cti, &crm->connection_taken))
1515  {
1516  GCC_latency_observed (cti,
1518  crm->first_transmission_time));
1519  }
1520  }
1521  GNUNET_free (crm->data_message);
1522  GNUNET_free (crm);
1523  send_ack_to_client (ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1524 }
1525 
1526 
1535 void
1537  struct CadetChannel *ch,
1538  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1539  const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1540 {
1541  struct CadetReliableMessage *crm;
1542  struct CadetReliableMessage *crmn;
1543  int found;
1544  uint32_t mid_base;
1545  uint64_t mid_mask;
1546  unsigned int delta;
1547 
1549  if (GNUNET_NO == ch->reliable)
1550  {
1551  /* not expecting ACKs on unreliable channel, odd */
1552  GNUNET_break_op (0);
1553  return;
1554  }
1555  /* mid_base is the MID of the next message that the
1556  other peer expects (i.e. that is missing!), everything
1557  LOWER (but excluding mid_base itself) was received. */
1558  mid_base = ntohl (ack->mid.mid);
1559  mid_mask = GNUNET_htonll (ack->futures);
1560  found = GNUNET_NO;
1561  for (crm = ch->head_sent; NULL != crm; crm = crmn)
1562  {
1563  crmn = crm->next;
1564  delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base);
1565  if (delta >= UINT_MAX - ch->max_pending_messages)
1566  {
1567  /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1569  "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1570  (unsigned int) mid_base,
1571  ntohl (crm->data_message->mid.mid),
1572  GCCH_2s (ch));
1573  handle_matching_ack (ch, cti, crm);
1574  found = GNUNET_YES;
1575  continue;
1576  }
1577  delta--;
1578  if (delta >= 64)
1579  continue;
1581  "Testing bit %llX for mid %u (base: %u)\n",
1582  (1LLU << delta),
1583  ntohl (crm->data_message->mid.mid),
1584  mid_base);
1585  if (0 != (mid_mask & (1LLU << delta)))
1586  {
1588  "Got DATA_ACK with mask for %u on %s\n",
1589  ntohl (crm->data_message->mid.mid),
1590  GCCH_2s (ch));
1591  handle_matching_ack (ch, cti, crm);
1592  found = GNUNET_YES;
1593  }
1594  }
1595  if (GNUNET_NO == found)
1596  {
1597  /* ACK for message we already dropped, might have been a
1598  duplicate ACK? Ignore. */
1600  "Duplicate DATA_ACK on %s, ignoring\n",
1601  GCCH_2s (ch));
1602  GNUNET_STATISTICS_update (stats, "# duplicate DATA_ACKs", 1, GNUNET_NO);
1603  return;
1604  }
1605  if (NULL != ch->retry_data_task)
1606  {
1608  ch->retry_data_task = NULL;
1609  }
1610  if ((NULL != ch->head_sent) && (NULL == ch->head_sent->qe))
1613  ch);
1614 }
1615 
1616 
1626 void
1628  struct CadetChannel *ch,
1629  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
1630 {
1631  struct CadetChannelClient *ccc;
1632 
1635  "Received remote channel DESTROY for %s\n",
1636  GCCH_2s (ch));
1637  if (GNUNET_YES == ch->destroy)
1638  {
1639  /* Local client already gone, this is instant-death. */
1640  channel_destroy (ch);
1641  return;
1642  }
1643  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1644  if ((NULL != ccc) && (NULL != ccc->head_recv))
1645  {
1647  "Lost end of transmission due to remote shutdown on %s\n",
1648  GCCH_2s (ch));
1649  /* FIXME: change API to notify client about truncated transmission! */
1650  }
1651  ch->destroy = GNUNET_YES;
1652  if (NULL != ccc)
1653  GSC_handle_remote_channel_destroy (ccc->c, ccc->ccn, ch);
1654  channel_destroy (ch);
1655 }
1656 
1657 
1666 static int
1668  struct CadetReliableMessage *crm1,
1669  struct CadetReliableMessage *crm2)
1670 {
1671  if (crm1->next_retry.abs_value_us < crm2->next_retry.abs_value_us)
1672  return GNUNET_YES;
1673  return GNUNET_NO;
1674 }
1675 
1676 
1687 static void
1688 data_sent_cb (void *cls,
1689  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1690 {
1691  struct CadetReliableMessage *crm = cls;
1692  struct CadetChannel *ch = crm->ch;
1693 
1695  GNUNET_assert (NULL != crm->qe);
1696  crm->qe = NULL;
1698  if (GNUNET_NO == ch->reliable)
1699  {
1700  GNUNET_free (crm->data_message);
1701  GNUNET_free (crm);
1702  ch->pending_messages--;
1703  send_ack_to_client (ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1704  return;
1705  }
1706  if (NULL == cid)
1707  {
1708  /* There was an error sending. */
1710  }
1711  else if (GNUNET_SYSERR != crm->num_transmissions)
1712  {
1713  /* Increment transmission counter, and possibly store @a cid
1714  if this was the first transmission. */
1715  crm->num_transmissions++;
1716  if (1 == crm->num_transmissions)
1717  {
1719  crm->connection_taken = *cid;
1720  GCC_ack_expected (cid);
1721  }
1722  }
1723  if ((0 == crm->retry_delay.rel_value_us) && (NULL != cid))
1724  {
1725  struct CadetConnection *cc = GCC_lookup (cid);
1726 
1727  if (NULL != cc)
1729  else
1730  crm->retry_delay = ch->retry_time;
1731  }
1735 
1738  NULL,
1739  ch->head_sent,
1740  ch->tail_sent,
1741  crm);
1743  "Message %u sent, next transmission on %s in %s\n",
1744  (unsigned int) ntohl (crm->data_message->mid.mid),
1745  GCCH_2s (ch),
1748  ch->head_sent->next_retry),
1749  GNUNET_YES));
1750  if (NULL == ch->head_sent->qe)
1751  {
1752  if (NULL != ch->retry_data_task)
1756  ch);
1757  }
1758 }
1759 
1760 
1775 int
1777  struct GNUNET_CADET_ClientChannelNumber sender_ccn,
1778  const char *buf,
1779  size_t buf_len)
1780 {
1781  struct CadetReliableMessage *crm;
1782 
1783  if (ch->pending_messages >= ch->max_pending_messages)
1784  {
1785  GNUNET_break (0); /* Fails: #5370 */
1786  return GNUNET_SYSERR;
1787  }
1788  if (GNUNET_YES == ch->destroy)
1789  {
1790  /* we are going down, drop messages */
1791  return GNUNET_OK;
1792  }
1793  ch->pending_messages++;
1794 
1795  if (GNUNET_YES == ch->is_loopback)
1796  {
1797  struct CadetChannelClient *receiver;
1798  struct GNUNET_MQ_Envelope *env;
1799  struct GNUNET_CADET_LocalData *ld;
1800  int ack_to_owner;
1801 
1802  env =
1804  if ((NULL != ch->owner) &&
1805  (sender_ccn.channel_of_client == ch->owner->ccn.channel_of_client))
1806  {
1807  receiver = ch->dest;
1808  ack_to_owner = GNUNET_YES;
1809  }
1810  else if ((NULL != ch->dest) &&
1811  (sender_ccn.channel_of_client == ch->dest->ccn.channel_of_client))
1812  {
1813  receiver = ch->owner;
1814  ack_to_owner = GNUNET_NO;
1815  }
1816  else
1817  {
1818  GNUNET_break (0);
1819  return GNUNET_SYSERR;
1820  }
1821  GNUNET_assert (NULL != receiver);
1822  ld->ccn = receiver->ccn;
1823  GNUNET_memcpy (&ld[1], buf, buf_len);
1824  if (GNUNET_YES == receiver->client_ready)
1825  {
1826  ch->pending_messages--;
1827  GSC_send_to_client (receiver->c, env);
1828  send_ack_to_client (ch, ack_to_owner);
1829  }
1830  else
1831  {
1832  struct CadetOutOfOrderMessage *oom;
1833 
1834  oom = GNUNET_new (struct CadetOutOfOrderMessage);
1835  oom->env = env;
1837  receiver->tail_recv,
1838  oom);
1839  receiver->num_recv++;
1840  }
1841  return GNUNET_OK;
1842  }
1843 
1844  /* Everything is correct, send the message. */
1845  crm = GNUNET_malloc (sizeof(*crm));
1846  crm->ch = ch;
1847  crm->data_message = GNUNET_malloc (
1848  sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1849  crm->data_message->header.size =
1850  htons (sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1851  crm->data_message->header.type =
1853  ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1854  crm->data_message->mid = ch->mid_send;
1855  crm->data_message->ctn = ch->ctn;
1856  GNUNET_memcpy (&crm->data_message[1], buf, buf_len);
1859  "Sending message %u from local client to %s with %u bytes\n",
1860  ntohl (crm->data_message->mid.mid),
1861  GCCH_2s (ch),
1862  buf_len);
1863  if (NULL != ch->retry_data_task)
1864  {
1866  ch->retry_data_task = NULL;
1867  }
1868  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm);
1869  GNUNET_assert (NULL == ch->retry_data_task);
1870  return GNUNET_OK;
1871 }
1872 
1873 
1881 void
1883  struct GNUNET_CADET_ClientChannelNumber client_ccn)
1884 {
1885  struct CadetChannelClient *ccc;
1886  struct CadetOutOfOrderMessage *com;
1887 
1888  if ((NULL != ch->owner) &&
1889  (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client))
1890  ccc = ch->owner;
1891  else if ((NULL != ch->dest) &&
1892  (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client))
1893  ccc = ch->dest;
1894  else
1895  GNUNET_assert (0);
1896  ccc->client_ready = GNUNET_YES;
1897  com = ccc->head_recv;
1898  if (NULL == com)
1899  {
1901  "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
1902  GSC_2s (ccc->c),
1903  ntohl (client_ccn.channel_of_client),
1904  GCCH_2s (ch),
1905  ntohl (ccc->ccn.channel_of_client),
1906  ccc);
1907  return; /* none pending */
1908  }
1909  if (GNUNET_YES == ch->is_loopback)
1910  {
1911  int to_owner;
1912 
1913  /* Messages are always in-order, just send */
1915  ccc->num_recv--;
1916  GSC_send_to_client (ccc->c, com->env);
1917  /* Notify sender that we can receive more */
1918  if ((NULL != ch->owner) &&
1920  {
1921  to_owner = GNUNET_NO;
1922  }
1923  else
1924  {
1925  GNUNET_assert ((NULL != ch->dest) && (ccc->ccn.channel_of_client ==
1926  ch->dest->ccn.channel_of_client));
1927  to_owner = GNUNET_YES;
1928  }
1929  send_ack_to_client (ch, to_owner);
1930  GNUNET_free (com);
1931  return;
1932  }
1933 
1934  if ((com->mid.mid != ch->mid_recv.mid) && (GNUNET_NO == ch->out_of_order) &&
1935  (GNUNET_YES == ch->reliable))
1936  {
1938  "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
1939  GSC_2s (ccc->c),
1940  ntohl (ccc->ccn.channel_of_client),
1941  ntohl (com->mid.mid),
1942  ntohl (ch->mid_recv.mid));
1943  return; /* missing next one in-order */
1944  }
1945 
1947  "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
1948  ntohl (com->mid.mid),
1949  GSC_2s (ccc->c),
1950  ntohl (ccc->ccn.channel_of_client),
1951  GCCH_2s (ch));
1952 
1953  /* all good, pass next message to client */
1955  ccc->num_recv--;
1956  /* FIXME: if unreliable, this is not aggressive
1957  enough, as it would be OK to have lost some! */
1958 
1959  ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
1960  ch->mid_futures >>= 1; /* equivalent to division by 2 */
1961  ccc->client_ready = GNUNET_NO;
1962  GSC_send_to_client (ccc->c, com->env);
1963  GNUNET_free (com);
1964  send_channel_data_ack (ch);
1965  if (NULL != ccc->head_recv)
1966  return;
1967  if (GNUNET_NO == ch->destroy)
1968  return;
1969  GCT_send_channel_destroy (ch->t, ch->ctn);
1970  channel_destroy (ch);
1971 }
1972 
1973 
1974 #define LOG2(level, ...) \
1975  GNUNET_log_from_nocheck (level, "cadet-chn", __VA_ARGS__)
1976 
1977 
1984 void
1986 {
1987 #if ! defined(GNUNET_CULL_LOGGING)
1988  int do_log;
1989 
1991  "cadet-chn",
1992  __FILE__,
1993  __FUNCTION__,
1994  __LINE__);
1995  if (0 == do_log)
1996  return;
1997 
1998  if (NULL == ch)
1999  {
2000  LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
2001  return;
2002  }
2003  LOG2 (level, "CHN %s:%X (%p)\n", GCT_2s (ch->t), ch->ctn, ch);
2004  if (NULL != ch->owner)
2005  {
2006  LOG2 (level,
2007  "CHN origin %s ready %s local-id: %u\n",
2008  GSC_2s (ch->owner->c),
2009  ch->owner->client_ready ? "YES" : "NO",
2010  ntohl (ch->owner->ccn.channel_of_client));
2011  }
2012  if (NULL != ch->dest)
2013  {
2014  LOG2 (level,
2015  "CHN destination %s ready %s local-id: %u\n",
2016  GSC_2s (ch->dest->c),
2017  ch->dest->client_ready ? "YES" : "NO",
2018  ntohl (ch->dest->ccn.channel_of_client));
2019  }
2020  LOG2 (level,
2021  "CHN Message IDs recv: %d (%LLX), send: %d\n",
2022  ntohl (ch->mid_recv.mid),
2023  (unsigned long long) ch->mid_futures,
2024  ntohl (ch->mid_send.mid));
2025 #endif
2026 }
2027 
2028 
2029 /* 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.
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:217
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:111
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:466
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:451
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:1253
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:1280
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:687
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:199
#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:321
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:492
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:227
#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: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...
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:189
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:1230
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:509
#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:966
struct GNUNET_HashCode port
Destination port of the channel.