GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
Loading...
Searching...
No Matches
gnunet-service-cadet_tunnels.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017, 2018 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 */
33#include "gnunet_common.h"
34#include "gnunet_pils_service.h"
36#include "platform.h"
37#include "gnunet_util_lib.h"
39#include "cadet_protocol.h"
45
46
47#define LOG(level, ...) GNUNET_log_from (level, "cadet-tun", __VA_ARGS__)
48
54#define MAX_UNVERIFIED_ATTEMPTS 16
55
59#define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply ( \
60 GNUNET_TIME_UNIT_SECONDS, 90)
61
66#define INITIAL_KX_RETRY_DELAY GNUNET_TIME_relative_multiply ( \
67 GNUNET_TIME_UNIT_MILLISECONDS, 250)
68
72#define MAX_SKIPPED_KEYS 64
73
78#define MAX_KEY_GAP 256
79
80
116
117
256
257
264typedef void
265(*CadetTunnelAxolotlCallback) (void *cls,
267
268
321
322
364
365
531
532
539int
541{
542 const struct GNUNET_PeerIdentity *my_identity;
543
546
547 if (0 > GNUNET_memcmp (my_identity, other))
548 return GNUNET_YES;
549 else if (0 < GNUNET_memcmp (my_identity, other))
550 return GNUNET_NO;
551 else
552 {
553 GNUNET_break_op (0);
554 return GNUNET_SYSERR;
555 }
556}
557
558
565static void
567{
568 struct CadetTunnel *t = ct->t;
569
571 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
572 t->connection_ready_tail,
573 ct);
574 GNUNET_assert (0 < t->num_ready_connections);
575 t->num_ready_connections--;
576 ct->is_ready = GNUNET_NO;
577 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
578 t->connection_busy_tail,
579 ct);
580 t->num_busy_connections++;
581}
582
583
591const char *
592GCT_2s (const struct CadetTunnel *t)
593{
594 static char buf[64];
595
596 if (NULL == t)
597 return "Tunnel(NULL)";
598 GNUNET_snprintf (buf,
599 sizeof(buf),
600 "Tunnel %s",
601 GNUNET_i2s (GCP_get_id (t->destination)));
602 return buf;
603}
604
605
613static const char *
615{
616 static char buf[32];
617
618 switch (es)
619 {
621 return "CADET_TUNNEL_KEY_UNINITIALIZED";
623 return "CADET_TUNNEL_KEY_AX_RECV";
625 return "CADET_TUNNEL_KEY_AX_SENT";
627 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
629 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
631 return "CADET_TUNNEL_KEY_OK";
632 }
633 GNUNET_snprintf (buf,
634 sizeof(buf),
635 "%u (UNKNOWN STATE)",
636 es);
637 return buf;
638}
639
640
647struct CadetPeer *
649{
650 return t->destination;
651}
652
653
654unsigned int
656{
657 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
658}
659
660
668static struct CadetChannel *
671{
672 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
673 ntohl (ctn.cn));
674}
675
676
677unsigned int
679{
680 return t->num_ready_connections + t->num_busy_connections;
681}
682
683
691static struct CadetTConnection *
693{
694 struct CadetTConnection *hd = t->connection_ready_head;
695
696 GNUNET_assert ((NULL == hd) ||
697 (GNUNET_YES == hd->is_ready));
698 return hd;
699}
700
701
711{
712 return t->estate;
713}
714
715
724static void
725trigger_transmissions (void *cls);
726
727
728/* ************************************** start core crypto ***************************** */
729
730
736static void
738{
740 "Creating new ephemeral ratchet key (DHRs)\n");
742}
743
744
753static void
755 struct GNUNET_HashCode *hash,
756 const void *source,
757 unsigned int len)
758{
759 static const char ctx[] = "axolotl HMAC-HASH";
760 struct GNUNET_CRYPTO_AuthKey auth_key;
761
763 &auth_key,
764 sizeof auth_key,
765 ctx,
766 sizeof(ctx),
767 key,
768 sizeof *key);
769 GNUNET_CRYPTO_hmac (&auth_key,
770 source,
771 len,
772 hash);
773}
774
775
784static void
786 struct GNUNET_CRYPTO_AeadSecretKey *out,
787 const void *source,
788 unsigned int len)
789{
790 static const char ctx[] = "axolotl derive key";
791 struct GNUNET_HashCode h;
792
794 &h,
795 source,
796 len);
798 out, sizeof(*out),
799 ctx, sizeof(ctx),
800 &h, sizeof(h));
801}
802
803
812static void
814 void *dst,
815 const void *src,
816 size_t size)
817{
819 struct GNUNET_CRYPTO_AeadNonce iv;
821
822 ax->ratchet_counter++;
823 if ((GNUNET_YES == ax->ratchet_allowed) &&
824 ((ratchet_messages <= ax->ratchet_counter) ||
827 {
829 }
830 if (GNUNET_YES == ax->ratchet_flag)
831 {
832 /* Advance ratchet */
833 struct GNUNET_CRYPTO_AeadSecretKey keys[3];
834 struct GNUNET_HashCode dh;
835 struct GNUNET_HashCode hmac;
836 static const char ctx[] = "axolotl ratchet";
837
838 new_ephemeral (ax);
839 ax->HKs = ax->NHKs;
840
841 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
843 &ax->DHRr,
844 &dh);
845 t_ax_hmac_hash (&ax->RK,
846 &hmac,
847 &dh,
848 sizeof(dh));
850 keys, sizeof(keys),
851 ctx, sizeof(ctx),
852 &hmac, sizeof(hmac));
853 ax->RK = keys[0];
854 ax->NHKs = keys[1];
855 ax->CKs = keys[2];
856
857 ax->PNs = ax->Ns;
858 ax->Ns = 0;
861 ax->ratchet_counter = 0;
865 }
866
868 &MK,
869 "0",
870 1);
871
873 sizeof iv,
874 NULL,
875 0,
876 &MK,
877 sizeof MK);
878
879 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) dst)[size];
881 src,
882 0,
883 NULL,
884 &MK,
885 &iv,
886 dst,
887 mac));
889 &ax->CKs,
890 "1",
891 1);
892}
893
894
903static void
905 void *dst,
906 const void *src,
907 size_t size)
908{
910 struct GNUNET_CRYPTO_AeadNonce iv;
912 size_t macoffset = size - sizeof (struct GNUNET_CRYPTO_AeadMac);
913
915 &MK,
916 "0",
917 1);
918
920 sizeof iv,
921 NULL,
922 0,
923 &MK,
924 sizeof MK);
925 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
926 mac = (struct GNUNET_CRYPTO_AeadMac*) &((char*) src)[macoffset];
928 src,
929 0,
930 NULL,
931 &MK,
932 &iv,
933 mac,
934 dst));
936 &ax->CKr,
937 "1",
938 1);
939}
940
941
948static void
951 size_t additional_data_size,
952 const unsigned char *additional_data)
953{
954 struct GNUNET_CRYPTO_AeadNonce nonce;
955
957 sizeof nonce,
958 NULL,
959 0,
960 &ax->HKs,
961 sizeof ax->HKs);
963 ,
964 (unsigned char*) &msg
965 ->ax_header,
966 additional_data_size,
967 additional_data,
968 &ax->HKs,
969 &nonce,
970 &msg->ax_header,
971 &msg->mac));
972}
973
974
986 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
987 size_t esize,
989{
990 struct GNUNET_CRYPTO_AeadNonce iv;
991
993 sizeof iv,
994 NULL,
995 0,
996 hkr,
997 sizeof *hkr);
998
999
1001 (unsigned char*) &src->ax_header,
1002 esize,
1003 (unsigned char*) &src[1],
1004 hkr,
1005 &iv,
1006 &dst->mac,
1007 &dst->ax_header);
1008}
1009
1010
1017static void
1019 struct CadetTunnelSkippedKey *key)
1020{
1022 ax->skipped_tail,
1023 key);
1024 GNUNET_free (key);
1025 ax->skipped--;
1026}
1027
1028
1039static ssize_t
1041 void *dst,
1042 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1043 size_t size)
1044{
1045 struct CadetTunnelSkippedKey *key;
1046 struct GNUNET_CRYPTO_AeadNonce iv;
1047 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1048 struct GNUNET_CRYPTO_AeadSecretKey *valid_HK;
1049 size_t esize;
1050 size_t len;
1051 unsigned int N;
1052 size_t macoffset = size - sizeof (struct GNUNET_CRYPTO_AeadMac);
1053
1055 "Trying skipped keys\n");
1056 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1057 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1059 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1060 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1061
1062 /* Find a correct Header Key */
1063 valid_HK = NULL;
1064 for (key = ax->skipped_head; NULL != key; key = key->next)
1065 {
1066 /* Try decrypt header */
1067 if (GNUNET_OK == t_h_decrypt (&key->HK,
1068 src,
1069 esize,
1070 &plaintext_header))
1071 {
1072 valid_HK = &key->HK;
1073 break;
1074 }
1075 }
1076 if (NULL == key)
1077 return -1;
1078
1079 /* Find the correct message key */
1080 N = ntohl (plaintext_header.ax_header.Ns);
1081 while ((NULL != key) &&
1082 (N != key->Kn))
1083 key = key->next;
1084 if ((NULL == key) ||
1085 (0 != GNUNET_memcmp (&key->HK,
1086 valid_HK)))
1087 return -1;
1088
1089 /* Decrypt payload */
1091 sizeof iv,
1092 NULL,
1093 0,
1094 &key->MK,
1095 sizeof key->MK);
1096
1098 len,
1099 (unsigned char*) &src[1],
1100 0,
1101 NULL,
1102 &key->MK,
1103 &iv,
1104 (struct GNUNET_CRYPTO_AeadMac*) &src[macoffset],
1105 dst))
1106 {
1107 return -1;
1108 }
1110 key);
1111 return len - sizeof (struct GNUNET_CRYPTO_AeadMac);
1112}
1113
1114
1121static void
1123 const struct GNUNET_CRYPTO_AeadSecretKey *HKr)
1124{
1125 struct CadetTunnelSkippedKey *key;
1126
1128 key->timestamp = GNUNET_TIME_absolute_get ();
1129 key->Kn = ax->Nr;
1130 key->HK = ax->HKr;
1131 t_hmac_derive_key (&ax->CKr,
1132 &key->MK,
1133 "0",
1134 1);
1135 t_hmac_derive_key (&ax->CKr,
1136 &ax->CKr,
1137 "1",
1138 1);
1140 ax->skipped_tail,
1141 key);
1142 ax->skipped++;
1143 ax->Nr++;
1144}
1145
1146
1157static int
1159 const struct GNUNET_CRYPTO_AeadSecretKey *HKr,
1160 uint32_t Np)
1161{
1162 int gap;
1163
1164 gap = Np - ax->Nr;
1166 "Storing skipped keys [%u, %u)\n",
1167 ax->Nr,
1168 Np);
1169 if (MAX_KEY_GAP < gap)
1170 {
1171 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1172 /* TODO: start new key exchange on return */
1173 GNUNET_break_op (0);
1175 "Got message %u, expected %u+\n",
1176 Np,
1177 ax->Nr);
1178 return GNUNET_SYSERR;
1179 }
1180 if (0 > gap)
1181 {
1182 /* Delayed message: don't store keys, flag to try old keys. */
1183 return GNUNET_SYSERR;
1184 }
1185
1186 while (ax->Nr < Np)
1188 HKr);
1189
1190 while (ax->skipped > MAX_SKIPPED_KEYS)
1192 ax->skipped_tail);
1193 return GNUNET_OK;
1194}
1195
1196
1207static ssize_t
1209 void *dst,
1210 const struct
1212 size_t size)
1213{
1214 struct GNUNET_HashCode hmac;
1215 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1216 uint32_t Np;
1217 uint32_t PNp;
1218 size_t esize; /* Size of encrypted payload */
1219
1220 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1221
1222 if (GNUNET_OK == t_h_decrypt (&ax->HKr,
1223 src,
1224 esize,
1225 &plaintext_header))
1226 {
1227 Np = ntohl (plaintext_header.ax_header.Ns);
1228 PNp = ntohl (plaintext_header.ax_header.PNs);
1229 }
1230 else
1231 {
1232 static const char ctx[] = "axolotl ratchet";
1233 struct GNUNET_CRYPTO_AeadSecretKey keys[3]; /* RKp, NHKp, CKp */
1235 struct GNUNET_HashCode dh;
1236 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1237
1238 /* Try Next HK */
1239 if (GNUNET_OK == t_h_decrypt (&ax->NHKr,
1240 src,
1241 esize,
1242 &plaintext_header))
1243 {
1244 /* Try the skipped keys, if that fails, we're out of luck. */
1245 return try_old_ax_keys (ax,
1246 dst,
1247 src,
1248 size);
1249 }
1250 HK = ax->HKr;
1251 ax->HKr = ax->NHKr;
1252 Np = ntohl (plaintext_header.ax_header.Ns);
1253 PNp = ntohl (plaintext_header.ax_header.PNs);
1254 DHRp = &plaintext_header.ax_header.DHRs;
1255 store_ax_keys (ax,
1256 &HK,
1257 PNp);
1258
1259 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1261 DHRp,
1262 &dh);
1263 t_ax_hmac_hash (&ax->RK,
1264 &hmac,
1265 &dh, sizeof(dh));
1267 keys, sizeof(keys),
1268 ctx, sizeof(ctx),
1269 &hmac, sizeof(hmac));
1270
1271 /* Commit "purported" keys */
1272 ax->RK = keys[0];
1273 ax->NHKr = keys[1];
1274 ax->CKr = keys[2];
1275 ax->DHRr = *DHRp;
1276 ax->Nr = 0;
1278
1279 }
1280 if ((Np != ax->Nr) &&
1281 (GNUNET_OK != store_ax_keys (ax,
1282 &ax->HKr,
1283 Np)))
1284 {
1285 /* Try the skipped keys, if that fails, we're out of luck. */
1286 return try_old_ax_keys (ax,
1287 dst,
1288 src,
1289 size);
1290 }
1291
1292 t_ax_decrypt (ax,
1293 dst,
1294 &src[1],
1295 esize);
1296 ax->Nr = Np + 1;
1297 return esize - sizeof (struct GNUNET_CRYPTO_AeadMac);
1298}
1299
1300
1310static int
1312 uint32_t key,
1313 void *value)
1314{
1315 struct CadetChannel *ch = value;
1316
1318 return GNUNET_OK;
1319}
1320
1321
1329void
1332{
1333 enum CadetTunnelEState old = t->estate;
1334
1335 t->estate = state;
1337 "%s estate changed from %s to %s\n",
1338 GCT_2s (t),
1339 estate2s (old),
1340 estate2s (state));
1341
1342 if ((CADET_TUNNEL_KEY_OK != old) &&
1343 (CADET_TUNNEL_KEY_OK == t->estate))
1344 {
1345 if (NULL != t->kx_task)
1346 {
1347 GNUNET_SCHEDULER_cancel (t->kx_task);
1348 t->kx_task = NULL;
1349 }
1350 /* notify all channels that have been waiting */
1353 t);
1354 if (NULL != t->send_task)
1355 GNUNET_SCHEDULER_cancel (t->send_task);
1357 t);
1358 }
1359}
1360
1361
1370static void
1372 struct CadetTConnection *ct,
1373 struct CadetTunnelAxolotl *ax)
1374{
1375 struct CadetConnection *cc;
1376 struct GNUNET_MQ_Envelope *env;
1379
1380 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1381 return; /* only Alice may send KX */
1382 if ((NULL == ct) ||
1383 (GNUNET_NO == ct->is_ready))
1384 ct = get_ready_connection (t);
1385 if (NULL == ct)
1386 {
1388 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1389 GCT_2s (t),
1390 estate2s (t->estate));
1391 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1392 return;
1393 }
1394 cc = ct->cc;
1397 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1398 msg->flags = htonl (flags);
1399 msg->cid = *GCC_get_id (cc);
1401 &msg->ephemeral_key);
1402#if DEBUG_KX
1403 msg->ephemeral_key_XXX = ax->kx_0;
1404#endif
1406 "Sending KX message to %s with ephemeral %s on CID %s\n",
1407 GCT_2s (t),
1408 GNUNET_e2s (&msg->ephemeral_key),
1409 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1411 &msg->ratchet_key);
1413 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1414 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1415 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1418 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1421 GCC_transmit (cc,
1422 env);
1424 "# KX transmitted",
1425 1,
1426 GNUNET_NO);
1427}
1428
1429
1440static void
1442 struct CadetTConnection *ct,
1443 struct CadetTunnelAxolotl *ax,
1444 int force_reply)
1445{
1446 struct CadetConnection *cc;
1447 struct GNUNET_MQ_Envelope *env;
1449 enum GNUNET_CADET_KX_Flags flags;
1450
1451 if ((NULL == ct) ||
1452 (GNUNET_NO == ct->is_ready))
1453 ct = get_ready_connection (t);
1454 if (NULL == ct)
1455 {
1457 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1458 GCT_2s (t));
1459 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1460 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1461 return;
1462 }
1463 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1464 cc = ct->cc;
1468 if (GNUNET_YES == force_reply)
1470 msg->kx.flags = htonl (flags);
1471 msg->kx.cid = *GCC_get_id (cc);
1473 &msg->kx.ephemeral_key);
1475 &msg->kx.ratchet_key);
1476#if DEBUG_KX
1477 msg->kx.ephemeral_key_XXX = ax->kx_0;
1478 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1479#endif
1481 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1482 GCT_2s (t),
1483 GNUNET_e2s (&msg->kx.ephemeral_key),
1484 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1485
1486 /* Compute authenticator (this is the main difference to #send_kx()) */
1487 GNUNET_CRYPTO_hash (&ax->RK,
1488 sizeof(ax->RK),
1489 &msg->auth);
1490 /* Compute when to be triggered again; actual job will
1491 be scheduled via #connection_ready_cb() */
1492 t->kx_retry_delay
1493 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1494 t->next_kx_attempt
1495 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1496
1497 /* Send via cc, mark it as unready */
1499
1500 /* Update state machine, unless we are already OK */
1501 if (CADET_TUNNEL_KEY_OK != t->estate)
1504 GCC_transmit (cc,
1505 env);
1507 "# KX_AUTH transmitted",
1508 1,
1509 GNUNET_NO);
1510}
1511
1512
1518static void
1520{
1521 while (NULL != ax->skipped_head)
1523 ax->skipped_head);
1524 GNUNET_assert (0 == ax->skipped);
1527}
1528
1529
1541static void
1543 const struct GNUNET_HashCode *key_result)
1544{
1545 struct CadetTunnelAsync *as;
1546 struct GNUNET_HashCode key_material[3];
1547 struct GNUNET_CRYPTO_AeadSecretKey keys[5];
1548 struct CadetTunnelAxolotl *ax;
1549 const struct GNUNET_PeerIdentity *pid;
1550 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key;
1551 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key;
1552 const char salt[] = "CADET Axolotl salt";
1553 int am_I_alice;
1554
1555 as = cls;
1556 ax = &as->ax;
1557 pid = &as->peer_id;
1558 ephemeral_key = &as->ephemeral_key;
1559 ratchet_key = &as->ratchet_key;
1560
1561 as->ecdh_op = NULL;
1562
1564 "Updating AX by KX with result from ECDH using ephemeral %s\n",
1565 GNUNET_e2s (ephemeral_key));
1566
1567 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1568 {
1569 GNUNET_break_op (0);
1570 if (as->cb)
1571 as->cb (as->cb_cls, GNUNET_SYSERR);
1572 return;
1573 }
1574
1575 if (0 == GNUNET_memcmp (&ax->DHRr,
1576 ratchet_key))
1577 {
1579 "# Ratchet key already known",
1580 1,
1581 GNUNET_NO);
1583 "Ratchet key already known. Ignoring KX.\n");
1584 if (as->cb)
1585 as->cb (as->cb_cls, GNUNET_NO);
1586 return;
1587 }
1588
1589 ax->DHRr = *ratchet_key;
1590 ax->last_ephemeral = *ephemeral_key;
1591 /* ECDH A B0 */
1592 if (GNUNET_YES == am_I_alice)
1593 {
1594 GNUNET_memcpy (&key_material[0], key_result,
1595 sizeof (*key_result));
1596 }
1597 else
1598 {
1599 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1600 &pid->public_key, /* A */
1601 &key_material[0]);
1602 }
1603 /* ECDH A0 B */
1604 if (GNUNET_YES == am_I_alice)
1605 {
1606 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1607 &pid->public_key, /* B */
1608 &key_material[1]);
1609 }
1610 else
1611 {
1612 GNUNET_memcpy (&key_material[1], key_result,
1613 sizeof (*key_result));
1614 }
1615
1616 /* ECDH A0 B0 */
1617 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1618 ephemeral_key, /* B0 or A0 */
1619 &key_material[2]);
1620 /* KDF */
1622 keys, sizeof(keys),
1623 salt, sizeof(salt),
1624 &key_material, sizeof(key_material));
1625
1626 if (0 == memcmp (&ax->RK,
1627 &keys[0],
1628 sizeof(ax->RK)))
1629 {
1631 "Root key already known. Ignoring KX.\n");
1633 "# Root key already known",
1634 1,
1635 GNUNET_NO);
1636 if (as->cb)
1637 as->cb (as->cb_cls, GNUNET_NO);
1638 return;
1639 }
1640
1641 ax->RK = keys[0];
1642 if (GNUNET_YES == am_I_alice)
1643 {
1644 ax->HKr = keys[1];
1645 ax->NHKs = keys[2];
1646 ax->NHKr = keys[3];
1647 ax->CKr = keys[4];
1649 }
1650 else
1651 {
1652 ax->HKs = keys[1];
1653 ax->NHKr = keys[2];
1654 ax->NHKs = keys[3];
1655 ax->CKs = keys[4];
1656 ax->ratchet_flag = GNUNET_NO;
1659 ratchet_time);
1660 }
1661
1662 if (as->cb)
1663 as->cb (as->cb_cls, GNUNET_OK);
1664}
1665
1666
1672static void
1673retry_kx (void *cls)
1674{
1675 struct CadetTunnel *t = cls;
1676 struct CadetTunnelAxolotl *ax;
1677
1678 t->kx_task = NULL;
1680 "Trying to make KX progress on %s in state %s\n",
1681 GCT_2s (t),
1682 estate2s (t->estate));
1683 switch (t->estate)
1684 {
1685 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1686 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1687 send_kx (t,
1688 NULL,
1689 &t->ax);
1690 break;
1691
1694 /* We are responding, so only require reply
1695 if WE have a channel waiting. */
1696 if (NULL != t->unverified_ax)
1697 {
1698 /* Send AX_AUTH so we might get this one verified */
1699 ax = t->unverified_ax;
1700 }
1701 else
1702 {
1703 /* How can this be? */
1704 GNUNET_break (0);
1705 ax = &t->ax;
1706 }
1707 send_kx_auth (t,
1708 NULL,
1709 ax,
1710 (0 == GCT_count_channels (t))
1711 ? GNUNET_NO
1712 : GNUNET_YES);
1713 break;
1714
1716 /* We are responding, so only require reply
1717 if WE have a channel waiting. */
1718 if (NULL != t->unverified_ax)
1719 {
1720 /* Send AX_AUTH so we might get this one verified */
1721 ax = t->unverified_ax;
1722 }
1723 else
1724 {
1725 /* How can this be? */
1726 GNUNET_break (0);
1727 ax = &t->ax;
1728 }
1729 send_kx_auth (t,
1730 NULL,
1731 ax,
1732 (0 == GCT_count_channels (t))
1733 ? GNUNET_NO
1734 : GNUNET_YES);
1735 break;
1736
1738 /* Must have been the *other* peer asking us to
1739 respond with a KX_AUTH. */
1740 if (NULL != t->unverified_ax)
1741 {
1742 /* Sending AX_AUTH in response to AX so we might get this one verified */
1743 ax = t->unverified_ax;
1744 }
1745 else
1746 {
1747 /* Sending AX_AUTH in response to AX_AUTH */
1748 ax = &t->ax;
1749 }
1750 send_kx_auth (t,
1751 NULL,
1752 ax,
1753 GNUNET_NO);
1754 break;
1755 }
1756}
1757
1758
1765static void
1768{
1769 struct CadetTunnel *t = cls;
1770
1771 if (t->unverified_ax)
1772 *(t->unverified_ax) = t->as.ax;
1773
1775 "Continue handling KX message from %s from %s\n",
1776 GCT_2s (t),
1777 GNUNET_i2s (GCP_get_id (t->destination)));
1778
1780 if (GNUNET_OK != ret)
1781 {
1783 "# Useless KX",
1784 1,
1785 GNUNET_NO);
1786 return; /* duplicate KX, nothing to do */
1787 }
1788 /* move ahead in our state machine */
1789 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1792 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1795
1796 /* KX is still not done, try again our end. */
1797 if (CADET_TUNNEL_KEY_OK != t->estate)
1798 {
1799 if (NULL != t->kx_task)
1800 GNUNET_SCHEDULER_cancel (t->kx_task);
1801 t->kx_task
1803 t);
1804 }
1805}
1806
1807
1814void
1817{
1818 struct CadetTunnel *t = ct->t;
1819
1821 "# KX received",
1822 1,
1823 GNUNET_NO);
1824 if (GNUNET_YES ==
1825 GCT_alice_or_betty (GCP_get_id (t->destination)))
1826 {
1827 /* Betty/Bob is not allowed to send KX! */
1828 GNUNET_break_op (0);
1829 return;
1830 }
1832 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1833 GCT_2s (t),
1834 GNUNET_e2s (&msg->ephemeral_key),
1835 GNUNET_i2s (GCP_get_id (t->destination)),
1836 GCC_2s (ct->cc));
1837#if 1
1838 if ((0 ==
1839 memcmp (&t->ax.DHRr,
1840 &msg->ratchet_key,
1841 sizeof(msg->ratchet_key))) &&
1842 (0 ==
1843 memcmp (&t->ax.last_ephemeral,
1844 &msg->ephemeral_key,
1845 sizeof(msg->ephemeral_key))))
1846
1847 {
1849 "# Duplicate KX received",
1850 1,
1851 GNUNET_NO);
1852 send_kx_auth (t,
1853 ct,
1854 &t->ax,
1855 GNUNET_NO);
1856 return;
1857 }
1858#endif
1859 /* We only keep ONE unverified KX around, so if there is an existing one,
1860 clean it up. */
1861 if (NULL != t->unverified_ax)
1862 {
1863 if ((0 ==
1864 memcmp (&t->unverified_ax->DHRr,
1865 &msg->ratchet_key,
1866 sizeof(msg->ratchet_key))) &&
1867 (0 ==
1868 memcmp (&t->unverified_ax->last_ephemeral,
1869 &msg->ephemeral_key,
1870 sizeof(msg->ephemeral_key))))
1871 {
1873 "# Duplicate unverified KX received",
1874 1,
1875 GNUNET_NO);
1876#if 1
1877 send_kx_auth (t,
1878 ct,
1879 t->unverified_ax,
1880 GNUNET_NO);
1881 return;
1882#endif
1883 }
1884 if ((t->as.ecdh_op) &&
1885 (0 ==
1886 memcmp (&t->as.ratchet_key,
1887 &msg->ratchet_key,
1888 sizeof(msg->ratchet_key))) &&
1889 (0 ==
1890 memcmp (&t->as.ephemeral_key,
1891 &msg->ephemeral_key,
1892 sizeof(msg->ephemeral_key))))
1893 {
1895 "Waiting for previous ECDH operation\n");
1896 return;
1897 }
1899 "Dropping old unverified KX state.\n");
1901 "# Unverified KX dropped for fresh KX",
1902 1,
1903 GNUNET_NO);
1904 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1905 memset (t->unverified_ax,
1906 0,
1907 sizeof(struct CadetTunnelAxolotl));
1908 }
1909 else
1910 {
1912 "Creating fresh unverified KX for %s\n",
1913 GCT_2s (t));
1915 "# Fresh KX setup",
1916 1,
1917 GNUNET_NO);
1918 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1919 }
1920 /* Set as the 'current' RK/DHRr the one we are currently using,
1921 so that the duplicate-detection logic of
1922 #update_ax_by_kx can work. */
1923 t->unverified_ax->RK = t->ax.RK;
1924 t->unverified_ax->DHRr = t->ax.DHRr;
1925 t->unverified_ax->DHRs = t->ax.DHRs;
1926 t->unverified_ax->kx_0 = t->ax.kx_0;
1927 t->unverified_attempts = 0;
1928
1929 t->as.ax = *(t->unverified_ax);
1930 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
1931 sizeof (t->as.peer_id));
1932 GNUNET_memcpy (&t->as.ephemeral_key, &msg->ephemeral_key,
1933 sizeof (t->as.ephemeral_key));
1934 GNUNET_memcpy (&t->as.ratchet_key, &msg->ratchet_key,
1935 sizeof (t->as.ratchet_key));
1936 memset (&t->as.auth, 0, sizeof (t->as.auth));
1937 t->as.flags = 0;
1938 t->as.cb_cls = t;
1939 t->as.cb = &cont_GCT_handle_kx;
1940
1941 if (t->as.ecdh_op)
1942 {
1944 "Cancelling previous ECDH operation\n");
1945
1946 GNUNET_PILS_cancel (t->as.ecdh_op);
1947 }
1948
1949 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->ephemeral_key,
1950 &update_ax_by_kx, &t->as);
1951}
1952
1953
1960static void
1963{
1964 struct CadetTunnel *t = cls;
1965 struct CadetTunnelAxolotl *ax_tmp;
1966 struct GNUNET_HashCode kx_auth;
1967
1968 ax_tmp = &t->as.ax;
1969
1971 "Continue handling KX_AUTH message from %s\n",
1972 GCT_2s (t));
1973
1974 if (GNUNET_OK != ret)
1975 {
1976 if (GNUNET_NO == ret)
1978 "# redundant KX_AUTH received",
1979 1,
1980 GNUNET_NO);
1981 else
1982 GNUNET_break (0); /* connect to self!? */
1983 return;
1984 }
1985 GNUNET_CRYPTO_hash (&ax_tmp->RK,
1986 sizeof(ax_tmp->RK),
1987 &kx_auth);
1988 if (0 != GNUNET_memcmp (&kx_auth,
1989 &t->as.auth))
1990 {
1991 /* This KX_AUTH is not using the latest KX/KX_AUTH data
1992 we transmitted to the sender, refuse it, try KX again. */
1994 "# KX_AUTH not using our last KX received (auth failure)",
1995 1,
1996 GNUNET_NO);
1998 "KX AUTH mismatch!\n");
1999#if DEBUG_KX
2000 {
2001 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
2002
2004 &ephemeral_key);
2005 if (0 != GNUNET_memcmp (&ephemeral_key,
2006 &msg->r_ephemeral_key_XXX))
2007 {
2009 "My ephemeral is %s!\n",
2010 GNUNET_e2s (&ephemeral_key));
2012 "Response is for ephemeral %s!\n",
2013 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2014 }
2015 }
2016#endif
2017 if (NULL == t->kx_task)
2018 t->kx_task
2019 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2020 &retry_kx,
2021 t);
2022 return;
2023 }
2024 /* Yep, we're good. */
2025 t->ax = *ax_tmp;
2026 if (NULL != t->unverified_ax)
2027 {
2028 /* We got some "stale" KX before, drop that. */
2029 cleanup_ax (t->unverified_ax);
2030 GNUNET_free (t->unverified_ax);
2031 t->unverified_ax = NULL;
2032 }
2033
2034 /* move ahead in our state machine */
2035 switch (t->estate)
2036 {
2039 /* Checked above, this is impossible. */
2040 GNUNET_assert (0);
2041 break;
2042
2043 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2044 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2045 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2048 break;
2049
2051 /* Did not expect another KX_AUTH, but so what, still acceptable.
2052 Nothing to do here. */
2053 break;
2054 }
2055 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (t->as.flags)))
2056 {
2057 send_kx_auth (t,
2058 NULL,
2059 &t->ax,
2060 GNUNET_NO);
2061 }
2062}
2063
2064
2071void
2074{
2075 struct CadetTunnel *t = ct->t;
2076
2078 "# KX_AUTH received",
2079 1,
2080 GNUNET_NO);
2081 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
2082 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
2083 {
2084 /* Confusing, we got a KX_AUTH before we even send our own
2085 KX. This should not happen. We'll send our own KX ASAP anyway,
2086 so let's ignore this here. */
2087 GNUNET_break_op (0);
2088 return;
2089 }
2091 "Handling KX_AUTH message from %s with ephemeral %s\n",
2092 GCT_2s (t),
2093 GNUNET_e2s (&msg->kx.ephemeral_key));
2094 if ((t->as.ecdh_op) &&
2095 (0 ==
2096 memcmp (&t->as.ratchet_key,
2097 &msg->kx.ratchet_key,
2098 sizeof(msg->kx.ratchet_key))) &&
2099 (0 ==
2100 memcmp (&t->as.ephemeral_key,
2101 &msg->kx.ephemeral_key,
2102 sizeof(msg->kx.ephemeral_key))))
2103 {
2105 "Waiting for previous ECDH operation\n");
2106 return;
2107 }
2108 /* We do everything in a copy until we've checked the authentication
2109 so we don't clobber anything we care about by accident. */
2110 t->as.ax = t->ax;
2111 GNUNET_memcpy (&t->as.peer_id, GCP_get_id (t->destination),
2112 sizeof (t->as.peer_id));
2113 GNUNET_memcpy (&t->as.ephemeral_key, &msg->kx.ephemeral_key,
2114 sizeof (t->as.ephemeral_key));
2115 GNUNET_memcpy (&t->as.ratchet_key, &msg->kx.ratchet_key,
2116 sizeof (t->as.ratchet_key));
2117 t->as.auth = msg->auth;
2118 t->as.flags = msg->kx.flags;
2119 t->as.cb_cls = t;
2120 t->as.cb = &cont_GCT_handle_kx_auth;
2121
2122 if (t->as.ecdh_op)
2123 {
2125 "Cancelling previous ECDH operation\n");
2126
2127 GNUNET_PILS_cancel (t->as.ecdh_op);
2128 }
2129
2130 /* Update 'ax' by the new key material */
2131 t->as.ecdh_op = GNUNET_PILS_ecdh (pils, &msg->kx.ephemeral_key,
2132 &update_ax_by_kx, &t->as);
2133}
2134
2135
2136/* ************************************** end core crypto ***************************** */
2137
2138
2147{
2148#define HIGH_BIT 0x08000000
2149 const struct GNUNET_PeerIdentity *my_identity;
2151 uint32_t ctn;
2152 int cmp;
2153 uint32_t highbit;
2154
2157
2160 if (0 < cmp)
2161 highbit = HIGH_BIT;
2162 else if (0 > cmp)
2163 highbit = 0;
2164 else
2165 GNUNET_assert (0); // loopback must never go here!
2166 ctn = ntohl (t->next_ctn.cn);
2167 while (NULL !=
2169 ctn | highbit))
2170 {
2171 ctn = ((ctn + 1) & (~HIGH_BIT));
2172 }
2173 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2174 ret.cn = htonl (ctn | highbit);
2175 return ret;
2176}
2177
2178
2190 struct CadetChannel *ch)
2191{
2193
2194 ctn = get_next_free_ctn (t);
2195 if (NULL != t->destroy_task)
2196 {
2197 GNUNET_SCHEDULER_cancel (t->destroy_task);
2198 t->destroy_task = NULL;
2199 }
2202 ntohl (ctn.cn),
2203 ch,
2206 "Adding %s to %s with state %d\n",
2207 GCCH_2s (ch),
2208 GCT_2s (t),
2209 t->estate);
2210 switch (t->estate)
2211 {
2213 /* waiting for connection to start KX */
2214 break;
2215
2219 /* we're currently waiting for KX to complete */
2220 break;
2221
2223 /* waiting for OTHER peer to send us data,
2224 we might need to prompt more aggressively! */
2225 if (NULL == t->kx_task)
2226 t->kx_task
2227 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2228 &retry_kx,
2229 t);
2230 break;
2231
2233 /* We are ready. Tell the new channel that we are up. */
2235 break;
2236 }
2237 return ctn;
2238}
2239
2240
2247void
2249{
2250 struct CadetTunnel *t = ct->t;
2251
2252 if (GNUNET_YES == ct->is_ready)
2253 {
2254 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2255 t->connection_ready_tail,
2256 ct);
2257 t->num_ready_connections--;
2258 }
2259 else
2260 {
2261 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2262 t->connection_busy_tail,
2263 ct);
2264 t->num_busy_connections--;
2265 }
2266 GNUNET_free (ct);
2267}
2268
2269
2276static void
2278 struct CadetTConnection *ct)
2279{
2280 struct CadetTunnel *t = cls;
2281 struct CadetConnection *cc = ct->cc;
2282
2283 GNUNET_assert (ct->t == t);
2286}
2287
2288
2294static void
2296{
2297 struct CadetTunnel *t = cls;
2298 struct CadetTunnelQueueEntry *tq;
2299
2300 t->destroy_task = NULL;
2302 "Destroying idle %s\n",
2303 GCT_2s (t));
2307 t);
2308 GNUNET_assert (NULL == t->connection_ready_head);
2309 GNUNET_assert (NULL == t->connection_busy_head);
2310 while (NULL != (tq = t->tq_head))
2311 {
2312 if (NULL != tq->cont)
2313 tq->cont (tq->cont_cls,
2314 NULL);
2315 GCT_send_cancel (tq);
2316 }
2317 GCP_drop_tunnel (t->destination,
2318 t);
2320 if (NULL != t->maintain_connections_task)
2321 {
2322 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2323 t->maintain_connections_task = NULL;
2324 }
2325 if (NULL != t->send_task)
2326 {
2327 GNUNET_SCHEDULER_cancel (t->send_task);
2328 t->send_task = NULL;
2329 }
2330 if (NULL != t->kx_task)
2331 {
2332 GNUNET_SCHEDULER_cancel (t->kx_task);
2333 t->kx_task = NULL;
2334 }
2335 if (NULL != t->as.ecdh_op)
2336 {
2337 GNUNET_PILS_cancel (t->as.ecdh_op);
2338 t->as.ecdh_op = NULL;
2339 }
2340 GNUNET_MST_destroy (t->mst);
2341 GNUNET_MQ_destroy (t->mq);
2342 if (NULL != t->unverified_ax)
2343 {
2344 cleanup_ax (t->unverified_ax);
2345 GNUNET_free (t->unverified_ax);
2346 }
2347 cleanup_ax (&t->ax);
2348 GNUNET_assert (NULL == t->destroy_task);
2349 GNUNET_free (t);
2350}
2351
2352
2360void
2362 struct CadetChannel *ch,
2364{
2366 "Removing %s from %s\n",
2367 GCCH_2s (ch),
2368 GCT_2s (t));
2371 ntohl (ctn.cn),
2372 ch));
2373 if ((0 ==
2374 GCT_count_channels (t)) &&
2375 (NULL == t->destroy_task))
2376 {
2377 t->destroy_task
2380 t);
2381 }
2382}
2383
2384
2393static int
2395 uint32_t key,
2396 void *value)
2397{
2398 struct CadetChannel *ch = value;
2399
2401 NULL);
2402 return GNUNET_OK;
2403}
2404
2405
2411void
2413{
2417 t);
2418 GNUNET_assert (0 ==
2420 if (NULL != t->destroy_task)
2421 {
2422 GNUNET_SCHEDULER_cancel (t->destroy_task);
2423 t->destroy_task = NULL;
2424 }
2425 destroy_tunnel (t);
2426}
2427
2428
2436static void
2438 struct CadetTConnection *ct)
2439{
2440 struct CadetTunnelQueueEntry *tq;
2441
2443 tq = t->tq_head;
2444 if (NULL == tq)
2445 {
2446 /* no messages pending right now */
2448 "Not sending payload of %s on ready %s (nothing pending)\n",
2449 GCT_2s (t),
2450 GCC_2s (ct->cc));
2451 return;
2452 }
2453 /* ready to send message 'tq' on tunnel 'ct' */
2454 GNUNET_assert (t == tq->t);
2456 t->tq_tail,
2457 tq);
2458 if (NULL != tq->cid)
2459 *tq->cid = *GCC_get_id (ct->cc);
2462 "Sending payload of %s on %s\n",
2463 GCT_2s (t),
2464 GCC_2s (ct->cc));
2465 GCC_transmit (ct->cc,
2466 tq->env);
2467 if (NULL != tq->cont)
2468 tq->cont (tq->cont_cls,
2469 GCC_get_id (ct->cc));
2470 GNUNET_free (tq);
2471}
2472
2473
2482static void
2484 int is_ready)
2485{
2486 struct CadetTConnection *ct = cls;
2487 struct CadetTunnel *t = ct->t;
2488
2489 if (GNUNET_NO == is_ready)
2490 {
2492 "%s no longer ready for %s\n",
2493 GCC_2s (ct->cc),
2494 GCT_2s (t));
2496 return;
2497 }
2499 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2500 t->connection_busy_tail,
2501 ct);
2502 GNUNET_assert (0 < t->num_busy_connections);
2503 t->num_busy_connections--;
2504 ct->is_ready = GNUNET_YES;
2505 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2506 t->connection_ready_tail,
2507 ct);
2508 t->num_ready_connections++;
2509
2511 "%s now ready for %s in state %s\n",
2512 GCC_2s (ct->cc),
2513 GCT_2s (t),
2514 estate2s (t->estate));
2515 switch (t->estate)
2516 {
2519 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2520 GCT_2s (t),
2521 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2522 t->next_kx_attempt).rel_value_us);
2523 /* Do not begin KX if WE have no channels waiting! */
2525 t->next_kx_attempt).rel_value_us)
2526 return; /* wait for timeout before retrying */
2527 /* We are uninitialized, just transmit immediately,
2528 without undue delay. */
2529
2531 "Why for %s \n",
2532 GCT_2s (t));
2533
2534 if (NULL != t->kx_task)
2535 {
2536 GNUNET_SCHEDULER_cancel (t->kx_task);
2537 t->kx_task = NULL;
2538 }
2539 send_kx (t,
2540 ct,
2541 &t->ax);
2542 if ((0 ==
2543 GCT_count_channels (t)) &&
2544 (NULL == t->destroy_task))
2545 {
2546 t->destroy_task
2549 t);
2550 }
2551 break;
2552
2557 /* we're currently waiting for KX to complete, schedule job */
2558 if (NULL == t->kx_task)
2559 t->kx_task
2560 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2561 &retry_kx,
2562 t);
2563 break;
2564
2566 if (GNUNET_YES == t->kx_auth_requested)
2567 {
2569 t->next_kx_attempt).rel_value_us)
2570 return; /* wait for timeout */
2571 if (NULL != t->kx_task)
2572 {
2573 GNUNET_SCHEDULER_cancel (t->kx_task);
2574 t->kx_task = NULL;
2575 }
2576 send_kx_auth (t,
2577 ct,
2578 &t->ax,
2579 GNUNET_NO);
2580 return;
2581 }
2583 ct);
2584 break;
2585 }
2586}
2587
2588
2597static void
2599{
2600 struct CadetTunnel *t = cls;
2601 struct CadetTConnection *ct;
2602
2603 t->send_task = NULL;
2604 if (NULL == t->tq_head)
2605 return; /* no messages pending right now */
2606 ct = get_ready_connection (t);
2607 if (NULL == ct)
2608 return; /* no connections ready */
2610 ct);
2611}
2612
2613
2661
2662
2670static void
2672 struct CadetTConnection *ct)
2673{
2674 struct EvaluationSummary *es = cls;
2675 struct CadetConnection *cc = ct->cc;
2676 unsigned int ct_length;
2677 struct CadetPeerPath *ps;
2678 const struct CadetConnectionMetrics *metrics;
2679 GNUNET_CONTAINER_HeapCostType ct_desirability;
2680 struct GNUNET_TIME_Relative uptime;
2681 struct GNUNET_TIME_Relative last_use;
2682 double score;
2683 double success_rate;
2684
2685 ps = GCC_get_path (cc,
2686 &ct_length);
2688 "Evaluating path %s of existing %s\n",
2689 GCPP_2s (ps),
2690 GCC_2s (cc));
2691 if (ps == es->path)
2692 {
2694 "Ignoring duplicate path %s.\n",
2695 GCPP_2s (es->path));
2696 es->duplicate = GNUNET_YES;
2697 return;
2698 }
2699 if (NULL != es->path)
2700 {
2701 int duplicate = GNUNET_YES;
2702
2703 for (unsigned int i = 0; i < ct_length; i++)
2704 {
2707 i) !=
2709 i))
2710 {
2711 duplicate = GNUNET_NO;
2712 break;
2713 }
2714 }
2715 if (GNUNET_YES == duplicate)
2716 {
2718 "Ignoring overlapping path %s.\n",
2719 GCPP_2s (es->path));
2720 es->duplicate = GNUNET_YES;
2721 return;
2722 }
2723 else
2724 {
2726 "Known path %s differs from proposed path\n",
2727 GCPP_2s (ps));
2728 }
2729 }
2730
2731 ct_desirability = GCPP_get_desirability (ps);
2732 metrics = GCC_get_metrics (cc);
2733 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2734 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2735 /* We add 1.0 here to avoid division by zero. */
2736 success_rate = (metrics->num_acked_transmissions + 1.0)
2737 / (metrics->num_successes + 1.0);
2738 score
2739 = ct_desirability
2740 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2741 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2742 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2743 score *= success_rate; /* weigh overall by success rate */
2744
2745 if ((NULL == es->worst) ||
2746 (score < es->worst_score))
2747 {
2748 es->worst = ct;
2749 es->worst_score = score;
2750 }
2751 es->min_length = GNUNET_MIN (es->min_length,
2752 ct_length);
2753 es->max_length = GNUNET_MAX (es->max_length,
2754 ct_length);
2755 es->min_desire = GNUNET_MIN (es->min_desire,
2756 ct_desirability);
2757 es->max_desire = GNUNET_MAX (es->max_desire,
2758 ct_desirability);
2759}
2760
2761
2771static int
2773 struct CadetPeerPath *path,
2774 unsigned int off)
2775{
2776 struct CadetTunnel *t = cls;
2777 struct EvaluationSummary es;
2778 struct CadetTConnection *ct;
2779
2780 GNUNET_assert (off < GCPP_get_length (path));
2782 off) == t->destination);
2783 es.min_length = UINT_MAX;
2784 es.max_length = 0;
2785 es.max_desire = 0;
2786 es.min_desire = UINT64_MAX;
2787 es.path = path;
2788 es.duplicate = GNUNET_NO;
2789 es.worst = NULL;
2790
2791 /* Compute evaluation summary over existing connections. */
2793 "Evaluating proposed path %s for target %s\n",
2794 GCPP_2s (path),
2795 GCT_2s (t));
2796 /* FIXME: suspect this does not ACTUALLY iterate
2797 over all existing paths, otherwise dup detection
2798 should work!!! */
2801 &es);
2802 if (GNUNET_YES == es.duplicate)
2803 return GNUNET_YES;
2804
2805 /* FIXME: not sure we should really just count
2806 'num_connections' here, as they may all have
2807 consistently failed to connect. */
2808
2809 /* We iterate by increasing path length; if we have enough paths and
2810 this one is more than twice as long than what we are currently
2811 using, then ignore all of these super-long ones! */
2813 (es.min_length * 2 < off) &&
2814 (es.max_length < off))
2815 {
2817 "Ignoring paths of length %u, they are way too long.\n",
2818 es.min_length * 2);
2819 return GNUNET_NO;
2820 }
2821 /* If we have enough paths and this one looks no better, ignore it. */
2823 (es.min_length < GCPP_get_length (path)) &&
2824 (es.min_desire > GCPP_get_desirability (path)) &&
2825 (es.max_length < off))
2826 {
2828 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2829 GCPP_get_length (path),
2830 (unsigned long long) GCPP_get_desirability (path),
2831 GCP_2s (t->destination));
2832 return GNUNET_YES;
2833 }
2834
2835 /* Path is interesting (better by some metric, or we don't have
2836 enough paths yet). */
2837 ct = GNUNET_new (struct CadetTConnection);
2839 ct->t = t;
2840 ct->cc = GCC_create (t->destination,
2841 path,
2842 off,
2843 ct,
2845 ct);
2846
2847 /* FIXME: schedule job to kill connection (and path?) if it takes
2848 too long to get ready! (And track performance data on how long
2849 other connections took with the tunnel!)
2850 => Note: to be done within 'connection'-logic! */
2851 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2852 t->connection_busy_tail,
2853 ct);
2854 t->num_busy_connections++;
2856 "Found interesting path %s for %s, created %s\n",
2857 GCPP_2s (path),
2858 GCT_2s (t),
2859 GCC_2s (ct->cc));
2860 return GNUNET_YES;
2861}
2862
2863
2877static void
2879{
2880 struct CadetTunnel *t = cls;
2881 struct GNUNET_TIME_Relative delay;
2882 struct EvaluationSummary es;
2883
2884 t->maintain_connections_task = NULL;
2886 "Performing connection maintenance for %s.\n",
2887 GCT_2s (t));
2888
2889 es.min_length = UINT_MAX;
2890 es.max_length = 0;
2891 es.max_desire = 0;
2892 es.min_desire = UINT64_MAX;
2893 es.path = NULL;
2894 es.worst = NULL;
2895 es.duplicate = GNUNET_NO;
2898 &es);
2899 if ((NULL != es.worst) &&
2901 {
2902 /* Clear out worst-performing connection 'es.worst'. */
2904 es.worst);
2905 }
2906
2907 /* Consider additional paths */
2908 (void) GCP_iterate_paths (t->destination,
2910 t);
2911
2912 /* FIXME: calculate when to try again based on how well we are doing;
2913 in particular, if we have to few connections, we might be able
2914 to do without this (as PATHS should tell us whenever a new path
2915 is available instantly; however, need to make sure this job is
2916 restarted after that happens).
2917 Furthermore, if the paths we do know are in a reasonably narrow
2918 quality band and are plentyful, we might also consider us stabilized
2919 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2920 t->maintain_connections_task
2923 t);
2924}
2925
2926
2927void
2929 struct CadetPeerPath *p,
2930 unsigned int off)
2931{
2933 "Considering %s for %s (offset %u)\n",
2934 GCPP_2s (p),
2935 GCT_2s (t),
2936 off);
2937 (void) consider_path_cb (t,
2938 p,
2939 off);
2940}
2941
2942
2949static void
2951 const struct GNUNET_MessageHeader *msg)
2952{
2953 struct CadetTunnel *t = cls;
2954
2956 "Received KEEPALIVE on %s\n",
2957 GCT_2s (t));
2959 "# keepalives received",
2960 1,
2961 GNUNET_NO);
2962}
2963
2964
2972static int
2975{
2976 return GNUNET_OK;
2977}
2978
2979
2987static void
2990{
2991 struct CadetTunnel *t = cls;
2992 struct CadetChannel *ch;
2993
2994 ch = lookup_channel (t,
2995 msg->ctn);
2996 if (NULL == ch)
2997 {
2998 /* We don't know about such a channel, might have been destroyed on our
2999 end in the meantime, or never existed. Send back a DESTROY. */
3001 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
3002 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
3003 ntohl (msg->ctn.cn));
3005 msg->ctn);
3006 return;
3007 }
3009 GCC_get_id (t->current_ct->cc),
3010 msg);
3011}
3012
3013
3022static void
3024 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
3025{
3026 struct CadetTunnel *t = cls;
3027 struct CadetChannel *ch;
3028
3029 ch = lookup_channel (t,
3030 ack->ctn);
3031 if (NULL == ch)
3032 {
3033 /* We don't know about such a channel, might have been destroyed on our
3034 end in the meantime, or never existed. Send back a DESTROY. */
3036 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
3037 ntohl (ack->ctn.cn));
3039 ack->ctn);
3040 return;
3041 }
3043 GCC_get_id (t->current_ct->cc),
3044 ack);
3045}
3046
3047
3055static void
3057 const struct
3059{
3060 struct CadetTunnel *t = cls;
3061 struct CadetChannel *ch;
3062
3064 ntohl (copen->ctn.cn));
3065 if (NULL != ch)
3066 {
3068 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
3069 GNUNET_h2s (&copen->h_port),
3070 GCT_2s (t),
3071 GCCH_2s (ch));
3073 GCC_get_id (t->current_ct->cc));
3074 return;
3075 }
3077 "Received CHANNEL_OPEN on h_port %s from %s\n",
3078 GNUNET_h2s (&copen->h_port),
3079 GCT_2s (t));
3081 copen->ctn,
3082 &copen->h_port,
3083 ntohl (copen->opt));
3084 if (NULL != t->destroy_task)
3085 {
3086 GNUNET_SCHEDULER_cancel (t->destroy_task);
3087 t->destroy_task = NULL;
3088 }
3091 ntohl (copen->ctn.cn),
3092 ch,
3094}
3095
3096
3103void
3106{
3108
3110 "Sending DESTROY message for channel ID %u\n",
3111 ntohl (ctn.cn));
3112 msg.header.size = htons (sizeof(msg));
3114 msg.reserved = htonl (0);
3115 msg.ctn = ctn;
3116 GCT_send (t,
3117 &msg.header,
3118 NULL,
3119 NULL,
3120 &ctn);
3121}
3122
3123
3132static void
3134 const struct
3136{
3137 struct CadetTunnel *t = cls;
3138 struct CadetChannel *ch;
3139
3140 ch = lookup_channel (t,
3141 cm->ctn);
3142 if (NULL == ch)
3143 {
3144 /* We don't know about such a channel, might have been destroyed on our
3145 end in the meantime, or never existed. Send back a DESTROY. */
3147 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3148 ntohl (cm->ctn.cn));
3150 cm->ctn);
3151 return;
3152 }
3154 "Received channel OPEN_ACK on channel %s from %s\n",
3155 GCCH_2s (ch),
3156 GCT_2s (t));
3158 GCC_get_id (t->current_ct->cc),
3159 &cm->port);
3160}
3161
3162
3170static void
3172 const struct
3174{
3175 struct CadetTunnel *t = cls;
3176 struct CadetChannel *ch;
3177
3178 ch = lookup_channel (t,
3179 cm->ctn);
3180 if (NULL == ch)
3181 {
3182 /* We don't know about such a channel, might have been destroyed on our
3183 end in the meantime, or never existed. */
3185 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3186 ntohl (cm->ctn.cn));
3187 return;
3188 }
3190 "Received channel DESTROY on %s from %s\n",
3191 GCCH_2s (ch),
3192 GCT_2s (t));
3194 GCC_get_id (t->current_ct->cc));
3195}
3196
3197
3208static int
3210 const struct GNUNET_MessageHeader *msg)
3211{
3212 struct CadetTunnel *t = cls;
3213
3214 GNUNET_assert (NULL != t->current_ct);
3216 msg);
3217 return GNUNET_OK;
3218}
3219
3220
3228static void
3230 enum GNUNET_MQ_Error error)
3231{
3232 GNUNET_break_op (0);
3233}
3234
3235
3243struct CadetTunnel *
3245{
3246 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3248 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3250 struct GNUNET_MessageHeader,
3251 t),
3252 GNUNET_MQ_hd_var_size (plaintext_data,
3255 t),
3256 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3259 t),
3260 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3263 t),
3264 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3267 t),
3268 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3271 t),
3273 };
3274
3275 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3276 new_ephemeral (&t->ax);
3278 t->destination = destination;
3280 t->maintain_connections_task
3282 t);
3283 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3284 NULL,
3285 NULL,
3286 NULL,
3287 handlers,
3289 t);
3291 t);
3292 return t;
3293}
3294
3295
3296int
3298 const struct
3300 struct CadetPeerPath *path)
3301{
3302 struct CadetTConnection *ct;
3303
3304 ct = GNUNET_new (struct CadetTConnection);
3306 ct->t = t;
3307 ct->cc = GCC_create_inbound (t->destination,
3308 path,
3309 ct,
3310 cid,
3312 ct);
3313 if (NULL == ct->cc)
3314 {
3316 "%s refused inbound %s (duplicate)\n",
3317 GCT_2s (t),
3318 GCC_2s (ct->cc));
3319 GNUNET_free (ct);
3320 return GNUNET_SYSERR;
3321 }
3322 /* FIXME: schedule job to kill connection (and path?) if it takes
3323 too long to get ready! (And track performance data on how long
3324 other connections took with the tunnel!)
3325 => Note: to be done within 'connection'-logic! */
3326 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3327 t->connection_busy_tail,
3328 ct);
3329 t->num_busy_connections++;
3331 "%s has new %s\n",
3332 GCT_2s (t),
3333 GCC_2s (ct->cc));
3334 return GNUNET_OK;
3335}
3336
3337
3344void
3347{
3348 struct CadetTunnel *t = ct->t;
3349 uint16_t size = ntohs (msg->header.size);
3350 char cbuf[size] GNUNET_ALIGN;
3351 ssize_t decrypted_size;
3352
3354 "%s received %u bytes of encrypted data in state %d\n",
3355 GCT_2s (t),
3356 (unsigned int) size,
3357 t->estate);
3358
3359 switch (t->estate)
3360 {
3363 /* We did not even SEND our KX, how can the other peer
3364 send us encrypted data? Must have been that we went
3365 down and the other peer still things we are up.
3366 Let's send it KX back. */
3368 "# received encrypted without any KX",
3369 1,
3370 GNUNET_NO);
3371 if (NULL != t->kx_task)
3372 {
3373 GNUNET_SCHEDULER_cancel (t->kx_task);
3374 t->kx_task = NULL;
3375 }
3376 send_kx (t,
3377 ct,
3378 &t->ax);
3379 return;
3380
3382 /* We send KX, and other peer send KX to us at the same time.
3383 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3385 "# received encrypted without KX_AUTH",
3386 1,
3387 GNUNET_NO);
3388 if (NULL != t->kx_task)
3389 {
3390 GNUNET_SCHEDULER_cancel (t->kx_task);
3391 t->kx_task = NULL;
3392 }
3393 send_kx_auth (t,
3394 ct,
3395 &t->ax,
3396 GNUNET_YES);
3397 return;
3398
3400 /* We did not get the KX of the other peer, but that
3401 might have been lost. Send our KX again immediately. */
3403 "# received encrypted without KX",
3404 1,
3405 GNUNET_NO);
3406 if (NULL != t->kx_task)
3407 {
3408 GNUNET_SCHEDULER_cancel (t->kx_task);
3409 t->kx_task = NULL;
3410 }
3411 send_kx (t,
3412 ct,
3413 &t->ax);
3414 return;
3415
3417 /* Great, first payload, we might graduate to OK! */
3419 /* We are up and running, all good. */
3420 break;
3421 }
3422
3423 decrypted_size = -1;
3424 if (CADET_TUNNEL_KEY_OK == t->estate)
3425 {
3426 /* We have well-established key material available,
3427 try that. (This is the common case.) */
3428 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3429 cbuf,
3430 msg,
3431 size);
3432 }
3433
3434 if ((-1 == decrypted_size) &&
3435 (NULL != t->unverified_ax))
3436 {
3437 /* We have un-authenticated KX material available. We should try
3438 this as a back-up option, in case the sender crashed and
3439 switched keys. */
3440 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3441 cbuf,
3442 msg,
3443 size);
3444 if (-1 != decrypted_size)
3445 {
3446 /* It worked! Treat this as authentication of the AX data! */
3447 cleanup_ax (&t->ax);
3448 t->ax = *t->unverified_ax;
3449 GNUNET_free (t->unverified_ax);
3450 t->unverified_ax = NULL;
3451 }
3452 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3453 {
3454 /* First time it worked, move tunnel into production! */
3457 if (NULL != t->send_task)
3458 GNUNET_SCHEDULER_cancel (t->send_task);
3460 t);
3461 }
3462 }
3463 if (NULL != t->unverified_ax)
3464 {
3465 /* We had unverified KX material that was useless; so increment
3466 counter and eventually move to ignore it. Note that we even do
3467 this increment if we successfully decrypted with the old KX
3468 material and thus didn't even both with the new one. This is
3469 the ideal case, as a malicious injection of bogus KX data
3470 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3472 "Failed to decrypt message with unverified KX data %u times\n",
3473 t->unverified_attempts);
3474 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3475 {
3476 cleanup_ax (t->unverified_ax);
3477 GNUNET_free (t->unverified_ax);
3478 t->unverified_ax = NULL;
3479 }
3480 }
3481
3482 if (-1 == decrypted_size)
3483 {
3484 /* Decryption failed for good, complain. */
3486 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3487 GCT_2s (t));
3489 "# unable to decrypt",
3490 1,
3491 GNUNET_NO);
3492 if (NULL != t->kx_task)
3493 {
3494 GNUNET_SCHEDULER_cancel (t->kx_task);
3495 t->kx_task = NULL;
3496 }
3497 send_kx (t,
3498 ct,
3499 &t->ax);
3500 return;
3501 }
3503 "# decrypted bytes",
3504 decrypted_size,
3505 GNUNET_NO);
3506
3507 /* The MST will ultimately call #handle_decrypted() on each message. */
3508 t->current_ct = ct;
3511 cbuf,
3512 decrypted_size,
3513 GNUNET_YES,
3514 GNUNET_NO));
3515 t->current_ct = NULL;
3516}
3517
3518
3519struct CadetTunnelQueueEntry *
3521 const struct GNUNET_MessageHeader *message,
3523 void *cont_cls,
3525{
3526 struct CadetTunnelQueueEntry *tq;
3527 uint16_t message_size;
3528 uint16_t payload_size;
3529 struct GNUNET_MQ_Envelope *env;
3531 struct CadetChannel *ch;
3532
3533 if (NULL != ctn)
3534 {
3535 ch = lookup_channel (t,
3536 *ctn);
3537 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3538 {
3539 GNUNET_break (0);
3540 return NULL;
3541 }
3542 }
3543
3544 if (CADET_TUNNEL_KEY_OK != t->estate)
3545 {
3546 GNUNET_break (0);
3547 return NULL;
3548 }
3549 message_size = ntohs (message->size);
3550 payload_size = message_size + sizeof (struct GNUNET_CRYPTO_AeadMac);
3552 "Encrypting %u bytes for %s\n",
3553 (unsigned int) message_size,
3554 GCT_2s (t));
3555 env = GNUNET_MQ_msg_extra (ax_msg,
3556 payload_size,
3558 t_ax_encrypt (&t->ax,
3559 &ax_msg[1],
3560 message,
3561 message_size);
3563 "# encrypted bytes",
3564 payload_size,
3565 GNUNET_NO);
3566 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3567 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3568 /* FIXME: we should do this once, not once per message;
3569 this is a point multiplication, and DHRs does not
3570 change all the time. */
3572 &ax_msg->ax_header.DHRs);
3573 t_h_encrypt (&t->ax,
3574 ax_msg,
3575 payload_size,
3576 (unsigned char*) &ax_msg[1]);
3577
3578 tq = GNUNET_malloc (sizeof(*tq));
3579 tq->t = t;
3580 tq->env = env;
3581 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3582 tq->cont = cont;
3583 tq->cont_cls = cont_cls;
3585 t->tq_tail,
3586 tq);
3587 if (NULL != t->send_task)
3588 GNUNET_SCHEDULER_cancel (t->send_task);
3589 t->send_task
3591 t);
3592 return tq;
3593}
3594
3595
3596void
3598{
3599 struct CadetTunnel *t = tq->t;
3600
3602 t->tq_tail,
3603 tq);
3604 GNUNET_MQ_discard (tq->env);
3605 GNUNET_free (tq);
3606}
3607
3608
3616void
3619 void *iter_cls)
3620{
3621 struct CadetTConnection *n;
3622
3623 for (struct CadetTConnection *ct = t->connection_ready_head;
3624 NULL != ct;
3625 ct = n)
3626 {
3627 n = ct->next;
3628 iter (iter_cls,
3629 ct);
3630 }
3631 for (struct CadetTConnection *ct = t->connection_busy_head;
3632 NULL != ct;
3633 ct = n)
3634 {
3635 n = ct->next;
3636 iter (iter_cls,
3637 ct);
3638 }
3639}
3640
3641
3657
3658
3667static int
3669 uint32_t key,
3670 void *value)
3671{
3672 struct ChanIterCls *ctx = cls;
3673 struct CadetChannel *ch = value;
3674
3675 ctx->iter (ctx->iter_cls,
3676 ch);
3677 return GNUNET_OK;
3678}
3679
3680
3688void
3691 void *iter_cls)
3692{
3693 struct ChanIterCls ctx;
3694
3695 ctx.iter = iter;
3696 ctx.iter_cls = iter_cls;
3699 &ctx);
3700}
3701
3702
3711static int
3712debug_channel (void *cls,
3713 uint32_t key,
3714 void *value)
3715{
3716 const enum GNUNET_ErrorType *level = cls;
3717 struct CadetChannel *ch = value;
3718
3719 GCCH_debug (ch, *level);
3720 return GNUNET_OK;
3721}
3722
3723
3724#define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3725 __VA_ARGS__)
3726
3727
3734void
3735GCT_debug (const struct CadetTunnel *t,
3736 enum GNUNET_ErrorType level)
3737{
3738#if ! defined(GNUNET_CULL_LOGGING)
3739 struct CadetTConnection *iter_c;
3740 int do_log;
3741
3743 "cadet-tun",
3744 __FILE__, __FUNCTION__, __LINE__);
3745 if (0 == do_log)
3746 return;
3747
3748 LOG2 (level,
3749 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3750 GCT_2s (t),
3751 estate2s (t->estate),
3752 t->tq_len,
3754 LOG2 (level,
3755 "TTT channels:\n");
3758 &level);
3759 LOG2 (level,
3760 "TTT connections:\n");
3761 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3762 GCC_debug (iter_c->cc,
3763 level);
3764 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3765 GCC_debug (iter_c->cc,
3766 level);
3767
3768 LOG2 (level,
3769 "TTT TUNNEL END\n");
3770#endif
3771}
3772
3773
3774/* end of gnunet-service-cadet_tunnels.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
P2P messages used by CADET.
GNUNET_CADET_KX_Flags
Flags to be used in GNUNET_CADET_KX.
@ GNUNET_CADET_KX_FLAG_NONE
Should the peer reply with its KX details?
@ GNUNET_CADET_KX_FLAG_FORCE_REPLY
The peer should reply with its KX details?
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_CADET_Channel * ch
Channel handle.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * ctx
static GstElement * source
Appsrc instance into which we write data for the pipeline.
static struct GNUNET_SCHEDULER_Task * t
Main task.
static int state
The current state of the parser.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static struct GNUNET_PILS_Handle * pils
Handle to PILS.
Definition gnunet-pils.c:44
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calculations.
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
struct GNUNET_TIME_Relative ratchet_time
How long until we trigger a ratched advance due to time.
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 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.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the 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.
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...
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
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.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
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).
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
GNUnet CADET service with encryption.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
struct CadetConnection * GCC_create_inbound(struct CadetPeer *destination, struct CadetPeerPath *path, struct CadetTConnection *ct, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_destroy_without_tunnel(struct CadetConnection *cc)
Destroy a connection, called if the tunnel association with the connection was already broken,...
struct CadetConnection * GCC_create(struct CadetPeer *destination, struct CadetPeerPath *path, unsigned int off, struct CadetTConnection *ct, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_transmit(struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
Transmit message msg via connection cc.
void GCC_debug(struct CadetConnection *cc, enum GNUNET_ErrorType level)
Log connection info.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
const struct GNUNET_CADET_ConnectionTunnelIdentifier * GCC_get_id(struct CadetConnection *cc)
Obtain unique ID for the connection.
A connection is a live end-to-end messaging mechanism where the peers are identified by a path and kn...
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
unsigned int GCPP_get_length(struct CadetPeerPath *path)
Return the length of the path.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping the path.
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
void GCP_drop_tunnel(struct CadetPeer *cp, struct CadetTunnel *t)
The tunnel to the given peer no longer exists, remove it from our data structures,...
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
unsigned int GCP_iterate_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer.
Information we track per peer.
static void cleanup_ax(struct CadetTunnelAxolotl *ax)
Cleanup state used by ax.
void GCT_handle_kx(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
Continue to handle KX message.
static int consider_path_cb(void *cls, struct CadetPeerPath *path, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_remove_channel(struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Remove a channel from a tunnel.
static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn(struct CadetTunnel *t)
Compute the next free channel tunnel number for this tunnel.
static struct CadetChannel * lookup_channel(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Lookup a channel by its ctn.
static int notify_tunnel_up_cb(void *cls, uint32_t key, void *value)
Our tunnel became ready for the first time, notify channels that have been waiting.
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
void(* CadetTunnelAxolotlCallback)(void *cls, enum GNUNET_GenericReturnValue res)
Signature of the follow up function from an udate AX by KX.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
static int debug_channel(void *cls, uint32_t key, void *value)
Call GCCH_debug() on a channel.
static void mark_connection_unready(struct CadetTConnection *ct)
Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.
static void handle_plaintext_channel_open_ack(void *cls, const struct GNUNET_CADET_ChannelOpenAckMessage *cm)
We have received confirmation from the target peer that the given channel could be established (the p...
unsigned int GCT_count_any_connections(const struct CadetTunnel *t)
Counts the number of connections created for a tunnel, including busy connections.
static void new_ephemeral(struct CadetTunnelAxolotl *ax)
Create a new Axolotl ephemeral (ratchet) key.
#define MAX_KEY_GAP
Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is eithe...
#define MAX_UNVERIFIED_ATTEMPTS
How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon ...
static int handle_decrypted(void *cls, const struct GNUNET_MessageHeader *msg)
Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching...
static void store_skipped_key(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_AeadSecretKey *HKr)
Delete a key from the list of skipped keys.
#define LOG2(level,...)
static void retry_kx(void *cls)
Try to redo the KX or KX_AUTH handshake, if we can.
void GCT_change_estate(struct CadetTunnel *t, enum CadetTunnelEState state)
Change the tunnel encryption state.
static void t_ax_decrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Decrypt data with the axolotl tunnel key.
static void send_kx(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
Send a KX message.
static void try_send_normal_payload(struct CadetTunnel *t, struct CadetTConnection *ct)
Send normal payload from queue in t via connection ct.
static void t_h_encrypt(struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg, size_t additional_data_size, const unsigned char *additional_data)
Encrypt header with the axolotl header key.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
static void decrypted_error_cb(void *cls, enum GNUNET_MQ_Error error)
Function called if we had an error processing an incoming decrypted message.
unsigned int GCT_count_channels(struct CadetTunnel *t)
Returns the number of channels using a tunnel.
void GCT_handle_kx_auth(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
Handle KX_AUTH message.
void GCT_iterate_connections(struct CadetTunnel *t, GCT_ConnectionIterator iter, void *iter_cls)
Iterate over all connections of a tunnel.
void GCT_handle_encrypted(struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Handle encrypted message.
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
static void connection_ready_cb(void *cls, int is_ready)
A connection is is_ready for transmission.
static void cont_GCT_handle_kx(void *cls, enum GNUNET_GenericReturnValue ret)
Continue to handle KX message.
static void maintain_connections_cb(void *cls)
Function called to maintain the connections underlying our tunnel.
static void handle_plaintext_channel_destroy(void *cls, const struct GNUNET_CADET_ChannelDestroyMessage *cm)
We received a message saying that a channel should be destroyed.
#define HIGH_BIT
static void handle_plaintext_channel_open(void *cls, const struct GNUNET_CADET_ChannelOpenMessage *copen)
We have received a request to open a channel to a port from another peer.
static int iterate_channels_cb(void *cls, uint32_t key, void *value)
Helper function for GCT_iterate_channels.
static void send_kx_auth(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
Send a KX_AUTH message.
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...
static int store_ax_keys(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_AeadSecretKey *HKr, uint32_t Np)
Stage skipped AX keys and calculate the message key.
int GCT_add_inbound_connection(struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
Add a connection to the tunnel.
void GCT_connection_lost(struct CadetTConnection *ct)
We lost a connection, remove it from our list and clean up the connection object itself.
enum CadetTunnelEState GCT_get_estate(struct CadetTunnel *t)
Get the encryption state of a tunnel.
#define INITIAL_KX_RETRY_DELAY
How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have co...
static int check_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
Check that msg is well-formed.
static void handle_plaintext_data_ack(void *cls, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We received an acknowledgement for data we sent on a channel.
static void handle_plaintext_keepalive(void *cls, const struct GNUNET_MessageHeader *msg)
We got a keepalive.
static void handle_plaintext_data(void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We received payload data for a channel.
static void trigger_transmissions(void *cls)
Called when either we have a new connection, or a new message in the queue, or some existing connecti...
static void cont_GCT_handle_kx_auth(void *cls, enum GNUNET_GenericReturnValue ret)
Continue to handle KX_AUTH message.
static void evaluate_connection(void *cls, struct CadetTConnection *ct)
Evaluate a connection, updating our summary information in cls about what kinds of connections we hav...
static void delete_skipped_key(struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
Delete a key from the list of skipped keys.
void GCT_destroy_tunnel_now(struct CadetTunnel *t)
Destroys the tunnel t now, without delay.
static void t_ax_encrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Encrypt data with the axolotl tunnel key.
struct CadetTunnel * GCT_create_tunnel(struct CadetPeer *destination)
Create a tunnel to destination.
#define LOG(level,...)
static struct CadetTConnection * get_ready_connection(struct CadetTunnel *t)
Find first connection that is ready in the list of our connections.
static const char * estate2s(enum CadetTunnelEState es)
Get string description for tunnel encryption state.
int GCT_alice_or_betty(const struct GNUNET_PeerIdentity *other)
Am I Alice or Betty (some call her Bob), or talking to myself?
#define IDLE_DESTROY_DELAY
How long do we wait until tearing down an idle tunnel?
static ssize_t try_old_ax_keys(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
#define MAX_SKIPPED_KEYS
Maximum number of skipped keys we keep in memory per tunnel.
static ssize_t t_ax_decrypt_and_validate(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
void GCT_consider_path(struct CadetTunnel *t, struct CadetPeerPath *p, unsigned int off)
Consider using the path p for the tunnel t.
void GCT_iterate_channels(struct CadetTunnel *t, GCT_ChannelIterator iter, void *iter_cls)
Iterate over all channels of a tunnel.
static void destroy_tunnel(void *cls)
This tunnel is no longer used, destroy it.
void GCT_debug(const struct CadetTunnel *t, enum GNUNET_ErrorType level)
Log all possible info about the tunnel state.
static int destroy_remaining_channels(void *cls, uint32_t key, void *value)
Destroy remaining channels during shutdown.
static void t_hmac_derive_key(const struct GNUNET_CRYPTO_AeadSecretKey *key, struct GNUNET_CRYPTO_AeadSecretKey *out, const void *source, unsigned int len)
Derive a symmetric encryption key from an HMAC-HASH.
static enum GNUNET_GenericReturnValue t_h_decrypt(const struct GNUNET_CRYPTO_AeadSecretKey *hkr, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t esize, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
Decrypt header with the current axolotl header key.
static void t_ax_hmac_hash(const struct GNUNET_CRYPTO_AeadSecretKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
Perform a HMAC.
static void update_ax_by_kx(void *cls, const struct GNUNET_HashCode *key_result)
Update our Axolotl key state based on the KX data we received.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
static void destroy_t_connection(void *cls, struct CadetTConnection *ct)
Clean up connection ct of a tunnel.
Information we track per tunnel.
CadetTunnelEState
All the encryption states a tunnel can be in.
@ CADET_TUNNEL_KEY_AX_AUTH_SENT
KX received and we sent KX_AUTH back, but we got no traffic yet, so we're waiting for either KX_AUTH ...
@ CADET_TUNNEL_KEY_AX_SENT
KX message sent, waiting for other peer's KX_AUTH.
@ CADET_TUNNEL_KEY_UNINITIALIZED
Uninitialized status, we need to send KX.
@ CADET_TUNNEL_KEY_AX_SENT_AND_RECV
KX message sent and received, trying to send back KX_AUTH.
@ CADET_TUNNEL_KEY_OK
Handshake completed: session key available.
@ CADET_TUNNEL_KEY_AX_RECV
KX message received, trying to send back KX_AUTH.
#define DESIRED_CONNECTIONS_PER_TUNNEL
How many connections would we like to have per tunnel?
void(* GCT_ConnectionIterator)(void *cls, struct CadetTConnection *ct)
Iterator over connections.
void(* GCT_SendContinuation)(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called when a transmission requested using GCT_send is done.
void(* GCT_ChannelIterator)(void *cls, struct CadetChannel *ch)
Iterator over channels.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
#define N
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_Process * p
Helper process we started.
Definition gnunet-uri.c:38
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
struct GNUNET_PILS_Operation * GNUNET_PILS_ecdh(struct GNUNET_PILS_Handle *handle, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, GNUNET_PILS_EcdhResultCallback cb, void *cb_cls)
Derive key material from a ECDH public key and our private key.
Definition pils_api.c:595
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:623
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
API to schedule computations using continuation passing style.
API to create, modify and access statistics.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
Definition crypto_ecc.c:752
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:454
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_aead_decrypt(size_t ct_len, const unsigned char ct[ct_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, const struct GNUNET_CRYPTO_AeadMac *mac, void *pt)
Decrypt the given data using XChaCha20-Poly1305.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition crypto_ecc.c:843
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_aead_encrypt(size_t pt_len, const unsigned char pt[pt_len], size_t aad_len, const unsigned char aad[aad_len], const struct GNUNET_CRYPTO_AeadSecretKey *key, const struct GNUNET_CRYPTO_AeadNonce *nonce, void *ct, struct GNUNET_CRYPTO_AeadMac *mac)
Encrypt the given data using XChaCha20-Poly1305.
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
Definition crypto_ecc.c:433
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:217
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
#define GNUNET_CRYPTO_hkdf_gnunet(result, out_len, xts, xts_len, skm, skm_len,...)
A peculiar HKDF instantiation that tried to mimic Truncated NMAC.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_remove(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
Remove the given key-value pair from the map.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
void * GNUNET_CONTAINER_multihashmap32_get(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
uint64_t GNUNET_CONTAINER_HeapCostType
Cost by which elements in a heap can be ordered.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MAX(a, b)
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_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_MIN(a, b)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
GNUNET_ErrorType
Types of errors.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:482
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition mq.c:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
Definition mq.c:187
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE
Announce connection is still alive (direction sensitive).
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
Axolotl key exchange response with authentication.
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
Axolotl encrypted data.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY
Ask the cadet service to destroy a channel.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
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:1260
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
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:1310
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:1283
enum GNUNET_GenericReturnValue GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition mst.c:101
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition mst.c:86
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition mst.c:404
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_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:438
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:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#define GNUNET_TIME_UNIT_MINUTES
One minute.
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:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition time.c:452
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition peer.c:68
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
Performance metrics for a connection.
unsigned long long num_acked_transmissions
How many packets that ought to generate an ACK did we send via this connection?
struct GNUNET_TIME_Absolute age
When was this connection first established? (by us sending or receiving the CREATE_ACK for the first ...
unsigned long long num_successes
Number of packets that were sent via this connection did actually receive an ACK? (Note: ACKs may be ...
struct GNUNET_TIME_Absolute last_use
When was this connection last used? (by us sending or receiving a PAYLOAD message on it)
Low-level connection to a destination.
struct CadetTConnection * ct
Which tunnel is using this connection?
unsigned int off
Offset of our destination in path.
Information regarding a possible path to reach a peer.
Struct containing all information regarding a given peer.
Entry in list of connections used by tunnel, with metadata.
struct CadetTConnection * next
Next in DLL.
struct CadetConnection * cc
Connection handle.
struct GNUNET_TIME_Absolute created
Creation time, to keep oldest connection alive.
int is_ready
Is the connection currently ready for transmission?
struct CadetTunnel * t
Tunnel this connection belongs to.
Struct used to store data required for an async update AX by KX process.
struct GNUNET_PeerIdentity peer_id
Peer identity of other peer.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
void * cb_cls
Update callback closure.
struct GNUNET_HashCode auth
KDF-proof that sender could compute the 3-DH, used in lieu of a signature or payload data.
struct CadetTunnelAxolotl ax
Struct used for Axolotl.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key
Ephemeral public key of other key.
struct GNUNET_CRYPTO_EcdhePublicKey ratchet_key
Ratchet key.
struct GNUNET_PILS_Operation * ecdh_op
Operation to derive key material.
CadetTunnelAxolotlCallback cb
Update callback.
Axolotl data, according to https://github.com/trevp/axolotl/wiki .
struct GNUNET_CRYPTO_AeadSecretKey CKr
32-byte chain keys (used for forward-secrecy) for receiving messages.
uint32_t PNs
Previous message numbers (# of msgs sent under prev ratchet)
struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral
Last ephemeral public key received from the other peer, for duplicate detection.
struct GNUNET_CRYPTO_AeadSecretKey RK
32-byte root key which gets updated by DH ratchet.
unsigned int skipped
Number of elements in skipped_head <-> skipped_tail.
struct GNUNET_TIME_Absolute ratchet_expiration
Time when the current ratchet expires and a new one is triggered (if ratchet_allowed is GNUNET_YES).
struct GNUNET_CRYPTO_AeadSecretKey NHKr
32-byte next header key (for receiving).
struct GNUNET_CRYPTO_EcdhePrivateKey kx_0
ECDH for key exchange (A0 / B0).
struct GNUNET_CRYPTO_EcdhePublicKey DHRr
ECDH Ratchet key (other peer's public key in the current DH).
uint32_t Ns
Message number (reset to 0 with each new ratchet, next message to send).
struct CadetTunnelSkippedKey * skipped_tail
Skipped messages' keys DLL, tail.
struct GNUNET_CRYPTO_AeadSecretKey CKs
32-byte chain keys (used for forward-secrecy) for sending messages.
struct GNUNET_CRYPTO_AeadSecretKey HKs
32-byte header key (currently used for sending).
struct CadetTunnelSkippedKey * skipped_head
A (double linked) list of stored message keys and associated header keys for "skipped" messages,...
uint32_t Nr
Message number (reset to 0 with each new ratchet, next message to recv).
int ratchet_allowed
True (GNUNET_YES) if we have received a message from the other peer that uses the keys from our last ...
int ratchet_flag
True (GNUNET_YES) if we have to send a new ratchet key in next msg.
struct GNUNET_CRYPTO_AeadSecretKey NHKs
32-byte next header key (for sending), used once the ratchet advances.
unsigned int ratchet_counter
Number of messages received since our last ratchet advance.
struct GNUNET_CRYPTO_EcdhePrivateKey DHRs
ECDH Ratchet key (our private key in the current DH).
struct GNUNET_CRYPTO_AeadSecretKey HKr
32-byte header key (currently used for receiving)
Struct used to save messages in a non-ready tunnel to send once connected.
struct CadetTunnelQueueEntry * prev
We are entries in a DLL.
struct GNUNET_MQ_Envelope * env
Envelope of message to send follows.
GCT_SendContinuation cont
Continuation to call once sent (on the channel layer).
struct GNUNET_CADET_ConnectionTunnelIdentifier * cid
Where to put the connection identifier into the payload of the message in env once we have it?
struct CadetTunnelQueueEntry * next
We are entries in a DLL.
struct CadetTunnel * t
Tunnel these messages belong in.
Struct to old keys for skipped messages while advancing the Axolotl ratchet.
struct GNUNET_TIME_Absolute timestamp
When was this key stored (for timeout).
struct GNUNET_CRYPTO_AeadSecretKey HK
Header key.
unsigned int Kn
Key number for a given HK.
struct CadetTunnelSkippedKey * next
DLL next.
struct GNUNET_CRYPTO_AeadSecretKey MK
Message key.
struct CadetTunnelSkippedKey * prev
DLL prev.
Struct containing all information regarding a tunnel to a peer.
struct GNUNET_SCHEDULER_Task * send_task
Task to send messages from queue (if possible).
struct CadetPeer * destination
Destination of the tunnel.
struct CadetTConnection * connection_ready_head
DLL of ready connections that are actively used to reach the destination peer.
struct CadetTunnelAsync as
Structure to store data temporally for async operations.
struct CadetTConnection * current_ct
Identification of the connection from which we are currently processing a message.
struct CadetTunnelQueueEntry * tq_tail
Queued messages, to transmit once tunnel gets connected.
struct GNUNET_SCHEDULER_Task * maintain_connections_task
Task to trim connections if too many are present.
struct CadetTConnection * connection_busy_head
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_TIME_Absolute next_kx_attempt
When do we try the next KX?
struct GNUNET_TIME_Relative kx_retry_delay
How long do we wait until we retry the KX?
struct CadetTConnection * connection_busy_tail
DLL of connections that we maintain that might be used to reach the destination peer.
struct GNUNET_MQ_Handle * mq
Dispatcher for decrypted messages only (do NOT use for sending!).
enum CadetTunnelEState estate
State of the tunnel encryption.
struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key
Peer's ephemeral key, to recreate e_key and d_key when own ephemeral key changes.
unsigned int num_busy_connections
Number of connections in the connection_busy_head DLL.
struct CadetTunnelAxolotl ax
Axolotl info.
struct GNUNET_CONTAINER_MultiHashMap32 * channels
Channels inside this tunnel.
struct GNUNET_CRYPTO_AeadSecretKey e_key
Encryption ("our") key.
struct GNUNET_SCHEDULER_Task * destroy_task
Task scheduled if there are no more channels using the tunnel.
struct CadetTConnection * connection_ready_tail
DLL of ready connections that are actively used to reach the destination peer.
struct GNUNET_MessageStreamTokenizer * mst
Tokenizer for decrypted messages.
struct CadetTunnelQueueEntry * tq_head
Queued messages, to transmit once tunnel gets connected.
unsigned int num_ready_connections
Number of connections in the connection_ready_head DLL.
struct GNUNET_SCHEDULER_Task * kx_task
Task to trigger KX.
struct CadetTunnelAxolotl * unverified_ax
Unverified Axolotl info, used only if we got a fresh KX (not a KX_AUTH) while our end of the tunnel w...
unsigned int tq_len
Number of entries in the tq_head DLL.
struct GNUNET_CADET_ChannelTunnelNumber next_ctn
Channel ID for the next created channel in this tunnel.
int kx_auth_requested
Force triggering KX_AUTH independent of estate.
struct GNUNET_CRYPTO_AeadSecretKey d_key
Decryption ("their") key.
unsigned int unverified_attempts
How often have we tried and failed to decrypt a message using the unverified KX material from unverif...
Closure for iterate_channels_cb.
void * iter_cls
Closure for iter.
GCT_ChannelIterator iter
Function to call.
Closure for evaluate_connection.
unsigned int max_length
Maximum length of any of our connections, 0 if we have none.
int duplicate
Set to GNUNET_YES if we have a connection over path already.
GNUNET_CONTAINER_HeapCostType min_desire
Minimum desirability of any of our connections, UINT64_MAX if we have none.
struct CadetTConnection * worst
Connection deemed the "worst" so far encountered by evaluate_connection, NULL if we did not yet encou...
unsigned int min_length
Minimum length of any of our connections, UINT_MAX if we have none.
GNUNET_CONTAINER_HeapCostType max_desire
Maximum desirability of any of our connections, 0 if we have none.
double worst_score
Numeric score of worst, only set if worst is non-NULL.
struct CadetPeerPath * path
Path we are comparing against for evaluate_connection, can be NULL.
Encrypted axolotl header with numbers that identify which keys in which ratchet are to be used to dec...
uint32_t PNs
Number of messages sent with the previous ratchet key.
struct GNUNET_CRYPTO_EcdhePublicKey DHRs
Current ratchet key.
uint32_t Ns
Number of messages sent with the current ratchet key.
Message for cadet data traffic.
Message to acknowledge end-to-end data.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to destroy a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
struct GNUNET_HashCode port
Port number of the channel, used to prove to the initiator that the receiver knows the port.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
Message to create a Channel.
struct GNUNET_HashCode h_port
Hash of destination port and listener.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel within the tunnel.
uint32_t opt
Channel options.
Number identifying a CADET channel within a tunnel.
uint32_t cn
Which number does this channel have that uniquely identifies it within its tunnel,...
Hash uniquely identifying a connection below a tunnel.
Axolotl-encrypted tunnel message with application payload.
struct GNUNET_CADET_AxHeader ax_header
Axolotl-header that specifies which keys to use in which ratchet to decrypt the body that follows.
struct GNUNET_CRYPTO_AeadMac mac
MAC of the encrypted message, used to verify message integrity.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
Message for a Key eXchange for a tunnel, with authentication.
Message for a Key eXchange for a tunnel.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.
Internal representation of the hash map.
type for session keys
unsigned char mac[16]
Initialization vector.
type for session keys
type for (message) authentication keys
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Handle to a message stream tokenizer.
Definition mst.c:45
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:141
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.