GNUnet 0.28.1-dev.4-24-g0cf3356dd
 
Loading...
Searching...
No Matches
gnunet-communicator-udp.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 2018, 2019, 2026 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14 :
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
40#include "platform.h"
41#include "gnunet_common.h"
42#include "gnunet_util_lib.h"
43#include "gnunet_protocols.h"
44#include "gnunet_signatures.h"
45#include "gnunet_constants.h"
46#include "gnunet_pils_service.h"
47#include "gnunet_nat_service.h"
51
52/* Shorthand for Logging */
53#define LOG(kind, ...) GNUNET_log_from (kind, "communicator-udp", __VA_ARGS__)
54
58#define DEFAULT_REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
59
63#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
64
73#define PEER_LIVENESS_TIMEOUT GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
74
78#define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
79
83#define INTERFACE_SCAN_FREQUENCY \
84 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
85
90#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
91
92#define WORKING_QUEUE_INTERVALL \
93 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)
94
98#define AES_KEY_SIZE (256 / 8)
99
103#define AES_IV_SIZE (96 / 8)
104
108#define GCM_TAG_SIZE (128 / 8)
109
110#define GENERATE_AT_ONCE 64
111
121#define KCN_THRESHOLD 96
122
129#define KCN_TARGET 128
130
140#define MAX_SQN_DELTA 160
141
151#define MAX_SECRETS 256
152
157#define DEFAULT_REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
158
163#define COMMUNICATOR_ADDRESS_PREFIX "udp"
164
168#define COMMUNICATOR_CONFIG_SECTION "communicator-udp"
169
171
172
206
207
226
227
233{
238
243
249
250 /* followed by messages */
251
252 /* padding may follow actual messages */
253};
254
255
278
279
305
306
326
327
332struct UDPBox
333{
342
351
352};
353
369
371
375struct SharedSecret;
376
377
383{
388
393
402
407
412};
413
414
419struct SenderAddress;
420
425struct ReceiverAddress;
426
505
506
589
590
726
731{
736
741
746
750 struct sockaddr *sa;
751
755 struct sockaddr *ba;
756
761
766 struct ipv6_mreq mcreq;
767
771 socklen_t salen;
772
776 int found;
777};
778
783
788
793
797static unsigned long long rekey_max_bytes;
798
803
808
813
818
823
828
833
838
843
848
853
858
863
868
873
877static const struct GNUNET_CONFIGURATION_Handle *cfg;
878
883
888
892static struct GNUNET_NAT_Handle *nat;
893
897static uint16_t my_port;
898
903
907static int disable_v6;
908
910
911
912static void
922
923
924static void
934
935
941static void
943{
944 if (AF_INET6 == bi->sa->sa_family)
945 {
946 /* Leave the multicast group */
948 IPPROTO_IPV6,
949 IPV6_LEAVE_GROUP,
950 &bi->mcreq,
951 sizeof(bi->mcreq)))
952 {
954 }
955 }
958 GNUNET_free (bi->sa);
959 GNUNET_free (bi->ba);
960 GNUNET_free (bi);
961}
962
963
964static int
965secret_destroy (struct SharedSecret *ss);
966
972static void
974{
975 struct SharedSecret *ss;
976 receiver->receiver_destroy_called = GNUNET_YES;
977
979 "Disconnecting receiver for peer `%s'\n",
980 GNUNET_i2s (&receiver->target));
981 if (NULL != receiver->kx_qh)
982 {
984 receiver->kx_qh = NULL;
985 receiver->kx_mq = NULL;
986 }
987 if (NULL != receiver->d_qh)
988 {
990 receiver->d_qh = NULL;
991 }
992 else if (NULL != receiver->d_mq)
993 {
995 receiver->d_mq = NULL;
996 }
997 if (NULL != receiver->udp_sock)
998 {
1001 receiver->udp_sock = NULL;
1002 }
1005 &receiver->key,
1006 receiver));
1009 "# receivers active",
1011 GNUNET_NO);
1012 while (NULL != (ss = receiver->ss_head))
1013 {
1014 secret_destroy (ss);
1015 }
1016 GNUNET_free (receiver->address);
1017 GNUNET_free (receiver->foreign_addr);
1019}
1020
1021
1027static void
1029{
1030 struct SharedSecret *ss = kce->ss;
1031
1032 ss->active_kce_count--;
1033 /* @e acks_available is "how many BOX keys do we have ready for this
1034 sender", so it must be maintained here, where a key actually goes away,
1035 and nowhere else. #kce_generate() is the only place one comes into
1036 existence. */
1037 if (NULL != ss->sender)
1038 {
1040 if (0 < ss->sender->acks_available)
1041 ss->sender->acks_available--;
1042 }
1045 &kce->kid,
1046 kce));
1047 GNUNET_free (kce);
1048}
1049
1050
1058static void
1059get_kid (const struct GNUNET_ShortHashCode *msec,
1060 uint32_t serial,
1061 struct GNUNET_ShortHashCode *kid)
1062{
1063 uint32_t sid = htonl (serial);
1064 struct GNUNET_ShortHashCode prk;
1066 &sid, sizeof (sid),
1067 msec, sizeof (*msec));
1068
1070 kid,
1071 sizeof(*kid),
1072 &prk,
1073 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-kid"));
1074}
1075
1076
1083static void
1084kce_generate (struct SharedSecret *ss, uint32_t seq)
1085{
1086 struct KeyCacheEntry *kce;
1087
1088 GNUNET_assert (0 < seq);
1089 kce = GNUNET_new (struct KeyCacheEntry);
1090 kce->ss = ss;
1091 kce->sequence_number = seq;
1092 get_kid (&ss->master, seq, &kce->kid);
1097 key_cache,
1098 &kce->kid,
1099 kce,
1102 "# KIDs active",
1104 GNUNET_NO);
1105}
1106
1107
1114static int
1116{
1117 struct SenderAddress *sender;
1118 struct ReceiverAddress *receiver;
1119 struct KeyCacheEntry *kce;
1120
1122 "secret %s destroy %u\n",
1123 GNUNET_sh2s (&ss->master),
1125 if (NULL != (sender = ss->sender))
1126 {
1127 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1128 sender->num_secrets--;
1130 "%u sender->num_secrets %u allowed %u used, %u available\n",
1132 sender->acks_available);
1133 /* NOTE: this used to subtract `sequence_allowed - sequence_used', which
1134 is not the number of keys this secret still holds. Keys also go away
1135 without @e sequence_used moving: #consider_ss_ack() drops entries past
1136 #MAX_SQN_DELTA, and #decrypt_box() destroys the entry of a datagram
1137 that failed to decrypt. Over-subtracting wraps this unsigned counter
1138 to ~4e9, after which `KCN_THRESHOLD > acks_available' is false
1139 forever: we never generate another key, never send another UDPAck,
1140 and the peer -- which can only send BOXes for sequence numbers we
1141 acknowledged -- falls back to a full key exchange per datagram for
1142 good. The #kce_destroy() loop below now accounts for exactly the keys
1143 that existed. */
1144 if (NULL != ss->sender->kce_task)
1145 {
1147 ss->sender->kce_task = NULL;
1148 }
1149 }
1150 if (NULL != (receiver = ss->receiver))
1151 {
1152 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1153 receiver->num_secrets--;
1154 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1156 "%u receiver->num_secrets\n",
1157 receiver->num_secrets);
1158 }
1159 while (NULL != (kce = ss->kce_head))
1160 kce_destroy (kce);
1161 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1163 "# KIDs active",
1165 GNUNET_NO);
1166 GNUNET_free (ss);
1167 return GNUNET_YES;
1168}
1169
1170
1177static void
1179{
1180 struct SharedSecret *ss;
1183 GNUNET_YES ==
1187 "# senders active",
1189 GNUNET_NO);
1190 while (NULL != (ss = sender->ss_head))
1191 {
1192 secret_destroy (ss);
1193 }
1196}
1197
1198
1207static void
1209 uint32_t serial,
1210 char key[AES_KEY_SIZE],
1211 char iv[AES_IV_SIZE])
1212{
1213 uint32_t sid = htonl (serial);
1214
1216 key,
1218 msec,
1219 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-key"),
1222 iv,
1224 msec,
1225 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-iv"),
1227}
1228
1229
1235static void
1242
1243
1253static void
1261
1262
1279static enum GNUNET_GenericReturnValue
1281{
1284 <=,
1286 return GNUNET_YES;
1288 "Peer `%s' did not acknowledge a single datagram for %s while we "
1289 "kept transmitting, considering it disconnected\n",
1290 GNUNET_i2s (&receiver->target),
1292 GNUNET_YES));
1294 "# receivers destroyed (peer unresponsive)",
1295 1,
1296 GNUNET_NO);
1297 if (GNUNET_YES != receiver->receiver_destroy_called)
1299 return GNUNET_NO;
1300}
1301
1302
1308static void
1310{
1311 struct GNUNET_TIME_Relative st;
1312 struct GNUNET_TIME_Relative rt;
1313 struct GNUNET_TIME_Relative delay;
1314 struct ReceiverAddress *receiver;
1315 struct SenderAddress *sender;
1316
1317 (void) cls;
1318 timeout_task = NULL;
1321 {
1323 if (0 != rt.rel_value_us)
1324 break;
1326 "Receiver timed out\n");
1328 }
1330 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1331 {
1332 /* NOTE: no @e sender_destroy_called check here -- #sender_destroy()
1333 removes the node from the heap, so anything we can peek at is live.
1334 Skipping instead of breaking would spin forever on the same node. */
1336 if (0 != st.rel_value_us)
1337 break;
1338 sender_destroy (sender);
1339 }
1340 delay = GNUNET_TIME_relative_min (rt, st);
1341 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1343}
1344
1345
1351static void
1353{
1355 &ss->cmac,
1356 sizeof(ss->cmac),
1357 &ss->master,
1358 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-cmac"));
1359}
1360
1361
1370static void
1372 const void *plaintext,
1373 size_t plaintext_len)
1374{
1375 const struct GNUNET_MessageHeader *hdr = plaintext;
1376 const char *pos = plaintext;
1377
1378 while (ntohs (hdr->size) <= plaintext_len)
1379 {
1381 "# bytes given to core",
1382 ntohs (hdr->size),
1383 GNUNET_NO);
1385 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1388 &sender->target,
1389 hdr,
1391 NULL /* no flow control possible */
1392 ,
1393 NULL));
1394 /* move on to next message, if any */
1395 plaintext_len -= ntohs (hdr->size);
1396 if (plaintext_len < sizeof(*hdr))
1397 break;
1398 pos += ntohs (hdr->size);
1399 hdr = (const struct GNUNET_MessageHeader *) pos;
1400 // TODO for now..., we do not actually sen >1msg or have a way of telling
1401 // if we are done
1402 break;
1403 }
1405 "# bytes padding discarded",
1406 plaintext_len,
1407 GNUNET_NO);
1408}
1409
1410
1419static void
1421 uint32_t serial,
1422 gcry_cipher_hd_t *cipher)
1423{
1424 char key[AES_KEY_SIZE];
1425 char iv[AES_IV_SIZE];
1426 int rc;
1427
1428 GNUNET_assert (0 ==
1429 gcry_cipher_open (cipher,
1430 GCRY_CIPHER_AES256 /* low level: go for speed */
1431 ,
1432 GCRY_CIPHER_MODE_GCM,
1433 0 /* flags */));
1434 get_iv_key (msec, serial, key, iv);
1435 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1436 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1437 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1438 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1439}
1440
1441
1454static int
1455try_decrypt (const struct SharedSecret *ss,
1456 const uint8_t *tag,
1457 uint32_t serial,
1458 const char *in_buf,
1459 size_t in_buf_size,
1460 char *out_buf)
1461{
1462 gcry_cipher_hd_t cipher;
1463
1464 setup_cipher (&ss->master, serial, &cipher);
1466 0 ==
1467 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1468 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1469 {
1470 gcry_cipher_close (cipher);
1472 "# AEAD authentication failures",
1473 1,
1474 GNUNET_NO);
1475 return GNUNET_SYSERR;
1476 }
1477 gcry_cipher_close (cipher);
1478 return GNUNET_OK;
1479}
1480
1481
1488static struct SharedSecret *
1490 )
1491{
1493 struct SharedSecret *ss;
1494
1497
1498 ss = GNUNET_new (struct SharedSecret);
1500 ephemeral,
1501 &ss->master);
1502 calculate_cmac (ss);
1503 return ss;
1504}
1505
1506
1513static struct SharedSecret *
1516{
1518 struct GNUNET_CRYPTO_HpkePrivateKey my_hpke_key;
1519 struct SharedSecret *ss;
1520
1523
1524 eddsa_priv_to_hpke_key (my_private_key, &my_hpke_key);
1525
1526 ss = GNUNET_new (struct SharedSecret);
1528 &ss->master);
1530 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1531 calculate_cmac (ss);
1532 return ss;
1533}
1534
1535
1543static struct SharedSecret *
1545 ,
1546 struct ReceiverAddress *receiver)
1547{
1548 struct SharedSecret *ss;
1549
1550 ss = GNUNET_new (struct SharedSecret);
1551 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1552 ephemeral,
1553 &ss->master);
1554 calculate_cmac (ss);
1555 ss->receiver = receiver;
1556 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1557 receiver->num_secrets++;
1558 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1559 return ss;
1560}
1561
1562
1570static struct SharedSecret *
1573 struct ReceiverAddress *receiver)
1574{
1575 struct SharedSecret *ss;
1576
1577 ss = GNUNET_new (struct SharedSecret);
1579 c, &ss->master);
1581 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1582 calculate_cmac (ss);
1583 ss->receiver = receiver;
1584 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1585 receiver->num_secrets++;
1586 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1587 return ss;
1588}
1589
1590
1598static void
1600
1601
1609static unsigned int
1610purge_secrets (struct SharedSecret *ss_list_tail)
1611{
1612 struct SharedSecret *pos;
1613 struct SharedSecret *ss_to_purge;
1614 unsigned int deleted = 0;
1615
1617 "Purging secrets.\n");
1618 pos = ss_list_tail;
1619 while (NULL != pos)
1620 {
1621 ss_to_purge = pos;
1622 pos = pos->prev;
1623
1624 // FIXME we may also want to purge old unacked.
1625 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1626 {
1627 secret_destroy (ss_to_purge);
1628 deleted++;
1629 }
1630 }
1632 "Finished purging all, deleted %u.\n", deleted);
1633 return deleted;
1634}
1635
1636
1637static void
1638add_acks (struct SharedSecret *ss, int acks_to_add)
1639{
1640
1641 struct ReceiverAddress *receiver = ss->receiver;
1642
1643 GNUNET_assert (NULL != ss);
1644 GNUNET_assert (NULL != receiver);
1645
1646 if (NULL == receiver->d_qh)
1647 {
1648 receiver->d_qh =
1650 &receiver->target,
1651 receiver->foreign_addr,
1652 receiver->d_mtu,
1653 acks_to_add,
1654 1, /* Priority */
1655 receiver->nt,
1657 receiver->d_mq);
1658 }
1659 else
1660 {
1662 receiver->d_qh,
1663 acks_to_add,
1664 1);
1665 }
1666
1668 "Tell transport we have %u more acks!\n",
1669 acks_to_add);
1670
1671 // Until here for alternative 1
1672
1673 /* move ss to head to avoid discarding it anytime soon! */
1674
1675 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1676 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1677}
1678
1679
1690static int
1691handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1692{
1693 const struct UDPAck *ack = cls;
1694 struct ReceiverAddress *receiver = value;
1695 uint32_t acks_to_add;
1696 uint32_t allowed;
1697
1699 "in handle ack with cmac %s\n",
1700 GNUNET_h2s (&ack->cmac));
1701
1702 (void) key;
1703 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1704 {
1705 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1706 {
1707
1709 "Found matching cmac\n");
1710
1711 /* Whatever window it grants us, this ACK proves the peer is alive.
1712 Note that this is the *only* inbound signal tied to a receiver. */
1713 receiver->last_ack = GNUNET_TIME_absolute_get ();
1714
1715 allowed = ntohl (ack->sequence_ack);
1716
1717 if (allowed <= ss->sequence_allowed)
1718 {
1720 "Ignoring ack, not giving us increased window\n.");
1721 return GNUNET_NO;
1722 }
1723 acks_to_add = (allowed - ss->sequence_allowed);
1724 GNUNET_assert (0 != acks_to_add);
1725 receiver->acks_available += (allowed - ss->sequence_allowed);
1726 ss->sequence_allowed = allowed;
1727 add_acks (ss, acks_to_add);
1729 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1730 allowed,
1731 acks_to_add,
1732 receiver->acks_available,
1733 GNUNET_sh2s (&ss->master));
1734 return GNUNET_NO;
1735 }
1736 }
1738 "Matching cmac not found for ack!\n");
1739 return GNUNET_YES;
1740}
1741
1742
1744{
1745 const struct UDPAck *ack;
1746
1748};
1749
1750
1765static int
1766handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
1767{
1768 struct ReceiverAddress *receiver = value;
1769 struct AckInfo *ai = cls;
1770
1771 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
1772 {
1773 return GNUNET_YES;
1774 }
1775 handle_ack ((void*) ai->ack, key, receiver);
1776 return GNUNET_YES;
1777}
1778
1779
1788static void
1790{
1791 struct UDPAck ack;
1792 GNUNET_assert (NULL != ss->sender);
1794 "Considering SS UDPAck %s\n",
1795 GNUNET_i2s_full (&ss->sender->target));
1796
1798 "Sender has %u acks available.\n",
1799 ss->sender->acks_available);
1800 /* drop ancient KeyCacheEntries */
1801 while ((NULL != ss->kce_head) &&
1802 (MAX_SQN_DELTA <
1804 kce_destroy (ss->kce_tail);
1805
1806
1808 ack.header.size = htons (sizeof(ack));
1809 ack.sequence_ack = htonl (ss->sequence_allowed);
1810 ack.cmac = ss->cmac;
1812 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1814 ss->sequence_allowed,
1815 GNUNET_sh2s (&(ss->master)));
1817 &ss->sender->target,
1819 &ack.header);
1820}
1821
1822
1823static void
1825{
1826 struct SharedSecret *ss = cls;
1827 ss->sender->kce_task = NULL;
1828
1830 "Precomputing %u keys for master %s\n",
1832 GNUNET_sh2s (&ss->master));
1833 if ((ss->override_available_acks != GNUNET_YES) &&
1834 (KCN_TARGET < ss->sender->acks_available) &&
1835 (0 != ss->sequence_allowed))
1836 {
1837 /* Enough keys for this sender overall, and this secret already has some
1838 the peer may use.
1839 Do NOT just return: @e kce_task_finished is a latch that decides which
1840 of the two places that arm this task is allowed to do so -- the KX
1841 path only arms it while it is #GNUNET_NO, #decrypt_box() only while it
1842 is #GNUNET_YES. Leaving it #GNUNET_NO here means #decrypt_box() can
1843 never ask for more keys again, so the sender's supply runs down to
1844 zero and stays there. And the peer is waiting on the UDPAck that says
1845 how far it may count with this secret; without it, it can only reach
1846 us by doing a full key exchange per datagram. */
1850 consider_ss_ack (ss);
1851 return;
1852 }
1853 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1854 kce_generate (ss, ++ss->sequence_allowed);
1855
1860 if (KCN_TARGET > ss->sender->acks_available)
1861 {
1865 ss);
1866 return;
1867 }
1869 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1873 consider_ss_ack (ss);
1874}
1875
1876
1885static void
1887 const void *buf,
1888 size_t buf_size)
1889{
1890 const struct GNUNET_MessageHeader *hdr;
1891 const struct UDPAck *ack;
1892 const struct UDPRekey *rekey;
1893 struct SharedSecret *ss_rekey;
1894 const char *buf_pos = buf;
1895 size_t bytes_remaining = buf_size;
1896 uint16_t type;
1897
1898 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1899 if (sizeof(*hdr) > bytes_remaining)
1900 {
1901 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1902 return; /* no data left */
1903 }
1905 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1906 (unsigned long long) bytes_remaining,
1907 ntohs (hdr->size),
1908 sizeof(*hdr),
1909 ntohs (hdr->type));
1910 if (ntohs (hdr->size) > bytes_remaining)
1911 return; /* buffer too short for indicated message length */
1912 type = ntohs (hdr->type);
1913 switch (type)
1914 {
1916 rekey = (struct UDPRekey*) buf_pos;
1917 if (ntohs (hdr->size) < sizeof (struct UDPRekey))
1918 {
1919 GNUNET_break_op (0);
1920 return;
1921 }
1922 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1923 ss_rekey->sender = sender;
1924 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1925 sender->num_secrets++;
1927 "Received rekey secret with cmac %s\n",
1928 GNUNET_h2s (&(ss_rekey->cmac)));
1930 "Received secret with master %s.\n",
1931 GNUNET_sh2s (&(ss_rekey->master)));
1933 "We have %u sequence_allowed.\n",
1934 ss_rekey->sequence_allowed);
1936 "We have a sender %p\n",
1937 ss_rekey->sender);
1939 "We have %u acks available.\n",
1940 ss_rekey->sender->acks_available);
1942 "# rekeying successful",
1943 1,
1944 GNUNET_NO);
1947 /* Go through @e kce_task rather than calling #kce_generate_cb() inline.
1948 That function starts with `sender->kce_task = NULL', so calling it
1949 directly dropped the handle of a task that may well have been armed
1950 for another of this sender's secrets: it still fires, but nothing can
1951 cancel it any more -- including #secret_destroy(), which then leaves
1952 it pointing at a freed `struct SharedSecret'. */
1953 if (NULL != ss_rekey->sender->kce_task)
1956 ss_rekey);
1957 // FIXME: Theoretically, this could be an Ack
1958 buf_pos += ntohs (hdr->size);
1959 bytes_remaining -= ntohs (hdr->size);
1960 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1961 if (0 == purge_secrets (sender->ss_tail))
1962 {
1963 // No secret purged. Delete oldest.
1964 if (sender->num_secrets > MAX_SECRETS)
1965 {
1966 secret_destroy (sender->ss_tail);
1967 }
1968 }
1969 break;
1971 /* lookup master secret by 'cmac', then update sequence_max */
1972 ack = (struct UDPAck*) buf_pos;
1973 if (ntohs (hdr->size) < sizeof (struct UDPAck))
1974 {
1975 GNUNET_break_op (0);
1976 return;
1977 }
1978 {
1979 /* NOTE: @e key of a sender is H(source address || peer), that of a
1980 receiver H(address we send to || peer). Looking @a receivers up by
1981 the sender's key therefore only ever hits when the peer reached us
1982 from exactly the address we send to -- i.e. never for a peer behind
1983 a NAT, which is the case that needs the ACK most. Match on the peer
1984 instead, the same way #enc_notify_cb() does for the backchannel. */
1985 struct AckInfo ai = {
1986 .ack = ack,
1987 .sender = &sender->target
1988 };
1989
1992 &ai);
1993 }
1994 /* There could be more messages after the ACK, handle those as well */
1995 buf_pos += ntohs (hdr->size);
1996 bytes_remaining -= ntohs (hdr->size);
1997 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1998 break;
1999
2001 /* skip padding */
2002 break;
2003
2004 default:
2005 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
2006 }
2007 return;
2008}
2009
2010
2018static void
2019decrypt_box (const struct UDPBox *box,
2020 size_t box_len,
2021 struct KeyCacheEntry *kce)
2022{
2023 struct SharedSecret *ss = kce->ss;
2024 struct SharedSecret *ss_c = ss->sender->ss_tail;
2025 struct SharedSecret *ss_tmp;
2026 int ss_destroyed = 0;
2027 char out_buf[box_len - sizeof(*box)];
2028
2029 GNUNET_assert (NULL != ss->sender);
2030 if (GNUNET_OK != try_decrypt (ss,
2031 box->gcm_tag,
2032 kce->sequence_number,
2033 (const char *) &box[1],
2034 sizeof(out_buf),
2035 out_buf))
2036 {
2037 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
2039 "# Decryption failures with valid KCE",
2040 1,
2041 GNUNET_NO);
2042 /* NOTE: no `acks_available--' here or below -- #kce_destroy() does it.
2043 Doing it here as well double-counted, and on this path (decryption
2044 failure) @e sequence_used does *not* advance, so #secret_destroy()'s
2045 old `sequence_allowed - sequence_used' could not have compensated for
2046 it either. */
2047 kce_destroy (kce);
2048 return;
2049 }
2050 kce_destroy (kce);
2051 kce = NULL;
2052 ss->bytes_sent += box_len;
2053 ss->sequence_used++;
2055 "# bytes decrypted with BOX",
2056 sizeof(out_buf),
2057 GNUNET_NO);
2059 "# messages decrypted with BOX",
2060 1,
2061 GNUNET_NO);
2063 "decrypted UDPBox with kid %s\n",
2064 GNUNET_sh2s (&box->kid));
2065 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
2066
2067 while (NULL != ss_c)
2068 {
2069 if (ss_c->bytes_sent >= rekey_max_bytes)
2070 {
2072 "Removing SS because rekey bytes reached.\n");
2073 ss_tmp = ss_c->prev;
2074 if (ss == ss_c)
2075 ss_destroyed = 1;
2076 secret_destroy (ss_c);
2077 ss_c = ss_tmp;
2078 continue;
2079 }
2080 ss_c = ss_c->prev;
2081 }
2082 if (1 == ss_destroyed)
2083 return;
2085 "Sender has %u ack left.\n",
2086 ss->sender->acks_available);
2087 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2088 (NULL == ss->sender->kce_task) &&
2090 {
2092 "Sender has %u ack left which is under threshold.\n",
2093 ss->sender->acks_available);
2097 ss);
2098 }
2099}
2100
2101
2106{
2110 const struct sockaddr *address;
2111
2115 socklen_t address_len;
2116
2121};
2122
2123
2137static struct SenderAddress *
2139 const struct sockaddr *address,
2140 socklen_t address_len,
2141 int *is_new)
2142{
2143 struct SenderAddress *sender;
2144 struct GNUNET_HashContext *hsh;
2145 struct GNUNET_HashCode sender_key;
2146
2148 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
2149 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
2150 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
2151
2152 if (NULL != is_new)
2153 *is_new = GNUNET_NO;
2154 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
2155 if (NULL != sender)
2156 {
2158 return sender;
2159 }
2160 if (NULL != is_new)
2161 *is_new = GNUNET_YES;
2162 sender = GNUNET_new (struct SenderAddress);
2163 sender->key = sender_key;
2164 sender->target = *target;
2165 sender->address = GNUNET_memdup (address, address_len);
2166 sender->address_len = address_len;
2168 senders,
2169 &sender->key,
2170 sender,
2173 "# senders active",
2175 GNUNET_NO);
2176 sender->timeout =
2179 sender,
2180 sender->timeout.abs_value_us);
2181 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2182 if (NULL == timeout_task)
2184 return sender;
2185}
2186
2187
2195static int
2197 const struct UDPConfirmation *uc)
2198{
2199 const struct GNUNET_PeerIdentity *my_identity;
2200 struct UdpHandshakeSignature uhs;
2201
2204
2205 uhs.purpose.purpose = htonl (
2207 uhs.purpose.size = htonl (sizeof(uhs));
2208 uhs.sender = uc->sender;
2209 uhs.receiver = *my_identity;
2210 uhs.enc = *enc;
2211 uhs.monotonic_time = uc->monotonic_time;
2214 &uhs,
2215 &uc->sender_sig,
2216 &uc->sender.public_key);
2217}
2218
2219
2228static char *
2229sockaddr_to_udpaddr_string (const struct sockaddr *address,
2230 socklen_t address_len)
2231{
2232 char *ret;
2233
2234 switch (address->sa_family)
2235 {
2236 case AF_INET:
2238 "%s-%s",
2240 GNUNET_a2s (address, address_len));
2241 break;
2242
2243 case AF_INET6:
2245 "%s-%s",
2247 GNUNET_a2s (address, address_len));
2248 break;
2249
2250 default:
2251 GNUNET_assert (0);
2252 }
2253 return ret;
2254}
2255
2256
2257static struct GNUNET_NETWORK_Handle *
2259{
2261
2262 if (NULL == receiver->udp_sock)
2263 {
2264 if (AF_INET6 == receiver->address->sa_family)
2266 else
2268 }
2269 else
2270 udp_sock = receiver->udp_sock;
2271
2272 return udp_sock;
2273}
2274
2275
2284static struct sockaddr *
2285udp_address_to_sockaddr (const char *bindto,
2286 sa_family_t family,
2287 socklen_t *sock_len)
2288{
2289 struct sockaddr *in;
2290 unsigned int port;
2291 char dummy[2];
2292 char *colon;
2293 char *cp;
2294
2295 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2296 {
2297 /* interpreting value as just a PORT number */
2298 if (port > UINT16_MAX)
2299 {
2301 "BINDTO specification `%s' invalid: value too large for port\n",
2302 bindto);
2303 return NULL;
2304 }
2305 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2306 {
2307 struct sockaddr_in *i4;
2308
2309 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2310 i4->sin_family = AF_INET;
2311 i4->sin_port = htons ((uint16_t) port);
2312 *sock_len = sizeof(struct sockaddr_in);
2313 in = (struct sockaddr *) i4;
2314 }
2315 else
2316 {
2317 struct sockaddr_in6 *i6;
2318
2319 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2320 i6->sin6_family = AF_INET6;
2321 i6->sin6_port = htons ((uint16_t) port);
2322 *sock_len = sizeof(struct sockaddr_in6);
2323 in = (struct sockaddr *) i6;
2324 }
2325 return in;
2326 }
2327 cp = GNUNET_strdup (bindto);
2328 colon = strrchr (cp, ':');
2329 if (NULL != colon)
2330 {
2331 /* interpret value after colon as port */
2332 *colon = '\0';
2333 colon++;
2334 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2335 {
2336 /* interpreting value as just a PORT number */
2337 if (port > UINT16_MAX)
2338 {
2340 "BINDTO specification `%s' invalid: value too large for port\n",
2341 bindto);
2342 GNUNET_free (cp);
2343 return NULL;
2344 }
2345 }
2346 else
2347 {
2348 GNUNET_log (
2350 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2351 bindto);
2352 GNUNET_free (cp);
2353 return NULL;
2354 }
2355 }
2356 else
2357 {
2358 /* interpret missing port as 0, aka pick any free one */
2359 port = 0;
2360 }
2361 if (AF_INET6 != family)
2362 {
2363 /* try IPv4 */
2364 struct sockaddr_in v4;
2365
2366 memset (&v4, 0, sizeof(v4));
2367 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2368 {
2369 v4.sin_family = AF_INET;
2370 v4.sin_port = htons ((uint16_t) port);
2371#if HAVE_SOCKADDR_IN_SIN_LEN
2372 v4.sin_len = sizeof(struct sockaddr_in);
2373#endif
2374 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2375 *sock_len = sizeof(struct sockaddr_in);
2376 GNUNET_free (cp);
2377 return in;
2378 }
2379 }
2380 if (AF_INET != family)
2381 {
2382 /* try IPv6 */
2383 struct sockaddr_in6 v6;
2384 const char *start;
2385
2386 memset (&v6, 0, sizeof(v6));
2387 start = cp;
2388 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2389 {
2390 start++; /* skip over '[' */
2391 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2392 }
2393 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2394 {
2395 v6.sin6_family = AF_INET6;
2396 v6.sin6_port = htons ((uint16_t) port);
2397#if HAVE_SOCKADDR_IN_SIN_LEN
2398 v6.sin6_len = sizeof(struct sockaddr_in6);
2399#endif
2400 in = GNUNET_memdup (&v6, sizeof(v6));
2401 *sock_len = sizeof(v6);
2402 GNUNET_free (cp);
2403 return in;
2404 }
2405 }
2406 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2407 GNUNET_free (cp);
2408 return NULL;
2409}
2410
2411
2412static void
2413sock_read (void *cls);
2414
2415
2416static enum GNUNET_GenericReturnValue
2418 const char *address,
2420{
2421 struct GNUNET_HashContext *hsh;
2422 struct ReceiverAddress *receiver;
2423 struct GNUNET_HashCode receiver_key;
2424 const char *path;
2425 struct sockaddr *in;
2426 socklen_t in_len;
2427
2428 if (0 != strncmp (address,
2430 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2431 {
2432 GNUNET_break_op (0);
2433 return GNUNET_SYSERR;
2434 }
2435 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2436 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2437
2438 if (NULL == in)
2439 {
2441 "Failed to setup UDP socket address\n");
2442 return GNUNET_SYSERR;
2443 }
2444 if ((AF_INET6 == in->sa_family) &&
2446 {
2448 "IPv6 disabled, skipping %s\n", address);
2449 GNUNET_free (in);
2450 return GNUNET_SYSERR;
2451 }
2452 else if (AF_INET == in->sa_family)
2453 {
2454 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2455 if (0 == sin->sin_port)
2456 {
2457 GNUNET_free (in);
2458 return GNUNET_NO;
2459 }
2460 }
2461
2463 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2464 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2465 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2466
2468 if (NULL != receiver)
2469 {
2471 "receiver %s already exist or is being connected to\n",
2472 address);
2473 /* Only the new-receiver path below takes ownership of @a in. */
2474 GNUNET_free (in);
2475 return GNUNET_NO;
2476 }
2477
2479 receiver->udp_sock = udp_sock;
2480 receiver->key = receiver_key;
2481 receiver->address = in;
2482 receiver->address_len = in_len;
2483 receiver->target = *peer;
2484 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2485 &receiver->target_hpke_key);
2486 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2488 receivers,
2489 &receiver->key,
2490 receiver,
2493 "Added %s to receivers with address %s and sock %p\n",
2494 GNUNET_i2s_full (&receiver->target),
2495 address,
2496 udp_sock);
2497 receiver->timeout =
2499 /* Give a fresh receiver a full window to produce its first ACK. */
2500 receiver->last_ack = GNUNET_TIME_absolute_get ();
2502 receiver,
2503 receiver->timeout.abs_value_us);
2505 "# receivers active",
2507 GNUNET_NO);
2508 receiver->foreign_addr =
2509 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2510 if (NULL != udp_sock)
2513 udp_sock,
2514 &sock_read,
2515 udp_sock);
2517 if (NULL == timeout_task)
2519 return GNUNET_OK;
2520}
2521
2522
2551static void
2553 const struct sockaddr *address,
2554 socklen_t address_len)
2555{
2556 char *addr_s;
2557
2558 addr_s = sockaddr_to_udpaddr_string (address, address_len);
2559 /* #create_receiver() is keyed by (address, peer), so this is a cheap
2560 no-op whenever the peer reached us from an address we already have. */
2561 if (GNUNET_OK == create_receiver (target, addr_s, NULL))
2562 {
2564 "Learned return path %s for peer `%s' from the source of an "
2565 "authenticated datagram\n",
2566 addr_s,
2567 GNUNET_i2s (target));
2569 "# receivers added (reflexive address)",
2570 1,
2571 GNUNET_NO);
2572 }
2573 GNUNET_free (addr_s);
2574}
2575
2576
2582static void
2583sock_read (void *cls)
2584{
2585 struct sockaddr_storage sa;
2586 struct sockaddr_in *addr_verify;
2587 socklen_t salen = sizeof(sa);
2588 char buf[UINT16_MAX];
2589 ssize_t rcvd;
2590
2591 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2592
2595 udp_sock,
2596 &sock_read,
2597 udp_sock);
2600 udp_sock,
2601 &sock_read,
2602 udp_sock);
2603 while (1)
2604 {
2606 buf,
2607 sizeof(buf),
2608 (struct sockaddr *) &sa,
2609 &salen);
2610 if (-1 == rcvd)
2611 {
2612 struct sockaddr *addr = (struct sockaddr*) &sa;
2613
2614 if (EAGAIN == errno)
2615 break; // We are done reading data
2617 "Failed to recv from %s family %d failed sock %p\n",
2618 GNUNET_a2s ((struct sockaddr*) &sa,
2619 salen),
2620 addr->sa_family,
2621 udp_sock);
2623 return;
2624 }
2626 "Read %llu bytes\n",
2627 (unsigned long long) rcvd);
2628 if (0 == rcvd)
2629 {
2630 GNUNET_break_op (0);
2632 "Read 0 bytes from UDP socket\n");
2633 return;
2634 }
2635
2636 /* first, see if it is a GNUNET_BurstMessage */
2637 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2638 {
2639 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2640 struct sockaddr *addr = (struct sockaddr*) &sa;
2641 /* NOTE: @a salen, not `sizeof (*addr)' -- the latter is 16, which
2642 truncates an IPv6 source to the point where #GNUNET_a2s() renders
2643 "<invalid v6 address>" and #create_receiver() then fails to parse
2644 it, silently breaking burst NAT traversal over IPv6. */
2645 char *address = sockaddr_to_udpaddr_string (addr, salen);
2646
2647 if (0 != bm->local_port)
2648 {
2649 GNUNET_break_op (0);
2651 "Received a burst message on port %u\n",
2652 bm->local_port);
2653 return;
2654 }
2656 "Received a burst message for default port\n");
2657 create_receiver (&bm->peer,
2658 address,
2659 NULL);
2660 if (AF_INET6 == addr->sa_family)
2662 else
2666 return;
2667 }
2668 /* second, see if it is a UDPBox */
2669 if (rcvd > sizeof(struct UDPBox))
2670 {
2671 const struct UDPBox *box;
2672 struct KeyCacheEntry *kce;
2673
2674 box = (const struct UDPBox *) buf;
2676 if (NULL != kce)
2677 {
2679 "Found KCE with kid %s\n",
2680 GNUNET_sh2s (&box->kid));
2681 decrypt_box (box, (size_t) rcvd, kce);
2682 continue;
2683 }
2684 }
2685
2686 /* next, check if it is a broadcast */
2687 if (sizeof(struct UDPBroadcast) == rcvd)
2688 {
2689 const struct GNUNET_PeerIdentity *my_identity;
2690 const struct UDPBroadcast *ub;
2691 struct UdpBroadcastSignature uhs;
2692 struct GNUNET_PeerIdentity sender;
2693
2696
2697 addr_verify = GNUNET_memdup (&sa, salen);
2698 addr_verify->sin_port = 0;
2700 "received UDPBroadcast from %s\n",
2701 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2702 ub = (const struct UDPBroadcast *) buf;
2703 uhs.purpose.purpose = htonl (
2705 uhs.purpose.size = htonl (sizeof(uhs));
2706 uhs.sender = ub->sender;
2707 sender = ub->sender;
2708 if (0 == memcmp (&sender, my_identity, sizeof (struct
2710 {
2712 "Received our own broadcast\n");
2713 GNUNET_free (addr_verify);
2714 continue;
2715 }
2717 "checking UDPBroadcastSignature for %s\n",
2718 GNUNET_i2s (&sender));
2719 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2720 &uhs.h_address);
2721 if (GNUNET_OK ==
2724 &uhs,
2725 &ub->sender_sig,
2726 &ub->sender.public_key))
2727 {
2728 char *addr_s;
2730
2731 addr_s =
2732 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2733 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2734 /* use our own mechanism to determine network type */
2735 nt =
2736 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2738 "validating address %s received from UDPBroadcast\n",
2739 GNUNET_i2s (&sender));
2741 GNUNET_free (addr_s);
2742 GNUNET_free (addr_verify);
2743 continue;
2744 }
2745 else
2746 {
2748 "VerifyingPeer %s is verifying UDPBroadcast\n",
2751 "Verifying UDPBroadcast from %s failed\n",
2752 GNUNET_i2s (&ub->sender));
2753 }
2754 GNUNET_free (addr_verify);
2755 /* continue with KX, mostly for statistics... */
2756 }
2757
2758
2759 /* finally, test if it is a KX */
2760 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2761 {
2763 "# messages dropped (no kid, too small for KX)",
2764 1,
2765 GNUNET_NO);
2766 continue;
2767 }
2769 "Got KX\n");
2770 {
2771 const struct InitialKX *kx;
2772 struct SharedSecret *ss;
2773 char pbuf[rcvd - sizeof(struct InitialKX)];
2774 const struct UDPConfirmation *uc;
2775 struct SenderAddress *sender;
2776 int sender_is_new;
2777
2778 kx = (const struct InitialKX *) buf;
2781 "Before DEC\n");
2782
2783 if (GNUNET_OK != try_decrypt (ss,
2784 kx->gcm_tag,
2785 0,
2786 &buf[sizeof(*kx)],
2787 sizeof(pbuf),
2788 pbuf))
2789 {
2791 "Unable to decrypt tag, dropping...\n");
2792 GNUNET_free (ss);
2794 stats,
2795 "# messages dropped (no kid, AEAD decryption failed)",
2796 1,
2797 GNUNET_NO);
2798 continue;
2799 }
2801 "Before VERIFY\n");
2802
2803 uc = (const struct UDPConfirmation *) pbuf;
2804
2805 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2806 {
2807 GNUNET_break_op (0);
2808 GNUNET_free (ss);
2810 "# messages dropped (sender signature invalid)",
2811 1,
2812 GNUNET_NO);
2813 continue;
2814 }
2816 "Before SETUP_SENDER\n");
2817
2818 calculate_cmac (ss);
2819 sender = setup_sender (&uc->sender,
2820 (const struct sockaddr *) &sa,
2821 salen,
2822 &sender_is_new);
2823 ss->sender = sender;
2824 /* The signature in @a uc is verified, so we know who sent this.
2825 Only on a *new* sender: #setup_sender() is keyed on (address, peer),
2826 so this fires exactly once per source address per peer instead of on
2827 every KX datagram. A peer with no ACK credit left sends every
2828 message as a KX, and doing the string formatting plus the map lookup
2829 underneath #consider_reflexive_address() for each of those is pure
2830 waste -- and worse, it makes any address churn (a NAT rotating its
2831 mapping) add a transport queue per datagram.
2832
2833 Restricted to the shared sockets: #create_receiver() takes ownership
2834 of any socket handed to it (#receiver_destroy() closes it), so the
2835 per-receiver sockets the burst code hands out must not be passed on
2836 here, and replying from a socket other than the one the datagram
2837 arrived on would leave the peer's NAT mapping unused anyway. */
2838 if ((GNUNET_YES == sender_is_new) &&
2841 (const struct sockaddr *) &sa,
2842 salen);
2843 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2844 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2845 (NULL == ss->sender->kce_task) &&
2847 {
2848 // 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.
2852 ss);
2853 }
2854 sender->num_secrets++;
2855 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2857 "# messages decrypted without BOX",
2858 1,
2859 GNUNET_NO);
2860 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2861 if (0 == purge_secrets (sender->ss_tail))
2862 {
2863 // No secret purged. Delete oldest.
2864 if (sender->num_secrets > MAX_SECRETS)
2865 {
2866 secret_destroy (sender->ss_tail);
2867 }
2868 }
2869 }
2870 }
2871}
2872
2873
2881static void
2882do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2883{
2884 char pad[pad_size];
2885
2887 sizeof(pad));
2888 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2889 {
2890 struct GNUNET_MessageHeader hdr =
2891 { .size = htons (sizeof(pad)),
2893
2894 memcpy (pad, &hdr, sizeof(hdr));
2895 }
2897 0 ==
2898 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2899}
2900
2901
2902static void
2905 struct GNUNET_MQ_Handle *mq)
2906{
2907 const struct GNUNET_PeerIdentity *my_identity;
2909 uint16_t msize = ntohs (msg->size);
2910 struct UdpHandshakeSignature uhs;
2911 struct UDPConfirmation uc;
2912 struct InitialKX kx;
2913 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2914 size_t dpos;
2915 gcry_cipher_hd_t out_cipher;
2916 struct SharedSecret *ss;
2917
2921
2922 if (msize > receiver->kx_mtu)
2923 {
2924 GNUNET_break (0);
2925 if (GNUNET_YES != receiver->receiver_destroy_called)
2927 return;
2928 }
2930
2931 /* setup key material */
2933
2934 if (0 == purge_secrets (receiver->ss_tail))
2935 {
2936 // No secret purged. Delete oldest.
2937 if (receiver->num_secrets > MAX_SECRETS)
2938 {
2939 secret_destroy (receiver->ss_tail);
2940 }
2941 }
2942
2943 setup_cipher (&ss->master, 0, &out_cipher);
2944 /* compute 'uc' */
2945 uc.sender = *my_identity;
2946 uc.monotonic_time =
2948 uhs.purpose.purpose = htonl (
2950 uhs.purpose.size = htonl (sizeof(uhs));
2951 uhs.sender = *my_identity;
2952 uhs.receiver = receiver->target;
2953 uhs.monotonic_time = uc.monotonic_time;
2955 &uhs,
2956 &uc.sender_sig);
2957 /* Leave space for kx */
2958 dpos = sizeof(kx);
2959 /* Append encrypted uc to dgram */
2960 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2961 &dgram[dpos],
2962 sizeof(uc),
2963 &uc,
2964 sizeof(uc)));
2965 dpos += sizeof(uc);
2966 /* Append encrypted payload to dgram */
2968 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2969 dpos += msize;
2970 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2971 /* Datagram starts with kx */
2972 kx.enc = uhs.enc;
2974 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2975 gcry_cipher_close (out_cipher);
2976 memcpy (dgram, &kx, sizeof(kx));
2978 dgram,
2979 sizeof(dgram),
2980 receiver->address,
2981 receiver->address_len))
2982 {
2985 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2986 msize,
2987 GNUNET_a2s (receiver->address,
2988 receiver->address_len),
2989 receiver->address->sa_family,
2993 return;
2994 }
2996 "Sending KX with payload size %u to %s with socket %p\n",
2997 msize,
2998 GNUNET_a2s (receiver->address,
2999 receiver->address_len),
3002}
3003
3004
3013static void
3015 const struct GNUNET_MessageHeader *msg,
3016 void *impl_state)
3017{
3018 struct ReceiverAddress *receiver = impl_state;
3019
3020 GNUNET_assert (mq == receiver->kx_mq);
3022 return; /* @a receiver has been freed */
3024}
3025
3026
3027static void
3029 UDPRekey *rekey)
3030{
3031 struct SharedSecret *ss_rekey;
3032
3034 /* setup key material */
3035 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
3036 receiver);
3037 ss_rekey->sequence_allowed = 0;
3039 "Setup secret with k = %s\n",
3040 GNUNET_sh2s (&ss_rekey->master));
3042 "Setup secret with H(k) = %s\n",
3043 GNUNET_h2s (&(ss_rekey->cmac)));
3044
3045 /* Append encrypted payload to dgram */
3047 rekey->header.size = htons (sizeof (struct UDPRekey));
3048}
3049
3050
3059static void
3061 const struct GNUNET_MessageHeader *msg,
3062 void *impl_state)
3063{
3064 struct ReceiverAddress *receiver = impl_state;
3065 struct UDPRekey rekey;
3066 struct SharedSecret *ss;
3067 int inject_rekey = GNUNET_NO;
3068 uint16_t msize = ntohs (msg->size);
3069
3070 GNUNET_assert (mq == receiver->d_mq);
3072 return; /* @a receiver has been freed */
3073 if (msize > receiver->d_mtu)
3074 {
3075 /* Transport handed us more than the MTU we advertised for this queue;
3076 that is a bug on its side and we cannot box it. */
3078 "msize: %u, mtu: %llu\n",
3079 (unsigned int) msize,
3080 (unsigned long long) receiver->d_mtu);
3081 GNUNET_break (0);
3082 if (GNUNET_YES != receiver->receiver_destroy_called)
3084 return;
3085 }
3086 if (0 == receiver->acks_available)
3087 {
3088 /* Out of ACK credit. This is NOT a protocol violation and must not cost
3089 us the connection. Transport's idea of our window can only ever drift
3090 *upwards*: #GNUNET_TRANSPORT_communicator_mq_update() takes an
3091 unsigned @a q_len that #handle_update_queue_message() *adds* to
3092 `q_capacity', so there is no way to hand credit back once
3093 #secret_destroy() reclaims a shared secret that still had unused
3094 sequence numbers -- which #purge_secrets() and the rekey path below do
3095 routinely. Given enough uptime the two counters therefore always
3096 diverge, and tearing the receiver down here turns that bookkeeping
3097 drift into a dropped link.
3098
3099 Fall back to KX instead, exactly as the tail of this function already
3100 does when it finds no usable shared secret. That also fixes itself:
3101 a KX makes the peer generate key cache entries and ACK them, which is
3102 what replenishes the credit. */
3104 "No ACKs available for %s, sending as KX\n",
3105 GNUNET_i2s (&receiver->target));
3107 "# messages sent via KX (no ACKs available)",
3108 1,
3109 GNUNET_NO);
3112 return;
3113 }
3115
3116 if (receiver->num_secrets > MAX_SECRETS)
3117 {
3118 if ((0 == purge_secrets (receiver->ss_tail)) &&
3119 (NULL != receiver->ss_tail))
3120 {
3121 // No secret purged. Delete oldest.
3122 secret_destroy (receiver->ss_tail);
3123 }
3124 }
3125 /* begin "BOX" encryption method, scan for ACKs from tail! */
3126 ss = receiver->ss_tail;
3127 while (NULL != ss)
3128 {
3129 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
3131 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
3132 GNUNET_sh2s (&ss->master), ss->sequence_used,
3133 ss->sequence_allowed, ss->bytes_sent);
3134 if (ss->sequence_used >= ss->sequence_allowed)
3135 {
3136 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3137 // "Skipping ss because no acks to use.\n");
3138 ss = ss->prev;
3139 continue;
3140 }
3141 if (ss->bytes_sent >= rekey_max_bytes)
3142 {
3143 struct SharedSecret *ss_tmp;
3145 "Skipping ss because rekey bytes reached.\n");
3146 // FIXME cleanup ss with too many bytes sent!
3147 ss_tmp = ss->prev;
3148 secret_destroy (ss);
3149 ss = ss_tmp;
3150 continue;
3151 }
3152 if (ss->bytes_sent > rekey_max_bytes * 0.7)
3153 {
3154 if (ss->rekey_initiated == GNUNET_NO)
3155 {
3157 "Injecting rekey for ss with byte sent %lu\n",
3158 (unsigned long) ss->bytes_sent);
3159 create_rekey (receiver, ss, &rekey);
3161 payload_len += sizeof (rekey);
3163 }
3164 }
3165 if (0 < ss->sequence_used)
3167 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
3168 GNUNET_sh2s (&ss->master),
3169 ss->sequence_used,
3170 ss->sequence_allowed);
3171 {
3172 char dgram[payload_len];
3173 struct UDPBox *box;
3174 gcry_cipher_hd_t out_cipher;
3175 size_t dpos;
3176
3177 box = (struct UDPBox *) dgram;
3178 ss->sequence_used++;
3179 get_kid (&ss->master, ss->sequence_used, &box->kid);
3180 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
3181 /* Append encrypted payload to dgram */
3182 dpos = sizeof(struct UDPBox);
3183 if (GNUNET_YES == inject_rekey)
3184 {
3186 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
3187 &rekey, sizeof (rekey)));
3188 dpos += sizeof (rekey);
3189 }
3191 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
3192 dpos += msize;
3193 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
3194 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
3195 box->gcm_tag,
3196 sizeof(box->gcm_tag)));
3197 gcry_cipher_close (out_cipher);
3198
3200 dgram,
3201 payload_len, // FIXME why always send sizeof dgram?
3202 receiver->address,
3203 receiver->address_len))
3204 {
3207 "Sending UDPBox to %s family %d failed sock %p failed\n",
3208 GNUNET_a2s (receiver->address,
3209 receiver->address_len),
3210 receiver->address->sa_family,
3213 return;
3214 }
3216 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
3217 msize,
3218 receiver->acks_available,
3219 (unsigned long) ss->bytes_sent,
3221 ss->bytes_sent += sizeof (dgram);
3222 receiver->acks_available--;
3224 return;
3225 }
3226 }
3228 "No suitable ss found, sending as KX...\n");
3230}
3231
3232
3241static void
3242mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
3243{
3244 struct ReceiverAddress *receiver = impl_state;
3246 "Default MQ destroyed\n");
3247 if (mq == receiver->d_mq)
3248 {
3249 receiver->d_mq = NULL;
3250 if (GNUNET_YES != receiver->receiver_destroy_called)
3252 }
3253}
3254
3255
3264static void
3265mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
3266{
3267 struct ReceiverAddress *receiver = impl_state;
3269 "KX MQ destroyed\n");
3270 if (mq == receiver->kx_mq)
3271 {
3272 receiver->kx_mq = NULL;
3273 if (GNUNET_YES != receiver->receiver_destroy_called)
3275 }
3276}
3277
3278
3285static void
3286mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
3287{
3288 /* Cancellation is impossible with UDP; bail */
3289 GNUNET_assert (0);
3290}
3291
3292
3302static void
3303mq_error (void *cls, enum GNUNET_MQ_Error error)
3304{
3305 struct ReceiverAddress *receiver = cls;
3306
3308 "MQ error in queue to %s: %d\n",
3309 GNUNET_i2s (&receiver->target),
3310 (int) error);
3312}
3313
3314
3322static void
3324{
3325 size_t base_mtu;
3326
3327 switch (receiver->address->sa_family)
3328 {
3329 case AF_INET:
3330 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3331 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3332 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3333 break;
3334
3335 case AF_INET6:
3336 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3337 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3338 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3339 break;
3340
3341 default:
3342 GNUNET_assert (0);
3343 break;
3344 }
3345 /* MTU based on full KX messages */
3346 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3347 - sizeof(struct UDPConfirmation); /* 104 */
3348 /* MTU based on BOXed messages */
3349 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3350
3352 "Setting up MQs and QHs\n");
3353 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3354 1404 (IPv4 + Box) bytes, depending on circumstances... */
3355 if (NULL == receiver->kx_mq)
3358 &mq_cancel,
3359 receiver,
3360 NULL,
3361 &mq_error,
3362 receiver);
3363 if (NULL == receiver->d_mq)
3365 &mq_destroy_d,
3366 &mq_cancel,
3367 receiver,
3368 NULL,
3369 &mq_error,
3370 receiver);
3371
3372 receiver->kx_qh =
3374 &receiver->target,
3375 receiver->foreign_addr,
3376 receiver->kx_mtu,
3378 0, /* Priority */
3379 receiver->nt,
3381 receiver->kx_mq);
3382}
3383
3384
3403static int
3404mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3405{
3406 (void) cls;
3408 "create receiver for mq_init\n");
3409 return create_receiver (peer,
3410 address,
3411 NULL);
3412}
3413
3414
3423static int
3425 const struct GNUNET_HashCode *target,
3426 void *value)
3427{
3428 struct ReceiverAddress *receiver = value;
3429
3430 (void) cls;
3431 (void) target;
3433 return GNUNET_OK;
3434}
3435
3436
3445static int
3447 const struct GNUNET_HashCode *target,
3448 void *value)
3449{
3450 struct SenderAddress *sender = value;
3451
3452 (void) cls;
3453 (void) target;
3454
3455
3456 sender_destroy (sender);
3457 return GNUNET_OK;
3458}
3459
3460
3466static void
3467do_shutdown (void *cls)
3468{
3470 "do_shutdown\n");
3471 GNUNET_stop_burst (NULL);
3472 if (NULL != nat)
3473 {
3475 nat = NULL;
3476 }
3477 while (NULL != bi_head)
3479 if (NULL != broadcast_task)
3480 {
3482 broadcast_task = NULL;
3483 }
3484 if (NULL != timeout_task)
3485 {
3487 timeout_task = NULL;
3488 }
3489 if (NULL != read_v6_task)
3490 {
3492 read_v6_task = NULL;
3493 }
3494 if (NULL != read_v4_task)
3495 {
3497 read_v4_task = NULL;
3498 }
3499 if (NULL != default_v6_sock)
3500 {
3503 default_v6_sock = NULL;
3504 }
3505 if (NULL != default_v4_sock)
3506 {
3509 default_v4_sock = NULL;
3510 }
3513 NULL);
3517 NULL);
3522 if (NULL != timeout_task)
3523 {
3525 timeout_task = NULL;
3526 }
3527 if (NULL != ch)
3528 {
3531 ch = NULL;
3532 }
3533 if (NULL != ah)
3534 {
3536 ah = NULL;
3537 }
3538 if (NULL != pils)
3539 {
3541 pils = NULL;
3542 }
3543 if (NULL != key_ring)
3544 {
3546 key_ring = NULL;
3547 }
3548 if (NULL != stats)
3549 {
3551 stats = NULL;
3552 }
3553 if (NULL != is)
3554 {
3556 is = NULL;
3557 }
3559 "do_shutdown finished\n");
3560}
3561
3562
3572static void
3573enc_notify_cb (void *cls,
3574 const struct GNUNET_PeerIdentity *sender,
3575 const struct GNUNET_MessageHeader *msg)
3576{
3577 struct AckInfo ai;
3578
3579 (void) cls;
3581 "Storing UDPAck received from backchannel from %s\n",
3584 (ntohs (msg->size) != sizeof(struct UDPAck)))
3585 {
3586 GNUNET_break_op (0);
3587 return;
3588 }
3589 ai.ack = (const struct UDPAck *) msg;
3590 ai.sender = sender;
3593 &ai);
3594}
3595
3596
3610static void
3612 void **app_ctx,
3613 int add_remove,
3615 const struct sockaddr *addr,
3616 socklen_t addrlen)
3617{
3618 char *my_addr;
3620
3621 if (GNUNET_YES == add_remove)
3622 {
3624
3625 GNUNET_asprintf (&my_addr,
3626 "%s-%s",
3628 GNUNET_a2s (addr, addrlen));
3629 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3630 ai =
3632 my_addr,
3633 nt,
3635 GNUNET_free (my_addr);
3636 *app_ctx = ai;
3637 }
3638 else
3639 {
3640 ai = *app_ctx;
3642 *app_ctx = NULL;
3643 }
3644}
3645
3646
3652static void
3653ifc_broadcast (void *cls)
3654{
3655 struct BroadcastInterface *bi = cls;
3656 struct GNUNET_TIME_Relative delay;
3657
3658 delay = BROADCAST_FREQUENCY;
3659 delay.rel_value_us =
3661 bi->broadcast_task =
3663
3664 switch (bi->sa->sa_family)
3665 {
3666 case AF_INET: {
3667 static int yes = 1;
3668 static int no = 0;
3669 ssize_t sent;
3670
3671 if (GNUNET_OK !=
3673 SOL_SOCKET,
3674 SO_BROADCAST,
3675 &yes,
3676 sizeof(int)))
3678 "setsockopt");
3680 "creating UDPBroadcast from %s\n",
3681 GNUNET_i2s (&(bi->bcm.sender)));
3683 "sending UDPBroadcast to add %s\n",
3684 GNUNET_a2s (bi->ba, bi->salen));
3686 &bi->bcm,
3687 sizeof(bi->bcm),
3688 bi->ba,
3689 bi->salen);
3690 if (-1 == sent)
3692 "sendto");
3694 SOL_SOCKET,
3695 SO_BROADCAST,
3696 &no,
3697 sizeof(int)))
3699 "setsockopt");
3700 break;
3701 }
3702
3703 case AF_INET6: {
3704 ssize_t sent;
3705 struct sockaddr_in6 dst;
3706
3707 dst.sin6_family = AF_INET6;
3708 dst.sin6_port = htons (my_port);
3709 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3710 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3711
3713 "sending UDPBroadcast\n");
3715 &bi->bcm,
3716 sizeof(bi->bcm),
3717 (const struct sockaddr *) &dst,
3718 sizeof(dst));
3719 if (-1 == sent)
3721 break;
3722 }
3723
3724 default:
3725 GNUNET_break (0);
3726 break;
3727 }
3728}
3729
3730
3745static int
3746iface_proc (void *cls,
3747 const char *name,
3748 int isDefault,
3749 const struct sockaddr *addr,
3750 const struct sockaddr *broadcast_addr,
3751 const struct sockaddr *netmask,
3752 socklen_t addrlen)
3753{
3754 const struct GNUNET_PeerIdentity *my_identity;
3756 struct BroadcastInterface *bi;
3757 enum GNUNET_NetworkType network;
3758 struct UdpBroadcastSignature ubs;
3759
3760 (void) cls;
3761 (void) netmask;
3762
3765
3766 if ((NULL == my_identity) || (NULL == my_private_key))
3767 return GNUNET_YES;
3768 if (NULL == addr)
3769 return GNUNET_YES; /* need to know our address! */
3770 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3771 if (GNUNET_NT_LOOPBACK == network)
3772 {
3773 /* Broadcasting on loopback does not make sense */
3774 return GNUNET_YES;
3775 }
3776 for (bi = bi_head; NULL != bi; bi = bi->next)
3777 {
3778 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3779 {
3780 bi->found = GNUNET_YES;
3781 return GNUNET_OK;
3782 }
3783 }
3784
3785 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3786 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3787 if ((AF_INET6 == addr->sa_family) && (NULL == default_v6_sock))
3788 return GNUNET_OK; /* not using IPv6 */
3789
3790 bi = GNUNET_new (struct BroadcastInterface);
3791 bi->sa = GNUNET_memdup (addr,
3792 addrlen);
3793 if ( (NULL != broadcast_addr) &&
3794 (addrlen == sizeof (struct sockaddr_in)) )
3795 {
3796 struct sockaddr_in *ba;
3797
3798 ba = GNUNET_memdup (broadcast_addr,
3799 addrlen);
3800 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3801 bi->ba = (struct sockaddr *) ba;
3802 }
3803 bi->salen = addrlen;
3804 bi->found = GNUNET_YES;
3805 bi->bcm.sender = *my_identity;
3806 ubs.purpose.purpose = htonl (
3808 ubs.purpose.size = htonl (sizeof(ubs));
3809 ubs.sender = *my_identity;
3811 "creating UDPBroadcastSignature for %s\n",
3812 GNUNET_a2s (addr, addrlen));
3813 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3815 &ubs,
3816 &bi->bcm.sender_sig);
3817 if (NULL != bi->ba)
3818 {
3821 }
3822 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3823 {
3824 /* Create IPv6 multicast request */
3825 const struct sockaddr_in6 *s6 =
3826 (const struct sockaddr_in6 *) broadcast_addr;
3827
3829 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3830
3831 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3832 *
3833 * IPV6_JOIN_GROUP
3834 *
3835 * Join a multicast group on a specified local interface. If the
3836 * interface index is specified as 0, the kernel chooses the local
3837 * interface. For example, some kernels look up the multicast
3838 * group in the normal IPv6 routing table and using the resulting
3839 * interface; we do this for each interface, so no need to use
3840 * zero (anymore...).
3841 */
3842 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3843
3844 /* Join the multicast group */
3846 IPPROTO_IPV6,
3847 IPV6_JOIN_GROUP,
3848 &bi->mcreq,
3849 sizeof(bi->mcreq)))
3850 {
3852 }
3853 }
3854 return GNUNET_OK;
3855}
3856
3857
3863static void
3864do_broadcast (void *cls)
3865{
3866 struct BroadcastInterface *bin;
3867
3868 (void) cls;
3869 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3870 bi->found = GNUNET_NO;
3872 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3873 {
3874 bin = bi->next;
3875 if (GNUNET_NO == bi->found)
3876 bi_destroy (bi);
3877 }
3879 &do_broadcast,
3880 NULL);
3881}
3882
3883
3884static void
3886 const struct sockaddr *addr,
3887 socklen_t addrlen)
3888{
3889 /* FIXME: support reversal: #5529 */
3891 "No connection reversal implemented!\n");
3892}
3893
3894
3895static void
3897{
3898 // FIXME: This sizeof application truncates IPv6 addresses!
3900 sizeof (*sock_info->actual_address
3901 ));
3902 create_receiver (sock_info->pid,
3903 address,
3904 default_v4_sock == sock_info->udp_sock ||
3905 default_v6_sock == sock_info->udp_sock ?
3906 NULL : sock_info->udp_sock);
3908 GNUNET_free (sock_info);
3909}
3910
3911
3912static void
3913start_burst (const char *addr,
3914 struct GNUNET_TIME_Relative rtt,
3915 struct GNUNET_PeerIdentity *pid)
3916{
3917 struct GNUNET_UdpSocketInfo *sock_info;
3918
3920 "Communicator was called to start burst to address %s from %s\n",
3921 addr,
3922 my_ipv4);
3923
3924 GNUNET_stop_burst (NULL);
3925
3926 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3927 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3928 sock_info->address = GNUNET_strdup (addr);
3929 sock_info->bind_address = my_ipv4;
3930 sock_info->has_port = GNUNET_YES;
3931 sock_info->udp_sock = default_v4_sock;
3932 sock_info->rtt = rtt;
3933 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3934 sock_info->std_port = my_port;
3936 "1 sock addr %s addr %s rtt %lu %u\n",
3937 sock_info->address,
3938 addr,
3939 (unsigned long) sock_info->rtt.rel_value_us,
3940 my_port);
3941 burst_task = GNUNET_get_udp_socket (sock_info,
3943 GNUNET_free (sock_info);
3944}
3945
3946
3947static struct GNUNET_NETWORK_Handle*
3948create_udp_socket (const char *bindto,
3949 sa_family_t family,
3950 struct sockaddr **out,
3951 socklen_t *out_len)
3952{
3953 struct GNUNET_NETWORK_Handle *sock;
3954 struct sockaddr *in;
3955 socklen_t in_len;
3956 struct sockaddr_storage in_sto;
3957 socklen_t sto_len;
3958
3959 in = udp_address_to_sockaddr (bindto, family, &in_len);
3960 if (NULL == in)
3961 {
3963 "Failed to setup UDP socket address with path `%s'\n",
3964 bindto);
3965 return NULL;
3966 }
3967
3968 if ((AF_UNSPEC != family) && (in->sa_family != family))
3969 {
3971 "Invalid UDP socket address setup with path `%s'\n",
3972 bindto);
3973 GNUNET_free (in);
3974 return NULL;
3975 }
3976
3977 sock =
3978 GNUNET_NETWORK_socket_create (in->sa_family,
3979 SOCK_DGRAM,
3980 IPPROTO_UDP);
3981 if (NULL == sock)
3982 {
3985 "Failed to create socket for %s family %d\n",
3986 GNUNET_a2s (in,
3987 in_len),
3988 in->sa_family);
3989 GNUNET_free (in);
3990 return NULL;
3991 }
3992 if (GNUNET_OK !=
3994 in,
3995 in_len))
3996 {
3998 "bind",
3999 bindto);
4001 "Failed to bind socket for %s family %d sock %p\n",
4002 GNUNET_a2s (in,
4003 in_len),
4004 in->sa_family,
4005 sock);
4007 sock = NULL;
4008 GNUNET_free (in);
4009 return NULL;
4010 }
4011
4012 /* We might have bound to port 0, allowing the OS to figure it out;
4013 thus, get the real IN-address from the socket */
4014 sto_len = sizeof(in_sto);
4015 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
4016 (struct sockaddr *) &in_sto,
4017 &sto_len))
4018 {
4019 memcpy (&in_sto, in, in_len);
4020 sto_len = in_len;
4021 }
4022 GNUNET_free (in);
4023 *out = GNUNET_malloc (sto_len);
4024 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
4025 *out_len = sto_len;
4026 return sock;
4027}
4028
4029
4030static void
4031shutdown_run (struct sockaddr *addrs[2])
4032{
4033 if (NULL != addrs[0])
4034 GNUNET_free (addrs[0]);
4035 if (NULL != addrs[1])
4036 GNUNET_free (addrs[1]);
4038}
4039
4040
4041static void
4042run (void *cls,
4043 char *const *args,
4044 const char *cfgfile,
4045 const struct GNUNET_CONFIGURATION_Handle *c)
4046{
4047 const struct sockaddr_in *v4;
4048 char *bindto;
4049 char *bindto6;
4050 struct sockaddr *in[2];
4051 socklen_t in_len[2];
4052
4054 "Entering the run method of udp communicator.\n");
4055
4056 cfg = c;
4058 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
4059 (GNUNET_YES ==
4062 "DISABLE_V6")))
4063 {
4065 }
4066
4067 if (GNUNET_OK !=
4070 "BINDTO",
4071 &bindto))
4072 {
4075 "BINDTO");
4076 return;
4077 }
4079 "The udp communicator will bind to %s for IPv4\n",
4080 bindto);
4081 if (GNUNET_YES != disable_v6)
4082 {
4083 if (GNUNET_OK !=
4086 "BINDTO6",
4087 &bindto6))
4088 {
4091 "BINDTO6");
4092 return;
4093 }
4094
4096 "The udp communicator will bind to %s for IPv6\n",
4097 bindto6);
4098 }
4099 else
4100 bindto6 = NULL;
4101 if (GNUNET_OK !=
4104 "REKEY_INTERVAL",
4107
4108 if (GNUNET_OK !=
4111 "REKEY_MAX_BYTES",
4113 {
4115 }
4116
4117 memset (in, 0, sizeof(struct sockaddr*) * 2);
4118 memset (in_len, 0, sizeof(socklen_t) * 2);
4119
4120 GNUNET_assert (bindto);
4122 bindto, AF_INET, &(in[0]), &(in_len[0]));
4123 GNUNET_free (bindto);
4124
4125 if (GNUNET_YES != disable_v6)
4126 {
4127 GNUNET_assert (bindto6);
4129 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
4130 GNUNET_free (bindto6);
4131 }
4132 else
4133 default_v6_sock = NULL;
4134
4135 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
4136 return;
4137
4138 my_port = 0;
4139 if (NULL != default_v4_sock)
4140 {
4141 GNUNET_assert (in[0]);
4143 "transport",
4144 "Bound to `%s' sock %p\n",
4145 GNUNET_a2s ((const struct sockaddr *) in[0],
4146 in_len[0]),
4148
4149 v4 = (const struct sockaddr_in *) in[0];
4150
4151 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
4152 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
4153 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
4154 }
4155 if (NULL != default_v6_sock)
4156 {
4157 GNUNET_assert (in[1]);
4159 "transport",
4160 "Bound to `%s' sock %p\n",
4161 GNUNET_a2s ((const struct sockaddr *) in[1],
4162 in_len[1]),
4164 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
4165 }
4166 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
4175 /* start reading */
4176 if (NULL != default_v4_sock)
4179 &sock_read,
4181 else
4182 read_v4_task = NULL;
4183 if (NULL != default_v6_sock)
4186 &sock_read,
4188 else
4189 read_v6_task = NULL;
4194 &mq_init,
4195 NULL,
4197 NULL,
4198 &start_burst);
4199 if (NULL == ch)
4200 {
4201 GNUNET_break (0);
4202 shutdown_run (in);
4203 return;
4204 }
4206 if (NULL == ah)
4207 {
4208 GNUNET_break (0);
4209 shutdown_run (in);
4210 return;
4211 }
4212 /* start broadcasting */
4213 if (GNUNET_YES !=
4216 "DISABLE_BROADCAST"))
4217 {
4219 }
4221 GNUNET_assert (NULL != key_ring);
4222 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
4223 GNUNET_assert (NULL != pils);
4224
4227 IPPROTO_UDP,
4228 (NULL != in[0]? 1 : 0)
4229 + (NULL != in[1]? 1 : 0),
4230 (const struct sockaddr**)
4231 (NULL != in[0]? in : &(in[1])),
4232 NULL != in[0]? in_len : &(in_len[1]),
4235 NULL /* closure */);
4236 if (NULL != in[0])
4237 GNUNET_free (in[0]);
4238 if (NULL != in[1])
4239 GNUNET_free (in[1]);
4240}
4241
4242
4243GNUNET_DAEMON_MAIN ("gnunet-communicator-udp",
4244 _ ("GNUnet UDP communicator"),
4245 &run)
4246/* end of gnunet-communicator-udp.c */
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static uint16_t port
Port number.
Definition gnunet-bcd.c:146
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
#define AES_KEY_SIZE
AES key size.
static struct BroadcastInterface * bi_tail
Broadcast interface tasks.
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
static int try_decrypt(const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
Try to decrypt buf using shared secret ss and key/iv derived using serial.
#define WORKING_QUEUE_INTERVALL
static void kce_destroy(struct KeyCacheEntry *kce)
Free memory used by key cache entry.
static int handle_ack(void *cls, const struct GNUNET_HashCode *key, void *value)
We received an ACK for pid.
static void create_rekey(struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static int secret_destroy(struct SharedSecret *ss)
Destroy ss and associated key cache entries.
static enum GNUNET_GenericReturnValue check_peer_alive(struct ReceiverAddress *receiver)
Check whether the peer behind receiver is still reacting to what we send it, and tear receiver down i...
#define GCM_TAG_SIZE
Size of the GCM tag.
static void get_iv_key(const struct GNUNET_ShortHashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
Compute key and iv.
static void mq_send_kx(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static struct SharedSecret * setup_initial_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM for initial handshake.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static void kce_generate(struct SharedSecret *ss, uint32_t seq)
Setup key cache entry for sequence number seq and shared secret ss.
static void setup_cipher(const struct GNUNET_ShortHashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.
static struct GNUNET_NETWORK_Handle * create_udp_socket(const char *bindto, sa_family_t family, struct sockaddr **out, socklen_t *out_len)
static void add_acks(struct SharedSecret *ss, int acks_to_add)
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static struct GNUNET_SCHEDULER_Task * read_v6_task
ID of read IPv6 task.
static void eddsa_pub_to_hpke_key(const struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_HpkePublicKey *pk)
static struct GNUNET_SCHEDULER_Task * read_v4_task
ID of read IPv4 task.
static void mq_destroy_kx(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static int get_receiver_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all receivers to clean up.
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static void eddsa_priv_to_hpke_key(const struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
static struct GNUNET_SCHEDULER_Task * broadcast_task
ID of master broadcast task.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static int verify_confirmation(const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct UDPConfirmation *uc)
Check signature from uc against ephemeral.
static int disable_v6
IPv6 disabled or not.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static struct GNUNET_NETWORK_Handle * default_v4_sock
Our IPv4 socket.
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received a backchannel message for this communicator (...
static void consider_reflexive_address(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
Consider the address a datagram from target arrived from as a path we can send to.
#define PEER_LIVENESS_TIMEOUT
How long may we keep transmitting to a peer that never acknowledges a single datagram before we concl...
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)
Offer an ACK we received from ai->sender to the receiver in value, if that receiver is for that peer.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
#define DEFAULT_REKEY_MAX_BYTES
Default value for how often we do rekey based on number of bytes transmitted? (additionally randomize...
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static void shutdown_run(struct sockaddr *addrs[2])
static struct GNUNET_CONTAINER_MultiHashMap * receivers
Receivers (map from peer identity to struct ReceiverAddress)
#define GENERATE_AT_ONCE
static void kce_generate_cb(void *cls)
static void try_handle_plaintext(struct SenderAddress *sender, const void *buf, size_t buf_size)
Test if we have received a valid message in plaintext.
static struct GNUNET_PILS_KeyRing * key_ring
For PILS.
static void receiver_destroy(struct ReceiverAddress *receiver)
Destroys a receiving state due to timeout or shutdown.
static struct GNUNET_CONTAINER_MultiShortmap * key_cache
Cache of pre-generated key IDs.
static void udp_socket_notify(struct GNUNET_UdpSocketInfo *sock_info)
#define KCN_TARGET
How many KCNs do we keep around after we hit the KCN_THRESHOLD? Should be larger than KCN_THRESHOLD s...
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
static struct GNUNET_TRANSPORT_ApplicationHandle * ah
Our handle to report addresses for validation to TRANSPORT.
static void bi_destroy(struct BroadcastInterface *bi)
An interface went away, stop broadcasting on it.
static void pass_plaintext_to_core(struct SenderAddress *sender, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext from a sender.
static struct GNUNET_CONTAINER_MultiHashMap * senders
Senders (map from peer identity to struct SenderAddress)
static int mq_init(void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
Function called by the transport service to initialize a message queue given address information abou...
static void do_broadcast(void *cls)
Scan interfaces to broadcast our presence on the LAN.
#define INTERFACE_SCAN_FREQUENCY
How often do we scan for changes to our network interfaces?
static struct sockaddr * udp_address_to_sockaddr(const char *bindto, sa_family_t family, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
static struct GNUNET_CONTAINER_Heap * receivers_heap
Expiration heap for receivers (contains struct ReceiverAddress)
static uint16_t my_port
Port number to which we are actually bound.
static char * sockaddr_to_udpaddr_string(const struct sockaddr *address, socklen_t address_len)
Converts address to the address string format used by this communicator in HELLOs.
static void check_timeouts(void *cls)
Task run to check #receiver_heap and #sender_heap for timeouts.
static void calculate_cmac(struct SharedSecret *ss)
Calculate cmac from master in ss.
static struct GNUNET_SCHEDULER_Task * timeout_task
ID of timeout task.
char * my_ipv4
Our ipv4 address.
static struct GNUNET_SCHEDULER_Task * burst_task
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral)
Setup shared secret for decryption.
#define MAX_SQN_DELTA
What is the maximum delta between KCN sequence numbers that we allow.
#define KCN_THRESHOLD
If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET...
#define MAX_SECRETS
How many shared master secrets do we keep around at most per sender? Should be large enough so that w...
static struct BroadcastInterface * bi_head
Broadcast interface tasks.
static enum GNUNET_GenericReturnValue create_receiver(const struct GNUNET_PeerIdentity *peer, const char *address, struct GNUNET_NETWORK_Handle *udp_sock)
static struct GNUNET_NETWORK_Handle * get_socket(struct ReceiverAddress *receiver)
static void send_msg_with_kx(const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver, struct GNUNET_MQ_Handle *mq)
static struct GNUNET_NETWORK_Handle * default_v6_sock
Our IPv6 socket.
static struct SenderAddress * setup_sender(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len, int *is_new)
Create sender address for target.
static void mq_error(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static int iface_proc(void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
Callback function invoked for each interface found.
static void ifc_broadcast(void *cls)
Broadcast our presence on one of our interfaces.
static struct GNUNET_PILS_Handle * pils
For PILS.
static void decrypt_box(const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
We received a box with matching kce.
static unsigned int purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
static void consider_ss_ack(struct SharedSecret *ss)
We established a shared secret with a sender.
static unsigned long long rekey_max_bytes
How often we do rekey based on number of bytes transmitted.
#define AES_IV_SIZE
AES (GCM) IV size.
#define BROADCAST_FREQUENCY
How often do we broadcast our presence on the LAN?
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static char * address
GNS address for this phone.
struct GNUNET_HashCode key
The key used in the DHT.
static OpusEncoder * enc
OPUS encoder.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
struct GNUNET_CRYPTO_BlindablePrivateKey pk
Private key from command line option, or NULL.
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
struct GNUNET_CRYPTO_EddsaPrivateKey my_private_key
The current private key.
static struct GNUNET_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:624
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:647
struct GNUNET_PILS_KeyRing * GNUNET_PILS_create_key_ring(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_SCHEDULER_TaskCallback init_cb, void *cls)
Create a key ring handle to use the current peer identity key.
Definition pils_api.c:1008
void GNUNET_PILS_destroy_key_ring(struct GNUNET_PILS_KeyRing *key_ring)
Destroy a key ring handle and free its memory.
Definition pils_api.c:1068
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:875
const struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_PILS_key_ring_get_private_key(const struct GNUNET_PILS_KeyRing *key_ring)
Return the current private key of a given key ring handle.
Definition pils_api.c:1091
Constants for network protocols.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE
Signature used by UDP communicator handshake.
API to create, modify and access statistics.
Bandwidth allocation API for applications to interact with.
API of the transport service towards the communicator processes.
void GNUNET_TRANSPORT_communicator_address_remove(struct GNUNET_TRANSPORT_AddressIdentifier *ai)
Notify transport service about an address that this communicator no longer provides for this peer.
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
void GNUNET_TRANSPORT_communicator_burst_finished(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
The communicator tells the transport service that it finished the burst.
void GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
struct GNUNET_TRANSPORT_QueueHandle * GNUNET_TRANSPORT_communicator_mq_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *peer, const char *address, uint32_t mtu, uint64_t q_len, uint32_t priority, enum GNUNET_NetworkType nt, enum GNUNET_TRANSPORT_ConnectionStatus cs, struct GNUNET_MQ_Handle *mq)
Notify transport service that a MQ became available due to an "inbound" connection or because the com...
void GNUNET_TRANSPORT_application_validate(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_NetworkType nt, const char *addr)
An application (or a communicator) has received a HELLO (or other address data of another peer) and w...
void GNUNET_TRANSPORT_communicator_mq_update(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_TRANSPORT_QueueHandle *u_qh, uint64_t q_len, uint32_t priority)
Notify transport service that an MQ was updated.
void GNUNET_TRANSPORT_communicator_notify(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *pid, const char *comm, const struct GNUNET_MessageHeader *header)
The communicator asks the transport service to route a message via a different path to another commun...
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls, GNUNET_TRANSPORT_StartBurstNotify sb)
Connect to the transport service.
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer.
void GNUNET_TRANSPORT_communicator_address_remove_all(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Notify transport service that this communicator no longer provides all its addresses for this peer.
@ GNUNET_TRANSPORT_CC_UNRELIABLE
Transmission is unreliable (e.g.
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Decapsulate a key for a private EdDSA key.
uint64_t GNUNET_CRYPTO_random_u64(uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps(const struct GNUNET_CRYPTO_HpkePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_decaps(const struct GNUNET_CRYPTO_HpkePrivateKey *skR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh decapsulation with own private key and the representative of the received public key...
void GNUNET_CRYPTO_random_block(void *buffer, size_t length)
Fill block with a random values.
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.
#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:40
#define GNUNET_CRYPTO_hkdf_expand(result, out_len, prk,...)
HKDF-Expand using SHA256.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
#define GNUNET_CRYPTO_kdf_arg_string(d)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_BlindablePrivateKey *sk, struct GNUNET_CRYPTO_HpkePrivateKey *sk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
#define GNUNET_CRYPTO_kdf_arg_auto(d)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_BlindablePublicKey *pk, struct GNUNET_CRYPTO_HpkePublicKey *pk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...) __attribute__((format(printf
Log function that specifies an alternative component.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:514
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:469
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:732
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:513
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:568
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition network.c:1000
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition network.c:687
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition network.c:79
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition network.c:439
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition network.c:805
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition network.c:771
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition nt.c:428
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition nt.c:407
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition nt.c:309
@ GNUNET_NT_LOOPBACK
Loopback (same host).
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition os_network.c:397
#define GNUNET_DAEMON_MAIN(daemon_name, daemon_help, init_cb)
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY
UDP Rekey.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK
UDP KX acknowledgement.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition scheduler.c:1517
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition time.c:344
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
#define GNUNET_TIME_relative_cmp(t1, op, t2)
Compare two relative times.
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
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:610
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition time.c:860
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:636
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
static void receiver(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition socks.c:330
const struct UDPAck * ack
const struct GNUNET_PeerIdentity * sender
Interface we broadcast our presence on.
socklen_t salen
Number of bytes in sa.
struct ipv6_mreq mcreq
If this is an IPv6 interface, this is the request we use to join/leave the group.
struct BroadcastInterface * next
Kept in a DLL.
int found
Was this interface found in the last iface_proc() scan?
struct UDPBroadcast bcm
Message we broadcast on this interface.
struct sockaddr * ba
Broadcast address to use on the interface.
struct GNUNET_SCHEDULER_Task * broadcast_task
Task for this broadcast interface.
struct BroadcastInterface * prev
Kept in a DLL.
struct sockaddr * sa
Sender's address of the interface.
Message send during burst mode.
struct GNUNET_PeerIdentity peer
The peer who send the msg.
unsigned int local_port
The local port the message was send from.
Handle to a node in a heap.
Internal representation of the hash map.
Internal representation of the hash map.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
an ECC signature using EdDSA.
HPKE DHKEM encapsulation (X25519) See RFC 9180.
A public key used for decryption.
A public key used for encryption.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Header for all communications.
Handle for active NAT registrations.
Definition nat_api.c:72
handle to a socket
Definition network.c:53
Handle to the interface scanner.
Definition nt.c:104
A handle for the PILS service.
Definition pils_api.c:86
A simplified handle for using the peer identity key.
Definition pils_api.c:149
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:141
Handle for the service.
A 256-bit hashcode.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Internal representation of an address a communicator is currently providing for the transport service...
Handle to the TRANSPORT subsystem for application management.
Opaque handle to the transport service for communicators.
Handle returned to identify the internal data structure the transport API has created to manage a mes...
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.
Struct with the socket we like to use to send messages to another peer.
const char * bind_address
Our address without port.
enum GNUNET_GenericReturnValue has_port
Flag indicating, if the address is without port information.
struct GNUNET_TIME_Relative rtt
The actual RTT between the peers.
char * address
The address of the other peer without port.
unsigned int std_port
Default local port we are bound to.
struct sockaddr * actual_address
The address of the other peer we received a burst message from.
struct GNUNET_NETWORK_Handle * udp_sock
struct GNUNET_PeerIdentity * pid
The peer we like to connect to.
"Plaintext" header at beginning of KX message.
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
struct GNUNET_CRYPTO_HpkeEncapsulation enc
Representative of ephemeral key for KX.
Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct U...
struct GNUNET_ShortHashCode kid
Key and IV identification code.
uint32_t sequence_number
Sequence number used to derive this entry from master key.
struct KeyCacheEntry * next
Kept in a DLL.
struct KeyCacheEntry * prev
Kept in a DLL.
struct SharedSecret * ss
Corresponding shared secret.
Information we track per receiving address we have recently been in contact with (encryption to recei...
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct GNUNET_TIME_Absolute rekey_timeout
Timeout for this receiver address.
struct SharedSecret * ss_tail
Shared secrets we received with target, last used is tail.
char * foreign_addr
Address of the receiver in the human-readable format with the COMMUNICATOR_ADDRESS_PREFIX.
struct GNUNET_SCHEDULER_Task * read_task
Read task, if this receiver has its own socket.
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this receiver.
struct SharedSecret * ss_head
Shared secrets we received from target, first used is head.
struct GNUNET_TRANSPORT_QueueHandle * kx_qh
handle for KX queue with the ch.
unsigned int num_secrets
Length of the DLL at ss_head.
struct GNUNET_TIME_Absolute timeout
Timeout for this receiver address.
size_t kx_mtu
MTU we allowed transport for this receiver's KX queue.
struct GNUNET_TIME_Absolute last_ack
When did we last receive a GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK that belongs to this receiver?...
struct sockaddr * address
Address of the other peer.
struct GNUNET_PeerIdentity target
To whom are we talking to.
socklen_t address_len
Length of the address.
struct GNUNET_MQ_Handle * kx_mq
KX message queue we are providing for the ch.
int receiver_destroy_called
receiver_destroy already called on receiver.
struct GNUNET_NETWORK_Handle * udp_sock
Socket this receiver got via NAT traversal.
size_t d_mtu
MTU we allowed transport for this receiver's default queue.
enum GNUNET_NetworkType nt
Which network type does this queue use?
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.
struct GNUNET_CRYPTO_HpkePublicKey target_hpke_key
To whom are we talking to.
struct GNUNET_TRANSPORT_QueueHandle * d_qh
handle for default queue with the ch.
struct GNUNET_HashCode key
The address key for this entry.
Closure for #find_sender_by_address()
const struct sockaddr * address
Address we are looking for.
struct SenderAddress * sender
Return value to set if we found a match.
socklen_t address_len
Number of bytes in address.
Information we track per sender address we have recently been in contact with (we decrypt messages fr...
struct GNUNET_PeerIdentity target
To whom are we talking to.
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct sockaddr * address
Address of the other peer.
socklen_t address_len
Length of the address.
enum GNUNET_NetworkType nt
Which network type does this queue use?
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this sender.
unsigned int num_secrets
Length of the DLL at ss_head.
int kce_send_ack_on_finish
When KCE finishes, send ACK if GNUNET_YES.
struct GNUNET_TIME_Absolute timeout
Timeout for this sender.
int kce_task_finished
Is the kce_task finished?
struct GNUNET_SCHEDULER_Task * kce_task
ID of kce working queue task.
struct GNUNET_HashCode key
The address key for this entry.
struct SharedSecret * ss_head
Shared secrets we used with target, first used is head.
int sender_destroy_called
sender_destroy already called on sender.
struct SharedSecret * ss_tail
Shared secrets we used with target, last used is tail.
Shared secret we generated for a particular sender or receiver.
struct KeyCacheEntry * kce_tail
Kept in a DLL, sorted by sequence number.
uint32_t sequence_allowed
Up to which sequence number did the other peer allow us to use this key, or up to which number did we...
struct SharedSecret * next
Kept in a DLL.
unsigned int active_kce_count
Number of active KCN entries.
uint32_t sequence_used
Up to which sequence number did we use this master already? (for encrypting only)
size_t bytes_sent
Bytes sent with this shared secret.
struct SharedSecret * prev
Kept in a DLL.
struct SenderAddress * sender
Sender we use this shared secret with, or NULL.
struct KeyCacheEntry * kce_head
Kept in a DLL, sorted by sequence number.
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.
struct ReceiverAddress * receiver
Receiver we use this shared secret with, or NULL.
struct GNUNET_ShortHashCode master
Master shared secret.
int override_available_acks
Also precompute keys despite sufficient acks (for rekey)
int rekey_initiated
rekey initiated for this secret?
UDP key acknowledgement.
uint32_t sequence_ack
Sequence acknowledgement limit.
struct GNUNET_HashCode cmac
CMAC of the base key being acknowledged.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
UDP message box.
uint8_t gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
Broadcast by peer in LAN announcing its presence.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_PeerIdentity sender
Sender's peer identity.
Encrypted continuation of UDP initial handshake, followed by message header with payload.
struct GNUNET_PeerIdentity sender
Sender's identity.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
Plaintext of a rekey payload in a UDPBox.
struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral
Ephemeral key to rekey with.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_HashCode h_address
Hash of the sender's UDP address.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP broadcast.
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_HpkeEncapsulation enc
Ephemeral key used by the sender.
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the UDP connection (UDP server)
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP connection (UDP client).