GNUnet 0.25.2-11-g84e94e98c
 
Loading...
Searching...
No Matches
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_pils_service.h"
47#include "gnunet_nat_service.h"
51
52/* Shorthand for Logging */
53#define LOG(kind, ...) GNUNET_log_from (kind, "communicator-udp", __VA_ARGS__)
54
58#define DEFAULT_REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
59
63#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
64
68#define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
69
73#define INTERFACE_SCAN_FREQUENCY \
74 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
75
80#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
81
82#define WORKING_QUEUE_INTERVALL \
83 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)
84
88#define AES_KEY_SIZE (256 / 8)
89
93#define AES_IV_SIZE (96 / 8)
94
98#define GCM_TAG_SIZE (128 / 8)
99
100#define GENERATE_AT_ONCE 64
101
111#define KCN_THRESHOLD 96
112
119#define KCN_TARGET 128
120
130#define MAX_SQN_DELTA 160
131
141#define MAX_SECRETS 256
142
147#define DEFAULT_REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
148
153#define COMMUNICATOR_ADDRESS_PREFIX "udp"
154
158#define COMMUNICATOR_CONFIG_SECTION "communicator-udp"
159
161
162
196
197
216
217
223{
228
233
239
240 /* followed by messages */
241
242 /* padding may follow actual messages */
243};
244
245
268
269
295
296
316
317
322struct UDPBox
323{
332
341
342};
343
359
361
365struct SharedSecret;
366
367
373{
378
383
392
397
402};
403
404
409struct SenderAddress;
410
415struct ReceiverAddress;
416
495
496
579
580
705
710{
715
720
725
729 struct sockaddr *sa;
730
734 struct sockaddr *ba;
735
740
745 struct ipv6_mreq mcreq;
746
750 socklen_t salen;
751
755 int found;
756};
757
761static unsigned char ikm[256 / 8];
762
767
772
776static unsigned long long rekey_max_bytes;
777
782
787
792
797
802
807
812
817
822
827
832
837
842
847
852
857
862
867
871static const struct GNUNET_CONFIGURATION_Handle *cfg;
872
877
882
886static struct GNUNET_NAT_Handle *nat;
887
891static uint16_t my_port;
892
897
901static int disable_v6;
902
904
905
906static void
916
917
918static void
928
929
935static void
937{
938 if (AF_INET6 == bi->sa->sa_family)
939 {
940 /* Leave the multicast group */
942 IPPROTO_IPV6,
943 IPV6_LEAVE_GROUP,
944 &bi->mcreq,
945 sizeof(bi->mcreq)))
946 {
948 }
949 }
952 GNUNET_free (bi->sa);
953 GNUNET_free (bi->ba);
954 GNUNET_free (bi);
955}
956
957
958static int
959secret_destroy (struct SharedSecret *ss);
960
966static void
968{
969 struct SharedSecret *ss;
970 receiver->receiver_destroy_called = GNUNET_YES;
971
973 "Disconnecting receiver for peer `%s'\n",
974 GNUNET_i2s (&receiver->target));
975 if (NULL != receiver->kx_qh)
976 {
978 receiver->kx_qh = NULL;
979 receiver->kx_mq = NULL;
980 }
981 if (NULL != receiver->d_qh)
982 {
984 receiver->d_qh = NULL;
985 }
986 else if (NULL != receiver->d_mq)
987 {
989 receiver->d_mq = NULL;
990 }
991 if (NULL != receiver->udp_sock)
992 {
995 receiver->udp_sock = NULL;
996 }
999 &receiver->key,
1000 receiver));
1003 "# receivers active",
1005 GNUNET_NO);
1006 while (NULL != (ss = receiver->ss_head))
1007 {
1008 secret_destroy (ss);
1009 }
1010 GNUNET_free (receiver->address);
1011 GNUNET_free (receiver->foreign_addr);
1013}
1014
1015
1021static void
1023{
1024 struct SharedSecret *ss = kce->ss;
1025
1026 ss->active_kce_count--;
1029 &kce->kid,
1030 kce));
1031 GNUNET_free (kce);
1032}
1033
1034
1042static void
1043get_kid (const struct GNUNET_ShortHashCode *msec,
1044 uint32_t serial,
1045 struct GNUNET_ShortHashCode *kid)
1046{
1047 uint32_t sid = htonl (serial);
1048 struct GNUNET_ShortHashCode prk;
1050 &sid, sizeof (sid),
1051 msec, sizeof (*msec));
1052
1054 sizeof(*kid),
1055 &prk,
1056 "gnunet-communicator-udp-kid",
1057 strlen ("gnunet-communicator-udp-kid"),
1058 NULL,
1059 0);
1060}
1061
1062
1069static void
1070kce_generate (struct SharedSecret *ss, uint32_t seq)
1071{
1072 struct KeyCacheEntry *kce;
1073
1074 GNUNET_assert (0 < seq);
1075 kce = GNUNET_new (struct KeyCacheEntry);
1076 kce->ss = ss;
1077 kce->sequence_number = seq;
1078 get_kid (&ss->master, seq, &kce->kid);
1083 key_cache,
1084 &kce->kid,
1085 kce,
1088 "# KIDs active",
1090 GNUNET_NO);
1091}
1092
1093
1100static int
1102{
1103 struct SenderAddress *sender;
1104 struct ReceiverAddress *receiver;
1105 struct KeyCacheEntry *kce;
1106
1108 "secret %s destroy %u\n",
1109 GNUNET_sh2s (&ss->master),
1111 if (NULL != (sender = ss->sender))
1112 {
1113 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1114 sender->num_secrets--;
1116 "%u sender->num_secrets %u allowed %u used, %u available\n",
1118 sender->acks_available);
1120 if (NULL != ss->sender->kce_task)
1121 {
1123 ss->sender->kce_task = NULL;
1124 }
1125 }
1126 if (NULL != (receiver = ss->receiver))
1127 {
1128 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1129 receiver->num_secrets--;
1130 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1132 "%u receiver->num_secrets\n",
1133 receiver->num_secrets);
1134 }
1135 while (NULL != (kce = ss->kce_head))
1136 kce_destroy (kce);
1137 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1139 "# KIDs active",
1141 GNUNET_NO);
1142 GNUNET_free (ss);
1143 return GNUNET_YES;
1144}
1145
1146
1153static void
1155{
1156 struct SharedSecret *ss;
1159 GNUNET_YES ==
1163 "# senders active",
1165 GNUNET_NO);
1166 while (NULL != (ss = sender->ss_head))
1167 {
1168 secret_destroy (ss);
1169 }
1172}
1173
1174
1183static void
1185 uint32_t serial,
1186 char key[AES_KEY_SIZE],
1187 char iv[AES_IV_SIZE])
1188{
1189 uint32_t sid = htonl (serial);
1190
1193 msec,
1194 "gnunet-communicator-udp-key",
1195 strlen ("gnunet-communicator-udp-key"),
1196 &sid, sizeof (sid),
1197 NULL,
1198 0);
1201 msec,
1202 "gnunet-communicator-udp-iv",
1203 strlen ("gnunet-communicator-udp-iv"),
1204 &sid, sizeof (sid),
1205 NULL,
1206 0);
1207}
1208
1209
1215static void
1222
1223
1229static void
1237
1238
1244static void
1246{
1247 struct GNUNET_TIME_Relative st;
1248 struct GNUNET_TIME_Relative rt;
1249 struct GNUNET_TIME_Relative delay;
1250 struct ReceiverAddress *receiver;
1251 struct SenderAddress *sender;
1252
1253 (void) cls;
1254 timeout_task = NULL;
1257 {
1259 if (0 != rt.rel_value_us)
1260 break;
1262 "Receiver timed out\n");
1264 }
1266 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1267 {
1268 if (GNUNET_YES != sender->sender_destroy_called)
1269 {
1271 if (0 != st.rel_value_us)
1272 break;
1273 sender_destroy (sender);
1274 }
1275 }
1276 delay = GNUNET_TIME_relative_min (rt, st);
1277 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1279}
1280
1281
1287static void
1289{
1291 sizeof(ss->cmac),
1292 &ss->master,
1293 "gnunet-communicator-udp-cmac",
1294 strlen ("gnunet-communicator-udp-cmac"),
1295 NULL,
1296 0);
1297}
1298
1299
1308static void
1310 const void *plaintext,
1311 size_t plaintext_len)
1312{
1313 const struct GNUNET_MessageHeader *hdr = plaintext;
1314 const char *pos = plaintext;
1315
1316 while (ntohs (hdr->size) <= plaintext_len)
1317 {
1319 "# bytes given to core",
1320 ntohs (hdr->size),
1321 GNUNET_NO);
1323 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1326 &sender->target,
1327 hdr,
1329 NULL /* no flow control possible */
1330 ,
1331 NULL));
1332 /* move on to next message, if any */
1333 plaintext_len -= ntohs (hdr->size);
1334 if (plaintext_len < sizeof(*hdr))
1335 break;
1336 pos += ntohs (hdr->size);
1337 hdr = (const struct GNUNET_MessageHeader *) pos;
1338 // TODO for now..., we do not actually sen >1msg or have a way of telling
1339 // if we are done
1340 break;
1341 }
1343 "# bytes padding discarded",
1344 plaintext_len,
1345 GNUNET_NO);
1346}
1347
1348
1357static void
1359 uint32_t serial,
1360 gcry_cipher_hd_t *cipher)
1361{
1362 char key[AES_KEY_SIZE];
1363 char iv[AES_IV_SIZE];
1364 int rc;
1365
1366 GNUNET_assert (0 ==
1367 gcry_cipher_open (cipher,
1368 GCRY_CIPHER_AES256 /* low level: go for speed */
1369 ,
1370 GCRY_CIPHER_MODE_GCM,
1371 0 /* flags */));
1372 get_iv_key (msec, serial, key, iv);
1373 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1374 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1375 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1376 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1377}
1378
1379
1392static int
1393try_decrypt (const struct SharedSecret *ss,
1394 const uint8_t *tag,
1395 uint32_t serial,
1396 const char *in_buf,
1397 size_t in_buf_size,
1398 char *out_buf)
1399{
1400 gcry_cipher_hd_t cipher;
1401
1402 setup_cipher (&ss->master, serial, &cipher);
1404 0 ==
1405 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1406 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1407 {
1408 gcry_cipher_close (cipher);
1410 "# AEAD authentication failures",
1411 1,
1412 GNUNET_NO);
1413 return GNUNET_SYSERR;
1414 }
1415 gcry_cipher_close (cipher);
1416 return GNUNET_OK;
1417}
1418
1419
1426static struct SharedSecret *
1428 )
1429{
1430 struct SharedSecret *ss;
1431
1432 ss = GNUNET_new (struct SharedSecret);
1434 ephemeral,
1435 &ss->master);
1436 calculate_cmac (ss);
1437 return ss;
1438}
1439
1440
1447static struct SharedSecret *
1450{
1451 struct SharedSecret *ss;
1452
1453 ss = GNUNET_new (struct SharedSecret);
1455 &ss->master);
1457 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1458 calculate_cmac (ss);
1459 return ss;
1460}
1461
1462
1470static struct SharedSecret *
1472 ,
1473 struct ReceiverAddress *receiver)
1474{
1475 struct SharedSecret *ss;
1476
1477 ss = GNUNET_new (struct SharedSecret);
1478 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1479 ephemeral,
1480 &ss->master);
1481 calculate_cmac (ss);
1482 ss->receiver = receiver;
1483 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1484 receiver->num_secrets++;
1485 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1486 return ss;
1487}
1488
1489
1497static struct SharedSecret *
1500 struct ReceiverAddress *receiver)
1501{
1502 struct SharedSecret *ss;
1503
1504 ss = GNUNET_new (struct SharedSecret);
1506 c, &ss->master);
1508 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1509 calculate_cmac (ss);
1510 ss->receiver = receiver;
1511 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1512 receiver->num_secrets++;
1513 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1514 return ss;
1515}
1516
1517
1525static void
1527
1528
1536static unsigned int
1537purge_secrets (struct SharedSecret *ss_list_tail)
1538{
1539 struct SharedSecret *pos;
1540 struct SharedSecret *ss_to_purge;
1541 unsigned int deleted = 0;
1542
1544 "Purging secrets.\n");
1545 pos = ss_list_tail;
1546 while (NULL != pos)
1547 {
1548 ss_to_purge = pos;
1549 pos = pos->prev;
1550
1551 // FIXME we may also want to purge old unacked.
1552 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1553 {
1554 secret_destroy (ss_to_purge);
1555 deleted++;
1556 }
1557 }
1559 "Finished purging all, deleted %u.\n", deleted);
1560 return deleted;
1561}
1562
1563
1564static void
1565add_acks (struct SharedSecret *ss, int acks_to_add)
1566{
1567
1568 struct ReceiverAddress *receiver = ss->receiver;
1569
1570 GNUNET_assert (NULL != ss);
1571 GNUNET_assert (NULL != receiver);
1572
1573 if (NULL == receiver->d_qh)
1574 {
1575 receiver->d_qh =
1577 &receiver->target,
1578 receiver->foreign_addr,
1579 receiver->d_mtu,
1580 acks_to_add,
1581 1, /* Priority */
1582 receiver->nt,
1584 receiver->d_mq);
1585 }
1586 else
1587 {
1589 receiver->d_qh,
1590 acks_to_add,
1591 1);
1592 }
1593
1595 "Tell transport we have %u more acks!\n",
1596 acks_to_add);
1597
1598 // Until here for alternative 1
1599
1600 /* move ss to head to avoid discarding it anytime soon! */
1601
1602 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1603 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1604}
1605
1606
1617static int
1618handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1619{
1620 const struct UDPAck *ack = cls;
1621 struct ReceiverAddress *receiver = value;
1622 uint32_t acks_to_add;
1623 uint32_t allowed;
1624
1626 "in handle ack with cmac %s\n",
1627 GNUNET_h2s (&ack->cmac));
1628
1629 (void) key;
1630 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1631 {
1632 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1633 {
1634
1636 "Found matching cmac\n");
1637
1638 allowed = ntohl (ack->sequence_ack);
1639
1640 if (allowed <= ss->sequence_allowed)
1641 {
1643 "Ignoring ack, not giving us increased window\n.");
1644 return GNUNET_NO;
1645 }
1646 acks_to_add = (allowed - ss->sequence_allowed);
1647 GNUNET_assert (0 != acks_to_add);
1648 receiver->acks_available += (allowed - ss->sequence_allowed);
1649 ss->sequence_allowed = allowed;
1650 add_acks (ss, acks_to_add);
1652 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1653 allowed,
1654 acks_to_add,
1655 receiver->acks_available,
1656 GNUNET_sh2s (&ss->master));
1657 return GNUNET_NO;
1658 }
1659 }
1661 "Matching cmac not found for ack!\n");
1662 return GNUNET_YES;
1663}
1664
1665
1674static void
1676{
1677 struct UDPAck ack;
1678 GNUNET_assert (NULL != ss->sender);
1680 "Considering SS UDPAck %s\n",
1681 GNUNET_i2s_full (&ss->sender->target));
1682
1684 "Sender has %u acks available.\n",
1685 ss->sender->acks_available);
1686 /* drop ancient KeyCacheEntries */
1687 while ((NULL != ss->kce_head) &&
1688 (MAX_SQN_DELTA <
1690 kce_destroy (ss->kce_tail);
1691
1692
1694 ack.header.size = htons (sizeof(ack));
1695 ack.sequence_ack = htonl (ss->sequence_allowed);
1696 ack.cmac = ss->cmac;
1698 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1700 ss->sequence_allowed,
1701 GNUNET_sh2s (&(ss->master)));
1703 &ss->sender->target,
1705 &ack.header);
1706}
1707
1708
1709static void
1711{
1712 struct SharedSecret *ss = cls;
1713 ss->sender->kce_task = NULL;
1714
1716 "Precomputing %u keys for master %s\n",
1718 GNUNET_sh2s (&ss->master));
1719 if ((ss->override_available_acks != GNUNET_YES) &&
1720 (KCN_TARGET < ss->sender->acks_available))
1721 return;
1722 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1723 kce_generate (ss, ++ss->sequence_allowed);
1724
1729 if (KCN_TARGET > ss->sender->acks_available)
1730 {
1734 ss);
1735 return;
1736 }
1738 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1742 consider_ss_ack (ss);
1743}
1744
1745
1754static void
1756 const void *buf,
1757 size_t buf_size)
1758{
1759 const struct GNUNET_MessageHeader *hdr;
1760 const struct UDPAck *ack;
1761 const struct UDPRekey *rekey;
1762 struct SharedSecret *ss_rekey;
1763 const char *buf_pos = buf;
1764 size_t bytes_remaining = buf_size;
1765 uint16_t type;
1766
1767 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1768 if (sizeof(*hdr) > bytes_remaining)
1769 {
1770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1771 return; /* no data left */
1772 }
1774 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1775 (unsigned long long) bytes_remaining,
1776 ntohs (hdr->size),
1777 sizeof(*hdr),
1778 ntohs (hdr->type));
1779 if (ntohs (hdr->size) > bytes_remaining)
1780 return; /* buffer too short for indicated message length */
1781 type = ntohs (hdr->type);
1782 switch (type)
1783 {
1785 rekey = (struct UDPRekey*) buf_pos;
1786 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1787 ss_rekey->sender = sender;
1788 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1789 sender->num_secrets++;
1791 "Received rekey secret with cmac %s\n",
1792 GNUNET_h2s (&(ss_rekey->cmac)));
1794 "Received secret with master %s.\n",
1795 GNUNET_sh2s (&(ss_rekey->master)));
1797 "We have %u sequence_allowed.\n",
1798 ss_rekey->sequence_allowed);
1800 "We have a sender %p\n",
1801 ss_rekey->sender);
1803 "We have %u acks available.\n",
1804 ss_rekey->sender->acks_available);
1806 "# rekeying successful",
1807 1,
1808 GNUNET_NO);
1811 // FIXME
1812 kce_generate_cb (ss_rekey);
1813 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1814 WORKING_QUEUE_INTERVALL,
1815 kce_generate_cb,
1816 ss_rekey);*/
1817 // FIXME: Theoretically, this could be an Ack
1818 buf_pos += ntohs (hdr->size);
1819 bytes_remaining -= ntohs (hdr->size);
1820 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1821 if (0 == purge_secrets (sender->ss_tail))
1822 {
1823 // No secret purged. Delete oldest.
1824 if (sender->num_secrets > MAX_SECRETS)
1825 {
1826 secret_destroy (sender->ss_tail);
1827 }
1828 }
1829 break;
1831 /* lookup master secret by 'cmac', then update sequence_max */
1832 ack = (struct UDPAck*) buf_pos;
1834 &sender->key,
1835 &handle_ack,
1836 (void *) ack);
1837 /* There could be more messages after the ACK, handle those as well */
1838 buf_pos += ntohs (hdr->size);
1839 bytes_remaining -= ntohs (hdr->size);
1840 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1841 break;
1842
1844 /* skip padding */
1845 break;
1846
1847 default:
1848 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1849 }
1850 return;
1851}
1852
1853
1861static void
1862decrypt_box (const struct UDPBox *box,
1863 size_t box_len,
1864 struct KeyCacheEntry *kce)
1865{
1866 struct SharedSecret *ss = kce->ss;
1867 struct SharedSecret *ss_c = ss->sender->ss_tail;
1868 struct SharedSecret *ss_tmp;
1869 int ss_destroyed = 0;
1870 char out_buf[box_len - sizeof(*box)];
1871
1872 GNUNET_assert (NULL != ss->sender);
1873 if (GNUNET_OK != try_decrypt (ss,
1874 box->gcm_tag,
1875 kce->sequence_number,
1876 (const char *) &box[1],
1877 sizeof(out_buf),
1878 out_buf))
1879 {
1880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1882 "# Decryption failures with valid KCE",
1883 1,
1884 GNUNET_NO);
1885 kce_destroy (kce);
1886 ss->sender->acks_available--;
1887 return;
1888 }
1889 kce_destroy (kce);
1890 kce = NULL;
1891 ss->bytes_sent += box_len;
1892 ss->sender->acks_available--;
1893 ss->sequence_used++;
1895 "# bytes decrypted with BOX",
1896 sizeof(out_buf),
1897 GNUNET_NO);
1899 "# messages decrypted with BOX",
1900 1,
1901 GNUNET_NO);
1903 "decrypted UDPBox with kid %s\n",
1904 GNUNET_sh2s (&box->kid));
1905 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1906
1907 while (NULL != ss_c)
1908 {
1909 if (ss_c->bytes_sent >= rekey_max_bytes)
1910 {
1912 "Removing SS because rekey bytes reached.\n");
1913 ss_tmp = ss_c->prev;
1914 if (ss == ss_c)
1915 ss_destroyed = 1;
1916 secret_destroy (ss_c);
1917 ss_c = ss_tmp;
1918 continue;
1919 }
1920 ss_c = ss_c->prev;
1921 }
1922 if (1 == ss_destroyed)
1923 return;
1925 "Sender has %u ack left.\n",
1926 ss->sender->acks_available);
1927 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1928 (NULL == ss->sender->kce_task) &&
1930 {
1932 "Sender has %u ack left which is under threshold.\n",
1933 ss->sender->acks_available);
1937 ss);
1938 }
1939}
1940
1941
1946{
1950 const struct sockaddr *address;
1951
1955 socklen_t address_len;
1956
1961};
1962
1963
1975static struct SenderAddress *
1977 const struct sockaddr *address,
1978 socklen_t address_len)
1979{
1980 struct SenderAddress *sender;
1981 struct GNUNET_HashContext *hsh;
1982 struct GNUNET_HashCode sender_key;
1983
1985 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1986 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1987 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1988
1989 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1990 if (NULL != sender)
1991 {
1993 return sender;
1994 }
1995 sender = GNUNET_new (struct SenderAddress);
1996 sender->key = sender_key;
1997 sender->target = *target;
1998 sender->address = GNUNET_memdup (address, address_len);
1999 sender->address_len = address_len;
2001 senders,
2002 &sender->key,
2003 sender,
2006 "# senders active",
2008 GNUNET_NO);
2009 sender->timeout =
2012 sender,
2013 sender->timeout.abs_value_us);
2014 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2015 if (NULL == timeout_task)
2017 return sender;
2018}
2019
2020
2028static int
2030 const struct UDPConfirmation *uc)
2031{
2032 struct UdpHandshakeSignature uhs;
2033
2034 uhs.purpose.purpose = htonl (
2036 uhs.purpose.size = htonl (sizeof(uhs));
2037 uhs.sender = uc->sender;
2038 uhs.receiver = my_identity;
2039 uhs.enc = *enc;
2040 uhs.monotonic_time = uc->monotonic_time;
2043 &uhs,
2044 &uc->sender_sig,
2045 &uc->sender.public_key);
2046}
2047
2048
2057static char *
2058sockaddr_to_udpaddr_string (const struct sockaddr *address,
2059 socklen_t address_len)
2060{
2061 char *ret;
2062
2063 switch (address->sa_family)
2064 {
2065 case AF_INET:
2067 "%s-%s",
2069 GNUNET_a2s (address, address_len));
2070 break;
2071
2072 case AF_INET6:
2074 "%s-%s",
2076 GNUNET_a2s (address, address_len));
2077 break;
2078
2079 default:
2080 GNUNET_assert (0);
2081 }
2082 return ret;
2083}
2084
2085
2086static struct GNUNET_NETWORK_Handle *
2088{
2090
2091 if (NULL == receiver->udp_sock)
2092 {
2093 if (AF_INET6 == receiver->address->sa_family)
2095 else
2097 }
2098 else
2099 udp_sock = receiver->udp_sock;
2100
2101 return udp_sock;
2102}
2103
2104
2113static struct sockaddr *
2114udp_address_to_sockaddr (const char *bindto,
2115 sa_family_t family,
2116 socklen_t *sock_len)
2117{
2118 struct sockaddr *in;
2119 unsigned int port;
2120 char dummy[2];
2121 char *colon;
2122 char *cp;
2123
2124 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2125 {
2126 /* interpreting value as just a PORT number */
2127 if (port > UINT16_MAX)
2128 {
2130 "BINDTO specification `%s' invalid: value too large for port\n",
2131 bindto);
2132 return NULL;
2133 }
2134 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2135 {
2136 struct sockaddr_in *i4;
2137
2138 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2139 i4->sin_family = AF_INET;
2140 i4->sin_port = htons ((uint16_t) port);
2141 *sock_len = sizeof(struct sockaddr_in);
2142 in = (struct sockaddr *) i4;
2143 }
2144 else
2145 {
2146 struct sockaddr_in6 *i6;
2147
2148 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2149 i6->sin6_family = AF_INET6;
2150 i6->sin6_port = htons ((uint16_t) port);
2151 *sock_len = sizeof(struct sockaddr_in6);
2152 in = (struct sockaddr *) i6;
2153 }
2154 return in;
2155 }
2156 cp = GNUNET_strdup (bindto);
2157 colon = strrchr (cp, ':');
2158 if (NULL != colon)
2159 {
2160 /* interpret value after colon as port */
2161 *colon = '\0';
2162 colon++;
2163 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2164 {
2165 /* interpreting value as just a PORT number */
2166 if (port > UINT16_MAX)
2167 {
2169 "BINDTO specification `%s' invalid: value too large for port\n",
2170 bindto);
2171 GNUNET_free (cp);
2172 return NULL;
2173 }
2174 }
2175 else
2176 {
2177 GNUNET_log (
2179 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2180 bindto);
2181 GNUNET_free (cp);
2182 return NULL;
2183 }
2184 }
2185 else
2186 {
2187 /* interpret missing port as 0, aka pick any free one */
2188 port = 0;
2189 }
2190 if (AF_INET6 != family)
2191 {
2192 /* try IPv4 */
2193 struct sockaddr_in v4;
2194
2195 memset (&v4, 0, sizeof(v4));
2196 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2197 {
2198 v4.sin_family = AF_INET;
2199 v4.sin_port = htons ((uint16_t) port);
2200#if HAVE_SOCKADDR_IN_SIN_LEN
2201 v4.sin_len = sizeof(struct sockaddr_in);
2202#endif
2203 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2204 *sock_len = sizeof(struct sockaddr_in);
2205 GNUNET_free (cp);
2206 return in;
2207 }
2208 }
2209 if (AF_INET != family)
2210 {
2211 /* try IPv6 */
2212 struct sockaddr_in6 v6;
2213 const char *start;
2214
2215 memset (&v6, 0, sizeof(v6));
2216 start = cp;
2217 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2218 {
2219 start++; /* skip over '[' */
2220 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2221 }
2222 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2223 {
2224 v6.sin6_family = AF_INET6;
2225 v6.sin6_port = htons ((uint16_t) port);
2226#if HAVE_SOCKADDR_IN_SIN_LEN
2227 v6.sin6_len = sizeof(struct sockaddr_in6);
2228#endif
2229 in = GNUNET_memdup (&v6, sizeof(v6));
2230 *sock_len = sizeof(v6);
2231 GNUNET_free (cp);
2232 return in;
2233 }
2234 }
2235 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2236 GNUNET_free (cp);
2237 return NULL;
2238}
2239
2240
2241static void
2242sock_read (void *cls);
2243
2244
2245static enum GNUNET_GenericReturnValue
2247 const char *address,
2249{
2250 struct GNUNET_HashContext *hsh;
2251 struct ReceiverAddress *receiver;
2252 struct GNUNET_HashCode receiver_key;
2253 const char *path;
2254 struct sockaddr *in;
2255 socklen_t in_len;
2256
2257 if (0 != strncmp (address,
2259 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2260 {
2261 GNUNET_break_op (0);
2262 return GNUNET_SYSERR;
2263 }
2264 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2265 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2266
2267 if (NULL == in)
2268 {
2270 "Failed to setup UDP socket address\n");
2271 return GNUNET_SYSERR;
2272 }
2273 if ((AF_INET6 == in->sa_family) &&
2275 {
2277 "IPv6 disabled, skipping %s\n", address);
2278 GNUNET_free (in);
2279 return GNUNET_SYSERR;
2280 }
2281 else if (AF_INET == in->sa_family)
2282 {
2283 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2284 if (0 == sin->sin_port)
2285 {
2286 GNUNET_free (in);
2287 return GNUNET_NO;
2288 }
2289 }
2290
2292 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2293 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2294 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2295
2297 if (NULL != receiver)
2298 {
2300 "receiver %s already exist or is being connected to\n",
2301 address);
2302 return GNUNET_NO;
2303 }
2304
2306 receiver->udp_sock = udp_sock;
2307 receiver->key = receiver_key;
2308 receiver->address = in;
2309 receiver->address_len = in_len;
2310 receiver->target = *peer;
2311 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2312 &receiver->target_hpke_key);
2313 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2315 receivers,
2316 &receiver->key,
2317 receiver,
2320 "Added %s to receivers with address %s and sock %p\n",
2321 GNUNET_i2s_full (&receiver->target),
2322 address,
2323 udp_sock);
2324 receiver->timeout =
2327 receiver,
2328 receiver->timeout.abs_value_us);
2330 "# receivers active",
2332 GNUNET_NO);
2333 receiver->foreign_addr =
2334 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2335 if (NULL != udp_sock)
2338 udp_sock,
2339 &sock_read,
2340 udp_sock);
2342 if (NULL == timeout_task)
2344 return GNUNET_OK;
2345}
2346
2347
2353static void
2354sock_read (void *cls)
2355{
2356 struct sockaddr_storage sa;
2357 struct sockaddr_in *addr_verify;
2358 socklen_t salen = sizeof(sa);
2359 char buf[UINT16_MAX];
2360 ssize_t rcvd;
2361
2362 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2363
2366 udp_sock,
2367 &sock_read,
2368 udp_sock);
2371 udp_sock,
2372 &sock_read,
2373 udp_sock);
2374 while (1)
2375 {
2377 buf,
2378 sizeof(buf),
2379 (struct sockaddr *) &sa,
2380 &salen);
2381 if (-1 == rcvd)
2382 {
2383 struct sockaddr *addr = (struct sockaddr*) &sa;
2384
2385 if (EAGAIN == errno)
2386 break; // We are done reading data
2388 "Failed to recv from %s family %d failed sock %p\n",
2389 GNUNET_a2s ((struct sockaddr*) &sa,
2390 sizeof (*addr)),
2391 addr->sa_family,
2392 udp_sock);
2394 return;
2395 }
2397 "Read %llu bytes\n",
2398 (unsigned long long) rcvd);
2399 if (0 == rcvd)
2400 {
2401 GNUNET_break_op (0);
2403 "Read 0 bytes from UDP socket\n");
2404 return;
2405 }
2406
2407 /* first, see if it is a GNUNET_BurstMessage */
2408 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2409 {
2410 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2411 struct sockaddr *addr = (struct sockaddr*) &sa;
2412 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2413
2414 GNUNET_assert (0 == bm->local_port);
2416 "Received a burst message for default port\n");
2417 create_receiver (&bm->peer,
2418 address,
2419 NULL);
2420 if (AF_INET6 == addr->sa_family)
2422 else
2426 return;
2427 }
2428 /* second, see if it is a UDPBox */
2429 if (rcvd > sizeof(struct UDPBox))
2430 {
2431 const struct UDPBox *box;
2432 struct KeyCacheEntry *kce;
2433
2434 box = (const struct UDPBox *) buf;
2436 if (NULL != kce)
2437 {
2439 "Found KCE with kid %s\n",
2440 GNUNET_sh2s (&box->kid));
2441 decrypt_box (box, (size_t) rcvd, kce);
2442 continue;
2443 }
2444 }
2445
2446 /* next, check if it is a broadcast */
2447 if (sizeof(struct UDPBroadcast) == rcvd)
2448 {
2449 const struct UDPBroadcast *ub;
2450 struct UdpBroadcastSignature uhs;
2451 struct GNUNET_PeerIdentity sender;
2452
2453 addr_verify = GNUNET_memdup (&sa, salen);
2454 addr_verify->sin_port = 0;
2456 "received UDPBroadcast from %s\n",
2457 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2458 ub = (const struct UDPBroadcast *) buf;
2459 uhs.purpose.purpose = htonl (
2461 uhs.purpose.size = htonl (sizeof(uhs));
2462 uhs.sender = ub->sender;
2463 sender = ub->sender;
2464 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2466 {
2468 "Received our own broadcast\n");
2469 GNUNET_free (addr_verify);
2470 continue;
2471 }
2473 "checking UDPBroadcastSignature for %s\n",
2474 GNUNET_i2s (&sender));
2475 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2476 &uhs.h_address);
2477 if (GNUNET_OK ==
2480 &uhs,
2481 &ub->sender_sig,
2482 &ub->sender.public_key))
2483 {
2484 char *addr_s;
2486
2487 addr_s =
2488 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2489 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2490 /* use our own mechanism to determine network type */
2491 nt =
2492 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2494 "validating address %s received from UDPBroadcast\n",
2495 GNUNET_i2s (&sender));
2497 GNUNET_free (addr_s);
2498 GNUNET_free (addr_verify);
2499 continue;
2500 }
2501 else
2502 {
2504 "VerifyingPeer %s is verifying UDPBroadcast\n",
2507 "Verifying UDPBroadcast from %s failed\n",
2508 GNUNET_i2s (&ub->sender));
2509 }
2510 GNUNET_free (addr_verify);
2511 /* continue with KX, mostly for statistics... */
2512 }
2513
2514
2515 /* finally, test if it is a KX */
2516 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2517 {
2519 "# messages dropped (no kid, too small for KX)",
2520 1,
2521 GNUNET_NO);
2522 continue;
2523 }
2525 "Got KX\n");
2526 {
2527 const struct InitialKX *kx;
2528 struct SharedSecret *ss;
2529 char pbuf[rcvd - sizeof(struct InitialKX)];
2530 const struct UDPConfirmation *uc;
2531 struct SenderAddress *sender;
2532
2533 kx = (const struct InitialKX *) buf;
2536 "Before DEC\n");
2537
2538 if (GNUNET_OK != try_decrypt (ss,
2539 kx->gcm_tag,
2540 0,
2541 &buf[sizeof(*kx)],
2542 sizeof(pbuf),
2543 pbuf))
2544 {
2546 "Unable to decrypt tag, dropping...\n");
2547 GNUNET_free (ss);
2549 stats,
2550 "# messages dropped (no kid, AEAD decryption failed)",
2551 1,
2552 GNUNET_NO);
2553 continue;
2554 }
2556 "Before VERIFY\n");
2557
2558 uc = (const struct UDPConfirmation *) pbuf;
2559
2560 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2561 {
2562 GNUNET_break_op (0);
2563 GNUNET_free (ss);
2565 "# messages dropped (sender signature invalid)",
2566 1,
2567 GNUNET_NO);
2568 continue;
2569 }
2571 "Before SETUP_SENDER\n");
2572
2573 calculate_cmac (ss);
2574 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2575 ss->sender = sender;
2576 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2577 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2578 (NULL == ss->sender->kce_task) &&
2580 {
2581 // 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.
2585 ss);
2586 }
2587 sender->num_secrets++;
2588 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2590 "# messages decrypted without BOX",
2591 1,
2592 GNUNET_NO);
2593 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2594 if (0 == purge_secrets (sender->ss_tail))
2595 {
2596 // No secret purged. Delete oldest.
2597 if (sender->num_secrets > MAX_SECRETS)
2598 {
2599 secret_destroy (sender->ss_tail);
2600 }
2601 }
2602 }
2603 }
2604}
2605
2606
2614static void
2615do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2616{
2617 char pad[pad_size];
2618
2620 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2621 {
2622 struct GNUNET_MessageHeader hdr =
2623 { .size = htons (sizeof(pad)),
2625
2626 memcpy (pad, &hdr, sizeof(hdr));
2627 }
2629 0 ==
2630 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2631}
2632
2633
2634static void
2637 struct GNUNET_MQ_Handle *mq)
2638{
2639 uint16_t msize = ntohs (msg->size);
2640 struct UdpHandshakeSignature uhs;
2641 struct UDPConfirmation uc;
2642 struct InitialKX kx;
2643 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2644 size_t dpos;
2645 gcry_cipher_hd_t out_cipher;
2646 struct SharedSecret *ss;
2647
2648 if (msize > receiver->kx_mtu)
2649 {
2650 GNUNET_break (0);
2651 if (GNUNET_YES != receiver->receiver_destroy_called)
2653 return;
2654 }
2656
2657 /* setup key material */
2659
2660 if (0 == purge_secrets (receiver->ss_tail))
2661 {
2662 // No secret purged. Delete oldest.
2663 if (receiver->num_secrets > MAX_SECRETS)
2664 {
2665 secret_destroy (receiver->ss_tail);
2666 }
2667 }
2668
2669 setup_cipher (&ss->master, 0, &out_cipher);
2670 /* compute 'uc' */
2671 uc.sender = my_identity;
2672 uc.monotonic_time =
2674 uhs.purpose.purpose = htonl (
2676 uhs.purpose.size = htonl (sizeof(uhs));
2677 uhs.sender = my_identity;
2678 uhs.receiver = receiver->target;
2679 uhs.monotonic_time = uc.monotonic_time;
2681 &uhs,
2682 &uc.sender_sig);
2683 /* Leave space for kx */
2684 dpos = sizeof(kx);
2685 /* Append encrypted uc to dgram */
2686 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2687 &dgram[dpos],
2688 sizeof(uc),
2689 &uc,
2690 sizeof(uc)));
2691 dpos += sizeof(uc);
2692 /* Append encrypted payload to dgram */
2694 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2695 dpos += msize;
2696 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2697 /* Datagram starts with kx */
2698 kx.enc = uhs.enc;
2700 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2701 gcry_cipher_close (out_cipher);
2702 memcpy (dgram, &kx, sizeof(kx));
2704 dgram,
2705 sizeof(dgram),
2706 receiver->address,
2707 receiver->address_len))
2708 {
2711 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2712 msize,
2713 GNUNET_a2s (receiver->address,
2714 receiver->address_len),
2715 receiver->address->sa_family,
2719 return;
2720 }
2722 "Sending KX with payload size %u to %s with socket %p\n",
2723 msize,
2724 GNUNET_a2s (receiver->address,
2725 receiver->address_len),
2728}
2729
2730
2739static void
2741 const struct GNUNET_MessageHeader *msg,
2742 void *impl_state)
2743{
2744 struct ReceiverAddress *receiver = impl_state;
2745
2746 GNUNET_assert (mq == receiver->kx_mq);
2748}
2749
2750
2751static void
2753 UDPRekey *rekey)
2754{
2755 struct SharedSecret *ss_rekey;
2756
2758 /* setup key material */
2759 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2760 receiver);
2761 ss_rekey->sequence_allowed = 0;
2763 "Setup secret with k = %s\n",
2764 GNUNET_sh2s (&ss_rekey->master));
2766 "Setup secret with H(k) = %s\n",
2767 GNUNET_h2s (&(ss_rekey->cmac)));
2768
2769 /* Append encrypted payload to dgram */
2771 rekey->header.size = htons (sizeof (struct UDPRekey));
2772}
2773
2774
2783static void
2785 const struct GNUNET_MessageHeader *msg,
2786 void *impl_state)
2787{
2788 struct ReceiverAddress *receiver = impl_state;
2789 struct UDPRekey rekey;
2790 struct SharedSecret *ss;
2791 int inject_rekey = GNUNET_NO;
2792 uint16_t msize = ntohs (msg->size);
2793
2794 GNUNET_assert (mq == receiver->d_mq);
2795 if ((msize > receiver->d_mtu) ||
2796 (0 == receiver->acks_available))
2797 {
2799 "msize: %u, mtu: %llu, acks: %u\n",
2800 (unsigned int) msize,
2801 (unsigned long long) receiver->d_mtu,
2802 receiver->acks_available);
2803
2804 GNUNET_break (0);
2805 if (GNUNET_YES != receiver->receiver_destroy_called)
2807 return;
2808 }
2810
2811 if (receiver->num_secrets > MAX_SECRETS)
2812 {
2813 if ((0 == purge_secrets (receiver->ss_tail)) &&
2814 (NULL != receiver->ss_tail))
2815 {
2816 // No secret purged. Delete oldest.
2817 secret_destroy (receiver->ss_tail);
2818 }
2819 }
2820 /* begin "BOX" encryption method, scan for ACKs from tail! */
2821 ss = receiver->ss_tail;
2822 while (NULL != ss)
2823 {
2824 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2826 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2827 GNUNET_sh2s (&ss->master), ss->sequence_used,
2828 ss->sequence_allowed, ss->bytes_sent);
2829 if (ss->sequence_used >= ss->sequence_allowed)
2830 {
2831 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2832 // "Skipping ss because no acks to use.\n");
2833 ss = ss->prev;
2834 continue;
2835 }
2836 if (ss->bytes_sent >= rekey_max_bytes)
2837 {
2838 struct SharedSecret *ss_tmp;
2840 "Skipping ss because rekey bytes reached.\n");
2841 // FIXME cleanup ss with too many bytes sent!
2842 ss_tmp = ss->prev;
2843 secret_destroy (ss);
2844 ss = ss_tmp;
2845 continue;
2846 }
2847 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2848 {
2849 if (ss->rekey_initiated == GNUNET_NO)
2850 {
2852 "Injecting rekey for ss with byte sent %lu\n",
2853 (unsigned long) ss->bytes_sent);
2854 create_rekey (receiver, ss, &rekey);
2856 payload_len += sizeof (rekey);
2858 }
2859 }
2860 if (0 < ss->sequence_used)
2862 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
2863 GNUNET_sh2s (&ss->master),
2864 ss->sequence_used,
2865 ss->sequence_allowed);
2866 {
2867 char dgram[payload_len];
2868 struct UDPBox *box;
2869 gcry_cipher_hd_t out_cipher;
2870 size_t dpos;
2871
2872 box = (struct UDPBox *) dgram;
2873 ss->sequence_used++;
2874 get_kid (&ss->master, ss->sequence_used, &box->kid);
2875 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2876 /* Append encrypted payload to dgram */
2877 dpos = sizeof(struct UDPBox);
2878 if (GNUNET_YES == inject_rekey)
2879 {
2881 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2882 &rekey, sizeof (rekey)));
2883 dpos += sizeof (rekey);
2884 }
2886 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2887 dpos += msize;
2888 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2889 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2890 box->gcm_tag,
2891 sizeof(box->gcm_tag)));
2892 gcry_cipher_close (out_cipher);
2893
2895 dgram,
2896 payload_len, // FIXME why always send sizeof dgram?
2897 receiver->address,
2898 receiver->address_len))
2899 {
2902 "Sending UDPBox to %s family %d failed sock %p failed\n",
2903 GNUNET_a2s (receiver->address,
2904 receiver->address_len),
2905 receiver->address->sa_family,
2908 return;
2909 }
2911 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
2912 msize,
2913 receiver->acks_available,
2914 (unsigned long) ss->bytes_sent,
2916 ss->bytes_sent += sizeof (dgram);
2917 receiver->acks_available--;
2919 return;
2920 }
2921 }
2923 "No suitable ss found, sending as KX...\n");
2925}
2926
2927
2936static void
2937mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2938{
2939 struct ReceiverAddress *receiver = impl_state;
2941 "Default MQ destroyed\n");
2942 if (mq == receiver->d_mq)
2943 {
2944 receiver->d_mq = NULL;
2945 if (GNUNET_YES != receiver->receiver_destroy_called)
2947 }
2948}
2949
2950
2959static void
2960mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2961{
2962 struct ReceiverAddress *receiver = impl_state;
2964 "KX MQ destroyed\n");
2965 if (mq == receiver->kx_mq)
2966 {
2967 receiver->kx_mq = NULL;
2968 if (GNUNET_YES != receiver->receiver_destroy_called)
2970 }
2971}
2972
2973
2980static void
2981mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2982{
2983 /* Cancellation is impossible with UDP; bail */
2984 GNUNET_assert (0);
2985}
2986
2987
2997static void
2998mq_error (void *cls, enum GNUNET_MQ_Error error)
2999{
3000 struct ReceiverAddress *receiver = cls;
3001
3003 "MQ error in queue to %s: %d\n",
3004 GNUNET_i2s (&receiver->target),
3005 (int) error);
3007}
3008
3009
3017static void
3019{
3020 size_t base_mtu;
3021
3022 switch (receiver->address->sa_family)
3023 {
3024 case AF_INET:
3025 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3026 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3027 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3028 break;
3029
3030 case AF_INET6:
3031 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3032 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3033 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3034 break;
3035
3036 default:
3037 GNUNET_assert (0);
3038 break;
3039 }
3040 /* MTU based on full KX messages */
3041 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3042 - sizeof(struct UDPConfirmation); /* 104 */
3043 /* MTU based on BOXed messages */
3044 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3045
3047 "Setting up MQs and QHs\n");
3048 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3049 1404 (IPv4 + Box) bytes, depending on circumstances... */
3050 if (NULL == receiver->kx_mq)
3053 &mq_cancel,
3054 receiver,
3055 NULL,
3056 &mq_error,
3057 receiver);
3058 if (NULL == receiver->d_mq)
3060 &mq_destroy_d,
3061 &mq_cancel,
3062 receiver,
3063 NULL,
3064 &mq_error,
3065 receiver);
3066
3067 receiver->kx_qh =
3069 &receiver->target,
3070 receiver->foreign_addr,
3071 receiver->kx_mtu,
3073 0, /* Priority */
3074 receiver->nt,
3076 receiver->kx_mq);
3077}
3078
3079
3098static int
3099mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3100{
3101 (void) cls;
3103 "create receiver for mq_init\n");
3104 return create_receiver (peer,
3105 address,
3106 NULL);
3107}
3108
3109
3118static int
3120 const struct GNUNET_HashCode *target,
3121 void *value)
3122{
3123 struct ReceiverAddress *receiver = value;
3124
3125 (void) cls;
3126 (void) target;
3128 return GNUNET_OK;
3129}
3130
3131
3140static int
3142 const struct GNUNET_HashCode *target,
3143 void *value)
3144{
3145 struct SenderAddress *sender = value;
3146
3147 (void) cls;
3148 (void) target;
3149
3150
3151 sender_destroy (sender);
3152 return GNUNET_OK;
3153}
3154
3155
3161static void
3162do_shutdown (void *cls)
3163{
3165 "do_shutdown\n");
3166 GNUNET_stop_burst (NULL);
3167 if (NULL != nat)
3168 {
3170 nat = NULL;
3171 }
3172 while (NULL != bi_head)
3174 if (NULL != broadcast_task)
3175 {
3177 broadcast_task = NULL;
3178 }
3179 if (NULL != timeout_task)
3180 {
3182 timeout_task = NULL;
3183 }
3184 if (NULL != read_v6_task)
3185 {
3187 read_v6_task = NULL;
3188 }
3189 if (NULL != read_v4_task)
3190 {
3192 read_v4_task = NULL;
3193 }
3194 if (NULL != default_v6_sock)
3195 {
3198 default_v6_sock = NULL;
3199 }
3200 if (NULL != default_v4_sock)
3201 {
3204 default_v4_sock = NULL;
3205 }
3208 NULL);
3212 NULL);
3217 if (NULL != timeout_task)
3218 {
3220 timeout_task = NULL;
3221 }
3222 if (NULL != ch)
3223 {
3225 ch = NULL;
3226 }
3227 if (NULL != ah)
3228 {
3230 ah = NULL;
3231 }
3232 if (NULL != pils)
3233 {
3235 pils = NULL;
3236 }
3237 if (NULL != stats)
3238 {
3240 stats = NULL;
3241 }
3242 if (NULL != my_private_key)
3243 {
3245 my_private_key = NULL;
3246 }
3247 if (NULL != is)
3248 {
3250 is = NULL;
3251 }
3253 "do_shutdown finished\n");
3254}
3255
3256
3258{
3259 const struct UDPAck *ack;
3260
3262};
3263
3264static int
3265handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3266{
3267 struct ReceiverAddress *receiver = value;
3268 struct AckInfo *ai = cls;
3269
3270 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3271 {
3272 return GNUNET_YES;
3273 }
3274 handle_ack ((void*) ai->ack, key, receiver);
3275 return GNUNET_YES;
3276}
3277
3278
3288static void
3289enc_notify_cb (void *cls,
3290 const struct GNUNET_PeerIdentity *sender,
3291 const struct GNUNET_MessageHeader *msg)
3292{
3293 struct AckInfo ai;
3294
3295 (void) cls;
3297 "Storing UDPAck received from backchannel from %s\n",
3300 (ntohs (msg->size) != sizeof(struct UDPAck)))
3301 {
3302 GNUNET_break_op (0);
3303 return;
3304 }
3305 ai.ack = (const struct UDPAck *) msg;
3306 ai.sender = sender;
3309 &ai);
3310}
3311
3312
3326static void
3328 void **app_ctx,
3329 int add_remove,
3331 const struct sockaddr *addr,
3332 socklen_t addrlen)
3333{
3334 char *my_addr;
3336
3337 if (GNUNET_YES == add_remove)
3338 {
3340
3341 GNUNET_asprintf (&my_addr,
3342 "%s-%s",
3344 GNUNET_a2s (addr, addrlen));
3345 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3346 ai =
3348 my_addr,
3349 nt,
3351 GNUNET_free (my_addr);
3352 *app_ctx = ai;
3353 }
3354 else
3355 {
3356 ai = *app_ctx;
3358 *app_ctx = NULL;
3359 }
3360}
3361
3362
3368static void
3369ifc_broadcast (void *cls)
3370{
3371 struct BroadcastInterface *bi = cls;
3372 struct GNUNET_TIME_Relative delay;
3373
3374 delay = BROADCAST_FREQUENCY;
3375 delay.rel_value_us =
3377 bi->broadcast_task =
3379
3380 switch (bi->sa->sa_family)
3381 {
3382 case AF_INET: {
3383 static int yes = 1;
3384 static int no = 0;
3385 ssize_t sent;
3386
3387 if (GNUNET_OK !=
3389 SOL_SOCKET,
3390 SO_BROADCAST,
3391 &yes,
3392 sizeof(int)))
3394 "setsockopt");
3396 "creating UDPBroadcast from %s\n",
3397 GNUNET_i2s (&(bi->bcm.sender)));
3399 "sending UDPBroadcast to add %s\n",
3400 GNUNET_a2s (bi->ba, bi->salen));
3402 &bi->bcm,
3403 sizeof(bi->bcm),
3404 bi->ba,
3405 bi->salen);
3406 if (-1 == sent)
3408 "sendto");
3410 SOL_SOCKET,
3411 SO_BROADCAST,
3412 &no,
3413 sizeof(int)))
3415 "setsockopt");
3416 break;
3417 }
3418
3419 case AF_INET6: {
3420 ssize_t sent;
3421 struct sockaddr_in6 dst;
3422
3423 dst.sin6_family = AF_INET6;
3424 dst.sin6_port = htons (my_port);
3425 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3426 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3427
3429 "sending UDPBroadcast\n");
3431 &bi->bcm,
3432 sizeof(bi->bcm),
3433 (const struct sockaddr *) &dst,
3434 sizeof(dst));
3435 if (-1 == sent)
3437 break;
3438 }
3439
3440 default:
3441 GNUNET_break (0);
3442 break;
3443 }
3444}
3445
3446
3461static int
3462iface_proc (void *cls,
3463 const char *name,
3464 int isDefault,
3465 const struct sockaddr *addr,
3466 const struct sockaddr *broadcast_addr,
3467 const struct sockaddr *netmask,
3468 socklen_t addrlen)
3469{
3470 struct BroadcastInterface *bi;
3471 enum GNUNET_NetworkType network;
3472 struct UdpBroadcastSignature ubs;
3473
3474 (void) cls;
3475 (void) netmask;
3476 if (NULL == my_private_key)
3477 return GNUNET_YES;
3478 if (NULL == addr)
3479 return GNUNET_YES; /* need to know our address! */
3480 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3481 if (GNUNET_NT_LOOPBACK == network)
3482 {
3483 /* Broadcasting on loopback does not make sense */
3484 return GNUNET_YES;
3485 }
3486 for (bi = bi_head; NULL != bi; bi = bi->next)
3487 {
3488 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3489 {
3490 bi->found = GNUNET_YES;
3491 return GNUNET_OK;
3492 }
3493 }
3494
3495 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3496 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3497 if ((AF_INET6 == addr->sa_family) && (NULL != default_v6_sock))
3498 return GNUNET_OK; /* not using IPv6 */
3499
3500 bi = GNUNET_new (struct BroadcastInterface);
3501 bi->sa = GNUNET_memdup (addr,
3502 addrlen);
3503 if ( (NULL != broadcast_addr) &&
3504 (addrlen == sizeof (struct sockaddr_in)) )
3505 {
3506 struct sockaddr_in *ba;
3507
3508 ba = GNUNET_memdup (broadcast_addr,
3509 addrlen);
3510 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3511 bi->ba = (struct sockaddr *) ba;
3512 }
3513 bi->salen = addrlen;
3514 bi->found = GNUNET_YES;
3515 bi->bcm.sender = my_identity;
3516 ubs.purpose.purpose = htonl (
3518 ubs.purpose.size = htonl (sizeof(ubs));
3519 ubs.sender = my_identity;
3521 "creating UDPBroadcastSignature for %s\n",
3522 GNUNET_a2s (addr, addrlen));
3523 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3525 &ubs,
3526 &bi->bcm.sender_sig);
3527 if (NULL != bi->ba)
3528 {
3531 }
3532 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3533 {
3534 /* Create IPv6 multicast request */
3535 const struct sockaddr_in6 *s6 =
3536 (const struct sockaddr_in6 *) broadcast_addr;
3537
3539 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3540
3541 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3542 *
3543 * IPV6_JOIN_GROUP
3544 *
3545 * Join a multicast group on a specified local interface. If the
3546 * interface index is specified as 0, the kernel chooses the local
3547 * interface. For example, some kernels look up the multicast
3548 * group in the normal IPv6 routing table and using the resulting
3549 * interface; we do this for each interface, so no need to use
3550 * zero (anymore...).
3551 */
3552 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3553
3554 /* Join the multicast group */
3556 IPPROTO_IPV6,
3557 IPV6_JOIN_GROUP,
3558 &bi->mcreq,
3559 sizeof(bi->mcreq)))
3560 {
3562 }
3563 }
3564 return GNUNET_OK;
3565}
3566
3567
3573static void
3574do_broadcast (void *cls)
3575{
3576 struct BroadcastInterface *bin;
3577
3578 (void) cls;
3579 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3580 bi->found = GNUNET_NO;
3582 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3583 {
3584 bin = bi->next;
3585 if (GNUNET_NO == bi->found)
3586 bi_destroy (bi);
3587 }
3589 &do_broadcast,
3590 NULL);
3591}
3592
3593
3594static void
3596 const struct sockaddr *addr,
3597 socklen_t addrlen)
3598{
3599 /* FIXME: support reversal: #5529 */
3601 "No connection reversal implemented!\n");
3602}
3603
3604
3605static void
3607{
3609 sizeof (*sock_info->actual_address
3610 ));
3611 create_receiver (sock_info->pid,
3612 address,
3613 default_v4_sock == sock_info->udp_sock ||
3614 default_v6_sock == sock_info->udp_sock ?
3615 NULL : sock_info->udp_sock);
3617 GNUNET_free (sock_info);
3618}
3619
3620
3621static void
3622start_burst (const char *addr,
3623 struct GNUNET_TIME_Relative rtt,
3624 struct GNUNET_PeerIdentity *pid)
3625{
3626 struct GNUNET_UdpSocketInfo *sock_info;
3627
3629 "Communicator was called to start burst to address %s from %s\n",
3630 addr,
3631 my_ipv4);
3632
3633 GNUNET_stop_burst (NULL);
3634
3635 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3636 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3637 sock_info->address = GNUNET_strdup (addr);
3638 sock_info->bind_address = my_ipv4;
3639 sock_info->has_port = GNUNET_YES;
3640 sock_info->udp_sock = default_v4_sock;
3641 sock_info->rtt = rtt;
3642 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3643 sock_info->std_port = my_port;
3645 "1 sock addr %s addr %s rtt %lu %u\n",
3646 sock_info->address,
3647 addr,
3648 (unsigned long) sock_info->rtt.rel_value_us,
3649 my_port);
3650 burst_task = GNUNET_get_udp_socket (sock_info,
3652 GNUNET_free (sock_info);
3653}
3654
3655
3656static struct GNUNET_NETWORK_Handle*
3657create_udp_socket (const char *bindto,
3658 sa_family_t family,
3659 struct sockaddr **out,
3660 socklen_t *out_len)
3661{
3662 struct GNUNET_NETWORK_Handle *sock;
3663 struct sockaddr *in;
3664 socklen_t in_len;
3665 struct sockaddr_storage in_sto;
3666 socklen_t sto_len;
3667
3668 in = udp_address_to_sockaddr (bindto, family, &in_len);
3669 if (NULL == in)
3670 {
3672 "Failed to setup UDP socket address with path `%s'\n",
3673 bindto);
3674 return NULL;
3675 }
3676
3677 if ((AF_UNSPEC != family) && (in->sa_family != family))
3678 {
3680 "Invalid UDP socket address setup with path `%s'\n",
3681 bindto);
3682 GNUNET_free (in);
3683 return NULL;
3684 }
3685
3686 sock =
3687 GNUNET_NETWORK_socket_create (in->sa_family,
3688 SOCK_DGRAM,
3689 IPPROTO_UDP);
3690 if (NULL == sock)
3691 {
3694 "Failed to create socket for %s family %d\n",
3695 GNUNET_a2s (in,
3696 in_len),
3697 in->sa_family);
3698 GNUNET_free (in);
3699 return NULL;
3700 }
3701 if (GNUNET_OK !=
3703 in,
3704 in_len))
3705 {
3707 "bind",
3708 bindto);
3710 "Failed to bind socket for %s family %d sock %p\n",
3711 GNUNET_a2s (in,
3712 in_len),
3713 in->sa_family,
3714 sock);
3716 sock = NULL;
3717 GNUNET_free (in);
3718 return NULL;
3719 }
3720
3721 /* We might have bound to port 0, allowing the OS to figure it out;
3722 thus, get the real IN-address from the socket */
3723 sto_len = sizeof(in_sto);
3724 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3725 (struct sockaddr *) &in_sto,
3726 &sto_len))
3727 {
3728 memcpy (&in_sto, in, in_len);
3729 sto_len = in_len;
3730 }
3731 GNUNET_free (in);
3732 *out = GNUNET_malloc (sto_len);
3733 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3734 *out_len = sto_len;
3735 return sock;
3736}
3737
3738
3739static void
3740shutdown_run (struct sockaddr *addrs[2])
3741{
3742 if (NULL != addrs[0])
3743 GNUNET_free (addrs[0]);
3744 if (NULL != addrs[1])
3745 GNUNET_free (addrs[1]);
3747}
3748
3749
3760static void
3762{
3763 char *keyfile;
3765
3766 if (GNUNET_OK !=
3768 "PEER",
3769 "PRIVATE_KEY",
3770 &keyfile))
3771 {
3773 "PEER",
3774 "PRIVATE_KEY");
3776 return;
3777 }
3778 if (GNUNET_SYSERR ==
3780 GNUNET_YES,
3781 &key))
3782 {
3784 "Failed to setup peer's private key\n");
3785 GNUNET_free (keyfile);
3787 return;
3788 }
3789 GNUNET_free (keyfile);
3790 GNUNET_assert (sizeof ikm == sizeof key.d);
3791 memcpy (ikm, key.d, sizeof ikm);
3792}
3793
3794
3795void
3796pid_change_cb (void *cls,
3797 const struct GNUNET_HELLO_Parser *parser,
3798 const struct GNUNET_HashCode *addr_hash)
3799{
3801 "Got PID to derive from `%s':\n",
3802 GNUNET_h2s (addr_hash));
3803 if (NULL == my_private_key)
3805
3807 (uint8_t*) ikm,
3808 addr_hash,
3814 /* start broadcasting */
3815 if (GNUNET_YES !=
3818 "DISABLE_BROADCAST"))
3819 {
3820 if (NULL == broadcast_task)
3822 }
3823}
3824
3825
3826static void
3827run (void *cls,
3828 char *const *args,
3829 const char *cfgfile,
3830 const struct GNUNET_CONFIGURATION_Handle *c)
3831{
3832 const struct sockaddr_in *v4;
3833 char *bindto;
3834 char *bindto6;
3835 struct sockaddr *in[2];
3836 socklen_t in_len[2];
3837
3839 "Entering the run method of udp communicator.\n");
3840
3841 cfg = c;
3843 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3844 (GNUNET_YES ==
3847 "DISABLE_V6")))
3848 {
3850 }
3851
3852 if (GNUNET_OK !=
3855 "BINDTO",
3856 &bindto))
3857 {
3860 "BINDTO");
3861 return;
3862 }
3864 "The udp communicator will bind to %s for IPv4\n",
3865 bindto);
3866 if (GNUNET_YES != disable_v6)
3867 {
3868 if (GNUNET_OK !=
3871 "BINDTO6",
3872 &bindto6))
3873 {
3876 "BINDTO6");
3877 return;
3878 }
3879
3881 "The udp communicator will bind to %s for IPv6\n",
3882 bindto6);
3883 }
3884 else
3885 bindto6 = NULL;
3886 if (GNUNET_OK !=
3889 "REKEY_INTERVAL",
3892
3893 if (GNUNET_OK !=
3896 "REKEY_MAX_BYTES",
3898 {
3900 }
3901
3902 memset (in, 0, sizeof(struct sockaddr*) * 2);
3903 memset (in_len, 0, sizeof(socklen_t) * 2);
3904
3905 GNUNET_assert (bindto);
3907 bindto, AF_INET, &(in[0]), &(in_len[0]));
3908 GNUNET_free (bindto);
3909
3910 if (GNUNET_YES != disable_v6)
3911 {
3912 GNUNET_assert (bindto6);
3914 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3915 GNUNET_free (bindto6);
3916 }
3917 else
3918 default_v6_sock = NULL;
3919
3920 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3921 return;
3922
3923 my_port = 0;
3924 if (NULL != default_v4_sock)
3925 {
3926 GNUNET_assert (in[0]);
3928 "transport",
3929 "Bound to `%s' sock %p\n",
3930 GNUNET_a2s ((const struct sockaddr *) in[0],
3931 in_len[0]),
3933
3934 v4 = (const struct sockaddr_in *) in[0];
3935
3936 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3937 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3938 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3939 }
3940 if (NULL != default_v6_sock)
3941 {
3942 GNUNET_assert (in[1]);
3944 "transport",
3945 "Bound to `%s' sock %p\n",
3946 GNUNET_a2s ((const struct sockaddr *) in[1],
3947 in_len[1]),
3949 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3950 }
3951 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3960 /* start reading */
3961 if (NULL != default_v4_sock)
3964 &sock_read,
3966 else
3967 read_v4_task = NULL;
3968 if (NULL != default_v6_sock)
3971 &sock_read,
3973 else
3974 read_v6_task = NULL;
3979 &mq_init,
3980 NULL,
3982 NULL,
3983 &start_burst);
3984 if (NULL == ch)
3985 {
3986 GNUNET_break (0);
3987 shutdown_run (in);
3988 return;
3989 }
3991 if (NULL == ah)
3992 {
3993 GNUNET_break (0);
3994 shutdown_run (in);
3995 return;
3996 }
3997 /* start broadcasting */
3998 if (GNUNET_YES !=
4001 "DISABLE_BROADCAST"))
4002 {
4004 }
4005 load_ikm ();
4007 GNUNET_assert (NULL != pils);
4008
4011 IPPROTO_UDP,
4012 (NULL != in[0]? 1 : 0)
4013 + (NULL != in[1]? 1 : 0),
4014 (const struct sockaddr**)
4015 (NULL != in[0]? in : &(in[1])),
4016 NULL != in[0]? in_len : &(in_len[1]),
4019 NULL /* closure */);
4020 if (NULL != in[0])
4021 GNUNET_free (in[0]);
4022 if (NULL != in[1])
4023 GNUNET_free (in[1]);
4024}
4025
4026
4027GNUNET_DAEMON_MAIN ("gnunet-communicator-udp",
4028 _ ("GNUnet UDP communicator"),
4029 &run)
4030/* end of gnunet-communicator-udp.c */
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:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static uint16_t port
Port number.
Definition gnunet-bcd.c:146
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
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.
void pid_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
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 unsigned char ikm[256/8]
The initial key material for the peer.
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 struct GNUNET_NETWORK_Handle * create_udp_socket(const char *bindto, sa_family_t family, struct sockaddr **out, socklen_t *out_len)
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 struct GNUNET_SCHEDULER_Task * read_v6_task
ID of read IPv6 task.
static struct GNUNET_SCHEDULER_Task * read_v4_task
ID of read IPv4 task.
static void mq_destroy_kx(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
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 struct GNUNET_NETWORK_Handle * default_v4_sock
Our IPv4 socket.
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.
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
static void start_burst(const char *addr, struct GNUNET_TIME_Relative rtt, struct GNUNET_PeerIdentity *pid)
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 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 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 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)
#define DEFAULT_REKEY_MAX_BYTES
Default value for how often we do rekey based on number of bytes transmitted? (additionally randomize...
static struct GNUNET_CRYPTO_HpkePrivateKey my_x25519_private_key
Our private key for HPKE.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static void shutdown_run(struct sockaddr *addrs[2])
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 void load_ikm()
Get the initial secret key for generating the peer id.
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.
static void udp_socket_notify(struct GNUNET_UdpSocketInfo *sock_info)
#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 eddsa_pub_to_hpke_key(struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_HpkePublicKey *pk)
static void bi_destroy(struct BroadcastInterface *bi)
An interface went away, stop broadcasting on it.
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 sockaddr * udp_address_to_sockaddr(const char *bindto, sa_family_t family, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
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 eddsa_priv_to_hpke_key(struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
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.
char * my_ipv4
Our ipv4 address.
static struct GNUNET_SCHEDULER_Task * burst_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.
#define LOG(kind,...)
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 enum GNUNET_GenericReturnValue create_receiver(const struct GNUNET_PeerIdentity *peer, const char *address, struct GNUNET_NETWORK_Handle *udp_sock)
static struct GNUNET_NETWORK_Handle * get_socket(struct ReceiverAddress *receiver)
static void send_msg_with_kx(const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver, struct GNUNET_MQ_Handle *mq)
static struct GNUNET_NETWORK_Handle * default_v6_sock
Our IPv6 socket.
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_PILS_Handle * pils
For PILS.
static void decrypt_box(const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
We received a box with matching kce.
static unsigned int purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
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_BlindablePrivateKey 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_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_FS_UnindexContext * uc
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:367
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:390
void GNUNET_PILS_derive_pid(size_t seed_key_bytes, const uint8_t seed_key[seed_key_bytes], const struct GNUNET_HashCode *addrs_hash, struct GNUNET_CRYPTO_EddsaPrivateKey *outkey)
Generate the peer id from the addresses hash and the initial secret key.
Definition pils_api.c:507
Constants for network protocols.
#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.
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_burst_finished(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
The communicator tells the transport service that it finished the burst.
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_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
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, GNUNET_TRANSPORT_StartBurstNotify sb)
Connect to the transport service.
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_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
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.
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_encaps(const struct GNUNET_CRYPTO_HpkePublicKey *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...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_key_from_file(const char *filename, int do_create, struct GNUNET_CRYPTO_EddsaPrivateKey *pkey)
Create a new private key by reading it from a file.
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_decaps(const struct GNUNET_CRYPTO_HpkePrivateKey *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...
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.
#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.
@ 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.
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.
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.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_BlindablePrivateKey *sk, struct GNUNET_CRYPTO_HpkePrivateKey *sk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
#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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_BlindablePublicKey *pk, struct GNUNET_CRYPTO_HpkePublicKey *pk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
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.
#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_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_SCHEDULER_Task * GNUNET_get_udp_socket(struct GNUNET_UdpSocketInfo *sock_info, GNUNET_NotifyUdpSocket nus)
Method to get a UDP socket for a peer that is natted.
Definition nat.c:509
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:703
void GNUNET_stop_burst(struct GNUNET_NETWORK_Handle *do_not_touch)
Method to stop all sockets we established to the other peer.
Definition nat.c:564
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:1001
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:688
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:833
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:806
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:772
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition nt.c:428
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition nt.c:407
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:309
@ GNUNET_NT_LOOPBACK
Loopback (same host).
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition os_network.c:397
#define GNUNET_DAEMON_MAIN(daemon_name, daemon_help, init_cb)
#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:1511
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:1339
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
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:1304
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:1277
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).
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:344
#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:406
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:636
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
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
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.
Message send during burst mode.
struct GNUNET_PeerIdentity peer
The peer who send the msg.
unsigned int local_port
The local port the message was send from.
Handle to a node in a heap.
Internal representation of the hash map.
Internal representation of the hash map.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
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 public key used for decryption.
A public key used for encryption.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
Context for parsing HELLOs.
Definition hello-uri.c:232
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
A handle for the PILS service.
Definition pils_api.c:82
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.
Struct with the socket we like to use to send messages to another peer.
const char * bind_address
Our address without port.
enum GNUNET_GenericReturnValue has_port
Flag indicating, if the address is without port information.
struct GNUNET_TIME_Relative rtt
The actual RTT between the peers.
char * address
The address of the other peer without port.
unsigned int std_port
Default local port we are bound to.
struct sockaddr * actual_address
The address of the other peer we received a burst message from.
struct GNUNET_NETWORK_Handle * udp_sock
struct GNUNET_PeerIdentity * pid
The peer we like to connect to.
"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.
struct GNUNET_SCHEDULER_Task * read_task
Read task, if this receiver has its own socket.
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.
struct GNUNET_NETWORK_Handle * udp_sock
Socket this receiver got via NAT traversal.
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_HpkePublicKey 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_SignaturePurpose 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_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP connection (UDP client).