GNUnet 0.27.0
 
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, 2026 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
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
856static const struct GNUNET_CONFIGURATION_Handle *cfg;
857
862
867
871static struct GNUNET_NAT_Handle *nat;
872
876static uint16_t my_port;
877
882
886static int disable_v6;
887
889
890
891static void
901
902
903static void
913
914
920static void
922{
923 if (AF_INET6 == bi->sa->sa_family)
924 {
925 /* Leave the multicast group */
927 IPPROTO_IPV6,
928 IPV6_LEAVE_GROUP,
929 &bi->mcreq,
930 sizeof(bi->mcreq)))
931 {
933 }
934 }
937 GNUNET_free (bi->sa);
938 GNUNET_free (bi->ba);
939 GNUNET_free (bi);
940}
941
942
943static int
944secret_destroy (struct SharedSecret *ss);
945
951static void
953{
954 struct SharedSecret *ss;
955 receiver->receiver_destroy_called = GNUNET_YES;
956
958 "Disconnecting receiver for peer `%s'\n",
959 GNUNET_i2s (&receiver->target));
960 if (NULL != receiver->kx_qh)
961 {
963 receiver->kx_qh = NULL;
964 receiver->kx_mq = NULL;
965 }
966 if (NULL != receiver->d_qh)
967 {
969 receiver->d_qh = NULL;
970 }
971 else if (NULL != receiver->d_mq)
972 {
974 receiver->d_mq = NULL;
975 }
976 if (NULL != receiver->udp_sock)
977 {
980 receiver->udp_sock = NULL;
981 }
984 &receiver->key,
985 receiver));
988 "# receivers active",
990 GNUNET_NO);
991 while (NULL != (ss = receiver->ss_head))
992 {
993 secret_destroy (ss);
994 }
995 GNUNET_free (receiver->address);
996 GNUNET_free (receiver->foreign_addr);
998}
999
1000
1006static void
1008{
1009 struct SharedSecret *ss = kce->ss;
1010
1011 ss->active_kce_count--;
1014 &kce->kid,
1015 kce));
1016 GNUNET_free (kce);
1017}
1018
1019
1027static void
1028get_kid (const struct GNUNET_ShortHashCode *msec,
1029 uint32_t serial,
1030 struct GNUNET_ShortHashCode *kid)
1031{
1032 uint32_t sid = htonl (serial);
1033 struct GNUNET_ShortHashCode prk;
1035 &sid, sizeof (sid),
1036 msec, sizeof (*msec));
1037
1039 kid,
1040 sizeof(*kid),
1041 &prk,
1042 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-kid"));
1043}
1044
1045
1052static void
1053kce_generate (struct SharedSecret *ss, uint32_t seq)
1054{
1055 struct KeyCacheEntry *kce;
1056
1057 GNUNET_assert (0 < seq);
1058 kce = GNUNET_new (struct KeyCacheEntry);
1059 kce->ss = ss;
1060 kce->sequence_number = seq;
1061 get_kid (&ss->master, seq, &kce->kid);
1066 key_cache,
1067 &kce->kid,
1068 kce,
1071 "# KIDs active",
1073 GNUNET_NO);
1074}
1075
1076
1083static int
1085{
1086 struct SenderAddress *sender;
1087 struct ReceiverAddress *receiver;
1088 struct KeyCacheEntry *kce;
1089
1091 "secret %s destroy %u\n",
1092 GNUNET_sh2s (&ss->master),
1094 if (NULL != (sender = ss->sender))
1095 {
1096 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1097 sender->num_secrets--;
1099 "%u sender->num_secrets %u allowed %u used, %u available\n",
1101 sender->acks_available);
1103 if (NULL != ss->sender->kce_task)
1104 {
1106 ss->sender->kce_task = NULL;
1107 }
1108 }
1109 if (NULL != (receiver = ss->receiver))
1110 {
1111 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1112 receiver->num_secrets--;
1113 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1115 "%u receiver->num_secrets\n",
1116 receiver->num_secrets);
1117 }
1118 while (NULL != (kce = ss->kce_head))
1119 kce_destroy (kce);
1120 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1122 "# KIDs active",
1124 GNUNET_NO);
1125 GNUNET_free (ss);
1126 return GNUNET_YES;
1127}
1128
1129
1136static void
1138{
1139 struct SharedSecret *ss;
1142 GNUNET_YES ==
1146 "# senders active",
1148 GNUNET_NO);
1149 while (NULL != (ss = sender->ss_head))
1150 {
1151 secret_destroy (ss);
1152 }
1155}
1156
1157
1166static void
1168 uint32_t serial,
1169 char key[AES_KEY_SIZE],
1170 char iv[AES_IV_SIZE])
1171{
1172 uint32_t sid = htonl (serial);
1173
1175 key,
1177 msec,
1178 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-key"),
1181 iv,
1183 msec,
1184 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-iv"),
1186}
1187
1188
1194static void
1201
1202
1208static void
1216
1217
1223static void
1225{
1226 struct GNUNET_TIME_Relative st;
1227 struct GNUNET_TIME_Relative rt;
1228 struct GNUNET_TIME_Relative delay;
1229 struct ReceiverAddress *receiver;
1230 struct SenderAddress *sender;
1231
1232 (void) cls;
1233 timeout_task = NULL;
1236 {
1238 if (0 != rt.rel_value_us)
1239 break;
1241 "Receiver timed out\n");
1243 }
1245 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1246 {
1247 if (GNUNET_YES != sender->sender_destroy_called)
1248 {
1250 if (0 != st.rel_value_us)
1251 break;
1252 sender_destroy (sender);
1253 }
1254 }
1255 delay = GNUNET_TIME_relative_min (rt, st);
1256 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1258}
1259
1260
1266static void
1268{
1270 &ss->cmac,
1271 sizeof(ss->cmac),
1272 &ss->master,
1273 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-cmac"));
1274}
1275
1276
1285static void
1287 const void *plaintext,
1288 size_t plaintext_len)
1289{
1290 const struct GNUNET_MessageHeader *hdr = plaintext;
1291 const char *pos = plaintext;
1292
1293 while (ntohs (hdr->size) <= plaintext_len)
1294 {
1296 "# bytes given to core",
1297 ntohs (hdr->size),
1298 GNUNET_NO);
1300 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1303 &sender->target,
1304 hdr,
1306 NULL /* no flow control possible */
1307 ,
1308 NULL));
1309 /* move on to next message, if any */
1310 plaintext_len -= ntohs (hdr->size);
1311 if (plaintext_len < sizeof(*hdr))
1312 break;
1313 pos += ntohs (hdr->size);
1314 hdr = (const struct GNUNET_MessageHeader *) pos;
1315 // TODO for now..., we do not actually sen >1msg or have a way of telling
1316 // if we are done
1317 break;
1318 }
1320 "# bytes padding discarded",
1321 plaintext_len,
1322 GNUNET_NO);
1323}
1324
1325
1334static void
1336 uint32_t serial,
1337 gcry_cipher_hd_t *cipher)
1338{
1339 char key[AES_KEY_SIZE];
1340 char iv[AES_IV_SIZE];
1341 int rc;
1342
1343 GNUNET_assert (0 ==
1344 gcry_cipher_open (cipher,
1345 GCRY_CIPHER_AES256 /* low level: go for speed */
1346 ,
1347 GCRY_CIPHER_MODE_GCM,
1348 0 /* flags */));
1349 get_iv_key (msec, serial, key, iv);
1350 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1351 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1352 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1353 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1354}
1355
1356
1369static int
1370try_decrypt (const struct SharedSecret *ss,
1371 const uint8_t *tag,
1372 uint32_t serial,
1373 const char *in_buf,
1374 size_t in_buf_size,
1375 char *out_buf)
1376{
1377 gcry_cipher_hd_t cipher;
1378
1379 setup_cipher (&ss->master, serial, &cipher);
1381 0 ==
1382 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1383 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1384 {
1385 gcry_cipher_close (cipher);
1387 "# AEAD authentication failures",
1388 1,
1389 GNUNET_NO);
1390 return GNUNET_SYSERR;
1391 }
1392 gcry_cipher_close (cipher);
1393 return GNUNET_OK;
1394}
1395
1396
1403static struct SharedSecret *
1405 )
1406{
1408 struct SharedSecret *ss;
1409
1412
1413 ss = GNUNET_new (struct SharedSecret);
1415 ephemeral,
1416 &ss->master);
1417 calculate_cmac (ss);
1418 return ss;
1419}
1420
1421
1428static struct SharedSecret *
1431{
1433 struct GNUNET_CRYPTO_HpkePrivateKey my_hpke_key;
1434 struct SharedSecret *ss;
1435
1438
1439 eddsa_priv_to_hpke_key (my_private_key, &my_hpke_key);
1440
1441 ss = GNUNET_new (struct SharedSecret);
1443 &ss->master);
1445 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1446 calculate_cmac (ss);
1447 return ss;
1448}
1449
1450
1458static struct SharedSecret *
1460 ,
1461 struct ReceiverAddress *receiver)
1462{
1463 struct SharedSecret *ss;
1464
1465 ss = GNUNET_new (struct SharedSecret);
1466 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1467 ephemeral,
1468 &ss->master);
1469 calculate_cmac (ss);
1470 ss->receiver = receiver;
1471 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1472 receiver->num_secrets++;
1473 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1474 return ss;
1475}
1476
1477
1485static struct SharedSecret *
1488 struct ReceiverAddress *receiver)
1489{
1490 struct SharedSecret *ss;
1491
1492 ss = GNUNET_new (struct SharedSecret);
1494 c, &ss->master);
1496 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1497 calculate_cmac (ss);
1498 ss->receiver = receiver;
1499 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1500 receiver->num_secrets++;
1501 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1502 return ss;
1503}
1504
1505
1513static void
1515
1516
1524static unsigned int
1525purge_secrets (struct SharedSecret *ss_list_tail)
1526{
1527 struct SharedSecret *pos;
1528 struct SharedSecret *ss_to_purge;
1529 unsigned int deleted = 0;
1530
1532 "Purging secrets.\n");
1533 pos = ss_list_tail;
1534 while (NULL != pos)
1535 {
1536 ss_to_purge = pos;
1537 pos = pos->prev;
1538
1539 // FIXME we may also want to purge old unacked.
1540 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1541 {
1542 secret_destroy (ss_to_purge);
1543 deleted++;
1544 }
1545 }
1547 "Finished purging all, deleted %u.\n", deleted);
1548 return deleted;
1549}
1550
1551
1552static void
1553add_acks (struct SharedSecret *ss, int acks_to_add)
1554{
1555
1556 struct ReceiverAddress *receiver = ss->receiver;
1557
1558 GNUNET_assert (NULL != ss);
1559 GNUNET_assert (NULL != receiver);
1560
1561 if (NULL == receiver->d_qh)
1562 {
1563 receiver->d_qh =
1565 &receiver->target,
1566 receiver->foreign_addr,
1567 receiver->d_mtu,
1568 acks_to_add,
1569 1, /* Priority */
1570 receiver->nt,
1572 receiver->d_mq);
1573 }
1574 else
1575 {
1577 receiver->d_qh,
1578 acks_to_add,
1579 1);
1580 }
1581
1583 "Tell transport we have %u more acks!\n",
1584 acks_to_add);
1585
1586 // Until here for alternative 1
1587
1588 /* move ss to head to avoid discarding it anytime soon! */
1589
1590 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1591 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1592}
1593
1594
1605static int
1606handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1607{
1608 const struct UDPAck *ack = cls;
1609 struct ReceiverAddress *receiver = value;
1610 uint32_t acks_to_add;
1611 uint32_t allowed;
1612
1614 "in handle ack with cmac %s\n",
1615 GNUNET_h2s (&ack->cmac));
1616
1617 (void) key;
1618 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1619 {
1620 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1621 {
1622
1624 "Found matching cmac\n");
1625
1626 allowed = ntohl (ack->sequence_ack);
1627
1628 if (allowed <= ss->sequence_allowed)
1629 {
1631 "Ignoring ack, not giving us increased window\n.");
1632 return GNUNET_NO;
1633 }
1634 acks_to_add = (allowed - ss->sequence_allowed);
1635 GNUNET_assert (0 != acks_to_add);
1636 receiver->acks_available += (allowed - ss->sequence_allowed);
1637 ss->sequence_allowed = allowed;
1638 add_acks (ss, acks_to_add);
1640 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1641 allowed,
1642 acks_to_add,
1643 receiver->acks_available,
1644 GNUNET_sh2s (&ss->master));
1645 return GNUNET_NO;
1646 }
1647 }
1649 "Matching cmac not found for ack!\n");
1650 return GNUNET_YES;
1651}
1652
1653
1662static void
1664{
1665 struct UDPAck ack;
1666 GNUNET_assert (NULL != ss->sender);
1668 "Considering SS UDPAck %s\n",
1669 GNUNET_i2s_full (&ss->sender->target));
1670
1672 "Sender has %u acks available.\n",
1673 ss->sender->acks_available);
1674 /* drop ancient KeyCacheEntries */
1675 while ((NULL != ss->kce_head) &&
1676 (MAX_SQN_DELTA <
1678 kce_destroy (ss->kce_tail);
1679
1680
1682 ack.header.size = htons (sizeof(ack));
1683 ack.sequence_ack = htonl (ss->sequence_allowed);
1684 ack.cmac = ss->cmac;
1686 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1688 ss->sequence_allowed,
1689 GNUNET_sh2s (&(ss->master)));
1691 &ss->sender->target,
1693 &ack.header);
1694}
1695
1696
1697static void
1699{
1700 struct SharedSecret *ss = cls;
1701 ss->sender->kce_task = NULL;
1702
1704 "Precomputing %u keys for master %s\n",
1706 GNUNET_sh2s (&ss->master));
1707 if ((ss->override_available_acks != GNUNET_YES) &&
1708 (KCN_TARGET < ss->sender->acks_available))
1709 return;
1710 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1711 kce_generate (ss, ++ss->sequence_allowed);
1712
1717 if (KCN_TARGET > ss->sender->acks_available)
1718 {
1722 ss);
1723 return;
1724 }
1726 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1730 consider_ss_ack (ss);
1731}
1732
1733
1742static void
1744 const void *buf,
1745 size_t buf_size)
1746{
1747 const struct GNUNET_MessageHeader *hdr;
1748 const struct UDPAck *ack;
1749 const struct UDPRekey *rekey;
1750 struct SharedSecret *ss_rekey;
1751 const char *buf_pos = buf;
1752 size_t bytes_remaining = buf_size;
1753 uint16_t type;
1754
1755 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1756 if (sizeof(*hdr) > bytes_remaining)
1757 {
1758 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1759 return; /* no data left */
1760 }
1762 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1763 (unsigned long long) bytes_remaining,
1764 ntohs (hdr->size),
1765 sizeof(*hdr),
1766 ntohs (hdr->type));
1767 if (ntohs (hdr->size) > bytes_remaining)
1768 return; /* buffer too short for indicated message length */
1769 type = ntohs (hdr->type);
1770 switch (type)
1771 {
1773 rekey = (struct UDPRekey*) buf_pos;
1774 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1775 ss_rekey->sender = sender;
1776 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1777 sender->num_secrets++;
1779 "Received rekey secret with cmac %s\n",
1780 GNUNET_h2s (&(ss_rekey->cmac)));
1782 "Received secret with master %s.\n",
1783 GNUNET_sh2s (&(ss_rekey->master)));
1785 "We have %u sequence_allowed.\n",
1786 ss_rekey->sequence_allowed);
1788 "We have a sender %p\n",
1789 ss_rekey->sender);
1791 "We have %u acks available.\n",
1792 ss_rekey->sender->acks_available);
1794 "# rekeying successful",
1795 1,
1796 GNUNET_NO);
1799 // FIXME
1800 kce_generate_cb (ss_rekey);
1801 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1802 WORKING_QUEUE_INTERVALL,
1803 kce_generate_cb,
1804 ss_rekey);*/
1805 // FIXME: Theoretically, this could be an Ack
1806 buf_pos += ntohs (hdr->size);
1807 bytes_remaining -= ntohs (hdr->size);
1808 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1809 if (0 == purge_secrets (sender->ss_tail))
1810 {
1811 // No secret purged. Delete oldest.
1812 if (sender->num_secrets > MAX_SECRETS)
1813 {
1814 secret_destroy (sender->ss_tail);
1815 }
1816 }
1817 break;
1819 /* lookup master secret by 'cmac', then update sequence_max */
1820 ack = (struct UDPAck*) buf_pos;
1822 &sender->key,
1823 &handle_ack,
1824 (void *) ack);
1825 /* There could be more messages after the ACK, handle those as well */
1826 buf_pos += ntohs (hdr->size);
1827 bytes_remaining -= ntohs (hdr->size);
1828 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1829 break;
1830
1832 /* skip padding */
1833 break;
1834
1835 default:
1836 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1837 }
1838 return;
1839}
1840
1841
1849static void
1850decrypt_box (const struct UDPBox *box,
1851 size_t box_len,
1852 struct KeyCacheEntry *kce)
1853{
1854 struct SharedSecret *ss = kce->ss;
1855 struct SharedSecret *ss_c = ss->sender->ss_tail;
1856 struct SharedSecret *ss_tmp;
1857 int ss_destroyed = 0;
1858 char out_buf[box_len - sizeof(*box)];
1859
1860 GNUNET_assert (NULL != ss->sender);
1861 if (GNUNET_OK != try_decrypt (ss,
1862 box->gcm_tag,
1863 kce->sequence_number,
1864 (const char *) &box[1],
1865 sizeof(out_buf),
1866 out_buf))
1867 {
1868 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1870 "# Decryption failures with valid KCE",
1871 1,
1872 GNUNET_NO);
1873 kce_destroy (kce);
1874 ss->sender->acks_available--;
1875 return;
1876 }
1877 kce_destroy (kce);
1878 kce = NULL;
1879 ss->bytes_sent += box_len;
1880 ss->sender->acks_available--;
1881 ss->sequence_used++;
1883 "# bytes decrypted with BOX",
1884 sizeof(out_buf),
1885 GNUNET_NO);
1887 "# messages decrypted with BOX",
1888 1,
1889 GNUNET_NO);
1891 "decrypted UDPBox with kid %s\n",
1892 GNUNET_sh2s (&box->kid));
1893 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1894
1895 while (NULL != ss_c)
1896 {
1897 if (ss_c->bytes_sent >= rekey_max_bytes)
1898 {
1900 "Removing SS because rekey bytes reached.\n");
1901 ss_tmp = ss_c->prev;
1902 if (ss == ss_c)
1903 ss_destroyed = 1;
1904 secret_destroy (ss_c);
1905 ss_c = ss_tmp;
1906 continue;
1907 }
1908 ss_c = ss_c->prev;
1909 }
1910 if (1 == ss_destroyed)
1911 return;
1913 "Sender has %u ack left.\n",
1914 ss->sender->acks_available);
1915 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1916 (NULL == ss->sender->kce_task) &&
1918 {
1920 "Sender has %u ack left which is under threshold.\n",
1921 ss->sender->acks_available);
1925 ss);
1926 }
1927}
1928
1929
1934{
1938 const struct sockaddr *address;
1939
1943 socklen_t address_len;
1944
1949};
1950
1951
1963static struct SenderAddress *
1965 const struct sockaddr *address,
1966 socklen_t address_len)
1967{
1968 struct SenderAddress *sender;
1969 struct GNUNET_HashContext *hsh;
1970 struct GNUNET_HashCode sender_key;
1971
1973 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1974 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1975 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1976
1977 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1978 if (NULL != sender)
1979 {
1981 return sender;
1982 }
1983 sender = GNUNET_new (struct SenderAddress);
1984 sender->key = sender_key;
1985 sender->target = *target;
1986 sender->address = GNUNET_memdup (address, address_len);
1987 sender->address_len = address_len;
1989 senders,
1990 &sender->key,
1991 sender,
1994 "# senders active",
1996 GNUNET_NO);
1997 sender->timeout =
2000 sender,
2001 sender->timeout.abs_value_us);
2002 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2003 if (NULL == timeout_task)
2005 return sender;
2006}
2007
2008
2016static int
2018 const struct UDPConfirmation *uc)
2019{
2020 const struct GNUNET_PeerIdentity *my_identity;
2021 struct UdpHandshakeSignature uhs;
2022
2025
2026 uhs.purpose.purpose = htonl (
2028 uhs.purpose.size = htonl (sizeof(uhs));
2029 uhs.sender = uc->sender;
2030 uhs.receiver = *my_identity;
2031 uhs.enc = *enc;
2032 uhs.monotonic_time = uc->monotonic_time;
2035 &uhs,
2036 &uc->sender_sig,
2037 &uc->sender.public_key);
2038}
2039
2040
2049static char *
2050sockaddr_to_udpaddr_string (const struct sockaddr *address,
2051 socklen_t address_len)
2052{
2053 char *ret;
2054
2055 switch (address->sa_family)
2056 {
2057 case AF_INET:
2059 "%s-%s",
2061 GNUNET_a2s (address, address_len));
2062 break;
2063
2064 case AF_INET6:
2066 "%s-%s",
2068 GNUNET_a2s (address, address_len));
2069 break;
2070
2071 default:
2072 GNUNET_assert (0);
2073 }
2074 return ret;
2075}
2076
2077
2078static struct GNUNET_NETWORK_Handle *
2080{
2082
2083 if (NULL == receiver->udp_sock)
2084 {
2085 if (AF_INET6 == receiver->address->sa_family)
2087 else
2089 }
2090 else
2091 udp_sock = receiver->udp_sock;
2092
2093 return udp_sock;
2094}
2095
2096
2105static struct sockaddr *
2106udp_address_to_sockaddr (const char *bindto,
2107 sa_family_t family,
2108 socklen_t *sock_len)
2109{
2110 struct sockaddr *in;
2111 unsigned int port;
2112 char dummy[2];
2113 char *colon;
2114 char *cp;
2115
2116 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2117 {
2118 /* interpreting value as just a PORT number */
2119 if (port > UINT16_MAX)
2120 {
2122 "BINDTO specification `%s' invalid: value too large for port\n",
2123 bindto);
2124 return NULL;
2125 }
2126 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2127 {
2128 struct sockaddr_in *i4;
2129
2130 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2131 i4->sin_family = AF_INET;
2132 i4->sin_port = htons ((uint16_t) port);
2133 *sock_len = sizeof(struct sockaddr_in);
2134 in = (struct sockaddr *) i4;
2135 }
2136 else
2137 {
2138 struct sockaddr_in6 *i6;
2139
2140 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2141 i6->sin6_family = AF_INET6;
2142 i6->sin6_port = htons ((uint16_t) port);
2143 *sock_len = sizeof(struct sockaddr_in6);
2144 in = (struct sockaddr *) i6;
2145 }
2146 return in;
2147 }
2148 cp = GNUNET_strdup (bindto);
2149 colon = strrchr (cp, ':');
2150 if (NULL != colon)
2151 {
2152 /* interpret value after colon as port */
2153 *colon = '\0';
2154 colon++;
2155 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2156 {
2157 /* interpreting value as just a PORT number */
2158 if (port > UINT16_MAX)
2159 {
2161 "BINDTO specification `%s' invalid: value too large for port\n",
2162 bindto);
2163 GNUNET_free (cp);
2164 return NULL;
2165 }
2166 }
2167 else
2168 {
2169 GNUNET_log (
2171 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2172 bindto);
2173 GNUNET_free (cp);
2174 return NULL;
2175 }
2176 }
2177 else
2178 {
2179 /* interpret missing port as 0, aka pick any free one */
2180 port = 0;
2181 }
2182 if (AF_INET6 != family)
2183 {
2184 /* try IPv4 */
2185 struct sockaddr_in v4;
2186
2187 memset (&v4, 0, sizeof(v4));
2188 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2189 {
2190 v4.sin_family = AF_INET;
2191 v4.sin_port = htons ((uint16_t) port);
2192#if HAVE_SOCKADDR_IN_SIN_LEN
2193 v4.sin_len = sizeof(struct sockaddr_in);
2194#endif
2195 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2196 *sock_len = sizeof(struct sockaddr_in);
2197 GNUNET_free (cp);
2198 return in;
2199 }
2200 }
2201 if (AF_INET != family)
2202 {
2203 /* try IPv6 */
2204 struct sockaddr_in6 v6;
2205 const char *start;
2206
2207 memset (&v6, 0, sizeof(v6));
2208 start = cp;
2209 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2210 {
2211 start++; /* skip over '[' */
2212 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2213 }
2214 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2215 {
2216 v6.sin6_family = AF_INET6;
2217 v6.sin6_port = htons ((uint16_t) port);
2218#if HAVE_SOCKADDR_IN_SIN_LEN
2219 v6.sin6_len = sizeof(struct sockaddr_in6);
2220#endif
2221 in = GNUNET_memdup (&v6, sizeof(v6));
2222 *sock_len = sizeof(v6);
2223 GNUNET_free (cp);
2224 return in;
2225 }
2226 }
2227 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2228 GNUNET_free (cp);
2229 return NULL;
2230}
2231
2232
2233static void
2234sock_read (void *cls);
2235
2236
2237static enum GNUNET_GenericReturnValue
2239 const char *address,
2241{
2242 struct GNUNET_HashContext *hsh;
2243 struct ReceiverAddress *receiver;
2244 struct GNUNET_HashCode receiver_key;
2245 const char *path;
2246 struct sockaddr *in;
2247 socklen_t in_len;
2248
2249 if (0 != strncmp (address,
2251 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2252 {
2253 GNUNET_break_op (0);
2254 return GNUNET_SYSERR;
2255 }
2256 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2257 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2258
2259 if (NULL == in)
2260 {
2262 "Failed to setup UDP socket address\n");
2263 return GNUNET_SYSERR;
2264 }
2265 if ((AF_INET6 == in->sa_family) &&
2267 {
2269 "IPv6 disabled, skipping %s\n", address);
2270 GNUNET_free (in);
2271 return GNUNET_SYSERR;
2272 }
2273 else if (AF_INET == in->sa_family)
2274 {
2275 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2276 if (0 == sin->sin_port)
2277 {
2278 GNUNET_free (in);
2279 return GNUNET_NO;
2280 }
2281 }
2282
2284 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2285 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2286 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2287
2289 if (NULL != receiver)
2290 {
2292 "receiver %s already exist or is being connected to\n",
2293 address);
2294 return GNUNET_NO;
2295 }
2296
2298 receiver->udp_sock = udp_sock;
2299 receiver->key = receiver_key;
2300 receiver->address = in;
2301 receiver->address_len = in_len;
2302 receiver->target = *peer;
2303 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2304 &receiver->target_hpke_key);
2305 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2307 receivers,
2308 &receiver->key,
2309 receiver,
2312 "Added %s to receivers with address %s and sock %p\n",
2313 GNUNET_i2s_full (&receiver->target),
2314 address,
2315 udp_sock);
2316 receiver->timeout =
2319 receiver,
2320 receiver->timeout.abs_value_us);
2322 "# receivers active",
2324 GNUNET_NO);
2325 receiver->foreign_addr =
2326 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2327 if (NULL != udp_sock)
2330 udp_sock,
2331 &sock_read,
2332 udp_sock);
2334 if (NULL == timeout_task)
2336 return GNUNET_OK;
2337}
2338
2339
2345static void
2346sock_read (void *cls)
2347{
2348 struct sockaddr_storage sa;
2349 struct sockaddr_in *addr_verify;
2350 socklen_t salen = sizeof(sa);
2351 char buf[UINT16_MAX];
2352 ssize_t rcvd;
2353
2354 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2355
2358 udp_sock,
2359 &sock_read,
2360 udp_sock);
2363 udp_sock,
2364 &sock_read,
2365 udp_sock);
2366 while (1)
2367 {
2369 buf,
2370 sizeof(buf),
2371 (struct sockaddr *) &sa,
2372 &salen);
2373 if (-1 == rcvd)
2374 {
2375 struct sockaddr *addr = (struct sockaddr*) &sa;
2376
2377 if (EAGAIN == errno)
2378 break; // We are done reading data
2380 "Failed to recv from %s family %d failed sock %p\n",
2381 GNUNET_a2s ((struct sockaddr*) &sa,
2382 sizeof (*addr)),
2383 addr->sa_family,
2384 udp_sock);
2386 return;
2387 }
2389 "Read %llu bytes\n",
2390 (unsigned long long) rcvd);
2391 if (0 == rcvd)
2392 {
2393 GNUNET_break_op (0);
2395 "Read 0 bytes from UDP socket\n");
2396 return;
2397 }
2398
2399 /* first, see if it is a GNUNET_BurstMessage */
2400 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2401 {
2402 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2403 struct sockaddr *addr = (struct sockaddr*) &sa;
2404 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2405
2406 GNUNET_assert (0 == bm->local_port);
2408 "Received a burst message for default port\n");
2409 create_receiver (&bm->peer,
2410 address,
2411 NULL);
2412 if (AF_INET6 == addr->sa_family)
2414 else
2418 return;
2419 }
2420 /* second, see if it is a UDPBox */
2421 if (rcvd > sizeof(struct UDPBox))
2422 {
2423 const struct UDPBox *box;
2424 struct KeyCacheEntry *kce;
2425
2426 box = (const struct UDPBox *) buf;
2428 if (NULL != kce)
2429 {
2431 "Found KCE with kid %s\n",
2432 GNUNET_sh2s (&box->kid));
2433 decrypt_box (box, (size_t) rcvd, kce);
2434 continue;
2435 }
2436 }
2437
2438 /* next, check if it is a broadcast */
2439 if (sizeof(struct UDPBroadcast) == rcvd)
2440 {
2441 const struct GNUNET_PeerIdentity *my_identity;
2442 const struct UDPBroadcast *ub;
2443 struct UdpBroadcastSignature uhs;
2444 struct GNUNET_PeerIdentity sender;
2445
2448
2449 addr_verify = GNUNET_memdup (&sa, salen);
2450 addr_verify->sin_port = 0;
2452 "received UDPBroadcast from %s\n",
2453 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2454 ub = (const struct UDPBroadcast *) buf;
2455 uhs.purpose.purpose = htonl (
2457 uhs.purpose.size = htonl (sizeof(uhs));
2458 uhs.sender = ub->sender;
2459 sender = ub->sender;
2460 if (0 == memcmp (&sender, my_identity, sizeof (struct
2462 {
2464 "Received our own broadcast\n");
2465 GNUNET_free (addr_verify);
2466 continue;
2467 }
2469 "checking UDPBroadcastSignature for %s\n",
2470 GNUNET_i2s (&sender));
2471 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2472 &uhs.h_address);
2473 if (GNUNET_OK ==
2476 &uhs,
2477 &ub->sender_sig,
2478 &ub->sender.public_key))
2479 {
2480 char *addr_s;
2482
2483 addr_s =
2484 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2485 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2486 /* use our own mechanism to determine network type */
2487 nt =
2488 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2490 "validating address %s received from UDPBroadcast\n",
2491 GNUNET_i2s (&sender));
2493 GNUNET_free (addr_s);
2494 GNUNET_free (addr_verify);
2495 continue;
2496 }
2497 else
2498 {
2500 "VerifyingPeer %s is verifying UDPBroadcast\n",
2503 "Verifying UDPBroadcast from %s failed\n",
2504 GNUNET_i2s (&ub->sender));
2505 }
2506 GNUNET_free (addr_verify);
2507 /* continue with KX, mostly for statistics... */
2508 }
2509
2510
2511 /* finally, test if it is a KX */
2512 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2513 {
2515 "# messages dropped (no kid, too small for KX)",
2516 1,
2517 GNUNET_NO);
2518 continue;
2519 }
2521 "Got KX\n");
2522 {
2523 const struct InitialKX *kx;
2524 struct SharedSecret *ss;
2525 char pbuf[rcvd - sizeof(struct InitialKX)];
2526 const struct UDPConfirmation *uc;
2527 struct SenderAddress *sender;
2528
2529 kx = (const struct InitialKX *) buf;
2532 "Before DEC\n");
2533
2534 if (GNUNET_OK != try_decrypt (ss,
2535 kx->gcm_tag,
2536 0,
2537 &buf[sizeof(*kx)],
2538 sizeof(pbuf),
2539 pbuf))
2540 {
2542 "Unable to decrypt tag, dropping...\n");
2543 GNUNET_free (ss);
2545 stats,
2546 "# messages dropped (no kid, AEAD decryption failed)",
2547 1,
2548 GNUNET_NO);
2549 continue;
2550 }
2552 "Before VERIFY\n");
2553
2554 uc = (const struct UDPConfirmation *) pbuf;
2555
2556 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2557 {
2558 GNUNET_break_op (0);
2559 GNUNET_free (ss);
2561 "# messages dropped (sender signature invalid)",
2562 1,
2563 GNUNET_NO);
2564 continue;
2565 }
2567 "Before SETUP_SENDER\n");
2568
2569 calculate_cmac (ss);
2570 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2571 ss->sender = sender;
2572 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2573 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2574 (NULL == ss->sender->kce_task) &&
2576 {
2577 // 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.
2581 ss);
2582 }
2583 sender->num_secrets++;
2584 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2586 "# messages decrypted without BOX",
2587 1,
2588 GNUNET_NO);
2589 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2590 if (0 == purge_secrets (sender->ss_tail))
2591 {
2592 // No secret purged. Delete oldest.
2593 if (sender->num_secrets > MAX_SECRETS)
2594 {
2595 secret_destroy (sender->ss_tail);
2596 }
2597 }
2598 }
2599 }
2600}
2601
2602
2610static void
2611do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2612{
2613 char pad[pad_size];
2614
2616 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2617 {
2618 struct GNUNET_MessageHeader hdr =
2619 { .size = htons (sizeof(pad)),
2621
2622 memcpy (pad, &hdr, sizeof(hdr));
2623 }
2625 0 ==
2626 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2627}
2628
2629
2630static void
2633 struct GNUNET_MQ_Handle *mq)
2634{
2635 const struct GNUNET_PeerIdentity *my_identity;
2637 uint16_t msize = ntohs (msg->size);
2638 struct UdpHandshakeSignature uhs;
2639 struct UDPConfirmation uc;
2640 struct InitialKX kx;
2641 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2642 size_t dpos;
2643 gcry_cipher_hd_t out_cipher;
2644 struct SharedSecret *ss;
2645
2649
2650 if (msize > receiver->kx_mtu)
2651 {
2652 GNUNET_break (0);
2653 if (GNUNET_YES != receiver->receiver_destroy_called)
2655 return;
2656 }
2658
2659 /* setup key material */
2661
2662 if (0 == purge_secrets (receiver->ss_tail))
2663 {
2664 // No secret purged. Delete oldest.
2665 if (receiver->num_secrets > MAX_SECRETS)
2666 {
2667 secret_destroy (receiver->ss_tail);
2668 }
2669 }
2670
2671 setup_cipher (&ss->master, 0, &out_cipher);
2672 /* compute 'uc' */
2673 uc.sender = *my_identity;
2674 uc.monotonic_time =
2676 uhs.purpose.purpose = htonl (
2678 uhs.purpose.size = htonl (sizeof(uhs));
2679 uhs.sender = *my_identity;
2680 uhs.receiver = receiver->target;
2681 uhs.monotonic_time = uc.monotonic_time;
2683 &uhs,
2684 &uc.sender_sig);
2685 /* Leave space for kx */
2686 dpos = sizeof(kx);
2687 /* Append encrypted uc to dgram */
2688 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2689 &dgram[dpos],
2690 sizeof(uc),
2691 &uc,
2692 sizeof(uc)));
2693 dpos += sizeof(uc);
2694 /* Append encrypted payload to dgram */
2696 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2697 dpos += msize;
2698 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2699 /* Datagram starts with kx */
2700 kx.enc = uhs.enc;
2702 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2703 gcry_cipher_close (out_cipher);
2704 memcpy (dgram, &kx, sizeof(kx));
2706 dgram,
2707 sizeof(dgram),
2708 receiver->address,
2709 receiver->address_len))
2710 {
2713 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2714 msize,
2715 GNUNET_a2s (receiver->address,
2716 receiver->address_len),
2717 receiver->address->sa_family,
2721 return;
2722 }
2724 "Sending KX with payload size %u to %s with socket %p\n",
2725 msize,
2726 GNUNET_a2s (receiver->address,
2727 receiver->address_len),
2730}
2731
2732
2741static void
2743 const struct GNUNET_MessageHeader *msg,
2744 void *impl_state)
2745{
2746 struct ReceiverAddress *receiver = impl_state;
2747
2748 GNUNET_assert (mq == receiver->kx_mq);
2750}
2751
2752
2753static void
2755 UDPRekey *rekey)
2756{
2757 struct SharedSecret *ss_rekey;
2758
2760 /* setup key material */
2761 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2762 receiver);
2763 ss_rekey->sequence_allowed = 0;
2765 "Setup secret with k = %s\n",
2766 GNUNET_sh2s (&ss_rekey->master));
2768 "Setup secret with H(k) = %s\n",
2769 GNUNET_h2s (&(ss_rekey->cmac)));
2770
2771 /* Append encrypted payload to dgram */
2773 rekey->header.size = htons (sizeof (struct UDPRekey));
2774}
2775
2776
2785static void
2787 const struct GNUNET_MessageHeader *msg,
2788 void *impl_state)
2789{
2790 struct ReceiverAddress *receiver = impl_state;
2791 struct UDPRekey rekey;
2792 struct SharedSecret *ss;
2793 int inject_rekey = GNUNET_NO;
2794 uint16_t msize = ntohs (msg->size);
2795
2796 GNUNET_assert (mq == receiver->d_mq);
2797 if ((msize > receiver->d_mtu) ||
2798 (0 == receiver->acks_available))
2799 {
2801 "msize: %u, mtu: %llu, acks: %u\n",
2802 (unsigned int) msize,
2803 (unsigned long long) receiver->d_mtu,
2804 receiver->acks_available);
2805
2806 GNUNET_break (0);
2807 if (GNUNET_YES != receiver->receiver_destroy_called)
2809 return;
2810 }
2812
2813 if (receiver->num_secrets > MAX_SECRETS)
2814 {
2815 if ((0 == purge_secrets (receiver->ss_tail)) &&
2816 (NULL != receiver->ss_tail))
2817 {
2818 // No secret purged. Delete oldest.
2819 secret_destroy (receiver->ss_tail);
2820 }
2821 }
2822 /* begin "BOX" encryption method, scan for ACKs from tail! */
2823 ss = receiver->ss_tail;
2824 while (NULL != ss)
2825 {
2826 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2828 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2829 GNUNET_sh2s (&ss->master), ss->sequence_used,
2830 ss->sequence_allowed, ss->bytes_sent);
2831 if (ss->sequence_used >= ss->sequence_allowed)
2832 {
2833 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2834 // "Skipping ss because no acks to use.\n");
2835 ss = ss->prev;
2836 continue;
2837 }
2838 if (ss->bytes_sent >= rekey_max_bytes)
2839 {
2840 struct SharedSecret *ss_tmp;
2842 "Skipping ss because rekey bytes reached.\n");
2843 // FIXME cleanup ss with too many bytes sent!
2844 ss_tmp = ss->prev;
2845 secret_destroy (ss);
2846 ss = ss_tmp;
2847 continue;
2848 }
2849 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2850 {
2851 if (ss->rekey_initiated == GNUNET_NO)
2852 {
2854 "Injecting rekey for ss with byte sent %lu\n",
2855 (unsigned long) ss->bytes_sent);
2856 create_rekey (receiver, ss, &rekey);
2858 payload_len += sizeof (rekey);
2860 }
2861 }
2862 if (0 < ss->sequence_used)
2864 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
2865 GNUNET_sh2s (&ss->master),
2866 ss->sequence_used,
2867 ss->sequence_allowed);
2868 {
2869 char dgram[payload_len];
2870 struct UDPBox *box;
2871 gcry_cipher_hd_t out_cipher;
2872 size_t dpos;
2873
2874 box = (struct UDPBox *) dgram;
2875 ss->sequence_used++;
2876 get_kid (&ss->master, ss->sequence_used, &box->kid);
2877 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2878 /* Append encrypted payload to dgram */
2879 dpos = sizeof(struct UDPBox);
2880 if (GNUNET_YES == inject_rekey)
2881 {
2883 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2884 &rekey, sizeof (rekey)));
2885 dpos += sizeof (rekey);
2886 }
2888 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2889 dpos += msize;
2890 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2891 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2892 box->gcm_tag,
2893 sizeof(box->gcm_tag)));
2894 gcry_cipher_close (out_cipher);
2895
2897 dgram,
2898 payload_len, // FIXME why always send sizeof dgram?
2899 receiver->address,
2900 receiver->address_len))
2901 {
2904 "Sending UDPBox to %s family %d failed sock %p failed\n",
2905 GNUNET_a2s (receiver->address,
2906 receiver->address_len),
2907 receiver->address->sa_family,
2910 return;
2911 }
2913 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
2914 msize,
2915 receiver->acks_available,
2916 (unsigned long) ss->bytes_sent,
2918 ss->bytes_sent += sizeof (dgram);
2919 receiver->acks_available--;
2921 return;
2922 }
2923 }
2925 "No suitable ss found, sending as KX...\n");
2927}
2928
2929
2938static void
2939mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2940{
2941 struct ReceiverAddress *receiver = impl_state;
2943 "Default MQ destroyed\n");
2944 if (mq == receiver->d_mq)
2945 {
2946 receiver->d_mq = NULL;
2947 if (GNUNET_YES != receiver->receiver_destroy_called)
2949 }
2950}
2951
2952
2961static void
2962mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2963{
2964 struct ReceiverAddress *receiver = impl_state;
2966 "KX MQ destroyed\n");
2967 if (mq == receiver->kx_mq)
2968 {
2969 receiver->kx_mq = NULL;
2970 if (GNUNET_YES != receiver->receiver_destroy_called)
2972 }
2973}
2974
2975
2982static void
2983mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2984{
2985 /* Cancellation is impossible with UDP; bail */
2986 GNUNET_assert (0);
2987}
2988
2989
2999static void
3000mq_error (void *cls, enum GNUNET_MQ_Error error)
3001{
3002 struct ReceiverAddress *receiver = cls;
3003
3005 "MQ error in queue to %s: %d\n",
3006 GNUNET_i2s (&receiver->target),
3007 (int) error);
3009}
3010
3011
3019static void
3021{
3022 size_t base_mtu;
3023
3024 switch (receiver->address->sa_family)
3025 {
3026 case AF_INET:
3027 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3028 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3029 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3030 break;
3031
3032 case AF_INET6:
3033 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3034 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3035 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3036 break;
3037
3038 default:
3039 GNUNET_assert (0);
3040 break;
3041 }
3042 /* MTU based on full KX messages */
3043 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3044 - sizeof(struct UDPConfirmation); /* 104 */
3045 /* MTU based on BOXed messages */
3046 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3047
3049 "Setting up MQs and QHs\n");
3050 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3051 1404 (IPv4 + Box) bytes, depending on circumstances... */
3052 if (NULL == receiver->kx_mq)
3055 &mq_cancel,
3056 receiver,
3057 NULL,
3058 &mq_error,
3059 receiver);
3060 if (NULL == receiver->d_mq)
3062 &mq_destroy_d,
3063 &mq_cancel,
3064 receiver,
3065 NULL,
3066 &mq_error,
3067 receiver);
3068
3069 receiver->kx_qh =
3071 &receiver->target,
3072 receiver->foreign_addr,
3073 receiver->kx_mtu,
3075 0, /* Priority */
3076 receiver->nt,
3078 receiver->kx_mq);
3079}
3080
3081
3100static int
3101mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3102{
3103 (void) cls;
3105 "create receiver for mq_init\n");
3106 return create_receiver (peer,
3107 address,
3108 NULL);
3109}
3110
3111
3120static int
3122 const struct GNUNET_HashCode *target,
3123 void *value)
3124{
3125 struct ReceiverAddress *receiver = value;
3126
3127 (void) cls;
3128 (void) target;
3130 return GNUNET_OK;
3131}
3132
3133
3142static int
3144 const struct GNUNET_HashCode *target,
3145 void *value)
3146{
3147 struct SenderAddress *sender = value;
3148
3149 (void) cls;
3150 (void) target;
3151
3152
3153 sender_destroy (sender);
3154 return GNUNET_OK;
3155}
3156
3157
3163static void
3164do_shutdown (void *cls)
3165{
3167 "do_shutdown\n");
3168 GNUNET_stop_burst (NULL);
3169 if (NULL != nat)
3170 {
3172 nat = NULL;
3173 }
3174 while (NULL != bi_head)
3176 if (NULL != broadcast_task)
3177 {
3179 broadcast_task = NULL;
3180 }
3181 if (NULL != timeout_task)
3182 {
3184 timeout_task = NULL;
3185 }
3186 if (NULL != read_v6_task)
3187 {
3189 read_v6_task = NULL;
3190 }
3191 if (NULL != read_v4_task)
3192 {
3194 read_v4_task = NULL;
3195 }
3196 if (NULL != default_v6_sock)
3197 {
3200 default_v6_sock = NULL;
3201 }
3202 if (NULL != default_v4_sock)
3203 {
3206 default_v4_sock = NULL;
3207 }
3210 NULL);
3214 NULL);
3219 if (NULL != timeout_task)
3220 {
3222 timeout_task = NULL;
3223 }
3224 if (NULL != ch)
3225 {
3228 ch = NULL;
3229 }
3230 if (NULL != ah)
3231 {
3233 ah = NULL;
3234 }
3235 if (NULL != pils)
3236 {
3238 pils = NULL;
3239 }
3240 if (NULL != key_ring)
3241 {
3243 key_ring = NULL;
3244 }
3245 if (NULL != stats)
3246 {
3248 stats = NULL;
3249 }
3250 if (NULL != is)
3251 {
3253 is = NULL;
3254 }
3256 "do_shutdown finished\n");
3257}
3258
3259
3261{
3262 const struct UDPAck *ack;
3263
3265};
3266
3267static int
3268handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3269{
3270 struct ReceiverAddress *receiver = value;
3271 struct AckInfo *ai = cls;
3272
3273 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3274 {
3275 return GNUNET_YES;
3276 }
3277 handle_ack ((void*) ai->ack, key, receiver);
3278 return GNUNET_YES;
3279}
3280
3281
3291static void
3292enc_notify_cb (void *cls,
3293 const struct GNUNET_PeerIdentity *sender,
3294 const struct GNUNET_MessageHeader *msg)
3295{
3296 struct AckInfo ai;
3297
3298 (void) cls;
3300 "Storing UDPAck received from backchannel from %s\n",
3303 (ntohs (msg->size) != sizeof(struct UDPAck)))
3304 {
3305 GNUNET_break_op (0);
3306 return;
3307 }
3308 ai.ack = (const struct UDPAck *) msg;
3309 ai.sender = sender;
3312 &ai);
3313}
3314
3315
3329static void
3331 void **app_ctx,
3332 int add_remove,
3334 const struct sockaddr *addr,
3335 socklen_t addrlen)
3336{
3337 char *my_addr;
3339
3340 if (GNUNET_YES == add_remove)
3341 {
3343
3344 GNUNET_asprintf (&my_addr,
3345 "%s-%s",
3347 GNUNET_a2s (addr, addrlen));
3348 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3349 ai =
3351 my_addr,
3352 nt,
3354 GNUNET_free (my_addr);
3355 *app_ctx = ai;
3356 }
3357 else
3358 {
3359 ai = *app_ctx;
3361 *app_ctx = NULL;
3362 }
3363}
3364
3365
3371static void
3372ifc_broadcast (void *cls)
3373{
3374 struct BroadcastInterface *bi = cls;
3375 struct GNUNET_TIME_Relative delay;
3376
3377 delay = BROADCAST_FREQUENCY;
3378 delay.rel_value_us =
3380 bi->broadcast_task =
3382
3383 switch (bi->sa->sa_family)
3384 {
3385 case AF_INET: {
3386 static int yes = 1;
3387 static int no = 0;
3388 ssize_t sent;
3389
3390 if (GNUNET_OK !=
3392 SOL_SOCKET,
3393 SO_BROADCAST,
3394 &yes,
3395 sizeof(int)))
3397 "setsockopt");
3399 "creating UDPBroadcast from %s\n",
3400 GNUNET_i2s (&(bi->bcm.sender)));
3402 "sending UDPBroadcast to add %s\n",
3403 GNUNET_a2s (bi->ba, bi->salen));
3405 &bi->bcm,
3406 sizeof(bi->bcm),
3407 bi->ba,
3408 bi->salen);
3409 if (-1 == sent)
3411 "sendto");
3413 SOL_SOCKET,
3414 SO_BROADCAST,
3415 &no,
3416 sizeof(int)))
3418 "setsockopt");
3419 break;
3420 }
3421
3422 case AF_INET6: {
3423 ssize_t sent;
3424 struct sockaddr_in6 dst;
3425
3426 dst.sin6_family = AF_INET6;
3427 dst.sin6_port = htons (my_port);
3428 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3429 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3430
3432 "sending UDPBroadcast\n");
3434 &bi->bcm,
3435 sizeof(bi->bcm),
3436 (const struct sockaddr *) &dst,
3437 sizeof(dst));
3438 if (-1 == sent)
3440 break;
3441 }
3442
3443 default:
3444 GNUNET_break (0);
3445 break;
3446 }
3447}
3448
3449
3464static int
3465iface_proc (void *cls,
3466 const char *name,
3467 int isDefault,
3468 const struct sockaddr *addr,
3469 const struct sockaddr *broadcast_addr,
3470 const struct sockaddr *netmask,
3471 socklen_t addrlen)
3472{
3473 const struct GNUNET_PeerIdentity *my_identity;
3475 struct BroadcastInterface *bi;
3476 enum GNUNET_NetworkType network;
3477 struct UdpBroadcastSignature ubs;
3478
3479 (void) cls;
3480 (void) netmask;
3481
3484
3485 if ((NULL == my_identity) || (NULL == my_private_key))
3486 return GNUNET_YES;
3487 if (NULL == addr)
3488 return GNUNET_YES; /* need to know our address! */
3489 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3490 if (GNUNET_NT_LOOPBACK == network)
3491 {
3492 /* Broadcasting on loopback does not make sense */
3493 return GNUNET_YES;
3494 }
3495 for (bi = bi_head; NULL != bi; bi = bi->next)
3496 {
3497 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3498 {
3499 bi->found = GNUNET_YES;
3500 return GNUNET_OK;
3501 }
3502 }
3503
3504 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3505 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3506 if ((AF_INET6 == addr->sa_family) && (NULL != default_v6_sock))
3507 return GNUNET_OK; /* not using IPv6 */
3508
3509 bi = GNUNET_new (struct BroadcastInterface);
3510 bi->sa = GNUNET_memdup (addr,
3511 addrlen);
3512 if ( (NULL != broadcast_addr) &&
3513 (addrlen == sizeof (struct sockaddr_in)) )
3514 {
3515 struct sockaddr_in *ba;
3516
3517 ba = GNUNET_memdup (broadcast_addr,
3518 addrlen);
3519 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3520 bi->ba = (struct sockaddr *) ba;
3521 }
3522 bi->salen = addrlen;
3523 bi->found = GNUNET_YES;
3524 bi->bcm.sender = *my_identity;
3525 ubs.purpose.purpose = htonl (
3527 ubs.purpose.size = htonl (sizeof(ubs));
3528 ubs.sender = *my_identity;
3530 "creating UDPBroadcastSignature for %s\n",
3531 GNUNET_a2s (addr, addrlen));
3532 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3534 &ubs,
3535 &bi->bcm.sender_sig);
3536 if (NULL != bi->ba)
3537 {
3540 }
3541 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3542 {
3543 /* Create IPv6 multicast request */
3544 const struct sockaddr_in6 *s6 =
3545 (const struct sockaddr_in6 *) broadcast_addr;
3546
3548 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3549
3550 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3551 *
3552 * IPV6_JOIN_GROUP
3553 *
3554 * Join a multicast group on a specified local interface. If the
3555 * interface index is specified as 0, the kernel chooses the local
3556 * interface. For example, some kernels look up the multicast
3557 * group in the normal IPv6 routing table and using the resulting
3558 * interface; we do this for each interface, so no need to use
3559 * zero (anymore...).
3560 */
3561 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3562
3563 /* Join the multicast group */
3565 IPPROTO_IPV6,
3566 IPV6_JOIN_GROUP,
3567 &bi->mcreq,
3568 sizeof(bi->mcreq)))
3569 {
3571 }
3572 }
3573 return GNUNET_OK;
3574}
3575
3576
3582static void
3583do_broadcast (void *cls)
3584{
3585 struct BroadcastInterface *bin;
3586
3587 (void) cls;
3588 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3589 bi->found = GNUNET_NO;
3591 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3592 {
3593 bin = bi->next;
3594 if (GNUNET_NO == bi->found)
3595 bi_destroy (bi);
3596 }
3598 &do_broadcast,
3599 NULL);
3600}
3601
3602
3603static void
3605 const struct sockaddr *addr,
3606 socklen_t addrlen)
3607{
3608 /* FIXME: support reversal: #5529 */
3610 "No connection reversal implemented!\n");
3611}
3612
3613
3614static void
3616{
3618 sizeof (*sock_info->actual_address
3619 ));
3620 create_receiver (sock_info->pid,
3621 address,
3622 default_v4_sock == sock_info->udp_sock ||
3623 default_v6_sock == sock_info->udp_sock ?
3624 NULL : sock_info->udp_sock);
3626 GNUNET_free (sock_info);
3627}
3628
3629
3630static void
3631start_burst (const char *addr,
3632 struct GNUNET_TIME_Relative rtt,
3633 struct GNUNET_PeerIdentity *pid)
3634{
3635 struct GNUNET_UdpSocketInfo *sock_info;
3636
3638 "Communicator was called to start burst to address %s from %s\n",
3639 addr,
3640 my_ipv4);
3641
3642 GNUNET_stop_burst (NULL);
3643
3644 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3645 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3646 sock_info->address = GNUNET_strdup (addr);
3647 sock_info->bind_address = my_ipv4;
3648 sock_info->has_port = GNUNET_YES;
3649 sock_info->udp_sock = default_v4_sock;
3650 sock_info->rtt = rtt;
3651 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3652 sock_info->std_port = my_port;
3654 "1 sock addr %s addr %s rtt %lu %u\n",
3655 sock_info->address,
3656 addr,
3657 (unsigned long) sock_info->rtt.rel_value_us,
3658 my_port);
3659 burst_task = GNUNET_get_udp_socket (sock_info,
3661 GNUNET_free (sock_info);
3662}
3663
3664
3665static struct GNUNET_NETWORK_Handle*
3666create_udp_socket (const char *bindto,
3667 sa_family_t family,
3668 struct sockaddr **out,
3669 socklen_t *out_len)
3670{
3671 struct GNUNET_NETWORK_Handle *sock;
3672 struct sockaddr *in;
3673 socklen_t in_len;
3674 struct sockaddr_storage in_sto;
3675 socklen_t sto_len;
3676
3677 in = udp_address_to_sockaddr (bindto, family, &in_len);
3678 if (NULL == in)
3679 {
3681 "Failed to setup UDP socket address with path `%s'\n",
3682 bindto);
3683 return NULL;
3684 }
3685
3686 if ((AF_UNSPEC != family) && (in->sa_family != family))
3687 {
3689 "Invalid UDP socket address setup with path `%s'\n",
3690 bindto);
3691 GNUNET_free (in);
3692 return NULL;
3693 }
3694
3695 sock =
3696 GNUNET_NETWORK_socket_create (in->sa_family,
3697 SOCK_DGRAM,
3698 IPPROTO_UDP);
3699 if (NULL == sock)
3700 {
3703 "Failed to create socket for %s family %d\n",
3704 GNUNET_a2s (in,
3705 in_len),
3706 in->sa_family);
3707 GNUNET_free (in);
3708 return NULL;
3709 }
3710 if (GNUNET_OK !=
3712 in,
3713 in_len))
3714 {
3716 "bind",
3717 bindto);
3719 "Failed to bind socket for %s family %d sock %p\n",
3720 GNUNET_a2s (in,
3721 in_len),
3722 in->sa_family,
3723 sock);
3725 sock = NULL;
3726 GNUNET_free (in);
3727 return NULL;
3728 }
3729
3730 /* We might have bound to port 0, allowing the OS to figure it out;
3731 thus, get the real IN-address from the socket */
3732 sto_len = sizeof(in_sto);
3733 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3734 (struct sockaddr *) &in_sto,
3735 &sto_len))
3736 {
3737 memcpy (&in_sto, in, in_len);
3738 sto_len = in_len;
3739 }
3740 GNUNET_free (in);
3741 *out = GNUNET_malloc (sto_len);
3742 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3743 *out_len = sto_len;
3744 return sock;
3745}
3746
3747
3748static void
3749shutdown_run (struct sockaddr *addrs[2])
3750{
3751 if (NULL != addrs[0])
3752 GNUNET_free (addrs[0]);
3753 if (NULL != addrs[1])
3754 GNUNET_free (addrs[1]);
3756}
3757
3758
3759static void
3760run (void *cls,
3761 char *const *args,
3762 const char *cfgfile,
3763 const struct GNUNET_CONFIGURATION_Handle *c)
3764{
3765 const struct sockaddr_in *v4;
3766 char *bindto;
3767 char *bindto6;
3768 struct sockaddr *in[2];
3769 socklen_t in_len[2];
3770
3772 "Entering the run method of udp communicator.\n");
3773
3774 cfg = c;
3776 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3777 (GNUNET_YES ==
3780 "DISABLE_V6")))
3781 {
3783 }
3784
3785 if (GNUNET_OK !=
3788 "BINDTO",
3789 &bindto))
3790 {
3793 "BINDTO");
3794 return;
3795 }
3797 "The udp communicator will bind to %s for IPv4\n",
3798 bindto);
3799 if (GNUNET_YES != disable_v6)
3800 {
3801 if (GNUNET_OK !=
3804 "BINDTO6",
3805 &bindto6))
3806 {
3809 "BINDTO6");
3810 return;
3811 }
3812
3814 "The udp communicator will bind to %s for IPv6\n",
3815 bindto6);
3816 }
3817 else
3818 bindto6 = NULL;
3819 if (GNUNET_OK !=
3822 "REKEY_INTERVAL",
3825
3826 if (GNUNET_OK !=
3829 "REKEY_MAX_BYTES",
3831 {
3833 }
3834
3835 memset (in, 0, sizeof(struct sockaddr*) * 2);
3836 memset (in_len, 0, sizeof(socklen_t) * 2);
3837
3838 GNUNET_assert (bindto);
3840 bindto, AF_INET, &(in[0]), &(in_len[0]));
3841 GNUNET_free (bindto);
3842
3843 if (GNUNET_YES != disable_v6)
3844 {
3845 GNUNET_assert (bindto6);
3847 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3848 GNUNET_free (bindto6);
3849 }
3850 else
3851 default_v6_sock = NULL;
3852
3853 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3854 return;
3855
3856 my_port = 0;
3857 if (NULL != default_v4_sock)
3858 {
3859 GNUNET_assert (in[0]);
3861 "transport",
3862 "Bound to `%s' sock %p\n",
3863 GNUNET_a2s ((const struct sockaddr *) in[0],
3864 in_len[0]),
3866
3867 v4 = (const struct sockaddr_in *) in[0];
3868
3869 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3870 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3871 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3872 }
3873 if (NULL != default_v6_sock)
3874 {
3875 GNUNET_assert (in[1]);
3877 "transport",
3878 "Bound to `%s' sock %p\n",
3879 GNUNET_a2s ((const struct sockaddr *) in[1],
3880 in_len[1]),
3882 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3883 }
3884 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3893 /* start reading */
3894 if (NULL != default_v4_sock)
3897 &sock_read,
3899 else
3900 read_v4_task = NULL;
3901 if (NULL != default_v6_sock)
3904 &sock_read,
3906 else
3907 read_v6_task = NULL;
3912 &mq_init,
3913 NULL,
3915 NULL,
3916 &start_burst);
3917 if (NULL == ch)
3918 {
3919 GNUNET_break (0);
3920 shutdown_run (in);
3921 return;
3922 }
3924 if (NULL == ah)
3925 {
3926 GNUNET_break (0);
3927 shutdown_run (in);
3928 return;
3929 }
3930 /* start broadcasting */
3931 if (GNUNET_YES !=
3934 "DISABLE_BROADCAST"))
3935 {
3937 }
3939 GNUNET_assert (NULL != key_ring);
3940 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
3941 GNUNET_assert (NULL != pils);
3942
3945 IPPROTO_UDP,
3946 (NULL != in[0]? 1 : 0)
3947 + (NULL != in[1]? 1 : 0),
3948 (const struct sockaddr**)
3949 (NULL != in[0]? in : &(in[1])),
3950 NULL != in[0]? in_len : &(in_len[1]),
3953 NULL /* closure */);
3954 if (NULL != in[0])
3955 GNUNET_free (in[0]);
3956 if (NULL != in[1])
3957 GNUNET_free (in[1]);
3958}
3959
3960
3961GNUNET_DAEMON_MAIN ("gnunet-communicator-udp",
3962 _ ("GNUnet UDP communicator"),
3963 &run)
3964/* 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.
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 void mq_send_kx(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static struct SharedSecret * setup_initial_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM for initial handshake.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static void kce_generate(struct SharedSecret *ss, uint32_t seq)
Setup key cache entry for sequence number seq and shared secret ss.
static void setup_cipher(const struct GNUNET_ShortHashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.
static 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 void eddsa_pub_to_hpke_key(const struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_HpkePublicKey *pk)
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 void eddsa_priv_to_hpke_key(const struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
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_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 try_handle_plaintext(struct SenderAddress *sender, const void *buf, size_t buf_size)
Test if we have received a valid message in plaintext.
static struct GNUNET_PILS_KeyRing * key_ring
For PILS.
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 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 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 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 my_identity
Identity of this peer.
struct GNUNET_CRYPTO_EddsaPrivateKey my_private_key
The current private key.
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:465
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:488
struct GNUNET_PILS_KeyRing * GNUNET_PILS_create_key_ring(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_SCHEDULER_TaskCallback init_cb, void *cls)
Create a key ring handle to use the current peer identity key.
Definition pils_api.c:804
void GNUNET_PILS_destroy_key_ring(struct GNUNET_PILS_KeyRing *key_ring)
Destroy a key ring handle and free its memory.
Definition pils_api.c:864
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
const struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_PILS_key_ring_get_private_key(const struct GNUNET_PILS_KeyRing *key_ring)
Return the current private key of a given key ring handle.
Definition pils_api.c:887
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.
void GNUNET_TRANSPORT_communicator_address_remove_all(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Notify transport service that this communicator no longer provides all its addresses for this peer.
@ GNUNET_TRANSPORT_CC_UNRELIABLE
Transmission is unreliable (e.g.
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Decapsulate a key for a private EdDSA key.
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...
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
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
#define GNUNET_CRYPTO_hkdf_expand(result, out_len, 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.
#define GNUNET_CRYPTO_kdf_arg_string(d)
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_CRYPTO_kdf_arg_auto(d)
#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:1000
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition network.c:687
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition network.c:79
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition network.c:439
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition network.c:805
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition network.c:771
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
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:572
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:1517
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:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
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 (!...
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
A simplified handle for using the peer identity key.
Definition pils_api.c:132
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:141
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).