GNUnet 0.21.1
gnunet-communicator-udp.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 2018, 2019 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14 :
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
40#include "platform.h"
41#include "gnunet_common.h"
42#include "gnunet_util_lib.h"
43#include "gnunet_protocols.h"
44#include "gnunet_signatures.h"
45#include "gnunet_constants.h"
46#include "gnunet_nat_service.h"
50
54#define DEFAULT_REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
55
59#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
60
64#define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
65
69#define INTERFACE_SCAN_FREQUENCY \
70 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
71
76#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
77
78#define WORKING_QUEUE_INTERVALL \
79 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)
80
84#define AES_KEY_SIZE (256 / 8)
85
89#define AES_IV_SIZE (96 / 8)
90
94#define GCM_TAG_SIZE (128 / 8)
95
96#define GENERATE_AT_ONCE 64
97
107#define KCN_THRESHOLD 96
108
115#define KCN_TARGET 128
116
126#define MAX_SQN_DELTA 160
127
137#define MAX_SECRETS 256
138
143#define DEFAULT_REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
144
149#define COMMUNICATOR_ADDRESS_PREFIX "udp"
150
154#define COMMUNICATOR_CONFIG_SECTION "communicator-udp"
155
157
158
165{
170
175
180
185
191};
192
193
199{
204
210
211};
212
213
219{
224
229
235
236 /* followed by messages */
237
238 /* padding may follow actual messages */
239};
240
241
246struct UDPAck
247{
252
258
263};
264
265
275{
280
285
290};
291
292
300{
305
311};
312
313
318struct UDPBox
319{
328
337
338};
339
344{
349
354};
355
357
361struct SharedSecret;
362
363
369{
374
379
388
393
398};
399
400
405struct SenderAddress;
406
411struct ReceiverAddress;
412
417{
422
427
432
437
442
447
452
457
463
470
474 unsigned int active_kce_count;
475
480
485
490};
491
492
498{
503
508
513
518
522 struct sockaddr *address;
523
527 socklen_t address_len;
528
533
538
542 unsigned int num_secrets;
543
548 unsigned int acks_available;
549
554
559
564
569
574};
575
576
582{
587
592
597
602
607
613
617 struct sockaddr *address;
618
622 socklen_t address_len;
623
628
633
638
643
648
653
657 size_t kx_mtu;
658
662 size_t d_mtu;
663
667 unsigned int num_secrets;
668
673 unsigned int acks_available;
674
679
684};
685
690{
695
700
705
709 struct sockaddr *sa;
710
714 struct sockaddr *ba;
715
720
725 struct ipv6_mreq mcreq;
726
730 socklen_t salen;
731
735 int found;
736};
737
742
746static unsigned long long rekey_max_bytes;
747
752
757
762
767
772
777
782
787
792
797
802
807
812
816static int have_v6_socket;
817
822
827
831static const struct GNUNET_CONFIGURATION_Handle *cfg;
832
837
842
846static struct GNUNET_NAT_Handle *nat;
847
851static uint16_t my_port;
852
856static int disable_v6;
857
858
864static void
866{
867 if (AF_INET6 == bi->sa->sa_family)
868 {
869 /* Leave the multicast group */
871 IPPROTO_IPV6,
872 IPV6_LEAVE_GROUP,
873 &bi->mcreq,
874 sizeof(bi->mcreq)))
875 {
877 }
878 }
881 GNUNET_free (bi->sa);
882 GNUNET_free (bi->ba);
883 GNUNET_free (bi);
884}
885
886
892static void
894{
895
896 receiver->receiver_destroy_called = GNUNET_YES;
897
899 "Disconnecting receiver for peer `%s'\n",
900 GNUNET_i2s (&receiver->target));
901 if (NULL != receiver->kx_qh)
902 {
904 receiver->kx_qh = NULL;
905 receiver->kx_mq = NULL;
906 }
907 if (NULL != receiver->d_qh)
908 {
910 receiver->d_qh = NULL;
911 }
914 &receiver->key,
915 receiver));
918 "# receivers active",
920 GNUNET_NO);
921 GNUNET_free (receiver->address);
922 GNUNET_free (receiver->foreign_addr);
924}
925
926
932static void
934{
935 struct SharedSecret *ss = kce->ss;
936
937 ss->active_kce_count--;
940 &kce->kid,
941 kce));
942 GNUNET_free (kce);
943}
944
945
953static void
954get_kid (const struct GNUNET_HashCode *msec,
955 uint32_t serial,
956 struct GNUNET_ShortHashCode *kid)
957{
958 uint32_t sid = htonl (serial);
959
961 sizeof(*kid),
962 GCRY_MD_SHA512,
963 GCRY_MD_SHA256,
964 &sid,
965 sizeof(sid),
966 msec,
967 sizeof(*msec),
968 "UDP-KID",
969 strlen ("UDP-KID"),
970 NULL,
971 0);
972}
973
974
981static void
982kce_generate (struct SharedSecret *ss, uint32_t seq)
983{
984 struct KeyCacheEntry *kce;
985
986 GNUNET_assert (0 < seq);
987 kce = GNUNET_new (struct KeyCacheEntry);
988 kce->ss = ss;
989 kce->sequence_number = seq;
990 get_kid (&ss->master, seq, &kce->kid);
995 key_cache,
996 &kce->kid,
997 kce,
1000 "# KIDs active",
1002 GNUNET_NO);
1003}
1004
1005
1012static int
1014{
1015 struct SenderAddress *sender;
1016 struct ReceiverAddress *receiver;
1017 struct KeyCacheEntry *kce;
1018
1020 "secret %s destroy %u\n",
1021 GNUNET_h2s (&ss->master),
1023 if (NULL != (sender = ss->sender))
1024 {
1025 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1026 sender->num_secrets--;
1028 "%u sender->num_secrets %u allowed %u used, %u available\n",
1030 sender->acks_available);
1032 if (NULL != ss->sender->kce_task)
1033 {
1035 ss->sender->kce_task = NULL;
1036 }
1037 }
1038 if (NULL != (receiver = ss->receiver))
1039 {
1040 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1041 receiver->num_secrets--;
1042 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1044 "%u receiver->num_secrets\n",
1045 receiver->num_secrets);
1046 }
1047 while (NULL != (kce = ss->kce_head))
1048 kce_destroy (kce);
1049 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1051 "# KIDs active",
1053 GNUNET_NO);
1054 GNUNET_free (ss);
1055 return GNUNET_YES;
1056}
1057
1058
1065static void
1067{
1070 GNUNET_YES ==
1074 "# senders active",
1076 GNUNET_NO);
1077 GNUNET_free (sender->address);
1078 GNUNET_free (sender);
1079}
1080
1081
1090static void
1091get_iv_key (const struct GNUNET_HashCode *msec,
1092 uint32_t serial,
1093 char key[AES_KEY_SIZE],
1094 char iv[AES_IV_SIZE])
1095{
1096 uint32_t sid = htonl (serial);
1098
1100 sizeof(res),
1101 GCRY_MD_SHA512,
1102 GCRY_MD_SHA256,
1103 &sid,
1104 sizeof(sid),
1105 msec,
1106 sizeof(*msec),
1107 "UDP-IV-KEY",
1108 strlen ("UDP-IV-KEY"),
1109 NULL,
1110 0);
1111 memcpy (key, res, AES_KEY_SIZE);
1112 memcpy (iv, &res[AES_KEY_SIZE], AES_IV_SIZE);
1113}
1114
1115
1121static void
1123{
1124 sender->timeout =
1127}
1128
1129
1135static void
1137{
1138 receiver->timeout =
1141 receiver->timeout.abs_value_us);
1142}
1143
1144
1150static void
1152{
1153 struct GNUNET_TIME_Relative st;
1154 struct GNUNET_TIME_Relative rt;
1155 struct GNUNET_TIME_Relative delay;
1156 struct ReceiverAddress *receiver;
1157 struct SenderAddress *sender;
1158
1159 (void) cls;
1160 timeout_task = NULL;
1163 {
1165 if (0 != rt.rel_value_us)
1166 break;
1168 "Receiver timed out\n");
1170 }
1172 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1173 {
1174 if (GNUNET_YES != sender->sender_destroy_called)
1175 {
1177 if (0 != st.rel_value_us)
1178 break;
1179 sender_destroy (sender);
1180 }
1181 }
1182 delay = GNUNET_TIME_relative_min (rt, st);
1183 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1185}
1186
1187
1193static void
1195{
1197 sizeof(ss->cmac),
1198 GCRY_MD_SHA512,
1199 GCRY_MD_SHA256,
1200 "CMAC",
1201 strlen ("CMAC"),
1202 &ss->master,
1203 sizeof(ss->master),
1204 "UDP-CMAC",
1205 strlen ("UDP-CMAC"),
1206 NULL,
1207 0);
1208}
1209
1210
1219static void
1221 const void *plaintext,
1222 size_t plaintext_len)
1223{
1224 const struct GNUNET_MessageHeader *hdr = plaintext;
1225 const char *pos = plaintext;
1226
1227 while (ntohs (hdr->size) <= plaintext_len)
1228 {
1230 "# bytes given to core",
1231 ntohs (hdr->size),
1232 GNUNET_NO);
1234 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1237 &sender->target,
1238 hdr,
1240 NULL /* no flow control possible */
1241 ,
1242 NULL));
1243 /* move on to next message, if any */
1244 plaintext_len -= ntohs (hdr->size);
1245 if (plaintext_len < sizeof(*hdr))
1246 break;
1247 pos += ntohs (hdr->size);
1248 hdr = (const struct GNUNET_MessageHeader *) pos;
1249 // TODO for now..., we do not actually sen >1msg or have a way of telling
1250 // if we are done
1251 break;
1252 }
1254 "# bytes padding discarded",
1255 plaintext_len,
1256 GNUNET_NO);
1257}
1258
1259
1268static void
1269setup_cipher (const struct GNUNET_HashCode *msec,
1270 uint32_t serial,
1271 gcry_cipher_hd_t *cipher)
1272{
1273 char key[AES_KEY_SIZE];
1274 char iv[AES_IV_SIZE];
1275 int rc;
1276
1277 GNUNET_assert (0 ==
1278 gcry_cipher_open (cipher,
1279 GCRY_CIPHER_AES256 /* low level: go for speed */
1280 ,
1281 GCRY_CIPHER_MODE_GCM,
1282 0 /* flags */));
1283 get_iv_key (msec, serial, key, iv);
1284 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1285 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1286 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1287 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1288}
1289
1290
1303static int
1304try_decrypt (const struct SharedSecret *ss,
1305 const uint8_t *tag,
1306 uint32_t serial,
1307 const char *in_buf,
1308 size_t in_buf_size,
1309 char *out_buf)
1310{
1311 gcry_cipher_hd_t cipher;
1312
1313 setup_cipher (&ss->master, serial, &cipher);
1315 0 ==
1316 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1317 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1318 {
1319 gcry_cipher_close (cipher);
1321 "# AEAD authentication failures",
1322 1,
1323 GNUNET_NO);
1324 return GNUNET_SYSERR;
1325 }
1326 gcry_cipher_close (cipher);
1327 return GNUNET_OK;
1328}
1329
1330
1337static struct SharedSecret *
1339{
1340 struct SharedSecret *ss;
1341
1342 ss = GNUNET_new (struct SharedSecret);
1344 calculate_cmac (ss);
1345 return ss;
1346}
1347
1348
1355static struct SharedSecret *
1358 representative)
1359{
1360 struct SharedSecret *ss;
1361
1362 ss = GNUNET_new (struct SharedSecret);
1364 &ss->master);
1365 calculate_cmac (ss);
1366 return ss;
1367}
1368
1369
1377static struct SharedSecret *
1379 struct ReceiverAddress *receiver)
1380{
1381 struct SharedSecret *ss;
1382 struct GNUNET_HashCode k;
1383
1384 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key, ephemeral, &k);
1385 ss = GNUNET_new (struct SharedSecret);
1386 memcpy (&ss->master, &k, sizeof (k));
1387 calculate_cmac (ss);
1388 ss->receiver = receiver;
1389 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1390 receiver->num_secrets++;
1391 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1392 return ss;
1393}
1394
1395
1403static struct SharedSecret *
1406 representative,
1407 struct ReceiverAddress *receiver)
1408{
1409 struct SharedSecret *ss;
1410 struct GNUNET_HashCode k;
1411
1413 representative, &k);
1414 ss = GNUNET_new (struct SharedSecret);
1415 memcpy (&ss->master, &k, sizeof (k));
1416 calculate_cmac (ss);
1417 ss->receiver = receiver;
1418 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1419 receiver->num_secrets++;
1420 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1421 return ss;
1422}
1423
1424
1432static void
1434
1435
1443unsigned int
1444purge_secrets (struct SharedSecret *ss_list_tail)
1445{
1446 struct SharedSecret *pos;
1447 struct SharedSecret *ss_to_purge;
1448 unsigned int deleted = 0;
1449
1451 "Purging secrets.\n");
1452 pos = ss_list_tail;
1453 while (NULL != pos)
1454 {
1455 ss_to_purge = pos;
1456 pos = pos->prev;
1457
1458 // FIXME we may also want to purge old unacked.
1459 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1460 {
1461 secret_destroy (ss_to_purge);
1462 deleted++;
1463 }
1464 }
1466 "Finished purging all, deleted %u.\n", deleted);
1467 return deleted;
1468}
1469
1470
1471static void
1472add_acks (struct SharedSecret *ss, int acks_to_add)
1473{
1474
1475 struct ReceiverAddress *receiver = ss->receiver;
1476
1477 GNUNET_assert (NULL != ss);
1478 GNUNET_assert (NULL != receiver);
1479
1480 if (NULL == receiver->d_qh)
1481 {
1482 receiver->d_qh =
1484 &receiver->target,
1485 receiver->foreign_addr,
1486 receiver->d_mtu,
1487 acks_to_add,
1488 1, /* Priority */
1489 receiver->nt,
1491 receiver->d_mq);
1492 }
1493 else
1494 {
1496 receiver->d_qh,
1497 acks_to_add,
1498 1);
1499 }
1500
1502 "Tell transport we have %u more acks!\n",
1503 acks_to_add);
1504
1505 // Until here for alternativ 1
1506
1507 /* move ss to head to avoid discarding it anytime soon! */
1508
1509 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1510 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1511}
1512
1513
1524static int
1525handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1526{
1527 const struct UDPAck *ack = cls;
1528 struct ReceiverAddress *receiver = value;
1529 uint32_t acks_to_add;
1530 uint32_t allowed;
1531
1533 "in handle ack with cmac %s\n",
1534 GNUNET_h2s (&ack->cmac));
1535
1536 (void) key;
1537 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1538 {
1539 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1540 {
1541
1543 "Found matching cmac\n");
1544
1545 allowed = ntohl (ack->sequence_ack);
1546
1547 if (allowed <= ss->sequence_allowed)
1548 {
1550 "Ignoring ack, not giving us increased window\n.");
1551 return GNUNET_NO;
1552 }
1553 acks_to_add = (allowed - ss->sequence_allowed);
1554 GNUNET_assert (0 != acks_to_add);
1555 receiver->acks_available += (allowed - ss->sequence_allowed);
1556 ss->sequence_allowed = allowed;
1557 add_acks (ss, acks_to_add);
1559 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1560 allowed,
1561 acks_to_add,
1562 receiver->acks_available,
1563 GNUNET_h2s (&ss->master));
1564 return GNUNET_NO;
1565 }
1566 }
1568 "Matching cmac not found for ack!\n");
1569 return GNUNET_YES;
1570}
1571
1572
1581static void
1583{
1584 struct UDPAck ack;
1585 GNUNET_assert (NULL != ss->sender);
1587 "Considering SS UDPAck %s\n",
1588 GNUNET_i2s_full (&ss->sender->target));
1589
1591 "Sender has %u acks available.\n",
1592 ss->sender->acks_available);
1593 /* drop ancient KeyCacheEntries */
1594 while ((NULL != ss->kce_head) &&
1595 (MAX_SQN_DELTA <
1597 kce_destroy (ss->kce_tail);
1598
1599
1601 ack.header.size = htons (sizeof(ack));
1602 ack.sequence_ack = htonl (ss->sequence_allowed);
1603 ack.cmac = ss->cmac;
1605 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1607 ss->sequence_allowed,
1608 GNUNET_h2s (&(ss->master)));
1610 &ss->sender->target,
1612 &ack.header);
1613}
1614
1615
1616static void
1618{
1619 struct SharedSecret *ss = cls;
1620 ss->sender->kce_task = NULL;
1621
1623 "Precomputing %u keys for master %s\n",
1625 GNUNET_h2s (&(ss->master)));
1626 if ((ss->override_available_acks != GNUNET_YES) &&
1627 (KCN_TARGET < ss->sender->acks_available))
1628 return;
1629 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1630 kce_generate (ss, ++ss->sequence_allowed);
1631
1636 if (KCN_TARGET > ss->sender->acks_available)
1637 {
1641 ss);
1642 return;
1643 }
1645 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1649 consider_ss_ack (ss);
1650}
1651
1652
1661static void
1663 const void *buf,
1664 size_t buf_size)
1665{
1666 const struct GNUNET_MessageHeader *hdr;
1667 const struct UDPAck *ack;
1668 const struct UDPRekey *rekey;
1669 struct SharedSecret *ss_rekey;
1670 const char *buf_pos = buf;
1671 size_t bytes_remaining = buf_size;
1672 uint16_t type;
1673
1674 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1675 if (sizeof(*hdr) > bytes_remaining)
1676 {
1677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1678 return; /* no data left */
1679 }
1681 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1682 (unsigned long long) bytes_remaining,
1683 ntohs (hdr->size),
1684 sizeof(*hdr),
1685 ntohs (hdr->type));
1686 if (ntohs (hdr->size) > bytes_remaining)
1687 return; /* buffer too short for indicated message length */
1688 type = ntohs (hdr->type);
1689 switch (type)
1690 {
1692 rekey = (struct UDPRekey*) buf_pos;
1693 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1694 ss_rekey->sender = sender;
1695 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1696 sender->num_secrets++;
1698 "Received rekey secret with cmac %s\n",
1699 GNUNET_h2s (&(ss_rekey->cmac)));
1701 "Received secret with master %s.\n",
1702 GNUNET_h2s (&(ss_rekey->master)));
1704 "We have %u sequence_allowed.\n",
1705 ss_rekey->sequence_allowed);
1707 "We have a sender %p\n",
1708 ss_rekey->sender);
1710 "We have %u acks available.\n",
1711 ss_rekey->sender->acks_available);
1713 "# rekeying successful",
1714 1,
1715 GNUNET_NO);
1718 // FIXME
1719 kce_generate_cb (ss_rekey);
1720 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1721 WORKING_QUEUE_INTERVALL,
1722 kce_generate_cb,
1723 ss_rekey);*/
1724 // FIXME: Theoretically, this could be an Ack
1725 buf_pos += ntohs (hdr->size);
1726 bytes_remaining -= ntohs (hdr->size);
1727 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1728 if (0 == purge_secrets (sender->ss_tail))
1729 {
1730 // No secret purged. Delete oldest.
1731 if (sender->num_secrets > MAX_SECRETS)
1732 {
1733 secret_destroy (sender->ss_tail);
1734 }
1735 }
1736 break;
1738 /* lookup master secret by 'cmac', then update sequence_max */
1739 ack = (struct UDPAck*) buf_pos;
1741 &sender->key,
1742 &handle_ack,
1743 (void *) ack);
1744 /* There could be more messages after the ACK, handle those as well */
1745 buf_pos += ntohs (hdr->size);
1746 bytes_remaining -= ntohs (hdr->size);
1747 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1748 break;
1749
1751 /* skip padding */
1752 break;
1753
1754 default:
1755 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1756 }
1757 return;
1758}
1759
1760
1768static void
1769decrypt_box (const struct UDPBox *box,
1770 size_t box_len,
1771 struct KeyCacheEntry *kce)
1772{
1773 struct SharedSecret *ss = kce->ss;
1774 struct SharedSecret *ss_c = ss->sender->ss_tail;
1775 struct SharedSecret *ss_tmp;
1776 int ss_destroyed = 0;
1777 char out_buf[box_len - sizeof(*box)];
1778
1779 GNUNET_assert (NULL != ss->sender);
1780 if (GNUNET_OK != try_decrypt (ss,
1781 box->gcm_tag,
1782 kce->sequence_number,
1783 (const char *) &box[1],
1784 sizeof(out_buf),
1785 out_buf))
1786 {
1787 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1789 "# Decryption failures with valid KCE",
1790 1,
1791 GNUNET_NO);
1792 kce_destroy (kce);
1793 ss->sender->acks_available--;
1794 return;
1795 }
1796 kce_destroy (kce);
1797 kce = NULL;
1798 ss->bytes_sent += box_len;
1799 ss->sender->acks_available--;
1800 ss->sequence_used++;
1802 "# bytes decrypted with BOX",
1803 sizeof(out_buf),
1804 GNUNET_NO);
1806 "# messages decrypted with BOX",
1807 1,
1808 GNUNET_NO);
1810 "decrypted UDPBox with kid %s\n",
1811 GNUNET_sh2s (&box->kid));
1812 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1813
1814 while (NULL != ss_c)
1815 {
1816 if (ss_c->bytes_sent >= rekey_max_bytes)
1817 {
1819 "Removing SS because rekey bytes reached.\n");
1820 ss_tmp = ss_c->prev;
1821 if (ss == ss_c)
1822 ss_destroyed = 1;
1823 secret_destroy (ss_c);
1824 ss_c = ss_tmp;
1825 continue;
1826 }
1827 ss_c = ss_c->prev;
1828 }
1829 if (1 == ss_destroyed)
1830 return;
1832 "Sender has %u ack left.\n",
1833 ss->sender->acks_available);
1834 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1835 (NULL == ss->sender->kce_task) &&
1837 {
1839 "Sender has %u ack left which is under threshold.\n",
1840 ss->sender->acks_available);
1844 ss);
1845 }
1846}
1847
1848
1853{
1857 const struct sockaddr *address;
1858
1862 socklen_t address_len;
1863
1868};
1869
1870
1882static struct SenderAddress *
1884 const struct sockaddr *address,
1885 socklen_t address_len)
1886{
1887 struct SenderAddress *sender;
1888 struct GNUNET_HashContext *hsh;
1889 struct GNUNET_HashCode sender_key;
1890
1892 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1893 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1894 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1895
1896 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1897 if (NULL != sender)
1898 {
1900 return sender;
1901 }
1902 sender = GNUNET_new (struct SenderAddress);
1903 sender->key = sender_key;
1904 sender->target = *target;
1905 sender->address = GNUNET_memdup (address, address_len);
1906 sender->address_len = address_len;
1908 senders,
1909 &sender->key,
1910 sender,
1913 "# senders active",
1915 GNUNET_NO);
1916 sender->timeout =
1919 sender,
1920 sender->timeout.abs_value_us);
1921 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
1922 if (NULL == timeout_task)
1924 return sender;
1925}
1926
1927
1935static int
1937 const struct UDPConfirmation *uc)
1938{
1939 struct UdpHandshakeSignature uhs;
1940
1941 uhs.purpose.purpose = htonl (
1943 uhs.purpose.size = htonl (sizeof(uhs));
1944 uhs.sender = uc->sender;
1945 uhs.receiver = my_identity;
1946 uhs.ephemeral = *ephemeral;
1947 uhs.monotonic_time = uc->monotonic_time;
1950 &uhs,
1951 &uc->sender_sig,
1952 &uc->sender.public_key);
1953}
1954
1955
1964static char *
1965sockaddr_to_udpaddr_string (const struct sockaddr *address,
1966 socklen_t address_len)
1967{
1968 char *ret;
1969
1970 switch (address->sa_family)
1971 {
1972 case AF_INET:
1974 "%s-%s",
1976 GNUNET_a2s (address, address_len));
1977 break;
1978
1979 case AF_INET6:
1981 "%s-%s",
1983 GNUNET_a2s (address, address_len));
1984 break;
1985
1986 default:
1987 GNUNET_assert (0);
1988 }
1989 return ret;
1990}
1991
1992
1998static void
1999sock_read (void *cls)
2000{
2001 struct sockaddr_storage sa;
2002 struct sockaddr_in *addr_verify;
2003 socklen_t salen = sizeof(sa);
2004 char buf[UINT16_MAX];
2005 ssize_t rcvd;
2006
2007 (void) cls;
2009 udp_sock,
2010 &sock_read,
2011 NULL);
2012 while (1)
2013 {
2015 buf,
2016 sizeof(buf),
2017 (struct sockaddr *) &sa,
2018 &salen);
2019 if (-1 == rcvd)
2020 {
2021 struct sockaddr *addr = (struct sockaddr*) &sa;
2022
2023 if (EAGAIN == errno)
2024 break; // We are done reading data
2026 "Failed to recv from %s family %d failed sock %p\n",
2027 GNUNET_a2s ((struct sockaddr*) &sa,
2028 sizeof (*addr)),
2029 addr->sa_family,
2030 udp_sock);
2032 return;
2033 }
2035 "Read %llu bytes\n",
2036 (unsigned long long) rcvd);
2037 if (0 == rcvd)
2038 {
2039 GNUNET_break_op (0);
2041 "Read 0 bytes from UDP socket\n");
2042 return;
2043 }
2044
2045 /* first, see if it is a UDPBox */
2046 if (rcvd > sizeof(struct UDPBox))
2047 {
2048 const struct UDPBox *box;
2049 struct KeyCacheEntry *kce;
2050
2051 box = (const struct UDPBox *) buf;
2053 if (NULL != kce)
2054 {
2056 "Found KCE with kid %s\n",
2057 GNUNET_sh2s (&box->kid));
2058 decrypt_box (box, (size_t) rcvd, kce);
2059 continue;
2060 }
2061 }
2062
2063 /* next, check if it is a broadcast */
2064 if (sizeof(struct UDPBroadcast) == rcvd)
2065 {
2066 const struct UDPBroadcast *ub;
2067 struct UdpBroadcastSignature uhs;
2068 struct GNUNET_PeerIdentity sender;
2069
2070 addr_verify = GNUNET_memdup (&sa, salen);
2071 addr_verify->sin_port = 0;
2073 "received UDPBroadcast from %s\n",
2074 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2075 ub = (const struct UDPBroadcast *) buf;
2076 uhs.purpose.purpose = htonl (
2078 uhs.purpose.size = htonl (sizeof(uhs));
2079 uhs.sender = ub->sender;
2080 sender = ub->sender;
2081 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2083 {
2085 "Received our own broadcast\n");
2086 GNUNET_free (addr_verify);
2087 continue;
2088 }
2090 "checking UDPBroadcastSignature for %s\n",
2091 GNUNET_i2s (&sender));
2092 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2093 &uhs.h_address);
2094 if (GNUNET_OK ==
2097 &uhs,
2098 &ub->sender_sig,
2099 &ub->sender.public_key))
2100 {
2101 char *addr_s;
2103
2104 addr_s =
2105 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2106 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2107 /* use our own mechanism to determine network type */
2108 nt =
2109 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2111 "validating address %s received from UDPBroadcast\n",
2112 GNUNET_i2s (&sender));
2114 GNUNET_free (addr_s);
2115 GNUNET_free (addr_verify);
2116 continue;
2117 }
2118 else
2119 {
2121 "VerifyingPeer %s is verifying UDPBroadcast\n",
2124 "Verifying UDPBroadcast from %s failed\n",
2125 GNUNET_i2s (&ub->sender));
2126 }
2127 GNUNET_free (addr_verify);
2128 /* continue with KX, mostly for statistics... */
2129 }
2130
2131
2132 /* finally, test if it is a KX */
2133 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2134 {
2136 "# messages dropped (no kid, too small for KX)",
2137 1,
2138 GNUNET_NO);
2139 continue;
2140 }
2142 "Got KX\n");
2143 {
2144 const struct InitialKX *kx;
2145 struct SharedSecret *ss;
2146 char pbuf[rcvd - sizeof(struct InitialKX)];
2147 const struct UDPConfirmation *uc;
2148 struct SenderAddress *sender;
2149
2150 kx = (const struct InitialKX *) buf;
2153 "Before DEC\n");
2154
2155 if (GNUNET_OK != try_decrypt (ss,
2156 kx->gcm_tag,
2157 0,
2158 &buf[sizeof(*kx)],
2159 sizeof(pbuf),
2160 pbuf))
2161 {
2163 "Unable to decrypt tag, dropping...\n");
2164 GNUNET_free (ss);
2166 stats,
2167 "# messages dropped (no kid, AEAD decryption failed)",
2168 1,
2169 GNUNET_NO);
2170 continue;
2171 }
2173 "Before VERIFY\n");
2174
2175 uc = (const struct UDPConfirmation *) pbuf;
2176
2177 struct GNUNET_CRYPTO_EcdhePublicKey pub_ephemeral;
2178 GNUNET_CRYPTO_ecdhe_elligator_decoding (&pub_ephemeral, NULL,
2179 &kx->representative);
2180 if (GNUNET_OK != verify_confirmation (&pub_ephemeral, uc)) // TODO: need ephemeral instead of representative
2181 {
2182 GNUNET_break_op (0);
2183 GNUNET_free (ss);
2185 "# messages dropped (sender signature invalid)",
2186 1,
2187 GNUNET_NO);
2188 continue;
2189 }
2191 "Before SETUP_SENDER\n");
2192
2193 calculate_cmac (ss);
2194 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2195 ss->sender = sender;
2196 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2197 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2198 (NULL == ss->sender->kce_task) &&
2200 {
2201 // 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.
2205 ss);
2206 }
2207 sender->num_secrets++;
2208 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2210 "# messages decrypted without BOX",
2211 1,
2212 GNUNET_NO);
2213 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2214 if (0 == purge_secrets (sender->ss_tail))
2215 {
2216 // No secret purged. Delete oldest.
2217 if (sender->num_secrets > MAX_SECRETS)
2218 {
2219 secret_destroy (sender->ss_tail);
2220 }
2221 }
2222 }
2223 }
2224}
2225
2226
2234static struct sockaddr *
2235udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2236{
2237 struct sockaddr *in;
2238 unsigned int port;
2239 char dummy[2];
2240 char *colon;
2241 char *cp;
2242
2243 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2244 {
2245 /* interpreting value as just a PORT number */
2246 if (port > UINT16_MAX)
2247 {
2249 "BINDTO specification `%s' invalid: value too large for port\n",
2250 bindto);
2251 return NULL;
2252 }
2253 if (GNUNET_YES == disable_v6)
2254 {
2255 struct sockaddr_in *i4;
2256
2257 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2258 i4->sin_family = AF_INET;
2259 i4->sin_port = htons ((uint16_t) port);
2260 *sock_len = sizeof(struct sockaddr_in);
2261 in = (struct sockaddr *) i4;
2262 }
2263 else
2264 {
2265 struct sockaddr_in6 *i6;
2266
2267 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2268 i6->sin6_family = AF_INET6;
2269 i6->sin6_port = htons ((uint16_t) port);
2270 *sock_len = sizeof(struct sockaddr_in6);
2271 in = (struct sockaddr *) i6;
2272 }
2273 return in;
2274 }
2275 cp = GNUNET_strdup (bindto);
2276 colon = strrchr (cp, ':');
2277 if (NULL != colon)
2278 {
2279 /* interpret value after colon as port */
2280 *colon = '\0';
2281 colon++;
2282 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2283 {
2284 /* interpreting value as just a PORT number */
2285 if (port > UINT16_MAX)
2286 {
2288 "BINDTO specification `%s' invalid: value too large for port\n",
2289 bindto);
2290 GNUNET_free (cp);
2291 return NULL;
2292 }
2293 }
2294 else
2295 {
2296 GNUNET_log (
2298 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2299 bindto);
2300 GNUNET_free (cp);
2301 return NULL;
2302 }
2303 }
2304 else
2305 {
2306 /* interpret missing port as 0, aka pick any free one */
2307 port = 0;
2308 }
2309 {
2310 /* try IPv4 */
2311 struct sockaddr_in v4;
2312
2313 memset (&v4, 0, sizeof(v4));
2314 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2315 {
2316 v4.sin_family = AF_INET;
2317 v4.sin_port = htons ((uint16_t) port);
2318#if HAVE_SOCKADDR_IN_SIN_LEN
2319 v4.sin_len = sizeof(struct sockaddr_in);
2320#endif
2321 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2322 *sock_len = sizeof(struct sockaddr_in);
2323 GNUNET_free (cp);
2324 return in;
2325 }
2326 }
2327 {
2328 /* try IPv6 */
2329 struct sockaddr_in6 v6;
2330 const char *start;
2331
2332 memset (&v6, 0, sizeof(v6));
2333 start = cp;
2334 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2335 {
2336 start++; /* skip over '[' */
2337 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2338 }
2339 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2340 {
2341 v6.sin6_family = AF_INET6;
2342 v6.sin6_port = htons ((uint16_t) port);
2343#if HAVE_SOCKADDR_IN_SIN_LEN
2344 v6.sin6_len = sizeof(struct sockaddr_in6);
2345#endif
2346 in = GNUNET_memdup (&v6, sizeof(v6));
2347 *sock_len = sizeof(v6);
2348 GNUNET_free (cp);
2349 return in;
2350 }
2351 }
2352 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2353 GNUNET_free (cp);
2354 return NULL;
2355}
2356
2357
2365static void
2366do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2367{
2368 char pad[pad_size];
2369
2371 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2372 {
2373 struct GNUNET_MessageHeader hdr =
2374 { .size = htons (sizeof(pad)),
2376
2377 memcpy (pad, &hdr, sizeof(hdr));
2378 }
2380 0 ==
2381 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2382}
2383
2384
2385static void
2388 struct GNUNET_MQ_Handle *mq)
2389{
2390 uint16_t msize = ntohs (msg->size);
2391 struct UdpHandshakeSignature uhs;
2392 struct UDPConfirmation uc;
2393 struct InitialKX kx;
2394 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2395 size_t dpos;
2396 gcry_cipher_hd_t out_cipher;
2397 struct SharedSecret *ss;
2398
2399 if (msize > receiver->kx_mtu)
2400 {
2401 GNUNET_break (0);
2402 if (GNUNET_YES != receiver->receiver_destroy_called)
2404 return;
2405 }
2407
2408 /* setup key material */
2412 &repr);
2413
2414 if (0 == purge_secrets (receiver->ss_tail))
2415 {
2416 // No secret purged. Delete oldest.
2417 if (receiver->num_secrets > MAX_SECRETS)
2418 {
2419 secret_destroy (receiver->ss_tail);
2420 }
2421 }
2422
2423 setup_cipher (&ss->master, 0, &out_cipher);
2424 /* compute 'uc' */
2425 uc.sender = my_identity;
2426 uc.monotonic_time =
2428 uhs.purpose.purpose = htonl (
2430 uhs.purpose.size = htonl (sizeof(uhs));
2431 uhs.sender = my_identity;
2432 uhs.receiver = receiver->target;
2433 uhs.monotonic_time = uc.monotonic_time;
2435 &uhs,
2436 &uc.sender_sig);
2437 /* Leave space for kx */
2438 dpos = sizeof(kx);
2439 /* Append encrypted uc to dgram */
2440 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2441 &dgram[dpos],
2442 sizeof(uc),
2443 &uc,
2444 sizeof(uc)));
2445 dpos += sizeof(uc);
2446 /* Append encrypted payload to dgram */
2448 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2449 dpos += msize;
2450 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2451 /* Datagram starts with kx */
2452 kx.representative = repr;
2454 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2455 gcry_cipher_close (out_cipher);
2456 memcpy (dgram, &kx, sizeof(kx));
2458 dgram,
2459 sizeof(dgram),
2460 receiver->address,
2461 receiver->address_len))
2462 {
2465 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2466 msize,
2467 GNUNET_a2s (receiver->address,
2468 receiver->address_len),
2469 receiver->address->sa_family,
2470 udp_sock);
2473 return;
2474 }
2476 "Sending KX with payload size %u to %s\n",
2477 msize,
2478 GNUNET_a2s (receiver->address,
2479 receiver->address_len));
2481}
2482
2483
2492static void
2494 const struct GNUNET_MessageHeader *msg,
2495 void *impl_state)
2496{
2497 struct ReceiverAddress *receiver = impl_state;
2498
2499 GNUNET_assert (mq == receiver->kx_mq);
2501}
2502
2503
2504static void
2506 UDPRekey *rekey)
2507{
2508 struct SharedSecret *ss_rekey;
2509
2511 /* setup key material */
2512 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2513 receiver);
2514 ss_rekey->sequence_allowed = 0;
2516 "Setup secret with k = %s\n",
2517 GNUNET_h2s (&(ss_rekey->master)));
2519 "Setup secret with H(k) = %s\n",
2520 GNUNET_h2s (&(ss_rekey->cmac)));
2521
2522 /* Append encrypted payload to dgram */
2524 rekey->header.size = htons (sizeof (struct UDPRekey));
2525}
2526
2527
2536static void
2538 const struct GNUNET_MessageHeader *msg,
2539 void *impl_state)
2540{
2541 struct ReceiverAddress *receiver = impl_state;
2542 struct UDPRekey rekey;
2543 struct SharedSecret *ss;
2544 int inject_rekey = GNUNET_NO;
2545 uint16_t msize = ntohs (msg->size);
2546
2547 GNUNET_assert (mq == receiver->d_mq);
2548 if ((msize > receiver->d_mtu) ||
2549 (0 == receiver->acks_available))
2550 {
2552 "msize: %u, mtu: %llu, acks: %u\n",
2553 (unsigned int) msize,
2554 (unsigned long long) receiver->d_mtu,
2555 receiver->acks_available);
2556
2557 GNUNET_break (0);
2558 if (GNUNET_YES != receiver->receiver_destroy_called)
2560 return;
2561 }
2563
2564 if (receiver->num_secrets > MAX_SECRETS)
2565 {
2566 if ((0 == purge_secrets (receiver->ss_tail)) &&
2567 (NULL != receiver->ss_tail))
2568 {
2569 // No secret purged. Delete oldest.
2570 secret_destroy (receiver->ss_tail);
2571 }
2572 }
2573 /* begin "BOX" encryption method, scan for ACKs from tail! */
2574 ss = receiver->ss_tail;
2575 struct SharedSecret *ss_tmp;
2576 while (NULL != ss)
2577 {
2578 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2580 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2581 GNUNET_h2s (&ss->master), ss->sequence_used,
2582 ss->sequence_allowed, ss->bytes_sent);
2583 if (ss->sequence_used >= ss->sequence_allowed)
2584 {
2585 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2586 // "Skipping ss because no acks to use.\n");
2587 ss = ss->prev;
2588 continue;
2589 }
2590 if (ss->bytes_sent >= rekey_max_bytes)
2591 {
2593 "Skipping ss because rekey bytes reached.\n");
2594 // FIXME cleanup ss with too many bytes sent!
2595 ss_tmp = ss->prev;
2596 secret_destroy (ss);
2597 ss = ss_tmp;
2598 continue;
2599 }
2600 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2601 {
2602 if (ss->rekey_initiated == GNUNET_NO)
2603 {
2605 "Injecting rekey for ss with byte sent %lu\n",
2606 (unsigned long) ss->bytes_sent);
2607 create_rekey (receiver, ss, &rekey);
2609 payload_len += sizeof (rekey);
2611 }
2612 }
2613 if (0 < ss->sequence_used)
2615 "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n",
2616 GNUNET_h2s (&ss->master),
2617 ss->sequence_used,
2618 ss->sequence_allowed);
2619
2620 char dgram[payload_len];
2621 struct UDPBox *box;
2622 gcry_cipher_hd_t out_cipher;
2623 size_t dpos;
2624
2625 box = (struct UDPBox *) dgram;
2626 ss->sequence_used++;
2627 get_kid (&ss->master, ss->sequence_used, &box->kid);
2628 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2629 /* Append encrypted payload to dgram */
2630 dpos = sizeof(struct UDPBox);
2631 if (GNUNET_YES == inject_rekey)
2632 {
2634 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2635 &rekey, sizeof (rekey)));
2636 dpos += sizeof (rekey);
2637 }
2639 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2640 dpos += msize;
2641 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2642 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2643 box->gcm_tag,
2644 sizeof(box->gcm_tag)));
2645 gcry_cipher_close (out_cipher);
2646
2648 dgram,
2649 payload_len, // FIXME why always send sizeof dgram?
2650 receiver->address,
2651 receiver->address_len))
2652 {
2655 "Sending UDPBox to %s family %d failed sock %p failed\n",
2656 GNUNET_a2s (receiver->address,
2657 receiver->address_len),
2658 receiver->address->sa_family,
2659 udp_sock);
2661 return;
2662 }
2664 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent\n",
2665 msize,
2666 receiver->acks_available,
2667 (unsigned long) ss->bytes_sent);
2668 ss->bytes_sent += sizeof (dgram);
2669 receiver->acks_available--;
2671 return;
2672 }
2674 "No suitable ss found, sending as KX...\n");
2676}
2677
2678
2687static void
2688mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2689{
2690 struct ReceiverAddress *receiver = impl_state;
2692 "Default MQ destroyed\n");
2693 if (mq == receiver->d_mq)
2694 {
2695 receiver->d_mq = NULL;
2696 if (GNUNET_YES != receiver->receiver_destroy_called)
2698 }
2699}
2700
2701
2710static void
2711mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2712{
2713 struct ReceiverAddress *receiver = impl_state;
2715 "KX MQ destroyed\n");
2716 if (mq == receiver->kx_mq)
2717 {
2718 receiver->kx_mq = NULL;
2719 if (GNUNET_YES != receiver->receiver_destroy_called)
2721 }
2722}
2723
2724
2731static void
2732mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2733{
2734 /* Cancellation is impossible with UDP; bail */
2735 GNUNET_assert (0);
2736}
2737
2738
2748static void
2749mq_error (void *cls, enum GNUNET_MQ_Error error)
2750{
2751 struct ReceiverAddress *receiver = cls;
2752
2754 "MQ error in queue to %s: %d\n",
2755 GNUNET_i2s (&receiver->target),
2756 (int) error);
2758}
2759
2760
2768static void
2770{
2771 size_t base_mtu;
2772
2773 switch (receiver->address->sa_family)
2774 {
2775 case AF_INET:
2776 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
2777 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
2778 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2779 break;
2780
2781 case AF_INET6:
2782 base_mtu = 1280 /* Minimum MTU required by IPv6 */
2783 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
2784 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2785 break;
2786
2787 default:
2788 GNUNET_assert (0);
2789 break;
2790 }
2791 /* MTU based on full KX messages */
2792 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
2793 - sizeof(struct UDPConfirmation); /* 104 */
2794 /* MTU based on BOXed messages */
2795 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
2796
2798 "Setting up MQs and QHs\n");
2799 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
2800 1404 (IPv4 + Box) bytes, depending on circumstances... */
2801 if (NULL == receiver->kx_mq)
2804 &mq_cancel,
2805 receiver,
2806 NULL,
2807 &mq_error,
2808 receiver);
2809 if (NULL == receiver->d_mq)
2811 &mq_destroy_d,
2812 &mq_cancel,
2813 receiver,
2814 NULL,
2815 &mq_error,
2816 receiver);
2817
2818 receiver->kx_qh =
2820 &receiver->target,
2821 receiver->foreign_addr,
2822 receiver->kx_mtu,
2824 0, /* Priority */
2825 receiver->nt,
2827 receiver->kx_mq);
2828}
2829
2830
2849static int
2850mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2851{
2852 struct ReceiverAddress *receiver;
2853 struct GNUNET_HashContext *hsh;
2854 struct GNUNET_HashCode receiver_key;
2855 const char *path;
2856 struct sockaddr *in;
2857 socklen_t in_len;
2858
2859 if (0 != strncmp (address,
2861 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2862 {
2863 GNUNET_break_op (0);
2864 return GNUNET_SYSERR;
2865 }
2866 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2867 in = udp_address_to_sockaddr (path, &in_len);
2868
2869 if (NULL == in)
2870 {
2872 "Failed to setup UDP socket address\n");
2873 return GNUNET_SYSERR;
2874 }
2875 if ((AF_INET6 == in->sa_family) &&
2877 {
2879 "IPv6 disabled, skipping %s\n", address);
2880 GNUNET_free (in);
2881 return GNUNET_SYSERR;
2882 }
2883
2885 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2886 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2887 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2888
2890 if (NULL != receiver)
2891 {
2893 "receiver %s already exist or is being connected to\n",
2894 address);
2895 return GNUNET_NO;
2896 }
2897
2899 receiver->key = receiver_key;
2900 receiver->address = in;
2901 receiver->address_len = in_len;
2902 receiver->target = *peer;
2903 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2905 receivers,
2906 &receiver->key,
2907 receiver,
2910 "Added %s to receivers\n",
2911 GNUNET_i2s_full (&receiver->target));
2912 receiver->timeout =
2915 receiver,
2916 receiver->timeout.abs_value_us);
2918 "# receivers active",
2920 GNUNET_NO);
2921 receiver->foreign_addr =
2922 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2924 if (NULL == timeout_task)
2926 return GNUNET_OK;
2927}
2928
2929
2938static int
2940 const struct GNUNET_HashCode *target,
2941 void *value)
2942{
2943 struct ReceiverAddress *receiver = value;
2944
2945 (void) cls;
2946 (void) target;
2948 return GNUNET_OK;
2949}
2950
2951
2960static int
2962 const struct GNUNET_HashCode *target,
2963 void *value)
2964{
2965 struct SenderAddress *sender = value;
2966
2967 (void) cls;
2968 (void) target;
2969
2970
2971 sender_destroy (sender);
2972 return GNUNET_OK;
2973}
2974
2975
2981static void
2982do_shutdown (void *cls)
2983{
2985 "do_shutdown\n");
2986 if (NULL != nat)
2987 {
2989 nat = NULL;
2990 }
2991 while (NULL != bi_head)
2993 if (NULL != broadcast_task)
2994 {
2996 broadcast_task = NULL;
2997 }
2998 if (NULL != timeout_task)
2999 {
3001 timeout_task = NULL;
3002 }
3003 if (NULL != read_task)
3004 {
3006 read_task = NULL;
3007 }
3008 if (NULL != udp_sock)
3009 {
3012 udp_sock = NULL;
3013 }
3016 NULL);
3020 NULL);
3025 if (NULL != timeout_task)
3026 {
3028 timeout_task = NULL;
3029 }
3030 if (NULL != ch)
3031 {
3033 ch = NULL;
3034 }
3035 if (NULL != ah)
3036 {
3038 ah = NULL;
3039 }
3040 if (NULL != stats)
3041 {
3043 stats = NULL;
3044 }
3045 if (NULL != my_private_key)
3046 {
3048 my_private_key = NULL;
3049 }
3050 if (NULL != is)
3051 {
3053 is = NULL;
3054 }
3056 "do_shutdown finished\n");
3057}
3058
3059
3061{
3062 const struct UDPAck *ack;
3063
3065};
3066
3067static int
3068handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3069{
3070 struct ReceiverAddress *receiver = value;
3071 struct AckInfo *ai = cls;
3072
3073 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3074 {
3075 return GNUNET_YES;
3076 }
3077 handle_ack ((void*) ai->ack, key, receiver);
3078 return GNUNET_YES;
3079}
3080
3081
3091static void
3092enc_notify_cb (void *cls,
3093 const struct GNUNET_PeerIdentity *sender,
3094 const struct GNUNET_MessageHeader *msg)
3095{
3096 struct AckInfo ai;
3097
3098 (void) cls;
3100 "Storing UDPAck received from backchannel from %s\n",
3103 (ntohs (msg->size) != sizeof(struct UDPAck)))
3104 {
3105 GNUNET_break_op (0);
3106 return;
3107 }
3108 ai.ack = (const struct UDPAck *) msg;
3109 ai.sender = sender;
3112 &ai);
3113}
3114
3115
3129static void
3131 void **app_ctx,
3132 int add_remove,
3134 const struct sockaddr *addr,
3135 socklen_t addrlen)
3136{
3137 char *my_addr;
3139
3140 if (GNUNET_YES == add_remove)
3141 {
3143
3144 GNUNET_asprintf (&my_addr,
3145 "%s-%s",
3147 GNUNET_a2s (addr, addrlen));
3148 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3149 ai =
3151 my_addr,
3152 nt,
3154 GNUNET_free (my_addr);
3155 *app_ctx = ai;
3156 }
3157 else
3158 {
3159 ai = *app_ctx;
3161 *app_ctx = NULL;
3162 }
3163}
3164
3165
3171static void
3172ifc_broadcast (void *cls)
3173{
3174 struct BroadcastInterface *bi = cls;
3175 struct GNUNET_TIME_Relative delay;
3176
3177 delay = BROADCAST_FREQUENCY;
3178 delay.rel_value_us =
3180 bi->broadcast_task =
3182
3183 switch (bi->sa->sa_family)
3184 {
3185 case AF_INET: {
3186 static int yes = 1;
3187 static int no = 0;
3188 ssize_t sent;
3189
3190 if (GNUNET_OK !=
3192 SOL_SOCKET,
3193 SO_BROADCAST,
3194 &yes,
3195 sizeof(int)))
3197 "setsockopt");
3199 "creating UDPBroadcast from %s\n",
3200 GNUNET_i2s (&(bi->bcm.sender)));
3202 "sending UDPBroadcast to add %s\n",
3203 GNUNET_a2s (bi->ba, bi->salen));
3205 &bi->bcm,
3206 sizeof(bi->bcm),
3207 bi->ba,
3208 bi->salen);
3209 if (-1 == sent)
3211 "sendto");
3213 SOL_SOCKET,
3214 SO_BROADCAST,
3215 &no,
3216 sizeof(int)))
3218 "setsockopt");
3219 break;
3220 }
3221
3222 case AF_INET6: {
3223 ssize_t sent;
3224 struct sockaddr_in6 dst;
3225
3226 dst.sin6_family = AF_INET6;
3227 dst.sin6_port = htons (my_port);
3228 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3229 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3230
3232 "sending UDPBroadcast\n");
3234 &bi->bcm,
3235 sizeof(bi->bcm),
3236 (const struct sockaddr *) &dst,
3237 sizeof(dst));
3238 if (-1 == sent)
3240 break;
3241 }
3242
3243 default:
3244 GNUNET_break (0);
3245 break;
3246 }
3247}
3248
3249
3264static int
3265iface_proc (void *cls,
3266 const char *name,
3267 int isDefault,
3268 const struct sockaddr *addr,
3269 const struct sockaddr *broadcast_addr,
3270 const struct sockaddr *netmask,
3271 socklen_t addrlen)
3272{
3273 struct BroadcastInterface *bi;
3274 enum GNUNET_NetworkType network;
3275 struct UdpBroadcastSignature ubs;
3276
3277 (void) cls;
3278 (void) netmask;
3279 if (NULL == addr)
3280 return GNUNET_YES; /* need to know our address! */
3281 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3282 if (GNUNET_NT_LOOPBACK == network)
3283 {
3284 /* Broadcasting on loopback does not make sense */
3285 return GNUNET_YES;
3286 }
3287 for (bi = bi_head; NULL != bi; bi = bi->next)
3288 {
3289 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3290 {
3291 bi->found = GNUNET_YES;
3292 return GNUNET_OK;
3293 }
3294 }
3295
3296 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3297 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3298 if ((AF_INET6 == addr->sa_family) && (GNUNET_YES != have_v6_socket))
3299 return GNUNET_OK; /* not using IPv6 */
3300
3301 bi = GNUNET_new (struct BroadcastInterface);
3302 bi->sa = GNUNET_memdup (addr,
3303 addrlen);
3304 if ( (NULL != broadcast_addr) &&
3305 (addrlen == sizeof (struct sockaddr_in)) )
3306 {
3307 struct sockaddr_in *ba;
3308
3309 ba = GNUNET_memdup (broadcast_addr,
3310 addrlen);
3311 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3312 bi->ba = (struct sockaddr *) ba;
3313 }
3314 bi->salen = addrlen;
3315 bi->found = GNUNET_YES;
3316 bi->bcm.sender = my_identity;
3317 ubs.purpose.purpose = htonl (
3319 ubs.purpose.size = htonl (sizeof(ubs));
3320 ubs.sender = my_identity;
3322 "creating UDPBroadcastSignature for %s\n",
3323 GNUNET_a2s (addr, addrlen));
3324 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3326 &ubs,
3327 &bi->bcm.sender_sig);
3328 if (NULL != bi->ba)
3329 {
3332 }
3333 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3334 {
3335 /* Create IPv6 multicast request */
3336 const struct sockaddr_in6 *s6 =
3337 (const struct sockaddr_in6 *) broadcast_addr;
3338
3340 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3341
3342 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3343 *
3344 * IPV6_JOIN_GROUP
3345 *
3346 * Join a multicast group on a specified local interface. If the
3347 * interface index is specified as 0, the kernel chooses the local
3348 * interface. For example, some kernels look up the multicast
3349 * group in the normal IPv6 routing table and using the resulting
3350 * interface; we do this for each interface, so no need to use
3351 * zero (anymore...).
3352 */
3353 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3354
3355 /* Join the multicast group */
3357 IPPROTO_IPV6,
3358 IPV6_JOIN_GROUP,
3359 &bi->mcreq,
3360 sizeof(bi->mcreq)))
3361 {
3363 }
3364 }
3365 return GNUNET_OK;
3366}
3367
3368
3374static void
3375do_broadcast (void *cls)
3376{
3377 struct BroadcastInterface *bin;
3378
3379 (void) cls;
3380 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3381 bi->found = GNUNET_NO;
3383 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3384 {
3385 bin = bi->next;
3386 if (GNUNET_NO == bi->found)
3387 bi_destroy (bi);
3388 }
3390 &do_broadcast,
3391 NULL);
3392}
3393
3394
3395static void
3397 const struct sockaddr *addr,
3398 socklen_t addrlen)
3399{
3400 /* FIXME: support reversal: #5529 */
3402 "No connection reversal implemented!");
3403}
3404
3405
3414static void
3415run (void *cls,
3416 char *const *args,
3417 const char *cfgfile,
3418 const struct GNUNET_CONFIGURATION_Handle *c)
3419{
3420 char *bindto;
3421 struct sockaddr *in;
3422 socklen_t in_len;
3423 struct sockaddr_storage in_sto;
3424 socklen_t sto_len;
3425
3426 (void) cls;
3427 cfg = c;
3428 if (GNUNET_OK !=
3431 "BINDTO",
3432 &bindto))
3433 {
3436 "BINDTO");
3437 return;
3438 }
3439
3440 if (GNUNET_OK !=
3443 "REKEY_INTERVAL",
3446
3447 if (GNUNET_OK !=
3450 "REKEY_MAX_BYTES",
3452 {
3454 }
3456 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3457 (GNUNET_YES ==
3460 "DISABLE_V6")))
3461 {
3463 }
3464
3465 in = udp_address_to_sockaddr (bindto, &in_len);
3466 if (NULL == in)
3467 {
3469 "Failed to setup UDP socket address with path `%s'\n",
3470 bindto);
3471 GNUNET_free (bindto);
3472 return;
3473 }
3474 udp_sock =
3475 GNUNET_NETWORK_socket_create (in->sa_family,
3476 SOCK_DGRAM,
3477 IPPROTO_UDP);
3478 if (NULL == udp_sock)
3479 {
3482 "Failed to create socket for %s family %d\n",
3483 GNUNET_a2s (in,
3484 in_len),
3485 in->sa_family);
3486 GNUNET_free (in);
3487 GNUNET_free (bindto);
3488 return;
3489 }
3490 if (AF_INET6 == in->sa_family)
3492 if (GNUNET_OK !=
3494 in,
3495 in_len))
3496 {
3498 "bind",
3499 bindto);
3501 "Failed to bind socket for %s family %d sock %p\n",
3502 GNUNET_a2s (in,
3503 in_len),
3504 in->sa_family,
3505 udp_sock);
3507 udp_sock = NULL;
3508 GNUNET_free (in);
3509 GNUNET_free (bindto);
3510 return;
3511 }
3512
3513 /* We might have bound to port 0, allowing the OS to figure it out;
3514 thus, get the real IN-address from the socket */
3515 sto_len = sizeof(in_sto);
3516 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
3517 (struct sockaddr *) &in_sto,
3518 &sto_len))
3519 {
3520 memcpy (&in_sto, in, in_len);
3521 sto_len = in_len;
3522 }
3523 GNUNET_free (in);
3524 GNUNET_free (bindto);
3525 in = (struct sockaddr *) &in_sto;
3526 in_len = sto_len;
3528 "transport",
3529 "Bound to `%s' sock %p\n",
3530 GNUNET_a2s ((const struct sockaddr *) &in_sto,
3531 sto_len),
3532 udp_sock);
3533 switch (in->sa_family)
3534 {
3535 case AF_INET:
3536 my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
3537 break;
3538
3539 case AF_INET6:
3540 my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
3541 break;
3542
3543 default:
3544 GNUNET_break (0);
3545 my_port = 0;
3546 }
3547 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3557 if (NULL == my_private_key)
3558 {
3559 GNUNET_log (
3561 _ (
3562 "Transport service is lacking key configuration settings. Exiting.\n"));
3564 return;
3565 }
3567 /* start reading */
3569 udp_sock,
3570 &sock_read,
3571 NULL);
3576 &mq_init,
3577 NULL,
3579 NULL);
3580 if (NULL == ch)
3581 {
3582 GNUNET_break (0);
3584 return;
3585 }
3587 if (NULL == ah)
3588 {
3589 GNUNET_break (0);
3591 return;
3592 }
3593 /* start broadcasting */
3594 if (GNUNET_YES !=
3597 "DISABLE_BROADCAST"))
3598 {
3600 }
3603 IPPROTO_UDP,
3604 1 /* one address */,
3605 (const struct sockaddr **) &in,
3606 &in_len,
3609 NULL /* closure */);
3610}
3611
3612
3620int
3621main (int argc, char *const *argv)
3622{
3623 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3625 };
3626 int ret;
3627
3629 "transport",
3630 "Starting udp communicator\n");
3631 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3632 return 2;
3633
3634 ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
3635 argv,
3636 "gnunet-communicator-udp",
3637 _ ("GNUnet UDP communicator"),
3638 options,
3639 &run,
3640 NULL))
3641 ? 0
3642 : 1;
3643 GNUNET_free_nz ((void *) argv);
3644 return ret;
3645}
3646
3647
3648/* end of gnunet-communicator-udp.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int ret
Final status code.
Definition: gnunet-arm.c:94
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
#define AES_KEY_SIZE
AES key size.
static struct BroadcastInterface * bi_tail
Broadcast interface tasks.
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
static int try_decrypt(const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
Try to decrypt buf using shared secret ss and key/iv derived using serial.
#define WORKING_QUEUE_INTERVALL
static void kce_destroy(struct KeyCacheEntry *kce)
Free memory used by key cache entry.
static int handle_ack(void *cls, const struct GNUNET_HashCode *key, void *value)
We received an ACK for pid.
static void create_rekey(struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static void get_iv_key(const struct GNUNET_HashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
Compute key and iv.
static int secret_destroy(struct SharedSecret *ss)
Destroy ss and associated key cache entries.
static void setup_cipher(const struct GNUNET_HashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.
#define GCM_TAG_SIZE
Size of the GCM tag.
static struct GNUNET_PeerIdentity my_identity
Our public key.
static struct SharedSecret * setup_shared_secret_ephemeral(struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM.
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.
#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 add_acks(struct SharedSecret *ss, int acks_to_add)
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static void mq_destroy_kx(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static int get_receiver_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all receivers to clean up.
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static struct GNUNET_SCHEDULER_Task * broadcast_task
ID of master broadcast task.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static int disable_v6
IPv6 disabled or not.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received a backchannel message for this communicator (...
static struct SenderAddress * setup_sender(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
Create sender address for target.
unsigned int purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
static void reschedule_receiver_timeout(struct ReceiverAddress *receiver)
Increment receiver timeout due to activity.
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static void do_pad(gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
Pad dgram by pad_size using out_cipher.
static void mq_send_d(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static void sock_read(void *cls)
Socket read task.
static void reschedule_sender_timeout(struct SenderAddress *sender)
Increment sender timeout due to activity.
static struct GNUNET_CONTAINER_Heap * senders_heap
Expiration heap for senders (contains struct SenderAddress)
static void do_shutdown(void *cls)
Shutdown the UNIX communicator.
static int get_sender_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all senders to clean up.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static void nat_address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
static void sender_destroy(struct SenderAddress *sender)
Functions with this signature are called whenever we need to close a sender's state due to timeout.
static void setup_receiver_mq(struct ReceiverAddress *receiver)
Setup the MQ for the receiver.
static struct sockaddr * udp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
static int handle_ack_by_sender(void *cls, const struct GNUNET_HashCode *key, void *value)
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
#define DEFAULT_REKEY_MAX_BYTES
Default value for how often we do rekey based on number of bytes transmitted? (additionally randomize...
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static struct GNUNET_CONTAINER_MultiHashMap * receivers
Receivers (map from peer identity to struct ReceiverAddress)
#define GENERATE_AT_ONCE
static void kce_generate_cb(void *cls)
static struct GNUNET_SCHEDULER_Task * read_task
ID of read task.
static void try_handle_plaintext(struct SenderAddress *sender, const void *buf, size_t buf_size)
Test if we have received a valid message in plaintext.
static void receiver_destroy(struct ReceiverAddress *receiver)
Destroys a receiving state due to timeout or shutdown.
static struct GNUNET_CONTAINER_MultiShortmap * key_cache
Cache of pre-generated key IDs.
#define KCN_TARGET
How many KCNs do we keep around after we hit the KCN_THRESHOLD? Should be larger than KCN_THRESHOLD s...
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
static struct GNUNET_TRANSPORT_ApplicationHandle * ah
Our handle to report addresses for validation to TRANSPORT.
static void bi_destroy(struct BroadcastInterface *bi)
An interface went away, stop broadcasting on it.
static int have_v6_socket
GNUNET_YES if udp_sock supports IPv6.
static void pass_plaintext_to_core(struct SenderAddress *sender, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext from a sender.
static struct GNUNET_CONTAINER_MultiHashMap * senders
Senders (map from peer identity to struct SenderAddress)
static int mq_init(void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
Function called by the transport service to initialize a message queue given address information abou...
static void do_broadcast(void *cls)
Scan interfaces to broadcast our presence on the LAN.
#define INTERFACE_SCAN_FREQUENCY
How often do we scan for changes to our network interfaces?
static struct GNUNET_CONTAINER_Heap * receivers_heap
Expiration heap for receivers (contains struct ReceiverAddress)
static uint16_t my_port
Port number to which we are actually bound.
static void get_kid(const struct GNUNET_HashCode *msec, uint32_t serial, struct GNUNET_ShortHashCode *kid)
Compute kid.
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.
#define MAX_SQN_DELTA
What is the maximum delta between KCN sequence numbers that we allow.
int main(int argc, char *const *argv)
The main function for the UNIX communicator.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
#define KCN_THRESHOLD
If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET...
#define MAX_SECRETS
How many shared master secrets do we keep around at most per sender? Should be large enough so that w...
static struct BroadcastInterface * bi_head
Broadcast interface tasks.
static struct SharedSecret * setup_initial_shared_secret_ephemeral(struct GNUNET_CRYPTO_ElligatorRepresentative *representative, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM for initial handshake.
static void send_msg_with_kx(const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver, struct GNUNET_MQ_Handle *mq)
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral)
Setup shared secret for decryption.
static struct SharedSecret * setup_initial_shared_secret_dec(const struct GNUNET_CRYPTO_ElligatorRepresentative *representative)
Setup shared secret for decryption for initial handshake.
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 void decrypt_box(const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
We received a box with matching kce.
static int verify_confirmation(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, const struct UDPConfirmation *uc)
Check signature from uc against ephemeral.
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 struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * name
Name (label) of the records to list.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
static struct GNUNET_FS_UnindexContext * uc
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Constants for network protocols.
API to create, modify and access statistics.
Bandwidth allocation API for applications to interact with.
API of the transport service towards the communicator processes.
void GNUNET_TRANSPORT_communicator_address_remove(struct GNUNET_TRANSPORT_AddressIdentifier *ai)
Notify transport service about an address that this communicator no longer provides for this peer.
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
void GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
struct GNUNET_TRANSPORT_QueueHandle * GNUNET_TRANSPORT_communicator_mq_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *peer, const char *address, uint32_t mtu, uint64_t q_len, uint32_t priority, enum GNUNET_NetworkType nt, enum GNUNET_TRANSPORT_ConnectionStatus cs, struct GNUNET_MQ_Handle *mq)
Notify transport service that a MQ became available due to an "inbound" connection or because the com...
void GNUNET_TRANSPORT_application_validate(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_NetworkType nt, const char *addr)
An application (or a communicator) has received a HELLO (or other address data of another peer) and w...
void GNUNET_TRANSPORT_communicator_mq_update(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_TRANSPORT_QueueHandle *u_qh, uint64_t q_len, uint32_t priority)
Notify transport service that an MQ was updated.
void GNUNET_TRANSPORT_communicator_notify(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *pid, const char *comm, const struct GNUNET_MessageHeader *header)
The communicator asks the transport service to route a message via a different path to another commun...
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls)
Connect to the transport service.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer.
@ GNUNET_TRANSPORT_CC_UNRELIABLE
Transmission is unreliable (e.g.
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material)
Decapsulate a key for a private EdDSA key.
Definition: crypto_ecc.c:749
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_elligator_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_ElligatorRepresentative *r, struct GNUNET_HashCode *key_material)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:198
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material)
Encapsulate key material for a EdDSA public key.
Definition: crypto_ecc.c:794
void GNUNET_CRYPTO_ecdhe_elligator_decoding(struct GNUNET_CRYPTO_EcdhePublicKey *point, bool *high_y, const struct GNUNET_CRYPTO_ElligatorRepresentative *representative)
Clears the most significant bit and second most significant bit of the serialized representaive befor...
#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.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_elligator_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_ElligatorRepresentative *r, struct GNUNET_HashCode *key_material)
Carries out ecdh decapsulation with own private key and the representative of the received public key...
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer's key from the file specified in the configuration.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf(void *result, size_t out_len, int xtr_algo, int prf_algo, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_hkdf.c:341
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
Definition: crypto_hash.c:366
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:390
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:350
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...) __attribute__((format(printf
Log function that specifies an alternative component.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:465
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:421
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:727
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1000
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:687
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:439
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition: network.c:805
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:771
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:44
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:426
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:405
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition: nt.c:307
@ GNUNET_NT_LOOPBACK
Loopback (same host).
Definition: gnunet_nt_lib.h:53
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:397
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY
UDP Rekey.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK
UDP KX acknowledgement.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1512
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1340
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1305
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1278
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:343
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition: time.c:860
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
void receiver(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition: socks.c:330
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE
Signature used by UDP communicator handshake.
const struct UDPAck * ack
const struct GNUNET_PeerIdentity * sender
Interface we broadcast our presence on.
socklen_t salen
Number of bytes in sa.
struct ipv6_mreq mcreq
If this is an IPv6 interface, this is the request we use to join/leave the group.
struct BroadcastInterface * next
Kept in a DLL.
int found
Was this interface found in the last iface_proc() scan?
struct UDPBroadcast bcm
Message we broadcast on this interface.
struct sockaddr * ba
Broadcast address to use on the interface.
struct GNUNET_SCHEDULER_Task * broadcast_task
Task for this broadcast interface.
struct BroadcastInterface * prev
Kept in a DLL.
struct sockaddr * sa
Sender's address of the interface.
Handle to a node in a heap.
Internal representation of the hash map.
Internal representation of the hash map.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Private ECC key encoded for transmission.
an ECC signature using EdDSA.
Elligator representative (always for Curve25519)
Definition of a command line option.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Handle for active NAT registrations.
Definition: nat_api.c:72
handle to a socket
Definition: network.c:53
Handle to the interface scanner.
Definition: nt.c:104
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle for the service.
A 256-bit hashcode.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Internal representation of an address a communicator is currently providing for the transport service...
Handle to the TRANSPORT subsystem for application management.
Opaque handle to the transport service for communicators.
Handle returned to identify the internal data structure the transport API has created to manage a mes...
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.
"Plaintext" header at beginning of KX message.
struct GNUNET_CRYPTO_ElligatorRepresentative representative
Representative of ephemeral key for KX.
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct U...
struct GNUNET_ShortHashCode kid
Key and IV identification code.
uint32_t sequence_number
Sequence number used to derive this entry from master key.
struct KeyCacheEntry * next
Kept in a DLL.
struct KeyCacheEntry * prev
Kept in a DLL.
struct SharedSecret * ss
Corresponding shared secret.
Information we track per receiving address we have recently been in contact with (encryption to recei...
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct GNUNET_TIME_Absolute rekey_timeout
Timeout for this receiver address.
struct SharedSecret * ss_tail
Shared secrets we received with target, last used is tail.
char * foreign_addr
Address of the receiver in the human-readable format with the COMMUNICATOR_ADDRESS_PREFIX.
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this receiver.
struct SharedSecret * ss_head
Shared secrets we received from target, first used is head.
struct GNUNET_TRANSPORT_QueueHandle * kx_qh
handle for KX queue with the ch.
unsigned int num_secrets
Length of the DLL at ss_head.
struct GNUNET_TIME_Absolute timeout
Timeout for this receiver address.
size_t kx_mtu
MTU we allowed transport for this receiver's KX queue.
struct sockaddr * address
Address of the other peer.
struct GNUNET_PeerIdentity target
To whom are we talking to.
socklen_t address_len
Length of the address.
struct GNUNET_MQ_Handle * kx_mq
KX message queue we are providing for the ch.
int receiver_destroy_called
receiver_destroy already called on receiver.
size_t d_mtu
MTU we allowed transport for this receiver's default queue.
enum GNUNET_NetworkType nt
Which network type does this queue use?
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.
struct GNUNET_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_HashCode 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_EcdhePublicKey ephemeral
Ephemeral key to rekey with.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_HashCode h_address
Hash of the sender's UDP address.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP broadcast.
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_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_EcdhePublicKey ephemeral
Ephemeral key used by the sender.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP connection (UDP client).