GNUnet  0.10.x
gnunet-service-cadet_channel.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2017 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
36 #include "platform.h"
37 #include "cadet.h"
43 
44 #define LOG(level,...) GNUNET_log_from (level,"cadet-chn",__VA_ARGS__)
45 
49 #define CADET_INITIAL_RETRANSMIT_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)
50 
55 #define TIMEOUT_CLOSED_PORT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
56 
60 #define MIN_RTT_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 75)
61 
72 #define MAX_OUT_OF_ORDER_DISTANCE 1024
73 
74 
79 {
84 
90 
95 
100 };
101 
102 
109 {
114 
119 
123  struct CadetChannel *ch;
124 
131 
136 
142 
148 
154 
160 
167 
168 };
169 
170 
175 {
180 
185 
191 
196 
197 };
198 
199 
206 {
213  struct CadetClient *c;
214 
219 
224 
231 
235  unsigned int num_recv;
236 
241 
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 
386 
394 const char *
395 GCCH_2s (const struct CadetChannel *ch)
396 {
397  static char buf[128];
398 
399  GNUNET_snprintf (buf,
400  sizeof (buf),
401  "Channel %s:%s ctn:%X(%X/%X)",
402  (GNUNET_YES == ch->is_loopback)
403  ? "loopback"
405  GNUNET_h2s (&ch->port),
406  ch->ctn,
407  (NULL == ch->owner) ? 0 : ntohl (ch->owner->ccn.channel_of_client),
408  (NULL == ch->dest) ? 0 : ntohl (ch->dest->ccn.channel_of_client));
409  return buf;
410 }
411 
412 
422 void
424  const struct GNUNET_HashCode *port,
425  const struct GNUNET_PeerIdentity *listener)
426 {
427  struct GNUNET_HashContext *hc;
428 
431  port,
432  sizeof (*port));
434  listener,
435  sizeof (*listener));
437  h_port);
439  "Calculated port hash %s\n",
440  GNUNET_h2s (h_port));
441 }
442 
443 
452 GCCH_get_id (const struct CadetChannel *ch)
453 {
454  return ch->ctn;
455 }
456 
457 
463 static void
465 {
466  struct CadetOutOfOrderMessage *com;
467 
468  while (NULL != (com = ccc->head_recv))
469  {
471  ccc->tail_recv,
472  com);
473  ccc->num_recv--;
474  GNUNET_MQ_discard (com->env);
475  GNUNET_free (com);
476  }
477  GNUNET_free (ccc);
478 }
479 
480 
486 static void
488 {
489  struct CadetReliableMessage *crm;
490 
491  while (NULL != (crm = ch->head_sent))
492  {
493  GNUNET_assert (ch == crm->ch);
494  if (NULL != crm->qe)
495  {
496  GCT_send_cancel (crm->qe);
497  crm->qe = NULL;
498  }
500  ch->tail_sent,
501  crm);
502  GNUNET_free (crm->data_message);
503  GNUNET_free (crm);
504  }
505  if (CADET_CHANNEL_LOOSE == ch->state)
506  {
508  ch);
509  }
510  if (NULL != ch->owner)
511  {
513  ch->owner = NULL;
514  }
515  if (NULL != ch->dest)
516  {
518  ch->dest = NULL;
519  }
520  if (NULL != ch->last_control_qe)
521  {
523  ch->last_control_qe = NULL;
524  }
525  if (NULL != ch->retry_data_task)
526  {
528  ch->retry_data_task = NULL;
529  }
530  if (NULL != ch->retry_control_task)
531  {
533  ch->retry_control_task = NULL;
534  }
535  if (GNUNET_NO == ch->is_loopback)
536  {
537  GCT_remove_channel (ch->t,
538  ch,
539  ch->ctn);
540  ch->t = NULL;
541  }
542  GNUNET_free (ch);
543 }
544 
545 
551 static void
552 send_channel_open (void *cls);
553 
554 
563 static void
565  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
566 {
567  struct CadetChannel *ch = cls;
568 
569  GNUNET_assert (NULL != ch->last_control_qe);
570  ch->last_control_qe = NULL;
573  "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
574  GCCH_2s (ch),
576  GNUNET_YES));
580  ch);
581 }
582 
583 
589 static void
590 send_channel_open (void *cls)
591 {
592  struct CadetChannel *ch = cls;
593  struct GNUNET_CADET_ChannelOpenMessage msgcc;
594  uint32_t options;
595 
596  ch->retry_control_task = NULL;
598  "Sending CHANNEL_OPEN message for %s\n",
599  GCCH_2s (ch));
600  options = 0;
601  if (ch->nobuffer)
602  options |= GNUNET_CADET_OPTION_NOBUFFER;
603  if (ch->reliable)
604  options |= GNUNET_CADET_OPTION_RELIABLE;
605  if (ch->out_of_order)
607  msgcc.header.size = htons (sizeof (msgcc));
609  msgcc.opt = htonl (options);
610  msgcc.h_port = ch->h_port;
611  msgcc.ctn = ch->ctn;
613  if (NULL != ch->last_control_qe)
615  ch->last_control_qe = GCT_send (ch->t,
616  &msgcc.header,
618  ch);
619  GNUNET_assert (NULL == ch->retry_control_task);
620 }
621 
622 
633 void
635 {
636  GNUNET_assert (NULL == ch->retry_control_task);
638  "Tunnel up, sending CHANNEL_OPEN on %s now\n",
639  GCCH_2s (ch));
642  ch);
643 }
644 
645 
656 struct CadetChannel *
659  struct CadetPeer *destination,
660  const struct GNUNET_HashCode *port,
661  uint32_t options)
662 {
663  struct CadetChannel *ch;
664  struct CadetChannelClient *ccco;
665 
666  ccco = GNUNET_new (struct CadetChannelClient);
667  ccco->c = owner;
668  ccco->ccn = ccn;
669  ccco->client_ready = GNUNET_YES;
670 
671  ch = GNUNET_new (struct CadetChannel);
672  ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */
673  ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
674  ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
675  ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
676  ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
677  ch->owner = ccco;
678  ch->port = *port;
679  GCCH_hash_port (&ch->h_port,
680  port,
681  GCP_get_id (destination));
682  if (0 == GNUNET_memcmp (&my_full_id,
683  GCP_get_id (destination)))
684  {
685  struct OpenPort *op;
686 
687  ch->is_loopback = GNUNET_YES;
689  &ch->h_port);
690  if (NULL == op)
691  {
692  /* port closed, wait for it to possibly open */
695  &ch->h_port,
696  ch,
699  "Created loose incoming loopback channel to port %s\n",
700  GNUNET_h2s (&ch->port));
701  }
702  else
703  {
704  GCCH_bind (ch,
705  op->c,
706  &op->port);
707  }
708  }
709  else
710  {
711  ch->t = GCP_get_tunnel (destination,
712  GNUNET_YES);
714  ch->ctn = GCT_add_channel (ch->t,
715  ch);
716  }
718  "# channels",
719  1,
720  GNUNET_NO);
722  "Created channel to port %s at peer %s for %s using %s\n",
723  GNUNET_h2s (port),
724  GCP_2s (destination),
725  GSC_2s (owner),
726  (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
727  return ch;
728 }
729 
730 
737 static void
738 timeout_closed_cb (void *cls)
739 {
740  struct CadetChannel *ch = cls;
741 
742  ch->retry_control_task = NULL;
744  "Closing incoming channel to port %s from peer %s due to timeout\n",
745  GNUNET_h2s (&ch->port),
746  GCP_2s (GCT_get_destination (ch->t)));
747  channel_destroy (ch);
748 }
749 
750 
760 struct CadetChannel *
763  const struct GNUNET_HashCode *h_port,
764  uint32_t options)
765 {
766  struct CadetChannel *ch;
767  struct OpenPort *op;
768 
769  ch = GNUNET_new (struct CadetChannel);
770  ch->h_port = *h_port;
771  ch->t = t;
772  ch->ctn = ctn;
774  ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
775  ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
776  ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
777  ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
779  "# channels",
780  1,
781  GNUNET_NO);
782 
784  h_port);
785  if (NULL == op)
786  {
787  /* port closed, wait for it to possibly open */
790  &ch->h_port,
791  ch,
793  GNUNET_assert (NULL == ch->retry_control_task);
797  ch);
799  "Created loose incoming channel to port %s from peer %s\n",
800  GNUNET_h2s (&ch->port),
801  GCP_2s (GCT_get_destination (ch->t)));
802  }
803  else
804  {
805  GCCH_bind (ch,
806  op->c,
807  &op->port);
808  }
810  "# channels",
811  1,
812  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,
862  &msg.header,
863  &send_ack_cb,
864  ch);
865 }
866 
867 
874 static void
875 send_open_ack (void *cls)
876 {
877  struct CadetChannel *ch = cls;
879 
880  ch->retry_control_task = NULL;
882  "Sending CHANNEL_OPEN_ACK on %s\n",
883  GCCH_2s (ch));
885  msg.header.size = htons (sizeof (msg));
886  msg.reserved = htonl (0);
887  msg.ctn = ch->ctn;
888  msg.port = ch->port;
889  if (NULL != ch->last_control_qe)
891  ch->last_control_qe = GCT_send (ch->t,
892  &msg.header,
893  &send_ack_cb,
894  ch);
895 }
896 
897 
906 void
908  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
909 {
910  if (NULL == ch->dest)
911  {
913  "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
914  GCCH_2s (ch));
915  return;
916  }
917  if (NULL != ch->retry_control_task)
918  {
920  "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
921  GCCH_2s (ch));
922  return;
923  }
925  "Retransmitting CHANNEL_OPEN_ACK on %s\n",
926  GCCH_2s (ch));
929  ch);
930 }
931 
932 
940 static void
942  int to_owner)
943 {
944  struct GNUNET_MQ_Envelope *env;
945  struct GNUNET_CADET_LocalAck *ack;
946  struct CadetChannelClient *ccc;
947 
948  ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
949  if (NULL == ccc)
950  {
951  /* This can happen if we are just getting ACKs after
952  our local client already disconnected. */
954  return;
955  }
956  env = GNUNET_MQ_msg (ack,
958  ack->ccn = ccc->ccn;
960  "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X (%u/%u pending)\n",
961  GSC_2s (ccc->c),
962  (GNUNET_YES == to_owner) ? "owner" : "dest",
963  ntohl (ack->ccn.channel_of_client),
964  ch->pending_messages,
966  GSC_send_to_client (ccc->c,
967  env);
968 }
969 
970 
980 void
982  struct CadetClient *c,
983  const struct GNUNET_HashCode *port)
984 {
985  uint32_t options;
986  struct CadetChannelClient *cccd;
987 
989  "Binding %s from %s to port %s of %s\n",
990  GCCH_2s (ch),
991  GCT_2s (ch->t),
992  GNUNET_h2s (&ch->port),
993  GSC_2s (c));
994  if (NULL != ch->retry_control_task)
995  {
996  /* there might be a timeout task here */
998  ch->retry_control_task = NULL;
999  }
1000  options = 0;
1001  if (ch->nobuffer)
1002  options |= GNUNET_CADET_OPTION_NOBUFFER;
1003  if (ch->reliable)
1004  options |= GNUNET_CADET_OPTION_RELIABLE;
1005  if (ch->out_of_order)
1007  cccd = GNUNET_new (struct CadetChannelClient);
1008  GNUNET_assert (NULL == ch->dest);
1009  ch->dest = cccd;
1010  ch->port = *port;
1011  cccd->c = c;
1012  cccd->client_ready = GNUNET_YES;
1013  cccd->ccn = GSC_bind (c,
1014  ch,
1015  (GNUNET_YES == ch->is_loopback)
1016  ? GCP_get (&my_full_id,
1017  GNUNET_YES)
1018  : GCT_get_destination (ch->t),
1019  port,
1020  options);
1021  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1023  ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */
1024  if (GNUNET_YES == ch->is_loopback)
1025  {
1028  NULL,
1029  port);
1030  }
1031  else
1032  {
1033  /* notify other peer that we accepted the connection */
1034  ch->state = CADET_CHANNEL_READY;
1035  ch->retry_control_task
1037  ch);
1038  }
1039  /* give client it's initial supply of ACKs */
1040  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1042  for (unsigned int i=0;i<ch->max_pending_messages;i++)
1043  send_ack_to_client (ch,
1044  GNUNET_NO);
1045 }
1046 
1047 
1055 static void
1057 {
1058  struct CadetChannel *ch = cls;
1059  struct CadetChannelClient *ccc;
1060 
1061  /* Find which end is left... */
1062  ch->retry_control_task = NULL;
1063  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1065  ccc->ccn,
1066  ch);
1067  channel_destroy (ch);
1068 }
1069 
1070 
1079 void
1081  struct CadetClient *c,
1083 {
1085  "%s asks for destruction of %s\n",
1086  GSC_2s (c),
1087  GCCH_2s (ch));
1088  GNUNET_assert (NULL != c);
1089  if ( (NULL != ch->owner) &&
1090  (c == ch->owner->c) &&
1092  {
1093  free_channel_client (ch->owner);
1094  ch->owner = NULL;
1095  }
1096  else if ( (NULL != ch->dest) &&
1097  (c == ch->dest->c) &&
1099  {
1100  free_channel_client (ch->dest);
1101  ch->dest = NULL;
1102  }
1103  else
1104  {
1105  GNUNET_assert (0);
1106  }
1107 
1108  if (GNUNET_YES == ch->destroy)
1109  {
1110  /* other end already destroyed, with the local client gone, no need
1111  to finish transmissions, just destroy immediately. */
1112  channel_destroy (ch);
1113  return;
1114  }
1115  if ( (NULL != ch->head_sent) &&
1116  ( (NULL != ch->owner) ||
1117  (NULL != ch->dest) ) )
1118  {
1119  /* Wait for other end to destroy us as well,
1120  and otherwise allow send queue to be transmitted first */
1121  ch->destroy = GNUNET_YES;
1122  return;
1123  }
1124  if ( (GNUNET_YES == ch->is_loopback) &&
1125  ( (NULL != ch->owner) ||
1126  (NULL != ch->dest) ) )
1127  {
1128  if (NULL != ch->retry_control_task)
1130  ch->retry_control_task
1132  ch);
1133  return;
1134  }
1135  if (GNUNET_NO == ch->is_loopback)
1136  {
1137  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1138  switch (ch->state)
1139  {
1140  case CADET_CHANNEL_NEW:
1141  /* We gave up on a channel that we created as a client to a remote
1142  target, but that never went anywhere. Nothing to do here. */
1143  break;
1144  case CADET_CHANNEL_LOOSE:
1145  break;
1146  default:
1148  ch->ctn);
1149  }
1150  }
1151  /* Nothing left to do, just finish destruction */
1152  channel_destroy (ch);
1153 }
1154 
1155 
1165 void
1167  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1168  const struct GNUNET_HashCode *port)
1169 {
1170  switch (ch->state)
1171  {
1172  case CADET_CHANNEL_NEW:
1173  /* this should be impossible */
1174  GNUNET_break (0);
1175  break;
1176  case CADET_CHANNEL_LOOSE:
1177  /* This makes no sense. */
1178  GNUNET_break_op (0);
1179  break;
1181  if (NULL == ch->owner)
1182  {
1183  /* We're not the owner, wrong direction! */
1184  GNUNET_break_op (0);
1185  return;
1186  }
1187  if (0 != GNUNET_memcmp (&ch->port,
1188  port))
1189  {
1190  /* Other peer failed to provide the right port,
1191  refuse connection. */
1192  GNUNET_break_op (0);
1193  return;
1194  }
1196  "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1197  GCCH_2s (ch));
1198  if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1199  {
1201  ch->retry_control_task = NULL;
1202  }
1203  ch->state = CADET_CHANNEL_READY;
1204  /* On first connect, send client as many ACKs as we allow messages
1205  to be buffered! */
1206  for (unsigned int i=0;i<ch->max_pending_messages;i++)
1207  send_ack_to_client (ch,
1208  GNUNET_YES);
1209  break;
1210  case CADET_CHANNEL_READY:
1211  /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1213  "Received duplicate channel OPEN_ACK for %s\n",
1214  GCCH_2s (ch));
1216  "# duplicate CREATE_ACKs",
1217  1,
1218  GNUNET_NO);
1219  break;
1220  }
1221 }
1222 
1223 
1232 static int
1233 is_before (void *cls,
1234  struct CadetOutOfOrderMessage *m1,
1235  struct CadetOutOfOrderMessage *m2)
1236 {
1237  int *duplicate = cls;
1238  uint32_t v1 = ntohl (m1->mid.mid);
1239  uint32_t v2 = ntohl (m2->mid.mid);
1240  uint32_t delta;
1241 
1242  delta = v2 - v1;
1243  if (0 == delta)
1244  *duplicate = GNUNET_YES;
1245  if (delta > (uint32_t) INT_MAX)
1246  {
1247  /* in overflow range, we can safely assume we wrapped around */
1248  return GNUNET_NO;
1249  }
1250  else
1251  {
1252  /* result is small, thus v2 > v1, thus m1 < m2 */
1253  return GNUNET_YES;
1254  }
1255 }
1256 
1257 
1266 void
1268  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1270 {
1271  struct GNUNET_MQ_Envelope *env;
1272  struct GNUNET_CADET_LocalData *ld;
1273  struct CadetChannelClient *ccc;
1274  size_t payload_size;
1275  struct CadetOutOfOrderMessage *com;
1276  int duplicate;
1277  uint32_t mid_min;
1278  uint32_t mid_max;
1279  uint32_t mid_msg;
1280  uint32_t delta;
1281 
1283  if ( (NULL == ch->owner) &&
1284  (NULL == ch->dest) )
1285  {
1286  /* This client is gone, but we still have messages to send to
1287  the other end (which is why @a ch is not yet dead). However,
1288  we cannot pass messages to our client anymore. */
1290  "Dropping incoming payload on %s as this end is already closed\n",
1291  GCCH_2s (ch));
1292  /* send back DESTROY notification to stop further retransmissions! */
1293  if (GNUNET_YES == ch->destroy)
1295  ch->ctn);
1296  return;
1297  }
1298  payload_size = ntohs (msg->header.size) - sizeof (*msg);
1299  env = GNUNET_MQ_msg_extra (ld,
1300  payload_size,
1302  ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1303  GNUNET_memcpy (&ld[1],
1304  &msg[1],
1305  payload_size);
1306  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1307  if (GNUNET_YES == ccc->client_ready)
1308  {
1309  /*
1310  * We ad-hoc send the message if
1311  * - The channel is out-of-order
1312  * - The channel is reliable and MID matches next expected MID
1313  * - The channel is unreliable and MID is before lowest seen MID
1314  */
1315  if ( (GNUNET_YES == ch->out_of_order) ||
1316  ((msg->mid.mid == ch->mid_recv.mid) &&
1317  (GNUNET_YES == ch->reliable)) ||
1318  ((GNUNET_NO == ch->reliable) &&
1319  (ntohl (msg->mid.mid) >= ntohl (ch->mid_recv.mid)) &&
1320  ((NULL == ccc->head_recv) ||
1321  (ntohl (msg->mid.mid) < ntohl (ccc->head_recv->mid.mid)))) )
1322  {
1324  "Giving %u bytes of payload with MID %u from %s to client %s\n",
1325  (unsigned int) payload_size,
1326  ntohl (msg->mid.mid),
1327  GCCH_2s (ch),
1328  GSC_2s (ccc->c));
1329  ccc->client_ready = GNUNET_NO;
1330  GSC_send_to_client (ccc->c,
1331  env);
1332  if (GNUNET_NO == ch->out_of_order)
1333  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1334  else
1335  ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
1336  ch->mid_futures >>= 1;
1337  if ( (GNUNET_YES == ch->out_of_order) &&
1338  (GNUNET_NO == ch->reliable) )
1339  {
1340  /* possibly shift by more if we skipped messages */
1341  uint64_t delta = htonl (msg->mid.mid) - 1 - ntohl (ch->mid_recv.mid);
1342 
1343  if (delta > 63)
1344  ch->mid_futures = 0;
1345  else
1346  ch->mid_futures >>= delta;
1347  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1348  }
1349  send_channel_data_ack (ch);
1350  return;
1351  }
1352  }
1353 
1354  if (GNUNET_YES == ch->reliable)
1355  {
1356  /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1357  mid_min = ntohl (ch->mid_recv.mid);
1358  mid_max = mid_min + ch->max_pending_messages;
1359  mid_msg = ntohl (msg->mid.mid);
1360  if ( ( (uint32_t) (mid_msg - mid_min) > ch->max_pending_messages) ||
1361  ( (uint32_t) (mid_max - mid_msg) > ch->max_pending_messages) )
1362  {
1364  "%s at %u drops ancient or far-future message %u\n",
1365  GCCH_2s (ch),
1366  (unsigned int) mid_min,
1367  ntohl (msg->mid.mid));
1368 
1370  "# duplicate DATA (ancient or future)",
1371  1,
1372  GNUNET_NO);
1373  GNUNET_MQ_discard (env);
1374  send_channel_data_ack (ch);
1375  return;
1376  }
1377  /* mark bit for future ACKs */
1378  delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1379  if (delta < 64)
1380  {
1381  if (0 != (ch->mid_futures & (1LLU << delta)))
1382  {
1383  /* Duplicate within the queue, drop also */
1385  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1386  (unsigned int) payload_size,
1387  GCCH_2s (ch),
1388  ntohl (msg->mid.mid));
1390  "# duplicate DATA",
1391  1,
1392  GNUNET_NO);
1393  GNUNET_MQ_discard (env);
1394  send_channel_data_ack (ch);
1395  return;
1396  }
1397  ch->mid_futures |= (1LLU << delta);
1399  "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1400  (1LLU << delta),
1401  mid_msg,
1402  mid_min,
1403  ch->mid_futures);
1404  }
1405  }
1406  else /* ! ch->reliable */
1407  {
1408  struct CadetOutOfOrderMessage *next_msg;
1409 
1414  if ((NULL != ccc->head_recv) &&
1415  (GNUNET_YES == ccc->client_ready))
1416  {
1417  next_msg = ccc->head_recv;
1419  "Giving queued MID %u from %s to client %s\n",
1420  ntohl (next_msg->mid.mid),
1421  GCCH_2s (ch),
1422  GSC_2s (ccc->c));
1423  ccc->client_ready = GNUNET_NO;
1424  GSC_send_to_client (ccc->c,
1425  next_msg->env);
1426  ch->mid_recv.mid = htonl (1 + ntohl (next_msg->mid.mid));
1427  ch->mid_futures >>= 1;
1428  send_channel_data_ack (ch);
1430  ccc->tail_recv,
1431  next_msg);
1432  ccc->num_recv--;
1433  /* Do not process duplicate MID */
1434  if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
1435  {
1436  /* Duplicate within the queue, drop */
1438  "Message on %s (mid %u) dropped, duplicate\n",
1439  GCCH_2s (ch),
1440  ntohl (msg->mid.mid));
1441  GNUNET_free (next_msg);
1442  GNUNET_MQ_discard (env);
1443  return;
1444  }
1445  GNUNET_free (next_msg);
1446  }
1447 
1448  if (ntohl (msg->mid.mid) < ntohl (ch->mid_recv.mid)) /* Old */
1449  {
1450  /* Duplicate within the queue, drop */
1452  "Message on %s (mid %u) dropped, old.\n",
1453  GCCH_2s (ch),
1454  ntohl (msg->mid.mid));
1455  GNUNET_MQ_discard (env);
1456  return;
1457  }
1458 
1459  /* Channel is unreliable, so we do not ACK. But we also cannot
1460  allow buffering everything, so check if we have space... */
1461  if (ccc->num_recv >= ch->max_pending_messages)
1462  {
1463  struct CadetOutOfOrderMessage *drop;
1464 
1465  /* Yep, need to drop. Drop the oldest message in
1466  the buffer. */
1468  "Queue full due slow client on %s, dropping oldest message\n",
1469  GCCH_2s (ch));
1471  "# messages dropped due to slow client",
1472  1,
1473  GNUNET_NO);
1474  drop = ccc->head_recv;
1475  GNUNET_assert (NULL != drop);
1477  ccc->tail_recv,
1478  drop);
1479  ccc->num_recv--;
1480  GNUNET_MQ_discard (drop->env);
1481  GNUNET_free (drop);
1482  }
1483  }
1484 
1485  /* Insert message into sorted out-of-order queue */
1486  com = GNUNET_new (struct CadetOutOfOrderMessage);
1487  com->mid = msg->mid;
1488  com->env = env;
1489  duplicate = GNUNET_NO;
1491  is_before,
1492  &duplicate,
1493  ccc->head_recv,
1494  ccc->tail_recv,
1495  com);
1496  ccc->num_recv++;
1497  if (GNUNET_YES == duplicate)
1498  {
1499  /* Duplicate within the queue, drop also (this is not covered by
1500  the case above if "delta" >= 64, which could be the case if
1501  max_pending_messages is also >= 64 or if our client is unready
1502  and we are seeing retransmissions of the message our client is
1503  blocked on. */
1505  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1506  (unsigned int) payload_size,
1507  GCCH_2s (ch),
1508  ntohl (msg->mid.mid));
1510  "# duplicate DATA",
1511  1,
1512  GNUNET_NO);
1514  ccc->tail_recv,
1515  com);
1516  ccc->num_recv--;
1517  GNUNET_MQ_discard (com->env);
1518  GNUNET_free (com);
1519  send_channel_data_ack (ch);
1520  return;
1521  }
1523  "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1524  (GNUNET_YES == ccc->client_ready)
1525  ? "out-of-order"
1526  : "client-not-ready",
1527  (unsigned int) payload_size,
1528  GCCH_2s (ch),
1529  ntohl (ccc->ccn.channel_of_client),
1530  ccc,
1531  ntohl (msg->mid.mid),
1532  ntohl (ch->mid_recv.mid));
1533  /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1534  the sender may already be transmitting the previous one. Needs
1535  experimental evaluation to see if/when this ACK helps or
1536  hurts. (We might even want another option.) */
1537  send_channel_data_ack (ch);
1538 }
1539 
1540 
1551 static void
1552 data_sent_cb (void *cls,
1553  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
1554 
1555 
1562 static void
1564 {
1565  struct CadetChannel *ch = cls;
1566  struct CadetReliableMessage *crm = ch->head_sent;
1567 
1568  ch->retry_data_task = NULL;
1569  GNUNET_assert (NULL == crm->qe);
1571  "Retrying transmission on %s of message %u\n",
1572  GCCH_2s (ch),
1573  (unsigned int) ntohl (crm->data_message->mid.mid));
1574  crm->qe = GCT_send (ch->t,
1575  &crm->data_message->header,
1576  &data_sent_cb,
1577  crm);
1578  GNUNET_assert (NULL == ch->retry_data_task);
1579 }
1580 
1581 
1590 static void
1592  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1593  struct CadetReliableMessage *crm)
1594 {
1596  ch->tail_sent,
1597  crm);
1598  ch->pending_messages--;
1601  "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1602  GCCH_2s (ch),
1603  (unsigned int) ntohl (crm->data_message->mid.mid),
1604  ch->pending_messages);
1605  if (NULL != crm->qe)
1606  {
1607  GCT_send_cancel (crm->qe);
1608  crm->qe = NULL;
1609  }
1610  if ( (1 == crm->num_transmissions) &&
1611  (NULL != cti) )
1612  {
1613  GCC_ack_observed (cti);
1614  if (0 == GNUNET_memcmp (cti,
1615  &crm->connection_taken))
1616  {
1617  GCC_latency_observed (cti,
1619  }
1620  }
1621  GNUNET_free (crm->data_message);
1622  GNUNET_free (crm);
1623  send_ack_to_client (ch,
1624  (NULL == ch->owner)
1625  ? GNUNET_NO
1626  : GNUNET_YES);
1627 }
1628 
1629 
1638 void
1640  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1641  const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1642 {
1643  struct CadetReliableMessage *crm;
1644  struct CadetReliableMessage *crmn;
1645  int found;
1646  uint32_t mid_base;
1647  uint64_t mid_mask;
1648  unsigned int delta;
1649 
1651  if (GNUNET_NO == ch->reliable)
1652  {
1653  /* not expecting ACKs on unreliable channel, odd */
1654  GNUNET_break_op (0);
1655  return;
1656  }
1657  /* mid_base is the MID of the next message that the
1658  other peer expects (i.e. that is missing!), everything
1659  LOWER (but excluding mid_base itself) was received. */
1660  mid_base = ntohl (ack->mid.mid);
1661  mid_mask = GNUNET_htonll (ack->futures);
1662  found = GNUNET_NO;
1663  for (crm = ch->head_sent;
1664  NULL != crm;
1665  crm = crmn)
1666  {
1667  crmn = crm->next;
1668  delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base);
1669  if (delta >= UINT_MAX - ch->max_pending_messages)
1670  {
1671  /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1673  "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1674  (unsigned int) mid_base,
1675  ntohl (crm->data_message->mid.mid),
1676  GCCH_2s (ch));
1677  handle_matching_ack (ch,
1678  cti,
1679  crm);
1680  found = GNUNET_YES;
1681  continue;
1682  }
1683  delta--;
1684  if (delta >= 64)
1685  continue;
1687  "Testing bit %llX for mid %u (base: %u)\n",
1688  (1LLU << delta),
1689  ntohl (crm->data_message->mid.mid),
1690  mid_base);
1691  if (0 != (mid_mask & (1LLU << delta)))
1692  {
1694  "Got DATA_ACK with mask for %u on %s\n",
1695  ntohl (crm->data_message->mid.mid),
1696  GCCH_2s (ch));
1697  handle_matching_ack (ch,
1698  cti,
1699  crm);
1700  found = GNUNET_YES;
1701  }
1702  }
1703  if (GNUNET_NO == found)
1704  {
1705  /* ACK for message we already dropped, might have been a
1706  duplicate ACK? Ignore. */
1708  "Duplicate DATA_ACK on %s, ignoring\n",
1709  GCCH_2s (ch));
1711  "# duplicate DATA_ACKs",
1712  1,
1713  GNUNET_NO);
1714  return;
1715  }
1716  if (NULL != ch->retry_data_task)
1717  {
1719  ch->retry_data_task = NULL;
1720  }
1721  if ( (NULL != ch->head_sent) &&
1722  (NULL == ch->head_sent->qe) )
1723  ch->retry_data_task
1726  ch);
1727 }
1728 
1729 
1739 void
1741  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
1742 {
1743  struct CadetChannelClient *ccc;
1744 
1747  "Received remote channel DESTROY for %s\n",
1748  GCCH_2s (ch));
1749  if (GNUNET_YES == ch->destroy)
1750  {
1751  /* Local client already gone, this is instant-death. */
1752  channel_destroy (ch);
1753  return;
1754  }
1755  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1756  if ( (NULL != ccc) &&
1757  (NULL != ccc->head_recv) )
1758  {
1760  "Lost end of transmission due to remote shutdown on %s\n",
1761  GCCH_2s (ch));
1762  /* FIXME: change API to notify client about truncated transmission! */
1763  }
1764  ch->destroy = GNUNET_YES;
1765  if (NULL != ccc)
1767  ccc->ccn,
1768  ch);
1769  channel_destroy (ch);
1770 }
1771 
1772 
1781 static int
1783  struct CadetReliableMessage *crm1,
1784  struct CadetReliableMessage *crm2)
1785 {
1786  if (crm1->next_retry.abs_value_us <
1787  crm2->next_retry.abs_value_us)
1788  return GNUNET_YES;
1789  return GNUNET_NO;
1790 }
1791 
1792 
1803 static void
1804 data_sent_cb (void *cls,
1805  const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1806 {
1807  struct CadetReliableMessage *crm = cls;
1808  struct CadetChannel *ch = crm->ch;
1809 
1811  GNUNET_assert (NULL != crm->qe);
1812  crm->qe = NULL;
1814  ch->tail_sent,
1815  crm);
1816  if (GNUNET_NO == ch->reliable)
1817  {
1818  GNUNET_free (crm->data_message);
1819  GNUNET_free (crm);
1820  ch->pending_messages--;
1821  send_ack_to_client (ch,
1822  (NULL == ch->owner)
1823  ? GNUNET_NO
1824  : GNUNET_YES);
1825  return;
1826  }
1827  if (NULL == cid)
1828  {
1829  /* There was an error sending. */
1831  }
1832  else if (GNUNET_SYSERR != crm->num_transmissions)
1833  {
1834  /* Increment transmission counter, and possibly store @a cid
1835  if this was the first transmission. */
1836  crm->num_transmissions++;
1837  if (1 == crm->num_transmissions)
1838  {
1840  crm->connection_taken = *cid;
1841  GCC_ack_expected (cid);
1842  }
1843  }
1844  if ( (0 == crm->retry_delay.rel_value_us) &&
1845  (NULL != cid) )
1846  {
1847  struct CadetConnection *cc = GCC_lookup (cid);
1848 
1849  if (NULL != cc)
1851  else
1852  crm->retry_delay = ch->retry_time;
1853  }
1856  MIN_RTT_DELAY);
1858 
1861  NULL,
1862  ch->head_sent,
1863  ch->tail_sent,
1864  crm);
1866  "Message %u sent, next transmission on %s in %s\n",
1867  (unsigned int) ntohl (crm->data_message->mid.mid),
1868  GCCH_2s (ch),
1870  GNUNET_YES));
1871  if (NULL == ch->head_sent->qe)
1872  {
1873  if (NULL != ch->retry_data_task)
1875  ch->retry_data_task
1878  ch);
1879  }
1880 }
1881 
1882 
1897 int
1899  struct GNUNET_CADET_ClientChannelNumber sender_ccn,
1900  const char *buf,
1901  size_t buf_len)
1902 {
1903  struct CadetReliableMessage *crm;
1904 
1905  if (ch->pending_messages >= ch->max_pending_messages)
1906  {
1907  GNUNET_break (0); /* Fails: #5370 */
1908  return GNUNET_SYSERR;
1909  }
1910  if (GNUNET_YES == ch->destroy)
1911  {
1912  /* we are going down, drop messages */
1913  return GNUNET_OK;
1914  }
1915  ch->pending_messages++;
1916 
1917  if (GNUNET_YES == ch->is_loopback)
1918  {
1919  struct CadetChannelClient *receiver;
1920  struct GNUNET_MQ_Envelope *env;
1921  struct GNUNET_CADET_LocalData *ld;
1922  int ack_to_owner;
1923 
1924  env = GNUNET_MQ_msg_extra (ld,
1925  buf_len,
1927  if ( (NULL != ch->owner) &&
1928  (sender_ccn.channel_of_client ==
1929  ch->owner->ccn.channel_of_client) )
1930  {
1931  receiver = ch->dest;
1932  ack_to_owner = GNUNET_YES;
1933  }
1934  else if ( (NULL != ch->dest) &&
1935  (sender_ccn.channel_of_client ==
1936  ch->dest->ccn.channel_of_client) )
1937  {
1938  receiver = ch->owner;
1939  ack_to_owner = GNUNET_NO;
1940  }
1941  else
1942  {
1943  GNUNET_break (0);
1944  return GNUNET_SYSERR;
1945  }
1946  GNUNET_assert (NULL != receiver);
1947  ld->ccn = receiver->ccn;
1948  GNUNET_memcpy (&ld[1],
1949  buf,
1950  buf_len);
1951  if (GNUNET_YES == receiver->client_ready)
1952  {
1953  ch->pending_messages--;
1954  GSC_send_to_client (receiver->c,
1955  env);
1956  send_ack_to_client (ch,
1957  ack_to_owner);
1958  }
1959  else
1960  {
1961  struct CadetOutOfOrderMessage *oom;
1962 
1963  oom = GNUNET_new (struct CadetOutOfOrderMessage);
1964  oom->env = env;
1966  receiver->tail_recv,
1967  oom);
1968  receiver->num_recv++;
1969  }
1970  return GNUNET_OK;
1971  }
1972 
1973  /* Everything is correct, send the message. */
1974  crm = GNUNET_malloc (sizeof (*crm));
1975  crm->ch = ch;
1977  + buf_len);
1978  crm->data_message->header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1980  ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1981  crm->data_message->mid = ch->mid_send;
1982  crm->data_message->ctn = ch->ctn;
1983  GNUNET_memcpy (&crm->data_message[1],
1984  buf,
1985  buf_len);
1987  ch->tail_sent,
1988  crm);
1990  "Sending message %u from local client to %s with %u bytes\n",
1991  ntohl (crm->data_message->mid.mid),
1992  GCCH_2s (ch),
1993  buf_len);
1994  if (NULL != ch->retry_data_task)
1995  {
1997  ch->retry_data_task = NULL;
1998  }
1999  crm->qe = GCT_send (ch->t,
2000  &crm->data_message->header,
2001  &data_sent_cb,
2002  crm);
2003  GNUNET_assert (NULL == ch->retry_data_task);
2004  return GNUNET_OK;
2005 }
2006 
2007 
2015 void
2017  struct GNUNET_CADET_ClientChannelNumber client_ccn)
2018 {
2019  struct CadetChannelClient *ccc;
2020  struct CadetOutOfOrderMessage *com;
2021 
2022  if ( (NULL != ch->owner) &&
2023  (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client) )
2024  ccc = ch->owner;
2025  else if ( (NULL != ch->dest) &&
2026  (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client) )
2027  ccc = ch->dest;
2028  else
2029  GNUNET_assert (0);
2030  ccc->client_ready = GNUNET_YES;
2031  com = ccc->head_recv;
2032  if (NULL == com)
2033  {
2035  "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
2036  GSC_2s (ccc->c),
2037  ntohl (client_ccn.channel_of_client),
2038  GCCH_2s (ch),
2039  ntohl (ccc->ccn.channel_of_client),
2040  ccc);
2041  return; /* none pending */
2042  }
2043  if (GNUNET_YES == ch->is_loopback)
2044  {
2045  int to_owner;
2046 
2047  /* Messages are always in-order, just send */
2049  ccc->tail_recv,
2050  com);
2051  ccc->num_recv--;
2052  GSC_send_to_client (ccc->c,
2053  com->env);
2054  /* Notify sender that we can receive more */
2055  if ( (NULL != ch->owner) &&
2056  (ccc->ccn.channel_of_client ==
2057  ch->owner->ccn.channel_of_client) )
2058  {
2059  to_owner = GNUNET_NO;
2060  }
2061  else
2062  {
2063  GNUNET_assert ( (NULL != ch->dest) &&
2064  (ccc->ccn.channel_of_client ==
2065  ch->dest->ccn.channel_of_client) );
2066  to_owner = GNUNET_YES;
2067  }
2068  send_ack_to_client (ch,
2069  to_owner);
2070  GNUNET_free (com);
2071  return;
2072  }
2073 
2074  if ( (com->mid.mid != ch->mid_recv.mid) &&
2075  (GNUNET_NO == ch->out_of_order) &&
2076  (GNUNET_YES == ch->reliable) )
2077  {
2079  "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
2080  GSC_2s (ccc->c),
2081  ntohl (ccc->ccn.channel_of_client),
2082  ntohl (com->mid.mid),
2083  ntohl (ch->mid_recv.mid));
2084  return; /* missing next one in-order */
2085  }
2086 
2088  "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
2089  ntohl (com->mid.mid),
2090  GSC_2s (ccc->c),
2091  ntohl (ccc->ccn.channel_of_client),
2092  GCCH_2s (ch));
2093 
2094  /* all good, pass next message to client */
2096  ccc->tail_recv,
2097  com);
2098  ccc->num_recv--;
2099  /* FIXME: if unreliable, this is not aggressive
2100  enough, as it would be OK to have lost some! */
2101 
2102  ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
2103  ch->mid_futures >>= 1; /* equivalent to division by 2 */
2104  ccc->client_ready = GNUNET_NO;
2105  GSC_send_to_client (ccc->c,
2106  com->env);
2107  GNUNET_free (com);
2108  send_channel_data_ack (ch);
2109  if (NULL != ccc->head_recv)
2110  return;
2111  if (GNUNET_NO == ch->destroy)
2112  return;
2114  ch->ctn);
2115  channel_destroy (ch);
2116 }
2117 
2118 
2119 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__)
2120 
2121 
2128 void
2130  enum GNUNET_ErrorType level)
2131 {
2132 #if !defined(GNUNET_CULL_LOGGING)
2133  int do_log;
2134 
2136  "cadet-chn",
2137  __FILE__, __FUNCTION__, __LINE__);
2138  if (0 == do_log)
2139  return;
2140 
2141  if (NULL == ch)
2142  {
2143  LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
2144  return;
2145  }
2146  LOG2 (level,
2147  "CHN %s:%X (%p)\n",
2148  GCT_2s (ch->t),
2149  ch->ctn,
2150  ch);
2151  if (NULL != ch->owner)
2152  {
2153  LOG2 (level,
2154  "CHN origin %s ready %s local-id: %u\n",
2155  GSC_2s (ch->owner->c),
2156  ch->owner->client_ready ? "YES" : "NO",
2157  ntohl (ch->owner->ccn.channel_of_client));
2158  }
2159  if (NULL != ch->dest)
2160  {
2161  LOG2 (level,
2162  "CHN destination %s ready %s local-id: %u\n",
2163  GSC_2s (ch->dest->c),
2164  ch->dest->client_ready ? "YES" : "NO",
2165  ntohl (ch->dest->ccn.channel_of_client));
2166  }
2167  LOG2 (level,
2168  "CHN Message IDs recv: %d (%LLX), send: %d\n",
2169  ntohl (ch->mid_recv.mid),
2170  (unsigned long long) ch->mid_futures,
2171  ntohl (ch->mid_send.mid));
2172 #endif
2173 }
2174 
2175 
2176 
2177 /* end of gnunet-service-cadet-new_channel.c */
int out_of_order
Is the tunnel out-of-order?
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static int is_before(void *cls, struct CadetOutOfOrderMessage *m1, struct CadetOutOfOrderMessage *m2)
Test if element e1 comes before element e2.
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
uint64_t futures
Bitfield of already-received newer messages.
void GCT_remove_channel(struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Remove a channel from a tunnel.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
struct CadetChannel * ch
Which channel is this message in?
struct GNUNET_HashCode h_port
Hash of destination port and listener.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
Connection confirmed, ready to carry traffic.
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK&#39;d.
enum CadetChannelState state
Channel state.
Peer description.
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
Info needed to retry a message in case it gets lost.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
Message to allow the client send more data to the service (always service -> client).
Definition: cadet.h: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:286
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:245
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.
Enable channel reliability, lost messages will be retransmitted.
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 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:81
CadetChannelState
All the states a channel can be in.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:446
GNUNET_ErrorType
Types of errors.
uint32_t opt
Channel options.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct CadetChannel * GCCH_channel_local_new(struct CadetClient *owner, struct GNUNET_CADET_ClientChannelNumber ccn, struct CadetPeer *destination, const struct GNUNET_HashCode *port, uint32_t options)
Create a new channel.
static void retry_transmission(void *cls)
We need to retry a transmission, the last one took too long to be acknowledged.
void GSC_handle_remote_channel_destroy(struct CadetClient *c, struct GNUNET_CADET_ClientChannelNumber ccn, struct CadetChannel *ch)
A channel was destroyed by the other peer.
List of received out-of-order data messages.
struct CadetReliableMessage * prev
Double linked list, FIFO style.
Context for cummulative hashing.
Definition: crypto_hash.c:431
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GCCH_hash_port(struct GNUNET_HashCode *h_port, const struct GNUNET_HashCode *port, const struct GNUNET_PeerIdentity *listener)
Hash the port and initiator and listener to calculate the "challenge" h_port we send to the other pee...
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_MQ_Envelope * env
The envelope with the payload of the out-of-order message.
unsigned int num_recv
Number of entries currently in head_recv DLL.
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
void GCCH_handle_local_ack(struct CadetChannel *ch, struct GNUNET_CADET_ClientChannelNumber client_ccn)
Handle ACK from client on local channel.
static void signal_remote_destroy_cb(void *cls)
One of our clients has disconnected, tell the other one that we are finished.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
struct GNUNET_CONTAINER_MultiHashMap * open_ports
All ports clients of this peer have opened.
int reliable
Is the tunnel reliable?
struct GNUNET_CONTAINER_MultiHashMap * loose_channels
Map from ports to channels where the ports were closed at the time we got the inbound connection...
static void free_channel_client(struct CadetChannelClient *ccc)
Release memory associated with ccc.
#define INT_MAX
struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id(const struct CadetChannel *ch)
Get the channel&#39;s public ID.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
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
#define GNUNET_memcpy(dst, src, n)
unsigned int skip_ack_series
Count how many ACKs we skipped, used to prevent long sequences of ACK skipping.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN.
#define LOG(level,...)
struct GNUNET_TIME_Absolute next_retry
How soon should we retry if we fail to get an ACK? Messages in the queue are sorted by this value...
struct CadetOutOfOrderMessage * tail_recv
Tail DLL of messages received out of order or while client was unready.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_HashCode h_port
Port hashed with our PID (matches incoming OPEN messages).
Struct containing all information regarding a channel to a remote client.
Channel is to a port that is not open, we&#39;re waiting for the port to be opened.
struct GNUNET_CADET_ConnectionTunnelIdentifier connection_taken
Identifier of the connection that this message took when it was first transmitted.
struct GNUNET_TIME_Relative retry_time
Counter for exponential backoff.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
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:727
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.
Enable out of order delivery of messages.
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:79
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:472
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:79
Hash uniquely identifying a connection below a tunnel.
static void send_ack_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel confirms that we sent the ACK message.
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer stucture associated with the peer.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA
Payload client <-> service.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
Client endpoint of a struct CadetChannel.
struct GNUNET_TIME_Relative retry_delay
How long do we wait for an ACK after transmission? Use for the back-off calculation.
Number identifying a CADET channel within a tunnel.
Entry in list of pending tasks.
Definition: scheduler.c: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:80
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:139
struct ChannelMessageIdentifier mid
ID of the message (messages up to this point needed before we give this one to the client)...
static void send_open_ack(void *cls)
Send our initial GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the connect...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition: scheduler.c:1223
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:489
#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.
Disable buffering on intermediate nodes (for minimum latency).
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:965
struct GNUNET_HashCode port
Destination port of the channel.