GNUnet 0.26.2-20-ga2d76f2e4
 
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 "platform.h"
34#include "gnunet_util_lib.h"
36#include "cadet_protocol.h"
42
43
44#define LOG(level, ...) GNUNET_log_from (level, "cadet-tun", __VA_ARGS__)
45
51#define MAX_UNVERIFIED_ATTEMPTS 16
52
56#define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply ( \
57 GNUNET_TIME_UNIT_SECONDS, 90)
58
63#define INITIAL_KX_RETRY_DELAY GNUNET_TIME_relative_multiply ( \
64 GNUNET_TIME_UNIT_MILLISECONDS, 250)
65
69#define MAX_SKIPPED_KEYS 64
70
75#define MAX_KEY_GAP 256
76
77
113
114
253
254
296
297
458
459
466int
468{
469 if (0 > GNUNET_memcmp (&my_full_id,
470 other))
471 return GNUNET_YES;
472 else if (0 < GNUNET_memcmp (&my_full_id,
473 other))
474 return GNUNET_NO;
475 else
476 {
477 GNUNET_break_op (0);
478 return GNUNET_SYSERR;
479 }
480}
481
482
489static void
491{
492 struct CadetTunnel *t = ct->t;
493
495 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
496 t->connection_ready_tail,
497 ct);
498 GNUNET_assert (0 < t->num_ready_connections);
499 t->num_ready_connections--;
500 ct->is_ready = GNUNET_NO;
501 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
502 t->connection_busy_tail,
503 ct);
504 t->num_busy_connections++;
505}
506
507
515const char *
516GCT_2s (const struct CadetTunnel *t)
517{
518 static char buf[64];
519
520 if (NULL == t)
521 return "Tunnel(NULL)";
522 GNUNET_snprintf (buf,
523 sizeof(buf),
524 "Tunnel %s",
525 GNUNET_i2s (GCP_get_id (t->destination)));
526 return buf;
527}
528
529
537static const char *
539{
540 static char buf[32];
541
542 switch (es)
543 {
545 return "CADET_TUNNEL_KEY_UNINITIALIZED";
547 return "CADET_TUNNEL_KEY_AX_RECV";
549 return "CADET_TUNNEL_KEY_AX_SENT";
551 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
553 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
555 return "CADET_TUNNEL_KEY_OK";
556 }
557 GNUNET_snprintf (buf,
558 sizeof(buf),
559 "%u (UNKNOWN STATE)",
560 es);
561 return buf;
562}
563
564
571struct CadetPeer *
573{
574 return t->destination;
575}
576
577
578unsigned int
580{
581 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
582}
583
584
592static struct CadetChannel *
595{
596 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
597 ntohl (ctn.cn));
598}
599
600
601unsigned int
603{
604 return t->num_ready_connections + t->num_busy_connections;
605}
606
607
615static struct CadetTConnection *
617{
618 struct CadetTConnection *hd = t->connection_ready_head;
619
620 GNUNET_assert ((NULL == hd) ||
621 (GNUNET_YES == hd->is_ready));
622 return hd;
623}
624
625
635{
636 return t->estate;
637}
638
639
648static void
649trigger_transmissions (void *cls);
650
651
652/* ************************************** start core crypto ***************************** */
653
654
660static void
662{
664 "Creating new ephemeral ratchet key (DHRs)\n");
666}
667
668
678static void
679t_hmac (const void *plaintext,
680 size_t size,
681 uint32_t iv,
683 struct GNUNET_ShortHashCode *hmac)
684{
685 static const char ctx[] = "cadet authentication key";
686 struct GNUNET_CRYPTO_AuthKey auth_key;
687 struct GNUNET_HashCode hash;
688
689 // FIXME now that we directly invoke HKDF instead of a
690 // thin wrapper we can clearly see the sillyness of adding
691 // the key parameter twice...
693 &auth_key,
694 sizeof auth_key,
695 &iv,
696 sizeof(iv),
697 key,
698 sizeof(*key),
701 /* Two step: GNUNET_ShortHash is only 256 bits,
702 GNUNET_HashCode is 512, so we truncate. */
703 GNUNET_CRYPTO_hmac (&auth_key,
704 plaintext,
705 size,
706 &hash);
707 GNUNET_memcpy (hmac,
708 &hash,
709 sizeof(*hmac));
710}
711
712
721static void
723 struct GNUNET_HashCode *hash,
724 const void *source,
725 unsigned int len)
726{
727 static const char ctx[] = "axolotl HMAC-HASH";
728 struct GNUNET_CRYPTO_AuthKey auth_key;
729
731 &auth_key,
732 sizeof auth_key,
733 ctx,
734 sizeof(ctx),
735 key,
736 sizeof *key);
737 GNUNET_CRYPTO_hmac (&auth_key,
738 source,
739 len,
740 hash);
741}
742
743
752static void
755 const void *source,
756 unsigned int len)
757{
758 static const char ctx[] = "axolotl derive key";
759 struct GNUNET_HashCode h;
760
762 &h,
763 source,
764 len);
766 out, sizeof(*out),
767 ctx, sizeof(ctx),
768 &h, sizeof(h));
769}
770
771
780static void
782 void *dst,
783 const void *src,
784 size_t size)
785{
788 size_t out_size;
789
790 ax->ratchet_counter++;
791 if ((GNUNET_YES == ax->ratchet_allowed) &&
792 ((ratchet_messages <= ax->ratchet_counter) ||
795 {
797 }
798 if (GNUNET_YES == ax->ratchet_flag)
799 {
800 /* Advance ratchet */
802 struct GNUNET_HashCode dh;
803 struct GNUNET_HashCode hmac;
804 static const char ctx[] = "axolotl ratchet";
805
806 new_ephemeral (ax);
807 ax->HKs = ax->NHKs;
808
809 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
811 &ax->DHRr,
812 &dh);
813 t_ax_hmac_hash (&ax->RK,
814 &hmac,
815 &dh,
816 sizeof(dh));
818 keys, sizeof(keys),
819 ctx, sizeof(ctx),
820 &hmac, sizeof(hmac));
821 ax->RK = keys[0];
822 ax->NHKs = keys[1];
823 ax->CKs = keys[2];
824
825 ax->PNs = ax->Ns;
826 ax->Ns = 0;
829 ax->ratchet_counter = 0;
833 }
834
836 &MK,
837 "0",
838 1);
839
841 sizeof iv,
842 NULL,
843 0,
844 &MK,
845 sizeof MK);
846
847 out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
848 size,
849 &MK,
850 &iv,
851 dst);
852 GNUNET_assert (size == out_size);
854 &ax->CKs,
855 "1",
856 1);
857}
858
859
868static void
870 void *dst,
871 const void *src,
872 size_t size)
873{
876 size_t out_size;
877
879 &MK,
880 "0",
881 1);
882
884 sizeof iv,
885 NULL,
886 0,
887 &MK,
888 sizeof MK);
889 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
890 out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
891 size,
892 &MK,
893 &iv,
894 dst);
895 GNUNET_assert (out_size == size);
897 &ax->CKr,
898 "1",
899 1);
900}
901
902
909static void
912{
914 size_t out_size;
915
917 sizeof iv,
918 NULL,
919 0,
920 &ax->HKs,
921 sizeof ax->HKs);
922 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
923 sizeof(struct
925 &ax->HKs,
926 &iv,
927 &msg->ax_header);
928 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
929}
930
931
939static void
941 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
943{
945 size_t out_size;
946
948 sizeof iv,
949 NULL,
950 0,
951 &ax->HKr,
952 sizeof ax->HKr);
953
954
956 sizeof(struct
958 &ax->HKr,
959 &iv,
960 &dst->ax_header.Ns);
961 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
962}
963
964
971static void
981
982
993static ssize_t
995 void *dst,
996 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
997 size_t size)
998{
1000 struct GNUNET_ShortHashCode *hmac;
1002 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1003 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
1004 size_t esize;
1005 size_t res;
1006 size_t len;
1007 unsigned int N;
1008
1010 "Trying skipped keys\n");
1011 hmac = &plaintext_header.hmac;
1012 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1013
1014 /* Find a correct Header Key */
1015 valid_HK = NULL;
1016 for (key = ax->skipped_head; NULL != key; key = key->next)
1017 {
1018 t_hmac (&src->ax_header,
1019 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1020 0,
1021 &key->HK,
1022 hmac);
1023 if (0 == GNUNET_memcmp (hmac,
1024 &src->hmac))
1025 {
1026 valid_HK = &key->HK;
1027 break;
1028 }
1029 }
1030 if (NULL == key)
1031 return -1;
1032
1033 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1035 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1036 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1037
1038 /* Decrypt header */
1040 sizeof iv,
1041 NULL,
1042 0,
1043 &key->HK,
1044 sizeof key->HK);
1045
1047 sizeof(struct GNUNET_CADET_AxHeader),
1048 &key->HK,
1049 &iv,
1050 &plaintext_header.ax_header.Ns);
1051 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1052
1053 /* Find the correct message key */
1054 N = ntohl (plaintext_header.ax_header.Ns);
1055 while ((NULL != key) &&
1056 (N != key->Kn))
1057 key = key->next;
1058 if ((NULL == key) ||
1059 (0 != GNUNET_memcmp (&key->HK,
1060 valid_HK)))
1061 return -1;
1062
1063 /* Decrypt payload */
1065 sizeof iv,
1066 NULL,
1067 0,
1068 &key->MK,
1069 sizeof key->MK);
1070
1072 len,
1073 &key->MK,
1074 &iv,
1075 dst);
1077 key);
1078 return res;
1079}
1080
1081
1088static void
1090 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
1091{
1092 struct CadetTunnelSkippedKey *key;
1093
1095 key->timestamp = GNUNET_TIME_absolute_get ();
1096 key->Kn = ax->Nr;
1097 key->HK = ax->HKr;
1098 t_hmac_derive_key (&ax->CKr,
1099 &key->MK,
1100 "0",
1101 1);
1102 t_hmac_derive_key (&ax->CKr,
1103 &ax->CKr,
1104 "1",
1105 1);
1107 ax->skipped_tail,
1108 key);
1109 ax->skipped++;
1110 ax->Nr++;
1111}
1112
1113
1124static int
1126 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1127 uint32_t Np)
1128{
1129 int gap;
1130
1131 gap = Np - ax->Nr;
1133 "Storing skipped keys [%u, %u)\n",
1134 ax->Nr,
1135 Np);
1136 if (MAX_KEY_GAP < gap)
1137 {
1138 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1139 /* TODO: start new key exchange on return */
1140 GNUNET_break_op (0);
1142 "Got message %u, expected %u+\n",
1143 Np,
1144 ax->Nr);
1145 return GNUNET_SYSERR;
1146 }
1147 if (0 > gap)
1148 {
1149 /* Delayed message: don't store keys, flag to try old keys. */
1150 return GNUNET_SYSERR;
1151 }
1152
1153 while (ax->Nr < Np)
1155 HKr);
1156
1157 while (ax->skipped > MAX_SKIPPED_KEYS)
1159 ax->skipped_tail);
1160 return GNUNET_OK;
1161}
1162
1163
1174static ssize_t
1176 void *dst,
1177 const struct
1179 size_t size)
1180{
1181 struct GNUNET_ShortHashCode msg_hmac;
1182 struct GNUNET_HashCode hmac;
1183 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1184 uint32_t Np;
1185 uint32_t PNp;
1186 size_t esize; /* Size of encrypted payload */
1187
1188 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1189
1190 /* Try current HK */
1191 t_hmac (&src->ax_header,
1192 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1193 0, &ax->HKr,
1194 &msg_hmac);
1195 if (0 != GNUNET_memcmp (&msg_hmac,
1196 &src->hmac))
1197 {
1198 static const char ctx[] = "axolotl ratchet";
1199 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1201 struct GNUNET_HashCode dh;
1202 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1203
1204 /* Try Next HK */
1205 t_hmac (&src->ax_header,
1206 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1207 0,
1208 &ax->NHKr,
1209 &msg_hmac);
1210 if (0 != GNUNET_memcmp (&msg_hmac,
1211 &src->hmac))
1212 {
1213 /* Try the skipped keys, if that fails, we're out of luck. */
1214 return try_old_ax_keys (ax,
1215 dst,
1216 src,
1217 size);
1218 }
1219 HK = ax->HKr;
1220 ax->HKr = ax->NHKr;
1221 t_h_decrypt (ax,
1222 src,
1223 &plaintext_header);
1224 Np = ntohl (plaintext_header.ax_header.Ns);
1225 PNp = ntohl (plaintext_header.ax_header.PNs);
1226 DHRp = &plaintext_header.ax_header.DHRs;
1227 store_ax_keys (ax,
1228 &HK,
1229 PNp);
1230
1231 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1233 DHRp,
1234 &dh);
1235 t_ax_hmac_hash (&ax->RK,
1236 &hmac,
1237 &dh, sizeof(dh));
1239 keys, sizeof(keys),
1240 ctx, sizeof(ctx),
1241 &hmac, sizeof(hmac));
1242
1243 /* Commit "purported" keys */
1244 ax->RK = keys[0];
1245 ax->NHKr = keys[1];
1246 ax->CKr = keys[2];
1247 ax->DHRr = *DHRp;
1248 ax->Nr = 0;
1250 }
1251 else
1252 {
1253 t_h_decrypt (ax,
1254 src,
1255 &plaintext_header);
1256 Np = ntohl (plaintext_header.ax_header.Ns);
1257 PNp = ntohl (plaintext_header.ax_header.PNs);
1258 }
1259 if ((Np != ax->Nr) &&
1260 (GNUNET_OK != store_ax_keys (ax,
1261 &ax->HKr,
1262 Np)))
1263 {
1264 /* Try the skipped keys, if that fails, we're out of luck. */
1265 return try_old_ax_keys (ax,
1266 dst,
1267 src,
1268 size);
1269 }
1270
1271 t_ax_decrypt (ax,
1272 dst,
1273 &src[1],
1274 esize);
1275 ax->Nr = Np + 1;
1276 return esize;
1277}
1278
1279
1289static int
1291 uint32_t key,
1292 void *value)
1293{
1294 struct CadetChannel *ch = value;
1295
1297 return GNUNET_OK;
1298}
1299
1300
1308void
1311{
1312 enum CadetTunnelEState old = t->estate;
1313
1314 t->estate = state;
1316 "%s estate changed from %s to %s\n",
1317 GCT_2s (t),
1318 estate2s (old),
1319 estate2s (state));
1320
1321 if ((CADET_TUNNEL_KEY_OK != old) &&
1322 (CADET_TUNNEL_KEY_OK == t->estate))
1323 {
1324 if (NULL != t->kx_task)
1325 {
1326 GNUNET_SCHEDULER_cancel (t->kx_task);
1327 t->kx_task = NULL;
1328 }
1329 /* notify all channels that have been waiting */
1332 t);
1333 if (NULL != t->send_task)
1334 GNUNET_SCHEDULER_cancel (t->send_task);
1336 t);
1337 }
1338}
1339
1340
1349static void
1351 struct CadetTConnection *ct,
1352 struct CadetTunnelAxolotl *ax)
1353{
1354 struct CadetConnection *cc;
1355 struct GNUNET_MQ_Envelope *env;
1358
1359 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1360 return; /* only Alice may send KX */
1361 if ((NULL == ct) ||
1362 (GNUNET_NO == ct->is_ready))
1363 ct = get_ready_connection (t);
1364 if (NULL == ct)
1365 {
1367 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1368 GCT_2s (t),
1369 estate2s (t->estate));
1370 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1371 return;
1372 }
1373 cc = ct->cc;
1376 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1377 msg->flags = htonl (flags);
1378 msg->cid = *GCC_get_id (cc);
1380 &msg->ephemeral_key);
1381#if DEBUG_KX
1382 msg->ephemeral_key_XXX = ax->kx_0;
1383 msg->private_key_XXX = *my_private_key;
1384#endif
1386 "Sending KX message to %s with ephemeral %s on CID %s\n",
1387 GCT_2s (t),
1388 GNUNET_e2s (&msg->ephemeral_key),
1389 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1391 &msg->ratchet_key);
1393 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1394 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1395 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1398 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1401 GCC_transmit (cc,
1402 env);
1404 "# KX transmitted",
1405 1,
1406 GNUNET_NO);
1407}
1408
1409
1420static void
1422 struct CadetTConnection *ct,
1423 struct CadetTunnelAxolotl *ax,
1424 int force_reply)
1425{
1426 struct CadetConnection *cc;
1427 struct GNUNET_MQ_Envelope *env;
1429 enum GNUNET_CADET_KX_Flags flags;
1430
1431 if ((NULL == ct) ||
1432 (GNUNET_NO == ct->is_ready))
1433 ct = get_ready_connection (t);
1434 if (NULL == ct)
1435 {
1437 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1438 GCT_2s (t));
1439 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1440 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1441 return;
1442 }
1443 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1444 cc = ct->cc;
1448 if (GNUNET_YES == force_reply)
1450 msg->kx.flags = htonl (flags);
1451 msg->kx.cid = *GCC_get_id (cc);
1453 &msg->kx.ephemeral_key);
1455 &msg->kx.ratchet_key);
1456#if DEBUG_KX
1457 msg->kx.ephemeral_key_XXX = ax->kx_0;
1458 msg->kx.private_key_XXX = *my_private_key;
1459 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1460#endif
1462 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1463 GCT_2s (t),
1464 GNUNET_e2s (&msg->kx.ephemeral_key),
1465 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1466
1467 /* Compute authenticator (this is the main difference to #send_kx()) */
1468 GNUNET_CRYPTO_hash (&ax->RK,
1469 sizeof(ax->RK),
1470 &msg->auth);
1471 /* Compute when to be triggered again; actual job will
1472 be scheduled via #connection_ready_cb() */
1473 t->kx_retry_delay
1474 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1475 t->next_kx_attempt
1476 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1477
1478 /* Send via cc, mark it as unready */
1480
1481 /* Update state machine, unless we are already OK */
1482 if (CADET_TUNNEL_KEY_OK != t->estate)
1485 GCC_transmit (cc,
1486 env);
1488 "# KX_AUTH transmitted",
1489 1,
1490 GNUNET_NO);
1491}
1492
1493
1499static void
1501{
1502 while (NULL != ax->skipped_head)
1504 ax->skipped_head);
1505 GNUNET_assert (0 == ax->skipped);
1508}
1509
1510
1524static int
1526 const struct GNUNET_PeerIdentity *pid,
1527 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key,
1528 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
1529{
1530 struct GNUNET_HashCode key_material[3];
1531 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1532 const char salt[] = "CADET Axolotl salt";
1533 int am_I_alice;
1534
1535 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1536 {
1537 GNUNET_break_op (0);
1538 return GNUNET_SYSERR;
1539 }
1540 if (0 == GNUNET_memcmp (&ax->DHRr,
1541 ratchet_key))
1542 {
1544 "# Ratchet key already known",
1545 1,
1546 GNUNET_NO);
1548 "Ratchet key already known. Ignoring KX.\n");
1549 return GNUNET_NO;
1550 }
1551
1552 ax->DHRr = *ratchet_key;
1553 ax->last_ephemeral = *ephemeral_key;
1554 /* ECDH A B0 */
1555 if (GNUNET_YES == am_I_alice)
1556 {
1558 ephemeral_key, /* B0 */
1559 &key_material[0]);
1560 }
1561 else
1562 {
1563 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1564 &pid->public_key, /* A */
1565 &key_material[0]);
1566 }
1567 /* ECDH A0 B */
1568 if (GNUNET_YES == am_I_alice)
1569 {
1570 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1571 &pid->public_key, /* B */
1572 &key_material[1]);
1573 }
1574 else
1575 {
1577 ephemeral_key, /* A0 */
1578 &key_material[1]);
1579 }
1580
1581 /* ECDH A0 B0 */
1582 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1583 ephemeral_key, /* B0 or A0 */
1584 &key_material[2]);
1585 /* KDF */
1587 keys, sizeof(keys),
1588 salt, sizeof(salt),
1589 &key_material, sizeof(key_material));
1590
1591 if (0 == memcmp (&ax->RK,
1592 &keys[0],
1593 sizeof(ax->RK)))
1594 {
1596 "Root key already known. Ignoring KX.\n");
1598 "# Root key already known",
1599 1,
1600 GNUNET_NO);
1601 return GNUNET_NO;
1602 }
1603
1604 ax->RK = keys[0];
1605 if (GNUNET_YES == am_I_alice)
1606 {
1607 ax->HKr = keys[1];
1608 ax->NHKs = keys[2];
1609 ax->NHKr = keys[3];
1610 ax->CKr = keys[4];
1612 }
1613 else
1614 {
1615 ax->HKs = keys[1];
1616 ax->NHKr = keys[2];
1617 ax->NHKs = keys[3];
1618 ax->CKs = keys[4];
1619 ax->ratchet_flag = GNUNET_NO;
1622 ratchet_time);
1623 }
1624 return GNUNET_OK;
1625}
1626
1627
1633static void
1634retry_kx (void *cls)
1635{
1636 struct CadetTunnel *t = cls;
1637 struct CadetTunnelAxolotl *ax;
1638
1639 t->kx_task = NULL;
1641 "Trying to make KX progress on %s in state %s\n",
1642 GCT_2s (t),
1643 estate2s (t->estate));
1644 switch (t->estate)
1645 {
1646 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1647 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1648 send_kx (t,
1649 NULL,
1650 &t->ax);
1651 break;
1652
1655 /* We are responding, so only require reply
1656 if WE have a channel waiting. */
1657 if (NULL != t->unverified_ax)
1658 {
1659 /* Send AX_AUTH so we might get this one verified */
1660 ax = t->unverified_ax;
1661 }
1662 else
1663 {
1664 /* How can this be? */
1665 GNUNET_break (0);
1666 ax = &t->ax;
1667 }
1668 send_kx_auth (t,
1669 NULL,
1670 ax,
1671 (0 == GCT_count_channels (t))
1672 ? GNUNET_NO
1673 : GNUNET_YES);
1674 break;
1675
1677 /* We are responding, so only require reply
1678 if WE have a channel waiting. */
1679 if (NULL != t->unverified_ax)
1680 {
1681 /* Send AX_AUTH so we might get this one verified */
1682 ax = t->unverified_ax;
1683 }
1684 else
1685 {
1686 /* How can this be? */
1687 GNUNET_break (0);
1688 ax = &t->ax;
1689 }
1690 send_kx_auth (t,
1691 NULL,
1692 ax,
1693 (0 == GCT_count_channels (t))
1694 ? GNUNET_NO
1695 : GNUNET_YES);
1696 break;
1697
1699 /* Must have been the *other* peer asking us to
1700 respond with a KX_AUTH. */
1701 if (NULL != t->unverified_ax)
1702 {
1703 /* Sending AX_AUTH in response to AX so we might get this one verified */
1704 ax = t->unverified_ax;
1705 }
1706 else
1707 {
1708 /* Sending AX_AUTH in response to AX_AUTH */
1709 ax = &t->ax;
1710 }
1711 send_kx_auth (t,
1712 NULL,
1713 ax,
1714 GNUNET_NO);
1715 break;
1716 }
1717}
1718
1719
1720void
1723{
1724 struct CadetTunnel *t = ct->t;
1725 int ret;
1726
1728 "# KX received",
1729 1,
1730 GNUNET_NO);
1731 if (GNUNET_YES ==
1732 GCT_alice_or_betty (GCP_get_id (t->destination)))
1733 {
1734 /* Betty/Bob is not allowed to send KX! */
1735 GNUNET_break_op (0);
1736 return;
1737 }
1739 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1740 GCT_2s (t),
1741 GNUNET_e2s (&msg->ephemeral_key),
1742 GNUNET_i2s (GCP_get_id (t->destination)),
1743 GCC_2s (ct->cc));
1744#if 1
1745 if ((0 ==
1746 memcmp (&t->ax.DHRr,
1747 &msg->ratchet_key,
1748 sizeof(msg->ratchet_key))) &&
1749 (0 ==
1750 memcmp (&t->ax.last_ephemeral,
1751 &msg->ephemeral_key,
1752 sizeof(msg->ephemeral_key))))
1753
1754 {
1756 "# Duplicate KX received",
1757 1,
1758 GNUNET_NO);
1759 send_kx_auth (t,
1760 ct,
1761 &t->ax,
1762 GNUNET_NO);
1763 return;
1764 }
1765#endif
1766 /* We only keep ONE unverified KX around, so if there is an existing one,
1767 clean it up. */
1768 if (NULL != t->unverified_ax)
1769 {
1770 if ((0 ==
1771 memcmp (&t->unverified_ax->DHRr,
1772 &msg->ratchet_key,
1773 sizeof(msg->ratchet_key))) &&
1774 (0 ==
1775 memcmp (&t->unverified_ax->last_ephemeral,
1776 &msg->ephemeral_key,
1777 sizeof(msg->ephemeral_key))))
1778 {
1780 "# Duplicate unverified KX received",
1781 1,
1782 GNUNET_NO);
1783#if 1
1784 send_kx_auth (t,
1785 ct,
1786 t->unverified_ax,
1787 GNUNET_NO);
1788 return;
1789#endif
1790 }
1792 "Dropping old unverified KX state.\n");
1794 "# Unverified KX dropped for fresh KX",
1795 1,
1796 GNUNET_NO);
1797 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1798 memset (t->unverified_ax,
1799 0,
1800 sizeof(struct CadetTunnelAxolotl));
1801 }
1802 else
1803 {
1805 "Creating fresh unverified KX for %s\n",
1806 GCT_2s (t));
1808 "# Fresh KX setup",
1809 1,
1810 GNUNET_NO);
1811 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1812 }
1813 /* Set as the 'current' RK/DHRr the one we are currently using,
1814 so that the duplicate-detection logic of
1815 #update_ax_by_kx can work. */
1816 t->unverified_ax->RK = t->ax.RK;
1817 t->unverified_ax->DHRr = t->ax.DHRr;
1818 t->unverified_ax->DHRs = t->ax.DHRs;
1819 t->unverified_ax->kx_0 = t->ax.kx_0;
1820 t->unverified_attempts = 0;
1821
1822 /* Update 'ax' by the new key material */
1823 ret = update_ax_by_kx (t->unverified_ax,
1824 GCP_get_id (t->destination),
1825 &msg->ephemeral_key,
1826 &msg->ratchet_key);
1828 if (GNUNET_OK != ret)
1829 {
1831 "# Useless KX",
1832 1,
1833 GNUNET_NO);
1834 return; /* duplicate KX, nothing to do */
1835 }
1836 /* move ahead in our state machine */
1837 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1840 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1843
1844 /* KX is still not done, try again our end. */
1845 if (CADET_TUNNEL_KEY_OK != t->estate)
1846 {
1847 if (NULL != t->kx_task)
1848 GNUNET_SCHEDULER_cancel (t->kx_task);
1849 t->kx_task
1851 t);
1852 }
1853}
1854
1855
1856#if DEBUG_KX
1857static void
1858check_ee (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1859 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2)
1860{
1863 struct GNUNET_HashCode hc1;
1864 struct GNUNET_HashCode hc2;
1865
1867 &p1);
1869 &p2);
1872 &p2,
1873 &hc1));
1876 &p1,
1877 &hc2));
1878 GNUNET_break (0 == GNUNET_memcmp (&hc1,
1879 &hc2));
1880}
1881
1882
1883static void
1884check_ed (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1885 const struct GNUNET_CRYPTO_EddsaPrivateKey *e2)
1886{
1889 struct GNUNET_HashCode hc1;
1890 struct GNUNET_HashCode hc2;
1891
1893 &p1);
1895 &p2);
1898 &p2,
1899 &hc1));
1902 &p1,
1903 &hc2));
1904 GNUNET_break (0 == GNUNET_memcmp (&hc1,
1905 &hc2));
1906}
1907
1908
1909static void
1910test_crypto_bug (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1911 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2,
1912 const struct GNUNET_CRYPTO_EddsaPrivateKey *d1,
1913 const struct GNUNET_CRYPTO_EddsaPrivateKey *d2)
1914{
1915 check_ee (e1, e2);
1916 check_ed (e1, d2);
1917 check_ed (e2, d1);
1918}
1919
1920
1921#endif
1922
1923
1930void
1933{
1934 struct CadetTunnel *t = ct->t;
1935 struct CadetTunnelAxolotl ax_tmp;
1936 struct GNUNET_HashCode kx_auth;
1937 int ret;
1938
1940 "# KX_AUTH received",
1941 1,
1942 GNUNET_NO);
1943 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1944 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
1945 {
1946 /* Confusing, we got a KX_AUTH before we even send our own
1947 KX. This should not happen. We'll send our own KX ASAP anyway,
1948 so let's ignore this here. */
1949 GNUNET_break_op (0);
1950 return;
1951 }
1953 "Handling KX_AUTH message from %s with ephemeral %s\n",
1954 GCT_2s (t),
1955 GNUNET_e2s (&msg->kx.ephemeral_key));
1956 /* We do everything in ax_tmp until we've checked the authentication
1957 so we don't clobber anything we care about by accident. */
1958 ax_tmp = t->ax;
1959
1960 /* Update 'ax' by the new key material */
1961 ret = update_ax_by_kx (&ax_tmp,
1962 GCP_get_id (t->destination),
1963 &msg->kx.ephemeral_key,
1964 &msg->kx.ratchet_key);
1965 if (GNUNET_OK != ret)
1966 {
1967 if (GNUNET_NO == ret)
1969 "# redundant KX_AUTH received",
1970 1,
1971 GNUNET_NO);
1972 else
1973 GNUNET_break (0); /* connect to self!? */
1974 return;
1975 }
1976 GNUNET_CRYPTO_hash (&ax_tmp.RK,
1977 sizeof(ax_tmp.RK),
1978 &kx_auth);
1979 if (0 != GNUNET_memcmp (&kx_auth,
1980 &msg->auth))
1981 {
1982 /* This KX_AUTH is not using the latest KX/KX_AUTH data
1983 we transmitted to the sender, refuse it, try KX again. */
1985 "# KX_AUTH not using our last KX received (auth failure)",
1986 1,
1987 GNUNET_NO);
1989 "KX AUTH mismatch!\n");
1990#if DEBUG_KX
1991 {
1992 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1993
1995 &ephemeral_key);
1996 if (0 != GNUNET_memcmp (&ephemeral_key,
1997 &msg->r_ephemeral_key_XXX))
1998 {
2000 "My ephemeral is %s!\n",
2001 GNUNET_e2s (&ephemeral_key));
2003 "Response is for ephemeral %s!\n",
2004 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2005 }
2006 else
2007 {
2008 test_crypto_bug (&ax_tmp.kx_0,
2009 &msg->kx.ephemeral_key_XXX,
2011 &msg->kx.private_key_XXX);
2012 }
2013 }
2014#endif
2015 if (NULL == t->kx_task)
2016 t->kx_task
2017 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2018 &retry_kx,
2019 t);
2020 return;
2021 }
2022 /* Yep, we're good. */
2023 t->ax = ax_tmp;
2024 if (NULL != t->unverified_ax)
2025 {
2026 /* We got some "stale" KX before, drop that. */
2027 cleanup_ax (t->unverified_ax);
2028 GNUNET_free (t->unverified_ax);
2029 t->unverified_ax = NULL;
2030 }
2031
2032 /* move ahead in our state machine */
2033 switch (t->estate)
2034 {
2037 /* Checked above, this is impossible. */
2038 GNUNET_assert (0);
2039 break;
2040
2041 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2042 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2043 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2046 break;
2047
2049 /* Did not expect another KX_AUTH, but so what, still acceptable.
2050 Nothing to do here. */
2051 break;
2052 }
2053 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->kx.flags)))
2054 {
2055 send_kx_auth (t,
2056 NULL,
2057 &t->ax,
2058 GNUNET_NO);
2059 }
2060}
2061
2062
2063/* ************************************** end core crypto ***************************** */
2064
2065
2074{
2075#define HIGH_BIT 0x8000000
2077 uint32_t ctn;
2078 int cmp;
2079 uint32_t highbit;
2080
2081 cmp = GNUNET_memcmp (&my_full_id,
2083 if (0 < cmp)
2084 highbit = HIGH_BIT;
2085 else if (0 > cmp)
2086 highbit = 0;
2087 else
2088 GNUNET_assert (0); // loopback must never go here!
2089 ctn = ntohl (t->next_ctn.cn);
2090 while (NULL !=
2092 ctn | highbit))
2093 {
2094 ctn = ((ctn + 1) & (~HIGH_BIT));
2095 }
2096 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2097 ret.cn = htonl (ctn | highbit);
2098 return ret;
2099}
2100
2101
2113 struct CadetChannel *ch)
2114{
2116
2117 ctn = get_next_free_ctn (t);
2118 if (NULL != t->destroy_task)
2119 {
2120 GNUNET_SCHEDULER_cancel (t->destroy_task);
2121 t->destroy_task = NULL;
2122 }
2125 ntohl (ctn.cn),
2126 ch,
2129 "Adding %s to %s with state %d\n",
2130 GCCH_2s (ch),
2131 GCT_2s (t),
2132 t->estate);
2133 switch (t->estate)
2134 {
2136 /* waiting for connection to start KX */
2137 break;
2138
2142 /* we're currently waiting for KX to complete */
2143 break;
2144
2146 /* waiting for OTHER peer to send us data,
2147 we might need to prompt more aggressively! */
2148 if (NULL == t->kx_task)
2149 t->kx_task
2150 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2151 &retry_kx,
2152 t);
2153 break;
2154
2156 /* We are ready. Tell the new channel that we are up. */
2158 break;
2159 }
2160 return ctn;
2161}
2162
2163
2170void
2172{
2173 struct CadetTunnel *t = ct->t;
2174
2175 if (GNUNET_YES == ct->is_ready)
2176 {
2177 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2178 t->connection_ready_tail,
2179 ct);
2180 t->num_ready_connections--;
2181 }
2182 else
2183 {
2184 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2185 t->connection_busy_tail,
2186 ct);
2187 t->num_busy_connections--;
2188 }
2189 GNUNET_free (ct);
2190}
2191
2192
2199static void
2201 struct CadetTConnection *ct)
2202{
2203 struct CadetTunnel *t = cls;
2204 struct CadetConnection *cc = ct->cc;
2205
2206 GNUNET_assert (ct->t == t);
2209}
2210
2211
2217static void
2219{
2220 struct CadetTunnel *t = cls;
2221 struct CadetTunnelQueueEntry *tq;
2222
2223 t->destroy_task = NULL;
2225 "Destroying idle %s\n",
2226 GCT_2s (t));
2230 t);
2231 GNUNET_assert (NULL == t->connection_ready_head);
2232 GNUNET_assert (NULL == t->connection_busy_head);
2233 while (NULL != (tq = t->tq_head))
2234 {
2235 if (NULL != tq->cont)
2236 tq->cont (tq->cont_cls,
2237 NULL);
2238 GCT_send_cancel (tq);
2239 }
2240 GCP_drop_tunnel (t->destination,
2241 t);
2243 if (NULL != t->maintain_connections_task)
2244 {
2245 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2246 t->maintain_connections_task = NULL;
2247 }
2248 if (NULL != t->send_task)
2249 {
2250 GNUNET_SCHEDULER_cancel (t->send_task);
2251 t->send_task = NULL;
2252 }
2253 if (NULL != t->kx_task)
2254 {
2255 GNUNET_SCHEDULER_cancel (t->kx_task);
2256 t->kx_task = NULL;
2257 }
2258 GNUNET_MST_destroy (t->mst);
2259 GNUNET_MQ_destroy (t->mq);
2260 if (NULL != t->unverified_ax)
2261 {
2262 cleanup_ax (t->unverified_ax);
2263 GNUNET_free (t->unverified_ax);
2264 }
2265 cleanup_ax (&t->ax);
2266 GNUNET_assert (NULL == t->destroy_task);
2267 GNUNET_free (t);
2268}
2269
2270
2278void
2280 struct CadetChannel *ch,
2282{
2284 "Removing %s from %s\n",
2285 GCCH_2s (ch),
2286 GCT_2s (t));
2289 ntohl (ctn.cn),
2290 ch));
2291 if ((0 ==
2292 GCT_count_channels (t)) &&
2293 (NULL == t->destroy_task))
2294 {
2295 t->destroy_task
2298 t);
2299 }
2300}
2301
2302
2311static int
2313 uint32_t key,
2314 void *value)
2315{
2316 struct CadetChannel *ch = value;
2317
2319 NULL);
2320 return GNUNET_OK;
2321}
2322
2323
2329void
2331{
2335 t);
2336 GNUNET_assert (0 ==
2338 if (NULL != t->destroy_task)
2339 {
2340 GNUNET_SCHEDULER_cancel (t->destroy_task);
2341 t->destroy_task = NULL;
2342 }
2343 destroy_tunnel (t);
2344}
2345
2346
2354static void
2356 struct CadetTConnection *ct)
2357{
2358 struct CadetTunnelQueueEntry *tq;
2359
2361 tq = t->tq_head;
2362 if (NULL == tq)
2363 {
2364 /* no messages pending right now */
2366 "Not sending payload of %s on ready %s (nothing pending)\n",
2367 GCT_2s (t),
2368 GCC_2s (ct->cc));
2369 return;
2370 }
2371 /* ready to send message 'tq' on tunnel 'ct' */
2372 GNUNET_assert (t == tq->t);
2374 t->tq_tail,
2375 tq);
2376 if (NULL != tq->cid)
2377 *tq->cid = *GCC_get_id (ct->cc);
2380 "Sending payload of %s on %s\n",
2381 GCT_2s (t),
2382 GCC_2s (ct->cc));
2383 GCC_transmit (ct->cc,
2384 tq->env);
2385 if (NULL != tq->cont)
2386 tq->cont (tq->cont_cls,
2387 GCC_get_id (ct->cc));
2388 GNUNET_free (tq);
2389}
2390
2391
2400static void
2402 int is_ready)
2403{
2404 struct CadetTConnection *ct = cls;
2405 struct CadetTunnel *t = ct->t;
2406
2407 if (GNUNET_NO == is_ready)
2408 {
2410 "%s no longer ready for %s\n",
2411 GCC_2s (ct->cc),
2412 GCT_2s (t));
2414 return;
2415 }
2417 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2418 t->connection_busy_tail,
2419 ct);
2420 GNUNET_assert (0 < t->num_busy_connections);
2421 t->num_busy_connections--;
2422 ct->is_ready = GNUNET_YES;
2423 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2424 t->connection_ready_tail,
2425 ct);
2426 t->num_ready_connections++;
2427
2429 "%s now ready for %s in state %s\n",
2430 GCC_2s (ct->cc),
2431 GCT_2s (t),
2432 estate2s (t->estate));
2433 switch (t->estate)
2434 {
2437 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2438 GCT_2s (t),
2439 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2440 t->next_kx_attempt).rel_value_us);
2441 /* Do not begin KX if WE have no channels waiting! */
2443 t->next_kx_attempt).rel_value_us)
2444 return; /* wait for timeout before retrying */
2445 /* We are uninitialized, just transmit immediately,
2446 without undue delay. */
2447
2449 "Why for %s \n",
2450 GCT_2s (t));
2451
2452 if (NULL != t->kx_task)
2453 {
2454 GNUNET_SCHEDULER_cancel (t->kx_task);
2455 t->kx_task = NULL;
2456 }
2457 send_kx (t,
2458 ct,
2459 &t->ax);
2460 if ((0 ==
2461 GCT_count_channels (t)) &&
2462 (NULL == t->destroy_task))
2463 {
2464 t->destroy_task
2467 t);
2468 }
2469 break;
2470
2475 /* we're currently waiting for KX to complete, schedule job */
2476 if (NULL == t->kx_task)
2477 t->kx_task
2478 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2479 &retry_kx,
2480 t);
2481 break;
2482
2484 if (GNUNET_YES == t->kx_auth_requested)
2485 {
2487 t->next_kx_attempt).rel_value_us)
2488 return; /* wait for timeout */
2489 if (NULL != t->kx_task)
2490 {
2491 GNUNET_SCHEDULER_cancel (t->kx_task);
2492 t->kx_task = NULL;
2493 }
2494 send_kx_auth (t,
2495 ct,
2496 &t->ax,
2497 GNUNET_NO);
2498 return;
2499 }
2501 ct);
2502 break;
2503 }
2504}
2505
2506
2515static void
2517{
2518 struct CadetTunnel *t = cls;
2519 struct CadetTConnection *ct;
2520
2521 t->send_task = NULL;
2522 if (NULL == t->tq_head)
2523 return; /* no messages pending right now */
2524 ct = get_ready_connection (t);
2525 if (NULL == ct)
2526 return; /* no connections ready */
2528 ct);
2529}
2530
2531
2579
2580
2588static void
2590 struct CadetTConnection *ct)
2591{
2592 struct EvaluationSummary *es = cls;
2593 struct CadetConnection *cc = ct->cc;
2594 unsigned int ct_length;
2595 struct CadetPeerPath *ps;
2596 const struct CadetConnectionMetrics *metrics;
2597 GNUNET_CONTAINER_HeapCostType ct_desirability;
2598 struct GNUNET_TIME_Relative uptime;
2599 struct GNUNET_TIME_Relative last_use;
2600 double score;
2601 double success_rate;
2602
2603 ps = GCC_get_path (cc,
2604 &ct_length);
2606 "Evaluating path %s of existing %s\n",
2607 GCPP_2s (ps),
2608 GCC_2s (cc));
2609 if (ps == es->path)
2610 {
2612 "Ignoring duplicate path %s.\n",
2613 GCPP_2s (es->path));
2614 es->duplicate = GNUNET_YES;
2615 return;
2616 }
2617 if (NULL != es->path)
2618 {
2619 int duplicate = GNUNET_YES;
2620
2621 for (unsigned int i = 0; i < ct_length; i++)
2622 {
2625 i) !=
2627 i))
2628 {
2629 duplicate = GNUNET_NO;
2630 break;
2631 }
2632 }
2633 if (GNUNET_YES == duplicate)
2634 {
2636 "Ignoring overlapping path %s.\n",
2637 GCPP_2s (es->path));
2638 es->duplicate = GNUNET_YES;
2639 return;
2640 }
2641 else
2642 {
2644 "Known path %s differs from proposed path\n",
2645 GCPP_2s (ps));
2646 }
2647 }
2648
2649 ct_desirability = GCPP_get_desirability (ps);
2650 metrics = GCC_get_metrics (cc);
2651 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2652 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2653 /* We add 1.0 here to avoid division by zero. */
2654 success_rate = (metrics->num_acked_transmissions + 1.0)
2655 / (metrics->num_successes + 1.0);
2656 score
2657 = ct_desirability
2658 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2659 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2660 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2661 score *= success_rate; /* weigh overall by success rate */
2662
2663 if ((NULL == es->worst) ||
2664 (score < es->worst_score))
2665 {
2666 es->worst = ct;
2667 es->worst_score = score;
2668 }
2669 es->min_length = GNUNET_MIN (es->min_length,
2670 ct_length);
2671 es->max_length = GNUNET_MAX (es->max_length,
2672 ct_length);
2673 es->min_desire = GNUNET_MIN (es->min_desire,
2674 ct_desirability);
2675 es->max_desire = GNUNET_MAX (es->max_desire,
2676 ct_desirability);
2677}
2678
2679
2689static int
2691 struct CadetPeerPath *path,
2692 unsigned int off)
2693{
2694 struct CadetTunnel *t = cls;
2695 struct EvaluationSummary es;
2696 struct CadetTConnection *ct;
2697
2698 GNUNET_assert (off < GCPP_get_length (path));
2700 off) == t->destination);
2701 es.min_length = UINT_MAX;
2702 es.max_length = 0;
2703 es.max_desire = 0;
2704 es.min_desire = UINT64_MAX;
2705 es.path = path;
2706 es.duplicate = GNUNET_NO;
2707 es.worst = NULL;
2708
2709 /* Compute evaluation summary over existing connections. */
2711 "Evaluating proposed path %s for target %s\n",
2712 GCPP_2s (path),
2713 GCT_2s (t));
2714 /* FIXME: suspect this does not ACTUALLY iterate
2715 over all existing paths, otherwise dup detection
2716 should work!!! */
2719 &es);
2720 if (GNUNET_YES == es.duplicate)
2721 return GNUNET_YES;
2722
2723 /* FIXME: not sure we should really just count
2724 'num_connections' here, as they may all have
2725 consistently failed to connect. */
2726
2727 /* We iterate by increasing path length; if we have enough paths and
2728 this one is more than twice as long than what we are currently
2729 using, then ignore all of these super-long ones! */
2731 (es.min_length * 2 < off) &&
2732 (es.max_length < off))
2733 {
2735 "Ignoring paths of length %u, they are way too long.\n",
2736 es.min_length * 2);
2737 return GNUNET_NO;
2738 }
2739 /* If we have enough paths and this one looks no better, ignore it. */
2741 (es.min_length < GCPP_get_length (path)) &&
2742 (es.min_desire > GCPP_get_desirability (path)) &&
2743 (es.max_length < off))
2744 {
2746 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2747 GCPP_get_length (path),
2748 (unsigned long long) GCPP_get_desirability (path),
2749 GCP_2s (t->destination));
2750 return GNUNET_YES;
2751 }
2752
2753 /* Path is interesting (better by some metric, or we don't have
2754 enough paths yet). */
2755 ct = GNUNET_new (struct CadetTConnection);
2757 ct->t = t;
2758 ct->cc = GCC_create (t->destination,
2759 path,
2760 off,
2761 ct,
2763 ct);
2764
2765 /* FIXME: schedule job to kill connection (and path?) if it takes
2766 too long to get ready! (And track performance data on how long
2767 other connections took with the tunnel!)
2768 => Note: to be done within 'connection'-logic! */
2769 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2770 t->connection_busy_tail,
2771 ct);
2772 t->num_busy_connections++;
2774 "Found interesting path %s for %s, created %s\n",
2775 GCPP_2s (path),
2776 GCT_2s (t),
2777 GCC_2s (ct->cc));
2778 return GNUNET_YES;
2779}
2780
2781
2795static void
2797{
2798 struct CadetTunnel *t = cls;
2799 struct GNUNET_TIME_Relative delay;
2800 struct EvaluationSummary es;
2801
2802 t->maintain_connections_task = NULL;
2804 "Performing connection maintenance for %s.\n",
2805 GCT_2s (t));
2806
2807 es.min_length = UINT_MAX;
2808 es.max_length = 0;
2809 es.max_desire = 0;
2810 es.min_desire = UINT64_MAX;
2811 es.path = NULL;
2812 es.worst = NULL;
2813 es.duplicate = GNUNET_NO;
2816 &es);
2817 if ((NULL != es.worst) &&
2819 {
2820 /* Clear out worst-performing connection 'es.worst'. */
2822 es.worst);
2823 }
2824
2825 /* Consider additional paths */
2826 (void) GCP_iterate_paths (t->destination,
2828 t);
2829
2830 /* FIXME: calculate when to try again based on how well we are doing;
2831 in particular, if we have to few connections, we might be able
2832 to do without this (as PATHS should tell us whenever a new path
2833 is available instantly; however, need to make sure this job is
2834 restarted after that happens).
2835 Furthermore, if the paths we do know are in a reasonably narrow
2836 quality band and are plentyful, we might also consider us stabilized
2837 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2838 t->maintain_connections_task
2841 t);
2842}
2843
2844
2845void
2847 struct CadetPeerPath *p,
2848 unsigned int off)
2849{
2851 "Considering %s for %s (offset %u)\n",
2852 GCPP_2s (p),
2853 GCT_2s (t),
2854 off);
2855 (void) consider_path_cb (t,
2856 p,
2857 off);
2858}
2859
2860
2867static void
2869 const struct GNUNET_MessageHeader *msg)
2870{
2871 struct CadetTunnel *t = cls;
2872
2874 "Received KEEPALIVE on %s\n",
2875 GCT_2s (t));
2877 "# keepalives received",
2878 1,
2879 GNUNET_NO);
2880}
2881
2882
2890static int
2893{
2894 return GNUNET_OK;
2895}
2896
2897
2905static void
2908{
2909 struct CadetTunnel *t = cls;
2910 struct CadetChannel *ch;
2911
2912 ch = lookup_channel (t,
2913 msg->ctn);
2914 if (NULL == ch)
2915 {
2916 /* We don't know about such a channel, might have been destroyed on our
2917 end in the meantime, or never existed. Send back a DESTROY. */
2919 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
2920 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
2921 ntohl (msg->ctn.cn));
2923 msg->ctn);
2924 return;
2925 }
2927 GCC_get_id (t->current_ct->cc),
2928 msg);
2929}
2930
2931
2940static void
2942 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
2943{
2944 struct CadetTunnel *t = cls;
2945 struct CadetChannel *ch;
2946
2947 ch = lookup_channel (t,
2948 ack->ctn);
2949 if (NULL == ch)
2950 {
2951 /* We don't know about such a channel, might have been destroyed on our
2952 end in the meantime, or never existed. Send back a DESTROY. */
2954 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
2955 ntohl (ack->ctn.cn));
2957 ack->ctn);
2958 return;
2959 }
2961 GCC_get_id (t->current_ct->cc),
2962 ack);
2963}
2964
2965
2973static void
2975 const struct
2977{
2978 struct CadetTunnel *t = cls;
2979 struct CadetChannel *ch;
2980
2982 ntohl (copen->ctn.cn));
2983 if (NULL != ch)
2984 {
2986 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
2987 GNUNET_h2s (&copen->h_port),
2988 GCT_2s (t),
2989 GCCH_2s (ch));
2991 GCC_get_id (t->current_ct->cc));
2992 return;
2993 }
2995 "Received CHANNEL_OPEN on h_port %s from %s\n",
2996 GNUNET_h2s (&copen->h_port),
2997 GCT_2s (t));
2999 copen->ctn,
3000 &copen->h_port,
3001 ntohl (copen->opt));
3002 if (NULL != t->destroy_task)
3003 {
3004 GNUNET_SCHEDULER_cancel (t->destroy_task);
3005 t->destroy_task = NULL;
3006 }
3009 ntohl (copen->ctn.cn),
3010 ch,
3012}
3013
3014
3021void
3024{
3026
3028 "Sending DESTROY message for channel ID %u\n",
3029 ntohl (ctn.cn));
3030 msg.header.size = htons (sizeof(msg));
3032 msg.reserved = htonl (0);
3033 msg.ctn = ctn;
3034 GCT_send (t,
3035 &msg.header,
3036 NULL,
3037 NULL,
3038 &ctn);
3039}
3040
3041
3050static void
3052 const struct
3054{
3055 struct CadetTunnel *t = cls;
3056 struct CadetChannel *ch;
3057
3058 ch = lookup_channel (t,
3059 cm->ctn);
3060 if (NULL == ch)
3061 {
3062 /* We don't know about such a channel, might have been destroyed on our
3063 end in the meantime, or never existed. Send back a DESTROY. */
3065 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3066 ntohl (cm->ctn.cn));
3068 cm->ctn);
3069 return;
3070 }
3072 "Received channel OPEN_ACK on channel %s from %s\n",
3073 GCCH_2s (ch),
3074 GCT_2s (t));
3076 GCC_get_id (t->current_ct->cc),
3077 &cm->port);
3078}
3079
3080
3088static void
3090 const struct
3092{
3093 struct CadetTunnel *t = cls;
3094 struct CadetChannel *ch;
3095
3096 ch = lookup_channel (t,
3097 cm->ctn);
3098 if (NULL == ch)
3099 {
3100 /* We don't know about such a channel, might have been destroyed on our
3101 end in the meantime, or never existed. */
3103 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3104 ntohl (cm->ctn.cn));
3105 return;
3106 }
3108 "Received channel DESTROY on %s from %s\n",
3109 GCCH_2s (ch),
3110 GCT_2s (t));
3112 GCC_get_id (t->current_ct->cc));
3113}
3114
3115
3126static int
3128 const struct GNUNET_MessageHeader *msg)
3129{
3130 struct CadetTunnel *t = cls;
3131
3132 GNUNET_assert (NULL != t->current_ct);
3134 msg);
3135 return GNUNET_OK;
3136}
3137
3138
3146static void
3148 enum GNUNET_MQ_Error error)
3149{
3150 GNUNET_break_op (0);
3151}
3152
3153
3161struct CadetTunnel *
3163{
3164 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3166 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3168 struct GNUNET_MessageHeader,
3169 t),
3170 GNUNET_MQ_hd_var_size (plaintext_data,
3173 t),
3174 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3177 t),
3178 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3181 t),
3182 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3185 t),
3186 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3189 t),
3191 };
3192
3193 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3194 new_ephemeral (&t->ax);
3196 t->destination = destination;
3198 t->maintain_connections_task
3200 t);
3201 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3202 NULL,
3203 NULL,
3204 NULL,
3205 handlers,
3207 t);
3209 t);
3210 return t;
3211}
3212
3213
3214int
3216 const struct
3218 struct CadetPeerPath *path)
3219{
3220 struct CadetTConnection *ct;
3221
3222 ct = GNUNET_new (struct CadetTConnection);
3224 ct->t = t;
3225 ct->cc = GCC_create_inbound (t->destination,
3226 path,
3227 ct,
3228 cid,
3230 ct);
3231 if (NULL == ct->cc)
3232 {
3234 "%s refused inbound %s (duplicate)\n",
3235 GCT_2s (t),
3236 GCC_2s (ct->cc));
3237 GNUNET_free (ct);
3238 return GNUNET_SYSERR;
3239 }
3240 /* FIXME: schedule job to kill connection (and path?) if it takes
3241 too long to get ready! (And track performance data on how long
3242 other connections took with the tunnel!)
3243 => Note: to be done within 'connection'-logic! */
3244 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3245 t->connection_busy_tail,
3246 ct);
3247 t->num_busy_connections++;
3249 "%s has new %s\n",
3250 GCT_2s (t),
3251 GCC_2s (ct->cc));
3252 return GNUNET_OK;
3253}
3254
3255
3262void
3265{
3266 struct CadetTunnel *t = ct->t;
3267 uint16_t size = ntohs (msg->header.size);
3268 char cbuf[size] GNUNET_ALIGN;
3269 ssize_t decrypted_size;
3270
3272 "%s received %u bytes of encrypted data in state %d\n",
3273 GCT_2s (t),
3274 (unsigned int) size,
3275 t->estate);
3276
3277 switch (t->estate)
3278 {
3281 /* We did not even SEND our KX, how can the other peer
3282 send us encrypted data? Must have been that we went
3283 down and the other peer still things we are up.
3284 Let's send it KX back. */
3286 "# received encrypted without any KX",
3287 1,
3288 GNUNET_NO);
3289 if (NULL != t->kx_task)
3290 {
3291 GNUNET_SCHEDULER_cancel (t->kx_task);
3292 t->kx_task = NULL;
3293 }
3294 send_kx (t,
3295 ct,
3296 &t->ax);
3297 return;
3298
3300 /* We send KX, and other peer send KX to us at the same time.
3301 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3303 "# received encrypted without KX_AUTH",
3304 1,
3305 GNUNET_NO);
3306 if (NULL != t->kx_task)
3307 {
3308 GNUNET_SCHEDULER_cancel (t->kx_task);
3309 t->kx_task = NULL;
3310 }
3311 send_kx_auth (t,
3312 ct,
3313 &t->ax,
3314 GNUNET_YES);
3315 return;
3316
3318 /* We did not get the KX of the other peer, but that
3319 might have been lost. Send our KX again immediately. */
3321 "# received encrypted without KX",
3322 1,
3323 GNUNET_NO);
3324 if (NULL != t->kx_task)
3325 {
3326 GNUNET_SCHEDULER_cancel (t->kx_task);
3327 t->kx_task = NULL;
3328 }
3329 send_kx (t,
3330 ct,
3331 &t->ax);
3332 return;
3333
3335 /* Great, first payload, we might graduate to OK! */
3337 /* We are up and running, all good. */
3338 break;
3339 }
3340
3341 decrypted_size = -1;
3342 if (CADET_TUNNEL_KEY_OK == t->estate)
3343 {
3344 /* We have well-established key material available,
3345 try that. (This is the common case.) */
3346 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3347 cbuf,
3348 msg,
3349 size);
3350 }
3351
3352 if ((-1 == decrypted_size) &&
3353 (NULL != t->unverified_ax))
3354 {
3355 /* We have un-authenticated KX material available. We should try
3356 this as a back-up option, in case the sender crashed and
3357 switched keys. */
3358 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3359 cbuf,
3360 msg,
3361 size);
3362 if (-1 != decrypted_size)
3363 {
3364 /* It worked! Treat this as authentication of the AX data! */
3365 cleanup_ax (&t->ax);
3366 t->ax = *t->unverified_ax;
3367 GNUNET_free (t->unverified_ax);
3368 t->unverified_ax = NULL;
3369 }
3370 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3371 {
3372 /* First time it worked, move tunnel into production! */
3375 if (NULL != t->send_task)
3376 GNUNET_SCHEDULER_cancel (t->send_task);
3378 t);
3379 }
3380 }
3381 if (NULL != t->unverified_ax)
3382 {
3383 /* We had unverified KX material that was useless; so increment
3384 counter and eventually move to ignore it. Note that we even do
3385 this increment if we successfully decrypted with the old KX
3386 material and thus didn't even both with the new one. This is
3387 the ideal case, as a malicious injection of bogus KX data
3388 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3390 "Failed to decrypt message with unverified KX data %u times\n",
3391 t->unverified_attempts);
3392 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3393 {
3394 cleanup_ax (t->unverified_ax);
3395 GNUNET_free (t->unverified_ax);
3396 t->unverified_ax = NULL;
3397 }
3398 }
3399
3400 if (-1 == decrypted_size)
3401 {
3402 /* Decryption failed for good, complain. */
3404 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3405 GCT_2s (t));
3407 "# unable to decrypt",
3408 1,
3409 GNUNET_NO);
3410 if (NULL != t->kx_task)
3411 {
3412 GNUNET_SCHEDULER_cancel (t->kx_task);
3413 t->kx_task = NULL;
3414 }
3415 send_kx (t,
3416 ct,
3417 &t->ax);
3418 return;
3419 }
3421 "# decrypted bytes",
3422 decrypted_size,
3423 GNUNET_NO);
3424
3425 /* The MST will ultimately call #handle_decrypted() on each message. */
3426 t->current_ct = ct;
3429 cbuf,
3430 decrypted_size,
3431 GNUNET_YES,
3432 GNUNET_NO));
3433 t->current_ct = NULL;
3434}
3435
3436
3437struct CadetTunnelQueueEntry *
3439 const struct GNUNET_MessageHeader *message,
3441 void *cont_cls,
3443{
3444 struct CadetTunnelQueueEntry *tq;
3445 uint16_t payload_size;
3446 struct GNUNET_MQ_Envelope *env;
3448 struct CadetChannel *ch;
3449
3450 if (NULL != ctn)
3451 {
3452 ch = lookup_channel (t,
3453 *ctn);
3454 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3455 {
3456 GNUNET_break (0);
3457 return NULL;
3458 }
3459 }
3460
3461 if (CADET_TUNNEL_KEY_OK != t->estate)
3462 {
3463 GNUNET_break (0);
3464 return NULL;
3465 }
3466 payload_size = ntohs (message->size);
3468 "Encrypting %u bytes for %s\n",
3469 (unsigned int) payload_size,
3470 GCT_2s (t));
3471 env = GNUNET_MQ_msg_extra (ax_msg,
3472 payload_size,
3474 t_ax_encrypt (&t->ax,
3475 &ax_msg[1],
3476 message,
3477 payload_size);
3479 "# encrypted bytes",
3480 payload_size,
3481 GNUNET_NO);
3482 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3483 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3484 /* FIXME: we should do this once, not once per message;
3485 this is a point multiplication, and DHRs does not
3486 change all the time. */
3488 &ax_msg->ax_header.DHRs);
3489 t_h_encrypt (&t->ax,
3490 ax_msg);
3491 t_hmac (&ax_msg->ax_header,
3492 sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3493 0,
3494 &t->ax.HKs,
3495 &ax_msg->hmac);
3496
3497 tq = GNUNET_malloc (sizeof(*tq));
3498 tq->t = t;
3499 tq->env = env;
3500 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3501 tq->cont = cont;
3502 tq->cont_cls = cont_cls;
3504 t->tq_tail,
3505 tq);
3506 if (NULL != t->send_task)
3507 GNUNET_SCHEDULER_cancel (t->send_task);
3508 t->send_task
3510 t);
3511 return tq;
3512}
3513
3514
3515void
3517{
3518 struct CadetTunnel *t = tq->t;
3519
3521 t->tq_tail,
3522 tq);
3523 GNUNET_MQ_discard (tq->env);
3524 GNUNET_free (tq);
3525}
3526
3527
3535void
3538 void *iter_cls)
3539{
3540 struct CadetTConnection *n;
3541
3542 for (struct CadetTConnection *ct = t->connection_ready_head;
3543 NULL != ct;
3544 ct = n)
3545 {
3546 n = ct->next;
3547 iter (iter_cls,
3548 ct);
3549 }
3550 for (struct CadetTConnection *ct = t->connection_busy_head;
3551 NULL != ct;
3552 ct = n)
3553 {
3554 n = ct->next;
3555 iter (iter_cls,
3556 ct);
3557 }
3558}
3559
3560
3576
3577
3586static int
3588 uint32_t key,
3589 void *value)
3590{
3591 struct ChanIterCls *ctx = cls;
3592 struct CadetChannel *ch = value;
3593
3594 ctx->iter (ctx->iter_cls,
3595 ch);
3596 return GNUNET_OK;
3597}
3598
3599
3607void
3610 void *iter_cls)
3611{
3612 struct ChanIterCls ctx;
3613
3614 ctx.iter = iter;
3615 ctx.iter_cls = iter_cls;
3618 &ctx);
3619}
3620
3621
3630static int
3631debug_channel (void *cls,
3632 uint32_t key,
3633 void *value)
3634{
3635 const enum GNUNET_ErrorType *level = cls;
3636 struct CadetChannel *ch = value;
3637
3638 GCCH_debug (ch, *level);
3639 return GNUNET_OK;
3640}
3641
3642
3643#define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3644 __VA_ARGS__)
3645
3646
3653void
3654GCT_debug (const struct CadetTunnel *t,
3655 enum GNUNET_ErrorType level)
3656{
3657#if ! defined(GNUNET_CULL_LOGGING)
3658 struct CadetTConnection *iter_c;
3659 int do_log;
3660
3662 "cadet-tun",
3663 __FILE__, __FUNCTION__, __LINE__);
3664 if (0 == do_log)
3665 return;
3666
3667 LOG2 (level,
3668 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3669 GCT_2s (t),
3670 estate2s (t->estate),
3671 t->tq_len,
3673 LOG2 (level,
3674 "TTT channels:\n");
3677 &level);
3678 LOG2 (level,
3679 "TTT connections:\n");
3680 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3681 GCC_debug (iter_c->cc,
3682 level);
3683 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3684 GCC_debug (iter_c->cc,
3685 level);
3686
3687 LOG2 (level,
3688 "TTT TUNNEL END\n");
3689#endif
3690}
3691
3692
3693/* 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_CRYPTO_PowSalt salt
Salt for PoW calculations.
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Own private key.
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 t_h_decrypt(struct CadetTunnelAxolotl *ax, const struct GNUNET_CADET_TunnelEncryptedMessage *src, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
Decrypt header with the current axolotl header key.
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)
Handle KX message that lacks authentication (and which will thus only be considered authenticated aft...
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 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...
#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.
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 t_hmac(const void *plaintext, size_t size, uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_ShortHashCode *hmac)
Calculate HMAC.
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.
static void store_skipped_key(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
Delete a key from the list of skipped keys.
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 void t_ax_hmac_hash(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
Perform a HMAC.
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.
static int update_ax_by_kx(struct CadetTunnelAxolotl *ax, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
Update our Axolotl key state based on the KX data we received.
#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 int store_ax_keys(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, uint32_t Np)
Stage skipped AX keys and calculate the message key.
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 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 t_h_encrypt(struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Encrypt header with the axolotl header key.
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.
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.
static void t_hmac_derive_key(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricSessionKey *out, const void *source, unsigned int len)
Derive a symmetric encryption key from an HMAC-HASH.
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.
#define N
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
static struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
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:732
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:454
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:201
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition crypto_ecc.c:745
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:823
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
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
#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:41
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)
#define GNUNET_CRYPTO_kdf_arg_string(d)
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_CRYPTO_kdf_arg_auto(d)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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.
Axolotl data, according to https://github.com/trevp/axolotl/wiki .
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.
unsigned int skipped
Number of elements in skipped_head <-> skipped_tail.
struct GNUNET_CRYPTO_SymmetricSessionKey HKs
32-byte header key (currently used for sending).
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_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 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).
struct GNUNET_CRYPTO_SymmetricSessionKey RK
32-byte root key which gets updated by DH ratchet.
int ratchet_allowed
True (GNUNET_YES) if we have received a message from the other peer that uses the keys from our last ...
struct GNUNET_CRYPTO_SymmetricSessionKey HKr
32-byte header key (currently used for receiving)
int ratchet_flag
True (GNUNET_YES) if we have to send a new ratchet key in next msg.
struct GNUNET_CRYPTO_SymmetricSessionKey NHKr
32-byte next header key (for receiving).
struct GNUNET_CRYPTO_SymmetricSessionKey CKs
32-byte chain keys (used for forward-secrecy) for sending messages.
struct GNUNET_CRYPTO_SymmetricSessionKey CKr
32-byte chain keys (used for forward-secrecy) for receiving messages.
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_SymmetricSessionKey NHKs
32-byte next header key (for sending), used once the ratchet advances.
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_CRYPTO_SymmetricSessionKey MK
Message key.
struct GNUNET_CRYPTO_SymmetricSessionKey HK
Header key.
struct GNUNET_TIME_Absolute timestamp
When was this key stored (for timeout).
unsigned int Kn
Key number for a given HK.
struct CadetTunnelSkippedKey * next
DLL next.
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 CadetTConnection * current_ct
Identification of the connection from which we are currently processing a message.
struct GNUNET_CRYPTO_SymmetricSessionKey d_key
Decryption ("their") key.
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_CRYPTO_SymmetricSessionKey e_key
Encryption ("our") key.
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_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.
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_CADET_ConnectionTunnelIdentifier cid
ID of the connection.
struct GNUNET_ShortHashCode hmac
MAC of the encrypted message, used to verify message integrity.
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 (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...
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
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
A 256-bit hashcode.
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.