GNUnet 0.21.2
gnunet-communicator-udp.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 2018, 2019 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 */
20
40#include "platform.h"
41#include "gnunet_common.h"
42#include "gnunet_util_lib.h"
43#include "gnunet_protocols.h"
44#include "gnunet_signatures.h"
45#include "gnunet_constants.h"
46#include "gnunet_nat_service.h"
50
54#define DEFAULT_REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
55
59#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
60
64#define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
65
69#define INTERFACE_SCAN_FREQUENCY \
70 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
71
76#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
77
78#define WORKING_QUEUE_INTERVALL \
79 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)
80
84#define AES_KEY_SIZE (256 / 8)
85
89#define AES_IV_SIZE (96 / 8)
90
94#define GCM_TAG_SIZE (128 / 8)
95
96#define GENERATE_AT_ONCE 64
97
107#define KCN_THRESHOLD 96
108
115#define KCN_TARGET 128
116
126#define MAX_SQN_DELTA 160
127
137#define MAX_SECRETS 256
138
143#define DEFAULT_REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
144
149#define COMMUNICATOR_ADDRESS_PREFIX "udp"
150
154#define COMMUNICATOR_CONFIG_SECTION "communicator-udp"
155
157
158
165{
170
175
180
185
191};
192
193
199{
204
210
211};
212
213
219{
224
229
235
236 /* followed by messages */
237
238 /* padding may follow actual messages */
239};
240
241
246struct UDPAck
247{
252
258
263};
264
265
275{
280
285
290};
291
292
300{
305
311};
312
313
318struct UDPBox
319{
328
337
338};
339
344{
349
354};
355
357
361struct SharedSecret;
362
363
369{
374
379
388
393
398};
399
400
405struct SenderAddress;
406
411struct ReceiverAddress;
412
417{
422
427
432
437
442
447
452
457
463
470
474 unsigned int active_kce_count;
475
480
485
490};
491
492
498{
503
508
513
518
522 struct sockaddr *address;
523
527 socklen_t address_len;
528
533
538
542 unsigned int num_secrets;
543
548 unsigned int acks_available;
549
554
559
564
569
574};
575
576
582{
587
592
597
602
607
612
618
622 struct sockaddr *address;
623
627 socklen_t address_len;
628
633
638
643
648
653
658
662 size_t kx_mtu;
663
667 size_t d_mtu;
668
672 unsigned int num_secrets;
673
678 unsigned int acks_available;
679
684
689};
690
695{
700
705
710
714 struct sockaddr *sa;
715
719 struct sockaddr *ba;
720
725
730 struct ipv6_mreq mcreq;
731
735 socklen_t salen;
736
740 int found;
741};
742
747
751static unsigned long long rekey_max_bytes;
752
757
762
767
772
777
782
787
792
797
802
807
812
817
821static int have_v6_socket;
822
827
832
837
841static const struct GNUNET_CONFIGURATION_Handle *cfg;
842
847
852
856static struct GNUNET_NAT_Handle *nat;
857
861static uint16_t my_port;
862
866static int disable_v6;
867
868static void
871{
873 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
874 key.eddsa_key = *edpk;
876}
877
878
879static void
882{
884 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
885 key.eddsa_key = *edpk;
887}
888
889
895static void
897{
898 if (AF_INET6 == bi->sa->sa_family)
899 {
900 /* Leave the multicast group */
902 IPPROTO_IPV6,
903 IPV6_LEAVE_GROUP,
904 &bi->mcreq,
905 sizeof(bi->mcreq)))
906 {
908 }
909 }
912 GNUNET_free (bi->sa);
913 GNUNET_free (bi->ba);
914 GNUNET_free (bi);
915}
916
917
918static int
919secret_destroy (struct SharedSecret *ss);
920
926static void
928{
929 struct SharedSecret *ss;
930 receiver->receiver_destroy_called = GNUNET_YES;
931
933 "Disconnecting receiver for peer `%s'\n",
934 GNUNET_i2s (&receiver->target));
935 if (NULL != receiver->kx_qh)
936 {
938 receiver->kx_qh = NULL;
939 receiver->kx_mq = NULL;
940 }
941 if (NULL != receiver->d_qh)
942 {
944 receiver->d_qh = NULL;
945 }
946 else if (NULL != receiver->d_mq)
947 {
949 receiver->d_mq = NULL;
950 }
953 &receiver->key,
954 receiver));
957 "# receivers active",
959 GNUNET_NO);
960 while (NULL != (ss = receiver->ss_head))
961 {
962 secret_destroy (ss);
963 }
964 GNUNET_free (receiver->address);
965 GNUNET_free (receiver->foreign_addr);
967}
968
969
975static void
977{
978 struct SharedSecret *ss = kce->ss;
979
980 ss->active_kce_count--;
983 &kce->kid,
984 kce));
985 GNUNET_free (kce);
986}
987
988
996static void
997get_kid (const struct GNUNET_ShortHashCode *msec,
998 uint32_t serial,
999 struct GNUNET_ShortHashCode *kid)
1000{
1001 uint32_t sid = htonl (serial);
1002 struct GNUNET_ShortHashCode prk;
1004 &sid, sizeof (sid),
1005 msec, sizeof (*msec));
1006
1008 sizeof(*kid),
1009 &prk,
1010 "gnunet-communicator-udp-kid",
1011 strlen ("gnunet-communicator-udp-kid"),
1012 NULL,
1013 0);
1014}
1015
1016
1023static void
1024kce_generate (struct SharedSecret *ss, uint32_t seq)
1025{
1026 struct KeyCacheEntry *kce;
1027
1028 GNUNET_assert (0 < seq);
1029 kce = GNUNET_new (struct KeyCacheEntry);
1030 kce->ss = ss;
1031 kce->sequence_number = seq;
1032 get_kid (&ss->master, seq, &kce->kid);
1037 key_cache,
1038 &kce->kid,
1039 kce,
1042 "# KIDs active",
1044 GNUNET_NO);
1045}
1046
1047
1054static int
1056{
1057 struct SenderAddress *sender;
1058 struct ReceiverAddress *receiver;
1059 struct KeyCacheEntry *kce;
1060
1062 "secret %s destroy %u\n",
1063 GNUNET_sh2s (&ss->master),
1065 if (NULL != (sender = ss->sender))
1066 {
1067 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1068 sender->num_secrets--;
1070 "%u sender->num_secrets %u allowed %u used, %u available\n",
1072 sender->acks_available);
1074 if (NULL != ss->sender->kce_task)
1075 {
1077 ss->sender->kce_task = NULL;
1078 }
1079 }
1080 if (NULL != (receiver = ss->receiver))
1081 {
1082 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1083 receiver->num_secrets--;
1084 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1086 "%u receiver->num_secrets\n",
1087 receiver->num_secrets);
1088 }
1089 while (NULL != (kce = ss->kce_head))
1090 kce_destroy (kce);
1091 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1093 "# KIDs active",
1095 GNUNET_NO);
1096 GNUNET_free (ss);
1097 return GNUNET_YES;
1098}
1099
1100
1107static void
1109{
1110 struct SharedSecret *ss;
1113 GNUNET_YES ==
1117 "# senders active",
1119 GNUNET_NO);
1120 while (NULL != (ss = sender->ss_head))
1121 {
1122 secret_destroy (ss);
1123 }
1126}
1127
1128
1137static void
1139 uint32_t serial,
1140 char key[AES_KEY_SIZE],
1141 char iv[AES_IV_SIZE])
1142{
1143 uint32_t sid = htonl (serial);
1144
1147 msec,
1148 "gnunet-communicator-udp-key",
1149 strlen ("gnunet-communicator-udp-key"),
1150 &sid, sizeof (sid),
1151 NULL,
1152 0);
1155 msec,
1156 "gnunet-communicator-udp-iv",
1157 strlen ("gnunet-communicator-udp-iv"),
1158 &sid, sizeof (sid),
1159 NULL,
1160 0);
1161}
1162
1163
1169static void
1171{
1172 sender->timeout =
1175}
1176
1177
1183static void
1185{
1186 receiver->timeout =
1189 receiver->timeout.abs_value_us);
1190}
1191
1192
1198static void
1200{
1201 struct GNUNET_TIME_Relative st;
1202 struct GNUNET_TIME_Relative rt;
1203 struct GNUNET_TIME_Relative delay;
1204 struct ReceiverAddress *receiver;
1205 struct SenderAddress *sender;
1206
1207 (void) cls;
1208 timeout_task = NULL;
1211 {
1213 if (0 != rt.rel_value_us)
1214 break;
1216 "Receiver timed out\n");
1218 }
1220 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1221 {
1222 if (GNUNET_YES != sender->sender_destroy_called)
1223 {
1225 if (0 != st.rel_value_us)
1226 break;
1227 sender_destroy (sender);
1228 }
1229 }
1230 delay = GNUNET_TIME_relative_min (rt, st);
1231 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1233}
1234
1235
1241static void
1243{
1245 sizeof(ss->cmac),
1246 &ss->master,
1247 "gnunet-communicator-udp-cmac",
1248 strlen ("gnunet-communicator-udp-cmac"),
1249 NULL,
1250 0);
1251}
1252
1253
1262static void
1264 const void *plaintext,
1265 size_t plaintext_len)
1266{
1267 const struct GNUNET_MessageHeader *hdr = plaintext;
1268 const char *pos = plaintext;
1269
1270 while (ntohs (hdr->size) <= plaintext_len)
1271 {
1273 "# bytes given to core",
1274 ntohs (hdr->size),
1275 GNUNET_NO);
1277 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1280 &sender->target,
1281 hdr,
1283 NULL /* no flow control possible */
1284 ,
1285 NULL));
1286 /* move on to next message, if any */
1287 plaintext_len -= ntohs (hdr->size);
1288 if (plaintext_len < sizeof(*hdr))
1289 break;
1290 pos += ntohs (hdr->size);
1291 hdr = (const struct GNUNET_MessageHeader *) pos;
1292 // TODO for now..., we do not actually sen >1msg or have a way of telling
1293 // if we are done
1294 break;
1295 }
1297 "# bytes padding discarded",
1298 plaintext_len,
1299 GNUNET_NO);
1300}
1301
1302
1311static void
1313 uint32_t serial,
1314 gcry_cipher_hd_t *cipher)
1315{
1316 char key[AES_KEY_SIZE];
1317 char iv[AES_IV_SIZE];
1318 int rc;
1319
1320 GNUNET_assert (0 ==
1321 gcry_cipher_open (cipher,
1322 GCRY_CIPHER_AES256 /* low level: go for speed */
1323 ,
1324 GCRY_CIPHER_MODE_GCM,
1325 0 /* flags */));
1326 get_iv_key (msec, serial, key, iv);
1327 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1328 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1329 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1330 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1331}
1332
1333
1346static int
1347try_decrypt (const struct SharedSecret *ss,
1348 const uint8_t *tag,
1349 uint32_t serial,
1350 const char *in_buf,
1351 size_t in_buf_size,
1352 char *out_buf)
1353{
1354 gcry_cipher_hd_t cipher;
1355
1356 setup_cipher (&ss->master, serial, &cipher);
1358 0 ==
1359 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1360 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1361 {
1362 gcry_cipher_close (cipher);
1364 "# AEAD authentication failures",
1365 1,
1366 GNUNET_NO);
1367 return GNUNET_SYSERR;
1368 }
1369 gcry_cipher_close (cipher);
1370 return GNUNET_OK;
1371}
1372
1373
1380static struct SharedSecret *
1382 )
1383{
1384 struct SharedSecret *ss;
1385
1386 ss = GNUNET_new (struct SharedSecret);
1388 calculate_cmac (ss);
1389 return ss;
1390}
1391
1392
1399static struct SharedSecret *
1402{
1403 struct SharedSecret *ss;
1404
1405 ss = GNUNET_new (struct SharedSecret);
1407 &ss->master);
1409 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1410 calculate_cmac (ss);
1411 return ss;
1412}
1413
1414
1422static struct SharedSecret *
1424 ,
1425 struct ReceiverAddress *receiver)
1426{
1427 struct SharedSecret *ss;
1428
1429 ss = GNUNET_new (struct SharedSecret);
1430 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key, ephemeral,
1431 &ss->master);
1432 calculate_cmac (ss);
1433 ss->receiver = receiver;
1434 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1435 receiver->num_secrets++;
1436 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1437 return ss;
1438}
1439
1440
1448static struct SharedSecret *
1451 struct ReceiverAddress *receiver)
1452{
1453 struct SharedSecret *ss;
1454
1455 ss = GNUNET_new (struct SharedSecret);
1457 c, &ss->master);
1459 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1460 calculate_cmac (ss);
1461 ss->receiver = receiver;
1462 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1463 receiver->num_secrets++;
1464 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1465 return ss;
1466}
1467
1468
1476static void
1478
1479
1487unsigned int
1488purge_secrets (struct SharedSecret *ss_list_tail)
1489{
1490 struct SharedSecret *pos;
1491 struct SharedSecret *ss_to_purge;
1492 unsigned int deleted = 0;
1493
1495 "Purging secrets.\n");
1496 pos = ss_list_tail;
1497 while (NULL != pos)
1498 {
1499 ss_to_purge = pos;
1500 pos = pos->prev;
1501
1502 // FIXME we may also want to purge old unacked.
1503 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1504 {
1505 secret_destroy (ss_to_purge);
1506 deleted++;
1507 }
1508 }
1510 "Finished purging all, deleted %u.\n", deleted);
1511 return deleted;
1512}
1513
1514
1515static void
1516add_acks (struct SharedSecret *ss, int acks_to_add)
1517{
1518
1519 struct ReceiverAddress *receiver = ss->receiver;
1520
1521 GNUNET_assert (NULL != ss);
1522 GNUNET_assert (NULL != receiver);
1523
1524 if (NULL == receiver->d_qh)
1525 {
1526 receiver->d_qh =
1528 &receiver->target,
1529 receiver->foreign_addr,
1530 receiver->d_mtu,
1531 acks_to_add,
1532 1, /* Priority */
1533 receiver->nt,
1535 receiver->d_mq);
1536 }
1537 else
1538 {
1540 receiver->d_qh,
1541 acks_to_add,
1542 1);
1543 }
1544
1546 "Tell transport we have %u more acks!\n",
1547 acks_to_add);
1548
1549 // Until here for alternative 1
1550
1551 /* move ss to head to avoid discarding it anytime soon! */
1552
1553 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1554 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1555}
1556
1557
1568static int
1569handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1570{
1571 const struct UDPAck *ack = cls;
1572 struct ReceiverAddress *receiver = value;
1573 uint32_t acks_to_add;
1574 uint32_t allowed;
1575
1577 "in handle ack with cmac %s\n",
1578 GNUNET_h2s (&ack->cmac));
1579
1580 (void) key;
1581 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1582 {
1583 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1584 {
1585
1587 "Found matching cmac\n");
1588
1589 allowed = ntohl (ack->sequence_ack);
1590
1591 if (allowed <= ss->sequence_allowed)
1592 {
1594 "Ignoring ack, not giving us increased window\n.");
1595 return GNUNET_NO;
1596 }
1597 acks_to_add = (allowed - ss->sequence_allowed);
1598 GNUNET_assert (0 != acks_to_add);
1599 receiver->acks_available += (allowed - ss->sequence_allowed);
1600 ss->sequence_allowed = allowed;
1601 add_acks (ss, acks_to_add);
1603 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1604 allowed,
1605 acks_to_add,
1606 receiver->acks_available,
1607 GNUNET_sh2s (&ss->master));
1608 return GNUNET_NO;
1609 }
1610 }
1612 "Matching cmac not found for ack!\n");
1613 return GNUNET_YES;
1614}
1615
1616
1625static void
1627{
1628 struct UDPAck ack;
1629 GNUNET_assert (NULL != ss->sender);
1631 "Considering SS UDPAck %s\n",
1632 GNUNET_i2s_full (&ss->sender->target));
1633
1635 "Sender has %u acks available.\n",
1636 ss->sender->acks_available);
1637 /* drop ancient KeyCacheEntries */
1638 while ((NULL != ss->kce_head) &&
1639 (MAX_SQN_DELTA <
1641 kce_destroy (ss->kce_tail);
1642
1643
1645 ack.header.size = htons (sizeof(ack));
1646 ack.sequence_ack = htonl (ss->sequence_allowed);
1647 ack.cmac = ss->cmac;
1649 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1651 ss->sequence_allowed,
1652 GNUNET_sh2s (&(ss->master)));
1654 &ss->sender->target,
1656 &ack.header);
1657}
1658
1659
1660static void
1662{
1663 struct SharedSecret *ss = cls;
1664 ss->sender->kce_task = NULL;
1665
1667 "Precomputing %u keys for master %s\n",
1669 GNUNET_sh2s (&ss->master));
1670 if ((ss->override_available_acks != GNUNET_YES) &&
1671 (KCN_TARGET < ss->sender->acks_available))
1672 return;
1673 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1674 kce_generate (ss, ++ss->sequence_allowed);
1675
1680 if (KCN_TARGET > ss->sender->acks_available)
1681 {
1685 ss);
1686 return;
1687 }
1689 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1693 consider_ss_ack (ss);
1694}
1695
1696
1705static void
1707 const void *buf,
1708 size_t buf_size)
1709{
1710 const struct GNUNET_MessageHeader *hdr;
1711 const struct UDPAck *ack;
1712 const struct UDPRekey *rekey;
1713 struct SharedSecret *ss_rekey;
1714 const char *buf_pos = buf;
1715 size_t bytes_remaining = buf_size;
1716 uint16_t type;
1717
1718 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1719 if (sizeof(*hdr) > bytes_remaining)
1720 {
1721 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1722 return; /* no data left */
1723 }
1725 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1726 (unsigned long long) bytes_remaining,
1727 ntohs (hdr->size),
1728 sizeof(*hdr),
1729 ntohs (hdr->type));
1730 if (ntohs (hdr->size) > bytes_remaining)
1731 return; /* buffer too short for indicated message length */
1732 type = ntohs (hdr->type);
1733 switch (type)
1734 {
1736 rekey = (struct UDPRekey*) buf_pos;
1737 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1738 ss_rekey->sender = sender;
1739 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1740 sender->num_secrets++;
1742 "Received rekey secret with cmac %s\n",
1743 GNUNET_h2s (&(ss_rekey->cmac)));
1745 "Received secret with master %s.\n",
1746 GNUNET_sh2s (&(ss_rekey->master)));
1748 "We have %u sequence_allowed.\n",
1749 ss_rekey->sequence_allowed);
1751 "We have a sender %p\n",
1752 ss_rekey->sender);
1754 "We have %u acks available.\n",
1755 ss_rekey->sender->acks_available);
1757 "# rekeying successful",
1758 1,
1759 GNUNET_NO);
1762 // FIXME
1763 kce_generate_cb (ss_rekey);
1764 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1765 WORKING_QUEUE_INTERVALL,
1766 kce_generate_cb,
1767 ss_rekey);*/
1768 // FIXME: Theoretically, this could be an Ack
1769 buf_pos += ntohs (hdr->size);
1770 bytes_remaining -= ntohs (hdr->size);
1771 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1772 if (0 == purge_secrets (sender->ss_tail))
1773 {
1774 // No secret purged. Delete oldest.
1775 if (sender->num_secrets > MAX_SECRETS)
1776 {
1777 secret_destroy (sender->ss_tail);
1778 }
1779 }
1780 break;
1782 /* lookup master secret by 'cmac', then update sequence_max */
1783 ack = (struct UDPAck*) buf_pos;
1785 &sender->key,
1786 &handle_ack,
1787 (void *) ack);
1788 /* There could be more messages after the ACK, handle those as well */
1789 buf_pos += ntohs (hdr->size);
1790 bytes_remaining -= ntohs (hdr->size);
1791 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1792 break;
1793
1795 /* skip padding */
1796 break;
1797
1798 default:
1799 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1800 }
1801 return;
1802}
1803
1804
1812static void
1813decrypt_box (const struct UDPBox *box,
1814 size_t box_len,
1815 struct KeyCacheEntry *kce)
1816{
1817 struct SharedSecret *ss = kce->ss;
1818 struct SharedSecret *ss_c = ss->sender->ss_tail;
1819 struct SharedSecret *ss_tmp;
1820 int ss_destroyed = 0;
1821 char out_buf[box_len - sizeof(*box)];
1822
1823 GNUNET_assert (NULL != ss->sender);
1824 if (GNUNET_OK != try_decrypt (ss,
1825 box->gcm_tag,
1826 kce->sequence_number,
1827 (const char *) &box[1],
1828 sizeof(out_buf),
1829 out_buf))
1830 {
1831 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1833 "# Decryption failures with valid KCE",
1834 1,
1835 GNUNET_NO);
1836 kce_destroy (kce);
1837 ss->sender->acks_available--;
1838 return;
1839 }
1840 kce_destroy (kce);
1841 kce = NULL;
1842 ss->bytes_sent += box_len;
1843 ss->sender->acks_available--;
1844 ss->sequence_used++;
1846 "# bytes decrypted with BOX",
1847 sizeof(out_buf),
1848 GNUNET_NO);
1850 "# messages decrypted with BOX",
1851 1,
1852 GNUNET_NO);
1854 "decrypted UDPBox with kid %s\n",
1855 GNUNET_sh2s (&box->kid));
1856 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1857
1858 while (NULL != ss_c)
1859 {
1860 if (ss_c->bytes_sent >= rekey_max_bytes)
1861 {
1863 "Removing SS because rekey bytes reached.\n");
1864 ss_tmp = ss_c->prev;
1865 if (ss == ss_c)
1866 ss_destroyed = 1;
1867 secret_destroy (ss_c);
1868 ss_c = ss_tmp;
1869 continue;
1870 }
1871 ss_c = ss_c->prev;
1872 }
1873 if (1 == ss_destroyed)
1874 return;
1876 "Sender has %u ack left.\n",
1877 ss->sender->acks_available);
1878 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1879 (NULL == ss->sender->kce_task) &&
1881 {
1883 "Sender has %u ack left which is under threshold.\n",
1884 ss->sender->acks_available);
1888 ss);
1889 }
1890}
1891
1892
1897{
1901 const struct sockaddr *address;
1902
1906 socklen_t address_len;
1907
1912};
1913
1914
1926static struct SenderAddress *
1928 const struct sockaddr *address,
1929 socklen_t address_len)
1930{
1931 struct SenderAddress *sender;
1932 struct GNUNET_HashContext *hsh;
1933 struct GNUNET_HashCode sender_key;
1934
1936 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1937 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1938 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1939
1940 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1941 if (NULL != sender)
1942 {
1944 return sender;
1945 }
1946 sender = GNUNET_new (struct SenderAddress);
1947 sender->key = sender_key;
1948 sender->target = *target;
1949 sender->address = GNUNET_memdup (address, address_len);
1950 sender->address_len = address_len;
1952 senders,
1953 &sender->key,
1954 sender,
1957 "# senders active",
1959 GNUNET_NO);
1960 sender->timeout =
1963 sender,
1964 sender->timeout.abs_value_us);
1965 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
1966 if (NULL == timeout_task)
1968 return sender;
1969}
1970
1971
1979static int
1981 const struct UDPConfirmation *uc)
1982{
1983 struct UdpHandshakeSignature uhs;
1984
1985 uhs.purpose.purpose = htonl (
1987 uhs.purpose.size = htonl (sizeof(uhs));
1988 uhs.sender = uc->sender;
1989 uhs.receiver = my_identity;
1990 uhs.enc = *enc;
1991 uhs.monotonic_time = uc->monotonic_time;
1994 &uhs,
1995 &uc->sender_sig,
1996 &uc->sender.public_key);
1997}
1998
1999
2008static char *
2009sockaddr_to_udpaddr_string (const struct sockaddr *address,
2010 socklen_t address_len)
2011{
2012 char *ret;
2013
2014 switch (address->sa_family)
2015 {
2016 case AF_INET:
2018 "%s-%s",
2020 GNUNET_a2s (address, address_len));
2021 break;
2022
2023 case AF_INET6:
2025 "%s-%s",
2027 GNUNET_a2s (address, address_len));
2028 break;
2029
2030 default:
2031 GNUNET_assert (0);
2032 }
2033 return ret;
2034}
2035
2036
2042static void
2043sock_read (void *cls)
2044{
2045 struct sockaddr_storage sa;
2046 struct sockaddr_in *addr_verify;
2047 socklen_t salen = sizeof(sa);
2048 char buf[UINT16_MAX];
2049 ssize_t rcvd;
2050
2051 (void) cls;
2053 udp_sock,
2054 &sock_read,
2055 NULL);
2056 while (1)
2057 {
2059 buf,
2060 sizeof(buf),
2061 (struct sockaddr *) &sa,
2062 &salen);
2063 if (-1 == rcvd)
2064 {
2065 struct sockaddr *addr = (struct sockaddr*) &sa;
2066
2067 if (EAGAIN == errno)
2068 break; // We are done reading data
2070 "Failed to recv from %s family %d failed sock %p\n",
2071 GNUNET_a2s ((struct sockaddr*) &sa,
2072 sizeof (*addr)),
2073 addr->sa_family,
2074 udp_sock);
2076 return;
2077 }
2079 "Read %llu bytes\n",
2080 (unsigned long long) rcvd);
2081 if (0 == rcvd)
2082 {
2083 GNUNET_break_op (0);
2085 "Read 0 bytes from UDP socket\n");
2086 return;
2087 }
2088
2089 /* first, see if it is a UDPBox */
2090 if (rcvd > sizeof(struct UDPBox))
2091 {
2092 const struct UDPBox *box;
2093 struct KeyCacheEntry *kce;
2094
2095 box = (const struct UDPBox *) buf;
2097 if (NULL != kce)
2098 {
2100 "Found KCE with kid %s\n",
2101 GNUNET_sh2s (&box->kid));
2102 decrypt_box (box, (size_t) rcvd, kce);
2103 continue;
2104 }
2105 }
2106
2107 /* next, check if it is a broadcast */
2108 if (sizeof(struct UDPBroadcast) == rcvd)
2109 {
2110 const struct UDPBroadcast *ub;
2111 struct UdpBroadcastSignature uhs;
2112 struct GNUNET_PeerIdentity sender;
2113
2114 addr_verify = GNUNET_memdup (&sa, salen);
2115 addr_verify->sin_port = 0;
2117 "received UDPBroadcast from %s\n",
2118 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2119 ub = (const struct UDPBroadcast *) buf;
2120 uhs.purpose.purpose = htonl (
2122 uhs.purpose.size = htonl (sizeof(uhs));
2123 uhs.sender = ub->sender;
2124 sender = ub->sender;
2125 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2127 {
2129 "Received our own broadcast\n");
2130 GNUNET_free (addr_verify);
2131 continue;
2132 }
2134 "checking UDPBroadcastSignature for %s\n",
2135 GNUNET_i2s (&sender));
2136 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2137 &uhs.h_address);
2138 if (GNUNET_OK ==
2141 &uhs,
2142 &ub->sender_sig,
2143 &ub->sender.public_key))
2144 {
2145 char *addr_s;
2147
2148 addr_s =
2149 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2150 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2151 /* use our own mechanism to determine network type */
2152 nt =
2153 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2155 "validating address %s received from UDPBroadcast\n",
2156 GNUNET_i2s (&sender));
2158 GNUNET_free (addr_s);
2159 GNUNET_free (addr_verify);
2160 continue;
2161 }
2162 else
2163 {
2165 "VerifyingPeer %s is verifying UDPBroadcast\n",
2168 "Verifying UDPBroadcast from %s failed\n",
2169 GNUNET_i2s (&ub->sender));
2170 }
2171 GNUNET_free (addr_verify);
2172 /* continue with KX, mostly for statistics... */
2173 }
2174
2175
2176 /* finally, test if it is a KX */
2177 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2178 {
2180 "# messages dropped (no kid, too small for KX)",
2181 1,
2182 GNUNET_NO);
2183 continue;
2184 }
2186 "Got KX\n");
2187 {
2188 const struct InitialKX *kx;
2189 struct SharedSecret *ss;
2190 char pbuf[rcvd - sizeof(struct InitialKX)];
2191 const struct UDPConfirmation *uc;
2192 struct SenderAddress *sender;
2193
2194 kx = (const struct InitialKX *) buf;
2197 "Before DEC\n");
2198
2199 if (GNUNET_OK != try_decrypt (ss,
2200 kx->gcm_tag,
2201 0,
2202 &buf[sizeof(*kx)],
2203 sizeof(pbuf),
2204 pbuf))
2205 {
2207 "Unable to decrypt tag, dropping...\n");
2208 GNUNET_free (ss);
2210 stats,
2211 "# messages dropped (no kid, AEAD decryption failed)",
2212 1,
2213 GNUNET_NO);
2214 continue;
2215 }
2217 "Before VERIFY\n");
2218
2219 uc = (const struct UDPConfirmation *) pbuf;
2220
2221 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2222 {
2223 GNUNET_break_op (0);
2224 GNUNET_free (ss);
2226 "# messages dropped (sender signature invalid)",
2227 1,
2228 GNUNET_NO);
2229 continue;
2230 }
2232 "Before SETUP_SENDER\n");
2233
2234 calculate_cmac (ss);
2235 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2236 ss->sender = sender;
2237 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2238 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2239 (NULL == ss->sender->kce_task) &&
2241 {
2242 // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix.
2246 ss);
2247 }
2248 sender->num_secrets++;
2249 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2251 "# messages decrypted without BOX",
2252 1,
2253 GNUNET_NO);
2254 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2255 if (0 == purge_secrets (sender->ss_tail))
2256 {
2257 // No secret purged. Delete oldest.
2258 if (sender->num_secrets > MAX_SECRETS)
2259 {
2260 secret_destroy (sender->ss_tail);
2261 }
2262 }
2263 }
2264 }
2265}
2266
2267
2275static struct sockaddr *
2276udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2277{
2278 struct sockaddr *in;
2279 unsigned int port;
2280 char dummy[2];
2281 char *colon;
2282 char *cp;
2283
2284 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2285 {
2286 /* interpreting value as just a PORT number */
2287 if (port > UINT16_MAX)
2288 {
2290 "BINDTO specification `%s' invalid: value too large for port\n",
2291 bindto);
2292 return NULL;
2293 }
2294 if (GNUNET_YES == disable_v6)
2295 {
2296 struct sockaddr_in *i4;
2297
2298 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2299 i4->sin_family = AF_INET;
2300 i4->sin_port = htons ((uint16_t) port);
2301 *sock_len = sizeof(struct sockaddr_in);
2302 in = (struct sockaddr *) i4;
2303 }
2304 else
2305 {
2306 struct sockaddr_in6 *i6;
2307
2308 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2309 i6->sin6_family = AF_INET6;
2310 i6->sin6_port = htons ((uint16_t) port);
2311 *sock_len = sizeof(struct sockaddr_in6);
2312 in = (struct sockaddr *) i6;
2313 }
2314 return in;
2315 }
2316 cp = GNUNET_strdup (bindto);
2317 colon = strrchr (cp, ':');
2318 if (NULL != colon)
2319 {
2320 /* interpret value after colon as port */
2321 *colon = '\0';
2322 colon++;
2323 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2324 {
2325 /* interpreting value as just a PORT number */
2326 if (port > UINT16_MAX)
2327 {
2329 "BINDTO specification `%s' invalid: value too large for port\n",
2330 bindto);
2331 GNUNET_free (cp);
2332 return NULL;
2333 }
2334 }
2335 else
2336 {
2337 GNUNET_log (
2339 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2340 bindto);
2341 GNUNET_free (cp);
2342 return NULL;
2343 }
2344 }
2345 else
2346 {
2347 /* interpret missing port as 0, aka pick any free one */
2348 port = 0;
2349 }
2350 {
2351 /* try IPv4 */
2352 struct sockaddr_in v4;
2353
2354 memset (&v4, 0, sizeof(v4));
2355 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2356 {
2357 v4.sin_family = AF_INET;
2358 v4.sin_port = htons ((uint16_t) port);
2359#if HAVE_SOCKADDR_IN_SIN_LEN
2360 v4.sin_len = sizeof(struct sockaddr_in);
2361#endif
2362 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2363 *sock_len = sizeof(struct sockaddr_in);
2364 GNUNET_free (cp);
2365 return in;
2366 }
2367 }
2368 {
2369 /* try IPv6 */
2370 struct sockaddr_in6 v6;
2371 const char *start;
2372
2373 memset (&v6, 0, sizeof(v6));
2374 start = cp;
2375 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2376 {
2377 start++; /* skip over '[' */
2378 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2379 }
2380 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2381 {
2382 v6.sin6_family = AF_INET6;
2383 v6.sin6_port = htons ((uint16_t) port);
2384#if HAVE_SOCKADDR_IN_SIN_LEN
2385 v6.sin6_len = sizeof(struct sockaddr_in6);
2386#endif
2387 in = GNUNET_memdup (&v6, sizeof(v6));
2388 *sock_len = sizeof(v6);
2389 GNUNET_free (cp);
2390 return in;
2391 }
2392 }
2393 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2394 GNUNET_free (cp);
2395 return NULL;
2396}
2397
2398
2406static void
2407do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2408{
2409 char pad[pad_size];
2410
2412 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2413 {
2414 struct GNUNET_MessageHeader hdr =
2415 { .size = htons (sizeof(pad)),
2417
2418 memcpy (pad, &hdr, sizeof(hdr));
2419 }
2421 0 ==
2422 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2423}
2424
2425
2426static void
2429 struct GNUNET_MQ_Handle *mq)
2430{
2431 uint16_t msize = ntohs (msg->size);
2432 struct UdpHandshakeSignature uhs;
2433 struct UDPConfirmation uc;
2434 struct InitialKX kx;
2435 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2436 size_t dpos;
2437 gcry_cipher_hd_t out_cipher;
2438 struct SharedSecret *ss;
2439
2440 if (msize > receiver->kx_mtu)
2441 {
2442 GNUNET_break (0);
2443 if (GNUNET_YES != receiver->receiver_destroy_called)
2445 return;
2446 }
2448
2449 /* setup key material */
2451
2452 if (0 == purge_secrets (receiver->ss_tail))
2453 {
2454 // No secret purged. Delete oldest.
2455 if (receiver->num_secrets > MAX_SECRETS)
2456 {
2457 secret_destroy (receiver->ss_tail);
2458 }
2459 }
2460
2461 setup_cipher (&ss->master, 0, &out_cipher);
2462 /* compute 'uc' */
2463 uc.sender = my_identity;
2464 uc.monotonic_time =
2466 uhs.purpose.purpose = htonl (
2468 uhs.purpose.size = htonl (sizeof(uhs));
2469 uhs.sender = my_identity;
2470 uhs.receiver = receiver->target;
2471 uhs.monotonic_time = uc.monotonic_time;
2473 &uhs,
2474 &uc.sender_sig);
2475 /* Leave space for kx */
2476 dpos = sizeof(kx);
2477 /* Append encrypted uc to dgram */
2478 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2479 &dgram[dpos],
2480 sizeof(uc),
2481 &uc,
2482 sizeof(uc)));
2483 dpos += sizeof(uc);
2484 /* Append encrypted payload to dgram */
2486 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2487 dpos += msize;
2488 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2489 /* Datagram starts with kx */
2490 kx.enc = uhs.enc;
2492 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2493 gcry_cipher_close (out_cipher);
2494 memcpy (dgram, &kx, sizeof(kx));
2496 dgram,
2497 sizeof(dgram),
2498 receiver->address,
2499 receiver->address_len))
2500 {
2503 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2504 msize,
2505 GNUNET_a2s (receiver->address,
2506 receiver->address_len),
2507 receiver->address->sa_family,
2508 udp_sock);
2511 return;
2512 }
2514 "Sending KX with payload size %u to %s\n",
2515 msize,
2516 GNUNET_a2s (receiver->address,
2517 receiver->address_len));
2519}
2520
2521
2530static void
2532 const struct GNUNET_MessageHeader *msg,
2533 void *impl_state)
2534{
2535 struct ReceiverAddress *receiver = impl_state;
2536
2537 GNUNET_assert (mq == receiver->kx_mq);
2539}
2540
2541
2542static void
2544 UDPRekey *rekey)
2545{
2546 struct SharedSecret *ss_rekey;
2547
2549 /* setup key material */
2550 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2551 receiver);
2552 ss_rekey->sequence_allowed = 0;
2554 "Setup secret with k = %s\n",
2555 GNUNET_sh2s (&ss_rekey->master));
2557 "Setup secret with H(k) = %s\n",
2558 GNUNET_h2s (&(ss_rekey->cmac)));
2559
2560 /* Append encrypted payload to dgram */
2562 rekey->header.size = htons (sizeof (struct UDPRekey));
2563}
2564
2565
2574static void
2576 const struct GNUNET_MessageHeader *msg,
2577 void *impl_state)
2578{
2579 struct ReceiverAddress *receiver = impl_state;
2580 struct UDPRekey rekey;
2581 struct SharedSecret *ss;
2582 int inject_rekey = GNUNET_NO;
2583 uint16_t msize = ntohs (msg->size);
2584
2585 GNUNET_assert (mq == receiver->d_mq);
2586 if ((msize > receiver->d_mtu) ||
2587 (0 == receiver->acks_available))
2588 {
2590 "msize: %u, mtu: %llu, acks: %u\n",
2591 (unsigned int) msize,
2592 (unsigned long long) receiver->d_mtu,
2593 receiver->acks_available);
2594
2595 GNUNET_break (0);
2596 if (GNUNET_YES != receiver->receiver_destroy_called)
2598 return;
2599 }
2601
2602 if (receiver->num_secrets > MAX_SECRETS)
2603 {
2604 if ((0 == purge_secrets (receiver->ss_tail)) &&
2605 (NULL != receiver->ss_tail))
2606 {
2607 // No secret purged. Delete oldest.
2608 secret_destroy (receiver->ss_tail);
2609 }
2610 }
2611 /* begin "BOX" encryption method, scan for ACKs from tail! */
2612 ss = receiver->ss_tail;
2613 struct SharedSecret *ss_tmp;
2614 while (NULL != ss)
2615 {
2616 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2618 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2619 GNUNET_sh2s (&ss->master), ss->sequence_used,
2620 ss->sequence_allowed, ss->bytes_sent);
2621 if (ss->sequence_used >= ss->sequence_allowed)
2622 {
2623 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2624 // "Skipping ss because no acks to use.\n");
2625 ss = ss->prev;
2626 continue;
2627 }
2628 if (ss->bytes_sent >= rekey_max_bytes)
2629 {
2631 "Skipping ss because rekey bytes reached.\n");
2632 // FIXME cleanup ss with too many bytes sent!
2633 ss_tmp = ss->prev;
2634 secret_destroy (ss);
2635 ss = ss_tmp;
2636 continue;
2637 }
2638 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2639 {
2640 if (ss->rekey_initiated == GNUNET_NO)
2641 {
2643 "Injecting rekey for ss with byte sent %lu\n",
2644 (unsigned long) ss->bytes_sent);
2645 create_rekey (receiver, ss, &rekey);
2647 payload_len += sizeof (rekey);
2649 }
2650 }
2651 if (0 < ss->sequence_used)
2653 "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n",
2654 GNUNET_sh2s (&ss->master),
2655 ss->sequence_used,
2656 ss->sequence_allowed);
2657
2658 char dgram[payload_len];
2659 struct UDPBox *box;
2660 gcry_cipher_hd_t out_cipher;
2661 size_t dpos;
2662
2663 box = (struct UDPBox *) dgram;
2664 ss->sequence_used++;
2665 get_kid (&ss->master, ss->sequence_used, &box->kid);
2666 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2667 /* Append encrypted payload to dgram */
2668 dpos = sizeof(struct UDPBox);
2669 if (GNUNET_YES == inject_rekey)
2670 {
2672 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2673 &rekey, sizeof (rekey)));
2674 dpos += sizeof (rekey);
2675 }
2677 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2678 dpos += msize;
2679 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2680 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2681 box->gcm_tag,
2682 sizeof(box->gcm_tag)));
2683 gcry_cipher_close (out_cipher);
2684
2686 dgram,
2687 payload_len, // FIXME why always send sizeof dgram?
2688 receiver->address,
2689 receiver->address_len))
2690 {
2693 "Sending UDPBox to %s family %d failed sock %p failed\n",
2694 GNUNET_a2s (receiver->address,
2695 receiver->address_len),
2696 receiver->address->sa_family,
2697 udp_sock);
2699 return;
2700 }
2702 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent\n",
2703 msize,
2704 receiver->acks_available,
2705 (unsigned long) ss->bytes_sent);
2706 ss->bytes_sent += sizeof (dgram);
2707 receiver->acks_available--;
2709 return;
2710 }
2712 "No suitable ss found, sending as KX...\n");
2714}
2715
2716
2725static void
2726mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2727{
2728 struct ReceiverAddress *receiver = impl_state;
2730 "Default MQ destroyed\n");
2731 if (mq == receiver->d_mq)
2732 {
2733 receiver->d_mq = NULL;
2734 if (GNUNET_YES != receiver->receiver_destroy_called)
2736 }
2737}
2738
2739
2748static void
2749mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2750{
2751 struct ReceiverAddress *receiver = impl_state;
2753 "KX MQ destroyed\n");
2754 if (mq == receiver->kx_mq)
2755 {
2756 receiver->kx_mq = NULL;
2757 if (GNUNET_YES != receiver->receiver_destroy_called)
2759 }
2760}
2761
2762
2769static void
2770mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2771{
2772 /* Cancellation is impossible with UDP; bail */
2773 GNUNET_assert (0);
2774}
2775
2776
2786static void
2787mq_error (void *cls, enum GNUNET_MQ_Error error)
2788{
2789 struct ReceiverAddress *receiver = cls;
2790
2792 "MQ error in queue to %s: %d\n",
2793 GNUNET_i2s (&receiver->target),
2794 (int) error);
2796}
2797
2798
2806static void
2808{
2809 size_t base_mtu;
2810
2811 switch (receiver->address->sa_family)
2812 {
2813 case AF_INET:
2814 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
2815 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
2816 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2817 break;
2818
2819 case AF_INET6:
2820 base_mtu = 1280 /* Minimum MTU required by IPv6 */
2821 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
2822 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2823 break;
2824
2825 default:
2826 GNUNET_assert (0);
2827 break;
2828 }
2829 /* MTU based on full KX messages */
2830 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
2831 - sizeof(struct UDPConfirmation); /* 104 */
2832 /* MTU based on BOXed messages */
2833 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
2834
2836 "Setting up MQs and QHs\n");
2837 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
2838 1404 (IPv4 + Box) bytes, depending on circumstances... */
2839 if (NULL == receiver->kx_mq)
2842 &mq_cancel,
2843 receiver,
2844 NULL,
2845 &mq_error,
2846 receiver);
2847 if (NULL == receiver->d_mq)
2849 &mq_destroy_d,
2850 &mq_cancel,
2851 receiver,
2852 NULL,
2853 &mq_error,
2854 receiver);
2855
2856 receiver->kx_qh =
2858 &receiver->target,
2859 receiver->foreign_addr,
2860 receiver->kx_mtu,
2862 0, /* Priority */
2863 receiver->nt,
2865 receiver->kx_mq);
2866}
2867
2868
2887static int
2888mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2889{
2890 struct ReceiverAddress *receiver;
2891 struct GNUNET_HashContext *hsh;
2892 struct GNUNET_HashCode receiver_key;
2893 const char *path;
2894 struct sockaddr *in;
2895 socklen_t in_len;
2896
2897 if (0 != strncmp (address,
2899 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2900 {
2901 GNUNET_break_op (0);
2902 return GNUNET_SYSERR;
2903 }
2904 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2905 in = udp_address_to_sockaddr (path, &in_len);
2906
2907 if (NULL == in)
2908 {
2910 "Failed to setup UDP socket address\n");
2911 return GNUNET_SYSERR;
2912 }
2913 if ((AF_INET6 == in->sa_family) &&
2915 {
2917 "IPv6 disabled, skipping %s\n", address);
2918 GNUNET_free (in);
2919 return GNUNET_SYSERR;
2920 }
2921
2923 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2924 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2925 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2926
2928 if (NULL != receiver)
2929 {
2931 "receiver %s already exist or is being connected to\n",
2932 address);
2933 GNUNET_free (in);
2934 return GNUNET_NO;
2935 }
2936
2938 receiver->key = receiver_key;
2939 receiver->address = in;
2940 receiver->address_len = in_len;
2941 receiver->target = *peer;
2942 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2943 &receiver->target_hpke_key);
2944 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2946 receivers,
2947 &receiver->key,
2948 receiver,
2951 "Added %s to receivers\n",
2952 GNUNET_i2s_full (&receiver->target));
2953 receiver->timeout =
2956 receiver,
2957 receiver->timeout.abs_value_us);
2959 "# receivers active",
2961 GNUNET_NO);
2962 receiver->foreign_addr =
2963 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2965 if (NULL == timeout_task)
2967 return GNUNET_OK;
2968}
2969
2970
2979static int
2981 const struct GNUNET_HashCode *target,
2982 void *value)
2983{
2984 struct ReceiverAddress *receiver = value;
2985
2986 (void) cls;
2987 (void) target;
2989 return GNUNET_OK;
2990}
2991
2992
3001static int
3003 const struct GNUNET_HashCode *target,
3004 void *value)
3005{
3006 struct SenderAddress *sender = value;
3007
3008 (void) cls;
3009 (void) target;
3010
3011
3012 sender_destroy (sender);
3013 return GNUNET_OK;
3014}
3015
3016
3022static void
3023do_shutdown (void *cls)
3024{
3026 "do_shutdown\n");
3027 if (NULL != nat)
3028 {
3030 nat = NULL;
3031 }
3032 while (NULL != bi_head)
3034 if (NULL != broadcast_task)
3035 {
3037 broadcast_task = NULL;
3038 }
3039 if (NULL != timeout_task)
3040 {
3042 timeout_task = NULL;
3043 }
3044 if (NULL != read_task)
3045 {
3047 read_task = NULL;
3048 }
3049 if (NULL != udp_sock)
3050 {
3053 udp_sock = NULL;
3054 }
3057 NULL);
3061 NULL);
3066 if (NULL != timeout_task)
3067 {
3069 timeout_task = NULL;
3070 }
3071 if (NULL != ch)
3072 {
3074 ch = NULL;
3075 }
3076 if (NULL != ah)
3077 {
3079 ah = NULL;
3080 }
3081 if (NULL != stats)
3082 {
3084 stats = NULL;
3085 }
3086 if (NULL != my_private_key)
3087 {
3089 my_private_key = NULL;
3090 }
3091 if (NULL != is)
3092 {
3094 is = NULL;
3095 }
3097 "do_shutdown finished\n");
3098}
3099
3100
3102{
3103 const struct UDPAck *ack;
3104
3106};
3107
3108static int
3109handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3110{
3111 struct ReceiverAddress *receiver = value;
3112 struct AckInfo *ai = cls;
3113
3114 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3115 {
3116 return GNUNET_YES;
3117 }
3118 handle_ack ((void*) ai->ack, key, receiver);
3119 return GNUNET_YES;
3120}
3121
3122
3132static void
3133enc_notify_cb (void *cls,
3134 const struct GNUNET_PeerIdentity *sender,
3135 const struct GNUNET_MessageHeader *msg)
3136{
3137 struct AckInfo ai;
3138
3139 (void) cls;
3141 "Storing UDPAck received from backchannel from %s\n",
3144 (ntohs (msg->size) != sizeof(struct UDPAck)))
3145 {
3146 GNUNET_break_op (0);
3147 return;
3148 }
3149 ai.ack = (const struct UDPAck *) msg;
3150 ai.sender = sender;
3153 &ai);
3154}
3155
3156
3170static void
3172 void **app_ctx,
3173 int add_remove,
3175 const struct sockaddr *addr,
3176 socklen_t addrlen)
3177{
3178 char *my_addr;
3180
3181 if (GNUNET_YES == add_remove)
3182 {
3184
3185 GNUNET_asprintf (&my_addr,
3186 "%s-%s",
3188 GNUNET_a2s (addr, addrlen));
3189 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3190 ai =
3192 my_addr,
3193 nt,
3195 GNUNET_free (my_addr);
3196 *app_ctx = ai;
3197 }
3198 else
3199 {
3200 ai = *app_ctx;
3202 *app_ctx = NULL;
3203 }
3204}
3205
3206
3212static void
3213ifc_broadcast (void *cls)
3214{
3215 struct BroadcastInterface *bi = cls;
3216 struct GNUNET_TIME_Relative delay;
3217
3218 delay = BROADCAST_FREQUENCY;
3219 delay.rel_value_us =
3221 bi->broadcast_task =
3223
3224 switch (bi->sa->sa_family)
3225 {
3226 case AF_INET: {
3227 static int yes = 1;
3228 static int no = 0;
3229 ssize_t sent;
3230
3231 if (GNUNET_OK !=
3233 SOL_SOCKET,
3234 SO_BROADCAST,
3235 &yes,
3236 sizeof(int)))
3238 "setsockopt");
3240 "creating UDPBroadcast from %s\n",
3241 GNUNET_i2s (&(bi->bcm.sender)));
3243 "sending UDPBroadcast to add %s\n",
3244 GNUNET_a2s (bi->ba, bi->salen));
3246 &bi->bcm,
3247 sizeof(bi->bcm),
3248 bi->ba,
3249 bi->salen);
3250 if (-1 == sent)
3252 "sendto");
3254 SOL_SOCKET,
3255 SO_BROADCAST,
3256 &no,
3257 sizeof(int)))
3259 "setsockopt");
3260 break;
3261 }
3262
3263 case AF_INET6: {
3264 ssize_t sent;
3265 struct sockaddr_in6 dst;
3266
3267 dst.sin6_family = AF_INET6;
3268 dst.sin6_port = htons (my_port);
3269 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3270 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3271
3273 "sending UDPBroadcast\n");
3275 &bi->bcm,
3276 sizeof(bi->bcm),
3277 (const struct sockaddr *) &dst,
3278 sizeof(dst));
3279 if (-1 == sent)
3281 break;
3282 }
3283
3284 default:
3285 GNUNET_break (0);
3286 break;
3287 }
3288}
3289
3290
3305static int
3306iface_proc (void *cls,
3307 const char *name,
3308 int isDefault,
3309 const struct sockaddr *addr,
3310 const struct sockaddr *broadcast_addr,
3311 const struct sockaddr *netmask,
3312 socklen_t addrlen)
3313{
3314 struct BroadcastInterface *bi;
3315 enum GNUNET_NetworkType network;
3316 struct UdpBroadcastSignature ubs;
3317
3318 (void) cls;
3319 (void) netmask;
3320 if (NULL == addr)
3321 return GNUNET_YES; /* need to know our address! */
3322 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3323 if (GNUNET_NT_LOOPBACK == network)
3324 {
3325 /* Broadcasting on loopback does not make sense */
3326 return GNUNET_YES;
3327 }
3328 for (bi = bi_head; NULL != bi; bi = bi->next)
3329 {
3330 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3331 {
3332 bi->found = GNUNET_YES;
3333 return GNUNET_OK;
3334 }
3335 }
3336
3337 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3338 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3339 if ((AF_INET6 == addr->sa_family) && (GNUNET_YES != have_v6_socket))
3340 return GNUNET_OK; /* not using IPv6 */
3341
3342 bi = GNUNET_new (struct BroadcastInterface);
3343 bi->sa = GNUNET_memdup (addr,
3344 addrlen);
3345 if ( (NULL != broadcast_addr) &&
3346 (addrlen == sizeof (struct sockaddr_in)) )
3347 {
3348 struct sockaddr_in *ba;
3349
3350 ba = GNUNET_memdup (broadcast_addr,
3351 addrlen);
3352 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3353 bi->ba = (struct sockaddr *) ba;
3354 }
3355 bi->salen = addrlen;
3356 bi->found = GNUNET_YES;
3357 bi->bcm.sender = my_identity;
3358 ubs.purpose.purpose = htonl (
3360 ubs.purpose.size = htonl (sizeof(ubs));
3361 ubs.sender = my_identity;
3363 "creating UDPBroadcastSignature for %s\n",
3364 GNUNET_a2s (addr, addrlen));
3365 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3367 &ubs,
3368 &bi->bcm.sender_sig);
3369 if (NULL != bi->ba)
3370 {
3373 }
3374 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3375 {
3376 /* Create IPv6 multicast request */
3377 const struct sockaddr_in6 *s6 =
3378 (const struct sockaddr_in6 *) broadcast_addr;
3379
3381 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3382
3383 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3384 *
3385 * IPV6_JOIN_GROUP
3386 *
3387 * Join a multicast group on a specified local interface. If the
3388 * interface index is specified as 0, the kernel chooses the local
3389 * interface. For example, some kernels look up the multicast
3390 * group in the normal IPv6 routing table and using the resulting
3391 * interface; we do this for each interface, so no need to use
3392 * zero (anymore...).
3393 */
3394 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3395
3396 /* Join the multicast group */
3398 IPPROTO_IPV6,
3399 IPV6_JOIN_GROUP,
3400 &bi->mcreq,
3401 sizeof(bi->mcreq)))
3402 {
3404 }
3405 }
3406 return GNUNET_OK;
3407}
3408
3409
3415static void
3416do_broadcast (void *cls)
3417{
3418 struct BroadcastInterface *bin;
3419
3420 (void) cls;
3421 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3422 bi->found = GNUNET_NO;
3424 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3425 {
3426 bin = bi->next;
3427 if (GNUNET_NO == bi->found)
3428 bi_destroy (bi);
3429 }
3431 &do_broadcast,
3432 NULL);
3433}
3434
3435
3436static void
3438 const struct sockaddr *addr,
3439 socklen_t addrlen)
3440{
3441 /* FIXME: support reversal: #5529 */
3443 "No connection reversal implemented!");
3444}
3445
3446
3455static void
3456run (void *cls,
3457 char *const *args,
3458 const char *cfgfile,
3459 const struct GNUNET_CONFIGURATION_Handle *c)
3460{
3461 char *bindto;
3462 struct sockaddr *in;
3463 socklen_t in_len;
3464 struct sockaddr_storage in_sto;
3465 socklen_t sto_len;
3466
3467 (void) cls;
3468 cfg = c;
3469 if (GNUNET_OK !=
3472 "BINDTO",
3473 &bindto))
3474 {
3477 "BINDTO");
3478 return;
3479 }
3480
3481 if (GNUNET_OK !=
3484 "REKEY_INTERVAL",
3487
3488 if (GNUNET_OK !=
3491 "REKEY_MAX_BYTES",
3493 {
3495 }
3497 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3498 (GNUNET_YES ==
3501 "DISABLE_V6")))
3502 {
3504 }
3505
3506 in = udp_address_to_sockaddr (bindto, &in_len);
3507 if (NULL == in)
3508 {
3510 "Failed to setup UDP socket address with path `%s'\n",
3511 bindto);
3512 GNUNET_free (bindto);
3513 return;
3514 }
3515 udp_sock =
3516 GNUNET_NETWORK_socket_create (in->sa_family,
3517 SOCK_DGRAM,
3518 IPPROTO_UDP);
3519 if (NULL == udp_sock)
3520 {
3523 "Failed to create socket for %s family %d\n",
3524 GNUNET_a2s (in,
3525 in_len),
3526 in->sa_family);
3527 GNUNET_free (in);
3528 GNUNET_free (bindto);
3529 return;
3530 }
3531 if (AF_INET6 == in->sa_family)
3533 if (GNUNET_OK !=
3535 in,
3536 in_len))
3537 {
3539 "bind",
3540 bindto);
3542 "Failed to bind socket for %s family %d sock %p\n",
3543 GNUNET_a2s (in,
3544 in_len),
3545 in->sa_family,
3546 udp_sock);
3548 udp_sock = NULL;
3549 GNUNET_free (in);
3550 GNUNET_free (bindto);
3551 return;
3552 }
3553
3554 /* We might have bound to port 0, allowing the OS to figure it out;
3555 thus, get the real IN-address from the socket */
3556 sto_len = sizeof(in_sto);
3557 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
3558 (struct sockaddr *) &in_sto,
3559 &sto_len))
3560 {
3561 memcpy (&in_sto, in, in_len);
3562 sto_len = in_len;
3563 }
3564 GNUNET_free (in);
3565 GNUNET_free (bindto);
3566 in = (struct sockaddr *) &in_sto;
3567 in_len = sto_len;
3569 "transport",
3570 "Bound to `%s' sock %p\n",
3571 GNUNET_a2s ((const struct sockaddr *) &in_sto,
3572 sto_len),
3573 udp_sock);
3574 switch (in->sa_family)
3575 {
3576 case AF_INET:
3577 my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
3578 break;
3579
3580 case AF_INET6:
3581 my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
3582 break;
3583
3584 default:
3585 GNUNET_break (0);
3586 my_port = 0;
3587 }
3588 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3598 if (NULL == my_private_key)
3599 {
3600 GNUNET_log (
3602 _ (
3603 "Transport service is lacking key configuration settings. Exiting.\n"));
3605 return;
3606 }
3609 /* start reading */
3611 udp_sock,
3612 &sock_read,
3613 NULL);
3618 &mq_init,
3619 NULL,
3621 NULL);
3622 if (NULL == ch)
3623 {
3624 GNUNET_break (0);
3626 return;
3627 }
3629 if (NULL == ah)
3630 {
3631 GNUNET_break (0);
3633 return;
3634 }
3635 /* start broadcasting */
3636 if (GNUNET_YES !=
3639 "DISABLE_BROADCAST"))
3640 {
3642 }
3645 IPPROTO_UDP,
3646 1 /* one address */,
3647 (const struct sockaddr **) &in,
3648 &in_len,
3651 NULL /* closure */);
3652}
3653
3654
3662int
3663main (int argc, char *const *argv)
3664{
3665 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3667 };
3668 int ret;
3669
3671 "transport",
3672 "Starting udp communicator\n");
3673 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3674 return 2;
3675
3676 ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
3677 argv,
3678 "gnunet-communicator-udp",
3679 _ ("GNUnet UDP communicator"),
3680 options,
3681 &run,
3682 NULL))
3683 ? 0
3684 : 1;
3685 GNUNET_free_nz ((void *) argv);
3686 return ret;
3687}
3688
3689
3690/* end of gnunet-communicator-udp.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int ret
Final status code.
Definition: gnunet-arm.c:94
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
#define AES_KEY_SIZE
AES key size.
static struct BroadcastInterface * bi_tail
Broadcast interface tasks.
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
static int try_decrypt(const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
Try to decrypt buf using shared secret ss and key/iv derived using serial.
#define WORKING_QUEUE_INTERVALL
static void kce_destroy(struct KeyCacheEntry *kce)
Free memory used by key cache entry.
static int handle_ack(void *cls, const struct GNUNET_HashCode *key, void *value)
We received an ACK for pid.
static void create_rekey(struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static int secret_destroy(struct SharedSecret *ss)
Destroy ss and associated key cache entries.
#define GCM_TAG_SIZE
Size of the GCM tag.
static void get_iv_key(const struct GNUNET_ShortHashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
Compute key and iv.
static struct GNUNET_PeerIdentity my_identity
Our public key.
static void mq_send_kx(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static struct SharedSecret * setup_initial_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM for initial handshake.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static void kce_generate(struct SharedSecret *ss, uint32_t seq)
Setup key cache entry for sequence number seq and shared secret ss.
static void setup_cipher(const struct GNUNET_ShortHashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.
static void add_acks(struct SharedSecret *ss, int acks_to_add)
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static void mq_destroy_kx(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static void eddsa_priv_to_hpke_key(struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
static int get_receiver_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all receivers to clean up.
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static struct GNUNET_SCHEDULER_Task * broadcast_task
ID of master broadcast task.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static int verify_confirmation(const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct UDPConfirmation *uc)
Check signature from uc against ephemeral.
static int disable_v6
IPv6 disabled or not.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received a backchannel message for this communicator (...
static struct SenderAddress * setup_sender(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
Create sender address for target.
unsigned int purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
static void reschedule_receiver_timeout(struct ReceiverAddress *receiver)
Increment receiver timeout due to activity.
static struct SharedSecret * setup_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM.
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static void get_kid(const struct GNUNET_ShortHashCode *msec, uint32_t serial, struct GNUNET_ShortHashCode *kid)
Compute kid.
static void do_pad(gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
Pad dgram by pad_size using out_cipher.
static void mq_send_d(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static void sock_read(void *cls)
Socket read task.
static void reschedule_sender_timeout(struct SenderAddress *sender)
Increment sender timeout due to activity.
static struct GNUNET_CONTAINER_Heap * senders_heap
Expiration heap for senders (contains struct SenderAddress)
static void do_shutdown(void *cls)
Shutdown the UNIX communicator.
static int get_sender_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all senders to clean up.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static void nat_address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
static void sender_destroy(struct SenderAddress *sender)
Functions with this signature are called whenever we need to close a sender's state due to timeout.
static struct SharedSecret * setup_initial_shared_secret_dec(const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
Setup shared secret for decryption for initial handshake.
static void setup_receiver_mq(struct ReceiverAddress *receiver)
Setup the MQ for the receiver.
static struct sockaddr * udp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
static int handle_ack_by_sender(void *cls, const struct GNUNET_HashCode *key, void *value)
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
#define DEFAULT_REKEY_MAX_BYTES
Default value for how often we do rekey based on number of bytes transmitted? (additionally randomize...
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static struct GNUNET_CONTAINER_MultiHashMap * receivers
Receivers (map from peer identity to struct ReceiverAddress)
#define GENERATE_AT_ONCE
static void kce_generate_cb(void *cls)
static struct GNUNET_SCHEDULER_Task * read_task
ID of read task.
static void try_handle_plaintext(struct SenderAddress *sender, const void *buf, size_t buf_size)
Test if we have received a valid message in plaintext.
static void receiver_destroy(struct ReceiverAddress *receiver)
Destroys a receiving state due to timeout or shutdown.
static struct GNUNET_CONTAINER_MultiShortmap * key_cache
Cache of pre-generated key IDs.
#define KCN_TARGET
How many KCNs do we keep around after we hit the KCN_THRESHOLD? Should be larger than KCN_THRESHOLD s...
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
static struct GNUNET_TRANSPORT_ApplicationHandle * ah
Our handle to report addresses for validation to TRANSPORT.
static void bi_destroy(struct BroadcastInterface *bi)
An interface went away, stop broadcasting on it.
static int have_v6_socket
GNUNET_YES if udp_sock supports IPv6.
static void pass_plaintext_to_core(struct SenderAddress *sender, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext from a sender.
static struct GNUNET_CONTAINER_MultiHashMap * senders
Senders (map from peer identity to struct SenderAddress)
static int mq_init(void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
Function called by the transport service to initialize a message queue given address information abou...
static void do_broadcast(void *cls)
Scan interfaces to broadcast our presence on the LAN.
#define INTERFACE_SCAN_FREQUENCY
How often do we scan for changes to our network interfaces?
static struct GNUNET_CONTAINER_Heap * receivers_heap
Expiration heap for receivers (contains struct ReceiverAddress)
static uint16_t my_port
Port number to which we are actually bound.
static char * sockaddr_to_udpaddr_string(const struct sockaddr *address, socklen_t address_len)
Converts address to the address string format used by this communicator in HELLOs.
static void check_timeouts(void *cls)
Task run to check #receiver_heap and #sender_heap for timeouts.
static void calculate_cmac(struct SharedSecret *ss)
Calculate cmac from master in ss.
static struct GNUNET_SCHEDULER_Task * timeout_task
ID of timeout task.
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral)
Setup shared secret for decryption.
#define MAX_SQN_DELTA
What is the maximum delta between KCN sequence numbers that we allow.
int main(int argc, char *const *argv)
The main function for the UNIX communicator.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
#define KCN_THRESHOLD
If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET...
#define MAX_SECRETS
How many shared master secrets do we keep around at most per sender? Should be large enough so that w...
static struct BroadcastInterface * bi_head
Broadcast interface tasks.
static void eddsa_pub_to_hpke_key(struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_EcdhePublicKey *pk)
static void send_msg_with_kx(const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver, struct GNUNET_MQ_Handle *mq)
static void mq_error(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static int iface_proc(void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
Callback function invoked for each interface found.
static void ifc_broadcast(void *cls)
Broadcast our presence on one of our interfaces.
static struct GNUNET_CRYPTO_EcdhePrivateKey my_x25519_private_key
Our private key for HPKE.
static void decrypt_box(const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
We received a box with matching kce.
static void consider_ss_ack(struct SharedSecret *ss)
We established a shared secret with a sender.
static unsigned long long rekey_max_bytes
How often we do rekey based on number of bytes transmitted.
#define AES_IV_SIZE
AES (GCM) IV size.
#define BROADCAST_FREQUENCY
How often do we broadcast our presence on the LAN?
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static char * address
GNS address for this phone.
struct GNUNET_HashCode key
The key used in the DHT.
static OpusEncoder * enc
OPUS encoder.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
static struct GNUNET_FS_UnindexContext * uc
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Constants for network protocols.
API to create, modify and access statistics.
Bandwidth allocation API for applications to interact with.
API of the transport service towards the communicator processes.
void GNUNET_TRANSPORT_communicator_address_remove(struct GNUNET_TRANSPORT_AddressIdentifier *ai)
Notify transport service about an address that this communicator no longer provides for this peer.
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
void GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
struct GNUNET_TRANSPORT_QueueHandle * GNUNET_TRANSPORT_communicator_mq_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *peer, const char *address, uint32_t mtu, uint64_t q_len, uint32_t priority, enum GNUNET_NetworkType nt, enum GNUNET_TRANSPORT_ConnectionStatus cs, struct GNUNET_MQ_Handle *mq)
Notify transport service that a MQ became available due to an "inbound" connection or because the com...
void GNUNET_TRANSPORT_application_validate(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_NetworkType nt, const char *addr)
An application (or a communicator) has received a HELLO (or other address data of another peer) and w...
void GNUNET_TRANSPORT_communicator_mq_update(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_TRANSPORT_QueueHandle *u_qh, uint64_t q_len, uint32_t priority)
Notify transport service that an MQ was updated.
void GNUNET_TRANSPORT_communicator_notify(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *pid, const char *comm, const struct GNUNET_MessageHeader *header)
The communicator asks the transport service to route a message via a different path to another commun...
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls)
Connect to the transport service.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer.
@ GNUNET_TRANSPORT_CC_UNRELIABLE
Transmission is unreliable (e.g.
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Decapsulate a key for a private EdDSA key.
Definition: crypto_hpke.c:407
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_decaps(const struct GNUNET_CRYPTO_EcdhePrivateKey *skR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh decapsulation with own private key and the representative of the received public key...
Definition: crypto_hpke.c:459
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:201
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps(const struct GNUNET_CRYPTO_EcdhePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
Definition: crypto_hpke.c:443
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Encapsulate key material for a EdDSA public key.
Definition: crypto_hpke.c:312
#define GNUNET_CRYPTO_eddsa_sign(priv, ps, sig)
EdDSA sign a given block.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer's key from the file specified in the configuration.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_extract(struct GNUNET_ShortHashCode *prk, const void *salt, size_t salt_len, const void *ikm, size_t ikm_len)
HKDF-Extract using SHA256.
Definition: crypto_hkdf.c:224
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
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk,...)
HKDF-Expand using SHA256.
Definition: crypto_hkdf.c:156
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
Definition: crypto_hash.c:366
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:390
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_PrivateKey *sk, struct GNUNET_CRYPTO_EcdhePrivateKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
Definition: crypto_hpke.c:973
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_PublicKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
Definition: crypto_hpke.c:951
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:350
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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).
#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).
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity 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).
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...) __attribute__((format(printf
Log function that specifies an alternative component.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#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.
#define GNUNET_free_nz(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:482
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:437
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:700
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition: nat_api.c:366
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition: nat_api.c:702
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1000
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:687
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:439
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition: network.c:805
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:771
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:44
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:426
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:405
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition: nt.c:307
@ GNUNET_NT_LOOPBACK
Loopback (same host).
Definition: gnunet_nt_lib.h:53
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:397
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY
UDP Rekey.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK
UDP KX acknowledgement.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1512
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1340
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
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:343
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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_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_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition: time.c:860
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
void receiver(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition: socks.c:330
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE
Signature used by UDP communicator handshake.
const struct UDPAck * ack
const struct GNUNET_PeerIdentity * sender
Interface we broadcast our presence on.
socklen_t salen
Number of bytes in sa.
struct ipv6_mreq mcreq
If this is an IPv6 interface, this is the request we use to join/leave the group.
struct BroadcastInterface * next
Kept in a DLL.
int found
Was this interface found in the last iface_proc() scan?
struct UDPBroadcast bcm
Message we broadcast on this interface.
struct sockaddr * ba
Broadcast address to use on the interface.
struct GNUNET_SCHEDULER_Task * broadcast_task
Task for this broadcast interface.
struct BroadcastInterface * prev
Kept in a DLL.
struct sockaddr * sa
Sender's address of the interface.
Handle to a node in a heap.
Internal representation of the hash map.
Internal representation of the hash map.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
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...
an ECC signature using EdDSA.
HPKE DHKEM encapsulation (X25519) See RFC 9180.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Definition of a command line option.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
Handle for active NAT registrations.
Definition: nat_api.c:72
handle to a socket
Definition: network.c:53
Handle to the interface scanner.
Definition: nt.c:104
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
Handle for the service.
A 256-bit hashcode.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Internal representation of an address a communicator is currently providing for the transport service...
Handle to the TRANSPORT subsystem for application management.
Opaque handle to the transport service for communicators.
Handle returned to identify the internal data structure the transport API has created to manage a mes...
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.
"Plaintext" header at beginning of KX message.
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
struct GNUNET_CRYPTO_HpkeEncapsulation enc
Representative of ephemeral key for KX.
Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct U...
struct GNUNET_ShortHashCode kid
Key and IV identification code.
uint32_t sequence_number
Sequence number used to derive this entry from master key.
struct KeyCacheEntry * next
Kept in a DLL.
struct KeyCacheEntry * prev
Kept in a DLL.
struct SharedSecret * ss
Corresponding shared secret.
Information we track per receiving address we have recently been in contact with (encryption to recei...
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct GNUNET_TIME_Absolute rekey_timeout
Timeout for this receiver address.
struct SharedSecret * ss_tail
Shared secrets we received with target, last used is tail.
char * foreign_addr
Address of the receiver in the human-readable format with the COMMUNICATOR_ADDRESS_PREFIX.
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this receiver.
struct SharedSecret * ss_head
Shared secrets we received from target, first used is head.
struct GNUNET_TRANSPORT_QueueHandle * kx_qh
handle for KX queue with the ch.
unsigned int num_secrets
Length of the DLL at ss_head.
struct GNUNET_TIME_Absolute timeout
Timeout for this receiver address.
size_t kx_mtu
MTU we allowed transport for this receiver's KX queue.
struct sockaddr * address
Address of the other peer.
struct GNUNET_PeerIdentity target
To whom are we talking to.
socklen_t address_len
Length of the address.
struct GNUNET_MQ_Handle * kx_mq
KX message queue we are providing for the ch.
int receiver_destroy_called
receiver_destroy already called on receiver.
size_t d_mtu
MTU we allowed transport for this receiver's default queue.
enum GNUNET_NetworkType nt
Which network type does this queue use?
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.
struct GNUNET_CRYPTO_EcdhePublicKey target_hpke_key
To whom are we talking to.
struct GNUNET_TRANSPORT_QueueHandle * d_qh
handle for default queue with the ch.
struct GNUNET_HashCode key
The address key for this entry.
Closure for #find_sender_by_address()
const struct sockaddr * address
Address we are looking for.
struct SenderAddress * sender
Return value to set if we found a match.
socklen_t address_len
Number of bytes in address.
Information we track per sender address we have recently been in contact with (we decrypt messages fr...
struct GNUNET_PeerIdentity target
To whom are we talking to.
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct sockaddr * address
Address of the other peer.
socklen_t address_len
Length of the address.
enum GNUNET_NetworkType nt
Which network type does this queue use?
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this sender.
unsigned int num_secrets
Length of the DLL at ss_head.
int kce_send_ack_on_finish
When KCE finishes, send ACK if GNUNET_YES.
struct GNUNET_TIME_Absolute timeout
Timeout for this sender.
int kce_task_finished
Is the kce_task finished?
struct GNUNET_SCHEDULER_Task * kce_task
ID of kce working queue task.
struct GNUNET_HashCode key
The address key for this entry.
struct SharedSecret * ss_head
Shared secrets we used with target, first used is head.
int sender_destroy_called
sender_destroy already called on sender.
struct SharedSecret * ss_tail
Shared secrets we used with target, last used is tail.
Shared secret we generated for a particular sender or receiver.
struct KeyCacheEntry * kce_tail
Kept in a DLL, sorted by sequence number.
uint32_t sequence_allowed
Up to which sequence number did the other peer allow us to use this key, or up to which number did we...
struct SharedSecret * next
Kept in a DLL.
unsigned int active_kce_count
Number of active KCN entries.
uint32_t sequence_used
Up to which sequence number did we use this master already? (for encrypting only)
size_t bytes_sent
Bytes sent with this shared secret.
struct SharedSecret * prev
Kept in a DLL.
struct SenderAddress * sender
Sender we use this shared secret with, or NULL.
struct KeyCacheEntry * kce_head
Kept in a DLL, sorted by sequence number.
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.
struct ReceiverAddress * receiver
Receiver we use this shared secret with, or NULL.
struct GNUNET_ShortHashCode master
Master shared secret.
int override_available_acks
Also precompute keys despite sufficient acks (for rekey)
int rekey_initiated
rekey initiated for this secret?
UDP key acknowledgement.
uint32_t sequence_ack
Sequence acknowledgement limit.
struct GNUNET_HashCode cmac
CMAC of the base key being acknowledged.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
UDP message box.
uint8_t gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
Broadcast by peer in LAN announcing its presence.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_PeerIdentity sender
Sender's peer identity.
Encrypted continuation of UDP initial handshake, followed by message header with payload.
struct GNUNET_PeerIdentity sender
Sender's identity.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
Plaintext of a rekey payload in a UDPBox.
struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral
Ephemeral key to rekey with.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_HashCode h_address
Hash of the sender's UDP address.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP broadcast.
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_HpkeEncapsulation enc
Ephemeral key used by the sender.
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the UDP connection (UDP server)
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP connection (UDP client).