GNUnet 0.26.2-45-gb0324da85
 
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 key,
1280 sizeof(key),
1281 prk,
1282 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-tcp-key"))
1283 );
1284 GNUNET_assert (0 == gcry_cipher_setkey (*cipher, key, sizeof(key)));
1287 ctr,
1288 sizeof(ctr),
1289 prk,
1290 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-tcp-ctr"))
1291 );
1292 gcry_cipher_setctr (*cipher, ctr, sizeof(ctr));
1295 hmac_key,
1296 sizeof(struct GNUNET_HashCode),
1297 prk,
1298 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-hmac")));
1299}
1300
1301
1307static void
1308rekey_monotime_store_cb (void *cls, int success)
1309{
1310 struct Queue *queue = cls;
1311 if (GNUNET_OK != success)
1312 {
1314 "Failed to store rekey monotonic time in PEERSTORE!\n");
1315 }
1316 queue->rekey_monotime_sc = NULL;
1317 GNUNET_PEERSTORE_iteration_next (queue->rekey_monotime_get, 1);
1318}
1319
1320
1328static void
1330 const struct GNUNET_PEERSTORE_Record *record,
1331 const char *emsg)
1332{
1333 struct Queue *queue = cls;
1334 struct GNUNET_TIME_AbsoluteNBO *mtbe;
1335 struct GNUNET_TIME_Absolute mt;
1336 const struct GNUNET_PeerIdentity *pid;
1337 struct GNUNET_TIME_AbsoluteNBO *rekey_monotonic_time;
1338
1339 (void) emsg;
1340
1341 rekey_monotonic_time = &queue->rekey_monotonic_time;
1342 pid = &queue->target;
1343 if (NULL == record)
1344 {
1345 queue->rekey_monotime_get = NULL;
1346 return;
1347 }
1348 if (sizeof(*mtbe) != record->value_size)
1349 {
1350 GNUNET_PEERSTORE_iteration_next (queue->rekey_monotime_get, 1);
1351 GNUNET_break (0);
1352 return;
1353 }
1354 mtbe = record->value;
1355 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1357 queue->rekey_monotonic_time).abs_value_us)
1358 {
1360 "Queue from %s dropped, rekey monotime in the past\n",
1361 GNUNET_i2s (&queue->target));
1362 GNUNET_break (0);
1363 GNUNET_PEERSTORE_iteration_stop (queue->rekey_monotime_get);
1364 queue->rekey_monotime_get = NULL;
1365 // FIXME: Why should we try to gracefully finish here??
1367 return;
1368 }
1369 queue->rekey_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
1370 "transport_tcp_communicator",
1371 pid,
1373 rekey_monotonic_time,
1374 sizeof(*
1375 rekey_monotonic_time),
1379 queue);
1380}
1381
1382
1389static void
1391 const struct GNUNET_CRYPTO_HpkeEncapsulation *c,
1392 struct Queue *queue)
1393{
1394 struct GNUNET_ShortHashCode k;
1395
1397 c,
1398 &k);
1399 setup_cipher (&k, &my_identity, &queue->in_cipher, &queue->in_hmac);
1400}
1401
1402
1409static void
1411 struct Queue *queue)
1412{
1413 struct GNUNET_ShortHashCode k;
1414
1416 setup_cipher (&k, &my_identity, &queue->in_cipher, &queue->in_hmac);
1417}
1418
1419
1428static void
1429do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
1430{
1431 struct TcpRekeySignature thp;
1432
1434 thp.purpose.size = htonl (sizeof(thp));
1436 "do_rekey size %u\n",
1437 thp.purpose.size);
1438 thp.sender = queue->target;
1440 "sender %s\n",
1443 "sender %s\n",
1444 GNUNET_p2s (&queue->target.public_key));
1445 thp.receiver = my_identity;
1447 "receiver %s\n",
1449 thp.ephemeral = rekey->ephemeral;
1451 "ephemeral %s\n",
1453 );
1454 thp.monotonic_time = rekey->monotonic_time;
1456 "time %s\n",
1459 GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp)));
1460 if (GNUNET_OK !=
1463 &thp,
1464 &rekey->sender_sig,
1465 &queue->target.public_key))
1466 {
1467 GNUNET_break (0);
1468 // FIXME Why should we try to gracefully finish here?
1470 return;
1471 }
1472 queue->rekey_monotonic_time = rekey->monotonic_time;
1473 queue->rekey_monotime_get = GNUNET_PEERSTORE_iteration_start (peerstore,
1474 "transport_tcp_communicator",
1475 &queue->target,
1477 &
1479 queue);
1480 gcry_cipher_close (queue->in_cipher);
1481 queue->rekeyed = GNUNET_YES;
1482 setup_in_cipher (&rekey->ephemeral, queue);
1483}
1484
1485
1491static void
1492handshake_ack_monotime_store_cb (void *cls, int success)
1493{
1494 struct Queue *queue = cls;
1495
1496 if (GNUNET_OK != success)
1497 {
1499 "Failed to store handshake ack monotonic time in PEERSTORE!\n");
1500 }
1501 queue->handshake_ack_monotime_sc = NULL;
1502 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
1503}
1504
1505
1513static void
1515 const struct GNUNET_PEERSTORE_Record *record,
1516 const char *emsg)
1517{
1518 struct Queue *queue = cls;
1519 struct GNUNET_TIME_AbsoluteNBO *mtbe;
1520 struct GNUNET_TIME_Absolute mt;
1521 const struct GNUNET_PeerIdentity *pid;
1522 struct GNUNET_TIME_AbsoluteNBO *handshake_ack_monotonic_time;
1523
1524 (void) emsg;
1525
1526 handshake_ack_monotonic_time = &queue->handshake_ack_monotonic_time;
1527 pid = &queue->target;
1528 if (NULL == record)
1529 {
1530 queue->handshake_ack_monotime_get = NULL;
1531 return;
1532 }
1533 if (sizeof(*mtbe) != record->value_size)
1534 {
1535 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
1536 GNUNET_break (0);
1537 return;
1538 }
1539 mtbe = record->value;
1540 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1542 queue->handshake_ack_monotonic_time).abs_value_us)
1543 {
1545 "Queue from %s dropped, handshake ack monotime in the past\n",
1546 GNUNET_i2s (&queue->target));
1547 GNUNET_break (0);
1548 GNUNET_PEERSTORE_iteration_stop (queue->handshake_ack_monotime_get);
1549 queue->handshake_ack_monotime_get = NULL;
1550 // FIXME: Why should we try to gracefully finish here?
1552 return;
1553 }
1554 queue->handshake_ack_monotime_sc =
1556 "transport_tcp_communicator",
1557 pid,
1559 handshake_ack_monotonic_time,
1560 sizeof(*handshake_ack_monotonic_time),
1564 queue);
1565}
1566
1567
1574static void
1576 struct Queue *queue)
1577{
1578 struct TCPConfirmationAck tca;
1579 struct TcpHandshakeAckSignature thas;
1580
1582 "sending challenge\n");
1583
1584 tca.header.type = ntohs (
1586 tca.header.size = ntohs (sizeof(tca));
1587 tca.challenge = challenge;
1588 tca.sender = my_identity;
1589 tca.monotonic_time =
1591 thas.purpose.purpose = htonl (
1593 thas.purpose.size = htonl (sizeof(thas));
1594 thas.sender = my_identity;
1595 thas.receiver = queue->target;
1596 thas.monotonic_time = tca.monotonic_time;
1597 thas.challenge = tca.challenge;
1599 &thas,
1600 &tca.sender_sig);
1601 GNUNET_assert (0 ==
1602 gcry_cipher_encrypt (queue->out_cipher,
1603 &queue->cwrite_buf[queue->cwrite_off],
1604 sizeof(tca),
1605 &tca,
1606 sizeof(tca)));
1607 queue->cwrite_off += sizeof(tca);
1609 "sending challenge done\n");
1610}
1611
1612
1619static void
1621{
1622 setup_cipher (dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1624 queue->rekey_left_bytes =
1626}
1627
1628
1635static void
1637{
1638 struct TCPRekey rekey;
1639 struct TcpRekeySignature thp;
1640 struct GNUNET_ShortHashCode k;
1641
1642 GNUNET_assert (0 == queue->pwrite_off);
1643 memset (&rekey, 0, sizeof(rekey));
1644 GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &rekey.ephemeral,
1645 &k);
1647 rekey.header.size = ntohs (sizeof(rekey));
1648 rekey.monotonic_time =
1651 thp.purpose.size = htonl (sizeof(thp));
1653 "inject_rekey size %u\n",
1654 thp.purpose.size);
1655 thp.sender = my_identity;
1657 "sender %s\n",
1659 thp.receiver = queue->target;
1661 "receiver %s\n",
1663 thp.ephemeral = rekey.ephemeral;
1665 "ephemeral %s\n",
1667 );
1668 thp.monotonic_time = rekey.monotonic_time;
1670 "time %s\n",
1674 &thp,
1675 &rekey.sender_sig);
1676 calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1677 /* Encrypt rekey message with 'old' cipher */
1678 GNUNET_assert (0 ==
1679 gcry_cipher_encrypt (queue->out_cipher,
1680 &queue->cwrite_buf[queue->cwrite_off],
1681 sizeof(rekey),
1682 &rekey,
1683 sizeof(rekey)));
1684 queue->cwrite_off += sizeof(rekey);
1685 /* Setup new cipher for successive messages */
1686 gcry_cipher_close (queue->out_cipher);
1687 setup_out_cipher (queue, &k);
1688}
1689
1690
1691static int
1693 const struct GNUNET_HashCode *key,
1694 void *value)
1695{
1696 struct PendingReversal *pending_reversal = value;
1697 (void) cls;
1698
1699 if (NULL != pending_reversal->timeout_task)
1700 {
1701 GNUNET_SCHEDULER_cancel (pending_reversal->timeout_task);
1702 pending_reversal->timeout_task = NULL;
1703 }
1706 key,
1707 pending_reversal));
1708 GNUNET_free (pending_reversal->in);
1709 GNUNET_free (pending_reversal);
1710 return GNUNET_OK;
1711}
1712
1713
1714static void
1715check_and_remove_pending_reversal (struct sockaddr *in, sa_family_t sa_family,
1716 struct GNUNET_PeerIdentity *sender)
1717{
1718 if (AF_INET == sa_family)
1719 {
1720 struct PendingReversal *pending_reversal;
1721 struct GNUNET_HashCode key;
1722 struct sockaddr_in *natted_address;
1723
1724 natted_address = GNUNET_memdup (in, sizeof (struct sockaddr));
1725 natted_address->sin_port = 0;
1726 GNUNET_CRYPTO_hash (natted_address,
1727 sizeof(struct sockaddr),
1728 &key);
1729
1731 &key);
1732 if (NULL != pending_reversal && (NULL == sender ||
1733 0 != memcmp (sender,
1734 &pending_reversal->target,
1735 sizeof(struct
1737 {
1739 "Removing invalid pending reversal for `%s'at `%s'\n",
1740 GNUNET_i2s (&pending_reversal->target),
1741 GNUNET_a2s (in, sizeof (struct sockaddr)));
1742 pending_reversals_delete_it (NULL, &key, pending_reversal);
1743 }
1744 GNUNET_free (natted_address);
1745 }
1746}
1747
1748
1754static void
1756{
1757 if (NULL != pq->listen_sock)
1758 {
1760 pq->listen_sock = NULL;
1761 }
1762 if (NULL != pq->read_task)
1763 {
1765 pq->read_task = NULL;
1766 }
1767 if (NULL != pq->write_task)
1768 {
1770 pq->write_task = NULL;
1771 }
1772 check_and_remove_pending_reversal (pq->address, pq->address->sa_family, NULL);
1774 GNUNET_free (pq->address);
1776 GNUNET_free (pq);
1777}
1778
1779
1786static void
1788{
1789 struct ProtoQueue *pq = cls;
1790 ssize_t sent;
1791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In proto queue write\n");
1792 pq->write_task = NULL;
1793 if (0 != pq->write_off)
1794 {
1795 sent = GNUNET_NETWORK_socket_send (pq->sock,
1796 pq->write_buf,
1797 pq->write_off);
1799 "Sent %lu bytes to TCP queue\n", sent);
1800 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1801 {
1803 free_proto_queue (pq);
1804 return;
1805 }
1806 if (sent > 0)
1807 {
1808 size_t usent = (size_t) sent;
1809 pq->write_off -= usent;
1810 memmove (pq->write_buf,
1811 &pq->write_buf[usent],
1812 pq->write_off);
1813 }
1814 }
1815 /* do we care to write more? */
1816 if ((0 < pq->write_off))
1817 pq->write_task =
1819 pq->sock,
1821 pq);
1822}
1823
1824
1831static void
1832queue_write (void *cls)
1833{
1834 struct Queue *queue = cls;
1835 ssize_t sent;
1836 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In queue write\n");
1837 queue->write_task = NULL;
1838 if (0 != queue->cwrite_off)
1839 {
1840 sent = GNUNET_NETWORK_socket_send (queue->sock,
1841 queue->cwrite_buf,
1842 queue->cwrite_off);
1844 "Sent %lu bytes to TCP queue\n", sent);
1845 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1846 {
1849 return;
1850 }
1851 if (sent > 0)
1852 {
1853 size_t usent = (size_t) sent;
1854 queue->cwrite_off -= usent;
1855 memmove (queue->cwrite_buf,
1856 &queue->cwrite_buf[usent],
1857 queue->cwrite_off);
1858 queue->timeout =
1861 }
1862 }
1863 {
1864 /* can we encrypt more? (always encrypt full messages, needed
1865 such that #mq_cancel() can work!) */
1866 unsigned int we_do_not_need_to_rekey = (0 < queue->rekey_left_bytes
1867 - (queue->cwrite_off
1868 + queue->pwrite_off
1869 + sizeof (struct TCPRekey)));
1870 if (we_do_not_need_to_rekey &&
1871 (queue->pwrite_off > 0) &&
1872 (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1873 {
1875 "Encrypting %lu bytes\n", queue->pwrite_off);
1876 GNUNET_assert (0 ==
1877 gcry_cipher_encrypt (queue->out_cipher,
1878 &queue->cwrite_buf[queue->cwrite_off],
1879 queue->pwrite_off,
1880 queue->pwrite_buf,
1881 queue->pwrite_off));
1882 if (queue->rekey_left_bytes > queue->pwrite_off)
1883 queue->rekey_left_bytes -= queue->pwrite_off;
1884 else
1885 queue->rekey_left_bytes = 0;
1886 queue->cwrite_off += queue->pwrite_off;
1887 queue->pwrite_off = 0;
1888 }
1889 // if ((-1 != unverified_size)&& ((0 == queue->pwrite_off) &&
1890 if (((0 == queue->rekey_left_bytes) ||
1892 queue->rekey_time).rel_value_us)) &&
1893 (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey) &&
1894 (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE)))
1895 {
1897 }
1898 }
1899 if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1900 (GNUNET_YES == queue->mq_awaits_continue))
1901 {
1902 queue->mq_awaits_continue = GNUNET_NO;
1904 }
1905 /* did we just finish writing 'finish'? */
1906 if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1907 {
1909 "Finishing queue\n");
1911 return;
1912 }
1913 /* do we care to write more? */
1914 if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1915 queue->write_task =
1917 queue->sock,
1918 &queue_write,
1919 queue);
1920}
1921
1922
1930static size_t
1932{
1933 const struct GNUNET_MessageHeader *hdr;
1934 const struct TCPConfirmationAck *tca;
1935 const struct TCPBox *box;
1936 const struct TCPRekey *rekey;
1937 const struct TCPFinish *fin;
1938 struct TCPRekey rekeyz;
1939 struct TCPFinish finz;
1940 struct GNUNET_ShortHashCode tmac;
1941 uint16_t type;
1942 size_t size = 0;
1943 struct TcpHandshakeAckSignature thas;
1944 const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1945
1947 "try handle plaintext!\n");
1948
1949 hdr = (const struct GNUNET_MessageHeader *) queue->pread_buf;
1950 if ((sizeof(*hdr) > queue->pread_off))
1951 {
1953 "Handling plaintext, not even a header!\n");
1954 return 0; /* not even a header */
1955 }
1956
1957 if ((GNUNET_YES != queue->initial_core_kx_done) && (queue->unverified_size >
1959 {
1961 "Already received data of size %lu bigger than KX size %lu!\n",
1962 queue->unverified_size,
1964 GNUNET_break_op (0);
1966 return 0;
1967 }
1968
1969 type = ntohs (hdr->type);
1970 switch (type)
1971 {
1973 tca = (const struct TCPConfirmationAck *) queue->pread_buf;
1975 "start processing ack\n");
1976 if (sizeof(*tca) > queue->pread_off)
1977 {
1979 "Handling plaintext size of tca greater than pread offset.\n")
1980 ;
1981 return 0;
1982 }
1983 if (ntohs (hdr->size) != sizeof(*tca))
1984 {
1986 "Handling plaintext size does not match message type.\n");
1987 GNUNET_break_op (0);
1989 return 0;
1990 }
1991
1992 thas.purpose.purpose = htonl (
1994 thas.purpose.size = htonl (sizeof(thas));
1995 thas.sender = tca->sender;
1996 thas.receiver = my_identity;
1997 thas.monotonic_time = tca->monotonic_time;
1998 thas.challenge = tca->challenge;
1999
2002 &thas,
2003 &tca->sender_sig,
2004 &tca->sender.public_key))
2005 {
2007 "Verification of signature failed!\n");
2008 GNUNET_break (0);
2010 return 0;
2011 }
2012 if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
2013 {
2015 "Challenge in TCPConfirmationAck not correct!\n");
2016 GNUNET_break (0);
2018 return 0;
2019 }
2020
2021 queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iteration_start (
2022 peerstore,
2023 "transport_tcp_communicator",
2024 &queue->target,
2027 queue);
2028
2030 "Handling plaintext, ack processed!\n");
2031
2033 {
2034 send_challenge (queue->challenge_received, queue);
2035 queue->write_task =
2037 queue->sock,
2038 &queue_write,
2039 queue);
2040 }
2041 else if (GNUNET_TRANSPORT_CS_OUTBOUND == queue->cs)
2042 {
2044 queue->address->sa_family, NULL);
2045 }
2046
2051 queue->initial_core_kx_done = GNUNET_YES;
2052
2053 {
2054 char *foreign_addr;
2055
2056 switch (queue->address->sa_family)
2057 {
2058 case AF_INET:
2059 GNUNET_asprintf (&foreign_addr,
2060 "%s-%s",
2062 GNUNET_a2s (queue->address, queue->address_len));
2063 break;
2064
2065 case AF_INET6:
2066 GNUNET_asprintf (&foreign_addr,
2067 "%s-%s",
2069 GNUNET_a2s (queue->address, queue->address_len));
2070 break;
2071
2072 default:
2073 GNUNET_assert (0);
2074 }
2076 &queue->target,
2077 foreign_addr,
2078 UINT16_MAX, /* no MTU */
2080 0, /* Priority */
2081 queue->nt,
2082 queue->cs,
2083 queue->mq);
2084
2085 GNUNET_free (foreign_addr);
2086 }
2087
2088 size = ntohs (hdr->size);
2089 break;
2091 /* Special case: header size excludes box itself! */
2092 box = (const struct TCPBox *) queue->pread_buf;
2093 if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
2094 return 0;
2095 calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
2096 if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
2097 {
2098 GNUNET_break_op (0);
2100 return 0;
2101 }
2102 pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
2103 size = ntohs (hdr->size) + sizeof(*box);
2105 "Handling plaintext, box processed!\n");
2107 "# bytes decrypted with BOX",
2108 size,
2109 GNUNET_NO);
2111 "# messages decrypted with BOX",
2112 1,
2113 GNUNET_NO);
2114 break;
2115
2117 rekey = (const struct TCPRekey *) queue->pread_buf;
2118 if (sizeof(*rekey) > queue->pread_off)
2119 return 0;
2120 if (ntohs (hdr->size) != sizeof(*rekey))
2121 {
2122 GNUNET_break_op (0);
2124 return 0;
2125 }
2126 rekeyz = *rekey;
2127 memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
2128 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
2129 if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac)))
2130 {
2131 GNUNET_break_op (0);
2133 return 0;
2134 }
2135 do_rekey (queue, rekey);
2136 size = ntohs (hdr->size);
2138 "Handling plaintext, rekey processed!\n");
2140 "# rekeying successful",
2141 1,
2142 GNUNET_NO);
2143 break;
2144
2146 fin = (const struct TCPFinish *) queue->pread_buf;
2147 if (sizeof(*fin) > queue->pread_off)
2148 return 0;
2149 if (ntohs (hdr->size) != sizeof(*fin))
2150 {
2151 GNUNET_break_op (0);
2153 return 0;
2154 }
2155 finz = *fin;
2156 memset (&finz.hmac, 0, sizeof(finz.hmac));
2157 calculate_hmac (&queue->in_hmac, &finz, sizeof(finz), &tmac);
2158 if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
2159 {
2160 GNUNET_break_op (0);
2162 return 0;
2163 }
2164 /* handle FINISH by destroying queue */
2167 "Handling plaintext, finish processed!\n");
2168 break;
2169
2170 default:
2172 "Handling plaintext, nothing processed!\n");
2173 GNUNET_break_op (0);
2175 return 0;
2176 }
2177 GNUNET_assert (0 != size);
2178 if (-1 != queue->unverified_size)
2179 queue->unverified_size += size;
2180 return size;
2181}
2182
2183
2189static void
2190queue_read (void *cls)
2191{
2192 struct Queue *queue = cls;
2193 struct GNUNET_TIME_Relative left;
2194 ssize_t rcvd;
2195
2196 queue->read_task = NULL;
2197 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2198 &queue->cread_buf[queue->cread_off],
2199 BUF_SIZE - queue->cread_off);
2201 "Received %zd bytes from TCP queue\n", rcvd);
2202 if (-1 == rcvd)
2203 {
2204 if ((EAGAIN != errno) && (EINTR != errno))
2205 {
2208 return;
2209 }
2210 /* try again */
2211 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2212 if (0 != left.rel_value_us)
2213 {
2214 queue->read_task =
2216 return;
2217 }
2219 "Queue %p was idle for %s, disconnecting\n",
2220 queue,
2223 GNUNET_YES));
2225 return;
2226 }
2227 if (0 == rcvd)
2228 {
2229 /* Orderly shutdown of connection */
2231 "Socket for queue %p seems to have been closed\n", queue);
2233 return;
2234 }
2235 queue->timeout =
2237 queue->cread_off += rcvd;
2238 while ((queue->pread_off < sizeof(queue->pread_buf)) &&
2239 (queue->cread_off > 0))
2240 {
2241 size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
2242 queue->cread_off);
2243 size_t done;
2244 size_t total;
2245 size_t old_pread_off = queue->pread_off;
2246
2247 GNUNET_assert (0 ==
2248 gcry_cipher_decrypt (queue->in_cipher,
2249 &queue->pread_buf[queue->pread_off],
2250 max,
2251 queue->cread_buf,
2252 max));
2253 queue->pread_off += max;
2254 total = 0;
2255 while (0 != (done = try_handle_plaintext (queue)))
2256 {
2257 /* 'done' bytes of plaintext were used, shift buffer */
2258 GNUNET_assert (done <= queue->pread_off);
2259 /* NOTE: this memmove() could possibly sometimes be
2260 avoided if we pass 'total' into try_handle_plaintext()
2261 and use it at an offset into the buffer there! */
2262 memmove (queue->pread_buf,
2263 &queue->pread_buf[done],
2264 queue->pread_off - done);
2265 queue->pread_off -= done;
2266 total += done;
2267 /* The last plaintext was a rekey, abort for now */
2268 if (GNUNET_YES == queue->rekeyed)
2269 break;
2270 }
2271 /* when we encounter a rekey message, the decryption above uses the
2272 wrong key for everything after the rekey; in that case, we have
2273 to re-do the decryption at 'total' instead of at 'max'.
2274 However, we have to take into account that the plaintext buffer may have
2275 already contained data and not jumped too far ahead in the ciphertext.
2276 If there is no rekey and the last message is incomplete (max > total),
2277 it is safe to keep the decryption so we shift by 'max' */
2278 if (GNUNET_YES == queue->rekeyed)
2279 {
2280 max = total - old_pread_off;
2281 queue->rekeyed = GNUNET_NO;
2282 queue->pread_off = 0;
2283 }
2284 memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
2285 queue->cread_off -= max;
2286 }
2287 if (BUF_SIZE == queue->cread_off)
2288 return; /* buffer full, suspend reading */
2289 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2290 if (0 != left.rel_value_us)
2291 {
2292 if (max_queue_length > queue->backpressure)
2293 {
2294 /* continue reading */
2295 queue->read_task =
2297 }
2298 return;
2299 }
2301 "Queue %p was idle for %s, disconnecting\n",
2302 queue,
2305 GNUNET_YES));
2307}
2308
2309
2317static struct sockaddr *
2319 struct sockaddr_in6 v6,
2320 unsigned int port)
2321{
2322 struct sockaddr *in;
2323
2324 v6.sin6_family = AF_INET6;
2325 v6.sin6_port = htons ((uint16_t) port);
2326#if HAVE_SOCKADDR_IN_SIN_LEN
2327 v6.sin6_len = sizeof(struct sockaddr_in6);
2328#endif
2329 v6.sin6_flowinfo = 0;
2330 v6.sin6_scope_id = 0;
2331 in = GNUNET_memdup (&v6, sizeof(v6));
2332 *sock_len = sizeof(struct sockaddr_in6);
2333
2334 return in;
2335}
2336
2337
2345static struct sockaddr *
2347 struct sockaddr_in v4,
2348 unsigned int port)
2349{
2350 struct sockaddr *in;
2351
2352 v4.sin_family = AF_INET;
2353 v4.sin_port = htons ((uint16_t) port);
2354#if HAVE_SOCKADDR_IN_SIN_LEN
2355 v4.sin_len = sizeof(struct sockaddr_in);
2356#endif
2357 in = GNUNET_memdup (&v4, sizeof(v4));
2358 *sock_len = sizeof(struct sockaddr_in);
2359 return in;
2360}
2361
2362
2369static struct PortOnlyIpv4Ipv6 *
2370tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
2371{
2372 struct PortOnlyIpv4Ipv6 *po;
2373 struct sockaddr_in *i4;
2374 struct sockaddr_in6 *i6;
2375 socklen_t sock_len_ipv4;
2376 socklen_t sock_len_ipv6;
2377
2378 /* interpreting value as just a PORT number */
2379 if (*port > UINT16_MAX)
2380 {
2382 "BINDTO specification `%s' invalid: value too large for port\n",
2383 bindto);
2384 return NULL;
2385 }
2386
2387 po = GNUNET_new (struct PortOnlyIpv4Ipv6);
2388
2389 if (GNUNET_YES == disable_v6)
2390 {
2391 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2392 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2393 *port);
2394 po->addr_len_ipv4 = sock_len_ipv4;
2395 }
2396 else
2397 {
2398
2399 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2400 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2401 *port);
2402 po->addr_len_ipv4 = sock_len_ipv4;
2403
2404 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2405 po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
2406 *port);
2407
2408 po->addr_len_ipv6 = sock_len_ipv6;
2409
2410 GNUNET_free (i6);
2411 }
2412
2413 GNUNET_free (i4);
2414
2415 return po;
2416}
2417
2418
2425static char *
2426extract_address (const char *bindto)
2427{
2428 char *addr;
2429 char *start;
2430 char *token;
2431 char *cp;
2432 char *rest = NULL;
2433
2435 "extract address with bindto %s\n",
2436 bindto);
2437
2438 if (NULL == bindto)
2440 "bindto is NULL\n");
2441
2442 cp = GNUNET_strdup (bindto);
2443
2445 "extract address 2\n");
2446
2447 start = cp;
2448 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2449 {
2450 start++; /* skip over '['*/
2451 cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
2452 addr = GNUNET_strdup (start);
2453 }
2454 else
2455 {
2456 token = strtok_r (cp, "]", &rest);
2457 if (strlen (bindto) == strlen (token))
2458 {
2459 token = strtok_r (cp, ":", &rest);
2460 addr = GNUNET_strdup (token);
2461 }
2462 else
2463 {
2464 token++;
2465 addr = GNUNET_strdup (token);
2466 }
2467 }
2468
2470 "tcp address: %s\n",
2471 addr);
2472 GNUNET_free (cp);
2473 return addr;
2474}
2475
2476
2483static unsigned int
2484extract_port (const char *addr_and_port)
2485{
2486 unsigned int port;
2487 char dummy[2];
2488 char *token;
2489 char *addr;
2490 char *colon;
2491 char *cp;
2492 char *rest = NULL;
2493
2494 if (NULL != addr_and_port)
2495 {
2496 cp = GNUNET_strdup (addr_and_port);
2497 token = strtok_r (cp, "]", &rest);
2498 if (strlen (addr_and_port) == strlen (token))
2499 {
2500 colon = strrchr (cp, ':');
2501 if (NULL == colon)
2502 {
2503 GNUNET_free (cp);
2504 return 0;
2505 }
2506 addr = colon;
2507 addr++;
2508 }
2509 else
2510 {
2511 token = strtok_r (NULL, "]", &rest);
2512 if (NULL == token)
2513 {
2514 GNUNET_free (cp);
2515 return 0;
2516 }
2517 else
2518 {
2519 addr = token;
2520 addr++;
2521 }
2522 }
2523
2524
2525 if (1 == sscanf (addr, "%u%1s", &port, dummy))
2526 {
2527 /* interpreting value as just a PORT number */
2528 if (port > UINT16_MAX)
2529 {
2531 "Port `%u' invalid: value too large for port\n",
2532 port);
2533 GNUNET_free (cp);
2534 return 0;
2535 }
2536 }
2537 else
2538 {
2540 "BINDTO specification invalid: last ':' not followed by number\n");
2541 GNUNET_free (cp);
2542 return 0;
2543 }
2544 GNUNET_free (cp);
2545 }
2546 else
2547 {
2549 "return 0\n");
2550 /* interpret missing port as 0, aka pick any free one */
2551 port = 0;
2552 }
2553
2554 return port;
2555}
2556
2557
2565static struct sockaddr *
2566tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2567{
2568 struct sockaddr *in;
2569 unsigned int port;
2570 struct sockaddr_in v4;
2571 struct sockaddr_in6 v6;
2572 char *start;
2573
2574 memset (&v4, 0, sizeof(v4));
2575 start = extract_address (bindto);
2576 GNUNET_assert (NULL != start);
2578 "start %s\n",
2579 start);
2580
2582 "!bindto %s\n",
2583 bindto);
2584
2585
2586 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
2587 {
2588 port = extract_port (bindto);
2589
2591 "port %u\n",
2592 port);
2593
2594 in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
2595 }
2596 else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2597 {
2598 port = extract_port (bindto);
2599 in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
2600 }
2601 else
2602 {
2603 GNUNET_assert (0);
2604 }
2605
2607 return in;
2608}
2609
2610
2619static void
2621 const struct GNUNET_MessageHeader *msg,
2622 void *impl_state)
2623{
2624 struct Queue *queue = impl_state;
2625 uint16_t msize = ntohs (msg->size);
2626 struct TCPBox box;
2628 "In MQ send. Queue finishing: %s; write task running: %s\n",
2629 (GNUNET_YES == queue->finishing) ? "yes" : "no",
2630 (NULL == queue->write_task) ? "yes" : "no");
2631 GNUNET_assert (mq == queue->mq);
2632 queue->mq_awaits_continue = GNUNET_YES;
2633 if (GNUNET_YES == queue->finishing)
2634 return; /* this queue is dying, drop msg */
2635 GNUNET_assert (0 == queue->pwrite_off);
2637 box.header.size = htons (msize);
2638 calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
2639 memcpy (&queue->pwrite_buf[queue->pwrite_off], &box, sizeof(box));
2640 queue->pwrite_off += sizeof(box);
2641 memcpy (&queue->pwrite_buf[queue->pwrite_off], msg, msize);
2642 queue->pwrite_off += msize;
2644 "%lu bytes of plaintext to send\n", queue->pwrite_off);
2645 GNUNET_assert (NULL != queue->sock);
2646 if (NULL == queue->write_task)
2647 queue->write_task =
2649 queue->sock,
2650 &queue_write,
2651 queue);
2652}
2653
2654
2663static void
2664mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
2665{
2666 struct Queue *queue = impl_state;
2667
2668 if (mq == queue->mq)
2669 {
2670 queue->mq = NULL;
2672 }
2673}
2674
2675
2682static void
2683mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2684{
2685 struct Queue *queue = impl_state;
2686
2687 GNUNET_assert (0 != queue->pwrite_off);
2688 queue->pwrite_off = 0;
2689}
2690
2691
2701static void
2702mq_error (void *cls, enum GNUNET_MQ_Error error)
2703{
2704 struct Queue *queue = cls;
2705
2707 "MQ error in queue to %s: %d\n",
2708 GNUNET_i2s (&queue->target),
2709 (int) error);
2711}
2712
2713
2721static void
2723{
2724 queue->nt =
2725 GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
2727 queue_map,
2728 &queue->key,
2729 queue,
2732 "# queues active",
2734 GNUNET_NO);
2735 queue->timeout =
2738 &mq_destroy,
2739 &mq_cancel,
2740 queue,
2741 NULL,
2742 &mq_error,
2743 queue);
2744}
2745
2746
2757static void
2759 const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
2760{
2761 struct TcpHandshakeSignature ths;
2762 struct TCPConfirmation tc;
2763
2764 memcpy (queue->cwrite_buf, c, sizeof(*c));
2765 queue->cwrite_off = sizeof(*c);
2766 /* compute 'tc' and append in encrypted format to cwrite_buf */
2767 tc.sender = my_identity;
2768 tc.monotonic_time =
2771 &tc.challenge,
2772 sizeof(tc.challenge));
2773 ths.purpose.purpose = htonl (
2775 ths.purpose.size = htonl (sizeof(ths));
2776 ths.sender = my_identity;
2777 ths.receiver = queue->target;
2778 ths.ephemeral = *c;
2779 ths.monotonic_time = tc.monotonic_time;
2780 ths.challenge = tc.challenge;
2782 &ths,
2783 &tc.sender_sig);
2784 GNUNET_assert (0 ==
2785 gcry_cipher_encrypt (queue->out_cipher,
2786 &queue->cwrite_buf[queue->cwrite_off],
2787 sizeof(tc),
2788 &tc,
2789 sizeof(tc)));
2790 queue->challenge = tc.challenge;
2791 queue->cwrite_off += sizeof(tc);
2792
2794 "handshake written\n");
2795}
2796
2797
2805static void
2807{
2809 struct GNUNET_ShortHashCode k;
2810
2812 &c, &k);
2813 setup_out_cipher (queue, &k);
2814 transmit_kx (queue, &c);
2815}
2816
2817
2823static void
2824handshake_monotime_store_cb (void *cls, int success)
2825{
2826 struct Queue *queue = cls;
2827 if (GNUNET_OK != success)
2828 {
2830 "Failed to store handshake monotonic time in PEERSTORE!\n");
2831 }
2832 queue->handshake_monotime_sc = NULL;
2833 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
2834}
2835
2836
2844static void
2846 const struct GNUNET_PEERSTORE_Record *record,
2847 const char *emsg)
2848{
2849 struct Queue *queue = cls;
2850 struct GNUNET_TIME_AbsoluteNBO *mtbe;
2851 struct GNUNET_TIME_Absolute mt;
2852 const struct GNUNET_PeerIdentity *pid;
2853 struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
2854
2855 (void) emsg;
2856
2857 handshake_monotonic_time = &queue->handshake_monotonic_time;
2858 pid = &queue->target;
2860 "tcp handshake with us %s\n",
2862 if (NULL == record)
2863 {
2864 queue->handshake_monotime_get = NULL;
2865 return;
2866 }
2868 "tcp handshake from peer %s\n",
2869 GNUNET_i2s (pid));
2870 if (sizeof(*mtbe) != record->value_size)
2871 {
2872 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
2873 GNUNET_break (0);
2874 return;
2875 }
2876 mtbe = record->value;
2877 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
2879 queue->handshake_monotonic_time).abs_value_us)
2880 {
2882 "Queue from %s dropped, handshake monotime in the past\n",
2883 GNUNET_i2s (&queue->target));
2884 GNUNET_break (0);
2885 GNUNET_PEERSTORE_iteration_stop (queue->handshake_ack_monotime_get);
2886 queue->handshake_ack_monotime_get = NULL;
2888 return;
2889 }
2890 queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
2891 "transport_tcp_communicator",
2892 pid,
2894 handshake_monotonic_time,
2895 sizeof(*
2896 handshake_monotonic_time),
2899 &
2901 queue);
2902}
2903
2904
2916static int
2918 struct TCPConfirmation *tc,
2919 char *ibuf)
2920{
2921 struct TcpHandshakeSignature ths;
2923
2925 0 ==
2926 gcry_cipher_decrypt (queue->in_cipher,
2927 tc,
2928 sizeof(*tc),
2929 &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
2930 sizeof(*tc)));
2931 ths.purpose.purpose = htonl (
2933 ths.purpose.size = htonl (sizeof(ths));
2934 ths.sender = tc->sender;
2935 ths.receiver = my_identity;
2936 memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
2937 ths.monotonic_time = tc->monotonic_time;
2938 ths.challenge = tc->challenge;
2941 &ths,
2942 &tc->sender_sig,
2943 &tc->sender.public_key);
2944 if (GNUNET_YES == ret)
2945 queue->handshake_monotime_get =
2947 "transport_tcp_communicator",
2948 &queue->target,
2951 queue);
2952 return ret;
2953}
2954
2955
2963static void
2964queue_read_kx (void *cls)
2965{
2966 struct Queue *queue = cls;
2967 ssize_t rcvd;
2968 struct GNUNET_TIME_Relative left;
2969 struct TCPConfirmation tc;
2970
2971 queue->read_task = NULL;
2972 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2973 if (0 == left.rel_value_us)
2974 {
2976 return;
2977 }
2978 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2979 &queue->cread_buf[queue->cread_off],
2980 BUF_SIZE - queue->cread_off);
2982 "Received %lu bytes to write in buffer of size %lu for KX from queue %p (expires in %"
2983 PRIu64 ")\n",
2984 rcvd, BUF_SIZE - queue->cread_off, queue, left.rel_value_us);
2985 if (-1 == rcvd)
2986 {
2987 if ((EAGAIN != errno) && (EINTR != errno))
2988 {
2991 return;
2992 }
2993 queue->read_task =
2995 return;
2996 }
2997 if (0 == rcvd)
2998 {
2999 /* Orderly shutdown of connection */
3001 "Socket for queue %p seems to have been closed\n", queue);
3003 return;
3004 }
3005 queue->cread_off += rcvd;
3006 if (queue->cread_off < INITIAL_KX_SIZE)
3007 {
3008 /* read more */
3010 "%lu/%lu bytes of KX read. Rescheduling...\n",
3011 queue->cread_off, INITIAL_KX_SIZE);
3012 queue->read_task =
3014 return;
3015 }
3016 /* we got all the data, let's find out who we are talking to! */
3018 (const struct GNUNET_CRYPTO_HpkeEncapsulation*)
3019 queue->cread_buf,
3020 queue);
3021 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
3022 {
3024 "Invalid TCP KX received from %s\n",
3025 GNUNET_a2s (queue->address, queue->address_len));
3027 return;
3028 }
3029 if (0 !=
3030 memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
3031 {
3033 "Invalid sender in TCP KX received from %s\n",
3034 GNUNET_a2s (queue->address, queue->address_len));
3036 return;
3037 }
3038 send_challenge (tc.challenge, queue);
3039 queue->write_task =
3041 queue->sock,
3042 &queue_write,
3043 queue);
3044
3045 /* update queue timeout */
3046 queue->timeout =
3048 /* prepare to continue with regular read task immediately */
3049 memmove (queue->cread_buf,
3050 &queue->cread_buf[INITIAL_KX_SIZE],
3051 queue->cread_off - (INITIAL_KX_SIZE));
3053 "cread_off is %lu bytes before adjusting\n",
3054 queue->cread_off);
3055 queue->cread_off -= INITIAL_KX_SIZE;
3057 "cread_off set to %lu bytes\n",
3058 queue->cread_off);
3060}
3061
3062
3069static void
3070proto_read_kx (void *cls)
3071{
3072 struct ProtoQueue *pq = cls;
3073 ssize_t rcvd;
3074 struct GNUNET_TIME_Relative left;
3075 struct Queue *queue;
3076 struct TCPConfirmation tc;
3078
3079 pq->read_task = NULL;
3081 if (0 == left.rel_value_us)
3082 {
3083 free_proto_queue (pq);
3084 return;
3085 }
3086 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
3087 &pq->ibuf[pq->ibuf_off],
3088 sizeof(pq->ibuf) - pq->ibuf_off);
3090 "Proto received %lu bytes for KX\n", rcvd);
3091 if (-1 == rcvd)
3092 {
3093 if ((EAGAIN != errno) && (EINTR != errno))
3094 {
3096 free_proto_queue (pq);
3097 return;
3098 }
3099 /* try again */
3100 pq->read_task =
3102 return;
3103 }
3104 if (0 == rcvd)
3105 {
3106 /* Orderly shutdown of connection */
3108 "Socket for proto queue %p seems to have been closed\n", pq);
3109 free_proto_queue (pq);
3110 return;
3111 }
3112 pq->ibuf_off += rcvd;
3113 if (sizeof (struct TCPNATProbeMessage) == pq->ibuf_off)
3114 {
3115 struct TCPNATProbeMessage *pm = (struct TCPNATProbeMessage *) pq->ibuf;
3116
3118 &pm->clientIdentity);
3119
3120 queue = GNUNET_new (struct Queue);
3121 queue->target = pm->clientIdentity;
3122 eddsa_pub_to_hpke_key (&queue->target.public_key,
3123 &queue->target_hpke_key);
3126 }
3127 else if (pq->ibuf_off > sizeof(pq->ibuf))
3128 {
3129 /* read more */
3130 pq->read_task =
3132 return;
3133 }
3134 else
3135 {
3136 /* we got all the data, let's find out who we are talking to! */
3137 queue = GNUNET_new (struct Queue);
3139 (const struct GNUNET_CRYPTO_HpkeEncapsulation *) pq->
3140 ibuf,
3141 queue);
3142 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
3143 {
3145 "Invalid TCP KX received from %s\n",
3146 GNUNET_a2s (pq->address, pq->address_len));
3147 gcry_cipher_close (queue->in_cipher);
3149 free_proto_queue (pq);
3150 return;
3151 }
3152 queue->target = tc.sender;
3153 eddsa_pub_to_hpke_key (&queue->target.public_key,
3154 &queue->target_hpke_key);
3157 }
3158 queue->address = pq->address; /* steals reference */
3159 queue->address_len = pq->address_len;
3160 queue->listen_sock = pq->listen_sock;
3161 queue->sock = pq->sock;
3162
3164 "created queue with target %s\n",
3165 GNUNET_i2s (&queue->target));
3166
3168 "start kx proto\n");
3169
3171 boot_queue (queue);
3172 queue->read_task =
3174 queue->sock,
3175 read_task,
3176 queue);
3177 queue->write_task =
3179 queue->sock,
3180 &queue_write,
3181 queue);
3182 // TODO To early! Move it somewhere else.
3183 // send_challenge (tc.challenge, queue);
3184 queue->challenge_received = tc.challenge;
3185
3187 GNUNET_free (pq);
3188}
3189
3190
3191static struct ProtoQueue *
3193 struct sockaddr *in,
3194 socklen_t addrlen)
3195{
3196 struct ProtoQueue *pq = GNUNET_new (struct ProtoQueue);
3197
3198 if (NULL == sock)
3199 {
3200 // sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, addr, addrlen);
3201 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, 0);
3202 if (NULL == sock)
3203 {
3205 "socket(%d) failed: %s",
3206 in->sa_family,
3207 strerror (errno));
3208 GNUNET_free (in);
3209 GNUNET_free (pq);
3210 return NULL;
3211 }
3212 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, addrlen)) &&
3213 (errno != EINPROGRESS))
3214 {
3216 "connect to `%s' failed: %s",
3217 GNUNET_a2s (in, addrlen),
3218 strerror (errno));
3220 GNUNET_free (in);
3221 GNUNET_free (pq);
3222 return NULL;
3223 }
3224 }
3225 pq->address_len = addrlen;
3226 pq->address = in;
3228 pq->sock = sock;
3230 pq->sock,
3232 pq);
3234
3235 return pq;
3236}
3237
3238
3246static void
3247listen_cb (void *cls)
3248{
3249 struct sockaddr_storage in;
3250 socklen_t addrlen;
3251 struct GNUNET_NETWORK_Handle *sock;
3252 struct ListenTask *lt;
3253 struct sockaddr *in_addr;
3254
3256 "listen_cb\n");
3257
3258 lt = cls;
3259
3260 lt->listen_task = NULL;
3261 GNUNET_assert (NULL != lt->listen_sock);
3262 addrlen = sizeof(in);
3263 memset (&in, 0, sizeof(in));
3265 (struct sockaddr*) &in,
3266 &addrlen);
3267 if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
3268 return; /* system limit reached, wait until connection goes down */
3270 lt->listen_sock,
3271 &listen_cb,
3272 lt);
3273 if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
3274 return;
3275 if (NULL == sock)
3276 {
3278 return;
3279 }
3280 in_addr = GNUNET_memdup (&in, addrlen);
3281 create_proto_queue (sock, in_addr, addrlen);
3282}
3283
3284
3285static void
3287 const struct sockaddr *addr,
3288 socklen_t addrlen)
3289{
3290 struct TCPNATProbeMessage pm;
3291 struct ProtoQueue *pq;
3292 struct sockaddr *in_addr;
3293 (void) cls;
3294
3296 "addr->sa_family %d\n",
3297 addr->sa_family);
3299 "Try to connect back\n");
3300 in_addr = GNUNET_memdup (addr, addrlen);
3302 "in_addr->sa_family %d\n",
3303 in_addr->sa_family);
3304 pq = create_proto_queue (NULL, in_addr, addrlen);
3305 if (NULL != pq)
3306 {
3307 pm.header.size = htons (sizeof(struct TCPNATProbeMessage));
3308 pm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE);
3309 pm.clientIdentity = my_identity;
3310 memcpy (pq->write_buf, &pm, sizeof(struct TCPNATProbeMessage));
3311 pq->write_off = sizeof(struct TCPNATProbeMessage);
3313 pq->sock,
3315 pq);
3316 }
3317 else
3318 {
3320 "Couldn't create ProtoQueue for sending TCPNATProbeMessage\n");
3321 }
3322}
3323
3324
3325static void
3327{
3328 struct sockaddr *in = cls;
3329 struct PendingReversal *pending_reversal;
3330 struct GNUNET_HashCode key;
3331
3333 sizeof(struct sockaddr),
3334 &key);
3336 &key);
3337
3338 GNUNET_assert (NULL != pending_reversal);
3339
3341 &key,
3342 pending_reversal))
3344 "No pending reversal found for address %s\n",
3345 GNUNET_a2s (in, sizeof (struct sockaddr)));
3346 GNUNET_free (pending_reversal->in);
3347 GNUNET_free (pending_reversal);
3348}
3349
3350
3369static int
3370mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3371{
3372 struct sockaddr *in;
3373 socklen_t in_len = 0;
3374 const char *path;
3375 struct sockaddr_in *v4;
3376 struct sockaddr_in6 *v6;
3377 unsigned int is_natd = GNUNET_NO;
3378 struct GNUNET_HashCode key;
3379 struct GNUNET_HashCode queue_map_key;
3380 struct GNUNET_HashContext *hsh;
3381 struct Queue *queue;
3382
3384 "Connecting to %s at %s\n",
3385 GNUNET_i2s (peer),
3386 address);
3387 if (0 != strncmp (address,
3389 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
3390 {
3391 GNUNET_break_op (0);
3392 return GNUNET_SYSERR;
3393 }
3394 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
3395 in = tcp_address_to_sockaddr (path, &in_len);
3396
3397 if (NULL == in)
3398 {
3400 "Failed to setup TCP socket address\n");
3401 return GNUNET_SYSERR;
3402 }
3403
3405 "in %s\n",
3406 GNUNET_a2s (in, in_len));
3407
3410 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof (*peer));
3411 GNUNET_CRYPTO_hash_context_finish (hsh, &queue_map_key);
3413
3414 if (NULL != queue)
3415 {
3417 "Queue for %s already exists or is in construction\n", address);
3418 GNUNET_free (in);
3419 return GNUNET_NO;
3420 }
3421 switch (in->sa_family)
3422 {
3423 case AF_INET:
3424 v4 = (struct sockaddr_in *) in;
3425 if (0 == v4->sin_port)
3426 {
3427 is_natd = GNUNET_YES;
3429 sizeof(struct sockaddr),
3430 &key);
3433 &key))
3434 {
3436 "There is already a request reversal for `%s'at `%s'\n",
3437 GNUNET_i2s (peer),
3438 address);
3439 GNUNET_free (in);
3440 return GNUNET_SYSERR;
3441 }
3442 }
3443 break;
3444
3445 case AF_INET6:
3446 if (GNUNET_YES == disable_v6)
3447 {
3449 "IPv6 disabled, skipping %s\n", address);
3450 GNUNET_free (in);
3451 return GNUNET_SYSERR;
3452 }
3453 v6 = (struct sockaddr_in6 *) in;
3454 if (0 == v6->sin6_port)
3455 {
3457 "Request reversal for `%s' at `%s' not possible for an IPv6 address\n",
3458 GNUNET_i2s (peer),
3459 address);
3460 GNUNET_free (in);
3461 return GNUNET_SYSERR;
3462 }
3463 break;
3464
3465 default:
3466 GNUNET_assert (0);
3467 }
3468
3469 if (GNUNET_YES == is_natd)
3470 {
3471 struct sockaddr_in local_sa;
3472 struct PendingReversal *pending_reversal;
3473
3474 memset (&local_sa, 0, sizeof(local_sa));
3475 local_sa.sin_family = AF_INET;
3476 local_sa.sin_port = htons (bind_port);
3477 /* We leave sin_address at 0, let the kernel figure it out,
3478 even if our bind() is more specific. (May want to reconsider
3479 later.) */
3480 if (GNUNET_OK != GNUNET_NAT_request_reversal (nat, &local_sa, v4))
3481 {
3483 "request reversal for `%s' at `%s' failed\n",
3484 GNUNET_i2s (peer),
3485 address);
3486 GNUNET_free (in);
3487 return GNUNET_SYSERR;
3488 }
3489 pending_reversal = GNUNET_new (struct PendingReversal);
3490 pending_reversal->in = in;
3493 &key,
3494 pending_reversal,
3496 pending_reversal->target = *peer;
3498 &
3500 in);
3502 "Created NAT WAIT connection to `%s' at `%s'\n",
3503 GNUNET_i2s (peer),
3504 GNUNET_a2s (in, sizeof (struct sockaddr)));
3505 }
3506 else
3507 {
3508 struct GNUNET_NETWORK_Handle *sock;
3509
3510 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM,
3511 IPPROTO_TCP);
3512 if (NULL == sock)
3513 {
3515 "socket(%d) failed: %s",
3516 in->sa_family,
3517 strerror (errno));
3518 GNUNET_free (in);
3519 return GNUNET_SYSERR;
3520 }
3521 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) &&
3522 (errno != EINPROGRESS))
3523 {
3525 "connect to `%s' failed: %s",
3526 address,
3527 strerror (errno));
3529 GNUNET_free (in);
3530 return GNUNET_SYSERR;
3531 }
3532
3533 queue = GNUNET_new (struct Queue);
3534 queue->target = *peer;
3535 eddsa_pub_to_hpke_key (&queue->target.public_key, &queue->target_hpke_key);
3536 queue->key = queue_map_key;
3537 queue->address = in;
3538 queue->address_len = in_len;
3539 queue->sock = sock;
3541 boot_queue (queue);
3543 "booted queue with target %s\n",
3544 GNUNET_i2s (&queue->target));
3545 // queue->mq_awaits_continue = GNUNET_YES;
3546 queue->read_task =
3548 queue->sock,
3550 queue);
3551
3552
3554 "start kx mq_init\n");
3555
3557 queue->write_task =
3559 queue->sock,
3560 &queue_write,
3561 queue);
3562 }
3563
3564 return GNUNET_OK;
3565}
3566
3567
3576static int
3578 const struct GNUNET_HashCode *key,
3579 void *value)
3580{
3581 struct ListenTask *lt = value;
3582
3583 (void) cls;
3584 (void) key;
3585 if (NULL != lt->listen_task)
3586 {
3588 lt->listen_task = NULL;
3589 }
3590 if (NULL != lt->listen_sock)
3591 {
3593 lt->listen_sock = NULL;
3594 }
3595 GNUNET_free (lt);
3596 return GNUNET_OK;
3597}
3598
3599
3608static int
3610 const struct GNUNET_HashCode *target,
3611 void *value)
3612{
3613 struct Queue *queue = value;
3614
3615 (void) cls;
3616 (void) target;
3618 return GNUNET_OK;
3619}
3620
3621
3627static void
3628do_shutdown (void *cls)
3629{
3631 "Shutdown %s!\n",
3632 shutdown_running ? "running" : "not running");
3633
3635 return;
3636 else
3638
3639 while (NULL != proto_head)
3641 if (NULL != nat)
3642 {
3644 nat = NULL;
3645 }
3653 if (NULL != ch)
3654 {
3657 ch = NULL;
3658 }
3659 if (NULL != stats)
3660 {
3662 stats = NULL;
3663 }
3664 if (NULL != my_private_key)
3665 {
3667 my_private_key = NULL;
3668 }
3669 if (NULL != is)
3670 {
3672 is = NULL;
3673 }
3674 if (NULL != pils)
3675 {
3677 pils = NULL;
3678 }
3679 if (NULL != peerstore)
3680 {
3682 peerstore = NULL;
3683 }
3684 if (NULL != resolve_request_handle)
3685 {
3688 }
3690 "Shutdown done!\n");
3691}
3692
3693
3705static void
3706enc_notify_cb (void *cls,
3707 const struct GNUNET_PeerIdentity *sender,
3708 const struct GNUNET_MessageHeader *msg)
3709{
3710 (void) cls;
3711 (void) sender;
3712 (void) msg;
3713 GNUNET_break_op (0);
3714}
3715
3716
3730static void
3732 void **app_ctx,
3733 int add_remove,
3735 const struct sockaddr *addr,
3736 socklen_t addrlen)
3737{
3738 char *my_addr;
3740
3742 "nat address cb %s %s\n",
3743 add_remove ? "add" : "remove",
3744 GNUNET_a2s (addr, addrlen));
3745
3746 if (GNUNET_YES == add_remove)
3747 {
3749
3750 GNUNET_asprintf (&my_addr,
3751 "%s-%s",
3753 GNUNET_a2s (addr, addrlen));
3754 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3755 ai =
3757 my_addr,
3758 nt,
3760 GNUNET_free (my_addr);
3761 *app_ctx = ai;
3762 }
3763 else
3764 {
3765 ai = *app_ctx;
3767 *app_ctx = NULL;
3768 }
3769}
3770
3771
3775static void
3776add_addr (struct sockaddr *in, socklen_t in_len)
3777{
3778
3779 struct Addresses *saddrs;
3780
3782 "add address %s\n",
3783 GNUNET_a2s (in, in_len));
3784
3785 saddrs = GNUNET_new (struct Addresses);
3786 saddrs->addr = in;
3787 saddrs->addr_len = in_len;
3789
3791 "after add address %s\n",
3792 GNUNET_a2s (in, in_len));
3793
3795 "add address %s\n",
3796 GNUNET_a2s (saddrs->addr, saddrs->addr_len));
3797
3798 addrs_lens++;
3799}
3800
3801
3812static void
3814{
3815 char *keyfile;
3817
3818 if (GNUNET_OK !=
3820 "PEER",
3821 "PRIVATE_KEY",
3822 &keyfile))
3823 {
3825 "PEER",
3826 "PRIVATE_KEY");
3828 return;
3829 }
3830 if (GNUNET_SYSERR ==
3832 GNUNET_YES,
3833 &key))
3834 {
3836 "Failed to setup peer's private key\n");
3837 GNUNET_free (keyfile);
3839 return;
3840 }
3841 GNUNET_free (keyfile);
3842 GNUNET_assert (sizeof ikm == sizeof key.d);
3843 memcpy (ikm, key.d, sizeof ikm);
3844}
3845
3846
3854static int
3855init_socket (struct sockaddr *addr,
3856 socklen_t in_len)
3857{
3858 struct sockaddr_storage in_sto;
3859 socklen_t sto_len;
3860 struct GNUNET_NETWORK_Handle *listen_sock;
3861 struct ListenTask *lt;
3862 int sockfd;
3863 struct GNUNET_HashCode h_sock;
3864
3865 if (NULL == addr)
3866 {
3868 "Address is NULL.\n");
3869 return GNUNET_SYSERR;
3870 }
3871
3873 "address %s\n",
3874 GNUNET_a2s (addr, in_len));
3875
3876 listen_sock =
3877 GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
3878 if (NULL == listen_sock)
3879 {
3881 return GNUNET_SYSERR;
3882 }
3883
3884 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
3885 {
3887 GNUNET_NETWORK_socket_close (listen_sock);
3888 listen_sock = NULL;
3889 return GNUNET_SYSERR;
3890 }
3891
3892 if (GNUNET_OK !=
3893 GNUNET_NETWORK_socket_listen (listen_sock,
3894 5))
3895 {
3897 "listen");
3898 GNUNET_NETWORK_socket_close (listen_sock);
3899 listen_sock = NULL;
3900 return GNUNET_SYSERR;
3901 }
3902
3903 /* We might have bound to port 0, allowing the OS to figure it out;
3904 thus, get the real IN-address from the socket */
3905 sto_len = sizeof(in_sto);
3906
3907 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
3908 (struct sockaddr *) &in_sto,
3909 &sto_len))
3910 {
3911 memcpy (&in_sto, addr, in_len);
3912 sto_len = in_len;
3913 }
3914
3915 // addr = (struct sockaddr *) &in_sto;
3916 in_len = sto_len;
3918 "Bound to `%s'\n",
3919 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
3920 if (NULL == stats)
3921 stats = GNUNET_STATISTICS_create ("communicator-tcp", cfg);
3922
3923 if (NULL == is)
3925
3926 /* start listening */
3927
3928 lt = GNUNET_new (struct ListenTask);
3929 lt->listen_sock = listen_sock;
3930
3932 listen_sock,
3933 &listen_cb,
3934 lt);
3935
3937 "creating hash\n");
3938 sockfd = GNUNET_NETWORK_get_fd (lt->listen_sock);
3939 GNUNET_CRYPTO_hash (&sockfd,
3940 sizeof(int),
3941 &h_sock);
3942
3944 "creating map\n");
3945 if (NULL == lt_map)
3947
3949 "creating map entry\n");
3952 &h_sock,
3953 lt,
3955
3957 "map entry created\n");
3958
3959 if (NULL == queue_map)
3961
3962 if (NULL == ch)
3967 &mq_init,
3968 NULL,
3970 NULL,
3971 NULL);
3972
3973 if (NULL == ch)
3974 {
3975 GNUNET_break (0);
3976 if (NULL != resolve_request_handle)
3979 return GNUNET_SYSERR;
3980 }
3981
3982 add_addr (addr, in_len);
3983 return GNUNET_OK;
3984
3985}
3986
3987
3991static void
3993{
3994 struct sockaddr **saddrs;
3995 socklen_t *saddr_lens;
3996 int i;
3997 size_t len;
3998
4000 "starting nat register!\n");
4001 len = 0;
4002 i = 0;
4003 saddrs = GNUNET_malloc ((addrs_lens) * sizeof(struct sockaddr *));
4004 saddr_lens = GNUNET_malloc ((addrs_lens) * sizeof(socklen_t));
4005 for (struct Addresses *pos = addrs_head; NULL != pos; pos = pos->next)
4006 {
4008 "registering address %s\n",
4009 GNUNET_a2s (pos->addr, pos->addr_len));
4010
4011 saddr_lens[i] = pos->addr_len;
4012 len += saddr_lens[i];
4013 saddrs[i] = GNUNET_memdup (pos->addr, saddr_lens[i]);
4014 i++;
4015 }
4016
4018 "registering addresses %lu %lu %lu %lu\n",
4019 (addrs_lens) * sizeof(struct sockaddr *),
4020 (addrs_lens) * sizeof(socklen_t),
4021 len,
4025 IPPROTO_TCP,
4026 addrs_lens,
4027 (const struct sockaddr **) saddrs,
4028 saddr_lens,
4031 NULL /* closure */);
4032 for (i = addrs_lens - 1; i >= 0; i--)
4033 GNUNET_free (saddrs[i]);
4034 GNUNET_free (saddrs);
4035 GNUNET_free (saddr_lens);
4036
4037 if (NULL == nat)
4038 {
4039 GNUNET_break (0);
4040 if (NULL != resolve_request_handle)
4043 }
4044}
4045
4046
4054static void
4056 const struct sockaddr *addr,
4057 socklen_t in_len)
4058{
4059 struct sockaddr_in *v4;
4060 struct sockaddr_in6 *v6;
4061 struct sockaddr *in;
4062
4063 (void) cls;
4064 if (NULL != addr)
4065 {
4066 if (AF_INET == addr->sa_family)
4067 {
4068 v4 = (struct sockaddr_in *) addr;
4069 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, *v4, bind_port);// _global);
4070 }
4071 else if (AF_INET6 == addr->sa_family)
4072 {
4073 v6 = (struct sockaddr_in6 *) addr;
4074 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, *v6, bind_port);// _global);
4075 }
4076 else
4077 {
4079 "Address family %u not suitable (not AF_INET %u nor AF_INET6 %u \n",
4080 addr->sa_family,
4081 AF_INET,
4082 AF_INET6);
4083 return;
4084 }
4085 init_socket (in, in_len);
4086 }
4087 else
4088 {
4090 "Address is NULL. This might be an error or the resolver finished resolving.\n");
4091 if (NULL == addrs_head)
4092 {
4094 "Resolver finished resolving, but we do not listen to an address!.\n");
4095 return;
4096 }
4097 nat_register ();
4098 }
4099}
4100
4101
4102void
4103pid_change_cb (void *cls,
4104 const struct GNUNET_HELLO_Parser *parser,
4105 const struct GNUNET_HashCode *addr_hash)
4106{
4108 "Got PID to derive from `%s':\n",
4109 GNUNET_h2s (addr_hash));
4110 if (NULL == my_private_key)
4112
4114 (uint8_t*) ikm,
4115 addr_hash,
4121}
4122
4123
4132static void
4133run (void *cls,
4134 char *const *args,
4135 const char *cfgfile,
4136 const struct GNUNET_CONFIGURATION_Handle *c)
4137{
4138 char *bindto;
4139 struct sockaddr *in;
4140 socklen_t in_len;
4141 struct sockaddr_in v4;
4142 struct sockaddr_in6 v6;
4143 char *start;
4144 unsigned int port;
4145 char dummy[2];
4146 char *rest = NULL;
4147 struct PortOnlyIpv4Ipv6 *po;
4148 socklen_t addr_len_ipv4;
4149 socklen_t addr_len_ipv6;
4150
4151 (void) cls;
4152
4154 memset (&v4,0,sizeof(struct sockaddr_in));
4155 memset (&v6,0,sizeof(struct sockaddr_in6));
4156 cfg = c;
4157 if (GNUNET_OK !=
4160 "BINDTO",
4161 &bindto))
4162 {
4165 "BINDTO");
4166 return;
4167 }
4168 if (GNUNET_OK !=
4171 "MAX_QUEUE_LENGTH",
4173 {
4175 }
4176 if (GNUNET_OK !=
4179 "REKEY_INTERVAL",
4181 {
4183 }
4184 if (GNUNET_OK !=
4187 "REKEY_MAX_BYTES",
4189 {
4191 }
4193 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
4194 (GNUNET_YES ==
4197 "DISABLE_V6")))
4198 {
4200 }
4201 load_ikm ();
4203 GNUNET_assert (NULL != pils);
4205 if (NULL == peerstore)
4206 {
4207 GNUNET_free (bindto);
4208 GNUNET_break (0);
4210 return;
4211 }
4212
4214
4215 if (1 == sscanf (bindto, "%u%1s", &bind_port, dummy))
4216 {
4220 "address po %s\n",
4222 if (NULL != po->addr_ipv4)
4223 {
4225 }
4226 if (NULL != po->addr_ipv6)
4227 {
4230 }
4231 GNUNET_free (po);
4232 nat_register ();
4233 GNUNET_free (bindto);
4234 return;
4235 }
4236
4237 start = extract_address (bindto);
4238 // FIXME: check for NULL == start...
4239 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
4240 {
4241 bind_port = extract_port (bindto);
4242
4244 init_socket (in, in_len);
4245 nat_register ();
4247 GNUNET_free (bindto);
4248 return;
4249 }
4250
4251 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
4252 {
4253 bind_port = extract_port (bindto);
4255 init_socket (in, in_len);
4256 nat_register ();
4258 GNUNET_free (bindto);
4259 return;
4260 }
4261
4262 bind_port = extract_port (bindto);
4264 ":",
4265 &rest),
4266 AF_UNSPEC,
4269 &port);
4270
4271 GNUNET_free (bindto);
4273}
4274
4275
4283int
4284main (int argc, char *const *argv)
4285{
4286 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4288 };
4289 int ret;
4290
4292 "Starting tcp communicator\n");
4293
4294 ret = (GNUNET_OK ==
4296 argc,
4297 argv,
4298 "gnunet-communicator-tcp",
4299 _ ("GNUnet TCP communicator"),
4300 options,
4301 &run,
4302 NULL))
4303 ? 0
4304 : 1;
4305 return ret;
4306}
4307
4308
4309/* 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
#define GNUNET_CRYPTO_hkdf_expand(result, out_len, 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.
#define GNUNET_CRYPTO_kdf_arg_string(d)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_BlindablePrivateKey *sk, struct GNUNET_CRYPTO_HpkePrivateKey *sk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
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:1000
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:716
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_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:601
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:737
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:651
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:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition scheduler.c:1517
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_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:1588
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
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:1283
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
#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:604
#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:665
#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:436
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:141
Handle for the service.
A 256-bit hashcode.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Internal representation of an address a communicator is currently providing for the transport service...
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...