GNUnet 0.21.1
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 "gnunet_signatures.h"
37#include "cadet_protocol.h"
43
44
45#define LOG(level, ...) GNUNET_log_from (level, "cadet-tun", __VA_ARGS__)
46
52#define MAX_UNVERIFIED_ATTEMPTS 16
53
57#define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply ( \
58 GNUNET_TIME_UNIT_SECONDS, 90)
59
64#define INITIAL_KX_RETRY_DELAY GNUNET_TIME_relative_multiply ( \
65 GNUNET_TIME_UNIT_MILLISECONDS, 250)
66
70#define MAX_SKIPPED_KEYS 64
71
76#define MAX_KEY_GAP 256
77
78
83{
88
93
98
103
108
112 unsigned int Kn;
113};
114
115
120{
127
132
137
142
147
154
161
167
175
180
185
190
196
202
206 unsigned int skipped;
207
211 uint32_t Ns;
212
216 uint32_t Nr;
217
221 uint32_t PNs;
222
227
239
252 unsigned int ratchet_counter;
253};
254
255
260{
265
270
274 struct CadetTunnel *t;
275
280
284 void *cont_cls;
285
290
296};
297
298
303{
308
314
319
324
329
338
343
348
353
358
363
368
373
378
383
388
394
399
404
409
416
421
426
431
436
443
447 unsigned int tq_len;
448
453
458};
459
460
467int
469{
470 if (0 > GNUNET_memcmp (&my_full_id,
471 other))
472 return GNUNET_YES;
473 else if (0 < GNUNET_memcmp (&my_full_id,
474 other))
475 return GNUNET_NO;
476 else
477 {
478 GNUNET_break_op (0);
479 return GNUNET_SYSERR;
480 }
481}
482
483
490static void
492{
493 struct CadetTunnel *t = ct->t;
494
496 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
497 t->connection_ready_tail,
498 ct);
499 GNUNET_assert (0 < t->num_ready_connections);
500 t->num_ready_connections--;
501 ct->is_ready = GNUNET_NO;
502 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
503 t->connection_busy_tail,
504 ct);
505 t->num_busy_connections++;
506}
507
508
516const char *
517GCT_2s (const struct CadetTunnel *t)
518{
519 static char buf[64];
520
521 if (NULL == t)
522 return "Tunnel(NULL)";
523 GNUNET_snprintf (buf,
524 sizeof(buf),
525 "Tunnel %s",
526 GNUNET_i2s (GCP_get_id (t->destination)));
527 return buf;
528}
529
530
538static const char *
540{
541 static char buf[32];
542
543 switch (es)
544 {
546 return "CADET_TUNNEL_KEY_UNINITIALIZED";
548 return "CADET_TUNNEL_KEY_AX_RECV";
550 return "CADET_TUNNEL_KEY_AX_SENT";
552 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
554 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
556 return "CADET_TUNNEL_KEY_OK";
557 }
558 GNUNET_snprintf (buf,
559 sizeof(buf),
560 "%u (UNKNOWN STATE)",
561 es);
562 return buf;
563}
564
565
572struct CadetPeer *
574{
575 return t->destination;
576}
577
578
579unsigned int
581{
582 return GNUNET_CONTAINER_multihashmap32_size (t->channels);
583}
584
585
593struct CadetChannel *
596{
597 return GNUNET_CONTAINER_multihashmap32_get (t->channels,
598 ntohl (ctn.cn));
599}
600
601
602unsigned int
604{
605 return t->num_ready_connections + t->num_busy_connections;
606}
607
608
616static struct CadetTConnection *
618{
619 struct CadetTConnection *hd = t->connection_ready_head;
620
621 GNUNET_assert ((NULL == hd) ||
622 (GNUNET_YES == hd->is_ready));
623 return hd;
624}
625
626
636{
637 return t->estate;
638}
639
640
649static void
650trigger_transmissions (void *cls);
651
652
653/* ************************************** start core crypto ***************************** */
654
655
661static void
663{
665 "Creating new ephemeral ratchet key (DHRs)\n");
667}
668
669
679static void
680t_hmac (const void *plaintext,
681 size_t size,
682 uint32_t iv,
684 struct GNUNET_ShortHashCode *hmac)
685{
686 static const char ctx[] = "cadet authentication key";
687 struct GNUNET_CRYPTO_AuthKey auth_key;
688 struct GNUNET_HashCode hash;
689
691 key,
692 &iv, sizeof(iv),
693 key, sizeof(*key),
694 ctx, sizeof(ctx),
695 NULL);
696 /* Two step: GNUNET_ShortHash is only 256 bits,
697 GNUNET_HashCode is 512, so we truncate. */
698 GNUNET_CRYPTO_hmac (&auth_key,
699 plaintext,
700 size,
701 &hash);
702 GNUNET_memcpy (hmac,
703 &hash,
704 sizeof(*hmac));
705}
706
707
716static void
718 struct GNUNET_HashCode *hash,
719 const void *source,
720 unsigned int len)
721{
722 static const char ctx[] = "axolotl HMAC-HASH";
723 struct GNUNET_CRYPTO_AuthKey auth_key;
724
726 key,
727 ctx, sizeof(ctx),
728 NULL);
729 GNUNET_CRYPTO_hmac (&auth_key,
730 source,
731 len,
732 hash);
733}
734
735
744static void
747 const void *source,
748 unsigned int len)
749{
750 static const char ctx[] = "axolotl derive key";
751 struct GNUNET_HashCode h;
752
754 &h,
755 source,
756 len);
757 GNUNET_CRYPTO_kdf (out, sizeof(*out),
758 ctx, sizeof(ctx),
759 &h, sizeof(h),
760 NULL);
761}
762
763
772static void
774 void *dst,
775 const void *src,
776 size_t size)
777{
780 size_t out_size;
781
782 ax->ratchet_counter++;
783 if ((GNUNET_YES == ax->ratchet_allowed) &&
784 ((ratchet_messages <= ax->ratchet_counter) ||
787 {
789 }
790 if (GNUNET_YES == ax->ratchet_flag)
791 {
792 /* Advance ratchet */
794 struct GNUNET_HashCode dh;
795 struct GNUNET_HashCode hmac;
796 static const char ctx[] = "axolotl ratchet";
797
798 new_ephemeral (ax);
799 ax->HKs = ax->NHKs;
800
801 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
803 &ax->DHRr,
804 &dh);
805 t_ax_hmac_hash (&ax->RK,
806 &hmac,
807 &dh,
808 sizeof(dh));
809 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
810 ctx, sizeof(ctx),
811 &hmac, sizeof(hmac),
812 NULL);
813 ax->RK = keys[0];
814 ax->NHKs = keys[1];
815 ax->CKs = keys[2];
816
817 ax->PNs = ax->Ns;
818 ax->Ns = 0;
821 ax->ratchet_counter = 0;
825 }
826
828 &MK,
829 "0",
830 1);
832 &MK,
833 NULL, 0,
834 NULL);
835
836 out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
837 size,
838 &MK,
839 &iv,
840 dst);
841 GNUNET_assert (size == out_size);
843 &ax->CKs,
844 "1",
845 1);
846}
847
848
857static void
859 void *dst,
860 const void *src,
861 size_t size)
862{
865 size_t out_size;
866
868 &MK,
869 "0",
870 1);
872 &MK,
873 NULL, 0,
874 NULL);
875 GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
876 out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
877 size,
878 &MK,
879 &iv,
880 dst);
881 GNUNET_assert (out_size == size);
883 &ax->CKr,
884 "1",
885 1);
886}
887
888
895static void
898{
900 size_t out_size;
901
903 &ax->HKs,
904 NULL, 0,
905 NULL);
906 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
907 sizeof(struct
909 &ax->HKs,
910 &iv,
911 &msg->ax_header);
912 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
913}
914
915
923static void
925 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
927{
929 size_t out_size;
930
932 &ax->HKr,
933 NULL, 0,
934 NULL);
936 sizeof(struct
938 &ax->HKr,
939 &iv,
940 &dst->ax_header.Ns);
941 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
942}
943
944
951static void
954{
956 ax->skipped_tail,
957 key);
959 ax->skipped--;
960}
961
962
973static ssize_t
975 void *dst,
976 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
977 size_t size)
978{
980 struct GNUNET_ShortHashCode *hmac;
982 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
983 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
984 size_t esize;
985 size_t res;
986 size_t len;
987 unsigned int N;
988
990 "Trying skipped keys\n");
991 hmac = &plaintext_header.hmac;
992 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
993
994 /* Find a correct Header Key */
995 valid_HK = NULL;
996 for (key = ax->skipped_head; NULL != key; key = key->next)
997 {
998 t_hmac (&src->ax_header,
999 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1000 0,
1001 &key->HK,
1002 hmac);
1003 if (0 == GNUNET_memcmp (hmac,
1004 &src->hmac))
1005 {
1006 valid_HK = &key->HK;
1007 break;
1008 }
1009 }
1010 if (NULL == key)
1011 return -1;
1012
1013 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1015 len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1016 GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1017
1018 /* Decrypt header */
1020 &key->HK,
1021 NULL, 0,
1022 NULL);
1024 sizeof(struct GNUNET_CADET_AxHeader),
1025 &key->HK,
1026 &iv,
1027 &plaintext_header.ax_header.Ns);
1028 GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1029
1030 /* Find the correct message key */
1031 N = ntohl (plaintext_header.ax_header.Ns);
1032 while ((NULL != key) &&
1033 (N != key->Kn))
1034 key = key->next;
1035 if ((NULL == key) ||
1036 (0 != GNUNET_memcmp (&key->HK,
1037 valid_HK)))
1038 return -1;
1039
1040 /* Decrypt payload */
1042 &key->MK,
1043 NULL,
1044 0,
1045 NULL);
1047 len,
1048 &key->MK,
1049 &iv,
1050 dst);
1052 key);
1053 return res;
1054}
1055
1056
1063static void
1065 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
1066{
1067 struct CadetTunnelSkippedKey *key;
1068
1070 key->timestamp = GNUNET_TIME_absolute_get ();
1071 key->Kn = ax->Nr;
1072 key->HK = ax->HKr;
1073 t_hmac_derive_key (&ax->CKr,
1074 &key->MK,
1075 "0",
1076 1);
1077 t_hmac_derive_key (&ax->CKr,
1078 &ax->CKr,
1079 "1",
1080 1);
1082 ax->skipped_tail,
1083 key);
1084 ax->skipped++;
1085 ax->Nr++;
1086}
1087
1088
1099static int
1101 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1102 uint32_t Np)
1103{
1104 int gap;
1105
1106 gap = Np - ax->Nr;
1108 "Storing skipped keys [%u, %u)\n",
1109 ax->Nr,
1110 Np);
1111 if (MAX_KEY_GAP < gap)
1112 {
1113 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1114 /* TODO: start new key exchange on return */
1115 GNUNET_break_op (0);
1117 "Got message %u, expected %u+\n",
1118 Np,
1119 ax->Nr);
1120 return GNUNET_SYSERR;
1121 }
1122 if (0 > gap)
1123 {
1124 /* Delayed message: don't store keys, flag to try old keys. */
1125 return GNUNET_SYSERR;
1126 }
1127
1128 while (ax->Nr < Np)
1130 HKr);
1131
1132 while (ax->skipped > MAX_SKIPPED_KEYS)
1134 ax->skipped_tail);
1135 return GNUNET_OK;
1136}
1137
1138
1149static ssize_t
1151 void *dst,
1152 const struct
1154 size_t size)
1155{
1156 struct GNUNET_ShortHashCode msg_hmac;
1157 struct GNUNET_HashCode hmac;
1158 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1159 uint32_t Np;
1160 uint32_t PNp;
1161 size_t esize; /* Size of encryped payload */
1162
1163 esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1164
1165 /* Try current HK */
1166 t_hmac (&src->ax_header,
1167 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1168 0, &ax->HKr,
1169 &msg_hmac);
1170 if (0 != GNUNET_memcmp (&msg_hmac,
1171 &src->hmac))
1172 {
1173 static const char ctx[] = "axolotl ratchet";
1174 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1176 struct GNUNET_HashCode dh;
1177 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1178
1179 /* Try Next HK */
1180 t_hmac (&src->ax_header,
1181 sizeof(struct GNUNET_CADET_AxHeader) + esize,
1182 0,
1183 &ax->NHKr,
1184 &msg_hmac);
1185 if (0 != GNUNET_memcmp (&msg_hmac,
1186 &src->hmac))
1187 {
1188 /* Try the skipped keys, if that fails, we're out of luck. */
1189 return try_old_ax_keys (ax,
1190 dst,
1191 src,
1192 size);
1193 }
1194 HK = ax->HKr;
1195 ax->HKr = ax->NHKr;
1196 t_h_decrypt (ax,
1197 src,
1198 &plaintext_header);
1199 Np = ntohl (plaintext_header.ax_header.Ns);
1200 PNp = ntohl (plaintext_header.ax_header.PNs);
1201 DHRp = &plaintext_header.ax_header.DHRs;
1202 store_ax_keys (ax,
1203 &HK,
1204 PNp);
1205
1206 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1208 DHRp,
1209 &dh);
1210 t_ax_hmac_hash (&ax->RK,
1211 &hmac,
1212 &dh, sizeof(dh));
1213 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1214 ctx, sizeof(ctx),
1215 &hmac, sizeof(hmac),
1216 NULL);
1217
1218 /* Commit "purported" keys */
1219 ax->RK = keys[0];
1220 ax->NHKr = keys[1];
1221 ax->CKr = keys[2];
1222 ax->DHRr = *DHRp;
1223 ax->Nr = 0;
1225 }
1226 else
1227 {
1228 t_h_decrypt (ax,
1229 src,
1230 &plaintext_header);
1231 Np = ntohl (plaintext_header.ax_header.Ns);
1232 PNp = ntohl (plaintext_header.ax_header.PNs);
1233 }
1234 if ((Np != ax->Nr) &&
1235 (GNUNET_OK != store_ax_keys (ax,
1236 &ax->HKr,
1237 Np)))
1238 {
1239 /* Try the skipped keys, if that fails, we're out of luck. */
1240 return try_old_ax_keys (ax,
1241 dst,
1242 src,
1243 size);
1244 }
1245
1246 t_ax_decrypt (ax,
1247 dst,
1248 &src[1],
1249 esize);
1250 ax->Nr = Np + 1;
1251 return esize;
1252}
1253
1254
1264static int
1266 uint32_t key,
1267 void *value)
1268{
1269 struct CadetChannel *ch = value;
1270
1272 return GNUNET_OK;
1273}
1274
1275
1283void
1286{
1287 enum CadetTunnelEState old = t->estate;
1288
1289 t->estate = state;
1291 "%s estate changed from %s to %s\n",
1292 GCT_2s (t),
1293 estate2s (old),
1294 estate2s (state));
1295
1296 if ((CADET_TUNNEL_KEY_OK != old) &&
1297 (CADET_TUNNEL_KEY_OK == t->estate))
1298 {
1299 if (NULL != t->kx_task)
1300 {
1301 GNUNET_SCHEDULER_cancel (t->kx_task);
1302 t->kx_task = NULL;
1303 }
1304 /* notify all channels that have been waiting */
1307 t);
1308 if (NULL != t->send_task)
1309 GNUNET_SCHEDULER_cancel (t->send_task);
1311 t);
1312 }
1313}
1314
1315
1324static void
1326 struct CadetTConnection *ct,
1327 struct CadetTunnelAxolotl *ax)
1328{
1329 struct CadetConnection *cc;
1330 struct GNUNET_MQ_Envelope *env;
1333
1334 if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1335 return; /* only Alice may send KX */
1336 if ((NULL == ct) ||
1337 (GNUNET_NO == ct->is_ready))
1338 ct = get_ready_connection (t);
1339 if (NULL == ct)
1340 {
1342 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1343 GCT_2s (t),
1344 estate2s (t->estate));
1345 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1346 return;
1347 }
1348 cc = ct->cc;
1351 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1352 msg->flags = htonl (flags);
1353 msg->cid = *GCC_get_id (cc);
1355 &msg->ephemeral_key);
1356#if DEBUG_KX
1357 msg->ephemeral_key_XXX = ax->kx_0;
1358 msg->private_key_XXX = *my_private_key;
1359#endif
1361 "Sending KX message to %s with ephemeral %s on CID %s\n",
1362 GCT_2s (t),
1363 GNUNET_e2s (&msg->ephemeral_key),
1364 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1366 &msg->ratchet_key);
1368 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1369 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1370 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1373 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1376 GCC_transmit (cc,
1377 env);
1379 "# KX transmitted",
1380 1,
1381 GNUNET_NO);
1382}
1383
1384
1395static void
1397 struct CadetTConnection *ct,
1398 struct CadetTunnelAxolotl *ax,
1399 int force_reply)
1400{
1401 struct CadetConnection *cc;
1402 struct GNUNET_MQ_Envelope *env;
1404 enum GNUNET_CADET_KX_Flags flags;
1405
1406 if ((NULL == ct) ||
1407 (GNUNET_NO == ct->is_ready))
1408 ct = get_ready_connection (t);
1409 if (NULL == ct)
1410 {
1412 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1413 GCT_2s (t));
1414 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1415 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1416 return;
1417 }
1418 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1419 cc = ct->cc;
1423 if (GNUNET_YES == force_reply)
1425 msg->kx.flags = htonl (flags);
1426 msg->kx.cid = *GCC_get_id (cc);
1428 &msg->kx.ephemeral_key);
1430 &msg->kx.ratchet_key);
1431#if DEBUG_KX
1432 msg->kx.ephemeral_key_XXX = ax->kx_0;
1433 msg->kx.private_key_XXX = *my_private_key;
1434 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1435#endif
1437 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1438 GCT_2s (t),
1439 GNUNET_e2s (&msg->kx.ephemeral_key),
1440 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1441
1442 /* Compute authenticator (this is the main difference to #send_kx()) */
1443 GNUNET_CRYPTO_hash (&ax->RK,
1444 sizeof(ax->RK),
1445 &msg->auth);
1446 /* Compute when to be triggered again; actual job will
1447 be scheduled via #connection_ready_cb() */
1448 t->kx_retry_delay
1449 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1450 t->next_kx_attempt
1451 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1452
1453 /* Send via cc, mark it as unready */
1455
1456 /* Update state machine, unless we are already OK */
1457 if (CADET_TUNNEL_KEY_OK != t->estate)
1460 GCC_transmit (cc,
1461 env);
1463 "# KX_AUTH transmitted",
1464 1,
1465 GNUNET_NO);
1466}
1467
1468
1474static void
1476{
1477 while (NULL != ax->skipped_head)
1479 ax->skipped_head);
1480 GNUNET_assert (0 == ax->skipped);
1483}
1484
1485
1499static int
1501 const struct GNUNET_PeerIdentity *pid,
1502 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key,
1503 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
1504{
1505 struct GNUNET_HashCode key_material[3];
1506 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1507 const char salt[] = "CADET Axolotl salt";
1508 int am_I_alice;
1509
1510 if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1511 {
1512 GNUNET_break_op (0);
1513 return GNUNET_SYSERR;
1514 }
1515 if (0 == GNUNET_memcmp (&ax->DHRr,
1516 ratchet_key))
1517 {
1519 "# Ratchet key already known",
1520 1,
1521 GNUNET_NO);
1523 "Ratchet key already known. Ignoring KX.\n");
1524 return GNUNET_NO;
1525 }
1526
1527 ax->DHRr = *ratchet_key;
1528 ax->last_ephemeral = *ephemeral_key;
1529 /* ECDH A B0 */
1530 if (GNUNET_YES == am_I_alice)
1531 {
1533 ephemeral_key, /* B0 */
1534 &key_material[0]);
1535 }
1536 else
1537 {
1538 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1539 &pid->public_key, /* A */
1540 &key_material[0]);
1541 }
1542 /* ECDH A0 B */
1543 if (GNUNET_YES == am_I_alice)
1544 {
1545 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1546 &pid->public_key, /* B */
1547 &key_material[1]);
1548 }
1549 else
1550 {
1552 ephemeral_key, /* A0 */
1553 &key_material[1]);
1554 }
1555
1556 /* ECDH A0 B0 */
1557 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1558 ephemeral_key, /* B0 or A0 */
1559 &key_material[2]);
1560 /* KDF */
1561 GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1562 salt, sizeof(salt),
1563 &key_material, sizeof(key_material),
1564 NULL);
1565
1566 if (0 == memcmp (&ax->RK,
1567 &keys[0],
1568 sizeof(ax->RK)))
1569 {
1571 "Root key already known. Ignoring KX.\n");
1573 "# Root key already known",
1574 1,
1575 GNUNET_NO);
1576 return GNUNET_NO;
1577 }
1578
1579 ax->RK = keys[0];
1580 if (GNUNET_YES == am_I_alice)
1581 {
1582 ax->HKr = keys[1];
1583 ax->NHKs = keys[2];
1584 ax->NHKr = keys[3];
1585 ax->CKr = keys[4];
1587 }
1588 else
1589 {
1590 ax->HKs = keys[1];
1591 ax->NHKr = keys[2];
1592 ax->NHKs = keys[3];
1593 ax->CKs = keys[4];
1594 ax->ratchet_flag = GNUNET_NO;
1597 ratchet_time);
1598 }
1599 return GNUNET_OK;
1600}
1601
1602
1608static void
1609retry_kx (void *cls)
1610{
1611 struct CadetTunnel *t = cls;
1612 struct CadetTunnelAxolotl *ax;
1613
1614 t->kx_task = NULL;
1616 "Trying to make KX progress on %s in state %s\n",
1617 GCT_2s (t),
1618 estate2s (t->estate));
1619 switch (t->estate)
1620 {
1621 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1622 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1623 send_kx (t,
1624 NULL,
1625 &t->ax);
1626 break;
1627
1630 /* We are responding, so only require reply
1631 if WE have a channel waiting. */
1632 if (NULL != t->unverified_ax)
1633 {
1634 /* Send AX_AUTH so we might get this one verified */
1635 ax = t->unverified_ax;
1636 }
1637 else
1638 {
1639 /* How can this be? */
1640 GNUNET_break (0);
1641 ax = &t->ax;
1642 }
1643 send_kx_auth (t,
1644 NULL,
1645 ax,
1646 (0 == GCT_count_channels (t))
1647 ? GNUNET_NO
1648 : GNUNET_YES);
1649 break;
1650
1652 /* We are responding, so only require reply
1653 if WE have a channel waiting. */
1654 if (NULL != t->unverified_ax)
1655 {
1656 /* Send AX_AUTH so we might get this one verified */
1657 ax = t->unverified_ax;
1658 }
1659 else
1660 {
1661 /* How can this be? */
1662 GNUNET_break (0);
1663 ax = &t->ax;
1664 }
1665 send_kx_auth (t,
1666 NULL,
1667 ax,
1668 (0 == GCT_count_channels (t))
1669 ? GNUNET_NO
1670 : GNUNET_YES);
1671 break;
1672
1674 /* Must have been the *other* peer asking us to
1675 respond with a KX_AUTH. */
1676 if (NULL != t->unverified_ax)
1677 {
1678 /* Sending AX_AUTH in response to AX so we might get this one verified */
1679 ax = t->unverified_ax;
1680 }
1681 else
1682 {
1683 /* Sending AX_AUTH in response to AX_AUTH */
1684 ax = &t->ax;
1685 }
1686 send_kx_auth (t,
1687 NULL,
1688 ax,
1689 GNUNET_NO);
1690 break;
1691 }
1692}
1693
1694
1695void
1698{
1699 struct CadetTunnel *t = ct->t;
1700 int ret;
1701
1703 "# KX received",
1704 1,
1705 GNUNET_NO);
1706 if (GNUNET_YES ==
1707 GCT_alice_or_betty (GCP_get_id (t->destination)))
1708 {
1709 /* Betty/Bob is not allowed to send KX! */
1710 GNUNET_break_op (0);
1711 return;
1712 }
1714 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1715 GCT_2s (t),
1716 GNUNET_e2s (&msg->ephemeral_key),
1717 GNUNET_i2s (GCP_get_id (t->destination)),
1718 GCC_2s (ct->cc));
1719#if 1
1720 if ((0 ==
1721 memcmp (&t->ax.DHRr,
1722 &msg->ratchet_key,
1723 sizeof(msg->ratchet_key))) &&
1724 (0 ==
1725 memcmp (&t->ax.last_ephemeral,
1726 &msg->ephemeral_key,
1727 sizeof(msg->ephemeral_key))))
1728
1729 {
1731 "# Duplicate KX received",
1732 1,
1733 GNUNET_NO);
1734 send_kx_auth (t,
1735 ct,
1736 &t->ax,
1737 GNUNET_NO);
1738 return;
1739 }
1740#endif
1741 /* We only keep ONE unverified KX around, so if there is an existing one,
1742 clean it up. */
1743 if (NULL != t->unverified_ax)
1744 {
1745 if ((0 ==
1746 memcmp (&t->unverified_ax->DHRr,
1747 &msg->ratchet_key,
1748 sizeof(msg->ratchet_key))) &&
1749 (0 ==
1750 memcmp (&t->unverified_ax->last_ephemeral,
1751 &msg->ephemeral_key,
1752 sizeof(msg->ephemeral_key))))
1753 {
1755 "# Duplicate unverified KX received",
1756 1,
1757 GNUNET_NO);
1758#if 1
1759 send_kx_auth (t,
1760 ct,
1761 t->unverified_ax,
1762 GNUNET_NO);
1763 return;
1764#endif
1765 }
1767 "Dropping old unverified KX state.\n");
1769 "# Unverified KX dropped for fresh KX",
1770 1,
1771 GNUNET_NO);
1772 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1773 memset (t->unverified_ax,
1774 0,
1775 sizeof(struct CadetTunnelAxolotl));
1776 }
1777 else
1778 {
1780 "Creating fresh unverified KX for %s\n",
1781 GCT_2s (t));
1783 "# Fresh KX setup",
1784 1,
1785 GNUNET_NO);
1786 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1787 }
1788 /* Set as the 'current' RK/DHRr the one we are currently using,
1789 so that the duplicate-detection logic of
1790 #update_ax_by_kx can work. */
1791 t->unverified_ax->RK = t->ax.RK;
1792 t->unverified_ax->DHRr = t->ax.DHRr;
1793 t->unverified_ax->DHRs = t->ax.DHRs;
1794 t->unverified_ax->kx_0 = t->ax.kx_0;
1795 t->unverified_attempts = 0;
1796
1797 /* Update 'ax' by the new key material */
1798 ret = update_ax_by_kx (t->unverified_ax,
1799 GCP_get_id (t->destination),
1800 &msg->ephemeral_key,
1801 &msg->ratchet_key);
1803 if (GNUNET_OK != ret)
1804 {
1806 "# Useless KX",
1807 1,
1808 GNUNET_NO);
1809 return; /* duplicate KX, nothing to do */
1810 }
1811 /* move ahead in our state machine */
1812 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1815 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1818
1819 /* KX is still not done, try again our end. */
1820 if (CADET_TUNNEL_KEY_OK != t->estate)
1821 {
1822 if (NULL != t->kx_task)
1823 GNUNET_SCHEDULER_cancel (t->kx_task);
1824 t->kx_task
1826 t);
1827 }
1828}
1829
1830
1831#if DEBUG_KX
1832static void
1833check_ee (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1834 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2)
1835{
1838 struct GNUNET_HashCode hc1;
1839 struct GNUNET_HashCode hc2;
1840
1842 &p1);
1844 &p2);
1847 &p2,
1848 &hc1));
1851 &p1,
1852 &hc2));
1853 GNUNET_break (0 == GNUNET_memcmp (&hc1,
1854 &hc2));
1855}
1856
1857
1858static void
1859check_ed (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1860 const struct GNUNET_CRYPTO_EddsaPrivateKey *e2)
1861{
1864 struct GNUNET_HashCode hc1;
1865 struct GNUNET_HashCode hc2;
1866
1868 &p1);
1870 &p2);
1873 &p2,
1874 &hc1));
1877 &p1,
1878 &hc2));
1879 GNUNET_break (0 == GNUNET_memcmp (&hc1,
1880 &hc2));
1881}
1882
1883
1884static void
1885test_crypto_bug (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1886 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2,
1887 const struct GNUNET_CRYPTO_EddsaPrivateKey *d1,
1888 const struct GNUNET_CRYPTO_EddsaPrivateKey *d2)
1889{
1890 check_ee (e1, e2);
1891 check_ed (e1, d2);
1892 check_ed (e2, d1);
1893}
1894
1895
1896#endif
1897
1898
1905void
1908{
1909 struct CadetTunnel *t = ct->t;
1910 struct CadetTunnelAxolotl ax_tmp;
1911 struct GNUNET_HashCode kx_auth;
1912 int ret;
1913
1915 "# KX_AUTH received",
1916 1,
1917 GNUNET_NO);
1918 if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1919 (CADET_TUNNEL_KEY_AX_RECV == t->estate))
1920 {
1921 /* Confusing, we got a KX_AUTH before we even send our own
1922 KX. This should not happen. We'll send our own KX ASAP anyway,
1923 so let's ignore this here. */
1924 GNUNET_break_op (0);
1925 return;
1926 }
1928 "Handling KX_AUTH message from %s with ephemeral %s\n",
1929 GCT_2s (t),
1930 GNUNET_e2s (&msg->kx.ephemeral_key));
1931 /* We do everything in ax_tmp until we've checked the authentication
1932 so we don't clobber anything we care about by accident. */
1933 ax_tmp = t->ax;
1934
1935 /* Update 'ax' by the new key material */
1936 ret = update_ax_by_kx (&ax_tmp,
1937 GCP_get_id (t->destination),
1938 &msg->kx.ephemeral_key,
1939 &msg->kx.ratchet_key);
1940 if (GNUNET_OK != ret)
1941 {
1942 if (GNUNET_NO == ret)
1944 "# redundant KX_AUTH received",
1945 1,
1946 GNUNET_NO);
1947 else
1948 GNUNET_break (0); /* connect to self!? */
1949 return;
1950 }
1951 GNUNET_CRYPTO_hash (&ax_tmp.RK,
1952 sizeof(ax_tmp.RK),
1953 &kx_auth);
1954 if (0 != GNUNET_memcmp (&kx_auth,
1955 &msg->auth))
1956 {
1957 /* This KX_AUTH is not using the latest KX/KX_AUTH data
1958 we transmitted to the sender, refuse it, try KX again. */
1960 "# KX_AUTH not using our last KX received (auth failure)",
1961 1,
1962 GNUNET_NO);
1964 "KX AUTH mismatch!\n");
1965#if DEBUG_KX
1966 {
1967 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1968
1970 &ephemeral_key);
1971 if (0 != GNUNET_memcmp (&ephemeral_key,
1972 &msg->r_ephemeral_key_XXX))
1973 {
1975 "My ephemeral is %s!\n",
1976 GNUNET_e2s (&ephemeral_key));
1978 "Response is for ephemeral %s!\n",
1979 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
1980 }
1981 else
1982 {
1983 test_crypto_bug (&ax_tmp.kx_0,
1984 &msg->kx.ephemeral_key_XXX,
1986 &msg->kx.private_key_XXX);
1987 }
1988 }
1989#endif
1990 if (NULL == t->kx_task)
1991 t->kx_task
1992 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
1993 &retry_kx,
1994 t);
1995 return;
1996 }
1997 /* Yep, we're good. */
1998 t->ax = ax_tmp;
1999 if (NULL != t->unverified_ax)
2000 {
2001 /* We got some "stale" KX before, drop that. */
2002 cleanup_ax (t->unverified_ax);
2003 GNUNET_free (t->unverified_ax);
2004 t->unverified_ax = NULL;
2005 }
2006
2007 /* move ahead in our state machine */
2008 switch (t->estate)
2009 {
2012 /* Checked above, this is impossible. */
2013 GNUNET_assert (0);
2014 break;
2015
2016 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2017 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2018 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2021 break;
2022
2024 /* Did not expect another KX_AUTH, but so what, still acceptable.
2025 Nothing to do here. */
2026 break;
2027 }
2028 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->kx.flags)))
2029 {
2030 send_kx_auth (t,
2031 NULL,
2032 &t->ax,
2033 GNUNET_NO);
2034 }
2035}
2036
2037
2038/* ************************************** end core crypto ***************************** */
2039
2040
2049{
2050#define HIGH_BIT 0x8000000
2052 uint32_t ctn;
2053 int cmp;
2054 uint32_t highbit;
2055
2056 cmp = GNUNET_memcmp (&my_full_id,
2058 if (0 < cmp)
2059 highbit = HIGH_BIT;
2060 else if (0 > cmp)
2061 highbit = 0;
2062 else
2063 GNUNET_assert (0); // loopback must never go here!
2064 ctn = ntohl (t->next_ctn.cn);
2065 while (NULL !=
2067 ctn | highbit))
2068 {
2069 ctn = ((ctn + 1) & (~HIGH_BIT));
2070 }
2071 t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2072 ret.cn = htonl (ctn | highbit);
2073 return ret;
2074}
2075
2076
2088 struct CadetChannel *ch)
2089{
2091
2092 ctn = get_next_free_ctn (t);
2093 if (NULL != t->destroy_task)
2094 {
2095 GNUNET_SCHEDULER_cancel (t->destroy_task);
2096 t->destroy_task = NULL;
2097 }
2100 ntohl (ctn.cn),
2101 ch,
2104 "Adding %s to %s with state %d\n",
2105 GCCH_2s (ch),
2106 GCT_2s (t),
2107 t->estate);
2108 switch (t->estate)
2109 {
2111 /* waiting for connection to start KX */
2112 break;
2113
2117 /* we're currently waiting for KX to complete */
2118 break;
2119
2121 /* waiting for OTHER peer to send us data,
2122 we might need to prompt more aggressively! */
2123 if (NULL == t->kx_task)
2124 t->kx_task
2125 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2126 &retry_kx,
2127 t);
2128 break;
2129
2131 /* We are ready. Tell the new channel that we are up. */
2133 break;
2134 }
2135 return ctn;
2136}
2137
2138
2145void
2147{
2148 struct CadetTunnel *t = ct->t;
2149
2150 if (GNUNET_YES == ct->is_ready)
2151 {
2152 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2153 t->connection_ready_tail,
2154 ct);
2155 t->num_ready_connections--;
2156 }
2157 else
2158 {
2159 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2160 t->connection_busy_tail,
2161 ct);
2162 t->num_busy_connections--;
2163 }
2164 GNUNET_free (ct);
2165}
2166
2167
2174static void
2176 struct CadetTConnection *ct)
2177{
2178 struct CadetTunnel *t = cls;
2179 struct CadetConnection *cc = ct->cc;
2180
2181 GNUNET_assert (ct->t == t);
2184}
2185
2186
2192static void
2194{
2195 struct CadetTunnel *t = cls;
2196 struct CadetTunnelQueueEntry *tq;
2197
2198 t->destroy_task = NULL;
2200 "Destroying idle %s\n",
2201 GCT_2s (t));
2205 t);
2206 GNUNET_assert (NULL == t->connection_ready_head);
2207 GNUNET_assert (NULL == t->connection_busy_head);
2208 while (NULL != (tq = t->tq_head))
2209 {
2210 if (NULL != tq->cont)
2211 tq->cont (tq->cont_cls,
2212 NULL);
2213 GCT_send_cancel (tq);
2214 }
2215 GCP_drop_tunnel (t->destination,
2216 t);
2218 if (NULL != t->maintain_connections_task)
2219 {
2220 GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2221 t->maintain_connections_task = NULL;
2222 }
2223 if (NULL != t->send_task)
2224 {
2225 GNUNET_SCHEDULER_cancel (t->send_task);
2226 t->send_task = NULL;
2227 }
2228 if (NULL != t->kx_task)
2229 {
2230 GNUNET_SCHEDULER_cancel (t->kx_task);
2231 t->kx_task = NULL;
2232 }
2233 GNUNET_MST_destroy (t->mst);
2234 GNUNET_MQ_destroy (t->mq);
2235 if (NULL != t->unverified_ax)
2236 {
2237 cleanup_ax (t->unverified_ax);
2238 GNUNET_free (t->unverified_ax);
2239 }
2240 cleanup_ax (&t->ax);
2241 GNUNET_assert (NULL == t->destroy_task);
2242 GNUNET_free (t);
2243}
2244
2245
2253void
2255 struct CadetChannel *ch,
2257{
2259 "Removing %s from %s\n",
2260 GCCH_2s (ch),
2261 GCT_2s (t));
2264 ntohl (ctn.cn),
2265 ch));
2266 if ((0 ==
2267 GCT_count_channels (t)) &&
2268 (NULL == t->destroy_task))
2269 {
2270 t->destroy_task
2273 t);
2274 }
2275}
2276
2277
2286static int
2288 uint32_t key,
2289 void *value)
2290{
2291 struct CadetChannel *ch = value;
2292
2294 NULL);
2295 return GNUNET_OK;
2296}
2297
2298
2304void
2306{
2310 t);
2311 GNUNET_assert (0 ==
2313 if (NULL != t->destroy_task)
2314 {
2315 GNUNET_SCHEDULER_cancel (t->destroy_task);
2316 t->destroy_task = NULL;
2317 }
2318 destroy_tunnel (t);
2319}
2320
2321
2329static void
2331 struct CadetTConnection *ct)
2332{
2333 struct CadetTunnelQueueEntry *tq;
2334
2336 tq = t->tq_head;
2337 if (NULL == tq)
2338 {
2339 /* no messages pending right now */
2341 "Not sending payload of %s on ready %s (nothing pending)\n",
2342 GCT_2s (t),
2343 GCC_2s (ct->cc));
2344 return;
2345 }
2346 /* ready to send message 'tq' on tunnel 'ct' */
2347 GNUNET_assert (t == tq->t);
2349 t->tq_tail,
2350 tq);
2351 if (NULL != tq->cid)
2352 *tq->cid = *GCC_get_id (ct->cc);
2355 "Sending payload of %s on %s\n",
2356 GCT_2s (t),
2357 GCC_2s (ct->cc));
2358 GCC_transmit (ct->cc,
2359 tq->env);
2360 if (NULL != tq->cont)
2361 tq->cont (tq->cont_cls,
2362 GCC_get_id (ct->cc));
2363 GNUNET_free (tq);
2364}
2365
2366
2375static void
2377 int is_ready)
2378{
2379 struct CadetTConnection *ct = cls;
2380 struct CadetTunnel *t = ct->t;
2381
2382 if (GNUNET_NO == is_ready)
2383 {
2385 "%s no longer ready for %s\n",
2386 GCC_2s (ct->cc),
2387 GCT_2s (t));
2389 return;
2390 }
2392 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2393 t->connection_busy_tail,
2394 ct);
2395 GNUNET_assert (0 < t->num_busy_connections);
2396 t->num_busy_connections--;
2397 ct->is_ready = GNUNET_YES;
2398 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2399 t->connection_ready_tail,
2400 ct);
2401 t->num_ready_connections++;
2402
2404 "%s now ready for %s in state %s\n",
2405 GCC_2s (ct->cc),
2406 GCT_2s (t),
2407 estate2s (t->estate));
2408 switch (t->estate)
2409 {
2412 "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2413 GCT_2s (t),
2414 (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2415 t->next_kx_attempt).rel_value_us);
2416 /* Do not begin KX if WE have no channels waiting! */
2418 t->next_kx_attempt).rel_value_us)
2419 return; /* wait for timeout before retrying */
2420 /* We are uninitialized, just transmit immediately,
2421 without undue delay. */
2422
2424 "Why for %s \n",
2425 GCT_2s (t));
2426
2427 if (NULL != t->kx_task)
2428 {
2429 GNUNET_SCHEDULER_cancel (t->kx_task);
2430 t->kx_task = NULL;
2431 }
2432 send_kx (t,
2433 ct,
2434 &t->ax);
2435 if ((0 ==
2436 GCT_count_channels (t)) &&
2437 (NULL == t->destroy_task))
2438 {
2439 t->destroy_task
2442 t);
2443 }
2444 break;
2445
2450 /* we're currently waiting for KX to complete, schedule job */
2451 if (NULL == t->kx_task)
2452 t->kx_task
2453 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2454 &retry_kx,
2455 t);
2456 break;
2457
2459 if (GNUNET_YES == t->kx_auth_requested)
2460 {
2462 t->next_kx_attempt).rel_value_us)
2463 return; /* wait for timeout */
2464 if (NULL != t->kx_task)
2465 {
2466 GNUNET_SCHEDULER_cancel (t->kx_task);
2467 t->kx_task = NULL;
2468 }
2469 send_kx_auth (t,
2470 ct,
2471 &t->ax,
2472 GNUNET_NO);
2473 return;
2474 }
2476 ct);
2477 break;
2478 }
2479}
2480
2481
2490static void
2492{
2493 struct CadetTunnel *t = cls;
2494 struct CadetTConnection *ct;
2495
2496 t->send_task = NULL;
2497 if (NULL == t->tq_head)
2498 return; /* no messages pending right now */
2499 ct = get_ready_connection (t);
2500 if (NULL == ct)
2501 return; /* no connections ready */
2503 ct);
2504}
2505
2506
2512{
2516 unsigned int min_length;
2517
2521 unsigned int max_length;
2522
2527
2532
2537
2543
2548
2553};
2554
2555
2563static void
2565 struct CadetTConnection *ct)
2566{
2567 struct EvaluationSummary *es = cls;
2568 struct CadetConnection *cc = ct->cc;
2569 unsigned int ct_length;
2570 struct CadetPeerPath *ps;
2571 const struct CadetConnectionMetrics *metrics;
2572 GNUNET_CONTAINER_HeapCostType ct_desirability;
2573 struct GNUNET_TIME_Relative uptime;
2574 struct GNUNET_TIME_Relative last_use;
2575 double score;
2576 double success_rate;
2577
2578 ps = GCC_get_path (cc,
2579 &ct_length);
2581 "Evaluating path %s of existing %s\n",
2582 GCPP_2s (ps),
2583 GCC_2s (cc));
2584 if (ps == es->path)
2585 {
2587 "Ignoring duplicate path %s.\n",
2588 GCPP_2s (es->path));
2589 es->duplicate = GNUNET_YES;
2590 return;
2591 }
2592 if (NULL != es->path)
2593 {
2594 int duplicate = GNUNET_YES;
2595
2596 for (unsigned int i = 0; i < ct_length; i++)
2597 {
2600 i) !=
2602 i))
2603 {
2604 duplicate = GNUNET_NO;
2605 break;
2606 }
2607 }
2608 if (GNUNET_YES == duplicate)
2609 {
2611 "Ignoring overlapping path %s.\n",
2612 GCPP_2s (es->path));
2613 es->duplicate = GNUNET_YES;
2614 return;
2615 }
2616 else
2617 {
2619 "Known path %s differs from proposed path\n",
2620 GCPP_2s (ps));
2621 }
2622 }
2623
2624 ct_desirability = GCPP_get_desirability (ps);
2625 metrics = GCC_get_metrics (cc);
2626 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2627 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2628 /* We add 1.0 here to avoid division by zero. */
2629 success_rate = (metrics->num_acked_transmissions + 1.0)
2630 / (metrics->num_successes + 1.0);
2631 score
2632 = ct_desirability
2633 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2634 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2635 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2636 score *= success_rate; /* weigh overall by success rate */
2637
2638 if ((NULL == es->worst) ||
2639 (score < es->worst_score))
2640 {
2641 es->worst = ct;
2642 es->worst_score = score;
2643 }
2644 es->min_length = GNUNET_MIN (es->min_length,
2645 ct_length);
2646 es->max_length = GNUNET_MAX (es->max_length,
2647 ct_length);
2648 es->min_desire = GNUNET_MIN (es->min_desire,
2649 ct_desirability);
2650 es->max_desire = GNUNET_MAX (es->max_desire,
2651 ct_desirability);
2652}
2653
2654
2664static int
2666 struct CadetPeerPath *path,
2667 unsigned int off)
2668{
2669 struct CadetTunnel *t = cls;
2670 struct EvaluationSummary es;
2671 struct CadetTConnection *ct;
2672
2673 GNUNET_assert (off < GCPP_get_length (path));
2675 off) == t->destination);
2676 es.min_length = UINT_MAX;
2677 es.max_length = 0;
2678 es.max_desire = 0;
2679 es.min_desire = UINT64_MAX;
2680 es.path = path;
2681 es.duplicate = GNUNET_NO;
2682 es.worst = NULL;
2683
2684 /* Compute evaluation summary over existing connections. */
2686 "Evaluating proposed path %s for target %s\n",
2687 GCPP_2s (path),
2688 GCT_2s (t));
2689 /* FIXME: suspect this does not ACTUALLY iterate
2690 over all existing paths, otherwise dup detection
2691 should work!!! */
2694 &es);
2695 if (GNUNET_YES == es.duplicate)
2696 return GNUNET_YES;
2697
2698 /* FIXME: not sure we should really just count
2699 'num_connections' here, as they may all have
2700 consistently failed to connect. */
2701
2702 /* We iterate by increasing path length; if we have enough paths and
2703 this one is more than twice as long than what we are currently
2704 using, then ignore all of these super-long ones! */
2706 (es.min_length * 2 < off) &&
2707 (es.max_length < off))
2708 {
2710 "Ignoring paths of length %u, they are way too long.\n",
2711 es.min_length * 2);
2712 return GNUNET_NO;
2713 }
2714 /* If we have enough paths and this one looks no better, ignore it. */
2716 (es.min_length < GCPP_get_length (path)) &&
2717 (es.min_desire > GCPP_get_desirability (path)) &&
2718 (es.max_length < off))
2719 {
2721 "Ignoring path (%u/%llu) to %s, got something better already.\n",
2722 GCPP_get_length (path),
2723 (unsigned long long) GCPP_get_desirability (path),
2724 GCP_2s (t->destination));
2725 return GNUNET_YES;
2726 }
2727
2728 /* Path is interesting (better by some metric, or we don't have
2729 enough paths yet). */
2730 ct = GNUNET_new (struct CadetTConnection);
2732 ct->t = t;
2733 ct->cc = GCC_create (t->destination,
2734 path,
2735 off,
2736 ct,
2738 ct);
2739
2740 /* FIXME: schedule job to kill connection (and path?) if it takes
2741 too long to get ready! (And track performance data on how long
2742 other connections took with the tunnel!)
2743 => Note: to be done within 'connection'-logic! */
2744 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2745 t->connection_busy_tail,
2746 ct);
2747 t->num_busy_connections++;
2749 "Found interesting path %s for %s, created %s\n",
2750 GCPP_2s (path),
2751 GCT_2s (t),
2752 GCC_2s (ct->cc));
2753 return GNUNET_YES;
2754}
2755
2756
2770static void
2772{
2773 struct CadetTunnel *t = cls;
2774 struct GNUNET_TIME_Relative delay;
2775 struct EvaluationSummary es;
2776
2777 t->maintain_connections_task = NULL;
2779 "Performing connection maintenance for %s.\n",
2780 GCT_2s (t));
2781
2782 es.min_length = UINT_MAX;
2783 es.max_length = 0;
2784 es.max_desire = 0;
2785 es.min_desire = UINT64_MAX;
2786 es.path = NULL;
2787 es.worst = NULL;
2788 es.duplicate = GNUNET_NO;
2791 &es);
2792 if ((NULL != es.worst) &&
2794 {
2795 /* Clear out worst-performing connection 'es.worst'. */
2797 es.worst);
2798 }
2799
2800 /* Consider additional paths */
2801 (void) GCP_iterate_paths (t->destination,
2803 t);
2804
2805 /* FIXME: calculate when to try again based on how well we are doing;
2806 in particular, if we have to few connections, we might be able
2807 to do without this (as PATHS should tell us whenever a new path
2808 is available instantly; however, need to make sure this job is
2809 restarted after that happens).
2810 Furthermore, if the paths we do know are in a reasonably narrow
2811 quality band and are plentyful, we might also consider us stabilized
2812 and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2813 t->maintain_connections_task
2816 t);
2817}
2818
2819
2820void
2822 struct CadetPeerPath *p,
2823 unsigned int off)
2824{
2826 "Considering %s for %s (offset %u)\n",
2827 GCPP_2s (p),
2828 GCT_2s (t),
2829 off);
2830 (void) consider_path_cb (t,
2831 p,
2832 off);
2833}
2834
2835
2842static void
2844 const struct GNUNET_MessageHeader *msg)
2845{
2846 struct CadetTunnel *t = cls;
2847
2849 "Received KEEPALIVE on %s\n",
2850 GCT_2s (t));
2852 "# keepalives received",
2853 1,
2854 GNUNET_NO);
2855}
2856
2857
2865static int
2868{
2869 return GNUNET_OK;
2870}
2871
2872
2880static void
2883{
2884 struct CadetTunnel *t = cls;
2885 struct CadetChannel *ch;
2886
2887 ch = lookup_channel (t,
2888 msg->ctn);
2889 if (NULL == ch)
2890 {
2891 /* We don't know about such a channel, might have been destroyed on our
2892 end in the meantime, or never existed. Send back a DESTROY. */
2894 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
2895 (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
2896 ntohl (msg->ctn.cn));
2898 msg->ctn);
2899 return;
2900 }
2902 GCC_get_id (t->current_ct->cc),
2903 msg);
2904}
2905
2906
2915static void
2917 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
2918{
2919 struct CadetTunnel *t = cls;
2920 struct CadetChannel *ch;
2921
2922 ch = lookup_channel (t,
2923 ack->ctn);
2924 if (NULL == ch)
2925 {
2926 /* We don't know about such a channel, might have been destroyed on our
2927 end in the meantime, or never existed. Send back a DESTROY. */
2929 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
2930 ntohl (ack->ctn.cn));
2932 ack->ctn);
2933 return;
2934 }
2936 GCC_get_id (t->current_ct->cc),
2937 ack);
2938}
2939
2940
2948static void
2950 const struct
2952{
2953 struct CadetTunnel *t = cls;
2954 struct CadetChannel *ch;
2955
2957 ntohl (copen->ctn.cn));
2958 if (NULL != ch)
2959 {
2961 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
2962 GNUNET_h2s (&copen->h_port),
2963 GCT_2s (t),
2964 GCCH_2s (ch));
2966 GCC_get_id (t->current_ct->cc));
2967 return;
2968 }
2970 "Received CHANNEL_OPEN on h_port %s from %s\n",
2971 GNUNET_h2s (&copen->h_port),
2972 GCT_2s (t));
2974 copen->ctn,
2975 &copen->h_port,
2976 ntohl (copen->opt));
2977 if (NULL != t->destroy_task)
2978 {
2979 GNUNET_SCHEDULER_cancel (t->destroy_task);
2980 t->destroy_task = NULL;
2981 }
2984 ntohl (copen->ctn.cn),
2985 ch,
2987}
2988
2989
2996void
2999{
3001
3003 "Sending DESTROY message for channel ID %u\n",
3004 ntohl (ctn.cn));
3005 msg.header.size = htons (sizeof(msg));
3007 msg.reserved = htonl (0);
3008 msg.ctn = ctn;
3009 GCT_send (t,
3010 &msg.header,
3011 NULL,
3012 NULL,
3013 &ctn);
3014}
3015
3016
3025static void
3027 const struct
3029{
3030 struct CadetTunnel *t = cls;
3031 struct CadetChannel *ch;
3032
3033 ch = lookup_channel (t,
3034 cm->ctn);
3035 if (NULL == ch)
3036 {
3037 /* We don't know about such a channel, might have been destroyed on our
3038 end in the meantime, or never existed. Send back a DESTROY. */
3040 "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3041 ntohl (cm->ctn.cn));
3043 cm->ctn);
3044 return;
3045 }
3047 "Received channel OPEN_ACK on channel %s from %s\n",
3048 GCCH_2s (ch),
3049 GCT_2s (t));
3051 GCC_get_id (t->current_ct->cc),
3052 &cm->port);
3053}
3054
3055
3063static void
3065 const struct
3067{
3068 struct CadetTunnel *t = cls;
3069 struct CadetChannel *ch;
3070
3071 ch = lookup_channel (t,
3072 cm->ctn);
3073 if (NULL == ch)
3074 {
3075 /* We don't know about such a channel, might have been destroyed on our
3076 end in the meantime, or never existed. */
3078 "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3079 ntohl (cm->ctn.cn));
3080 return;
3081 }
3083 "Received channel DESTROY on %s from %s\n",
3084 GCCH_2s (ch),
3085 GCT_2s (t));
3087 GCC_get_id (t->current_ct->cc));
3088}
3089
3090
3101static int
3103 const struct GNUNET_MessageHeader *msg)
3104{
3105 struct CadetTunnel *t = cls;
3106
3107 GNUNET_assert (NULL != t->current_ct);
3109 msg);
3110 return GNUNET_OK;
3111}
3112
3113
3121static void
3123 enum GNUNET_MQ_Error error)
3124{
3125 GNUNET_break_op (0);
3126}
3127
3128
3136struct CadetTunnel *
3138{
3139 struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3141 GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3143 struct GNUNET_MessageHeader,
3144 t),
3145 GNUNET_MQ_hd_var_size (plaintext_data,
3148 t),
3149 GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3152 t),
3153 GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3156 t),
3157 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3160 t),
3161 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3164 t),
3166 };
3167
3168 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3169 new_ephemeral (&t->ax);
3171 t->destination = destination;
3173 t->maintain_connections_task
3175 t);
3176 t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3177 NULL,
3178 NULL,
3179 NULL,
3180 handlers,
3182 t);
3184 t);
3185 return t;
3186}
3187
3188
3189int
3191 const struct
3193 struct CadetPeerPath *path)
3194{
3195 struct CadetTConnection *ct;
3196
3197 ct = GNUNET_new (struct CadetTConnection);
3199 ct->t = t;
3200 ct->cc = GCC_create_inbound (t->destination,
3201 path,
3202 ct,
3203 cid,
3205 ct);
3206 if (NULL == ct->cc)
3207 {
3209 "%s refused inbound %s (duplicate)\n",
3210 GCT_2s (t),
3211 GCC_2s (ct->cc));
3212 GNUNET_free (ct);
3213 return GNUNET_SYSERR;
3214 }
3215 /* FIXME: schedule job to kill connection (and path?) if it takes
3216 too long to get ready! (And track performance data on how long
3217 other connections took with the tunnel!)
3218 => Note: to be done within 'connection'-logic! */
3219 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3220 t->connection_busy_tail,
3221 ct);
3222 t->num_busy_connections++;
3224 "%s has new %s\n",
3225 GCT_2s (t),
3226 GCC_2s (ct->cc));
3227 return GNUNET_OK;
3228}
3229
3230
3237void
3240{
3241 struct CadetTunnel *t = ct->t;
3242 uint16_t size = ntohs (msg->header.size);
3243 char cbuf[size] GNUNET_ALIGN;
3244 ssize_t decrypted_size;
3245
3247 "%s received %u bytes of encrypted data in state %d\n",
3248 GCT_2s (t),
3249 (unsigned int) size,
3250 t->estate);
3251
3252 switch (t->estate)
3253 {
3256 /* We did not even SEND our KX, how can the other peer
3257 send us encrypted data? Must have been that we went
3258 down and the other peer still things we are up.
3259 Let's send it KX back. */
3261 "# received encrypted without any KX",
3262 1,
3263 GNUNET_NO);
3264 if (NULL != t->kx_task)
3265 {
3266 GNUNET_SCHEDULER_cancel (t->kx_task);
3267 t->kx_task = NULL;
3268 }
3269 send_kx (t,
3270 ct,
3271 &t->ax);
3272 return;
3273
3275 /* We send KX, and other peer send KX to us at the same time.
3276 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3278 "# received encrypted without KX_AUTH",
3279 1,
3280 GNUNET_NO);
3281 if (NULL != t->kx_task)
3282 {
3283 GNUNET_SCHEDULER_cancel (t->kx_task);
3284 t->kx_task = NULL;
3285 }
3286 send_kx_auth (t,
3287 ct,
3288 &t->ax,
3289 GNUNET_YES);
3290 return;
3291
3293 /* We did not get the KX of the other peer, but that
3294 might have been lost. Send our KX again immediately. */
3296 "# received encrypted without KX",
3297 1,
3298 GNUNET_NO);
3299 if (NULL != t->kx_task)
3300 {
3301 GNUNET_SCHEDULER_cancel (t->kx_task);
3302 t->kx_task = NULL;
3303 }
3304 send_kx (t,
3305 ct,
3306 &t->ax);
3307 return;
3308
3310 /* Great, first payload, we might graduate to OK! */
3312 /* We are up and running, all good. */
3313 break;
3314 }
3315
3316 decrypted_size = -1;
3317 if (CADET_TUNNEL_KEY_OK == t->estate)
3318 {
3319 /* We have well-established key material available,
3320 try that. (This is the common case.) */
3321 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3322 cbuf,
3323 msg,
3324 size);
3325 }
3326
3327 if ((-1 == decrypted_size) &&
3328 (NULL != t->unverified_ax))
3329 {
3330 /* We have un-authenticated KX material available. We should try
3331 this as a back-up option, in case the sender crashed and
3332 switched keys. */
3333 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3334 cbuf,
3335 msg,
3336 size);
3337 if (-1 != decrypted_size)
3338 {
3339 /* It worked! Treat this as authentication of the AX data! */
3340 cleanup_ax (&t->ax);
3341 t->ax = *t->unverified_ax;
3342 GNUNET_free (t->unverified_ax);
3343 t->unverified_ax = NULL;
3344 }
3345 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3346 {
3347 /* First time it worked, move tunnel into production! */
3350 if (NULL != t->send_task)
3351 GNUNET_SCHEDULER_cancel (t->send_task);
3353 t);
3354 }
3355 }
3356 if (NULL != t->unverified_ax)
3357 {
3358 /* We had unverified KX material that was useless; so increment
3359 counter and eventually move to ignore it. Note that we even do
3360 this increment if we successfully decrypted with the old KX
3361 material and thus didn't even both with the new one. This is
3362 the ideal case, as a malicious injection of bogus KX data
3363 basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3365 "Failed to decrypt message with unverified KX data %u times\n",
3366 t->unverified_attempts);
3367 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3368 {
3369 cleanup_ax (t->unverified_ax);
3370 GNUNET_free (t->unverified_ax);
3371 t->unverified_ax = NULL;
3372 }
3373 }
3374
3375 if (-1 == decrypted_size)
3376 {
3377 /* Decryption failed for good, complain. */
3379 "%s failed to decrypt and validate encrypted data, retrying KX\n",
3380 GCT_2s (t));
3382 "# unable to decrypt",
3383 1,
3384 GNUNET_NO);
3385 if (NULL != t->kx_task)
3386 {
3387 GNUNET_SCHEDULER_cancel (t->kx_task);
3388 t->kx_task = NULL;
3389 }
3390 send_kx (t,
3391 ct,
3392 &t->ax);
3393 return;
3394 }
3396 "# decrypted bytes",
3397 decrypted_size,
3398 GNUNET_NO);
3399
3400 /* The MST will ultimately call #handle_decrypted() on each message. */
3401 t->current_ct = ct;
3404 cbuf,
3405 decrypted_size,
3406 GNUNET_YES,
3407 GNUNET_NO));
3408 t->current_ct = NULL;
3409}
3410
3411
3412struct CadetTunnelQueueEntry *
3414 const struct GNUNET_MessageHeader *message,
3416 void *cont_cls,
3418{
3419 struct CadetTunnelQueueEntry *tq;
3420 uint16_t payload_size;
3421 struct GNUNET_MQ_Envelope *env;
3423 struct CadetChannel *ch;
3424
3425 if (NULL != ctn)
3426 {
3427 ch = lookup_channel (t,
3428 *ctn);
3429 if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3430 {
3431 GNUNET_break (0);
3432 return NULL;
3433 }
3434 }
3435
3436 if (CADET_TUNNEL_KEY_OK != t->estate)
3437 {
3438 GNUNET_break (0);
3439 return NULL;
3440 }
3441 payload_size = ntohs (message->size);
3443 "Encrypting %u bytes for %s\n",
3444 (unsigned int) payload_size,
3445 GCT_2s (t));
3446 env = GNUNET_MQ_msg_extra (ax_msg,
3447 payload_size,
3449 t_ax_encrypt (&t->ax,
3450 &ax_msg[1],
3451 message,
3452 payload_size);
3454 "# encrypted bytes",
3455 payload_size,
3456 GNUNET_NO);
3457 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3458 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3459 /* FIXME: we should do this once, not once per message;
3460 this is a point multiplication, and DHRs does not
3461 change all the time. */
3463 &ax_msg->ax_header.DHRs);
3464 t_h_encrypt (&t->ax,
3465 ax_msg);
3466 t_hmac (&ax_msg->ax_header,
3467 sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3468 0,
3469 &t->ax.HKs,
3470 &ax_msg->hmac);
3471
3472 tq = GNUNET_malloc (sizeof(*tq));
3473 tq->t = t;
3474 tq->env = env;
3475 tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3476 tq->cont = cont;
3477 tq->cont_cls = cont_cls;
3479 t->tq_tail,
3480 tq);
3481 if (NULL != t->send_task)
3482 GNUNET_SCHEDULER_cancel (t->send_task);
3483 t->send_task
3485 t);
3486 return tq;
3487}
3488
3489
3490void
3492{
3493 struct CadetTunnel *t = tq->t;
3494
3496 t->tq_tail,
3497 tq);
3498 GNUNET_MQ_discard (tq->env);
3499 GNUNET_free (tq);
3500}
3501
3502
3510void
3513 void *iter_cls)
3514{
3515 struct CadetTConnection *n;
3516
3517 for (struct CadetTConnection *ct = t->connection_ready_head;
3518 NULL != ct;
3519 ct = n)
3520 {
3521 n = ct->next;
3522 iter (iter_cls,
3523 ct);
3524 }
3525 for (struct CadetTConnection *ct = t->connection_busy_head;
3526 NULL != ct;
3527 ct = n)
3528 {
3529 n = ct->next;
3530 iter (iter_cls,
3531 ct);
3532 }
3533}
3534
3535
3540{
3545
3550};
3551
3552
3561static int
3563 uint32_t key,
3564 void *value)
3565{
3566 struct ChanIterCls *ctx = cls;
3567 struct CadetChannel *ch = value;
3568
3569 ctx->iter (ctx->iter_cls,
3570 ch);
3571 return GNUNET_OK;
3572}
3573
3574
3582void
3585 void *iter_cls)
3586{
3587 struct ChanIterCls ctx;
3588
3589 ctx.iter = iter;
3590 ctx.iter_cls = iter_cls;
3593 &ctx);
3594}
3595
3596
3605static int
3606debug_channel (void *cls,
3607 uint32_t key,
3608 void *value)
3609{
3610 const enum GNUNET_ErrorType *level = cls;
3611 struct CadetChannel *ch = value;
3612
3613 GCCH_debug (ch, *level);
3614 return GNUNET_OK;
3615}
3616
3617
3618#define LOG2(level, ...) GNUNET_log_from_nocheck (level, "cadet-tun", \
3619 __VA_ARGS__)
3620
3621
3628void
3629GCT_debug (const struct CadetTunnel *t,
3630 enum GNUNET_ErrorType level)
3631{
3632#if ! defined(GNUNET_CULL_LOGGING)
3633 struct CadetTConnection *iter_c;
3634 int do_log;
3635
3637 "cadet-tun",
3638 __FILE__, __FUNCTION__, __LINE__);
3639 if (0 == do_log)
3640 return;
3641
3642 LOG2 (level,
3643 "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3644 GCT_2s (t),
3645 estate2s (t->estate),
3646 t->tq_len,
3648 LOG2 (level,
3649 "TTT channels:\n");
3652 &level);
3653 LOG2 (level,
3654 "TTT connections:\n");
3655 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3656 GCC_debug (iter_c->cc,
3657 level);
3658 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3659 GCC_debug (iter_c->cc,
3660 level);
3661
3662 LOG2 (level,
3663 "TTT TUNNEL END\n");
3664#endif
3665}
3666
3667
3668/* 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:99
static int ret
Final status code.
Definition: gnunet-arm.c:94
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
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
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
Definition: gnunet-hello.c:101
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
Definition: gnunet-hello.c:96
static GstElement * source
Appsrc instance into which we write data for the pipeline.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
enum State state
current state of profiling
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
Definition: gnunet-scrypt.c:34
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
struct GNUNET_TIME_Relative ratchet_time
How long until we trigger a ratched advance due to time.
void GCCH_handle_channel_plaintext_data_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
We got an acknowledgement for payload data for a channel.
struct CadetChannel * GCCH_channel_incoming_new(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn, const struct GNUNET_HashCode *h_port, uint32_t options)
Create a new channel based on a request coming in over the network.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
void GCCH_handle_duplicate_open(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
We got a GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for this channel.
void GCCH_tunnel_up(struct CadetChannel *ch)
Function called once and only once after a channel was bound to its tunnel via GCT_add_channel() is r...
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
void GCCH_handle_channel_plaintext_data(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
We got payload data for a channel.
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.
void GCCH_handle_channel_open_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_HashCode *port)
We got an acknowledgement for the creation of the channel (the port is open on the other side).
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
GNUnet CADET service with encryption.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
struct CadetConnection * GCC_create_inbound(struct CadetPeer *destination, struct CadetPeerPath *path, struct CadetTConnection *ct, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_destroy_without_tunnel(struct CadetConnection *cc)
Destroy a connection, called if the tunnel association with the connection was already broken,...
struct CadetConnection * GCC_create(struct CadetPeer *destination, struct CadetPeerPath *path, unsigned int off, struct CadetTConnection *ct, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
void GCC_transmit(struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
Transmit message msg via connection cc.
void GCC_debug(struct CadetConnection *cc, enum GNUNET_ErrorType level)
Log connection info.
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
const struct GNUNET_CADET_ConnectionTunnelIdentifier * GCC_get_id(struct CadetConnection *cc)
Obtain unique ID for the connection.
A connection is a live end-to-end messaging mechanism where the peers are identified by a path and kn...
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
unsigned int GCPP_get_length(struct CadetPeerPath *path)
Return the length of the path.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping the path.
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
void GCP_drop_tunnel(struct CadetPeer *cp, struct CadetTunnel *t)
The tunnel to the given peer no longer exists, remove it from our data structures,...
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
unsigned int GCP_iterate_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer.
Information we track per peer.
static void 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 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...
struct CadetChannel * lookup_channel(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Lookup a channel by its ctn.
#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.
static struct GNUNET_SCHEDULER_Task * t
Main task.
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:714
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:436
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:198
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:727
void GNUNET_CRYPTO_symmetric_derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len,...)
Derive an IV.
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:777
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:415
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:214
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)
Definition: crypto_hash.c:330
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:70
void GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len,...)
Derive an authentication key.
Definition: crypto_hash.c:267
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.
#define GNUNET_MAX(a, b)
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MIN(a, b)
@ 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:465
#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.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
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:683
#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:1255
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
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:1305
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:1278
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:436
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:405
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:450
#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?
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?
void * cont_cls
Closure for cont.
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 identfies it within its tunnel, in network byte ord...
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.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
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:136
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.