GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
gnunet-communicator-udp.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 2018, 2019 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14 :
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
40#include "platform.h"
41#include "gnunet_common.h"
42#include "gnunet_util_lib.h"
43#include "gnunet_protocols.h"
44#include "gnunet_signatures.h"
45#include "gnunet_constants.h"
46#include "gnunet_pils_service.h"
47#include "gnunet_nat_service.h"
51
52/* Shorthand for Logging */
53#define LOG(kind, ...) GNUNET_log_from (kind, "communicator-udp", __VA_ARGS__)
54
58#define DEFAULT_REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
59
63#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
64
68#define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
69
73#define INTERFACE_SCAN_FREQUENCY \
74 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
75
80#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
81
82#define WORKING_QUEUE_INTERVALL \
83 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)
84
88#define AES_KEY_SIZE (256 / 8)
89
93#define AES_IV_SIZE (96 / 8)
94
98#define GCM_TAG_SIZE (128 / 8)
99
100#define GENERATE_AT_ONCE 64
101
111#define KCN_THRESHOLD 96
112
119#define KCN_TARGET 128
120
130#define MAX_SQN_DELTA 160
131
141#define MAX_SECRETS 256
142
147#define DEFAULT_REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
148
153#define COMMUNICATOR_ADDRESS_PREFIX "udp"
154
158#define COMMUNICATOR_CONFIG_SECTION "communicator-udp"
159
161
162
196
197
216
217
223{
228
233
239
240 /* followed by messages */
241
242 /* padding may follow actual messages */
243};
244
245
268
269
295
296
316
317
322struct UDPBox
323{
332
341
342};
343
359
361
365struct SharedSecret;
366
367
373{
378
383
392
397
402};
403
404
409struct SenderAddress;
410
415struct ReceiverAddress;
416
495
496
579
580
705
710{
715
720
725
729 struct sockaddr *sa;
730
734 struct sockaddr *ba;
735
740
745 struct ipv6_mreq mcreq;
746
750 socklen_t salen;
751
755 int found;
756};
757
761static unsigned char ikm[256 / 8];
762
767
772
776static unsigned long long rekey_max_bytes;
777
782
787
792
797
802
807
812
817
822
827
832
837
842
847
852
857
862
867
871static const struct GNUNET_CONFIGURATION_Handle *cfg;
872
877
882
886static struct GNUNET_NAT_Handle *nat;
887
891static uint16_t my_port;
892
897
901static int disable_v6;
902
904
905
906static void
915
916
917static void
926
927
933static void
935{
936 if (AF_INET6 == bi->sa->sa_family)
937 {
938 /* Leave the multicast group */
940 IPPROTO_IPV6,
941 IPV6_LEAVE_GROUP,
942 &bi->mcreq,
943 sizeof(bi->mcreq)))
944 {
946 }
947 }
950 GNUNET_free (bi->sa);
951 GNUNET_free (bi->ba);
952 GNUNET_free (bi);
953}
954
955
956static int
957secret_destroy (struct SharedSecret *ss);
958
964static void
966{
967 struct SharedSecret *ss;
968 receiver->receiver_destroy_called = GNUNET_YES;
969
971 "Disconnecting receiver for peer `%s'\n",
972 GNUNET_i2s (&receiver->target));
973 if (NULL != receiver->kx_qh)
974 {
976 receiver->kx_qh = NULL;
977 receiver->kx_mq = NULL;
978 }
979 if (NULL != receiver->d_qh)
980 {
982 receiver->d_qh = NULL;
983 }
984 else if (NULL != receiver->d_mq)
985 {
987 receiver->d_mq = NULL;
988 }
989 if (NULL != receiver->udp_sock)
990 {
993 receiver->udp_sock = NULL;
994 }
997 &receiver->key,
998 receiver));
1001 "# receivers active",
1003 GNUNET_NO);
1004 while (NULL != (ss = receiver->ss_head))
1005 {
1006 secret_destroy (ss);
1007 }
1008 GNUNET_free (receiver->address);
1009 GNUNET_free (receiver->foreign_addr);
1011}
1012
1013
1019static void
1021{
1022 struct SharedSecret *ss = kce->ss;
1023
1024 ss->active_kce_count--;
1027 &kce->kid,
1028 kce));
1029 GNUNET_free (kce);
1030}
1031
1032
1040static void
1041get_kid (const struct GNUNET_ShortHashCode *msec,
1042 uint32_t serial,
1043 struct GNUNET_ShortHashCode *kid)
1044{
1045 uint32_t sid = htonl (serial);
1046 struct GNUNET_ShortHashCode prk;
1048 &sid, sizeof (sid),
1049 msec, sizeof (*msec));
1050
1052 sizeof(*kid),
1053 &prk,
1054 "gnunet-communicator-udp-kid",
1055 strlen ("gnunet-communicator-udp-kid"),
1056 NULL,
1057 0);
1058}
1059
1060
1067static void
1068kce_generate (struct SharedSecret *ss, uint32_t seq)
1069{
1070 struct KeyCacheEntry *kce;
1071
1072 GNUNET_assert (0 < seq);
1073 kce = GNUNET_new (struct KeyCacheEntry);
1074 kce->ss = ss;
1075 kce->sequence_number = seq;
1076 get_kid (&ss->master, seq, &kce->kid);
1081 key_cache,
1082 &kce->kid,
1083 kce,
1086 "# KIDs active",
1088 GNUNET_NO);
1089}
1090
1091
1098static int
1100{
1101 struct SenderAddress *sender;
1102 struct ReceiverAddress *receiver;
1103 struct KeyCacheEntry *kce;
1104
1106 "secret %s destroy %u\n",
1107 GNUNET_sh2s (&ss->master),
1109 if (NULL != (sender = ss->sender))
1110 {
1111 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1112 sender->num_secrets--;
1114 "%u sender->num_secrets %u allowed %u used, %u available\n",
1116 sender->acks_available);
1118 if (NULL != ss->sender->kce_task)
1119 {
1121 ss->sender->kce_task = NULL;
1122 }
1123 }
1124 if (NULL != (receiver = ss->receiver))
1125 {
1126 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1127 receiver->num_secrets--;
1128 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1130 "%u receiver->num_secrets\n",
1131 receiver->num_secrets);
1132 }
1133 while (NULL != (kce = ss->kce_head))
1134 kce_destroy (kce);
1135 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1137 "# KIDs active",
1139 GNUNET_NO);
1140 GNUNET_free (ss);
1141 return GNUNET_YES;
1142}
1143
1144
1151static void
1153{
1154 struct SharedSecret *ss;
1157 GNUNET_YES ==
1161 "# senders active",
1163 GNUNET_NO);
1164 while (NULL != (ss = sender->ss_head))
1165 {
1166 secret_destroy (ss);
1167 }
1170}
1171
1172
1181static void
1183 uint32_t serial,
1184 char key[AES_KEY_SIZE],
1185 char iv[AES_IV_SIZE])
1186{
1187 uint32_t sid = htonl (serial);
1188
1191 msec,
1192 "gnunet-communicator-udp-key",
1193 strlen ("gnunet-communicator-udp-key"),
1194 &sid, sizeof (sid),
1195 NULL,
1196 0);
1199 msec,
1200 "gnunet-communicator-udp-iv",
1201 strlen ("gnunet-communicator-udp-iv"),
1202 &sid, sizeof (sid),
1203 NULL,
1204 0);
1205}
1206
1207
1213static void
1220
1221
1227static void
1235
1236
1242static void
1244{
1245 struct GNUNET_TIME_Relative st;
1246 struct GNUNET_TIME_Relative rt;
1247 struct GNUNET_TIME_Relative delay;
1248 struct ReceiverAddress *receiver;
1249 struct SenderAddress *sender;
1250
1251 (void) cls;
1252 timeout_task = NULL;
1255 {
1257 if (0 != rt.rel_value_us)
1258 break;
1260 "Receiver timed out\n");
1262 }
1264 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1265 {
1266 if (GNUNET_YES != sender->sender_destroy_called)
1267 {
1269 if (0 != st.rel_value_us)
1270 break;
1271 sender_destroy (sender);
1272 }
1273 }
1274 delay = GNUNET_TIME_relative_min (rt, st);
1275 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1277}
1278
1279
1285static void
1287{
1289 sizeof(ss->cmac),
1290 &ss->master,
1291 "gnunet-communicator-udp-cmac",
1292 strlen ("gnunet-communicator-udp-cmac"),
1293 NULL,
1294 0);
1295}
1296
1297
1306static void
1308 const void *plaintext,
1309 size_t plaintext_len)
1310{
1311 const struct GNUNET_MessageHeader *hdr = plaintext;
1312 const char *pos = plaintext;
1313
1314 while (ntohs (hdr->size) <= plaintext_len)
1315 {
1317 "# bytes given to core",
1318 ntohs (hdr->size),
1319 GNUNET_NO);
1321 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1324 &sender->target,
1325 hdr,
1327 NULL /* no flow control possible */
1328 ,
1329 NULL));
1330 /* move on to next message, if any */
1331 plaintext_len -= ntohs (hdr->size);
1332 if (plaintext_len < sizeof(*hdr))
1333 break;
1334 pos += ntohs (hdr->size);
1335 hdr = (const struct GNUNET_MessageHeader *) pos;
1336 // TODO for now..., we do not actually sen >1msg or have a way of telling
1337 // if we are done
1338 break;
1339 }
1341 "# bytes padding discarded",
1342 plaintext_len,
1343 GNUNET_NO);
1344}
1345
1346
1355static void
1357 uint32_t serial,
1358 gcry_cipher_hd_t *cipher)
1359{
1360 char key[AES_KEY_SIZE];
1361 char iv[AES_IV_SIZE];
1362 int rc;
1363
1364 GNUNET_assert (0 ==
1365 gcry_cipher_open (cipher,
1366 GCRY_CIPHER_AES256 /* low level: go for speed */
1367 ,
1368 GCRY_CIPHER_MODE_GCM,
1369 0 /* flags */));
1370 get_iv_key (msec, serial, key, iv);
1371 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1372 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1373 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1374 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1375}
1376
1377
1390static int
1391try_decrypt (const struct SharedSecret *ss,
1392 const uint8_t *tag,
1393 uint32_t serial,
1394 const char *in_buf,
1395 size_t in_buf_size,
1396 char *out_buf)
1397{
1398 gcry_cipher_hd_t cipher;
1399
1400 setup_cipher (&ss->master, serial, &cipher);
1402 0 ==
1403 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1404 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1405 {
1406 gcry_cipher_close (cipher);
1408 "# AEAD authentication failures",
1409 1,
1410 GNUNET_NO);
1411 return GNUNET_SYSERR;
1412 }
1413 gcry_cipher_close (cipher);
1414 return GNUNET_OK;
1415}
1416
1417
1424static struct SharedSecret *
1426 )
1427{
1428 struct SharedSecret *ss;
1429
1430 ss = GNUNET_new (struct SharedSecret);
1432 calculate_cmac (ss);
1433 return ss;
1434}
1435
1436
1443static struct SharedSecret *
1446{
1447 struct SharedSecret *ss;
1448
1449 ss = GNUNET_new (struct SharedSecret);
1451 &ss->master);
1453 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1454 calculate_cmac (ss);
1455 return ss;
1456}
1457
1458
1466static struct SharedSecret *
1468 ,
1469 struct ReceiverAddress *receiver)
1470{
1471 struct SharedSecret *ss;
1472
1473 ss = GNUNET_new (struct SharedSecret);
1474 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key, ephemeral,
1475 &ss->master);
1476 calculate_cmac (ss);
1477 ss->receiver = receiver;
1478 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1479 receiver->num_secrets++;
1480 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1481 return ss;
1482}
1483
1484
1492static struct SharedSecret *
1495 struct ReceiverAddress *receiver)
1496{
1497 struct SharedSecret *ss;
1498
1499 ss = GNUNET_new (struct SharedSecret);
1501 c, &ss->master);
1503 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1504 calculate_cmac (ss);
1505 ss->receiver = receiver;
1506 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1507 receiver->num_secrets++;
1508 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1509 return ss;
1510}
1511
1512
1520static void
1522
1523
1531static unsigned int
1532purge_secrets (struct SharedSecret *ss_list_tail)
1533{
1534 struct SharedSecret *pos;
1535 struct SharedSecret *ss_to_purge;
1536 unsigned int deleted = 0;
1537
1539 "Purging secrets.\n");
1540 pos = ss_list_tail;
1541 while (NULL != pos)
1542 {
1543 ss_to_purge = pos;
1544 pos = pos->prev;
1545
1546 // FIXME we may also want to purge old unacked.
1547 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1548 {
1549 secret_destroy (ss_to_purge);
1550 deleted++;
1551 }
1552 }
1554 "Finished purging all, deleted %u.\n", deleted);
1555 return deleted;
1556}
1557
1558
1559static void
1560add_acks (struct SharedSecret *ss, int acks_to_add)
1561{
1562
1563 struct ReceiverAddress *receiver = ss->receiver;
1564
1565 GNUNET_assert (NULL != ss);
1566 GNUNET_assert (NULL != receiver);
1567
1568 if (NULL == receiver->d_qh)
1569 {
1570 receiver->d_qh =
1572 &receiver->target,
1573 receiver->foreign_addr,
1574 receiver->d_mtu,
1575 acks_to_add,
1576 1, /* Priority */
1577 receiver->nt,
1579 receiver->d_mq);
1580 }
1581 else
1582 {
1584 receiver->d_qh,
1585 acks_to_add,
1586 1);
1587 }
1588
1590 "Tell transport we have %u more acks!\n",
1591 acks_to_add);
1592
1593 // Until here for alternative 1
1594
1595 /* move ss to head to avoid discarding it anytime soon! */
1596
1597 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1598 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1599}
1600
1601
1612static int
1613handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1614{
1615 const struct UDPAck *ack = cls;
1616 struct ReceiverAddress *receiver = value;
1617 uint32_t acks_to_add;
1618 uint32_t allowed;
1619
1621 "in handle ack with cmac %s\n",
1622 GNUNET_h2s (&ack->cmac));
1623
1624 (void) key;
1625 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1626 {
1627 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1628 {
1629
1631 "Found matching cmac\n");
1632
1633 allowed = ntohl (ack->sequence_ack);
1634
1635 if (allowed <= ss->sequence_allowed)
1636 {
1638 "Ignoring ack, not giving us increased window\n.");
1639 return GNUNET_NO;
1640 }
1641 acks_to_add = (allowed - ss->sequence_allowed);
1642 GNUNET_assert (0 != acks_to_add);
1643 receiver->acks_available += (allowed - ss->sequence_allowed);
1644 ss->sequence_allowed = allowed;
1645 add_acks (ss, acks_to_add);
1647 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1648 allowed,
1649 acks_to_add,
1650 receiver->acks_available,
1651 GNUNET_sh2s (&ss->master));
1652 return GNUNET_NO;
1653 }
1654 }
1656 "Matching cmac not found for ack!\n");
1657 return GNUNET_YES;
1658}
1659
1660
1669static void
1671{
1672 struct UDPAck ack;
1673 GNUNET_assert (NULL != ss->sender);
1675 "Considering SS UDPAck %s\n",
1676 GNUNET_i2s_full (&ss->sender->target));
1677
1679 "Sender has %u acks available.\n",
1680 ss->sender->acks_available);
1681 /* drop ancient KeyCacheEntries */
1682 while ((NULL != ss->kce_head) &&
1683 (MAX_SQN_DELTA <
1685 kce_destroy (ss->kce_tail);
1686
1687
1689 ack.header.size = htons (sizeof(ack));
1690 ack.sequence_ack = htonl (ss->sequence_allowed);
1691 ack.cmac = ss->cmac;
1693 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1695 ss->sequence_allowed,
1696 GNUNET_sh2s (&(ss->master)));
1698 &ss->sender->target,
1700 &ack.header);
1701}
1702
1703
1704static void
1706{
1707 struct SharedSecret *ss = cls;
1708 ss->sender->kce_task = NULL;
1709
1711 "Precomputing %u keys for master %s\n",
1713 GNUNET_sh2s (&ss->master));
1714 if ((ss->override_available_acks != GNUNET_YES) &&
1715 (KCN_TARGET < ss->sender->acks_available))
1716 return;
1717 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1718 kce_generate (ss, ++ss->sequence_allowed);
1719
1724 if (KCN_TARGET > ss->sender->acks_available)
1725 {
1729 ss);
1730 return;
1731 }
1733 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1737 consider_ss_ack (ss);
1738}
1739
1740
1749static void
1751 const void *buf,
1752 size_t buf_size)
1753{
1754 const struct GNUNET_MessageHeader *hdr;
1755 const struct UDPAck *ack;
1756 const struct UDPRekey *rekey;
1757 struct SharedSecret *ss_rekey;
1758 const char *buf_pos = buf;
1759 size_t bytes_remaining = buf_size;
1760 uint16_t type;
1761
1762 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1763 if (sizeof(*hdr) > bytes_remaining)
1764 {
1765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1766 return; /* no data left */
1767 }
1769 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1770 (unsigned long long) bytes_remaining,
1771 ntohs (hdr->size),
1772 sizeof(*hdr),
1773 ntohs (hdr->type));
1774 if (ntohs (hdr->size) > bytes_remaining)
1775 return; /* buffer too short for indicated message length */
1776 type = ntohs (hdr->type);
1777 switch (type)
1778 {
1780 rekey = (struct UDPRekey*) buf_pos;
1781 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1782 ss_rekey->sender = sender;
1783 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1784 sender->num_secrets++;
1786 "Received rekey secret with cmac %s\n",
1787 GNUNET_h2s (&(ss_rekey->cmac)));
1789 "Received secret with master %s.\n",
1790 GNUNET_sh2s (&(ss_rekey->master)));
1792 "We have %u sequence_allowed.\n",
1793 ss_rekey->sequence_allowed);
1795 "We have a sender %p\n",
1796 ss_rekey->sender);
1798 "We have %u acks available.\n",
1799 ss_rekey->sender->acks_available);
1801 "# rekeying successful",
1802 1,
1803 GNUNET_NO);
1806 // FIXME
1807 kce_generate_cb (ss_rekey);
1808 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1809 WORKING_QUEUE_INTERVALL,
1810 kce_generate_cb,
1811 ss_rekey);*/
1812 // FIXME: Theoretically, this could be an Ack
1813 buf_pos += ntohs (hdr->size);
1814 bytes_remaining -= ntohs (hdr->size);
1815 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1816 if (0 == purge_secrets (sender->ss_tail))
1817 {
1818 // No secret purged. Delete oldest.
1819 if (sender->num_secrets > MAX_SECRETS)
1820 {
1821 secret_destroy (sender->ss_tail);
1822 }
1823 }
1824 break;
1826 /* lookup master secret by 'cmac', then update sequence_max */
1827 ack = (struct UDPAck*) buf_pos;
1829 &sender->key,
1830 &handle_ack,
1831 (void *) ack);
1832 /* There could be more messages after the ACK, handle those as well */
1833 buf_pos += ntohs (hdr->size);
1834 bytes_remaining -= ntohs (hdr->size);
1835 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1836 break;
1837
1839 /* skip padding */
1840 break;
1841
1842 default:
1843 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1844 }
1845 return;
1846}
1847
1848
1856static void
1857decrypt_box (const struct UDPBox *box,
1858 size_t box_len,
1859 struct KeyCacheEntry *kce)
1860{
1861 struct SharedSecret *ss = kce->ss;
1862 struct SharedSecret *ss_c = ss->sender->ss_tail;
1863 struct SharedSecret *ss_tmp;
1864 int ss_destroyed = 0;
1865 char out_buf[box_len - sizeof(*box)];
1866
1867 GNUNET_assert (NULL != ss->sender);
1868 if (GNUNET_OK != try_decrypt (ss,
1869 box->gcm_tag,
1870 kce->sequence_number,
1871 (const char *) &box[1],
1872 sizeof(out_buf),
1873 out_buf))
1874 {
1875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1877 "# Decryption failures with valid KCE",
1878 1,
1879 GNUNET_NO);
1880 kce_destroy (kce);
1881 ss->sender->acks_available--;
1882 return;
1883 }
1884 kce_destroy (kce);
1885 kce = NULL;
1886 ss->bytes_sent += box_len;
1887 ss->sender->acks_available--;
1888 ss->sequence_used++;
1890 "# bytes decrypted with BOX",
1891 sizeof(out_buf),
1892 GNUNET_NO);
1894 "# messages decrypted with BOX",
1895 1,
1896 GNUNET_NO);
1898 "decrypted UDPBox with kid %s\n",
1899 GNUNET_sh2s (&box->kid));
1900 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1901
1902 while (NULL != ss_c)
1903 {
1904 if (ss_c->bytes_sent >= rekey_max_bytes)
1905 {
1907 "Removing SS because rekey bytes reached.\n");
1908 ss_tmp = ss_c->prev;
1909 if (ss == ss_c)
1910 ss_destroyed = 1;
1911 secret_destroy (ss_c);
1912 ss_c = ss_tmp;
1913 continue;
1914 }
1915 ss_c = ss_c->prev;
1916 }
1917 if (1 == ss_destroyed)
1918 return;
1920 "Sender has %u ack left.\n",
1921 ss->sender->acks_available);
1922 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1923 (NULL == ss->sender->kce_task) &&
1925 {
1927 "Sender has %u ack left which is under threshold.\n",
1928 ss->sender->acks_available);
1932 ss);
1933 }
1934}
1935
1936
1941{
1945 const struct sockaddr *address;
1946
1950 socklen_t address_len;
1951
1956};
1957
1958
1970static struct SenderAddress *
1972 const struct sockaddr *address,
1973 socklen_t address_len)
1974{
1975 struct SenderAddress *sender;
1976 struct GNUNET_HashContext *hsh;
1977 struct GNUNET_HashCode sender_key;
1978
1980 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1981 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1982 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1983
1984 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1985 if (NULL != sender)
1986 {
1988 return sender;
1989 }
1990 sender = GNUNET_new (struct SenderAddress);
1991 sender->key = sender_key;
1992 sender->target = *target;
1993 sender->address = GNUNET_memdup (address, address_len);
1994 sender->address_len = address_len;
1996 senders,
1997 &sender->key,
1998 sender,
2001 "# senders active",
2003 GNUNET_NO);
2004 sender->timeout =
2007 sender,
2008 sender->timeout.abs_value_us);
2009 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2010 if (NULL == timeout_task)
2012 return sender;
2013}
2014
2015
2023static int
2025 const struct UDPConfirmation *uc)
2026{
2027 struct UdpHandshakeSignature uhs;
2028
2029 uhs.purpose.purpose = htonl (
2031 uhs.purpose.size = htonl (sizeof(uhs));
2032 uhs.sender = uc->sender;
2033 uhs.receiver = my_identity;
2034 uhs.enc = *enc;
2035 uhs.monotonic_time = uc->monotonic_time;
2038 &uhs,
2039 &uc->sender_sig,
2040 &uc->sender.public_key);
2041}
2042
2043
2052static char *
2053sockaddr_to_udpaddr_string (const struct sockaddr *address,
2054 socklen_t address_len)
2055{
2056 char *ret;
2057
2058 switch (address->sa_family)
2059 {
2060 case AF_INET:
2062 "%s-%s",
2064 GNUNET_a2s (address, address_len));
2065 break;
2066
2067 case AF_INET6:
2069 "%s-%s",
2071 GNUNET_a2s (address, address_len));
2072 break;
2073
2074 default:
2075 GNUNET_assert (0);
2076 }
2077 return ret;
2078}
2079
2080
2081static struct GNUNET_NETWORK_Handle *
2083{
2085
2086 if (NULL == receiver->udp_sock)
2087 {
2088 if (AF_INET6 == receiver->address->sa_family)
2090 else
2092 }
2093 else
2094 udp_sock = receiver->udp_sock;
2095
2096 return udp_sock;
2097}
2098
2099
2108static struct sockaddr *
2109udp_address_to_sockaddr (const char *bindto,
2110 sa_family_t family,
2111 socklen_t *sock_len)
2112{
2113 struct sockaddr *in;
2114 unsigned int port;
2115 char dummy[2];
2116 char *colon;
2117 char *cp;
2118
2119 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2120 {
2121 /* interpreting value as just a PORT number */
2122 if (port > UINT16_MAX)
2123 {
2125 "BINDTO specification `%s' invalid: value too large for port\n",
2126 bindto);
2127 return NULL;
2128 }
2129 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2130 {
2131 struct sockaddr_in *i4;
2132
2133 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2134 i4->sin_family = AF_INET;
2135 i4->sin_port = htons ((uint16_t) port);
2136 *sock_len = sizeof(struct sockaddr_in);
2137 in = (struct sockaddr *) i4;
2138 }
2139 else
2140 {
2141 struct sockaddr_in6 *i6;
2142
2143 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2144 i6->sin6_family = AF_INET6;
2145 i6->sin6_port = htons ((uint16_t) port);
2146 *sock_len = sizeof(struct sockaddr_in6);
2147 in = (struct sockaddr *) i6;
2148 }
2149 return in;
2150 }
2151 cp = GNUNET_strdup (bindto);
2152 colon = strrchr (cp, ':');
2153 if (NULL != colon)
2154 {
2155 /* interpret value after colon as port */
2156 *colon = '\0';
2157 colon++;
2158 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2159 {
2160 /* interpreting value as just a PORT number */
2161 if (port > UINT16_MAX)
2162 {
2164 "BINDTO specification `%s' invalid: value too large for port\n",
2165 bindto);
2166 GNUNET_free (cp);
2167 return NULL;
2168 }
2169 }
2170 else
2171 {
2172 GNUNET_log (
2174 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2175 bindto);
2176 GNUNET_free (cp);
2177 return NULL;
2178 }
2179 }
2180 else
2181 {
2182 /* interpret missing port as 0, aka pick any free one */
2183 port = 0;
2184 }
2185 if (AF_INET6 != family)
2186 {
2187 /* try IPv4 */
2188 struct sockaddr_in v4;
2189
2190 memset (&v4, 0, sizeof(v4));
2191 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2192 {
2193 v4.sin_family = AF_INET;
2194 v4.sin_port = htons ((uint16_t) port);
2195#if HAVE_SOCKADDR_IN_SIN_LEN
2196 v4.sin_len = sizeof(struct sockaddr_in);
2197#endif
2198 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2199 *sock_len = sizeof(struct sockaddr_in);
2200 GNUNET_free (cp);
2201 return in;
2202 }
2203 }
2204 if (AF_INET != family)
2205 {
2206 /* try IPv6 */
2207 struct sockaddr_in6 v6;
2208 const char *start;
2209
2210 memset (&v6, 0, sizeof(v6));
2211 start = cp;
2212 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2213 {
2214 start++; /* skip over '[' */
2215 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2216 }
2217 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2218 {
2219 v6.sin6_family = AF_INET6;
2220 v6.sin6_port = htons ((uint16_t) port);
2221#if HAVE_SOCKADDR_IN_SIN_LEN
2222 v6.sin6_len = sizeof(struct sockaddr_in6);
2223#endif
2224 in = GNUNET_memdup (&v6, sizeof(v6));
2225 *sock_len = sizeof(v6);
2226 GNUNET_free (cp);
2227 return in;
2228 }
2229 }
2230 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2231 GNUNET_free (cp);
2232 return NULL;
2233}
2234
2235
2236static void
2237sock_read (void *cls);
2238
2239
2240static enum GNUNET_GenericReturnValue
2242 const char *address,
2244{
2245 struct GNUNET_HashContext *hsh;
2246 struct ReceiverAddress *receiver;
2247 struct GNUNET_HashCode receiver_key;
2248 const char *path;
2249 struct sockaddr *in;
2250 socklen_t in_len;
2251
2252 if (0 != strncmp (address,
2254 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2255 {
2256 GNUNET_break_op (0);
2257 return GNUNET_SYSERR;
2258 }
2259 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2260 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2261
2262 if (NULL == in)
2263 {
2265 "Failed to setup UDP socket address\n");
2266 return GNUNET_SYSERR;
2267 }
2268 if ((AF_INET6 == in->sa_family) &&
2270 {
2272 "IPv6 disabled, skipping %s\n", address);
2273 GNUNET_free (in);
2274 return GNUNET_SYSERR;
2275 }
2276 else if (AF_INET == in->sa_family)
2277 {
2278 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2279 if (0 == sin->sin_port)
2280 {
2281 GNUNET_free (in);
2282 return GNUNET_NO;
2283 }
2284 }
2285
2287 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2288 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2289 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2290
2292 if (NULL != receiver)
2293 {
2295 "receiver %s already exist or is being connected to\n",
2296 address);
2297 return GNUNET_NO;
2298 }
2299
2301 receiver->udp_sock = udp_sock;
2302 receiver->key = receiver_key;
2303 receiver->address = in;
2304 receiver->address_len = in_len;
2305 receiver->target = *peer;
2306 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2307 &receiver->target_hpke_key);
2308 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2310 receivers,
2311 &receiver->key,
2312 receiver,
2315 "Added %s to receivers with address %s and sock %p\n",
2316 GNUNET_i2s_full (&receiver->target),
2317 address,
2318 udp_sock);
2319 receiver->timeout =
2322 receiver,
2323 receiver->timeout.abs_value_us);
2325 "# receivers active",
2327 GNUNET_NO);
2328 receiver->foreign_addr =
2329 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2330 if (NULL != udp_sock)
2333 udp_sock,
2334 &sock_read,
2335 udp_sock);
2337 if (NULL == timeout_task)
2339 return GNUNET_OK;
2340}
2341
2342
2348static void
2349sock_read (void *cls)
2350{
2351 struct sockaddr_storage sa;
2352 struct sockaddr_in *addr_verify;
2353 socklen_t salen = sizeof(sa);
2354 char buf[UINT16_MAX];
2355 ssize_t rcvd;
2356
2357 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2358
2361 udp_sock,
2362 &sock_read,
2363 udp_sock);
2366 udp_sock,
2367 &sock_read,
2368 udp_sock);
2369 while (1)
2370 {
2372 buf,
2373 sizeof(buf),
2374 (struct sockaddr *) &sa,
2375 &salen);
2376 if (-1 == rcvd)
2377 {
2378 struct sockaddr *addr = (struct sockaddr*) &sa;
2379
2380 if (EAGAIN == errno)
2381 break; // We are done reading data
2383 "Failed to recv from %s family %d failed sock %p\n",
2384 GNUNET_a2s ((struct sockaddr*) &sa,
2385 sizeof (*addr)),
2386 addr->sa_family,
2387 udp_sock);
2389 return;
2390 }
2392 "Read %llu bytes\n",
2393 (unsigned long long) rcvd);
2394 if (0 == rcvd)
2395 {
2396 GNUNET_break_op (0);
2398 "Read 0 bytes from UDP socket\n");
2399 return;
2400 }
2401
2402 /* first, see if it is a GNUNET_BurstMessage */
2403 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2404 {
2405 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2406 struct sockaddr *addr = (struct sockaddr*) &sa;
2407 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2408
2409 GNUNET_assert (0 == bm->local_port);
2411 "Received a burst message for default port\n");
2412 create_receiver (&bm->peer,
2413 address,
2414 NULL);
2415 if (AF_INET6 == addr->sa_family)
2417 else
2421 return;
2422 }
2423 /* second, see if it is a UDPBox */
2424 if (rcvd > sizeof(struct UDPBox))
2425 {
2426 const struct UDPBox *box;
2427 struct KeyCacheEntry *kce;
2428
2429 box = (const struct UDPBox *) buf;
2431 if (NULL != kce)
2432 {
2434 "Found KCE with kid %s\n",
2435 GNUNET_sh2s (&box->kid));
2436 decrypt_box (box, (size_t) rcvd, kce);
2437 continue;
2438 }
2439 }
2440
2441 /* next, check if it is a broadcast */
2442 if (sizeof(struct UDPBroadcast) == rcvd)
2443 {
2444 const struct UDPBroadcast *ub;
2445 struct UdpBroadcastSignature uhs;
2446 struct GNUNET_PeerIdentity sender;
2447
2448 addr_verify = GNUNET_memdup (&sa, salen);
2449 addr_verify->sin_port = 0;
2451 "received UDPBroadcast from %s\n",
2452 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2453 ub = (const struct UDPBroadcast *) buf;
2454 uhs.purpose.purpose = htonl (
2456 uhs.purpose.size = htonl (sizeof(uhs));
2457 uhs.sender = ub->sender;
2458 sender = ub->sender;
2459 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2461 {
2463 "Received our own broadcast\n");
2464 GNUNET_free (addr_verify);
2465 continue;
2466 }
2468 "checking UDPBroadcastSignature for %s\n",
2469 GNUNET_i2s (&sender));
2470 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2471 &uhs.h_address);
2472 if (GNUNET_OK ==
2475 &uhs,
2476 &ub->sender_sig,
2477 &ub->sender.public_key))
2478 {
2479 char *addr_s;
2481
2482 addr_s =
2483 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2484 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2485 /* use our own mechanism to determine network type */
2486 nt =
2487 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2489 "validating address %s received from UDPBroadcast\n",
2490 GNUNET_i2s (&sender));
2492 GNUNET_free (addr_s);
2493 GNUNET_free (addr_verify);
2494 continue;
2495 }
2496 else
2497 {
2499 "VerifyingPeer %s is verifying UDPBroadcast\n",
2502 "Verifying UDPBroadcast from %s failed\n",
2503 GNUNET_i2s (&ub->sender));
2504 }
2505 GNUNET_free (addr_verify);
2506 /* continue with KX, mostly for statistics... */
2507 }
2508
2509
2510 /* finally, test if it is a KX */
2511 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2512 {
2514 "# messages dropped (no kid, too small for KX)",
2515 1,
2516 GNUNET_NO);
2517 continue;
2518 }
2520 "Got KX\n");
2521 {
2522 const struct InitialKX *kx;
2523 struct SharedSecret *ss;
2524 char pbuf[rcvd - sizeof(struct InitialKX)];
2525 const struct UDPConfirmation *uc;
2526 struct SenderAddress *sender;
2527
2528 kx = (const struct InitialKX *) buf;
2531 "Before DEC\n");
2532
2533 if (GNUNET_OK != try_decrypt (ss,
2534 kx->gcm_tag,
2535 0,
2536 &buf[sizeof(*kx)],
2537 sizeof(pbuf),
2538 pbuf))
2539 {
2541 "Unable to decrypt tag, dropping...\n");
2542 GNUNET_free (ss);
2544 stats,
2545 "# messages dropped (no kid, AEAD decryption failed)",
2546 1,
2547 GNUNET_NO);
2548 continue;
2549 }
2551 "Before VERIFY\n");
2552
2553 uc = (const struct UDPConfirmation *) pbuf;
2554
2555 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2556 {
2557 GNUNET_break_op (0);
2558 GNUNET_free (ss);
2560 "# messages dropped (sender signature invalid)",
2561 1,
2562 GNUNET_NO);
2563 continue;
2564 }
2566 "Before SETUP_SENDER\n");
2567
2568 calculate_cmac (ss);
2569 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2570 ss->sender = sender;
2571 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2572 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2573 (NULL == ss->sender->kce_task) &&
2575 {
2576 // 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.
2580 ss);
2581 }
2582 sender->num_secrets++;
2583 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2585 "# messages decrypted without BOX",
2586 1,
2587 GNUNET_NO);
2588 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2589 if (0 == purge_secrets (sender->ss_tail))
2590 {
2591 // No secret purged. Delete oldest.
2592 if (sender->num_secrets > MAX_SECRETS)
2593 {
2594 secret_destroy (sender->ss_tail);
2595 }
2596 }
2597 }
2598 }
2599}
2600
2601
2609static void
2610do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2611{
2612 char pad[pad_size];
2613
2615 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2616 {
2617 struct GNUNET_MessageHeader hdr =
2618 { .size = htons (sizeof(pad)),
2620
2621 memcpy (pad, &hdr, sizeof(hdr));
2622 }
2624 0 ==
2625 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2626}
2627
2628
2629static void
2632 struct GNUNET_MQ_Handle *mq)
2633{
2634 uint16_t msize = ntohs (msg->size);
2635 struct UdpHandshakeSignature uhs;
2636 struct UDPConfirmation uc;
2637 struct InitialKX kx;
2638 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2639 size_t dpos;
2640 gcry_cipher_hd_t out_cipher;
2641 struct SharedSecret *ss;
2642
2643 if (msize > receiver->kx_mtu)
2644 {
2645 GNUNET_break (0);
2646 if (GNUNET_YES != receiver->receiver_destroy_called)
2648 return;
2649 }
2651
2652 /* setup key material */
2654
2655 if (0 == purge_secrets (receiver->ss_tail))
2656 {
2657 // No secret purged. Delete oldest.
2658 if (receiver->num_secrets > MAX_SECRETS)
2659 {
2660 secret_destroy (receiver->ss_tail);
2661 }
2662 }
2663
2664 setup_cipher (&ss->master, 0, &out_cipher);
2665 /* compute 'uc' */
2666 uc.sender = my_identity;
2667 uc.monotonic_time =
2669 uhs.purpose.purpose = htonl (
2671 uhs.purpose.size = htonl (sizeof(uhs));
2672 uhs.sender = my_identity;
2673 uhs.receiver = receiver->target;
2674 uhs.monotonic_time = uc.monotonic_time;
2676 &uhs,
2677 &uc.sender_sig);
2678 /* Leave space for kx */
2679 dpos = sizeof(kx);
2680 /* Append encrypted uc to dgram */
2681 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2682 &dgram[dpos],
2683 sizeof(uc),
2684 &uc,
2685 sizeof(uc)));
2686 dpos += sizeof(uc);
2687 /* Append encrypted payload to dgram */
2689 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2690 dpos += msize;
2691 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2692 /* Datagram starts with kx */
2693 kx.enc = uhs.enc;
2695 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2696 gcry_cipher_close (out_cipher);
2697 memcpy (dgram, &kx, sizeof(kx));
2699 dgram,
2700 sizeof(dgram),
2701 receiver->address,
2702 receiver->address_len))
2703 {
2706 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2707 msize,
2708 GNUNET_a2s (receiver->address,
2709 receiver->address_len),
2710 receiver->address->sa_family,
2714 return;
2715 }
2717 "Sending KX with payload size %u to %s with socket %p\n",
2718 msize,
2719 GNUNET_a2s (receiver->address,
2720 receiver->address_len),
2723}
2724
2725
2734static void
2736 const struct GNUNET_MessageHeader *msg,
2737 void *impl_state)
2738{
2739 struct ReceiverAddress *receiver = impl_state;
2740
2741 GNUNET_assert (mq == receiver->kx_mq);
2743}
2744
2745
2746static void
2748 UDPRekey *rekey)
2749{
2750 struct SharedSecret *ss_rekey;
2751
2753 /* setup key material */
2754 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2755 receiver);
2756 ss_rekey->sequence_allowed = 0;
2758 "Setup secret with k = %s\n",
2759 GNUNET_sh2s (&ss_rekey->master));
2761 "Setup secret with H(k) = %s\n",
2762 GNUNET_h2s (&(ss_rekey->cmac)));
2763
2764 /* Append encrypted payload to dgram */
2766 rekey->header.size = htons (sizeof (struct UDPRekey));
2767}
2768
2769
2778static void
2780 const struct GNUNET_MessageHeader *msg,
2781 void *impl_state)
2782{
2783 struct ReceiverAddress *receiver = impl_state;
2784 struct UDPRekey rekey;
2785 struct SharedSecret *ss;
2786 int inject_rekey = GNUNET_NO;
2787 uint16_t msize = ntohs (msg->size);
2788
2789 GNUNET_assert (mq == receiver->d_mq);
2790 if ((msize > receiver->d_mtu) ||
2791 (0 == receiver->acks_available))
2792 {
2794 "msize: %u, mtu: %llu, acks: %u\n",
2795 (unsigned int) msize,
2796 (unsigned long long) receiver->d_mtu,
2797 receiver->acks_available);
2798
2799 GNUNET_break (0);
2800 if (GNUNET_YES != receiver->receiver_destroy_called)
2802 return;
2803 }
2805
2806 if (receiver->num_secrets > MAX_SECRETS)
2807 {
2808 if ((0 == purge_secrets (receiver->ss_tail)) &&
2809 (NULL != receiver->ss_tail))
2810 {
2811 // No secret purged. Delete oldest.
2812 secret_destroy (receiver->ss_tail);
2813 }
2814 }
2815 /* begin "BOX" encryption method, scan for ACKs from tail! */
2816 ss = receiver->ss_tail;
2817 while (NULL != ss)
2818 {
2819 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2821 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2822 GNUNET_sh2s (&ss->master), ss->sequence_used,
2823 ss->sequence_allowed, ss->bytes_sent);
2824 if (ss->sequence_used >= ss->sequence_allowed)
2825 {
2826 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2827 // "Skipping ss because no acks to use.\n");
2828 ss = ss->prev;
2829 continue;
2830 }
2831 if (ss->bytes_sent >= rekey_max_bytes)
2832 {
2833 struct SharedSecret *ss_tmp;
2835 "Skipping ss because rekey bytes reached.\n");
2836 // FIXME cleanup ss with too many bytes sent!
2837 ss_tmp = ss->prev;
2838 secret_destroy (ss);
2839 ss = ss_tmp;
2840 continue;
2841 }
2842 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2843 {
2844 if (ss->rekey_initiated == GNUNET_NO)
2845 {
2847 "Injecting rekey for ss with byte sent %lu\n",
2848 (unsigned long) ss->bytes_sent);
2849 create_rekey (receiver, ss, &rekey);
2851 payload_len += sizeof (rekey);
2853 }
2854 }
2855 if (0 < ss->sequence_used)
2857 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
2858 GNUNET_sh2s (&ss->master),
2859 ss->sequence_used,
2860 ss->sequence_allowed);
2861 {
2862 char dgram[payload_len];
2863 struct UDPBox *box;
2864 gcry_cipher_hd_t out_cipher;
2865 size_t dpos;
2866
2867 box = (struct UDPBox *) dgram;
2868 ss->sequence_used++;
2869 get_kid (&ss->master, ss->sequence_used, &box->kid);
2870 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2871 /* Append encrypted payload to dgram */
2872 dpos = sizeof(struct UDPBox);
2873 if (GNUNET_YES == inject_rekey)
2874 {
2876 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2877 &rekey, sizeof (rekey)));
2878 dpos += sizeof (rekey);
2879 }
2881 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2882 dpos += msize;
2883 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2884 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2885 box->gcm_tag,
2886 sizeof(box->gcm_tag)));
2887 gcry_cipher_close (out_cipher);
2888
2890 dgram,
2891 payload_len, // FIXME why always send sizeof dgram?
2892 receiver->address,
2893 receiver->address_len))
2894 {
2897 "Sending UDPBox to %s family %d failed sock %p failed\n",
2898 GNUNET_a2s (receiver->address,
2899 receiver->address_len),
2900 receiver->address->sa_family,
2903 return;
2904 }
2906 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
2907 msize,
2908 receiver->acks_available,
2909 (unsigned long) ss->bytes_sent,
2911 ss->bytes_sent += sizeof (dgram);
2912 receiver->acks_available--;
2914 return;
2915 }
2916 }
2918 "No suitable ss found, sending as KX...\n");
2920}
2921
2922
2931static void
2932mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2933{
2934 struct ReceiverAddress *receiver = impl_state;
2936 "Default MQ destroyed\n");
2937 if (mq == receiver->d_mq)
2938 {
2939 receiver->d_mq = NULL;
2940 if (GNUNET_YES != receiver->receiver_destroy_called)
2942 }
2943}
2944
2945
2954static void
2955mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2956{
2957 struct ReceiverAddress *receiver = impl_state;
2959 "KX MQ destroyed\n");
2960 if (mq == receiver->kx_mq)
2961 {
2962 receiver->kx_mq = NULL;
2963 if (GNUNET_YES != receiver->receiver_destroy_called)
2965 }
2966}
2967
2968
2975static void
2976mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2977{
2978 /* Cancellation is impossible with UDP; bail */
2979 GNUNET_assert (0);
2980}
2981
2982
2992static void
2993mq_error (void *cls, enum GNUNET_MQ_Error error)
2994{
2995 struct ReceiverAddress *receiver = cls;
2996
2998 "MQ error in queue to %s: %d\n",
2999 GNUNET_i2s (&receiver->target),
3000 (int) error);
3002}
3003
3004
3012static void
3014{
3015 size_t base_mtu;
3016
3017 switch (receiver->address->sa_family)
3018 {
3019 case AF_INET:
3020 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3021 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3022 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3023 break;
3024
3025 case AF_INET6:
3026 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3027 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3028 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3029 break;
3030
3031 default:
3032 GNUNET_assert (0);
3033 break;
3034 }
3035 /* MTU based on full KX messages */
3036 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3037 - sizeof(struct UDPConfirmation); /* 104 */
3038 /* MTU based on BOXed messages */
3039 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3040
3042 "Setting up MQs and QHs\n");
3043 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3044 1404 (IPv4 + Box) bytes, depending on circumstances... */
3045 if (NULL == receiver->kx_mq)
3048 &mq_cancel,
3049 receiver,
3050 NULL,
3051 &mq_error,
3052 receiver);
3053 if (NULL == receiver->d_mq)
3055 &mq_destroy_d,
3056 &mq_cancel,
3057 receiver,
3058 NULL,
3059 &mq_error,
3060 receiver);
3061
3062 receiver->kx_qh =
3064 &receiver->target,
3065 receiver->foreign_addr,
3066 receiver->kx_mtu,
3068 0, /* Priority */
3069 receiver->nt,
3071 receiver->kx_mq);
3072}
3073
3074
3093static int
3094mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3095{
3096 (void) cls;
3098 "create receiver for mq_init\n");
3099 return create_receiver (peer,
3100 address,
3101 NULL);
3102}
3103
3104
3113static int
3115 const struct GNUNET_HashCode *target,
3116 void *value)
3117{
3118 struct ReceiverAddress *receiver = value;
3119
3120 (void) cls;
3121 (void) target;
3123 return GNUNET_OK;
3124}
3125
3126
3135static int
3137 const struct GNUNET_HashCode *target,
3138 void *value)
3139{
3140 struct SenderAddress *sender = value;
3141
3142 (void) cls;
3143 (void) target;
3144
3145
3146 sender_destroy (sender);
3147 return GNUNET_OK;
3148}
3149
3150
3156static void
3157do_shutdown (void *cls)
3158{
3160 "do_shutdown\n");
3161 GNUNET_stop_burst (NULL);
3162 if (NULL != nat)
3163 {
3165 nat = NULL;
3166 }
3167 while (NULL != bi_head)
3169 if (NULL != broadcast_task)
3170 {
3172 broadcast_task = NULL;
3173 }
3174 if (NULL != timeout_task)
3175 {
3177 timeout_task = NULL;
3178 }
3179 if (NULL != read_v6_task)
3180 {
3182 read_v6_task = NULL;
3183 }
3184 if (NULL != read_v4_task)
3185 {
3187 read_v4_task = NULL;
3188 }
3189 if (NULL != default_v6_sock)
3190 {
3193 default_v6_sock = NULL;
3194 }
3195 if (NULL != default_v4_sock)
3196 {
3199 default_v4_sock = NULL;
3200 }
3203 NULL);
3207 NULL);
3212 if (NULL != timeout_task)
3213 {
3215 timeout_task = NULL;
3216 }
3217 if (NULL != ch)
3218 {
3220 ch = NULL;
3221 }
3222 if (NULL != ah)
3223 {
3225 ah = NULL;
3226 }
3227 if (NULL != pils)
3228 {
3230 pils = NULL;
3231 }
3232 if (NULL != stats)
3233 {
3235 stats = NULL;
3236 }
3237 if (NULL != my_private_key)
3238 {
3240 my_private_key = NULL;
3241 }
3242 if (NULL != is)
3243 {
3245 is = NULL;
3246 }
3248 "do_shutdown finished\n");
3249}
3250
3251
3253{
3254 const struct UDPAck *ack;
3255
3257};
3258
3259static int
3260handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3261{
3262 struct ReceiverAddress *receiver = value;
3263 struct AckInfo *ai = cls;
3264
3265 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3266 {
3267 return GNUNET_YES;
3268 }
3269 handle_ack ((void*) ai->ack, key, receiver);
3270 return GNUNET_YES;
3271}
3272
3273
3283static void
3284enc_notify_cb (void *cls,
3285 const struct GNUNET_PeerIdentity *sender,
3286 const struct GNUNET_MessageHeader *msg)
3287{
3288 struct AckInfo ai;
3289
3290 (void) cls;
3292 "Storing UDPAck received from backchannel from %s\n",
3295 (ntohs (msg->size) != sizeof(struct UDPAck)))
3296 {
3297 GNUNET_break_op (0);
3298 return;
3299 }
3300 ai.ack = (const struct UDPAck *) msg;
3301 ai.sender = sender;
3304 &ai);
3305}
3306
3307
3321static void
3323 void **app_ctx,
3324 int add_remove,
3326 const struct sockaddr *addr,
3327 socklen_t addrlen)
3328{
3329 char *my_addr;
3331
3332 if (GNUNET_YES == add_remove)
3333 {
3335
3336 GNUNET_asprintf (&my_addr,
3337 "%s-%s",
3339 GNUNET_a2s (addr, addrlen));
3340 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3341 ai =
3343 my_addr,
3344 nt,
3346 GNUNET_free (my_addr);
3347 *app_ctx = ai;
3348 }
3349 else
3350 {
3351 ai = *app_ctx;
3353 *app_ctx = NULL;
3354 }
3355}
3356
3357
3363static void
3364ifc_broadcast (void *cls)
3365{
3366 struct BroadcastInterface *bi = cls;
3367 struct GNUNET_TIME_Relative delay;
3368
3369 delay = BROADCAST_FREQUENCY;
3370 delay.rel_value_us =
3372 bi->broadcast_task =
3374
3375 switch (bi->sa->sa_family)
3376 {
3377 case AF_INET: {
3378 static int yes = 1;
3379 static int no = 0;
3380 ssize_t sent;
3381
3382 if (GNUNET_OK !=
3384 SOL_SOCKET,
3385 SO_BROADCAST,
3386 &yes,
3387 sizeof(int)))
3389 "setsockopt");
3391 "creating UDPBroadcast from %s\n",
3392 GNUNET_i2s (&(bi->bcm.sender)));
3394 "sending UDPBroadcast to add %s\n",
3395 GNUNET_a2s (bi->ba, bi->salen));
3397 &bi->bcm,
3398 sizeof(bi->bcm),
3399 bi->ba,
3400 bi->salen);
3401 if (-1 == sent)
3403 "sendto");
3405 SOL_SOCKET,
3406 SO_BROADCAST,
3407 &no,
3408 sizeof(int)))
3410 "setsockopt");
3411 break;
3412 }
3413
3414 case AF_INET6: {
3415 ssize_t sent;
3416 struct sockaddr_in6 dst;
3417
3418 dst.sin6_family = AF_INET6;
3419 dst.sin6_port = htons (my_port);
3420 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3421 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3422
3424 "sending UDPBroadcast\n");
3426 &bi->bcm,
3427 sizeof(bi->bcm),
3428 (const struct sockaddr *) &dst,
3429 sizeof(dst));
3430 if (-1 == sent)
3432 break;
3433 }
3434
3435 default:
3436 GNUNET_break (0);
3437 break;
3438 }
3439}
3440
3441
3456static int
3457iface_proc (void *cls,
3458 const char *name,
3459 int isDefault,
3460 const struct sockaddr *addr,
3461 const struct sockaddr *broadcast_addr,
3462 const struct sockaddr *netmask,
3463 socklen_t addrlen)
3464{
3465 struct BroadcastInterface *bi;
3466 enum GNUNET_NetworkType network;
3467 struct UdpBroadcastSignature ubs;
3468
3469 (void) cls;
3470 (void) netmask;
3471 if (NULL == my_private_key)
3472 return GNUNET_YES;
3473 if (NULL == addr)
3474 return GNUNET_YES; /* need to know our address! */
3475 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3476 if (GNUNET_NT_LOOPBACK == network)
3477 {
3478 /* Broadcasting on loopback does not make sense */
3479 return GNUNET_YES;
3480 }
3481 for (bi = bi_head; NULL != bi; bi = bi->next)
3482 {
3483 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3484 {
3485 bi->found = GNUNET_YES;
3486 return GNUNET_OK;
3487 }
3488 }
3489
3490 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3491 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3492 if ((AF_INET6 == addr->sa_family) && (NULL != default_v6_sock))
3493 return GNUNET_OK; /* not using IPv6 */
3494
3495 bi = GNUNET_new (struct BroadcastInterface);
3496 bi->sa = GNUNET_memdup (addr,
3497 addrlen);
3498 if ( (NULL != broadcast_addr) &&
3499 (addrlen == sizeof (struct sockaddr_in)) )
3500 {
3501 struct sockaddr_in *ba;
3502
3503 ba = GNUNET_memdup (broadcast_addr,
3504 addrlen);
3505 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3506 bi->ba = (struct sockaddr *) ba;
3507 }
3508 bi->salen = addrlen;
3509 bi->found = GNUNET_YES;
3510 bi->bcm.sender = my_identity;
3511 ubs.purpose.purpose = htonl (
3513 ubs.purpose.size = htonl (sizeof(ubs));
3514 ubs.sender = my_identity;
3516 "creating UDPBroadcastSignature for %s\n",
3517 GNUNET_a2s (addr, addrlen));
3518 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3520 &ubs,
3521 &bi->bcm.sender_sig);
3522 if (NULL != bi->ba)
3523 {
3526 }
3527 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3528 {
3529 /* Create IPv6 multicast request */
3530 const struct sockaddr_in6 *s6 =
3531 (const struct sockaddr_in6 *) broadcast_addr;
3532
3534 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3535
3536 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3537 *
3538 * IPV6_JOIN_GROUP
3539 *
3540 * Join a multicast group on a specified local interface. If the
3541 * interface index is specified as 0, the kernel chooses the local
3542 * interface. For example, some kernels look up the multicast
3543 * group in the normal IPv6 routing table and using the resulting
3544 * interface; we do this for each interface, so no need to use
3545 * zero (anymore...).
3546 */
3547 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3548
3549 /* Join the multicast group */
3551 IPPROTO_IPV6,
3552 IPV6_JOIN_GROUP,
3553 &bi->mcreq,
3554 sizeof(bi->mcreq)))
3555 {
3557 }
3558 }
3559 return GNUNET_OK;
3560}
3561
3562
3568static void
3569do_broadcast (void *cls)
3570{
3571 struct BroadcastInterface *bin;
3572
3573 (void) cls;
3574 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3575 bi->found = GNUNET_NO;
3577 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3578 {
3579 bin = bi->next;
3580 if (GNUNET_NO == bi->found)
3581 bi_destroy (bi);
3582 }
3584 &do_broadcast,
3585 NULL);
3586}
3587
3588
3589static void
3591 const struct sockaddr *addr,
3592 socklen_t addrlen)
3593{
3594 /* FIXME: support reversal: #5529 */
3596 "No connection reversal implemented!\n");
3597}
3598
3599
3600static void
3602{
3604 sizeof (*sock_info->actual_address
3605 ));
3606 create_receiver (sock_info->pid,
3607 address,
3608 default_v4_sock == sock_info->udp_sock ||
3609 default_v6_sock == sock_info->udp_sock ?
3610 NULL : sock_info->udp_sock);
3612 GNUNET_free (sock_info);
3613}
3614
3615
3616static void
3617start_burst (const char *addr,
3618 struct GNUNET_TIME_Relative rtt,
3619 struct GNUNET_PeerIdentity *pid)
3620{
3621 struct GNUNET_UdpSocketInfo *sock_info;
3622
3624 "Communicator was called to start burst to address %s from %s\n",
3625 addr,
3626 my_ipv4);
3627
3628 GNUNET_stop_burst (NULL);
3629
3630 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3631 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3632 sock_info->address = GNUNET_strdup (addr);
3633 sock_info->bind_address = my_ipv4;
3634 sock_info->has_port = GNUNET_YES;
3635 sock_info->udp_sock = default_v4_sock;
3636 sock_info->rtt = rtt;
3637 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3638 sock_info->std_port = my_port;
3640 "1 sock addr %s addr %s rtt %lu %u\n",
3641 sock_info->address,
3642 addr,
3643 (unsigned long) sock_info->rtt.rel_value_us,
3644 my_port);
3645 burst_task = GNUNET_get_udp_socket (sock_info,
3647 GNUNET_free (sock_info);
3648}
3649
3650
3651static struct GNUNET_NETWORK_Handle*
3652create_udp_socket (const char *bindto,
3653 sa_family_t family,
3654 struct sockaddr **out,
3655 socklen_t *out_len)
3656{
3657 struct GNUNET_NETWORK_Handle *sock;
3658 struct sockaddr *in;
3659 socklen_t in_len;
3660 struct sockaddr_storage in_sto;
3661 socklen_t sto_len;
3662
3663 in = udp_address_to_sockaddr (bindto, family, &in_len);
3664 if (NULL == in)
3665 {
3667 "Failed to setup UDP socket address with path `%s'\n",
3668 bindto);
3669 return NULL;
3670 }
3671
3672 if ((AF_UNSPEC != family) && (in->sa_family != family))
3673 {
3675 "Invalid UDP socket address setup with path `%s'\n",
3676 bindto);
3677 GNUNET_free (in);
3678 return NULL;
3679 }
3680
3681 sock =
3682 GNUNET_NETWORK_socket_create (in->sa_family,
3683 SOCK_DGRAM,
3684 IPPROTO_UDP);
3685 if (NULL == sock)
3686 {
3689 "Failed to create socket for %s family %d\n",
3690 GNUNET_a2s (in,
3691 in_len),
3692 in->sa_family);
3693 GNUNET_free (in);
3694 return NULL;
3695 }
3696 if (GNUNET_OK !=
3698 in,
3699 in_len))
3700 {
3702 "bind",
3703 bindto);
3705 "Failed to bind socket for %s family %d sock %p\n",
3706 GNUNET_a2s (in,
3707 in_len),
3708 in->sa_family,
3709 sock);
3711 sock = NULL;
3712 GNUNET_free (in);
3713 return NULL;
3714 }
3715
3716 /* We might have bound to port 0, allowing the OS to figure it out;
3717 thus, get the real IN-address from the socket */
3718 sto_len = sizeof(in_sto);
3719 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3720 (struct sockaddr *) &in_sto,
3721 &sto_len))
3722 {
3723 memcpy (&in_sto, in, in_len);
3724 sto_len = in_len;
3725 }
3726 GNUNET_free (in);
3727 *out = GNUNET_malloc (sto_len);
3728 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3729 *out_len = sto_len;
3730 return sock;
3731}
3732
3733
3734static void
3735shutdown_run (struct sockaddr *addrs[2])
3736{
3737 if (NULL != addrs[0])
3738 GNUNET_free (addrs[0]);
3739 if (NULL != addrs[1])
3740 GNUNET_free (addrs[1]);
3742}
3743
3744
3758static enum GNUNET_GenericReturnValue
3760{
3761 char *filename;
3762 struct GNUNET_DISK_FileHandle *filehandle;
3763 int ret;
3764
3765 if (GNUNET_OK !=
3767 "pils",
3768 "SECRET_KEY_FILE",
3769 &filename))
3770 {
3772 "PILS service is lacking initial secret key file configuration setting. Exiting\n");
3773 return GNUNET_SYSERR;
3774 }
3775 if (NULL == filename)
3776 return GNUNET_SYSERR;
3778 if (GNUNET_SYSERR == ret)
3779 return GNUNET_SYSERR;
3780 if (GNUNET_NO == ret)
3781 {
3782 /* File does not exist - generate a new initial secret key and save it */
3783 // TODO consider the case that the file exists and ist not readable
3785 ikm,
3786 sizeof ikm);
3788 {
3790 "PILS service cannot create dir for saving initial secret key file. Exiting\n");
3791 return GNUNET_SYSERR;
3792 }
3793 filehandle = GNUNET_DISK_file_open (filename,
3797 | // would
3798 // the
3799 // group
3800 // need
3801 // read
3802 // perm?
3804 if (NULL == filehandle)
3805 {
3807 "PILS service had an issue with opening the initial secret key file. Exiting\n");
3808 GNUNET_DISK_file_close (filehandle);
3809 return GNUNET_SYSERR;
3810 }
3811 ret = GNUNET_DISK_file_write (filehandle,
3812 ikm,
3813 sizeof ikm);
3814 GNUNET_DISK_file_close (filehandle);
3815 if (sizeof ikm != ret)
3816 {
3818 "PILS service had an issue with writing the initial secret key to file. Exiting\n")
3819 ;
3820 return GNUNET_SYSERR;
3821 }
3822 }
3823 else
3824 {
3825 /* File existes - just read from it */
3826 off_t size;
3828 "PILS is going to read initial secret key from file %s\n",
3829 filename);
3830 filehandle = GNUNET_DISK_file_open (filename,
3833 if (NULL == filehandle)
3834 {
3836 " Not able to open file\n");
3837 return GNUNET_SYSERR;
3838 }
3839 if (GNUNET_OK != GNUNET_DISK_file_handle_size (filehandle, &size))
3840 {
3842 " File has the wrong size %lu\n",
3843 size);
3844 GNUNET_DISK_file_close (filehandle);
3845 return GNUNET_SYSERR;
3846 }
3847 if (sizeof ikm != size)
3848 {
3850 " Something is wrong with the file size, expected: %lu size, got: %lu\n",
3851 size,
3852 sizeof ikm);
3853 GNUNET_DISK_file_close (filehandle);
3854 return GNUNET_SYSERR;
3855 }
3856 ret = GNUNET_DISK_file_read (filehandle,
3857 ikm,
3858 sizeof ikm);
3859 GNUNET_DISK_file_close (filehandle);
3860 if (sizeof ikm != ret)
3861 {
3863 " Read initial secret key with wrong size %u, expected %lu\n", ret,
3864 sizeof ikm);
3865 return GNUNET_SYSERR;
3866 }
3867
3868 }
3869 return GNUNET_OK;
3870}
3871
3872
3873void
3874pid_change_cb (void *cls,
3875 const struct GNUNET_HELLO_Parser *parser,
3876 const struct GNUNET_HashCode *addr_hash)
3877{
3879 "Got PID to derive from `%s':\n",
3880 GNUNET_h2s (addr_hash));
3881 if (NULL == my_private_key)
3883
3885 (uint8_t*) ikm,
3886 addr_hash,
3892 /* start broadcasting */
3893 if (GNUNET_YES !=
3896 "DISABLE_BROADCAST"))
3897 {
3898 if (NULL == broadcast_task)
3900 }
3901}
3902
3903
3904static void
3905run (void *cls,
3906 char *const *args,
3907 const char *cfgfile,
3908 const struct GNUNET_CONFIGURATION_Handle *c)
3909{
3910 const struct sockaddr_in *v4;
3911 char *bindto;
3912 char *bindto6;
3913 struct sockaddr *in[2];
3914 socklen_t in_len[2];
3915
3917 "Entering the run method of udp communicator.\n");
3918
3919 cfg = c;
3921 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3922 (GNUNET_YES ==
3925 "DISABLE_V6")))
3926 {
3928 }
3929
3930 if (GNUNET_OK !=
3933 "BINDTO",
3934 &bindto))
3935 {
3938 "BINDTO");
3939 return;
3940 }
3942 "The udp communicator will bind to %s for IPv4\n",
3943 bindto);
3944 if (GNUNET_YES != disable_v6)
3945 {
3946 if (GNUNET_OK !=
3949 "BINDTO6",
3950 &bindto6))
3951 {
3954 "BINDTO6");
3955 return;
3956 }
3957
3959 "The udp communicator will bind to %s for IPv6\n",
3960 bindto6);
3961 }
3962 else
3963 bindto6 = NULL;
3964 if (GNUNET_OK !=
3967 "REKEY_INTERVAL",
3970
3971 if (GNUNET_OK !=
3974 "REKEY_MAX_BYTES",
3976 {
3978 }
3979
3980 memset (in, 0, sizeof(struct sockaddr*) * 2);
3981 memset (in_len, 0, sizeof(socklen_t) * 2);
3982
3983 GNUNET_assert (bindto);
3985 bindto, AF_INET, &(in[0]), &(in_len[0]));
3986 GNUNET_free (bindto);
3987
3988 if (GNUNET_YES != disable_v6)
3989 {
3990 GNUNET_assert (bindto6);
3992 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3993 GNUNET_free (bindto6);
3994 }
3995 else
3996 default_v6_sock = NULL;
3997
3998 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3999 return;
4000
4001 my_port = 0;
4002 if (NULL != default_v4_sock)
4003 {
4004 GNUNET_assert (in[0]);
4006 "transport",
4007 "Bound to `%s' sock %p\n",
4008 GNUNET_a2s ((const struct sockaddr *) in[0],
4009 in_len[0]),
4011
4012 v4 = (const struct sockaddr_in *) in[0];
4013
4014 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
4015 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
4016 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
4017 }
4018 if (NULL != default_v6_sock)
4019 {
4020 GNUNET_assert (in[1]);
4022 "transport",
4023 "Bound to `%s' sock %p\n",
4024 GNUNET_a2s ((const struct sockaddr *) in[1],
4025 in_len[1]),
4027 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
4028 }
4029 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
4038 /* start reading */
4039 if (NULL != default_v4_sock)
4042 &sock_read,
4044 else
4045 read_v4_task = NULL;
4046 if (NULL != default_v6_sock)
4049 &sock_read,
4051 else
4052 read_v6_task = NULL;
4057 &mq_init,
4058 NULL,
4060 NULL,
4061 &start_burst);
4062 if (NULL == ch)
4063 {
4064 GNUNET_break (0);
4065 shutdown_run (in);
4066 return;
4067 }
4069 if (NULL == ah)
4070 {
4071 GNUNET_break (0);
4072 shutdown_run (in);
4073 return;
4074 }
4075 /* start broadcasting */
4076 if (GNUNET_YES !=
4079 "DISABLE_BROADCAST"))
4080 {
4082 }
4083 load_ikm ();
4085 GNUNET_assert (NULL != pils);
4086
4089 IPPROTO_UDP,
4090 (NULL != in[0]? 1 : 0)
4091 + (NULL != in[1]? 1 : 0),
4092 (const struct sockaddr**)
4093 (NULL != in[0]? in : &(in[1])),
4094 NULL != in[0]? in_len : &(in_len[1]),
4097 NULL /* closure */);
4098 if (NULL != in[0])
4099 GNUNET_free (in[0]);
4100 if (NULL != in[1])
4101 GNUNET_free (in[1]);
4102}
4103
4104
4105GNUNET_DAEMON_MAIN ("gnunet-communicator-udp",
4106 _ ("GNUnet UDP communicator"),
4107 &run)
4108/* end of gnunet-communicator-udp.c */
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static uint16_t port
Port number.
Definition gnunet-bcd.c:146
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
#define AES_KEY_SIZE
AES key size.
void pid_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
static struct BroadcastInterface * bi_tail
Broadcast interface tasks.
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
static int try_decrypt(const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
Try to decrypt buf using shared secret ss and key/iv derived using serial.
#define WORKING_QUEUE_INTERVALL
static void kce_destroy(struct KeyCacheEntry *kce)
Free memory used by key cache entry.
static int handle_ack(void *cls, const struct GNUNET_HashCode *key, void *value)
We received an ACK for pid.
static void create_rekey(struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static int secret_destroy(struct SharedSecret *ss)
Destroy ss and associated key cache entries.
#define GCM_TAG_SIZE
Size of the GCM tag.
static void get_iv_key(const struct GNUNET_ShortHashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
Compute key and iv.
static struct GNUNET_PeerIdentity my_identity
Our public key.
static void mq_send_kx(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static struct SharedSecret * setup_initial_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM for initial handshake.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static unsigned char ikm[256/8]
The initial key material for the peer.
static void kce_generate(struct SharedSecret *ss, uint32_t seq)
Setup key cache entry for sequence number seq and shared secret ss.
static void setup_cipher(const struct GNUNET_ShortHashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.
static struct GNUNET_NETWORK_Handle * create_udp_socket(const char *bindto, sa_family_t family, struct sockaddr **out, socklen_t *out_len)
static void add_acks(struct SharedSecret *ss, int acks_to_add)
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static struct GNUNET_SCHEDULER_Task * read_v6_task
ID of read IPv6 task.
static struct GNUNET_SCHEDULER_Task * read_v4_task
ID of read IPv4 task.
static void mq_destroy_kx(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static void eddsa_priv_to_hpke_key(struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
static int get_receiver_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all receivers to clean up.
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static struct GNUNET_SCHEDULER_Task * broadcast_task
ID of master broadcast task.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static int verify_confirmation(const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct UDPConfirmation *uc)
Check signature from uc against ephemeral.
static int disable_v6
IPv6 disabled or not.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static 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 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 enum GNUNET_GenericReturnValue load_ikm()
FIXME: We could alternatively ask PILS for de/encaps, but at a high cost wrt async RPC calls....
static struct GNUNET_SCHEDULER_Task * burst_task
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral)
Setup shared secret for decryption.
#define MAX_SQN_DELTA
What is the maximum delta between KCN sequence numbers that we allow.
#define LOG(kind,...)
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
#define KCN_THRESHOLD
If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET...
#define MAX_SECRETS
How many shared master secrets do we keep around at most per sender? Should be large enough so that w...
static struct BroadcastInterface * bi_head
Broadcast interface tasks.
static enum GNUNET_GenericReturnValue create_receiver(const struct GNUNET_PeerIdentity *peer, const char *address, struct GNUNET_NETWORK_Handle *udp_sock)
static void eddsa_pub_to_hpke_key(struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_EcdhePublicKey *pk)
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_CRYPTO_EcdhePrivateKey my_x25519_private_key
Our private key for HPKE.
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 char * filename
static OpusEncoder * enc
OPUS encoder.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_FS_UnindexContext * uc
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:367
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:390
void GNUNET_PILS_derive_pid(size_t seed_key_bytes, const uint8_t seed_key[seed_key_bytes], const struct GNUNET_HashCode *addrs_hash, struct GNUNET_CRYPTO_EddsaPrivateKey *outkey)
Generate the peer id from the addresses hash and the initial secret key.
Definition pils_api.c:507
Constants for network protocols.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE
Signature used by UDP communicator handshake.
API to create, modify and access statistics.
Bandwidth allocation API for applications to interact with.
API of the transport service towards the communicator processes.
void GNUNET_TRANSPORT_communicator_address_remove(struct GNUNET_TRANSPORT_AddressIdentifier *ai)
Notify transport service about an address that this communicator no longer provides for this peer.
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
void GNUNET_TRANSPORT_communicator_burst_finished(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
The communicator tells the transport service that it finished the burst.
void GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
struct GNUNET_TRANSPORT_QueueHandle * GNUNET_TRANSPORT_communicator_mq_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *peer, const char *address, uint32_t mtu, uint64_t q_len, uint32_t priority, enum GNUNET_NetworkType nt, enum GNUNET_TRANSPORT_ConnectionStatus cs, struct GNUNET_MQ_Handle *mq)
Notify transport service that a MQ became available due to an "inbound" connection or because the com...
void GNUNET_TRANSPORT_application_validate(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_NetworkType nt, const char *addr)
An application (or a communicator) has received a HELLO (or other address data of another peer) and w...
void GNUNET_TRANSPORT_communicator_mq_update(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_TRANSPORT_QueueHandle *u_qh, uint64_t q_len, uint32_t priority)
Notify transport service that an MQ was updated.
void GNUNET_TRANSPORT_communicator_notify(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *pid, const char *comm, const struct GNUNET_MessageHeader *header)
The communicator asks the transport service to route a message via a different path to another commun...
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls, GNUNET_TRANSPORT_StartBurstNotify sb)
Connect to the transport service.
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer.
@ GNUNET_TRANSPORT_CC_UNRELIABLE
Transmission is unreliable (e.g.
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Decapsulate a key for a private EdDSA key.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_decaps(const struct GNUNET_CRYPTO_EcdhePrivateKey *skR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh decapsulation with own private key and the representative of the received public key...
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:201
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps(const struct GNUNET_CRYPTO_EcdhePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
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).
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition disk.c:1258
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition disk.c:710
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test_read(const char *fil)
Check that fil corresponds to a filename and the file has read permissions.
Definition disk.c:540
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1332
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition disk.c:633
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition disk.c:673
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition disk.c:206
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_extract(struct GNUNET_ShortHashCode *prk, const void *salt, size_t salt_len, const void *ikm, size_t ikm_len)
HKDF-Extract using SHA256.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk,...)
HKDF-Expand using SHA256.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
#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.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_PrivateKey *sk, struct GNUNET_CRYPTO_EcdhePrivateKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_PublicKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...) __attribute__((format(printf
Log function that specifies an alternative component.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:482
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition mq.c:437
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
struct GNUNET_SCHEDULER_Task * GNUNET_get_udp_socket(struct GNUNET_UdpSocketInfo *sock_info, GNUNET_NotifyUdpSocket nus)
Method to get a UDP socket for a peer that is natted.
Definition nat.c:509
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition nat_api.c:366
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition nat_api.c:703
void GNUNET_stop_burst(struct GNUNET_NETWORK_Handle *do_not_touch)
Method to stop all sockets we established to the other peer.
Definition nat.c:564
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition network.c:1001
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition network.c:688
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition network.c:79
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition network.c:439
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition network.c:806
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition network.c:772
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition nt.c:428
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition nt.c:407
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition nt.c:309
@ GNUNET_NT_LOOPBACK
Loopback (same host).
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition os_network.c:397
#define GNUNET_DAEMON_MAIN(daemon_name, daemon_help, init_cb)
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY
UDP Rekey.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK
UDP KX acknowledgement.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition scheduler.c:1511
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1339
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1304
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1277
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition time.c:344
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition time.c:864
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:640
static unsigned int size
Size of the "table".
Definition peer.c:68
#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.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
an ECC signature using EdDSA.
HPKE DHKEM encapsulation (X25519) See RFC 9180.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Handle used to access files (and pipes).
Context for parsing HELLOs.
Definition hello-uri.c:232
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Header for all communications.
Handle for active NAT registrations.
Definition nat_api.c:72
handle to a socket
Definition network.c:53
Handle to the interface scanner.
Definition nt.c:104
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:136
Handle for the service.
A 256-bit hashcode.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Internal representation of an address a communicator is currently providing for the transport service...
Handle to the TRANSPORT subsystem for application management.
Opaque handle to the transport service for communicators.
Handle returned to identify the internal data structure the transport API has created to manage a mes...
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.
Struct with the socket we like to use to send messages to another peer.
const char * bind_address
Our address without port.
enum GNUNET_GenericReturnValue has_port
Flag indicating, if the address is without port information.
struct GNUNET_TIME_Relative rtt
The actual RTT between the peers.
char * address
The address of the other peer without port.
unsigned int std_port
Default local port we are bound to.
struct sockaddr * actual_address
The address of the other peer we received a burst message from.
struct GNUNET_NETWORK_Handle * udp_sock
struct GNUNET_PeerIdentity * pid
The peer we like to connect to.
"Plaintext" header at beginning of KX message.
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
struct GNUNET_CRYPTO_HpkeEncapsulation enc
Representative of ephemeral key for KX.
Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct U...
struct GNUNET_ShortHashCode kid
Key and IV identification code.
uint32_t sequence_number
Sequence number used to derive this entry from master key.
struct KeyCacheEntry * next
Kept in a DLL.
struct KeyCacheEntry * prev
Kept in a DLL.
struct SharedSecret * ss
Corresponding shared secret.
Information we track per receiving address we have recently been in contact with (encryption to recei...
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct GNUNET_TIME_Absolute rekey_timeout
Timeout for this receiver address.
struct SharedSecret * ss_tail
Shared secrets we received with target, last used is tail.
char * foreign_addr
Address of the receiver in the human-readable format with the COMMUNICATOR_ADDRESS_PREFIX.
struct GNUNET_SCHEDULER_Task * read_task
Read task, if this receiver has its own socket.
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this receiver.
struct SharedSecret * ss_head
Shared secrets we received from target, first used is head.
struct GNUNET_TRANSPORT_QueueHandle * kx_qh
handle for KX queue with the ch.
unsigned int num_secrets
Length of the DLL at ss_head.
struct GNUNET_TIME_Absolute timeout
Timeout for this receiver address.
size_t kx_mtu
MTU we allowed transport for this receiver's KX queue.
struct sockaddr * address
Address of the other peer.
struct GNUNET_PeerIdentity target
To whom are we talking to.
socklen_t address_len
Length of the address.
struct GNUNET_MQ_Handle * kx_mq
KX message queue we are providing for the ch.
int receiver_destroy_called
receiver_destroy already called on receiver.
struct GNUNET_NETWORK_Handle * udp_sock
Socket this receiver got via NAT traversal.
size_t d_mtu
MTU we allowed transport for this receiver's default queue.
enum GNUNET_NetworkType nt
Which network type does this queue use?
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.
struct GNUNET_CRYPTO_EcdhePublicKey target_hpke_key
To whom are we talking to.
struct GNUNET_TRANSPORT_QueueHandle * d_qh
handle for default queue with the ch.
struct GNUNET_HashCode key
The address key for this entry.
Closure for #find_sender_by_address()
const struct sockaddr * address
Address we are looking for.
struct SenderAddress * sender
Return value to set if we found a match.
socklen_t address_len
Number of bytes in address.
Information we track per sender address we have recently been in contact with (we decrypt messages fr...
struct GNUNET_PeerIdentity target
To whom are we talking to.
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct sockaddr * address
Address of the other peer.
socklen_t address_len
Length of the address.
enum GNUNET_NetworkType nt
Which network type does this queue use?
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this sender.
unsigned int num_secrets
Length of the DLL at ss_head.
int kce_send_ack_on_finish
When KCE finishes, send ACK if GNUNET_YES.
struct GNUNET_TIME_Absolute timeout
Timeout for this sender.
int kce_task_finished
Is the kce_task finished?
struct GNUNET_SCHEDULER_Task * kce_task
ID of kce working queue task.
struct GNUNET_HashCode key
The address key for this entry.
struct SharedSecret * ss_head
Shared secrets we used with target, first used is head.
int sender_destroy_called
sender_destroy already called on sender.
struct SharedSecret * ss_tail
Shared secrets we used with target, last used is tail.
Shared secret we generated for a particular sender or receiver.
struct KeyCacheEntry * kce_tail
Kept in a DLL, sorted by sequence number.
uint32_t sequence_allowed
Up to which sequence number did the other peer allow us to use this key, or up to which number did we...
struct SharedSecret * next
Kept in a DLL.
unsigned int active_kce_count
Number of active KCN entries.
uint32_t sequence_used
Up to which sequence number did we use this master already? (for encrypting only)
size_t bytes_sent
Bytes sent with this shared secret.
struct SharedSecret * prev
Kept in a DLL.
struct SenderAddress * sender
Sender we use this shared secret with, or NULL.
struct KeyCacheEntry * kce_head
Kept in a DLL, sorted by sequence number.
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.
struct ReceiverAddress * receiver
Receiver we use this shared secret with, or NULL.
struct GNUNET_ShortHashCode master
Master shared secret.
int override_available_acks
Also precompute keys despite sufficient acks (for rekey)
int rekey_initiated
rekey initiated for this secret?
UDP key acknowledgement.
uint32_t sequence_ack
Sequence acknowledgement limit.
struct GNUNET_HashCode cmac
CMAC of the base key being acknowledged.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
UDP message box.
uint8_t gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
Broadcast by peer in LAN announcing its presence.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_PeerIdentity sender
Sender's peer identity.
Encrypted continuation of UDP initial handshake, followed by message header with payload.
struct GNUNET_PeerIdentity sender
Sender's identity.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
Plaintext of a rekey payload in a UDPBox.
struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral
Ephemeral key to rekey with.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_HashCode h_address
Hash of the sender's UDP address.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP broadcast.
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_HpkeEncapsulation enc
Ephemeral key used by the sender.
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the UDP connection (UDP server)
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP connection (UDP client).