GNUnet 0.25.2-11-g84e94e98c
 
Loading...
Searching...
No Matches
gnunet-communicator-libp2p.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2025 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
29#include "platform.h"
30#include "gnunet_common.h"
31#include "gnunet_util_lib.h"
32#include "gnunet_pils_service.h"
33#include "gnunet_core_service.h"
35#include "gnunet_protocols.h"
36#include "gnunet_signatures.h"
37#include "gnunet_constants.h"
38#include "gnunet_nat_service.h"
42
43#include <libp2p/basic/scheduler.hpp>
44#include <libp2p/common/literals.hpp>
45#include <libp2p/injector/host_injector.hpp>
46#include <libp2p/layer/websocket/ws_adaptor.hpp>
47#include <libp2p/log/configurator.hpp>
48#include <libp2p/log/logger.hpp>
49#include <libp2p/protocol/echo.hpp>
50
51
52/* Shorthand for Logging */
53#define LOG(kind, ...) GNUNET_log_from (kind, "communicator-tcp", __VA_ARGS__)
54
55
57
58
62struct Queue
63{
68
73
78
82 struct sockaddr *address;
83
84};
85
86
91{
95 struct Addresses *next;
96
101
105 struct sockaddr *addr;
106
110 socklen_t addr_len;
111
112};
113
114
119
124
129
134
139
144
149
154
158static const struct GNUNET_CONFIGURATION_Handle *cfg;
159
163static struct Addresses *addrs_head;
164
168static struct Addresses *addrs_tail;
169
174
179
187static void
188listen_cb (void *cls);
189
190static void
199
200
201static void
210
211
219static void
221{
222 struct ListenTask *lt = NULL;
223 struct GNUNET_HashCode h_sock;
224 int sockfd;
225
226 if (NULL != queue->listen_sock)
227 {
228 sockfd = GNUNET_NETWORK_get_fd (queue->listen_sock);
229 GNUNET_CRYPTO_hash (&sockfd,
230 sizeof(int),
231 &h_sock);
232
234 }
235
237 "Disconnecting queue for peer `%s'\n",
238 GNUNET_i2s (&queue->target));
239 if (NULL != queue->rekey_monotime_sc)
240 {
241 GNUNET_PEERSTORE_store_cancel (queue->rekey_monotime_sc);
242 queue->rekey_monotime_sc = NULL;
243 }
244 if (NULL != queue->handshake_monotime_sc)
245 {
246 GNUNET_PEERSTORE_store_cancel (queue->handshake_monotime_sc);
247 queue->handshake_monotime_sc = NULL;
248 }
249 if (NULL != queue->handshake_ack_monotime_sc)
250 {
251 GNUNET_PEERSTORE_store_cancel (queue->handshake_ack_monotime_sc);
252 queue->handshake_ack_monotime_sc = NULL;
253 }
254 if (NULL != queue->rekey_monotime_get)
255 {
256 GNUNET_PEERSTORE_iteration_stop (queue->rekey_monotime_get);
257 queue->rekey_monotime_get = NULL;
258 }
259 if (NULL != queue->handshake_monotime_get)
260 {
261 GNUNET_PEERSTORE_iteration_stop (queue->handshake_monotime_get);
262 queue->handshake_monotime_get = NULL;
263 }
264 if (NULL != queue->handshake_ack_monotime_get)
265 {
266 GNUNET_PEERSTORE_iteration_stop (queue->handshake_ack_monotime_get);
267 queue->handshake_ack_monotime_get = NULL;
268 }
269 if (NULL != queue->qh)
270 {
272 queue->qh = NULL;
273 }
275 GNUNET_YES ==
278 "# queues active",
280 GNUNET_NO);
281 if (NULL != queue->read_task)
282 {
283 GNUNET_SCHEDULER_cancel (queue->read_task);
284 queue->read_task = NULL;
285 }
286 if (NULL != queue->write_task)
287 {
288 GNUNET_SCHEDULER_cancel (queue->write_task);
289 queue->write_task = NULL;
290 }
292 {
294 "closing socket failed\n");
295 }
296 gcry_cipher_close (queue->in_cipher);
297 gcry_cipher_close (queue->out_cipher);
298 GNUNET_free (queue->address);
299 if (0 != queue->backpressure)
300 queue->destroyed = GNUNET_YES;
301 else
303
304 if (NULL == lt)
305 return;
306
307 if ((! shutdown_running) && (NULL == lt->listen_task))
308 {
310 "add read net listen\n");
313 lt->listen_sock,
314 &listen_cb,
315 lt);
316 }
317 else
318 GNUNET_free (lt);
319}
320
321
330static void
331calculate_hmac (struct GNUNET_HashCode *hmac_secret,
332 const void *buf,
333 size_t buf_size,
334 struct GNUNET_ShortHashCode *smac)
335{
336 struct GNUNET_HashCode mac;
337
338 GNUNET_CRYPTO_hmac_raw (hmac_secret,
339 sizeof(struct GNUNET_HashCode),
340 buf,
341 buf_size,
342 &mac);
343 /* truncate to `struct GNUNET_ShortHashCode` */
344 memcpy (smac, &mac, sizeof(struct GNUNET_ShortHashCode));
345 /* ratchet hmac key */
346 GNUNET_CRYPTO_hash (hmac_secret,
347 sizeof(struct GNUNET_HashCode),
348 hmac_secret);
349}
350
351
358static void
360{
361 struct TCPFinish fin;
362
363 memset (&fin, 0, sizeof(fin));
364 fin.header.size = htons (sizeof(fin));
366 calculate_hmac (&queue->out_hmac, &fin, sizeof(fin), &fin.hmac);
367 /* if there is any message left in pwrite_buf, we
368 overwrite it (possibly dropping the last message
369 from CORE hard here) */
370 memcpy (queue->pwrite_buf, &fin, sizeof(fin));
371 queue->pwrite_off = sizeof(fin);
372 /* This flag will ensure that #queue_write() no longer
373 notifies CORE about the possibility of sending
374 more data, and that #queue_write() will call
375 #queue_destroy() once the @c fin was fully written. */
376 queue->finishing = GNUNET_YES;
377}
378
379
385static void
386queue_read (void *cls);
387
388
396static void
397core_read_finished_cb (void *cls, int success)
398{
399 struct Queue *queue = cls;
400 if (GNUNET_OK != success)
402 "# messages lost in communicator API towards CORE",
403 1,
404 GNUNET_NO);
405 if (NULL == queue)
406 return;
407
409 "backpressure %u\n",
410 queue->backpressure);
411
412 queue->backpressure--;
413 /* handle deferred queue destruction */
414 if ((queue->destroyed) && (0 == queue->backpressure))
415 {
417 return;
418 }
419 else if (GNUNET_YES != queue->destroyed)
420 {
421 queue->timeout =
423 );
424 /* possibly unchoke reading, now that CORE made progress */
425 if (NULL == queue->read_task)
426 queue->read_task =
428 queue->timeout),
429 queue->sock,
430 &queue_read,
431 queue);
432 }
433}
434
435
445static void
447 const void *plaintext,
448 size_t plaintext_len)
449{
450 const struct GNUNET_MessageHeader *hdr = plaintext;
451 int ret;
452
454 "pass message from %s to core\n",
455 GNUNET_i2s (&queue->target));
456
457 if (ntohs (hdr->size) != plaintext_len)
458 {
459 /* NOTE: If we ever allow multiple CORE messages in one
460 BOX, this will have to change! */
461 GNUNET_break (0);
462 return;
463 }
465 &queue->target,
466 hdr,
469 queue);
471 "passed to core\n");
472 if (GNUNET_OK == ret)
473 queue->backpressure++;
474 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
475 if (GNUNET_SYSERR == ret)
477 "# bytes lost due to CORE not running",
478 plaintext_len,
479 GNUNET_NO);
480}
481
482
492static void
494 const struct GNUNET_PeerIdentity *pid,
495 gcry_cipher_hd_t *cipher,
496 struct GNUNET_HashCode *hmac_key)
497{
498 char key[256 / 8];
499 char ctr[128 / 8];
500
501 GNUNET_assert (0 == gcry_cipher_open (cipher,
502 GCRY_CIPHER_AES256 /* low level: go for speed */
503 ,
504 GCRY_CIPHER_MODE_CTR,
505 0 /* flags */));
508 sizeof(key),
509 prk,
510 "gnunet-communicator-tcp-key",
511 strlen (
512 "gnunet-communicator-tcp-key"),
513 NULL,
514 0));
515 GNUNET_assert (0 == gcry_cipher_setkey (*cipher, key, sizeof(key)));
518 sizeof(ctr),
519 prk,
520 "gnunet-communicator-tcp-ctr",
521 strlen (
522 "gnunet-communicator-tcp-ctr"),
523 NULL,
524 0));
525 gcry_cipher_setctr (*cipher, ctr, sizeof(ctr));
528 sizeof(struct GNUNET_HashCode),
529 prk,
530 "gnunet-communicator-hmac",
531 strlen ("gnunet-communicator-hmac"),
532 NULL,
533 0));
534}
535
536
542static void
543rekey_monotime_store_cb (void *cls, int success)
544{
545 struct Queue *queue = cls;
546 if (GNUNET_OK != success)
547 {
549 "Failed to store rekey monotonic time in PEERSTORE!\n");
550 }
551 queue->rekey_monotime_sc = NULL;
552 GNUNET_PEERSTORE_iteration_next (queue->rekey_monotime_get, 1);
553}
554
555
563static void
565 const struct GNUNET_PEERSTORE_Record *record,
566 const char *emsg)
567{
568 struct Queue *queue = cls;
569 struct GNUNET_TIME_AbsoluteNBO *mtbe;
570 struct GNUNET_TIME_Absolute mt;
571 const struct GNUNET_PeerIdentity *pid;
572 struct GNUNET_TIME_AbsoluteNBO *rekey_monotonic_time;
573
574 (void) emsg;
575
576 rekey_monotonic_time = &queue->rekey_monotonic_time;
577 pid = &queue->target;
578 if (NULL == record)
579 {
580 queue->rekey_monotime_get = NULL;
581 return;
582 }
583 if (sizeof(*mtbe) != record->value_size)
584 {
585 GNUNET_PEERSTORE_iteration_next (queue->rekey_monotime_get, 1);
586 GNUNET_break (0);
587 return;
588 }
589 mtbe = record->value;
590 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
592 queue->rekey_monotonic_time).abs_value_us)
593 {
595 "Queue from %s dropped, rekey monotime in the past\n",
596 GNUNET_i2s (&queue->target));
597 GNUNET_break (0);
598 GNUNET_PEERSTORE_iteration_stop (queue->rekey_monotime_get);
599 queue->rekey_monotime_get = NULL;
600 // FIXME: Why should we try to gracefully finish here??
602 return;
603 }
604 queue->rekey_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
605 "transport_tcp_communicator",
606 pid,
608 rekey_monotonic_time,
609 sizeof(*
610 rekey_monotonic_time),
614 queue);
615}
616
617
624static void
626 const struct GNUNET_CRYPTO_HpkeEncapsulation *c,
627 struct Queue *queue)
628{
629 struct GNUNET_ShortHashCode k;
630
632 setup_cipher (&k, &my_identity, &queue->in_cipher, &queue->in_hmac);
633}
634
635
642static void
644 struct Queue *queue)
645{
646 struct GNUNET_ShortHashCode k;
647
649 setup_cipher (&k, &my_identity, &queue->in_cipher, &queue->in_hmac);
650}
651
652
661static void
662do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
663{
664 struct TcpRekeySignature thp;
665
667 thp.purpose.size = htonl (sizeof(thp));
669 "do_rekey size %u\n",
670 thp.purpose.size);
671 thp.sender = queue->target;
673 "sender %s\n",
676 "sender %s\n",
677 GNUNET_p2s (&queue->target.public_key));
678 thp.receiver = my_identity;
680 "receiver %s\n",
682 thp.ephemeral = rekey->ephemeral;
684 "ephemeral %s\n",
686 );
687 thp.monotonic_time = rekey->monotonic_time;
689 "time %s\n",
692 GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp)));
693 if (GNUNET_OK !=
696 &thp,
697 &rekey->sender_sig,
698 &queue->target.public_key))
699 {
700 GNUNET_break (0);
701 // FIXME Why should we try to gracefully finish here?
703 return;
704 }
705 queue->rekey_monotonic_time = rekey->monotonic_time;
706 queue->rekey_monotime_get = GNUNET_PEERSTORE_iteration_start (peerstore,
707 "transport_tcp_communicator",
708 &queue->target,
710 &
712 queue);
713 gcry_cipher_close (queue->in_cipher);
714 queue->rekeyed = GNUNET_YES;
716}
717
718
724static void
725handshake_ack_monotime_store_cb (void *cls, int success)
726{
727 struct Queue *queue = cls;
728
729 if (GNUNET_OK != success)
730 {
732 "Failed to store handshake ack monotonic time in PEERSTORE!\n");
733 }
734 queue->handshake_ack_monotime_sc = NULL;
735 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
736}
737
738
746static void
748 const struct GNUNET_PEERSTORE_Record *record,
749 const char *emsg)
750{
751 struct Queue *queue = cls;
752 struct GNUNET_TIME_AbsoluteNBO *mtbe;
753 struct GNUNET_TIME_Absolute mt;
754 const struct GNUNET_PeerIdentity *pid;
755 struct GNUNET_TIME_AbsoluteNBO *handshake_ack_monotonic_time;
756
757 (void) emsg;
758
759 handshake_ack_monotonic_time = &queue->handshake_ack_monotonic_time;
760 pid = &queue->target;
761 if (NULL == record)
762 {
763 queue->handshake_ack_monotime_get = NULL;
764 return;
765 }
766 if (sizeof(*mtbe) != record->value_size)
767 {
768 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
769 GNUNET_break (0);
770 return;
771 }
772 mtbe = record->value;
773 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
775 queue->handshake_ack_monotonic_time).abs_value_us)
776 {
778 "Queue from %s dropped, handshake ack monotime in the past\n",
779 GNUNET_i2s (&queue->target));
780 GNUNET_break (0);
781 GNUNET_PEERSTORE_iteration_stop (queue->handshake_ack_monotime_get);
782 queue->handshake_ack_monotime_get = NULL;
783 // FIXME: Why should we try to gracefully finish here?
785 return;
786 }
787 queue->handshake_ack_monotime_sc =
789 "transport_tcp_communicator",
790 pid,
792 handshake_ack_monotonic_time,
793 sizeof(*handshake_ack_monotonic_time),
797 queue);
798}
799
800
807static void
809 struct Queue *queue)
810{
811 struct TCPConfirmationAck tca;
812 struct TcpHandshakeAckSignature thas;
813
815 "sending challenge\n");
816
817 tca.header.type = ntohs (
819 tca.header.size = ntohs (sizeof(tca));
820 tca.challenge = challenge;
821 tca.sender = my_identity;
822 tca.monotonic_time =
824 thas.purpose.purpose = htonl (
826 thas.purpose.size = htonl (sizeof(thas));
827 thas.sender = my_identity;
828 thas.receiver = queue->target;
830 thas.challenge = tca.challenge;
832 &thas,
833 &tca.sender_sig);
834 GNUNET_assert (0 ==
835 gcry_cipher_encrypt (queue->out_cipher,
836 &queue->cwrite_buf[queue->cwrite_off],
837 sizeof(tca),
838 &tca,
839 sizeof(tca)));
840 queue->cwrite_off += sizeof(tca);
842 "sending challenge done\n");
843}
844
845
852static void
854{
855 setup_cipher (dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
857 queue->rekey_left_bytes =
859}
860
861
868static void
870{
871 struct TCPRekey rekey;
872 struct TcpRekeySignature thp;
873 struct GNUNET_ShortHashCode k;
874
875 GNUNET_assert (0 == queue->pwrite_off);
876 memset (&rekey, 0, sizeof(rekey));
877 GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &rekey.ephemeral,
878 &k);
880 rekey.header.size = ntohs (sizeof(rekey));
881 rekey.monotonic_time =
884 thp.purpose.size = htonl (sizeof(thp));
886 "inject_rekey size %u\n",
887 thp.purpose.size);
888 thp.sender = my_identity;
890 "sender %s\n",
892 thp.receiver = queue->target;
894 "receiver %s\n",
896 thp.ephemeral = rekey.ephemeral;
898 "ephemeral %s\n",
900 );
901 thp.monotonic_time = rekey.monotonic_time;
903 "time %s\n",
907 &thp,
908 &rekey.sender_sig);
909 calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
910 /* Encrypt rekey message with 'old' cipher */
911 GNUNET_assert (0 ==
912 gcry_cipher_encrypt (queue->out_cipher,
913 &queue->cwrite_buf[queue->cwrite_off],
914 sizeof(rekey),
915 &rekey,
916 sizeof(rekey)));
917 queue->cwrite_off += sizeof(rekey);
918 /* Setup new cipher for successive messages */
919 gcry_cipher_close (queue->out_cipher);
921}
922
923
924static int
926 const struct GNUNET_HashCode *key,
927 void *value)
928{
929 struct PendingReversal *pending_reversal = value;
930 (void) cls;
931
932 if (NULL != pending_reversal->timeout_task)
933 {
934 GNUNET_SCHEDULER_cancel (pending_reversal->timeout_task);
935 pending_reversal->timeout_task = NULL;
936 }
939 key,
940 pending_reversal));
941 GNUNET_free (pending_reversal->in);
942 GNUNET_free (pending_reversal);
943 return GNUNET_OK;
944}
945
946
947static void
948check_and_remove_pending_reversal (struct sockaddr *in, sa_family_t sa_family,
949 struct GNUNET_PeerIdentity *sender)
950{
951 if (AF_INET == sa_family)
952 {
953 struct PendingReversal *pending_reversal;
954 struct GNUNET_HashCode key;
955 struct sockaddr_in *natted_address;
956
957 natted_address = GNUNET_memdup (in, sizeof (struct sockaddr));
958 natted_address->sin_port = 0;
959 GNUNET_CRYPTO_hash (natted_address,
960 sizeof(struct sockaddr),
961 &key);
962
964 &key);
965 if (NULL != pending_reversal && (NULL == sender ||
966 0 != memcmp (sender,
967 &pending_reversal->target,
968 sizeof(struct
970 {
972 "Removing invalid pending reversal for `%s'at `%s'\n",
973 GNUNET_i2s (&pending_reversal->target),
974 GNUNET_a2s (in, sizeof (struct sockaddr)));
975 pending_reversals_delete_it (NULL, &key, pending_reversal);
976 }
977 GNUNET_free (natted_address);
978 }
979}
980
981
987static void
989{
990 if (NULL != pq->listen_sock)
991 {
993 pq->listen_sock = NULL;
994 }
995 if (NULL != pq->read_task)
996 {
998 pq->read_task = NULL;
999 }
1000 if (NULL != pq->write_task)
1001 {
1003 pq->write_task = NULL;
1004 }
1005 check_and_remove_pending_reversal (pq->address, pq->address->sa_family, NULL);
1007 GNUNET_free (pq->address);
1009 GNUNET_free (pq);
1010}
1011
1012
1019static void
1021{
1022 struct ProtoQueue *pq = cls;
1023 ssize_t sent;
1024 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In proto queue write\n");
1025 pq->write_task = NULL;
1026 if (0 != pq->write_off)
1027 {
1028 sent = GNUNET_NETWORK_socket_send (pq->sock,
1029 pq->write_buf,
1030 pq->write_off);
1032 "Sent %lu bytes to TCP queue\n", sent);
1033 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1034 {
1036 free_proto_queue (pq);
1037 return;
1038 }
1039 if (sent > 0)
1040 {
1041 size_t usent = (size_t) sent;
1042 pq->write_off -= usent;
1043 memmove (pq->write_buf,
1044 &pq->write_buf[usent],
1045 pq->write_off);
1046 }
1047 }
1048 /* do we care to write more? */
1049 if ((0 < pq->write_off))
1050 pq->write_task =
1052 pq->sock,
1054 pq);
1055}
1056
1057
1064static void
1065queue_write (void *cls)
1066{
1067 struct Queue *queue = cls;
1068 ssize_t sent;
1069 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In queue write\n");
1070 queue->write_task = NULL;
1071 if (0 != queue->cwrite_off)
1072 {
1073 sent = GNUNET_NETWORK_socket_send (queue->sock,
1074 queue->cwrite_buf,
1075 queue->cwrite_off);
1077 "Sent %lu bytes to TCP queue\n", sent);
1078 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1079 {
1082 return;
1083 }
1084 if (sent > 0)
1085 {
1086 size_t usent = (size_t) sent;
1087 queue->cwrite_off -= usent;
1088 memmove (queue->cwrite_buf,
1089 &queue->cwrite_buf[usent],
1090 queue->cwrite_off);
1091 queue->timeout =
1094 }
1095 }
1096 {
1097 /* can we encrypt more? (always encrypt full messages, needed
1098 such that #mq_cancel() can work!) */
1099 unsigned int we_do_not_need_to_rekey = (0 < queue->rekey_left_bytes
1100 - (queue->cwrite_off
1101 + queue->pwrite_off
1102 + sizeof (struct TCPRekey)));
1103 if (we_do_not_need_to_rekey &&
1104 (queue->pwrite_off > 0) &&
1105 (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1106 {
1108 "Encrypting %lu bytes\n", queue->pwrite_off);
1109 GNUNET_assert (0 ==
1110 gcry_cipher_encrypt (queue->out_cipher,
1111 &queue->cwrite_buf[queue->cwrite_off],
1112 queue->pwrite_off,
1113 queue->pwrite_buf,
1114 queue->pwrite_off));
1115 if (queue->rekey_left_bytes > queue->pwrite_off)
1116 queue->rekey_left_bytes -= queue->pwrite_off;
1117 else
1118 queue->rekey_left_bytes = 0;
1119 queue->cwrite_off += queue->pwrite_off;
1120 queue->pwrite_off = 0;
1121 }
1122 // if ((-1 != unverified_size)&& ((0 == queue->pwrite_off) &&
1123 if (((0 == queue->rekey_left_bytes) ||
1125 queue->rekey_time).rel_value_us)) &&
1126 (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey) &&
1127 (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE)))
1128 {
1130 }
1131 }
1132 if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1133 (GNUNET_YES == queue->mq_awaits_continue))
1134 {
1135 queue->mq_awaits_continue = GNUNET_NO;
1137 }
1138 /* did we just finish writing 'finish'? */
1139 if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1140 {
1142 "Finishing queue\n");
1144 return;
1145 }
1146 /* do we care to write more? */
1147 if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1148 queue->write_task =
1150 queue->sock,
1151 &queue_write,
1152 queue);
1153}
1154
1155
1163static size_t
1165{
1166 const struct GNUNET_MessageHeader *hdr;
1167 const struct TCPConfirmationAck *tca;
1168 const struct TCPBox *box;
1169 const struct TCPRekey *rekey;
1170 const struct TCPFinish *fin;
1171 struct TCPRekey rekeyz;
1172 struct TCPFinish finz;
1173 struct GNUNET_ShortHashCode tmac;
1174 uint16_t type;
1175 size_t size = 0;
1176 struct TcpHandshakeAckSignature thas;
1177 const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1178
1180 "try handle plaintext!\n");
1181
1182 hdr = (const struct GNUNET_MessageHeader *) queue->pread_buf;
1183 if ((sizeof(*hdr) > queue->pread_off))
1184 {
1186 "Handling plaintext, not even a header!\n");
1187 return 0; /* not even a header */
1188 }
1189
1190 if ((GNUNET_YES != queue->initial_core_kx_done) && (queue->unverified_size >
1192 {
1194 "Already received data of size %lu bigger than KX size %lu!\n",
1195 queue->unverified_size,
1197 GNUNET_break_op (0);
1199 return 0;
1200 }
1201
1202 type = ntohs (hdr->type);
1203 switch (type)
1204 {
1206 tca = (const struct TCPConfirmationAck *) queue->pread_buf;
1208 "start processing ack\n");
1209 if (sizeof(*tca) > queue->pread_off)
1210 {
1212 "Handling plaintext size of tca greater than pread offset.\n")
1213 ;
1214 return 0;
1215 }
1216 if (ntohs (hdr->size) != sizeof(*tca))
1217 {
1219 "Handling plaintext size does not match message type.\n");
1220 GNUNET_break_op (0);
1222 return 0;
1223 }
1224
1225 thas.purpose.purpose = htonl (
1227 thas.purpose.size = htonl (sizeof(thas));
1228 thas.sender = tca->sender;
1229 thas.receiver = my_identity;
1230 thas.monotonic_time = tca->monotonic_time;
1231 thas.challenge = tca->challenge;
1232
1235 &thas,
1236 &tca->sender_sig,
1237 &tca->sender.public_key))
1238 {
1240 "Verification of signature failed!\n");
1241 GNUNET_break (0);
1243 return 0;
1244 }
1245 if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
1246 {
1248 "Challenge in TCPConfirmationAck not correct!\n");
1249 GNUNET_break (0);
1251 return 0;
1252 }
1253
1254 queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iteration_start (
1255 peerstore,
1256 "transport_tcp_communicator",
1257 &queue->target,
1260 queue);
1261
1263 "Handling plaintext, ack processed!\n");
1264
1266 {
1267 send_challenge (queue->challenge_received, queue);
1268 queue->write_task =
1270 queue->sock,
1271 &queue_write,
1272 queue);
1273 }
1274 else if (GNUNET_TRANSPORT_CS_OUTBOUND == queue->cs)
1275 {
1277 queue->address->sa_family, NULL);
1278 }
1279
1284 queue->initial_core_kx_done = GNUNET_YES;
1285
1286 {
1287 char *foreign_addr;
1288
1289 switch (queue->address->sa_family)
1290 {
1291 case AF_INET:
1292 GNUNET_asprintf (&foreign_addr,
1293 "%s-%s",
1295 GNUNET_a2s (queue->address, queue->address_len));
1296 break;
1297
1298 case AF_INET6:
1299 GNUNET_asprintf (&foreign_addr,
1300 "%s-%s",
1302 GNUNET_a2s (queue->address, queue->address_len));
1303 break;
1304
1305 default:
1306 GNUNET_assert (0);
1307 }
1309 &queue->target,
1310 foreign_addr,
1311 UINT16_MAX, /* no MTU */
1313 0, /* Priority */
1314 queue->nt,
1315 queue->cs,
1316 queue->mq);
1317
1318 GNUNET_free (foreign_addr);
1319 }
1320
1321 size = ntohs (hdr->size);
1322 break;
1324 /* Special case: header size excludes box itself! */
1325 box = (const struct TCPBox *) queue->pread_buf;
1326 if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
1327 return 0;
1328 calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
1329 if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
1330 {
1331 GNUNET_break_op (0);
1333 return 0;
1334 }
1335 pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
1336 size = ntohs (hdr->size) + sizeof(*box);
1338 "Handling plaintext, box processed!\n");
1340 "# bytes decrypted with BOX",
1341 size,
1342 GNUNET_NO);
1344 "# messages decrypted with BOX",
1345 1,
1346 GNUNET_NO);
1347 break;
1348
1350 rekey = (const struct TCPRekey *) queue->pread_buf;
1351 if (sizeof(*rekey) > queue->pread_off)
1352 return 0;
1353 if (ntohs (hdr->size) != sizeof(*rekey))
1354 {
1355 GNUNET_break_op (0);
1357 return 0;
1358 }
1359 rekeyz = *rekey;
1360 memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
1361 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
1362 if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac)))
1363 {
1364 GNUNET_break_op (0);
1366 return 0;
1367 }
1368 do_rekey (queue, rekey);
1369 size = ntohs (hdr->size);
1371 "Handling plaintext, rekey processed!\n");
1373 "# rekeying successful",
1374 1,
1375 GNUNET_NO);
1376 break;
1377
1379 fin = (const struct TCPFinish *) queue->pread_buf;
1380 if (sizeof(*fin) > queue->pread_off)
1381 return 0;
1382 if (ntohs (hdr->size) != sizeof(*fin))
1383 {
1384 GNUNET_break_op (0);
1386 return 0;
1387 }
1388 finz = *fin;
1389 memset (&finz.hmac, 0, sizeof(finz.hmac));
1390 calculate_hmac (&queue->in_hmac, &finz, sizeof(finz), &tmac);
1391 if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
1392 {
1393 GNUNET_break_op (0);
1395 return 0;
1396 }
1397 /* handle FINISH by destroying queue */
1400 "Handling plaintext, finish processed!\n");
1401 break;
1402
1403 default:
1405 "Handling plaintext, nothing processed!\n");
1406 GNUNET_break_op (0);
1408 return 0;
1409 }
1410 GNUNET_assert (0 != size);
1411 if (-1 != queue->unverified_size)
1412 queue->unverified_size += size;
1413 return size;
1414}
1415
1416
1422static void
1423queue_read (void *cls)
1424{
1425 struct Queue *queue = cls;
1426 struct GNUNET_TIME_Relative left;
1427 ssize_t rcvd;
1428
1429 queue->read_task = NULL;
1430 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1431 &queue->cread_buf[queue->cread_off],
1432 BUF_SIZE - queue->cread_off);
1434 "Received %zd bytes from TCP queue\n", rcvd);
1435 if (-1 == rcvd)
1436 {
1437 if ((EAGAIN != errno) && (EINTR != errno))
1438 {
1441 return;
1442 }
1443 /* try again */
1444 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1445 if (0 != left.rel_value_us)
1446 {
1447 queue->read_task =
1449 return;
1450 }
1452 "Queue %p was idle for %s, disconnecting\n",
1453 queue,
1456 GNUNET_YES));
1458 return;
1459 }
1460 if (0 == rcvd)
1461 {
1462 /* Orderly shutdown of connection */
1464 "Socket for queue %p seems to have been closed\n", queue);
1466 return;
1467 }
1468 queue->timeout =
1470 queue->cread_off += rcvd;
1471 while ((queue->pread_off < sizeof(queue->pread_buf)) &&
1472 (queue->cread_off > 0))
1473 {
1474 size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
1475 queue->cread_off);
1476 size_t done;
1477 size_t total;
1478 size_t old_pread_off = queue->pread_off;
1479
1480 GNUNET_assert (0 ==
1481 gcry_cipher_decrypt (queue->in_cipher,
1482 &queue->pread_buf[queue->pread_off],
1483 max,
1484 queue->cread_buf,
1485 max));
1486 queue->pread_off += max;
1487 total = 0;
1488 while (0 != (done = try_handle_plaintext (queue)))
1489 {
1490 /* 'done' bytes of plaintext were used, shift buffer */
1491 GNUNET_assert (done <= queue->pread_off);
1492 /* NOTE: this memmove() could possibly sometimes be
1493 avoided if we pass 'total' into try_handle_plaintext()
1494 and use it at an offset into the buffer there! */
1495 memmove (queue->pread_buf,
1496 &queue->pread_buf[done],
1497 queue->pread_off - done);
1498 queue->pread_off -= done;
1499 total += done;
1500 /* The last plaintext was a rekey, abort for now */
1501 if (GNUNET_YES == queue->rekeyed)
1502 break;
1503 }
1504 /* when we encounter a rekey message, the decryption above uses the
1505 wrong key for everything after the rekey; in that case, we have
1506 to re-do the decryption at 'total' instead of at 'max'.
1507 However, we have to take into account that the plaintext buffer may have
1508 already contained data and not jumped too far ahead in the ciphertext.
1509 If there is no rekey and the last message is incomplete (max > total),
1510 it is safe to keep the decryption so we shift by 'max' */
1511 if (GNUNET_YES == queue->rekeyed)
1512 {
1513 max = total - old_pread_off;
1514 queue->rekeyed = GNUNET_NO;
1515 queue->pread_off = 0;
1516 }
1517 memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
1518 queue->cread_off -= max;
1519 }
1520 if (BUF_SIZE == queue->cread_off)
1521 return; /* buffer full, suspend reading */
1522 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1523 if (0 != left.rel_value_us)
1524 {
1525 if (max_queue_length > queue->backpressure)
1526 {
1527 /* continue reading */
1528 queue->read_task =
1530 }
1531 return;
1532 }
1534 "Queue %p was idle for %s, disconnecting\n",
1535 queue,
1538 GNUNET_YES));
1540}
1541
1542
1550static struct sockaddr *
1552 struct sockaddr_in6 v6,
1553 unsigned int port)
1554{
1555 struct sockaddr *in;
1556
1557 v6.sin6_family = AF_INET6;
1558 v6.sin6_port = htons ((uint16_t) port);
1559#if HAVE_SOCKADDR_IN_SIN_LEN
1560 v6.sin6_len = sizeof(struct sockaddr_in6);
1561#endif
1562 v6.sin6_flowinfo = 0;
1563 v6.sin6_scope_id = 0;
1564 in = GNUNET_memdup (&v6, sizeof(v6));
1565 *sock_len = sizeof(struct sockaddr_in6);
1566
1567 return in;
1568}
1569
1570
1578static struct sockaddr *
1580 struct sockaddr_in v4,
1581 unsigned int port)
1582{
1583 struct sockaddr *in;
1584
1585 v4.sin_family = AF_INET;
1586 v4.sin_port = htons ((uint16_t) port);
1587#if HAVE_SOCKADDR_IN_SIN_LEN
1588 v4.sin_len = sizeof(struct sockaddr_in);
1589#endif
1590 in = GNUNET_memdup (&v4, sizeof(v4));
1591 *sock_len = sizeof(struct sockaddr_in);
1592 return in;
1593}
1594
1595
1602static struct PortOnlyIpv4Ipv6 *
1603tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
1604{
1605 struct PortOnlyIpv4Ipv6 *po;
1606 struct sockaddr_in *i4;
1607 struct sockaddr_in6 *i6;
1608 socklen_t sock_len_ipv4;
1609 socklen_t sock_len_ipv6;
1610
1611 /* interpreting value as just a PORT number */
1612 if (*port > UINT16_MAX)
1613 {
1615 "BINDTO specification `%s' invalid: value too large for port\n",
1616 bindto);
1617 return NULL;
1618 }
1619
1620 po = GNUNET_new (struct PortOnlyIpv4Ipv6);
1621
1622 if (GNUNET_YES == disable_v6)
1623 {
1624 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
1625 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
1626 *port);
1627 po->addr_len_ipv4 = sock_len_ipv4;
1628 }
1629 else
1630 {
1631
1632 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
1633 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
1634 *port);
1635 po->addr_len_ipv4 = sock_len_ipv4;
1636
1637 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
1638 po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
1639 *port);
1640
1641 po->addr_len_ipv6 = sock_len_ipv6;
1642
1643 GNUNET_free (i6);
1644 }
1645
1646 GNUNET_free (i4);
1647
1648 return po;
1649}
1650
1651
1658static char *
1659extract_address (const char *bindto)
1660{
1661 char *addr;
1662 char *start;
1663 char *token;
1664 char *cp;
1665 char *rest = NULL;
1666
1668 "extract address with bindto %s\n",
1669 bindto);
1670
1671 if (NULL == bindto)
1673 "bindto is NULL\n");
1674
1675 cp = GNUNET_strdup (bindto);
1676
1678 "extract address 2\n");
1679
1680 start = cp;
1681 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
1682 {
1683 start++; /* skip over '['*/
1684 cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
1685 addr = GNUNET_strdup (start);
1686 }
1687 else
1688 {
1689 token = strtok_r (cp, "]", &rest);
1690 if (strlen (bindto) == strlen (token))
1691 {
1692 token = strtok_r (cp, ":", &rest);
1693 addr = GNUNET_strdup (token);
1694 }
1695 else
1696 {
1697 token++;
1698 addr = GNUNET_strdup (token);
1699 }
1700 }
1701
1703 "tcp address: %s\n",
1704 addr);
1705 GNUNET_free (cp);
1706 return addr;
1707}
1708
1709
1716static unsigned int
1717extract_port (const char *addr_and_port)
1718{
1719 unsigned int port;
1720 char dummy[2];
1721 char *token;
1722 char *addr;
1723 char *colon;
1724 char *cp;
1725 char *rest = NULL;
1726
1727 if (NULL != addr_and_port)
1728 {
1729 cp = GNUNET_strdup (addr_and_port);
1730 token = strtok_r (cp, "]", &rest);
1731 if (strlen (addr_and_port) == strlen (token))
1732 {
1733 colon = strrchr (cp, ':');
1734 if (NULL == colon)
1735 {
1736 GNUNET_free (cp);
1737 return 0;
1738 }
1739 addr = colon;
1740 addr++;
1741 }
1742 else
1743 {
1744 token = strtok_r (NULL, "]", &rest);
1745 if (NULL == token)
1746 {
1747 GNUNET_free (cp);
1748 return 0;
1749 }
1750 else
1751 {
1752 addr = token;
1753 addr++;
1754 }
1755 }
1756
1757
1758 if (1 == sscanf (addr, "%u%1s", &port, dummy))
1759 {
1760 /* interpreting value as just a PORT number */
1761 if (port > UINT16_MAX)
1762 {
1764 "Port `%u' invalid: value too large for port\n",
1765 port);
1766 GNUNET_free (cp);
1767 return 0;
1768 }
1769 }
1770 else
1771 {
1773 "BINDTO specification invalid: last ':' not followed by number\n");
1774 GNUNET_free (cp);
1775 return 0;
1776 }
1777 GNUNET_free (cp);
1778 }
1779 else
1780 {
1782 "return 0\n");
1783 /* interpret missing port as 0, aka pick any free one */
1784 port = 0;
1785 }
1786
1787 return port;
1788}
1789
1790
1798static struct sockaddr *
1799tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
1800{
1801 struct sockaddr *in;
1802 unsigned int port;
1803 struct sockaddr_in v4;
1804 struct sockaddr_in6 v6;
1805 char *start;
1806
1807 memset (&v4, 0, sizeof(v4));
1808 start = extract_address (bindto);
1809 GNUNET_assert (NULL != start);
1811 "start %s\n",
1812 start);
1813
1815 "!bindto %s\n",
1816 bindto);
1817
1818
1819 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
1820 {
1821 port = extract_port (bindto);
1822
1824 "port %u\n",
1825 port);
1826
1827 in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
1828 }
1829 else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
1830 {
1831 port = extract_port (bindto);
1832 in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
1833 }
1834 else
1835 {
1836 GNUNET_assert (0);
1837 }
1838
1840 return in;
1841}
1842
1843
1852static void
1854 const struct GNUNET_MessageHeader *msg,
1855 void *impl_state)
1856{
1857 struct Queue *queue = impl_state;
1858 uint16_t msize = ntohs (msg->size);
1859 struct TCPBox box;
1861 "In MQ send. Queue finishing: %s; write task running: %s\n",
1862 (GNUNET_YES == queue->finishing) ? "yes" : "no",
1863 (NULL == queue->write_task) ? "yes" : "no");
1864 GNUNET_assert (mq == queue->mq);
1865 queue->mq_awaits_continue = GNUNET_YES;
1866 if (GNUNET_YES == queue->finishing)
1867 return; /* this queue is dying, drop msg */
1868 GNUNET_assert (0 == queue->pwrite_off);
1870 box.header.size = htons (msize);
1871 calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
1872 memcpy (&queue->pwrite_buf[queue->pwrite_off], &box, sizeof(box));
1873 queue->pwrite_off += sizeof(box);
1874 memcpy (&queue->pwrite_buf[queue->pwrite_off], msg, msize);
1875 queue->pwrite_off += msize;
1877 "%lu bytes of plaintext to send\n", queue->pwrite_off);
1878 GNUNET_assert (NULL != queue->sock);
1879 if (NULL == queue->write_task)
1880 queue->write_task =
1882 queue->sock,
1883 &queue_write,
1884 queue);
1885}
1886
1887
1896static void
1897mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
1898{
1899 struct Queue *queue = impl_state;
1900
1901 if (mq == queue->mq)
1902 {
1903 queue->mq = NULL;
1905 }
1906}
1907
1908
1915static void
1916mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
1917{
1918 struct Queue *queue = impl_state;
1919
1920 GNUNET_assert (0 != queue->pwrite_off);
1921 queue->pwrite_off = 0;
1922}
1923
1924
1934static void
1935mq_error (void *cls, enum GNUNET_MQ_Error error)
1936{
1937 struct Queue *queue = cls;
1938
1940 "MQ error in queue to %s: %d\n",
1941 GNUNET_i2s (&queue->target),
1942 (int) error);
1944}
1945
1946
1954static void
1956{
1957 queue->nt =
1958 GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
1960 queue_map,
1961 &queue->key,
1962 queue,
1965 "# queues active",
1967 GNUNET_NO);
1968 queue->timeout =
1971 &mq_destroy,
1972 &mq_cancel,
1973 queue,
1974 NULL,
1975 &mq_error,
1976 queue);
1977}
1978
1979
1990static void
1992 const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
1993{
1994 struct TcpHandshakeSignature ths;
1995 struct TCPConfirmation tc;
1996
1997 memcpy (queue->cwrite_buf, c, sizeof(*c));
1998 queue->cwrite_off = sizeof(*c);
1999 /* compute 'tc' and append in encrypted format to cwrite_buf */
2000 tc.sender = my_identity;
2001 tc.monotonic_time =
2004 &tc.challenge,
2005 sizeof(tc.challenge));
2006 ths.purpose.purpose = htonl (
2008 ths.purpose.size = htonl (sizeof(ths));
2009 ths.sender = my_identity;
2010 ths.receiver = queue->target;
2011 ths.ephemeral = *c;
2012 ths.monotonic_time = tc.monotonic_time;
2013 ths.challenge = tc.challenge;
2015 &ths,
2016 &tc.sender_sig);
2017 GNUNET_assert (0 ==
2018 gcry_cipher_encrypt (queue->out_cipher,
2019 &queue->cwrite_buf[queue->cwrite_off],
2020 sizeof(tc),
2021 &tc,
2022 sizeof(tc)));
2023 queue->challenge = tc.challenge;
2024 queue->cwrite_off += sizeof(tc);
2025
2027 "handshake written\n");
2028}
2029
2030
2038static void
2040{
2042 struct GNUNET_ShortHashCode k;
2043
2045 &c, &k);
2046 setup_out_cipher (queue, &k);
2047 transmit_kx (queue, &c);
2048}
2049
2050
2056static void
2057handshake_monotime_store_cb (void *cls, int success)
2058{
2059 struct Queue *queue = cls;
2060 if (GNUNET_OK != success)
2061 {
2063 "Failed to store handshake monotonic time in PEERSTORE!\n");
2064 }
2065 queue->handshake_monotime_sc = NULL;
2066 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
2067}
2068
2069
2077static void
2079 const struct GNUNET_PEERSTORE_Record *record,
2080 const char *emsg)
2081{
2082 struct Queue *queue = cls;
2083 struct GNUNET_TIME_AbsoluteNBO *mtbe;
2084 struct GNUNET_TIME_Absolute mt;
2085 const struct GNUNET_PeerIdentity *pid;
2086 struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
2087
2088 (void) emsg;
2089
2090 handshake_monotonic_time = &queue->handshake_monotonic_time;
2091 pid = &queue->target;
2093 "tcp handshake with us %s\n",
2095 if (NULL == record)
2096 {
2097 queue->handshake_monotime_get = NULL;
2098 return;
2099 }
2101 "tcp handshake from peer %s\n",
2102 GNUNET_i2s (pid));
2103 if (sizeof(*mtbe) != record->value_size)
2104 {
2105 GNUNET_PEERSTORE_iteration_next (queue->handshake_ack_monotime_get, 1);
2106 GNUNET_break (0);
2107 return;
2108 }
2109 mtbe = record->value;
2110 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
2112 queue->handshake_monotonic_time).abs_value_us)
2113 {
2115 "Queue from %s dropped, handshake monotime in the past\n",
2116 GNUNET_i2s (&queue->target));
2117 GNUNET_break (0);
2118 GNUNET_PEERSTORE_iteration_stop (queue->handshake_ack_monotime_get);
2119 queue->handshake_ack_monotime_get = NULL;
2121 return;
2122 }
2123 queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
2124 "transport_tcp_communicator",
2125 pid,
2127 handshake_monotonic_time,
2128 sizeof(*
2129 handshake_monotonic_time),
2132 &
2134 queue);
2135}
2136
2137
2149static int
2151 struct TCPConfirmation *tc,
2152 char *ibuf)
2153{
2154 struct TcpHandshakeSignature ths;
2156
2158 0 ==
2159 gcry_cipher_decrypt (queue->in_cipher,
2160 tc,
2161 sizeof(*tc),
2162 &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
2163 sizeof(*tc)));
2164 ths.purpose.purpose = htonl (
2166 ths.purpose.size = htonl (sizeof(ths));
2167 ths.sender = tc->sender;
2168 ths.receiver = my_identity;
2169 memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
2170 ths.monotonic_time = tc->monotonic_time;
2171 ths.challenge = tc->challenge;
2174 &ths,
2175 &tc->sender_sig,
2176 &tc->sender.public_key);
2177 if (GNUNET_YES == ret)
2178 queue->handshake_monotime_get =
2180 "transport_tcp_communicator",
2181 &queue->target,
2184 queue);
2185 return ret;
2186}
2187
2188
2196static void
2197queue_read_kx (void *cls)
2198{
2199 struct Queue *queue = cls;
2200 ssize_t rcvd;
2201 struct GNUNET_TIME_Relative left;
2202 struct TCPConfirmation tc;
2203
2204 queue->read_task = NULL;
2205 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2206 if (0 == left.rel_value_us)
2207 {
2209 return;
2210 }
2211 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2212 &queue->cread_buf[queue->cread_off],
2213 BUF_SIZE - queue->cread_off);
2215 "Received %lu bytes to write in buffer of size %lu for KX from queue %p (expires in %"
2216 PRIu64 ")\n",
2217 rcvd, BUF_SIZE - queue->cread_off, queue, left.rel_value_us);
2218 if (-1 == rcvd)
2219 {
2220 if ((EAGAIN != errno) && (EINTR != errno))
2221 {
2224 return;
2225 }
2226 queue->read_task =
2228 return;
2229 }
2230 if (0 == rcvd)
2231 {
2232 /* Orderly shutdown of connection */
2234 "Socket for queue %p seems to have been closed\n", queue);
2236 return;
2237 }
2238 queue->cread_off += rcvd;
2239 if (queue->cread_off < INITIAL_KX_SIZE)
2240 {
2241 /* read more */
2243 "%lu/%lu bytes of KX read. Rescheduling...\n",
2244 queue->cread_off, INITIAL_KX_SIZE);
2245 queue->read_task =
2247 return;
2248 }
2249 /* we got all the data, let's find out who we are talking to! */
2251 (const struct GNUNET_CRYPTO_HpkeEncapsulation*)
2252 queue->cread_buf,
2253 queue);
2254 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
2255 {
2257 "Invalid TCP KX received from %s\n",
2258 GNUNET_a2s (queue->address, queue->address_len));
2260 return;
2261 }
2262 if (0 !=
2263 memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
2264 {
2266 "Invalid sender in TCP KX received from %s\n",
2267 GNUNET_a2s (queue->address, queue->address_len));
2269 return;
2270 }
2271 send_challenge (tc.challenge, queue);
2272 queue->write_task =
2274 queue->sock,
2275 &queue_write,
2276 queue);
2277
2278 /* update queue timeout */
2279 queue->timeout =
2281 /* prepare to continue with regular read task immediately */
2282 memmove (queue->cread_buf,
2283 &queue->cread_buf[INITIAL_KX_SIZE],
2284 queue->cread_off - (INITIAL_KX_SIZE));
2286 "cread_off is %lu bytes before adjusting\n",
2287 queue->cread_off);
2288 queue->cread_off -= INITIAL_KX_SIZE;
2290 "cread_off set to %lu bytes\n",
2291 queue->cread_off);
2293}
2294
2295
2302static void
2303proto_read_kx (void *cls)
2304{
2305 struct ProtoQueue *pq = cls;
2306 ssize_t rcvd;
2307 struct GNUNET_TIME_Relative left;
2308 struct Queue *queue;
2309 struct TCPConfirmation tc;
2311
2312 pq->read_task = NULL;
2314 if (0 == left.rel_value_us)
2315 {
2316 free_proto_queue (pq);
2317 return;
2318 }
2319 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
2320 &pq->ibuf[pq->ibuf_off],
2321 sizeof(pq->ibuf) - pq->ibuf_off);
2323 "Proto received %lu bytes for KX\n", rcvd);
2324 if (-1 == rcvd)
2325 {
2326 if ((EAGAIN != errno) && (EINTR != errno))
2327 {
2329 free_proto_queue (pq);
2330 return;
2331 }
2332 /* try again */
2333 pq->read_task =
2335 return;
2336 }
2337 if (0 == rcvd)
2338 {
2339 /* Orderly shutdown of connection */
2341 "Socket for proto queue %p seems to have been closed\n", pq);
2342 free_proto_queue (pq);
2343 return;
2344 }
2345 pq->ibuf_off += rcvd;
2346 if (sizeof (struct TCPNATProbeMessage) == pq->ibuf_off)
2347 {
2348 struct TCPNATProbeMessage *pm = (struct TCPNATProbeMessage *) pq->ibuf;
2349
2351 &pm->clientIdentity);
2352
2353 queue = GNUNET_new (struct Queue);
2354 queue->target = pm->clientIdentity;
2355 eddsa_pub_to_hpke_key (&queue->target.public_key, &queue->target_hpke_key);
2358 }
2359 else if (pq->ibuf_off > sizeof(pq->ibuf))
2360 {
2361 /* read more */
2362 pq->read_task =
2364 return;
2365 }
2366 else
2367 {
2368 /* we got all the data, let's find out who we are talking to! */
2369 queue = GNUNET_new (struct Queue);
2371 (const struct GNUNET_CRYPTO_HpkeEncapsulation *) pq->
2372 ibuf,
2373 queue);
2374 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
2375 {
2377 "Invalid TCP KX received from %s\n",
2378 GNUNET_a2s (pq->address, pq->address_len));
2379 gcry_cipher_close (queue->in_cipher);
2381 free_proto_queue (pq);
2382 return;
2383 }
2384 queue->target = tc.sender;
2385 eddsa_pub_to_hpke_key (&queue->target.public_key, &queue->target_hpke_key);
2388 }
2389 queue->address = pq->address; /* steals reference */
2390 queue->address_len = pq->address_len;
2391 queue->listen_sock = pq->listen_sock;
2392 queue->sock = pq->sock;
2393
2395 "created queue with target %s\n",
2396 GNUNET_i2s (&queue->target));
2397
2399 "start kx proto\n");
2400
2402 boot_queue (queue);
2403 queue->read_task =
2405 queue->sock,
2406 read_task,
2407 queue);
2408 queue->write_task =
2410 queue->sock,
2411 &queue_write,
2412 queue);
2413 // TODO To early! Move it somewhere else.
2414 // send_challenge (tc.challenge, queue);
2415 queue->challenge_received = tc.challenge;
2416
2418 GNUNET_free (pq);
2419}
2420
2421
2422static struct ProtoQueue *
2424 struct sockaddr *in,
2425 socklen_t addrlen)
2426{
2427 struct ProtoQueue *pq = GNUNET_new (struct ProtoQueue);
2428
2429 if (NULL == sock)
2430 {
2431 // sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, addr, addrlen);
2432 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, 0);
2433 if (NULL == sock)
2434 {
2436 "socket(%d) failed: %s",
2437 in->sa_family,
2438 strerror (errno));
2439 GNUNET_free (in);
2440 GNUNET_free (pq);
2441 return NULL;
2442 }
2443 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, addrlen)) &&
2444 (errno != EINPROGRESS))
2445 {
2447 "connect to `%s' failed: %s",
2448 GNUNET_a2s (in, addrlen),
2449 strerror (errno));
2451 GNUNET_free (in);
2452 GNUNET_free (pq);
2453 return NULL;
2454 }
2455 }
2456 pq->address_len = addrlen;
2457 pq->address = in;
2459 pq->sock = sock;
2461 pq->sock,
2463 pq);
2465
2466 return pq;
2467}
2468
2469
2477static void
2478listen_cb (void *cls)
2479{
2480 struct sockaddr_storage in;
2481 socklen_t addrlen;
2482 struct GNUNET_NETWORK_Handle *sock;
2483 struct ListenTask *lt;
2484 struct sockaddr *in_addr;
2485
2487 "listen_cb\n");
2488
2489 lt = cls;
2490
2491 lt->listen_task = NULL;
2492 GNUNET_assert (NULL != lt->listen_sock);
2493 addrlen = sizeof(in);
2494 memset (&in, 0, sizeof(in));
2496 (struct sockaddr*) &in,
2497 &addrlen);
2498 if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
2499 return; /* system limit reached, wait until connection goes down */
2501 lt->listen_sock,
2502 &listen_cb,
2503 lt);
2504 if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
2505 return;
2506 if (NULL == sock)
2507 {
2509 return;
2510 }
2511 in_addr = GNUNET_memdup (&in, addrlen);
2512 create_proto_queue (sock, in_addr, addrlen);
2513}
2514
2515
2516static void
2518{
2519 struct sockaddr *in = cls;
2520 struct PendingReversal *pending_reversal;
2521 struct GNUNET_HashCode key;
2522
2524 sizeof(struct sockaddr),
2525 &key);
2527 &key);
2528
2529 GNUNET_assert (NULL != pending_reversal);
2530
2532 &key,
2533 pending_reversal))
2535 "No pending reversal found for address %s\n",
2536 GNUNET_a2s (in, sizeof (struct sockaddr)));
2537 GNUNET_free (pending_reversal->in);
2538 GNUNET_free (pending_reversal);
2539}
2540
2541
2560static int
2561mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2562{
2563 struct sockaddr *in;
2564 socklen_t in_len = 0;
2565 const char *path;
2566 struct sockaddr_in *v4;
2567 struct sockaddr_in6 *v6;
2568 unsigned int is_natd = GNUNET_NO;
2569 struct GNUNET_HashCode key;
2570 struct GNUNET_HashCode queue_map_key;
2571 struct GNUNET_HashContext *hsh;
2572 struct Queue *queue;
2573
2575 "Connecting to %s at %s\n",
2576 GNUNET_i2s (peer),
2577 address);
2578 if (0 != strncmp (address,
2580 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2581 {
2582 GNUNET_break_op (0);
2583 return GNUNET_SYSERR;
2584 }
2585 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2586 in = tcp_address_to_sockaddr (path, &in_len);
2587
2588 if (NULL == in)
2589 {
2591 "Failed to setup TCP socket address\n");
2592 return GNUNET_SYSERR;
2593 }
2594
2596 "in %s\n",
2597 GNUNET_a2s (in, in_len));
2598
2601 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof (*peer));
2602 GNUNET_CRYPTO_hash_context_finish (hsh, &queue_map_key);
2604
2605 if (NULL != queue)
2606 {
2608 "Queue for %s already exists or is in construction\n", address);
2609 GNUNET_free (in);
2610 return GNUNET_NO;
2611 }
2612 switch (in->sa_family)
2613 {
2614 case AF_INET:
2615 v4 = (struct sockaddr_in *) in;
2616 if (0 == v4->sin_port)
2617 {
2618 is_natd = GNUNET_YES;
2620 sizeof(struct sockaddr),
2621 &key);
2624 &key))
2625 {
2627 "There is already a request reversal for `%s'at `%s'\n",
2628 GNUNET_i2s (peer),
2629 address);
2630 GNUNET_free (in);
2631 return GNUNET_SYSERR;
2632 }
2633 }
2634 break;
2635
2636 case AF_INET6:
2637 if (GNUNET_YES == disable_v6)
2638 {
2640 "IPv6 disabled, skipping %s\n", address);
2641 GNUNET_free (in);
2642 return GNUNET_SYSERR;
2643 }
2644 v6 = (struct sockaddr_in6 *) in;
2645 if (0 == v6->sin6_port)
2646 {
2648 "Request reversal for `%s' at `%s' not possible for an IPv6 address\n",
2649 GNUNET_i2s (peer),
2650 address);
2651 GNUNET_free (in);
2652 return GNUNET_SYSERR;
2653 }
2654 break;
2655
2656 default:
2657 GNUNET_assert (0);
2658 }
2659
2660 if (GNUNET_YES == is_natd)
2661 {
2662 struct sockaddr_in local_sa;
2663 struct PendingReversal *pending_reversal;
2664
2665 memset (&local_sa, 0, sizeof(local_sa));
2666 local_sa.sin_family = AF_INET;
2667 local_sa.sin_port = htons (bind_port);
2668 /* We leave sin_address at 0, let the kernel figure it out,
2669 even if our bind() is more specific. (May want to reconsider
2670 later.) */
2671 if (GNUNET_OK != GNUNET_NAT_request_reversal (nat, &local_sa, v4))
2672 {
2674 "request reversal for `%s' at `%s' failed\n",
2675 GNUNET_i2s (peer),
2676 address);
2677 GNUNET_free (in);
2678 return GNUNET_SYSERR;
2679 }
2680 pending_reversal = GNUNET_new (struct PendingReversal);
2681 pending_reversal->in = in;
2684 &key,
2685 pending_reversal,
2687 pending_reversal->target = *peer;
2689 &
2691 in);
2693 "Created NAT WAIT connection to `%s' at `%s'\n",
2694 GNUNET_i2s (peer),
2695 GNUNET_a2s (in, sizeof (struct sockaddr)));
2696 }
2697 else
2698 {
2699 struct GNUNET_NETWORK_Handle *sock;
2700
2701 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM,
2702 IPPROTO_TCP);
2703 if (NULL == sock)
2704 {
2706 "socket(%d) failed: %s",
2707 in->sa_family,
2708 strerror (errno));
2709 GNUNET_free (in);
2710 return GNUNET_SYSERR;
2711 }
2712 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) &&
2713 (errno != EINPROGRESS))
2714 {
2716 "connect to `%s' failed: %s",
2717 address,
2718 strerror (errno));
2720 GNUNET_free (in);
2721 return GNUNET_SYSERR;
2722 }
2723
2724 queue = GNUNET_new (struct Queue);
2725 queue->target = *peer;
2726 eddsa_pub_to_hpke_key (&queue->target.public_key, &queue->target_hpke_key);
2727 queue->key = queue_map_key;
2728 queue->address = in;
2729 queue->address_len = in_len;
2730 queue->sock = sock;
2732 boot_queue (queue);
2734 "booted queue with target %s\n",
2735 GNUNET_i2s (&queue->target));
2736 // queue->mq_awaits_continue = GNUNET_YES;
2737 queue->read_task =
2739 queue->sock,
2741 queue);
2742
2743
2745 "start kx mq_init\n");
2746
2748 queue->write_task =
2750 queue->sock,
2751 &queue_write,
2752 queue);
2753 }
2754
2755 return GNUNET_OK;
2756}
2757
2758
2767static int
2769 const struct GNUNET_HashCode *key,
2770 void *value)
2771{
2772 struct ListenTask *lt = value;
2773
2774 (void) cls;
2775 (void) key;
2776 if (NULL != lt->listen_task)
2777 {
2779 lt->listen_task = NULL;
2780 }
2781 if (NULL != lt->listen_sock)
2782 {
2784 lt->listen_sock = NULL;
2785 }
2786 GNUNET_free (lt);
2787 return GNUNET_OK;
2788}
2789
2790
2799static int
2801 const struct GNUNET_HashCode *target,
2802 void *value)
2803{
2804 struct Queue *queue = value;
2805
2806 (void) cls;
2807 (void) target;
2809 return GNUNET_OK;
2810}
2811
2812
2818static void
2819do_shutdown (void *cls)
2820{
2822 "Shutdown %s!\n",
2823 shutdown_running ? "running" : "not running");
2824
2826 return;
2827 else
2829
2830 while (NULL != proto_head)
2832 if (NULL != nat)
2833 {
2835 nat = NULL;
2836 }
2844 if (NULL != ch)
2845 {
2848 ch = NULL;
2849 }
2850 if (NULL != stats)
2851 {
2853 stats = NULL;
2854 }
2855 if (NULL != my_private_key)
2856 {
2858 my_private_key = NULL;
2859 }
2860 if (NULL != is)
2861 {
2863 is = NULL;
2864 }
2865 if (NULL != pils)
2866 {
2868 pils = NULL;
2869 }
2870 if (NULL != peerstore)
2871 {
2873 peerstore = NULL;
2874 }
2875 if (NULL != resolve_request_handle)
2876 {
2879 }
2881 "Shutdown done!\n");
2882}
2883
2884
2896static void
2897enc_notify_cb (void *cls,
2898 const struct GNUNET_PeerIdentity *sender,
2899 const struct GNUNET_MessageHeader *msg)
2900{
2901 (void) cls;
2902 (void) sender;
2903 (void) msg;
2904 GNUNET_break_op (0);
2905}
2906
2907
2911static void
2912add_addr (struct sockaddr *in, socklen_t in_len)
2913{
2914
2915 struct Addresses *saddrs;
2916
2918 "add address %s\n",
2919 GNUNET_a2s (in, in_len));
2920
2921 saddrs = GNUNET_new (struct Addresses);
2922 saddrs->addr = in;
2923 saddrs->addr_len = in_len;
2925
2927 "after add address %s\n",
2928 GNUNET_a2s (in, in_len));
2929
2931 "add address %s\n",
2932 GNUNET_a2s (saddrs->addr, saddrs->addr_len));
2933
2934 addrs_lens++;
2935}
2936
2937
2951static enum GNUNET_GenericReturnValue
2953{
2954 char *filename;
2955 struct GNUNET_DISK_FileHandle *filehandle;
2956 int ret;
2957
2958 if (GNUNET_OK !=
2960 "pils",
2961 "SECRET_KEY_FILE",
2962 &filename))
2963 {
2965 "PILS service is lacking initial secret key file configuration setting. Exiting\n");
2966 return GNUNET_SYSERR;
2967 }
2968 if (NULL == filename)
2969 return GNUNET_SYSERR;
2971 if (GNUNET_SYSERR == ret)
2972 return GNUNET_SYSERR;
2973 if (GNUNET_NO == ret)
2974 {
2975 /* File does not exist - generate a new initial secret key and save it */
2976 // TODO consider the case that the file exists and ist not readable
2978 ikm,
2979 sizeof ikm);
2981 {
2983 "PILS service cannot create dir for saving initial secret key file. Exiting\n");
2984 return GNUNET_SYSERR;
2985 }
2986 filehandle = GNUNET_DISK_file_open (filename,
2990 | // would
2991 // the
2992 // group
2993 // need
2994 // read
2995 // perm?
2997 if (NULL == filehandle)
2998 {
3000 "PILS service had an issue with opening the initial secret key file. Exiting\n");
3001 GNUNET_DISK_file_close (filehandle);
3002 return GNUNET_SYSERR;
3003 }
3004 ret = GNUNET_DISK_file_write (filehandle,
3005 ikm,
3006 sizeof ikm);
3007 GNUNET_DISK_file_close (filehandle);
3008 if (sizeof ikm != ret)
3009 {
3011 "PILS service had an issue with writing the initial secret key to file. Exiting\n")
3012 ;
3013 return GNUNET_SYSERR;
3014 }
3015 }
3016 else
3017 {
3018 /* File existes - just read from it */
3019 off_t size;
3021 "PILS is going to read initial secret key from file %s\n",
3022 filename);
3023 filehandle = GNUNET_DISK_file_open (filename,
3026 if (NULL == filehandle)
3027 {
3029 " Not able to open file\n");
3030 return GNUNET_SYSERR;
3031 }
3032 if (GNUNET_OK != GNUNET_DISK_file_handle_size (filehandle, &size))
3033 {
3035 " File has the wrong size %lu\n",
3036 size);
3037 GNUNET_DISK_file_close (filehandle);
3038 return GNUNET_SYSERR;
3039 }
3040 if (sizeof ikm != size)
3041 {
3043 " Something is wrong with the file size, expected: %lu size, got: %lu\n",
3044 size,
3045 sizeof ikm);
3046 GNUNET_DISK_file_close (filehandle);
3047 return GNUNET_SYSERR;
3048 }
3049 ret = GNUNET_DISK_file_read (filehandle,
3050 ikm,
3051 sizeof ikm);
3052 GNUNET_DISK_file_close (filehandle);
3053 if (sizeof ikm != ret)
3054 {
3056 " Read initial secret key with wrong size %u, expected %lu\n", ret,
3057 sizeof ikm);
3058 return GNUNET_SYSERR;
3059 }
3060
3061 }
3062 return GNUNET_OK;
3063}
3064
3065
3073static int
3074init_socket (struct sockaddr *addr,
3075 socklen_t in_len)
3076{
3077 struct sockaddr_storage in_sto;
3078 socklen_t sto_len;
3079 struct GNUNET_NETWORK_Handle *listen_sock;
3080 struct ListenTask *lt;
3081 int sockfd;
3082 struct GNUNET_HashCode h_sock;
3083
3084 if (NULL == addr)
3085 {
3087 "Address is NULL.\n");
3088 return GNUNET_SYSERR;
3089 }
3090
3092 "address %s\n",
3093 GNUNET_a2s (addr, in_len));
3094
3095 listen_sock =
3096 GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
3097 if (NULL == listen_sock)
3098 {
3100 return GNUNET_SYSERR;
3101 }
3102
3103 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
3104 {
3106 GNUNET_NETWORK_socket_close (listen_sock);
3107 listen_sock = NULL;
3108 return GNUNET_SYSERR;
3109 }
3110
3111 if (GNUNET_OK !=
3112 GNUNET_NETWORK_socket_listen (listen_sock,
3113 5))
3114 {
3116 "listen");
3117 GNUNET_NETWORK_socket_close (listen_sock);
3118 listen_sock = NULL;
3119 return GNUNET_SYSERR;
3120 }
3121
3122 /* We might have bound to port 0, allowing the OS to figure it out;
3123 thus, get the real IN-address from the socket */
3124 sto_len = sizeof(in_sto);
3125
3126 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
3127 (struct sockaddr *) &in_sto,
3128 &sto_len))
3129 {
3130 memcpy (&in_sto, addr, in_len);
3131 sto_len = in_len;
3132 }
3133
3134 // addr = (struct sockaddr *) &in_sto;
3135 in_len = sto_len;
3137 "Bound to `%s'\n",
3138 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
3139 if (NULL == stats)
3140 stats = GNUNET_STATISTICS_create ("communicator-tcp", cfg);
3141
3142 if (NULL == is)
3144
3145 /* start listening */
3146
3147 lt = GNUNET_new (struct ListenTask);
3148 lt->listen_sock = listen_sock;
3149
3151 listen_sock,
3152 &listen_cb,
3153 lt);
3154
3156 "creating hash\n");
3157 sockfd = GNUNET_NETWORK_get_fd (lt->listen_sock);
3158 GNUNET_CRYPTO_hash (&sockfd,
3159 sizeof(int),
3160 &h_sock);
3161
3163 "creating map\n");
3164 if (NULL == lt_map)
3166
3168 "creating map entry\n");
3171 &h_sock,
3172 lt,
3174
3176 "map entry created\n");
3177
3178 if (NULL == queue_map)
3180
3181 if (NULL == ch)
3186 &mq_init,
3187 NULL,
3189 NULL,
3190 NULL);
3191
3192 if (NULL == ch)
3193 {
3194 GNUNET_break (0);
3195 if (NULL != resolve_request_handle)
3198 return GNUNET_SYSERR;
3199 }
3200
3201 add_addr (addr, in_len);
3202 return GNUNET_OK;
3203
3204}
3205
3206
3207void
3208pid_change_cb (void *cls,
3209 const struct GNUNET_HELLO_Parser *parser,
3210 const struct GNUNET_HashCode *addr_hash)
3211{
3213 "Got PID to derive from `%s':\n",
3214 GNUNET_h2s (addr_hash));
3215 if (NULL == my_private_key)
3217
3219 (uint8_t*) ikm,
3220 addr_hash,
3226}
3227
3228
3237static void
3238run (void *cls,
3239 char *const *args,
3240 const char *cfgfile,
3241 const struct GNUNET_CONFIGURATION_Handle *c)
3242{
3243 struct sockaddr *in;
3244
3245 (void) cls;
3246
3247 cfg = c;
3248 if (GNUNET_OK !=
3251 "REKEY_INTERVAL",
3253 {
3255 }
3256 load_ikm ();
3258 GNUNET_assert (NULL != pils);
3260 if (NULL == peerstore)
3261 {
3262 GNUNET_free (bindto);
3263 GNUNET_break (0);
3265 return;
3266 }
3267
3269
3270 if (1 == sscanf (bindto, "%u%1s", &bind_port, dummy))
3271 {
3273 addr_len_ipv4 = po->addr_len_ipv4;
3275 "address po %s\n",
3276 GNUNET_a2s (po->addr_ipv4, addr_len_ipv4));
3277 if (NULL != po->addr_ipv4)
3278 {
3279 init_socket (po->addr_ipv4, addr_len_ipv4);
3280 }
3281 if (NULL != po->addr_ipv6)
3282 {
3283 addr_len_ipv6 = po->addr_len_ipv6;
3284 init_socket (po->addr_ipv6, addr_len_ipv6);
3285 }
3286
3287 // The following snippet is taken from https://github.com/libp2p/cpp-libp2p/blob/master/example/01-echo/libp2p_echo_client.cpp
3288 // and needs to be wrapped to c for being able to be called from within
3289 // this communicator.
3290 // It is merely there as a reminder of the needed functions and general
3291 // structure in order to send something via the c++ implementation of
3292 // libp2p.
3293 //
3294 // post(
3295 // *context,
3296 // [log,
3297 // host{std::move(host)},
3298 // &echo,
3299 // &message,
3300 // argv, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3301 // sch] {
3302 // auto server_ma_res =
3303 // libp2p::multi::Multiaddress::create(argv[1]); // NOLINT
3304 // if (!server_ma_res) {
3305 // log->error("unable to create server multiaddress: {}",
3306 // server_ma_res.error());
3307 // std::exit(EXIT_FAILURE);
3308 // }
3309 // const auto &server_ma = server_ma_res.value();
3310
3311 // auto server_peer_id_str = server_ma.getPeerId();
3312 // if (!server_peer_id_str) {
3313 // log->error("unable to get peer id");
3314 // std::exit(EXIT_FAILURE);
3315 // }
3316
3317 // auto server_peer_id_res =
3318 // libp2p::peer::PeerId::fromBase58(*server_peer_id_str);
3319 // if (!server_peer_id_res) {
3320 // log->error("Unable to decode peer id from base 58: {}",
3321 // server_peer_id_res.error());
3322 // std::exit(EXIT_FAILURE);
3323 // }
3324
3325 // const auto &server_peer_id = server_peer_id_res.value();
3326
3327 // auto peer_info = libp2p::peer::PeerInfo{server_peer_id, {server_ma}};
3328
3329 // // create Host object and open a stream through it
3330 // host->newStream(
3331 // peer_info,
3332 // {echo.getProtocolId()},
3333 // [log, &echo, &message, sch](auto &&stream_res) {
3334 // if (!stream_res) {
3335 // log->error("Cannot connect to server: {}", stream_res.error());
3336 // std::exit(EXIT_FAILURE);
3337 // }
3338
3339 // auto stream_p = std::move(stream_res.value().stream);
3340
3341 // auto echo_client = echo.createClient(stream_p);
3342
3343 // if (message.size() < 120) {
3344 // log->info("SENDING {}", message);
3345 // } else {
3346 // log->info("SENDING {} bytes", message.size());
3347 // }
3348
3349 // sch->schedule(
3350 // [log, message, stream = std::move(stream_p), echo_client] {
3351 // echo_client->sendAnd(
3352 // message,
3353 // [log,
3354 // stream = std::move(stream)](auto &&response_result) {
3355 // if (response_result.has_error()) {
3356 // log->info("Error happened: {}",
3357 // response_result.error());
3358 // stream->close(
3359 // [log](auto &&) { std::exit(EXIT_SUCCESS); });
3360 // return;
3361 // }
3362 // auto &resp = response_result.value();
3363 // if (resp.size() < 120) {
3364 // log->info("RESPONSE {}", resp);
3365 // } else {
3366 // log->info("RESPONSE size={}", resp.size());
3367 // }
3368 // stream->close(
3369 // [](auto &&) { std::exit(EXIT_SUCCESS); });
3370 // });
3371 // },
3372 // std::chrono::milliseconds(1000));
3373 // });
3374 // });
3375
3376 GNUNET_free (po);
3377 GNUNET_free (bindto);
3378 return;
3379 }
3380}
3381
3382
3390int
3391main (int argc, char *const *argv)
3392{
3393 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3395 };
3396 int ret;
3397
3399 "Starting tcp communicator\n");
3400
3401 ret = (GNUNET_OK ==
3403 argc,
3404 argv,
3405 "gnunet-communicator-libp2p",
3406 _ ("GNUnet libp2p communicator"),
3407 options,
3408 &run,
3409 NULL))
3410 ? 0
3411 : 1;
3412 return ret;
3413}
3414
3415
3416/* 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
static struct GNUNET_TESTING_Interpreter * is
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
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 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.
static void mq_destroy(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
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.
static void do_rekey(struct Queue *queue, const struct TCPRekey *rekey)
Handle rekey message on queue.
static void eddsa_priv_to_hpke_key(struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
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 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 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 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_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 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 struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
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.
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 void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
static void pending_reversal_timeout(void *cls)
static void queue_read(void *cls)
Queue read task.
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.
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 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 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 int shutdown_running
A flag indicating we are already doing a shutdown.
static enum GNUNET_GenericReturnValue load_ikm()
FIXME: We could alternatively ask PILS for de/encaps, but at a high cost wrt async RPC calls....
static 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,...)
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 void eddsa_pub_to_hpke_key(struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_EcdhePublicKey *pk)
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.
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 struct GNUNET_CRYPTO_EcdhePrivateKey my_x25519_private_key
Our private key.
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 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 unsigned int bind_port
The port the communicator should be assigned to.
#define INITIAL_CORE_KX_SIZE
Size of the initial core key exchange messages.
static struct GNUNET_CONTAINER_MultiHashMap * pending_reversals
Map of pending reversals.
static struct ProtoQueue * proto_tail
Protoqueues DLL tail.
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.
static unsigned long long max_queue_length
Maximum queue length before we stop reading towards the transport service.
struct GNUNET_RESOLVER_RequestHandle * resolve_request_handle
Handle for DNS lookup of bindto address.
static int addrs_lens
Number of addresses in the DLL for register at NAT service.
#define PROTO_QUEUE_TIMEOUT
How long do we wait until we must have received the initial KX?
#define INITIAL_KX_SIZE
Size of the initial key exchange message sent first in both directions.
static struct ProtoQueue * proto_head
Protoqueues DLL head.
#define DEFAULT_REKEY_INTERVAL
How often do we rekey based on time (at least)
static unsigned long long rekey_max_bytes
The rekey byte maximum.
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 char * filename
static int disable_v6
Disable IPv6.
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 unsigned char ikm[256/8]
The initial key material for the peer.
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.
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.
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.
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_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.
#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...
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.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition disk.c:1258
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition disk.c:710
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test_read(const char *fil)
Check that fil corresponds to a filename and the file has read permissions.
Definition disk.c:540
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1332
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition disk.c:633
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition disk.c:673
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition disk.c:206
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk,...)
HKDF-Expand using SHA256.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_BlindablePrivateKey *sk, struct GNUNET_CRYPTO_HpkePrivateKey *sk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
#define GNUNET_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).
#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
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
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition network.c:392
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition network.c:1001
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition network.c:717
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition network.c:602
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition network.c:738
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition network.c:439
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition network.c:652
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_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.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition scheduler.c:1511
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition scheduler.c:1582
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1339
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1304
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1277
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:599
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition time.c:860
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:636
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:660
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define max(x, y)
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition scheduler.c:431
DLL to store the addresses we like to register at NAT service.
struct Addresses * next
Kept in a DLL.
struct Addresses * prev
Kept in a DLL.
struct sockaddr * addr
Address we like to register at NAT service.
socklen_t addr_len
Length of address we like to register at NAT service.
Internal representation of the hash map.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Type of a nonce used for challenges.
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
HPKE DHKEM encapsulation (X25519) See RFC 9180.
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 (!...
Handle used to access files (and pipes).
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 to a socket
Definition network.c:53
Handle to the PEERSTORE service.
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:136
Handle for the service.
A 256-bit hashcode.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Opaque handle to the transport service for communicators.
struct GNUNET_MQ_Handle * mq
Queue to talk to the transport service.
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.
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.
Handle for a queue.
struct GNUNET_MQ_Handle * mq
Message queue we are providing for the ch.
struct GNUNET_SCHEDULER_Task * write_task
ID of write task for this connection.
struct GNUNET_PeerIdentity target
To whom are we talking to.
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.
struct sockaddr * address
Address of the other peer.
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_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.
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...