GNUnet 0.26.0
 
Loading...
Searching...
No Matches
gnunet-communicator-tcp.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
30#include "platform.h"
31#include "gnunet_common.h"
32#include "gnunet_util_lib.h"
33#include "gnunet_pils_service.h"
34#include "gnunet_core_service.h"
36#include "gnunet_protocols.h"
37#include "gnunet_signatures.h"
38#include "gnunet_constants.h"
39#include "gnunet_nat_service.h"
43
44/* Shorthand for Logging */
45#define LOG(kind, ...) GNUNET_log_from (kind, "communicator-tcp", __VA_ARGS__)
46
47
52#define NAT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
53
58#define ADDRESS_VALIDITY_PERIOD \
59 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
60
69#define DEFAULT_MAX_QUEUE_LENGTH 8
70
75#define BUF_SIZE (2 * 64 * 1024 + sizeof(struct TCPBox))
76
80#define DEFAULT_REKEY_INTERVAL GNUNET_TIME_UNIT_DAYS
81
85#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
86
91#define REKEY_MAX_BYTES (1024LLU * 1024 * 400)
92
97#define INITIAL_KX_SIZE \
98 (sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) \
99 + sizeof(struct TCPConfirmation))
100
104#define INITIAL_CORE_KX_SIZE \
105 (sizeof(struct EphemeralKeyMessage) \
106 + sizeof(struct PingMessage) \
107 + sizeof(struct PongMessage))
108
112#define COMMUNICATOR_ADDRESS_PREFIX "tcp"
113
117#define COMMUNICATOR_CONFIG_SECTION "communicator-tcp"
118
120
121
159
192
220
255
259struct TCPBox
260{
268
278
279 /* followed by as may bytes of payload as indicated in @e header,
280 excluding the TCPBox itself! */
281};
282
283
321
354
377
394
396
401{
402 /*
403 * Timeout task.
404 */
406
411
415 struct sockaddr *in;
416};
417
433
437struct Queue
438{
443
448
453
458
462 gcry_cipher_hd_t in_cipher;
463
467 gcry_cipher_hd_t out_cipher;
468
473
478
484
489
494
498 struct sockaddr *address;
499
505
511
515 socklen_t address_len;
516
521
526
530 unsigned long long bytes_in_queue;
531
536
541
545 char pread_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
546
550 char pwrite_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
551
556 size_t cread_off;
557
563
568 size_t pread_off;
569
575
580
588 unsigned int backpressure;
589
594
599
604
609
617
623
628
633
638
643
648
653
658
663
668
673
678
682 // TODO remove?
684
689};
690
691
697{
702
707
712
717
722
726 char write_buf[sizeof (struct TCPNATProbeMessage)];
727
731 size_t write_off;
732
737
741 struct sockaddr *address;
742
746 socklen_t address_len;
747
752
758
762 size_t ibuf_off;
763};
764
769{
773 struct sockaddr *addr_ipv4;
774
778 socklen_t addr_len_ipv4;
779
783 struct sockaddr *addr_ipv6;
784
788 socklen_t addr_len_ipv6;
789
790};
791
795struct Addresses
796{
800 struct Addresses *next;
801
805 struct Addresses *prev;
806
810 struct sockaddr *addr;
811
815 socklen_t addr_len;
816
817};
818
819
823static unsigned long long max_queue_length;
824
829
834
839
844
849
854
858static unsigned long long rekey_max_bytes;
859
864
869
874
878static const struct GNUNET_CONFIGURATION_Handle *cfg;
879
884
888static struct GNUNET_NAT_Handle *nat;
889
893static struct ProtoQueue *proto_head;
894
898static struct ProtoQueue *proto_tail;
899
904
908static struct Addresses *addrs_head;
909
913static struct Addresses *addrs_tail;
914
918static int addrs_lens;
919
924
929
933static int disable_v6;
934
938static unsigned int bind_port;
939
944
948static unsigned char ikm[256 / 8];
949
957static void
958listen_cb (void *cls);
959
960static void
970
971
972static void
981
982
990static void
992{
993 struct ListenTask *lt = NULL;
994 struct GNUNET_HashCode h_sock;
995 int sockfd;
996
997 if (NULL != queue->listen_sock)
998 {
999 sockfd = GNUNET_NETWORK_get_fd (queue->listen_sock);
1000 GNUNET_CRYPTO_hash (&sockfd,
1001 sizeof(int),
1002 &h_sock);
1003
1005 }
1006
1008 "Disconnecting queue for peer `%s'\n",
1009 GNUNET_i2s (&queue->target));
1010 if (NULL != queue->rekey_monotime_sc)
1011 {
1012 GNUNET_PEERSTORE_store_cancel (queue->rekey_monotime_sc);
1013 queue->rekey_monotime_sc = NULL;
1014 }
1015 if (NULL != queue->handshake_monotime_sc)
1016 {
1017 GNUNET_PEERSTORE_store_cancel (queue->handshake_monotime_sc);
1018 queue->handshake_monotime_sc = NULL;
1019 }
1020 if (NULL != queue->handshake_ack_monotime_sc)
1021 {
1022 GNUNET_PEERSTORE_store_cancel (queue->handshake_ack_monotime_sc);
1023 queue->handshake_ack_monotime_sc = NULL;
1024 }
1025 if (NULL != queue->rekey_monotime_get)
1026 {
1027 GNUNET_PEERSTORE_iteration_stop (queue->rekey_monotime_get);
1028 queue->rekey_monotime_get = NULL;
1029 }
1030 if (NULL != queue->handshake_monotime_get)
1031 {
1032 GNUNET_PEERSTORE_iteration_stop (queue->handshake_monotime_get);
1033 queue->handshake_monotime_get = NULL;
1034 }
1035 if (NULL != queue->handshake_ack_monotime_get)
1036 {
1037 GNUNET_PEERSTORE_iteration_stop (queue->handshake_ack_monotime_get);
1038 queue->handshake_ack_monotime_get = NULL;
1039 }
1040 if (NULL != queue->qh)
1041 {
1043 queue->qh = NULL;
1044 }
1046 GNUNET_YES ==
1049 "# queues active",
1051 GNUNET_NO);
1052 if (NULL != queue->read_task)
1053 {
1054 GNUNET_SCHEDULER_cancel (queue->read_task);
1055 queue->read_task = NULL;
1056 }
1057 if (NULL != queue->write_task)
1058 {
1059 GNUNET_SCHEDULER_cancel (queue->write_task);
1060 queue->write_task = NULL;
1061 }
1063 {
1065 "closing socket failed\n");
1066 }
1067 gcry_cipher_close (queue->in_cipher);
1068 gcry_cipher_close (queue->out_cipher);
1069 GNUNET_free (queue->address);
1070 if (0 != queue->backpressure)
1071 queue->destroyed = GNUNET_YES;
1072 else
1074
1075 if (NULL == lt)
1076 return;
1077
1078 if ((! shutdown_running) && (NULL == lt->listen_task))
1079 {
1081 "add read net listen\n");
1084 lt->listen_sock,
1085 &listen_cb,
1086 lt);
1087 }
1088 else
1089 GNUNET_free (lt);
1090}
1091
1092
1101static void
1102calculate_hmac (struct GNUNET_HashCode *hmac_secret,
1103 const void *buf,
1104 size_t buf_size,
1105 struct GNUNET_ShortHashCode *smac)
1106{
1107 struct GNUNET_HashCode mac;
1108
1109 GNUNET_CRYPTO_hmac_raw (hmac_secret,
1110 sizeof(struct GNUNET_HashCode),
1111 buf,
1112 buf_size,
1113 &mac);
1114 /* truncate to `struct GNUNET_ShortHashCode` */
1115 memcpy (smac, &mac, sizeof(struct GNUNET_ShortHashCode));
1116 /* ratchet hmac key */
1117 GNUNET_CRYPTO_hash (hmac_secret,
1118 sizeof(struct GNUNET_HashCode),
1119 hmac_secret);
1120}
1121
1122
1129static void
1131{
1132 struct TCPFinish fin;
1133
1134 memset (&fin, 0, sizeof(fin));
1135 fin.header.size = htons (sizeof(fin));
1137 calculate_hmac (&queue->out_hmac, &fin, sizeof(fin), &fin.hmac);
1138 /* if there is any message left in pwrite_buf, we
1139 overwrite it (possibly dropping the last message
1140 from CORE hard here) */
1141 memcpy (queue->pwrite_buf, &fin, sizeof(fin));
1142 queue->pwrite_off = sizeof(fin);
1143 /* This flag will ensure that #queue_write() no longer
1144 notifies CORE about the possibility of sending
1145 more data, and that #queue_write() will call
1146 #queue_destroy() once the @c fin was fully written. */
1147 queue->finishing = GNUNET_YES;
1148}
1149
1150
1156static void
1157queue_read (void *cls);
1158
1159
1167static void
1168core_read_finished_cb (void *cls, int success)
1169{
1170 struct Queue *queue = cls;
1171 if (GNUNET_OK != success)
1173 "# messages lost in communicator API towards CORE",
1174 1,
1175 GNUNET_NO);
1176 if (NULL == queue)
1177 return;
1178
1180 "backpressure %u\n",
1181 queue->backpressure);
1182
1183 queue->backpressure--;
1184 /* handle deferred queue destruction */
1185 if ((queue->destroyed) && (0 == queue->backpressure))
1186 {
1188 return;
1189 }
1190 else if (GNUNET_YES != queue->destroyed)
1191 {
1192 queue->timeout =
1194 );
1195 /* possibly unchoke reading, now that CORE made progress */
1196 if (NULL == queue->read_task)
1197 queue->read_task =
1199 queue->timeout),
1200 queue->sock,
1201 &queue_read,
1202 queue);
1203 }
1204}
1205
1206
1216static void
1218 const void *plaintext,
1219 size_t plaintext_len)
1220{
1221 const struct GNUNET_MessageHeader *hdr = plaintext;
1222 int ret;
1223
1225 "pass message from %s to core\n",
1226 GNUNET_i2s (&queue->target));
1227
1228 if (ntohs (hdr->size) != plaintext_len)
1229 {
1230 /* NOTE: If we ever allow multiple CORE messages in one
1231 BOX, this will have to change! */
1232 GNUNET_break (0);
1233 return;
1234 }
1236 &queue->target,
1237 hdr,
1240 queue);
1242 "passed to core\n");
1243 if (GNUNET_OK == ret)
1244 queue->backpressure++;
1245 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
1246 if (GNUNET_SYSERR == ret)
1248 "# bytes lost due to CORE not running",
1249 plaintext_len,
1250 GNUNET_NO);
1251}
1252
1253
1263static void
1265 const struct GNUNET_PeerIdentity *pid,
1266 gcry_cipher_hd_t *cipher,
1267 struct GNUNET_HashCode *hmac_key)
1268{
1269 char key[256 / 8];
1270 char ctr[128 / 8];
1271
1272 GNUNET_assert (0 == gcry_cipher_open (cipher,
1273 GCRY_CIPHER_AES256 /* low level: go for speed */
1274 ,
1275 GCRY_CIPHER_MODE_CTR,
1276 0 /* flags */));
1279 sizeof(key),
1280 prk,
1281 "gnunet-communicator-tcp-key",
1282 strlen (
1283 "gnunet-communicator-tcp-key"),
1284 NULL,
1285 0));
1286 GNUNET_assert (0 == gcry_cipher_setkey (*cipher, key, sizeof(key)));
1289 sizeof(ctr),
1290 prk,
1291 "gnunet-communicator-tcp-ctr",
1292 strlen (
1293 "gnunet-communicator-tcp-ctr"),
1294 NULL,
1295 0));
1296 gcry_cipher_setctr (*cipher, ctr, sizeof(ctr));
1298 GNUNET_CRYPTO_hkdf_expand (hmac_key,
1299 sizeof(struct GNUNET_HashCode),
1300 prk,
1301 "gnunet-communicator-hmac",
1302 strlen ("gnunet-communicator-hmac"),
1303 NULL,
1304 0));
1305}
1306
1307
1313static void
1314rekey_monotime_store_cb (void *cls, int success)
1315{
1316 struct Queue *queue = cls;
1317 if (GNUNET_OK != success)
1318 {
1320 "Failed to store rekey monotonic time in PEERSTORE!\n");
1321 }
1322 queue->rekey_monotime_sc = NULL;
1323 GNUNET_PEERSTORE_iteration_next (queue->rekey_monotime_get, 1);
1324}
1325
1326
1334static void
1336 const struct GNUNET_PEERSTORE_Record *record,
1337 const char *emsg)
1338{
1339 struct Queue *queue = cls;
1340 struct GNUNET_TIME_AbsoluteNBO *mtbe;
1341 struct GNUNET_TIME_Absolute mt;
1342 const struct GNUNET_PeerIdentity *pid;
1343 struct GNUNET_TIME_AbsoluteNBO *rekey_monotonic_time;
1344
1345 (void) emsg;
1346
1347 rekey_monotonic_time = &queue->rekey_monotonic_time;
1348 pid = &queue->target;
1349 if (NULL == record)
1350 {
1351 queue->rekey_monotime_get = NULL;
1352 return;
1353 }
1354 if (sizeof(*mtbe) != record->value_size)
1355 {
1356 GNUNET_PEERSTORE_iteration_next (queue->rekey_monotime_get, 1);
1357 GNUNET_break (0);
1358 return;
1359 }
1360 mtbe = record->value;
1361 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1363 queue->rekey_monotonic_time).abs_value_us)
1364 {
1366 "Queue from %s dropped, rekey monotime in the past\n",
1367 GNUNET_i2s (&queue->target));
1368 GNUNET_break (0);
1369 GNUNET_PEERSTORE_iteration_stop (queue->rekey_monotime_get);
1370 queue->rekey_monotime_get = NULL;
1371 // FIXME: Why should we try to gracefully finish here??
1373 return;
1374 }
1375 queue->rekey_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
1376 "transport_tcp_communicator",
1377 pid,
1379 rekey_monotonic_time,
1380 sizeof(*
1381 rekey_monotonic_time),
1385 queue);
1386}
1387
1388
1395static void
1397 const struct GNUNET_CRYPTO_HpkeEncapsulation *c,
1398 struct Queue *queue)
1399{
1400 struct GNUNET_ShortHashCode k;
1401
1403 c,
1404 &k);
1405 setup_cipher (&k, &my_identity, &queue->in_cipher, &queue->in_hmac);
1406}
1407
1408
1415static void
1417 struct Queue *queue)
1418{
1419 struct GNUNET_ShortHashCode k;
1420
1422 setup_cipher (&k, &my_identity, &queue->in_cipher, &queue->in_hmac);
1423}
1424
1425
1434static void
1435do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
1436{
1437 struct TcpRekeySignature thp;
1438
1440 thp.purpose.size = htonl (sizeof(thp));
1442 "do_rekey size %u\n",
1443 thp.purpose.size);
1444 thp.sender = queue->target;
1446 "sender %s\n",
1449 "sender %s\n",
1450 GNUNET_p2s (&queue->target.public_key));
1451 thp.receiver = my_identity;
1453 "receiver %s\n",
1455 thp.ephemeral = rekey->ephemeral;
1457 "ephemeral %s\n",
1459 );
1460 thp.monotonic_time = rekey->monotonic_time;
1462 "time %s\n",
1465 GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp)));
1466 if (GNUNET_OK !=
1469 &thp,
1470 &rekey->sender_sig,
1471 &queue->target.public_key))
1472 {
1473 GNUNET_break (0);
1474 // FIXME Why should we try to gracefully finish here?
1476 return;
1477 }
1478 queue->rekey_monotonic_time = rekey->monotonic_time;
1479 queue->rekey_monotime_get = GNUNET_PEERSTORE_iteration_start (peerstore,
1480 "transport_tcp_communicator",
1481 &queue->target,
1483 &
1485 queue);
1486 gcry_cipher_close (queue->in_cipher);
1487 queue->rekeyed = GNUNET_YES;
1488 setup_in_cipher (&rekey->ephemeral, queue);
1489}
1490
1491
1497static void
1498handshake_ack_monotime_store_cb (void *cls, int success)
1499{
1500 struct Queue *queue = cls;
1501
1502 if (GNUNET_OK != success)
1503 {
1505 "Failed to store handshake ack monotonic time in PEERSTORE!\n");
1506 }
1507 queue->handshake_ack_monotime_sc = NULL;
1508 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
1509}
1510
1511
1519static void
1521 const struct GNUNET_PEERSTORE_Record *record,
1522 const char *emsg)
1523{
1524 struct Queue *queue = cls;
1525 struct GNUNET_TIME_AbsoluteNBO *mtbe;
1526 struct GNUNET_TIME_Absolute mt;
1527 const struct GNUNET_PeerIdentity *pid;
1528 struct GNUNET_TIME_AbsoluteNBO *handshake_ack_monotonic_time;
1529
1530 (void) emsg;
1531
1532 handshake_ack_monotonic_time = &queue->handshake_ack_monotonic_time;
1533 pid = &queue->target;
1534 if (NULL == record)
1535 {
1536 queue->handshake_ack_monotime_get = NULL;
1537 return;
1538 }
1539 if (sizeof(*mtbe) != record->value_size)
1540 {
1541 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
1542 GNUNET_break (0);
1543 return;
1544 }
1545 mtbe = record->value;
1546 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1548 queue->handshake_ack_monotonic_time).abs_value_us)
1549 {
1551 "Queue from %s dropped, handshake ack monotime in the past\n",
1552 GNUNET_i2s (&queue->target));
1553 GNUNET_break (0);
1554 GNUNET_PEERSTORE_iteration_stop (queue->handshake_ack_monotime_get);
1555 queue->handshake_ack_monotime_get = NULL;
1556 // FIXME: Why should we try to gracefully finish here?
1558 return;
1559 }
1560 queue->handshake_ack_monotime_sc =
1562 "transport_tcp_communicator",
1563 pid,
1565 handshake_ack_monotonic_time,
1566 sizeof(*handshake_ack_monotonic_time),
1570 queue);
1571}
1572
1573
1580static void
1582 struct Queue *queue)
1583{
1584 struct TCPConfirmationAck tca;
1585 struct TcpHandshakeAckSignature thas;
1586
1588 "sending challenge\n");
1589
1590 tca.header.type = ntohs (
1592 tca.header.size = ntohs (sizeof(tca));
1593 tca.challenge = challenge;
1594 tca.sender = my_identity;
1595 tca.monotonic_time =
1597 thas.purpose.purpose = htonl (
1599 thas.purpose.size = htonl (sizeof(thas));
1600 thas.sender = my_identity;
1601 thas.receiver = queue->target;
1602 thas.monotonic_time = tca.monotonic_time;
1603 thas.challenge = tca.challenge;
1605 &thas,
1606 &tca.sender_sig);
1607 GNUNET_assert (0 ==
1608 gcry_cipher_encrypt (queue->out_cipher,
1609 &queue->cwrite_buf[queue->cwrite_off],
1610 sizeof(tca),
1611 &tca,
1612 sizeof(tca)));
1613 queue->cwrite_off += sizeof(tca);
1615 "sending challenge done\n");
1616}
1617
1618
1625static void
1627{
1628 setup_cipher (dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1630 queue->rekey_left_bytes =
1632}
1633
1634
1641static void
1643{
1644 struct TCPRekey rekey;
1645 struct TcpRekeySignature thp;
1646 struct GNUNET_ShortHashCode k;
1647
1648 GNUNET_assert (0 == queue->pwrite_off);
1649 memset (&rekey, 0, sizeof(rekey));
1650 GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &rekey.ephemeral,
1651 &k);
1653 rekey.header.size = ntohs (sizeof(rekey));
1654 rekey.monotonic_time =
1657 thp.purpose.size = htonl (sizeof(thp));
1659 "inject_rekey size %u\n",
1660 thp.purpose.size);
1661 thp.sender = my_identity;
1663 "sender %s\n",
1665 thp.receiver = queue->target;
1667 "receiver %s\n",
1669 thp.ephemeral = rekey.ephemeral;
1671 "ephemeral %s\n",
1673 );
1674 thp.monotonic_time = rekey.monotonic_time;
1676 "time %s\n",
1680 &thp,
1681 &rekey.sender_sig);
1682 calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1683 /* Encrypt rekey message with 'old' cipher */
1684 GNUNET_assert (0 ==
1685 gcry_cipher_encrypt (queue->out_cipher,
1686 &queue->cwrite_buf[queue->cwrite_off],
1687 sizeof(rekey),
1688 &rekey,
1689 sizeof(rekey)));
1690 queue->cwrite_off += sizeof(rekey);
1691 /* Setup new cipher for successive messages */
1692 gcry_cipher_close (queue->out_cipher);
1693 setup_out_cipher (queue, &k);
1694}
1695
1696
1697static int
1699 const struct GNUNET_HashCode *key,
1700 void *value)
1701{
1702 struct PendingReversal *pending_reversal = value;
1703 (void) cls;
1704
1705 if (NULL != pending_reversal->timeout_task)
1706 {
1707 GNUNET_SCHEDULER_cancel (pending_reversal->timeout_task);
1708 pending_reversal->timeout_task = NULL;
1709 }
1712 key,
1713 pending_reversal));
1714 GNUNET_free (pending_reversal->in);
1715 GNUNET_free (pending_reversal);
1716 return GNUNET_OK;
1717}
1718
1719
1720static void
1721check_and_remove_pending_reversal (struct sockaddr *in, sa_family_t sa_family,
1722 struct GNUNET_PeerIdentity *sender)
1723{
1724 if (AF_INET == sa_family)
1725 {
1726 struct PendingReversal *pending_reversal;
1727 struct GNUNET_HashCode key;
1728 struct sockaddr_in *natted_address;
1729
1730 natted_address = GNUNET_memdup (in, sizeof (struct sockaddr));
1731 natted_address->sin_port = 0;
1732 GNUNET_CRYPTO_hash (natted_address,
1733 sizeof(struct sockaddr),
1734 &key);
1735
1737 &key);
1738 if (NULL != pending_reversal && (NULL == sender ||
1739 0 != memcmp (sender,
1740 &pending_reversal->target,
1741 sizeof(struct
1743 {
1745 "Removing invalid pending reversal for `%s'at `%s'\n",
1746 GNUNET_i2s (&pending_reversal->target),
1747 GNUNET_a2s (in, sizeof (struct sockaddr)));
1748 pending_reversals_delete_it (NULL, &key, pending_reversal);
1749 }
1750 GNUNET_free (natted_address);
1751 }
1752}
1753
1754
1760static void
1762{
1763 if (NULL != pq->listen_sock)
1764 {
1766 pq->listen_sock = NULL;
1767 }
1768 if (NULL != pq->read_task)
1769 {
1771 pq->read_task = NULL;
1772 }
1773 if (NULL != pq->write_task)
1774 {
1776 pq->write_task = NULL;
1777 }
1778 check_and_remove_pending_reversal (pq->address, pq->address->sa_family, NULL);
1780 GNUNET_free (pq->address);
1782 GNUNET_free (pq);
1783}
1784
1785
1792static void
1794{
1795 struct ProtoQueue *pq = cls;
1796 ssize_t sent;
1797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In proto queue write\n");
1798 pq->write_task = NULL;
1799 if (0 != pq->write_off)
1800 {
1801 sent = GNUNET_NETWORK_socket_send (pq->sock,
1802 pq->write_buf,
1803 pq->write_off);
1805 "Sent %lu bytes to TCP queue\n", sent);
1806 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1807 {
1809 free_proto_queue (pq);
1810 return;
1811 }
1812 if (sent > 0)
1813 {
1814 size_t usent = (size_t) sent;
1815 pq->write_off -= usent;
1816 memmove (pq->write_buf,
1817 &pq->write_buf[usent],
1818 pq->write_off);
1819 }
1820 }
1821 /* do we care to write more? */
1822 if ((0 < pq->write_off))
1823 pq->write_task =
1825 pq->sock,
1827 pq);
1828}
1829
1830
1837static void
1838queue_write (void *cls)
1839{
1840 struct Queue *queue = cls;
1841 ssize_t sent;
1842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In queue write\n");
1843 queue->write_task = NULL;
1844 if (0 != queue->cwrite_off)
1845 {
1846 sent = GNUNET_NETWORK_socket_send (queue->sock,
1847 queue->cwrite_buf,
1848 queue->cwrite_off);
1850 "Sent %lu bytes to TCP queue\n", sent);
1851 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1852 {
1855 return;
1856 }
1857 if (sent > 0)
1858 {
1859 size_t usent = (size_t) sent;
1860 queue->cwrite_off -= usent;
1861 memmove (queue->cwrite_buf,
1862 &queue->cwrite_buf[usent],
1863 queue->cwrite_off);
1864 queue->timeout =
1867 }
1868 }
1869 {
1870 /* can we encrypt more? (always encrypt full messages, needed
1871 such that #mq_cancel() can work!) */
1872 unsigned int we_do_not_need_to_rekey = (0 < queue->rekey_left_bytes
1873 - (queue->cwrite_off
1874 + queue->pwrite_off
1875 + sizeof (struct TCPRekey)));
1876 if (we_do_not_need_to_rekey &&
1877 (queue->pwrite_off > 0) &&
1878 (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1879 {
1881 "Encrypting %lu bytes\n", queue->pwrite_off);
1882 GNUNET_assert (0 ==
1883 gcry_cipher_encrypt (queue->out_cipher,
1884 &queue->cwrite_buf[queue->cwrite_off],
1885 queue->pwrite_off,
1886 queue->pwrite_buf,
1887 queue->pwrite_off));
1888 if (queue->rekey_left_bytes > queue->pwrite_off)
1889 queue->rekey_left_bytes -= queue->pwrite_off;
1890 else
1891 queue->rekey_left_bytes = 0;
1892 queue->cwrite_off += queue->pwrite_off;
1893 queue->pwrite_off = 0;
1894 }
1895 // if ((-1 != unverified_size)&& ((0 == queue->pwrite_off) &&
1896 if (((0 == queue->rekey_left_bytes) ||
1898 queue->rekey_time).rel_value_us)) &&
1899 (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey) &&
1900 (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE)))
1901 {
1903 }
1904 }
1905 if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1906 (GNUNET_YES == queue->mq_awaits_continue))
1907 {
1908 queue->mq_awaits_continue = GNUNET_NO;
1910 }
1911 /* did we just finish writing 'finish'? */
1912 if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1913 {
1915 "Finishing queue\n");
1917 return;
1918 }
1919 /* do we care to write more? */
1920 if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1921 queue->write_task =
1923 queue->sock,
1924 &queue_write,
1925 queue);
1926}
1927
1928
1936static size_t
1938{
1939 const struct GNUNET_MessageHeader *hdr;
1940 const struct TCPConfirmationAck *tca;
1941 const struct TCPBox *box;
1942 const struct TCPRekey *rekey;
1943 const struct TCPFinish *fin;
1944 struct TCPRekey rekeyz;
1945 struct TCPFinish finz;
1946 struct GNUNET_ShortHashCode tmac;
1947 uint16_t type;
1948 size_t size = 0;
1949 struct TcpHandshakeAckSignature thas;
1950 const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1951
1953 "try handle plaintext!\n");
1954
1955 hdr = (const struct GNUNET_MessageHeader *) queue->pread_buf;
1956 if ((sizeof(*hdr) > queue->pread_off))
1957 {
1959 "Handling plaintext, not even a header!\n");
1960 return 0; /* not even a header */
1961 }
1962
1963 if ((GNUNET_YES != queue->initial_core_kx_done) && (queue->unverified_size >
1965 {
1967 "Already received data of size %lu bigger than KX size %lu!\n",
1968 queue->unverified_size,
1970 GNUNET_break_op (0);
1972 return 0;
1973 }
1974
1975 type = ntohs (hdr->type);
1976 switch (type)
1977 {
1979 tca = (const struct TCPConfirmationAck *) queue->pread_buf;
1981 "start processing ack\n");
1982 if (sizeof(*tca) > queue->pread_off)
1983 {
1985 "Handling plaintext size of tca greater than pread offset.\n")
1986 ;
1987 return 0;
1988 }
1989 if (ntohs (hdr->size) != sizeof(*tca))
1990 {
1992 "Handling plaintext size does not match message type.\n");
1993 GNUNET_break_op (0);
1995 return 0;
1996 }
1997
1998 thas.purpose.purpose = htonl (
2000 thas.purpose.size = htonl (sizeof(thas));
2001 thas.sender = tca->sender;
2002 thas.receiver = my_identity;
2003 thas.monotonic_time = tca->monotonic_time;
2004 thas.challenge = tca->challenge;
2005
2008 &thas,
2009 &tca->sender_sig,
2010 &tca->sender.public_key))
2011 {
2013 "Verification of signature failed!\n");
2014 GNUNET_break (0);
2016 return 0;
2017 }
2018 if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
2019 {
2021 "Challenge in TCPConfirmationAck not correct!\n");
2022 GNUNET_break (0);
2024 return 0;
2025 }
2026
2027 queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iteration_start (
2028 peerstore,
2029 "transport_tcp_communicator",
2030 &queue->target,
2033 queue);
2034
2036 "Handling plaintext, ack processed!\n");
2037
2039 {
2040 send_challenge (queue->challenge_received, queue);
2041 queue->write_task =
2043 queue->sock,
2044 &queue_write,
2045 queue);
2046 }
2047 else if (GNUNET_TRANSPORT_CS_OUTBOUND == queue->cs)
2048 {
2050 queue->address->sa_family, NULL);
2051 }
2052
2057 queue->initial_core_kx_done = GNUNET_YES;
2058
2059 {
2060 char *foreign_addr;
2061
2062 switch (queue->address->sa_family)
2063 {
2064 case AF_INET:
2065 GNUNET_asprintf (&foreign_addr,
2066 "%s-%s",
2068 GNUNET_a2s (queue->address, queue->address_len));
2069 break;
2070
2071 case AF_INET6:
2072 GNUNET_asprintf (&foreign_addr,
2073 "%s-%s",
2075 GNUNET_a2s (queue->address, queue->address_len));
2076 break;
2077
2078 default:
2079 GNUNET_assert (0);
2080 }
2082 &queue->target,
2083 foreign_addr,
2084 UINT16_MAX, /* no MTU */
2086 0, /* Priority */
2087 queue->nt,
2088 queue->cs,
2089 queue->mq);
2090
2091 GNUNET_free (foreign_addr);
2092 }
2093
2094 size = ntohs (hdr->size);
2095 break;
2097 /* Special case: header size excludes box itself! */
2098 box = (const struct TCPBox *) queue->pread_buf;
2099 if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
2100 return 0;
2101 calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
2102 if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
2103 {
2104 GNUNET_break_op (0);
2106 return 0;
2107 }
2108 pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
2109 size = ntohs (hdr->size) + sizeof(*box);
2111 "Handling plaintext, box processed!\n");
2113 "# bytes decrypted with BOX",
2114 size,
2115 GNUNET_NO);
2117 "# messages decrypted with BOX",
2118 1,
2119 GNUNET_NO);
2120 break;
2121
2123 rekey = (const struct TCPRekey *) queue->pread_buf;
2124 if (sizeof(*rekey) > queue->pread_off)
2125 return 0;
2126 if (ntohs (hdr->size) != sizeof(*rekey))
2127 {
2128 GNUNET_break_op (0);
2130 return 0;
2131 }
2132 rekeyz = *rekey;
2133 memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
2134 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
2135 if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac)))
2136 {
2137 GNUNET_break_op (0);
2139 return 0;
2140 }
2141 do_rekey (queue, rekey);
2142 size = ntohs (hdr->size);
2144 "Handling plaintext, rekey processed!\n");
2146 "# rekeying successful",
2147 1,
2148 GNUNET_NO);
2149 break;
2150
2152 fin = (const struct TCPFinish *) queue->pread_buf;
2153 if (sizeof(*fin) > queue->pread_off)
2154 return 0;
2155 if (ntohs (hdr->size) != sizeof(*fin))
2156 {
2157 GNUNET_break_op (0);
2159 return 0;
2160 }
2161 finz = *fin;
2162 memset (&finz.hmac, 0, sizeof(finz.hmac));
2163 calculate_hmac (&queue->in_hmac, &finz, sizeof(finz), &tmac);
2164 if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
2165 {
2166 GNUNET_break_op (0);
2168 return 0;
2169 }
2170 /* handle FINISH by destroying queue */
2173 "Handling plaintext, finish processed!\n");
2174 break;
2175
2176 default:
2178 "Handling plaintext, nothing processed!\n");
2179 GNUNET_break_op (0);
2181 return 0;
2182 }
2183 GNUNET_assert (0 != size);
2184 if (-1 != queue->unverified_size)
2185 queue->unverified_size += size;
2186 return size;
2187}
2188
2189
2195static void
2196queue_read (void *cls)
2197{
2198 struct Queue *queue = cls;
2199 struct GNUNET_TIME_Relative left;
2200 ssize_t rcvd;
2201
2202 queue->read_task = NULL;
2203 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2204 &queue->cread_buf[queue->cread_off],
2205 BUF_SIZE - queue->cread_off);
2207 "Received %zd bytes from TCP queue\n", rcvd);
2208 if (-1 == rcvd)
2209 {
2210 if ((EAGAIN != errno) && (EINTR != errno))
2211 {
2214 return;
2215 }
2216 /* try again */
2217 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2218 if (0 != left.rel_value_us)
2219 {
2220 queue->read_task =
2222 return;
2223 }
2225 "Queue %p was idle for %s, disconnecting\n",
2226 queue,
2229 GNUNET_YES));
2231 return;
2232 }
2233 if (0 == rcvd)
2234 {
2235 /* Orderly shutdown of connection */
2237 "Socket for queue %p seems to have been closed\n", queue);
2239 return;
2240 }
2241 queue->timeout =
2243 queue->cread_off += rcvd;
2244 while ((queue->pread_off < sizeof(queue->pread_buf)) &&
2245 (queue->cread_off > 0))
2246 {
2247 size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
2248 queue->cread_off);
2249 size_t done;
2250 size_t total;
2251 size_t old_pread_off = queue->pread_off;
2252
2253 GNUNET_assert (0 ==
2254 gcry_cipher_decrypt (queue->in_cipher,
2255 &queue->pread_buf[queue->pread_off],
2256 max,
2257 queue->cread_buf,
2258 max));
2259 queue->pread_off += max;
2260 total = 0;
2261 while (0 != (done = try_handle_plaintext (queue)))
2262 {
2263 /* 'done' bytes of plaintext were used, shift buffer */
2264 GNUNET_assert (done <= queue->pread_off);
2265 /* NOTE: this memmove() could possibly sometimes be
2266 avoided if we pass 'total' into try_handle_plaintext()
2267 and use it at an offset into the buffer there! */
2268 memmove (queue->pread_buf,
2269 &queue->pread_buf[done],
2270 queue->pread_off - done);
2271 queue->pread_off -= done;
2272 total += done;
2273 /* The last plaintext was a rekey, abort for now */
2274 if (GNUNET_YES == queue->rekeyed)
2275 break;
2276 }
2277 /* when we encounter a rekey message, the decryption above uses the
2278 wrong key for everything after the rekey; in that case, we have
2279 to re-do the decryption at 'total' instead of at 'max'.
2280 However, we have to take into account that the plaintext buffer may have
2281 already contained data and not jumped too far ahead in the ciphertext.
2282 If there is no rekey and the last message is incomplete (max > total),
2283 it is safe to keep the decryption so we shift by 'max' */
2284 if (GNUNET_YES == queue->rekeyed)
2285 {
2286 max = total - old_pread_off;
2287 queue->rekeyed = GNUNET_NO;
2288 queue->pread_off = 0;
2289 }
2290 memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
2291 queue->cread_off -= max;
2292 }
2293 if (BUF_SIZE == queue->cread_off)
2294 return; /* buffer full, suspend reading */
2295 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2296 if (0 != left.rel_value_us)
2297 {
2298 if (max_queue_length > queue->backpressure)
2299 {
2300 /* continue reading */
2301 queue->read_task =
2303 }
2304 return;
2305 }
2307 "Queue %p was idle for %s, disconnecting\n",
2308 queue,
2311 GNUNET_YES));
2313}
2314
2315
2323static struct sockaddr *
2325 struct sockaddr_in6 v6,
2326 unsigned int port)
2327{
2328 struct sockaddr *in;
2329
2330 v6.sin6_family = AF_INET6;
2331 v6.sin6_port = htons ((uint16_t) port);
2332#if HAVE_SOCKADDR_IN_SIN_LEN
2333 v6.sin6_len = sizeof(struct sockaddr_in6);
2334#endif
2335 v6.sin6_flowinfo = 0;
2336 v6.sin6_scope_id = 0;
2337 in = GNUNET_memdup (&v6, sizeof(v6));
2338 *sock_len = sizeof(struct sockaddr_in6);
2339
2340 return in;
2341}
2342
2343
2351static struct sockaddr *
2353 struct sockaddr_in v4,
2354 unsigned int port)
2355{
2356 struct sockaddr *in;
2357
2358 v4.sin_family = AF_INET;
2359 v4.sin_port = htons ((uint16_t) port);
2360#if HAVE_SOCKADDR_IN_SIN_LEN
2361 v4.sin_len = sizeof(struct sockaddr_in);
2362#endif
2363 in = GNUNET_memdup (&v4, sizeof(v4));
2364 *sock_len = sizeof(struct sockaddr_in);
2365 return in;
2366}
2367
2368
2375static struct PortOnlyIpv4Ipv6 *
2376tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
2377{
2378 struct PortOnlyIpv4Ipv6 *po;
2379 struct sockaddr_in *i4;
2380 struct sockaddr_in6 *i6;
2381 socklen_t sock_len_ipv4;
2382 socklen_t sock_len_ipv6;
2383
2384 /* interpreting value as just a PORT number */
2385 if (*port > UINT16_MAX)
2386 {
2388 "BINDTO specification `%s' invalid: value too large for port\n",
2389 bindto);
2390 return NULL;
2391 }
2392
2393 po = GNUNET_new (struct PortOnlyIpv4Ipv6);
2394
2395 if (GNUNET_YES == disable_v6)
2396 {
2397 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2398 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2399 *port);
2400 po->addr_len_ipv4 = sock_len_ipv4;
2401 }
2402 else
2403 {
2404
2405 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2406 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2407 *port);
2408 po->addr_len_ipv4 = sock_len_ipv4;
2409
2410 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2411 po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
2412 *port);
2413
2414 po->addr_len_ipv6 = sock_len_ipv6;
2415
2416 GNUNET_free (i6);
2417 }
2418
2419 GNUNET_free (i4);
2420
2421 return po;
2422}
2423
2424
2431static char *
2432extract_address (const char *bindto)
2433{
2434 char *addr;
2435 char *start;
2436 char *token;
2437 char *cp;
2438 char *rest = NULL;
2439
2441 "extract address with bindto %s\n",
2442 bindto);
2443
2444 if (NULL == bindto)
2446 "bindto is NULL\n");
2447
2448 cp = GNUNET_strdup (bindto);
2449
2451 "extract address 2\n");
2452
2453 start = cp;
2454 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2455 {
2456 start++; /* skip over '['*/
2457 cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
2458 addr = GNUNET_strdup (start);
2459 }
2460 else
2461 {
2462 token = strtok_r (cp, "]", &rest);
2463 if (strlen (bindto) == strlen (token))
2464 {
2465 token = strtok_r (cp, ":", &rest);
2466 addr = GNUNET_strdup (token);
2467 }
2468 else
2469 {
2470 token++;
2471 addr = GNUNET_strdup (token);
2472 }
2473 }
2474
2476 "tcp address: %s\n",
2477 addr);
2478 GNUNET_free (cp);
2479 return addr;
2480}
2481
2482
2489static unsigned int
2490extract_port (const char *addr_and_port)
2491{
2492 unsigned int port;
2493 char dummy[2];
2494 char *token;
2495 char *addr;
2496 char *colon;
2497 char *cp;
2498 char *rest = NULL;
2499
2500 if (NULL != addr_and_port)
2501 {
2502 cp = GNUNET_strdup (addr_and_port);
2503 token = strtok_r (cp, "]", &rest);
2504 if (strlen (addr_and_port) == strlen (token))
2505 {
2506 colon = strrchr (cp, ':');
2507 if (NULL == colon)
2508 {
2509 GNUNET_free (cp);
2510 return 0;
2511 }
2512 addr = colon;
2513 addr++;
2514 }
2515 else
2516 {
2517 token = strtok_r (NULL, "]", &rest);
2518 if (NULL == token)
2519 {
2520 GNUNET_free (cp);
2521 return 0;
2522 }
2523 else
2524 {
2525 addr = token;
2526 addr++;
2527 }
2528 }
2529
2530
2531 if (1 == sscanf (addr, "%u%1s", &port, dummy))
2532 {
2533 /* interpreting value as just a PORT number */
2534 if (port > UINT16_MAX)
2535 {
2537 "Port `%u' invalid: value too large for port\n",
2538 port);
2539 GNUNET_free (cp);
2540 return 0;
2541 }
2542 }
2543 else
2544 {
2546 "BINDTO specification invalid: last ':' not followed by number\n");
2547 GNUNET_free (cp);
2548 return 0;
2549 }
2550 GNUNET_free (cp);
2551 }
2552 else
2553 {
2555 "return 0\n");
2556 /* interpret missing port as 0, aka pick any free one */
2557 port = 0;
2558 }
2559
2560 return port;
2561}
2562
2563
2571static struct sockaddr *
2572tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2573{
2574 struct sockaddr *in;
2575 unsigned int port;
2576 struct sockaddr_in v4;
2577 struct sockaddr_in6 v6;
2578 char *start;
2579
2580 memset (&v4, 0, sizeof(v4));
2581 start = extract_address (bindto);
2582 GNUNET_assert (NULL != start);
2584 "start %s\n",
2585 start);
2586
2588 "!bindto %s\n",
2589 bindto);
2590
2591
2592 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
2593 {
2594 port = extract_port (bindto);
2595
2597 "port %u\n",
2598 port);
2599
2600 in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
2601 }
2602 else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2603 {
2604 port = extract_port (bindto);
2605 in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
2606 }
2607 else
2608 {
2609 GNUNET_assert (0);
2610 }
2611
2613 return in;
2614}
2615
2616
2625static void
2627 const struct GNUNET_MessageHeader *msg,
2628 void *impl_state)
2629{
2630 struct Queue *queue = impl_state;
2631 uint16_t msize = ntohs (msg->size);
2632 struct TCPBox box;
2634 "In MQ send. Queue finishing: %s; write task running: %s\n",
2635 (GNUNET_YES == queue->finishing) ? "yes" : "no",
2636 (NULL == queue->write_task) ? "yes" : "no");
2637 GNUNET_assert (mq == queue->mq);
2638 queue->mq_awaits_continue = GNUNET_YES;
2639 if (GNUNET_YES == queue->finishing)
2640 return; /* this queue is dying, drop msg */
2641 GNUNET_assert (0 == queue->pwrite_off);
2643 box.header.size = htons (msize);
2644 calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
2645 memcpy (&queue->pwrite_buf[queue->pwrite_off], &box, sizeof(box));
2646 queue->pwrite_off += sizeof(box);
2647 memcpy (&queue->pwrite_buf[queue->pwrite_off], msg, msize);
2648 queue->pwrite_off += msize;
2650 "%lu bytes of plaintext to send\n", queue->pwrite_off);
2651 GNUNET_assert (NULL != queue->sock);
2652 if (NULL == queue->write_task)
2653 queue->write_task =
2655 queue->sock,
2656 &queue_write,
2657 queue);
2658}
2659
2660
2669static void
2670mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
2671{
2672 struct Queue *queue = impl_state;
2673
2674 if (mq == queue->mq)
2675 {
2676 queue->mq = NULL;
2678 }
2679}
2680
2681
2688static void
2689mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2690{
2691 struct Queue *queue = impl_state;
2692
2693 GNUNET_assert (0 != queue->pwrite_off);
2694 queue->pwrite_off = 0;
2695}
2696
2697
2707static void
2708mq_error (void *cls, enum GNUNET_MQ_Error error)
2709{
2710 struct Queue *queue = cls;
2711
2713 "MQ error in queue to %s: %d\n",
2714 GNUNET_i2s (&queue->target),
2715 (int) error);
2717}
2718
2719
2727static void
2729{
2730 queue->nt =
2731 GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
2733 queue_map,
2734 &queue->key,
2735 queue,
2738 "# queues active",
2740 GNUNET_NO);
2741 queue->timeout =
2744 &mq_destroy,
2745 &mq_cancel,
2746 queue,
2747 NULL,
2748 &mq_error,
2749 queue);
2750}
2751
2752
2763static void
2765 const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
2766{
2767 struct TcpHandshakeSignature ths;
2768 struct TCPConfirmation tc;
2769
2770 memcpy (queue->cwrite_buf, c, sizeof(*c));
2771 queue->cwrite_off = sizeof(*c);
2772 /* compute 'tc' and append in encrypted format to cwrite_buf */
2773 tc.sender = my_identity;
2774 tc.monotonic_time =
2777 &tc.challenge,
2778 sizeof(tc.challenge));
2779 ths.purpose.purpose = htonl (
2781 ths.purpose.size = htonl (sizeof(ths));
2782 ths.sender = my_identity;
2783 ths.receiver = queue->target;
2784 ths.ephemeral = *c;
2785 ths.monotonic_time = tc.monotonic_time;
2786 ths.challenge = tc.challenge;
2788 &ths,
2789 &tc.sender_sig);
2790 GNUNET_assert (0 ==
2791 gcry_cipher_encrypt (queue->out_cipher,
2792 &queue->cwrite_buf[queue->cwrite_off],
2793 sizeof(tc),
2794 &tc,
2795 sizeof(tc)));
2796 queue->challenge = tc.challenge;
2797 queue->cwrite_off += sizeof(tc);
2798
2800 "handshake written\n");
2801}
2802
2803
2811static void
2813{
2815 struct GNUNET_ShortHashCode k;
2816
2818 &c, &k);
2819 setup_out_cipher (queue, &k);
2820 transmit_kx (queue, &c);
2821}
2822
2823
2829static void
2830handshake_monotime_store_cb (void *cls, int success)
2831{
2832 struct Queue *queue = cls;
2833 if (GNUNET_OK != success)
2834 {
2836 "Failed to store handshake monotonic time in PEERSTORE!\n");
2837 }
2838 queue->handshake_monotime_sc = NULL;
2839 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
2840}
2841
2842
2850static void
2852 const struct GNUNET_PEERSTORE_Record *record,
2853 const char *emsg)
2854{
2855 struct Queue *queue = cls;
2856 struct GNUNET_TIME_AbsoluteNBO *mtbe;
2857 struct GNUNET_TIME_Absolute mt;
2858 const struct GNUNET_PeerIdentity *pid;
2859 struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
2860
2861 (void) emsg;
2862
2863 handshake_monotonic_time = &queue->handshake_monotonic_time;
2864 pid = &queue->target;
2866 "tcp handshake with us %s\n",
2868 if (NULL == record)
2869 {
2870 queue->handshake_monotime_get = NULL;
2871 return;
2872 }
2874 "tcp handshake from peer %s\n",
2875 GNUNET_i2s (pid));
2876 if (sizeof(*mtbe) != record->value_size)
2877 {
2878 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
2879 GNUNET_break (0);
2880 return;
2881 }
2882 mtbe = record->value;
2883 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
2885 queue->handshake_monotonic_time).abs_value_us)
2886 {
2888 "Queue from %s dropped, handshake monotime in the past\n",
2889 GNUNET_i2s (&queue->target));
2890 GNUNET_break (0);
2891 GNUNET_PEERSTORE_iteration_stop (queue->handshake_ack_monotime_get);
2892 queue->handshake_ack_monotime_get = NULL;
2894 return;
2895 }
2896 queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
2897 "transport_tcp_communicator",
2898 pid,
2900 handshake_monotonic_time,
2901 sizeof(*
2902 handshake_monotonic_time),
2905 &
2907 queue);
2908}
2909
2910
2922static int
2924 struct TCPConfirmation *tc,
2925 char *ibuf)
2926{
2927 struct TcpHandshakeSignature ths;
2929
2931 0 ==
2932 gcry_cipher_decrypt (queue->in_cipher,
2933 tc,
2934 sizeof(*tc),
2935 &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
2936 sizeof(*tc)));
2937 ths.purpose.purpose = htonl (
2939 ths.purpose.size = htonl (sizeof(ths));
2940 ths.sender = tc->sender;
2941 ths.receiver = my_identity;
2942 memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
2943 ths.monotonic_time = tc->monotonic_time;
2944 ths.challenge = tc->challenge;
2947 &ths,
2948 &tc->sender_sig,
2949 &tc->sender.public_key);
2950 if (GNUNET_YES == ret)
2951 queue->handshake_monotime_get =
2953 "transport_tcp_communicator",
2954 &queue->target,
2957 queue);
2958 return ret;
2959}
2960
2961
2969static void
2970queue_read_kx (void *cls)
2971{
2972 struct Queue *queue = cls;
2973 ssize_t rcvd;
2974 struct GNUNET_TIME_Relative left;
2975 struct TCPConfirmation tc;
2976
2977 queue->read_task = NULL;
2978 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2979 if (0 == left.rel_value_us)
2980 {
2982 return;
2983 }
2984 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2985 &queue->cread_buf[queue->cread_off],
2986 BUF_SIZE - queue->cread_off);
2988 "Received %lu bytes to write in buffer of size %lu for KX from queue %p (expires in %"
2989 PRIu64 ")\n",
2990 rcvd, BUF_SIZE - queue->cread_off, queue, left.rel_value_us);
2991 if (-1 == rcvd)
2992 {
2993 if ((EAGAIN != errno) && (EINTR != errno))
2994 {
2997 return;
2998 }
2999 queue->read_task =
3001 return;
3002 }
3003 if (0 == rcvd)
3004 {
3005 /* Orderly shutdown of connection */
3007 "Socket for queue %p seems to have been closed\n", queue);
3009 return;
3010 }
3011 queue->cread_off += rcvd;
3012 if (queue->cread_off < INITIAL_KX_SIZE)
3013 {
3014 /* read more */
3016 "%lu/%lu bytes of KX read. Rescheduling...\n",
3017 queue->cread_off, INITIAL_KX_SIZE);
3018 queue->read_task =
3020 return;
3021 }
3022 /* we got all the data, let's find out who we are talking to! */
3024 (const struct GNUNET_CRYPTO_HpkeEncapsulation*)
3025 queue->cread_buf,
3026 queue);
3027 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
3028 {
3030 "Invalid TCP KX received from %s\n",
3031 GNUNET_a2s (queue->address, queue->address_len));
3033 return;
3034 }
3035 if (0 !=
3036 memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
3037 {
3039 "Invalid sender in TCP KX received from %s\n",
3040 GNUNET_a2s (queue->address, queue->address_len));
3042 return;
3043 }
3044 send_challenge (tc.challenge, queue);
3045 queue->write_task =
3047 queue->sock,
3048 &queue_write,
3049 queue);
3050
3051 /* update queue timeout */
3052 queue->timeout =
3054 /* prepare to continue with regular read task immediately */
3055 memmove (queue->cread_buf,
3056 &queue->cread_buf[INITIAL_KX_SIZE],
3057 queue->cread_off - (INITIAL_KX_SIZE));
3059 "cread_off is %lu bytes before adjusting\n",
3060 queue->cread_off);
3061 queue->cread_off -= INITIAL_KX_SIZE;
3063 "cread_off set to %lu bytes\n",
3064 queue->cread_off);
3066}
3067
3068
3075static void
3076proto_read_kx (void *cls)
3077{
3078 struct ProtoQueue *pq = cls;
3079 ssize_t rcvd;
3080 struct GNUNET_TIME_Relative left;
3081 struct Queue *queue;
3082 struct TCPConfirmation tc;
3084
3085 pq->read_task = NULL;
3087 if (0 == left.rel_value_us)
3088 {
3089 free_proto_queue (pq);
3090 return;
3091 }
3092 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
3093 &pq->ibuf[pq->ibuf_off],
3094 sizeof(pq->ibuf) - pq->ibuf_off);
3096 "Proto received %lu bytes for KX\n", rcvd);
3097 if (-1 == rcvd)
3098 {
3099 if ((EAGAIN != errno) && (EINTR != errno))
3100 {
3102 free_proto_queue (pq);
3103 return;
3104 }
3105 /* try again */
3106 pq->read_task =
3108 return;
3109 }
3110 if (0 == rcvd)
3111 {
3112 /* Orderly shutdown of connection */
3114 "Socket for proto queue %p seems to have been closed\n", pq);
3115 free_proto_queue (pq);
3116 return;
3117 }
3118 pq->ibuf_off += rcvd;
3119 if (sizeof (struct TCPNATProbeMessage) == pq->ibuf_off)
3120 {
3121 struct TCPNATProbeMessage *pm = (struct TCPNATProbeMessage *) pq->ibuf;
3122
3124 &pm->clientIdentity);
3125
3126 queue = GNUNET_new (struct Queue);
3127 queue->target = pm->clientIdentity;
3128 eddsa_pub_to_hpke_key (&queue->target.public_key,
3129 &queue->target_hpke_key);
3132 }
3133 else if (pq->ibuf_off > sizeof(pq->ibuf))
3134 {
3135 /* read more */
3136 pq->read_task =
3138 return;
3139 }
3140 else
3141 {
3142 /* we got all the data, let's find out who we are talking to! */
3143 queue = GNUNET_new (struct Queue);
3145 (const struct GNUNET_CRYPTO_HpkeEncapsulation *) pq->
3146 ibuf,
3147 queue);
3148 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
3149 {
3151 "Invalid TCP KX received from %s\n",
3152 GNUNET_a2s (pq->address, pq->address_len));
3153 gcry_cipher_close (queue->in_cipher);
3155 free_proto_queue (pq);
3156 return;
3157 }
3158 queue->target = tc.sender;
3159 eddsa_pub_to_hpke_key (&queue->target.public_key,
3160 &queue->target_hpke_key);
3163 }
3164 queue->address = pq->address; /* steals reference */
3165 queue->address_len = pq->address_len;
3166 queue->listen_sock = pq->listen_sock;
3167 queue->sock = pq->sock;
3168
3170 "created queue with target %s\n",
3171 GNUNET_i2s (&queue->target));
3172
3174 "start kx proto\n");
3175
3177 boot_queue (queue);
3178 queue->read_task =
3180 queue->sock,
3181 read_task,
3182 queue);
3183 queue->write_task =
3185 queue->sock,
3186 &queue_write,
3187 queue);
3188 // TODO To early! Move it somewhere else.
3189 // send_challenge (tc.challenge, queue);
3190 queue->challenge_received = tc.challenge;
3191
3193 GNUNET_free (pq);
3194}
3195
3196
3197static struct ProtoQueue *
3199 struct sockaddr *in,
3200 socklen_t addrlen)
3201{
3202 struct ProtoQueue *pq = GNUNET_new (struct ProtoQueue);
3203
3204 if (NULL == sock)
3205 {
3206 // sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, addr, addrlen);
3207 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, 0);
3208 if (NULL == sock)
3209 {
3211 "socket(%d) failed: %s",
3212 in->sa_family,
3213 strerror (errno));
3214 GNUNET_free (in);
3215 GNUNET_free (pq);
3216 return NULL;
3217 }
3218 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, addrlen)) &&
3219 (errno != EINPROGRESS))
3220 {
3222 "connect to `%s' failed: %s",
3223 GNUNET_a2s (in, addrlen),
3224 strerror (errno));
3226 GNUNET_free (in);
3227 GNUNET_free (pq);
3228 return NULL;
3229 }
3230 }
3231 pq->address_len = addrlen;
3232 pq->address = in;
3234 pq->sock = sock;
3236 pq->sock,
3238 pq);
3240
3241 return pq;
3242}
3243
3244
3252static void
3253listen_cb (void *cls)
3254{
3255 struct sockaddr_storage in;
3256 socklen_t addrlen;
3257 struct GNUNET_NETWORK_Handle *sock;
3258 struct ListenTask *lt;
3259 struct sockaddr *in_addr;
3260
3262 "listen_cb\n");
3263
3264 lt = cls;
3265
3266 lt->listen_task = NULL;
3267 GNUNET_assert (NULL != lt->listen_sock);
3268 addrlen = sizeof(in);
3269 memset (&in, 0, sizeof(in));
3271 (struct sockaddr*) &in,
3272 &addrlen);
3273 if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
3274 return; /* system limit reached, wait until connection goes down */
3276 lt->listen_sock,
3277 &listen_cb,
3278 lt);
3279 if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
3280 return;
3281 if (NULL == sock)
3282 {
3284 return;
3285 }
3286 in_addr = GNUNET_memdup (&in, addrlen);
3287 create_proto_queue (sock, in_addr, addrlen);
3288}
3289
3290
3291static void
3293 const struct sockaddr *addr,
3294 socklen_t addrlen)
3295{
3296 struct TCPNATProbeMessage pm;
3297 struct ProtoQueue *pq;
3298 struct sockaddr *in_addr;
3299 (void) cls;
3300
3302 "addr->sa_family %d\n",
3303 addr->sa_family);
3305 "Try to connect back\n");
3306 in_addr = GNUNET_memdup (addr, addrlen);
3308 "in_addr->sa_family %d\n",
3309 in_addr->sa_family);
3310 pq = create_proto_queue (NULL, in_addr, addrlen);
3311 if (NULL != pq)
3312 {
3313 pm.header.size = htons (sizeof(struct TCPNATProbeMessage));
3314 pm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE);
3315 pm.clientIdentity = my_identity;
3316 memcpy (pq->write_buf, &pm, sizeof(struct TCPNATProbeMessage));
3317 pq->write_off = sizeof(struct TCPNATProbeMessage);
3319 pq->sock,
3321 pq);
3322 }
3323 else
3324 {
3326 "Couldn't create ProtoQueue for sending TCPNATProbeMessage\n");
3327 }
3328}
3329
3330
3331static void
3333{
3334 struct sockaddr *in = cls;
3335 struct PendingReversal *pending_reversal;
3336 struct GNUNET_HashCode key;
3337
3339 sizeof(struct sockaddr),
3340 &key);
3342 &key);
3343
3344 GNUNET_assert (NULL != pending_reversal);
3345
3347 &key,
3348 pending_reversal))
3350 "No pending reversal found for address %s\n",
3351 GNUNET_a2s (in, sizeof (struct sockaddr)));
3352 GNUNET_free (pending_reversal->in);
3353 GNUNET_free (pending_reversal);
3354}
3355
3356
3375static int
3376mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3377{
3378 struct sockaddr *in;
3379 socklen_t in_len = 0;
3380 const char *path;
3381 struct sockaddr_in *v4;
3382 struct sockaddr_in6 *v6;
3383 unsigned int is_natd = GNUNET_NO;
3384 struct GNUNET_HashCode key;
3385 struct GNUNET_HashCode queue_map_key;
3386 struct GNUNET_HashContext *hsh;
3387 struct Queue *queue;
3388
3390 "Connecting to %s at %s\n",
3391 GNUNET_i2s (peer),
3392 address);
3393 if (0 != strncmp (address,
3395 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
3396 {
3397 GNUNET_break_op (0);
3398 return GNUNET_SYSERR;
3399 }
3400 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
3401 in = tcp_address_to_sockaddr (path, &in_len);
3402
3403 if (NULL == in)
3404 {
3406 "Failed to setup TCP socket address\n");
3407 return GNUNET_SYSERR;
3408 }
3409
3411 "in %s\n",
3412 GNUNET_a2s (in, in_len));
3413
3416 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof (*peer));
3417 GNUNET_CRYPTO_hash_context_finish (hsh, &queue_map_key);
3419
3420 if (NULL != queue)
3421 {
3423 "Queue for %s already exists or is in construction\n", address);
3424 GNUNET_free (in);
3425 return GNUNET_NO;
3426 }
3427 switch (in->sa_family)
3428 {
3429 case AF_INET:
3430 v4 = (struct sockaddr_in *) in;
3431 if (0 == v4->sin_port)
3432 {
3433 is_natd = GNUNET_YES;
3435 sizeof(struct sockaddr),
3436 &key);
3439 &key))
3440 {
3442 "There is already a request reversal for `%s'at `%s'\n",
3443 GNUNET_i2s (peer),
3444 address);
3445 GNUNET_free (in);
3446 return GNUNET_SYSERR;
3447 }
3448 }
3449 break;
3450
3451 case AF_INET6:
3452 if (GNUNET_YES == disable_v6)
3453 {
3455 "IPv6 disabled, skipping %s\n", address);
3456 GNUNET_free (in);
3457 return GNUNET_SYSERR;
3458 }
3459 v6 = (struct sockaddr_in6 *) in;
3460 if (0 == v6->sin6_port)
3461 {
3463 "Request reversal for `%s' at `%s' not possible for an IPv6 address\n",
3464 GNUNET_i2s (peer),
3465 address);
3466 GNUNET_free (in);
3467 return GNUNET_SYSERR;
3468 }
3469 break;
3470
3471 default:
3472 GNUNET_assert (0);
3473 }
3474
3475 if (GNUNET_YES == is_natd)
3476 {
3477 struct sockaddr_in local_sa;
3478 struct PendingReversal *pending_reversal;
3479
3480 memset (&local_sa, 0, sizeof(local_sa));
3481 local_sa.sin_family = AF_INET;
3482 local_sa.sin_port = htons (bind_port);
3483 /* We leave sin_address at 0, let the kernel figure it out,
3484 even if our bind() is more specific. (May want to reconsider
3485 later.) */
3486 if (GNUNET_OK != GNUNET_NAT_request_reversal (nat, &local_sa, v4))
3487 {
3489 "request reversal for `%s' at `%s' failed\n",
3490 GNUNET_i2s (peer),
3491 address);
3492 GNUNET_free (in);
3493 return GNUNET_SYSERR;
3494 }
3495 pending_reversal = GNUNET_new (struct PendingReversal);
3496 pending_reversal->in = in;
3499 &key,
3500 pending_reversal,
3502 pending_reversal->target = *peer;
3504 &
3506 in);
3508 "Created NAT WAIT connection to `%s' at `%s'\n",
3509 GNUNET_i2s (peer),
3510 GNUNET_a2s (in, sizeof (struct sockaddr)));
3511 }
3512 else
3513 {
3514 struct GNUNET_NETWORK_Handle *sock;
3515
3516 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM,
3517 IPPROTO_TCP);
3518 if (NULL == sock)
3519 {
3521 "socket(%d) failed: %s",
3522 in->sa_family,
3523 strerror (errno));
3524 GNUNET_free (in);
3525 return GNUNET_SYSERR;
3526 }
3527 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) &&
3528 (errno != EINPROGRESS))
3529 {
3531 "connect to `%s' failed: %s",
3532 address,
3533 strerror (errno));
3535 GNUNET_free (in);
3536 return GNUNET_SYSERR;
3537 }
3538
3539 queue = GNUNET_new (struct Queue);
3540 queue->target = *peer;
3541 eddsa_pub_to_hpke_key (&queue->target.public_key, &queue->target_hpke_key);
3542 queue->key = queue_map_key;
3543 queue->address = in;
3544 queue->address_len = in_len;
3545 queue->sock = sock;
3547 boot_queue (queue);
3549 "booted queue with target %s\n",
3550 GNUNET_i2s (&queue->target));
3551 // queue->mq_awaits_continue = GNUNET_YES;
3552 queue->read_task =
3554 queue->sock,
3556 queue);
3557
3558
3560 "start kx mq_init\n");
3561
3563 queue->write_task =
3565 queue->sock,
3566 &queue_write,
3567 queue);
3568 }
3569
3570 return GNUNET_OK;
3571}
3572
3573
3582static int
3584 const struct GNUNET_HashCode *key,
3585 void *value)
3586{
3587 struct ListenTask *lt = value;
3588
3589 (void) cls;
3590 (void) key;
3591 if (NULL != lt->listen_task)
3592 {
3594 lt->listen_task = NULL;
3595 }
3596 if (NULL != lt->listen_sock)
3597 {
3599 lt->listen_sock = NULL;
3600 }
3601 GNUNET_free (lt);
3602 return GNUNET_OK;
3603}
3604
3605
3614static int
3616 const struct GNUNET_HashCode *target,
3617 void *value)
3618{
3619 struct Queue *queue = value;
3620
3621 (void) cls;
3622 (void) target;
3624 return GNUNET_OK;
3625}
3626
3627
3633static void
3634do_shutdown (void *cls)
3635{
3637 "Shutdown %s!\n",
3638 shutdown_running ? "running" : "not running");
3639
3641 return;
3642 else
3644
3645 while (NULL != proto_head)
3647 if (NULL != nat)
3648 {
3650 nat = NULL;
3651 }
3659 if (NULL != ch)
3660 {
3663 ch = NULL;
3664 }
3665 if (NULL != stats)
3666 {
3668 stats = NULL;
3669 }
3670 if (NULL != my_private_key)
3671 {
3673 my_private_key = NULL;
3674 }
3675 if (NULL != is)
3676 {
3678 is = NULL;
3679 }
3680 if (NULL != pils)
3681 {
3683 pils = NULL;
3684 }
3685 if (NULL != peerstore)
3686 {
3688 peerstore = NULL;
3689 }
3690 if (NULL != resolve_request_handle)
3691 {
3694 }
3696 "Shutdown done!\n");
3697}
3698
3699
3711static void
3712enc_notify_cb (void *cls,
3713 const struct GNUNET_PeerIdentity *sender,
3714 const struct GNUNET_MessageHeader *msg)
3715{
3716 (void) cls;
3717 (void) sender;
3718 (void) msg;
3719 GNUNET_break_op (0);
3720}
3721
3722
3736static void
3738 void **app_ctx,
3739 int add_remove,
3741 const struct sockaddr *addr,
3742 socklen_t addrlen)
3743{
3744 char *my_addr;
3746
3748 "nat address cb %s %s\n",
3749 add_remove ? "add" : "remove",
3750 GNUNET_a2s (addr, addrlen));
3751
3752 if (GNUNET_YES == add_remove)
3753 {
3755
3756 GNUNET_asprintf (&my_addr,
3757 "%s-%s",
3759 GNUNET_a2s (addr, addrlen));
3760 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3761 ai =
3763 my_addr,
3764 nt,
3766 GNUNET_free (my_addr);
3767 *app_ctx = ai;
3768 }
3769 else
3770 {
3771 ai = *app_ctx;
3773 *app_ctx = NULL;
3774 }
3775}
3776
3777
3781static void
3782add_addr (struct sockaddr *in, socklen_t in_len)
3783{
3784
3785 struct Addresses *saddrs;
3786
3788 "add address %s\n",
3789 GNUNET_a2s (in, in_len));
3790
3791 saddrs = GNUNET_new (struct Addresses);
3792 saddrs->addr = in;
3793 saddrs->addr_len = in_len;
3795
3797 "after add address %s\n",
3798 GNUNET_a2s (in, in_len));
3799
3801 "add address %s\n",
3802 GNUNET_a2s (saddrs->addr, saddrs->addr_len));
3803
3804 addrs_lens++;
3805}
3806
3807
3818static void
3820{
3821 char *keyfile;
3823
3824 if (GNUNET_OK !=
3826 "PEER",
3827 "PRIVATE_KEY",
3828 &keyfile))
3829 {
3831 "PEER",
3832 "PRIVATE_KEY");
3834 return;
3835 }
3836 if (GNUNET_SYSERR ==
3838 GNUNET_YES,
3839 &key))
3840 {
3842 "Failed to setup peer's private key\n");
3843 GNUNET_free (keyfile);
3845 return;
3846 }
3847 GNUNET_free (keyfile);
3848 GNUNET_assert (sizeof ikm == sizeof key.d);
3849 memcpy (ikm, key.d, sizeof ikm);
3850}
3851
3852
3860static int
3861init_socket (struct sockaddr *addr,
3862 socklen_t in_len)
3863{
3864 struct sockaddr_storage in_sto;
3865 socklen_t sto_len;
3866 struct GNUNET_NETWORK_Handle *listen_sock;
3867 struct ListenTask *lt;
3868 int sockfd;
3869 struct GNUNET_HashCode h_sock;
3870
3871 if (NULL == addr)
3872 {
3874 "Address is NULL.\n");
3875 return GNUNET_SYSERR;
3876 }
3877
3879 "address %s\n",
3880 GNUNET_a2s (addr, in_len));
3881
3882 listen_sock =
3883 GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
3884 if (NULL == listen_sock)
3885 {
3887 return GNUNET_SYSERR;
3888 }
3889
3890 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
3891 {
3893 GNUNET_NETWORK_socket_close (listen_sock);
3894 listen_sock = NULL;
3895 return GNUNET_SYSERR;
3896 }
3897
3898 if (GNUNET_OK !=
3899 GNUNET_NETWORK_socket_listen (listen_sock,
3900 5))
3901 {
3903 "listen");
3904 GNUNET_NETWORK_socket_close (listen_sock);
3905 listen_sock = NULL;
3906 return GNUNET_SYSERR;
3907 }
3908
3909 /* We might have bound to port 0, allowing the OS to figure it out;
3910 thus, get the real IN-address from the socket */
3911 sto_len = sizeof(in_sto);
3912
3913 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
3914 (struct sockaddr *) &in_sto,
3915 &sto_len))
3916 {
3917 memcpy (&in_sto, addr, in_len);
3918 sto_len = in_len;
3919 }
3920
3921 // addr = (struct sockaddr *) &in_sto;
3922 in_len = sto_len;
3924 "Bound to `%s'\n",
3925 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
3926 if (NULL == stats)
3927 stats = GNUNET_STATISTICS_create ("communicator-tcp", cfg);
3928
3929 if (NULL == is)
3931
3932 /* start listening */
3933
3934 lt = GNUNET_new (struct ListenTask);
3935 lt->listen_sock = listen_sock;
3936
3938 listen_sock,
3939 &listen_cb,
3940 lt);
3941
3943 "creating hash\n");
3944 sockfd = GNUNET_NETWORK_get_fd (lt->listen_sock);
3945 GNUNET_CRYPTO_hash (&sockfd,
3946 sizeof(int),
3947 &h_sock);
3948
3950 "creating map\n");
3951 if (NULL == lt_map)
3953
3955 "creating map entry\n");
3958 &h_sock,
3959 lt,
3961
3963 "map entry created\n");
3964
3965 if (NULL == queue_map)
3967
3968 if (NULL == ch)
3973 &mq_init,
3974 NULL,
3976 NULL,
3977 NULL);
3978
3979 if (NULL == ch)
3980 {
3981 GNUNET_break (0);
3982 if (NULL != resolve_request_handle)
3985 return GNUNET_SYSERR;
3986 }
3987
3988 add_addr (addr, in_len);
3989 return GNUNET_OK;
3990
3991}
3992
3993
3997static void
3999{
4000 struct sockaddr **saddrs;
4001 socklen_t *saddr_lens;
4002 int i;
4003 size_t len;
4004
4006 "starting nat register!\n");
4007 len = 0;
4008 i = 0;
4009 saddrs = GNUNET_malloc ((addrs_lens) * sizeof(struct sockaddr *));
4010 saddr_lens = GNUNET_malloc ((addrs_lens) * sizeof(socklen_t));
4011 for (struct Addresses *pos = addrs_head; NULL != pos; pos = pos->next)
4012 {
4014 "registering address %s\n",
4015 GNUNET_a2s (pos->addr, pos->addr_len));
4016
4017 saddr_lens[i] = pos->addr_len;
4018 len += saddr_lens[i];
4019 saddrs[i] = GNUNET_memdup (pos->addr, saddr_lens[i]);
4020 i++;
4021 }
4022
4024 "registering addresses %lu %lu %lu %lu\n",
4025 (addrs_lens) * sizeof(struct sockaddr *),
4026 (addrs_lens) * sizeof(socklen_t),
4027 len,
4031 IPPROTO_TCP,
4032 addrs_lens,
4033 (const struct sockaddr **) saddrs,
4034 saddr_lens,
4037 NULL /* closure */);
4038 for (i = addrs_lens - 1; i >= 0; i--)
4039 GNUNET_free (saddrs[i]);
4040 GNUNET_free (saddrs);
4041 GNUNET_free (saddr_lens);
4042
4043 if (NULL == nat)
4044 {
4045 GNUNET_break (0);
4046 if (NULL != resolve_request_handle)
4049 }
4050}
4051
4052
4060static void
4062 const struct sockaddr *addr,
4063 socklen_t in_len)
4064{
4065 struct sockaddr_in *v4;
4066 struct sockaddr_in6 *v6;
4067 struct sockaddr *in;
4068
4069 (void) cls;
4070 if (NULL != addr)
4071 {
4072 if (AF_INET == addr->sa_family)
4073 {
4074 v4 = (struct sockaddr_in *) addr;
4075 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, *v4, bind_port);// _global);
4076 }
4077 else if (AF_INET6 == addr->sa_family)
4078 {
4079 v6 = (struct sockaddr_in6 *) addr;
4080 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, *v6, bind_port);// _global);
4081 }
4082 else
4083 {
4085 "Address family %u not suitable (not AF_INET %u nor AF_INET6 %u \n",
4086 addr->sa_family,
4087 AF_INET,
4088 AF_INET6);
4089 return;
4090 }
4091 init_socket (in, in_len);
4092 }
4093 else
4094 {
4096 "Address is NULL. This might be an error or the resolver finished resolving.\n");
4097 if (NULL == addrs_head)
4098 {
4100 "Resolver finished resolving, but we do not listen to an address!.\n");
4101 return;
4102 }
4103 nat_register ();
4104 }
4105}
4106
4107
4108void
4109pid_change_cb (void *cls,
4110 const struct GNUNET_HELLO_Parser *parser,
4111 const struct GNUNET_HashCode *addr_hash)
4112{
4114 "Got PID to derive from `%s':\n",
4115 GNUNET_h2s (addr_hash));
4116 if (NULL == my_private_key)
4118
4120 (uint8_t*) ikm,
4121 addr_hash,
4127}
4128
4129
4138static void
4139run (void *cls,
4140 char *const *args,
4141 const char *cfgfile,
4142 const struct GNUNET_CONFIGURATION_Handle *c)
4143{
4144 char *bindto;
4145 struct sockaddr *in;
4146 socklen_t in_len;
4147 struct sockaddr_in v4;
4148 struct sockaddr_in6 v6;
4149 char *start;
4150 unsigned int port;
4151 char dummy[2];
4152 char *rest = NULL;
4153 struct PortOnlyIpv4Ipv6 *po;
4154 socklen_t addr_len_ipv4;
4155 socklen_t addr_len_ipv6;
4156
4157 (void) cls;
4158
4160 memset (&v4,0,sizeof(struct sockaddr_in));
4161 memset (&v6,0,sizeof(struct sockaddr_in6));
4162 cfg = c;
4163 if (GNUNET_OK !=
4166 "BINDTO",
4167 &bindto))
4168 {
4171 "BINDTO");
4172 return;
4173 }
4174 if (GNUNET_OK !=
4177 "MAX_QUEUE_LENGTH",
4179 {
4181 }
4182 if (GNUNET_OK !=
4185 "REKEY_INTERVAL",
4187 {
4189 }
4190 if (GNUNET_OK !=
4193 "REKEY_MAX_BYTES",
4195 {
4197 }
4199 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
4200 (GNUNET_YES ==
4203 "DISABLE_V6")))
4204 {
4206 }
4207 load_ikm ();
4209 GNUNET_assert (NULL != pils);
4211 if (NULL == peerstore)
4212 {
4213 GNUNET_free (bindto);
4214 GNUNET_break (0);
4216 return;
4217 }
4218
4220
4221 if (1 == sscanf (bindto, "%u%1s", &bind_port, dummy))
4222 {
4226 "address po %s\n",
4228 if (NULL != po->addr_ipv4)
4229 {
4231 }
4232 if (NULL != po->addr_ipv6)
4233 {
4236 }
4237 GNUNET_free (po);
4238 nat_register ();
4239 GNUNET_free (bindto);
4240 return;
4241 }
4242
4243 start = extract_address (bindto);
4244 // FIXME: check for NULL == start...
4245 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
4246 {
4247 bind_port = extract_port (bindto);
4248
4250 init_socket (in, in_len);
4251 nat_register ();
4253 GNUNET_free (bindto);
4254 return;
4255 }
4256
4257 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
4258 {
4259 bind_port = extract_port (bindto);
4261 init_socket (in, in_len);
4262 nat_register ();
4264 GNUNET_free (bindto);
4265 return;
4266 }
4267
4268 bind_port = extract_port (bindto);
4270 ":",
4271 &rest),
4272 AF_UNSPEC,
4275 &port);
4276
4277 GNUNET_free (bindto);
4279}
4280
4281
4289int
4290main (int argc, char *const *argv)
4291{
4292 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4294 };
4295 int ret;
4296
4298 "Starting tcp communicator\n");
4299
4300 ret = (GNUNET_OK ==
4302 argc,
4303 argv,
4304 "gnunet-communicator-tcp",
4305 _ ("GNUnet TCP communicator"),
4306 options,
4307 &run,
4308 NULL))
4309 ? 0
4310 : 1;
4311 return ret;
4312}
4313
4314
4315/* end of gnunet-communicator-tcp.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MessageHeader * msg
Definition 005.c:2
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static uint16_t port
Port number.
Definition gnunet-bcd.c:146
void pid_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
static void calculate_hmac(struct GNUNET_HashCode *hmac_secret, const void *buf, size_t buf_size, struct GNUNET_ShortHashCode *smac)
Compute mac over buf, and ratched the hmac_secret.
static void queue_finish(struct Queue *queue)
Append a 'finish' message to the outgoing transmission.
static void transmit_kx(struct Queue *queue, const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
Generate and transmit our ephemeral key and the signature for the initial KX with the other peer.
static void boot_queue(struct Queue *queue)
Add the given queue to our internal data structure.
static unsigned int bind_port
The port the communicator should be assigned to.
static size_t try_handle_plaintext(struct Queue *queue)
Test if we have received a full message in plaintext.
static void pass_plaintext_to_core(struct Queue *queue, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext on queue.
static struct sockaddr * tcp_address_to_sockaddr_numeric_v6(socklen_t *sock_len, struct sockaddr_in6 v6, unsigned int port)
Convert a struct sockaddr_in6 to astruct sockaddr *`.
static struct GNUNET_PeerIdentity my_identity
Our public key.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static unsigned char ikm[256/8]
The initial key material for the peer.
static void mq_destroy(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static struct PortOnlyIpv4Ipv6 * tcp_address_to_sockaddr_port_only(const char *bindto, unsigned int *port)
Convert TCP bind specification to a struct PortOnlyIpv4Ipv6 *
static void setup_in_cipher(const struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral, struct Queue *queue)
Setup cipher of queue for decryption.
#define INITIAL_CORE_KX_SIZE
Size of the initial core key exchange messages.
static void do_rekey(struct Queue *queue, const struct TCPRekey *rekey)
Handle rekey message on queue.
static struct ProtoQueue * create_proto_queue(struct GNUNET_NETWORK_Handle *sock, struct sockaddr *in, socklen_t addrlen)
static int init_socket(struct sockaddr *addr, socklen_t in_len)
This method launch network interactions for each address we like to bind to.
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static void listen_cb(void *cls)
We have been notified that our listen socket has something to read.
static void rekey_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY where...
static int disable_v6
IPv6 disabled.
static struct GNUNET_CONTAINER_MultiHashMap * pending_reversals
Map of pending reversals.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static void queue_destroy(struct Queue *queue)
Functions with this signature are called whenever we need to close a queue due to a disconnect or fai...
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 an acknowledgement for this communicator (!...
static void handshake_ack_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for handshake ack monotime value is finished.
static struct GNUNET_PEERSTORE_Handle * peerstore
Database for peer's HELLOs.
static int pending_reversals_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
static struct ProtoQueue * proto_tail
Protoqueues DLL tail.
static void queue_read_kx(void *cls)
Read from the socket of the queue until we have enough data to initialize the decryption logic and ca...
static int get_lt_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over all ListenTasks to clean up.
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
#define NAT_TIMEOUT
How long until we give up on establishing an NAT connection? Must be > 4 RTT.
#define BUF_SIZE
Size of our IO buffers for ciphertext data.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static struct GNUNET_CONTAINER_MultiHashMap * queue_map
Queues (map from peer identity to struct Queue)
static void proto_read_kx(void *cls)
Read from the socket of the proto queue until we have enough data to upgrade to full queue.
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 sockaddr * tcp_address_to_sockaddr_numeric_v4(socklen_t *sock_len, struct sockaddr_in v4, unsigned int port)
Convert a struct sockaddr_in4 to astruct sockaddr *`.
static void check_and_remove_pending_reversal(struct sockaddr *in, sa_family_t sa_family, struct GNUNET_PeerIdentity *sender)
static void init_socket_resolv(void *cls, const struct sockaddr *addr, socklen_t in_len)
This method is the callback called by the resolver API, and wraps method init_socket.
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
static unsigned long long max_queue_length
Maximum queue length before we stop reading towards the transport service.
static void setup_cipher(const struct GNUNET_ShortHashCode *prk, const struct GNUNET_PeerIdentity *pid, gcry_cipher_hd_t *cipher, struct GNUNET_HashCode *hmac_key)
Setup cipher based on shared secret dh and decrypting peer pid.
struct GNUNET_RESOLVER_RequestHandle * resolve_request_handle
Handle for DNS lookup of bindto address.
static void nat_register()
This method reads from the DLL addrs_head to register them at the NAT service.
static void setup_out_cipher(struct Queue *queue, struct GNUNET_ShortHashCode *dh)
Setup cipher for outgoing data stream based on target and our ephemeral private key.
static int addrs_lens
Number of addresses in the DLL for register at NAT service.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
static struct GNUNET_CRYPTO_HpkePrivateKey my_x25519_private_key
Our private key.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static void pending_reversal_timeout(void *cls)
static void load_ikm()
Get the initial secret key for generating the peer id.
#define PROTO_QUEUE_TIMEOUT
How long do we wait until we must have received the initial KX?
static void queue_read(void *cls)
Queue read task.
#define REKEY_MAX_BYTES
How often do we rekey based on number of bytes transmitted? (additionally randomized).
static int get_queue_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all message queues to clean up.
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
#define INITIAL_KX_SIZE
Size of the initial key exchange message sent first in both directions.
static void handshake_ack_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_A...
static void eddsa_pub_to_hpke_key(struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_HpkePublicKey *pk)
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 proto_queue_write(void *cls)
We have been notified that our socket is ready to write.
static void eddsa_priv_to_hpke_key(struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
static void handshake_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for handshake monotime is finished.
static void send_challenge(struct GNUNET_CRYPTO_ChallengeNonceP challenge, struct Queue *queue)
Sending challenge with TcpConfirmationAck back to sender of ephemeral key.
static void rekey_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for rekey monotime value is finished.
static char * extract_address(const char *bindto)
This Method extracts the address part of the BINDTO string.
static struct ProtoQueue * proto_head
Protoqueues DLL head.
static int shutdown_running
A flag indicating we are already doing a shutdown.
static int decrypt_and_check_tc(struct Queue *queue, struct TCPConfirmation *tc, char *ibuf)
We have received the first bytes from the other side on a queue.
#define LOG(kind,...)
#define DEFAULT_REKEY_INTERVAL
How often do we rekey based on time (at least)
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
static void queue_write(void *cls)
We have been notified that our socket is ready to write.
static void add_addr(struct sockaddr *in, socklen_t in_len)
This method adds addresses to the DLL, that are later register at the NAT service.
static void handshake_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE w...
static struct Addresses * addrs_head
Head of DLL with addresses we like to register at NAT service.
static struct sockaddr * tcp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert TCP bind specification to a struct sockaddr *
static struct Addresses * addrs_tail
Head of DLL with addresses we like to register at NAT service.
static void setup_in_cipher_elligator(const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct Queue *queue)
Setup cipher of queue for decryption from an elligator representative.
#define DEFAULT_MAX_QUEUE_LENGTH
How many messages do we keep at most in the queue to the transport service before we start to drop (d...
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 unsigned int extract_port(const char *addr_and_port)
This Method extracts the port part of the BINDTO string.
static void mq_send(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static struct GNUNET_PILS_Handle * pils
For PILS.
static void start_initial_kx_out(struct Queue *queue)
Initialize our key material for outgoing transmissions and inform the other peer about it.
static void free_proto_queue(struct ProtoQueue *pq)
Closes socket and frees memory associated with pq.
static struct GNUNET_CONTAINER_MultiHashMap * lt_map
ListenTasks (map from socket to struct ListenTask)
static unsigned long long rekey_max_bytes
The rekey byte maximum.
static void core_read_finished_cb(void *cls, int success)
Core tells us it is done processing a message that transport received on a queue with status success.
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
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.
struct GNUNET_CRYPTO_BlindablePrivateKey pk
Private key from command line option, or NULL.
struct GNUNET_SCHEDULER_Task * read_task
static void queue(const char *label, uint32_t rd_count, struct GNUNET_GNSRECORD_Data *rd, const struct Zone *zone)
Add hostname to the list of requests to be made.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Core service; the main API for encrypted P2P communications.
API to the peerstore service.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:367
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:390
void GNUNET_PILS_derive_pid(size_t seed_key_bytes, const uint8_t seed_key[seed_key_bytes], const struct GNUNET_HashCode *addrs_hash, struct GNUNET_CRYPTO_EddsaPrivateKey *outkey)
Generate the peer id from the addresses hash and the initial secret key.
Definition pils_api.c:507
Constants for network protocols.
Functions related to doing DNS lookups.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK
Signature by a peer sending back the nonce received at initial handshake.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY
Signature used by TCP communicator rekey.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE
Signature used by TCP communicator handshake.
API to create, modify and access statistics.
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.
#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_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
GNUNET_TRANSPORT_ConnectionStatus
Possible states of a connection.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls, GNUNET_TRANSPORT_StartBurstNotify sb)
Connect to the transport service.
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer.
void GNUNET_TRANSPORT_communicator_address_remove_all(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Notify transport service that this communicator no longer provides all its addresses for this peer.
@ GNUNET_TRANSPORT_CC_RELIABLE
Transmission is reliabile (with ACKs), e.g.
@ GNUNET_TRANSPORT_CS_INBOUND
this is an inbound connection (communicator initiated)
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Decapsulate a key for a private EdDSA key.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps(const struct GNUNET_CRYPTO_HpkePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_key_from_file(const char *filename, int do_create, struct GNUNET_CRYPTO_EddsaPrivateKey *pkey)
Create a new private key by reading it from a file.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:201
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_decaps(const struct GNUNET_CRYPTO_HpkePrivateKey *skR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh decapsulation with own private key and the representative of the received public key...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Encapsulate key material for a EdDSA public key.
#define GNUNET_CRYPTO_eddsa_sign(priv, ps, sig)
EdDSA sign a given block.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
#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.
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk,...)
HKDF-Expand using SHA256.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
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.
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.
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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_BlindablePrivateKey *sk, struct GNUNET_CRYPTO_HpkePrivateKey *sk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
GNUNET_GenericReturnValue
Named constants for return values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_BlindablePublicKey *pk, struct GNUNET_CRYPTO_HpkePublicKey *pk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
#define GNUNET_MIN(a, b)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
void GNUNET_CRYPTO_hmac_raw(const void *key, size_t key_len, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104) TODO: Shouldn't this be the standard hmac function and the abo...
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#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...
const char * GNUNET_p2s(const struct GNUNET_CRYPTO_EddsaPublicKey *p)
Convert a public key value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:482
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition mq.c:437
int GNUNET_NAT_request_reversal(struct GNUNET_NAT_Handle *nh, const struct sockaddr_in *local_sa, const struct sockaddr_in *remote_sa)
We learned about a peer (possibly behind NAT) so run the gnunet-nat-client to send dummy ICMP respons...
Definition nat_api.c:675
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition nat_api.c:366
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition nat_api.c:703
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition network.c:392
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition network.c:1001
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition network.c:717
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition network.c:602
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition network.c:738
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
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition network.c:652
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition nt.c:428
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition nt.c:407
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition nt.c:309
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
struct GNUNET_PEERSTORE_IterateContext * GNUNET_PEERSTORE_iteration_start(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Iterate over peerstore entries.
void GNUNET_PEERSTORE_iteration_next(struct GNUNET_PEERSTORE_IterateContext *ic, uint64_t limit)
Continue an iteration.
void GNUNET_PEERSTORE_store_cancel(struct GNUNET_PEERSTORE_StoreContext *sc)
Cancel a store request.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the PEERSTORE service.
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE
Key used to store sender's monotonic time from handshake message.
struct GNUNET_PEERSTORE_StoreContext * GNUNET_PEERSTORE_store(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Store a new entry in the PEERSTORE.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK
Key used to store sender's monotonic time from handshake ack message.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY
Key used to store sender's monotonic time from rekey message.
void GNUNET_PEERSTORE_iteration_stop(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iteration.
@ GNUNET_PEERSTORE_STOREOPTION_REPLACE
Delete any previous values for the given key before storing the given value.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, 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:407
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK
TCP communicator confirmation ack.
#define GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE
TCP NAT probe message, send from NAT'd peer to other peer to establish bi-directional communication.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH
TCP communicator end of stream.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX
TCP communicator payload box.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY
TCP communicator rekey message.
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_ip_get(const char *hostname, int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *callback_cls)
Convert a string to one or more IP addresses.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition scheduler.c:1511
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, 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:1582
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1339
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1304
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1277
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:599
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition time.c:860
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:636
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:660
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define max(x, y)
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition scheduler.c:431
DLL to store the addresses we like to register at NAT service.
struct Addresses * next
Kept in a DLL.
struct Addresses * prev
Kept in a DLL.
struct sockaddr * addr
Address we like to register at NAT service.
socklen_t addr_len
Length of address we like to register at NAT service.
Internal representation of the hash map.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Type of a nonce used for challenges.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
an ECC signature using EdDSA.
HPKE DHKEM encapsulation (X25519) See RFC 9180.
A public key used for decryption.
A public key used for encryption.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
Definition of a command line option.
Context for parsing HELLOs.
Definition hello-uri.c:232
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Header for all communications.
Handle for active NAT registrations.
Definition nat_api.c:72
handle to a socket
Definition network.c:53
Handle to the interface scanner.
Definition nt.c:104
Handle to the PEERSTORE service.
Context for a iterate request.
Context for a store request.
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Handle to a request given to the resolver.
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...
Opaque handle to the transport service for communicators.
struct GNUNET_MQ_Handle * mq
Queue to talk to the transport service.
Handle returned to identify the internal data structure the transport API has created to manage a mes...
Struct to use as closure.
struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
struct GNUNET_SCHEDULER_Task * listen_task
ID of listen task.
Struct for pending nat reversals.
struct sockaddr * in
Address the reversal was send to.
struct GNUNET_SCHEDULER_Task * timeout_task
struct GNUNET_PeerIdentity target
To whom are we like to talk to.
In case of port only configuration we like to bind to ipv4 and ipv6 addresses.
struct sockaddr * addr_ipv4
Ipv4 address we like to bind to.
struct sockaddr * addr_ipv6
Ipv6 address we like to bind to.
socklen_t addr_len_ipv6
Length of ipv6 address.
socklen_t addr_len_ipv4
Length of ipv4 address.
Handle for an incoming connection where we do not yet have enough information to setup a full queue.
socklen_t address_len
Length of the address.
struct GNUNET_SCHEDULER_Task * write_task
ID of write task for this connection.
char write_buf[sizeof(struct TCPNATProbeMessage)]
buffer for writing struct TCPNATProbeMessage to network.
struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
size_t ibuf_off
Current offset for reading into ibuf.
struct GNUNET_TIME_Absolute timeout
Timeout for this protoqueue.
struct GNUNET_NETWORK_Handle * sock
socket that we transmit all data with on this queue
struct sockaddr * address
Address of the other peer.
struct ProtoQueue * prev
Kept in a DLL.
char ibuf[(sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)+sizeof(struct TCPConfirmation))]
Buffer for reading all the information we need to upgrade from protoqueue to queue.
size_t write_off
Offset of the buffer?
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.
struct ProtoQueue * next
Kept in a DLL.
Handle for a queue.
unsigned int backpressure
How may messages did we pass from this queue to CORE for which we have yet to receive an acknowledgem...
struct GNUNET_NETWORK_Handle * sock
socket that we transmit all data with on this queue
struct GNUNET_PEERSTORE_IterateContext * handshake_ack_monotime_get
Iteration Context for retrieving the monotonic time send with the handshake ack.
int rekeyed
GNUNET_YES if we just rekeyed and must thus possibly re-decrypt ciphertext.
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
size_t unverified_size
Size of data received without KX challenge played back.
struct GNUNET_TRANSPORT_QueueHandle * qh
handle for this queue with the ch.
struct GNUNET_HashCode out_hmac
Shared secret for HMAC generation on outgoing data, ratcheted after each operation.
int finishing
Did we enqueue a finish message and are closing down the queue?
int initial_core_kx_done
Has the initial (core) handshake already happened?
struct GNUNET_HashCode key
Key in hash map.
socklen_t address_len
Length of the address.
struct GNUNET_MQ_Handle * mq
Message queue we are providing for the ch.
unsigned long long bytes_in_queue
Number of bytes we currently have in our write queue.
char pread_buf[UINT16_MAX+1+sizeof(struct TCPBox)]
Plaintext buffer for decrypted plaintext.
int destroyed
Did we technically destroy this queue, but kept the allocation around because of backpressure not bei...
struct GNUNET_PEERSTORE_StoreContext * rekey_monotime_sc
Store Context for retrieving the monotonic time send with key for rekeying.
size_t cwrite_off
At which offset in the ciphertext write buffer should we append more ciphertext from reading next?
struct GNUNET_PEERSTORE_IterateContext * rekey_monotime_get
Iteration Context for retrieving the monotonic time send with key for rekeying.
char cread_buf[(2 *64 *1024+sizeof(struct TCPBox))]
Buffer for reading ciphertext from network into.
struct GNUNET_CRYPTO_HpkePublicKey target_hpke_key
To whom are we talking to.
enum GNUNET_NetworkType nt
Which network type does this queue use?
struct GNUNET_CRYPTO_ChallengeNonceP challenge_received
Challenge value received.
uint64_t rekey_left_bytes
How many more bytes may we sent with the current out_cipher before we should rekey?
int mq_awaits_continue
Is MQ awaiting a GNUNET_MQ_impl_send_continue() call?
gcry_cipher_hd_t in_cipher
cipher for decryption of incoming data.
struct GNUNET_PEERSTORE_StoreContext * handshake_ack_monotime_sc
Store Context for retrieving the monotonic time send with the handshake ack.
struct GNUNET_SCHEDULER_Task * write_task
ID of write task for this connection.
size_t pwrite_off
At which offset in the plaintext output buffer should we append more plaintext for encryption next?
struct GNUNET_TIME_Absolute timeout
Timeout for this queue.
size_t cread_off
At which offset in the ciphertext read buffer should we append more ciphertext for transmission next?
struct GNUNET_TIME_Absolute rekey_time
Until what time may we sent with the current out_cipher before we should rekey?
struct GNUNET_PeerIdentity target
To whom are we talking to.
char cwrite_buf[(2 *64 *1024+sizeof(struct TCPBox))]
buffer for writing ciphertext to network.
struct GNUNET_PEERSTORE_StoreContext * handshake_monotime_sc
Store Context for retrieving the monotonic time send with the handshake.
size_t pread_off
At which offset in the plaintext input buffer should we append more plaintext from decryption next?
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.
enum GNUNET_TRANSPORT_ConnectionStatus cs
The connection status of this queue.
gcry_cipher_hd_t out_cipher
cipher for encryption of outgoing data.
char pwrite_buf[UINT16_MAX+1+sizeof(struct TCPBox)]
Plaintext buffer for messages to be encrypted.
struct GNUNET_HashCode in_hmac
Shared secret for HMAC verification on incoming data.
struct GNUNET_PEERSTORE_IterateContext * handshake_monotime_get
Iteration Context for retrieving the monotonic time send with the handshake.
struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
struct sockaddr * address
Address of the other peer.
struct GNUNET_TIME_AbsoluteNBO handshake_ack_monotonic_time
Monotonic time value for handshake ack message.
struct GNUNET_TIME_AbsoluteNBO rekey_monotonic_time
Monotonic time value for rekey message.
struct GNUNET_TIME_AbsoluteNBO handshake_monotonic_time
Monotonic time value for handshake message.
TCP message box.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
Ack for the encrypted continuation of TCP initial handshake.
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_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK.
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK.
struct GNUNET_PeerIdentity sender
Sender's identity.
Encrypted continuation of TCP initial handshake.
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_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Sender's identity.
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
Basically a WELCOME message, but with the purpose of giving the waiting peer a client handle to use.
struct GNUNET_PeerIdentity clientIdentity
Identity of the sender of the message.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE.
TCP rekey message box.
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_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY.
struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral
New ephemeral key.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY.
Signature we use to verify that the ack from the receiver of the ephemeral key was really send by the...
struct GNUNET_PeerIdentity sender
Identity of the inititor of the TCP connection (TCP client).
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the TCP connection (TCP server)
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral
Ephemeral key used by the sender (as Elligator representative).
struct GNUNET_PeerIdentity sender
Identity of the inititor of the TCP connection (TCP client).
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the TCP connection (TCP server)
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral
Ephemeral key used by the sender.
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the TCP connection (TCP client).
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the TCP connection (TCP server)
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...