aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-communicator-tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-communicator-tcp.c')
-rw-r--r--src/transport/gnunet-communicator-tcp.c4060
1 files changed, 0 insertions, 4060 deletions
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
deleted file mode 100644
index 7d4360bb0..000000000
--- a/src/transport/gnunet-communicator-tcp.c
+++ /dev/null
@@ -1,4060 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 2018, 2019 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file transport/gnunet-communicator-tcp.c
23 * @brief Transport plugin using TCP.
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - support NAT connection reversal method (#5529)
28 * - support other TCP-specific NAT traversal methods (#5531)
29 */
30#include "platform.h"
31#include "gnunet_util_lib.h"
32#include "gnunet_core_service.h"
33#include "gnunet_peerstore_service.h"
34#include "gnunet_protocols.h"
35#include "gnunet_signatures.h"
36#include "gnunet_constants.h"
37#include "gnunet_nt_lib.h"
38#include "gnunet_nat_service.h"
39#include "gnunet_statistics_service.h"
40#include "gnunet_transport_communication_service.h"
41#include "gnunet_resolver_service.h"
42
43
44/**
45 * How long until we give up on establishing an NAT connection?
46 * Must be > 4 RTT
47 */
48#define NAT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
49
50/**
51 * How long do we believe our addresses to remain up (before
52 * the other peer should revalidate).
53 */
54#define ADDRESS_VALIDITY_PERIOD \
55 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
56
57/**
58 * How many messages do we keep at most in the queue to the
59 * transport service before we start to drop (default,
60 * can be changed via the configuration file).
61 * Should be _below_ the level of the communicator API, as
62 * otherwise we may read messages just to have them dropped
63 * by the communicator API.
64 */
65#define DEFAULT_MAX_QUEUE_LENGTH 8
66
67/**
68 * Size of our IO buffers for ciphertext data. Must be at
69 * least UINT_MAX + sizeof (struct TCPBox).
70 */
71#define BUF_SIZE (2 * 64 * 1024 + sizeof(struct TCPBox))
72
73/**
74 * How often do we rekey based on time (at least)
75 */
76#define DEFAULT_REKEY_INTERVAL GNUNET_TIME_UNIT_DAYS
77
78/**
79 * How long do we wait until we must have received the initial KX?
80 */
81#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
82
83/**
84 * How often do we rekey based on number of bytes transmitted?
85 * (additionally randomized).
86 */
87#define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
88
89/**
90 * Size of the initial key exchange message sent first in both
91 * directions.
92 */
93#define INITIAL_KX_SIZE \
94 (sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) \
95 + sizeof(struct TCPConfirmation))
96
97/**
98 * Size of the initial core key exchange messages.
99 */
100#define INITIAL_CORE_KX_SIZE \
101 (sizeof(struct EphemeralKeyMessage) \
102 + sizeof(struct PingMessage) \
103 + sizeof(struct PongMessage))
104
105/**
106 * Address prefix used by the communicator.
107 */
108#define COMMUNICATOR_ADDRESS_PREFIX "tcp"
109
110/**
111 * Configuration section used by the communicator.
112 */
113#define COMMUNICATOR_CONFIG_SECTION "communicator-tcp"
114
115GNUNET_NETWORK_STRUCT_BEGIN
116
117
118/**
119 * Signature we use to verify that the ephemeral key was really chosen by
120 * the specified sender.
121 */
122struct TcpHandshakeSignature
123{
124 /**
125 * Purpose must be #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE
126 */
127 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
128
129 /**
130 * Identity of the inititor of the TCP connection (TCP client).
131 */
132 struct GNUNET_PeerIdentity sender;
133
134 /**
135 * Presumed identity of the target of the TCP connection (TCP server)
136 */
137 struct GNUNET_PeerIdentity receiver;
138
139 /**
140 * Ephemeral key used by the @e sender.
141 */
142 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
143
144 /**
145 * Monotonic time of @e sender, to possibly help detect replay attacks
146 * (if receiver persists times by sender).
147 */
148 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
149
150 /**
151 * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
152 */
153 struct GNUNET_CRYPTO_ChallengeNonceP challenge;
154};
155
156/**
157 * Signature we use to verify that the ack from the receiver of the ephemeral key was really send by
158 * the specified sender.
159 */
160struct TcpHandshakeAckSignature
161{
162 /**
163 * Purpose must be #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK
164 */
165 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
166
167 /**
168 * Identity of the inititor of the TCP connection (TCP client).
169 */
170 struct GNUNET_PeerIdentity sender;
171
172 /**
173 * Presumed identity of the target of the TCP connection (TCP server)
174 */
175 struct GNUNET_PeerIdentity receiver;
176
177 /**
178 * Monotonic time of @e sender, to possibly help detect replay attacks
179 * (if receiver persists times by sender).
180 */
181 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
182
183 /**
184 * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
185 */
186 struct GNUNET_CRYPTO_ChallengeNonceP challenge;
187};
188
189/**
190 * Encrypted continuation of TCP initial handshake.
191 */
192struct TCPConfirmation
193{
194 /**
195 * Sender's identity
196 */
197 struct GNUNET_PeerIdentity sender;
198
199 /**
200 * Sender's signature of type #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE
201 */
202 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
203
204 /**
205 * Monotonic time of @e sender, to possibly help detect replay attacks
206 * (if receiver persists times by sender).
207 */
208 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
209
210 /**
211 * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
212 */
213 struct GNUNET_CRYPTO_ChallengeNonceP challenge;
214
215};
216
217/**
218 * Ack for the encrypted continuation of TCP initial handshake.
219 */
220struct TCPConfirmationAck
221{
222
223
224 /**
225 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK.
226 */
227 struct GNUNET_MessageHeader header;
228
229 /**
230 * Sender's identity
231 */
232 struct GNUNET_PeerIdentity sender;
233
234 /**
235 * Sender's signature of type #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK
236 */
237 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
238
239 /**
240 * Monotonic time of @e sender, to possibly help detect replay attacks
241 * (if receiver persists times by sender).
242 */
243 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
244
245 /**
246 * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
247 */
248 struct GNUNET_CRYPTO_ChallengeNonceP challenge;
249
250};
251
252/**
253 * TCP message box. Always sent encrypted!
254 */
255struct TCPBox
256{
257 /**
258 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX. Warning: the
259 * header size EXCLUDES the size of the `struct TCPBox`. We usually
260 * never do this, but here the payload may truly be 64k *after* the
261 * TCPBox (as we have no MTU)!!
262 */
263 struct GNUNET_MessageHeader header;
264
265 /**
266 * HMAC for the following encrypted message. Yes, we MUST use
267 * mac-then-encrypt here, as we want to hide the message sizes on
268 * the wire (zero plaintext design!). Using CTR mode, padding oracle
269 * attacks do not apply. Besides, due to the use of ephemeral keys
270 * (hopefully with effective replay protection from monotonic time!)
271 * the attacker is limited in using the oracle.
272 */
273 struct GNUNET_ShortHashCode hmac;
274
275 /* followed by as may bytes of payload as indicated in @e header,
276 excluding the TCPBox itself! */
277};
278
279
280/**
281 * TCP rekey message box. Always sent encrypted! Data after
282 * this message will use the new key.
283 */
284struct TCPRekey
285{
286 /**
287 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY.
288 */
289 struct GNUNET_MessageHeader header;
290
291 /**
292 * HMAC for the following encrypted message. Yes, we MUST use
293 * mac-then-encrypt here, as we want to hide the message sizes on
294 * the wire (zero plaintext design!). Using CTR mode padding oracle
295 * attacks do not apply. Besides, due to the use of ephemeral keys
296 * (hopefully with effective replay protection from monotonic time!)
297 * the attacker is limited in using the oracle.
298 */
299 struct GNUNET_ShortHashCode hmac;
300
301 /**
302 * New ephemeral key.
303 */
304 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
305
306 /**
307 * Sender's signature of type #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY
308 */
309 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
310
311 /**
312 * Monotonic time of @e sender, to possibly help detect replay attacks
313 * (if receiver persists times by sender).
314 */
315 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
316};
317
318/**
319 * Signature we use to verify that the ephemeral key was really chosen by
320 * the specified sender.
321 */
322struct TcpRekeySignature
323{
324 /**
325 * Purpose must be #GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY
326 */
327 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
328
329 /**
330 * Identity of the inititor of the TCP connection (TCP client).
331 */
332 struct GNUNET_PeerIdentity sender;
333
334 /**
335 * Presumed identity of the target of the TCP connection (TCP server)
336 */
337 struct GNUNET_PeerIdentity receiver;
338
339 /**
340 * Ephemeral key used by the @e sender.
341 */
342 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
343
344 /**
345 * Monotonic time of @e sender, to possibly help detect replay attacks
346 * (if receiver persists times by sender).
347 */
348 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
349};
350
351/**
352 * TCP finish. Sender asks for the connection to be closed.
353 * Needed/useful in case we drop RST/FIN packets on the GNUnet
354 * port due to the possibility of malicious RST/FIN injection.
355 */
356struct TCPFinish
357{
358 /**
359 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH.
360 */
361 struct GNUNET_MessageHeader header;
362
363 /**
364 * HMAC for the following encrypted message. Yes, we MUST use
365 * mac-then-encrypt here, as we want to hide the message sizes on
366 * the wire (zero plaintext design!). Using CTR mode padding oracle
367 * attacks do not apply. Besides, due to the use of ephemeral keys
368 * (hopefully with effective replay protection from monotonic time!)
369 * the attacker is limited in using the oracle.
370 */
371 struct GNUNET_ShortHashCode hmac;
372};
373
374/**
375 * Basically a WELCOME message, but with the purpose
376 * of giving the waiting peer a client handle to use
377 */
378struct TCPNATProbeMessage
379{
380 /**
381 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE.
382 */
383 struct GNUNET_MessageHeader header;
384
385 /**
386 * Identity of the sender of the message.
387 */
388 struct GNUNET_PeerIdentity clientIdentity;
389};
390
391GNUNET_NETWORK_STRUCT_END
392
393/**
394 * Struct for pending nat reversals.
395 */
396struct PendingReversal
397{
398 /*
399 * Timeout task.
400 */
401 struct GNUNET_SCHEDULER_Task *timeout_task;
402
403 /**
404 * To whom are we like to talk to.
405 */
406 struct GNUNET_PeerIdentity target;
407
408 /**
409 * Address the reversal was send to.
410 */
411 struct sockaddr *in;
412};
413
414/**
415 * Struct to use as closure.
416 */
417struct ListenTask
418{
419 /**
420 * ID of listen task
421 */
422 struct GNUNET_SCHEDULER_Task *listen_task;
423
424 /**
425 * Listen socket.
426 */
427 struct GNUNET_NETWORK_Handle *listen_sock;
428};
429
430/**
431 * Handle for a queue.
432 */
433struct Queue
434{
435 /**
436 * To whom are we talking to.
437 */
438 struct GNUNET_PeerIdentity target;
439
440 /**
441 * Listen socket.
442 */
443 struct GNUNET_NETWORK_Handle *listen_sock;
444
445 /**
446 * socket that we transmit all data with on this queue
447 */
448 struct GNUNET_NETWORK_Handle *sock;
449
450 /**
451 * cipher for decryption of incoming data.
452 */
453 gcry_cipher_hd_t in_cipher;
454
455 /**
456 * cipher for encryption of outgoing data.
457 */
458 gcry_cipher_hd_t out_cipher;
459
460 /**
461 * Shared secret for HMAC verification on incoming data.
462 */
463 struct GNUNET_HashCode in_hmac;
464
465 /**
466 * Shared secret for HMAC generation on outgoing data, ratcheted after
467 * each operation.
468 */
469 struct GNUNET_HashCode out_hmac;
470
471 /**
472 * Our ephemeral key. Stored here temporarily during rekeying / key
473 * generation.
474 */
475 struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral;
476
477 /**
478 * ID of read task for this connection.
479 */
480 struct GNUNET_SCHEDULER_Task *read_task;
481
482 /**
483 * ID of write task for this connection.
484 */
485 struct GNUNET_SCHEDULER_Task *write_task;
486
487 /**
488 * Address of the other peer.
489 */
490 struct sockaddr *address;
491
492 /**
493 * How many more bytes may we sent with the current @e out_cipher
494 * before we should rekey?
495 */
496 uint64_t rekey_left_bytes;
497
498 /**
499 * Until what time may we sent with the current @e out_cipher
500 * before we should rekey?
501 */
502 struct GNUNET_TIME_Absolute rekey_time;
503
504 /**
505 * Length of the address.
506 */
507 socklen_t address_len;
508
509 /**
510 * Message queue we are providing for the #ch.
511 */
512 struct GNUNET_MQ_Handle *mq;
513
514 /**
515 * handle for this queue with the #ch.
516 */
517 struct GNUNET_TRANSPORT_QueueHandle *qh;
518
519 /**
520 * Number of bytes we currently have in our write queue.
521 */
522 unsigned long long bytes_in_queue;
523
524 /**
525 * Buffer for reading ciphertext from network into.
526 */
527 char cread_buf[BUF_SIZE];
528
529 /**
530 * buffer for writing ciphertext to network.
531 */
532 char cwrite_buf[BUF_SIZE];
533
534 /**
535 * Plaintext buffer for decrypted plaintext.
536 */
537 char pread_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
538
539 /**
540 * Plaintext buffer for messages to be encrypted.
541 */
542 char pwrite_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
543
544 /**
545 * At which offset in the ciphertext read buffer should we
546 * append more ciphertext for transmission next?
547 */
548 size_t cread_off;
549
550 /**
551 * At which offset in the ciphertext write buffer should we
552 * append more ciphertext from reading next?
553 */
554 size_t cwrite_off;
555
556 /**
557 * At which offset in the plaintext input buffer should we
558 * append more plaintext from decryption next?
559 */
560 size_t pread_off;
561
562 /**
563 * At which offset in the plaintext output buffer should we
564 * append more plaintext for encryption next?
565 */
566 size_t pwrite_off;
567
568 /**
569 * Timeout for this queue.
570 */
571 struct GNUNET_TIME_Absolute timeout;
572
573 /**
574 * How may messages did we pass from this queue to CORE for which we
575 * have yet to receive an acknoweldgement that CORE is done with
576 * them? If "large" (or even just non-zero), we should throttle
577 * reading to provide flow control. See also #DEFAULT_MAX_QUEUE_LENGTH
578 * and #max_queue_length.
579 */
580 unsigned int backpressure;
581
582 /**
583 * Which network type does this queue use?
584 */
585 enum GNUNET_NetworkType nt;
586
587 /**
588 * The connection status of this queue.
589 */
590 enum GNUNET_TRANSPORT_ConnectionStatus cs;
591
592 /**
593 * Is MQ awaiting a #GNUNET_MQ_impl_send_continue() call?
594 */
595 int mq_awaits_continue;
596
597 /**
598 * Did we enqueue a finish message and are closing down the queue?
599 */
600 int finishing;
601
602 /**
603 * Did we technically destroy this queue, but kept the allocation
604 * around because of @e backpressure not being zero yet? Used
605 * simply to delay the final #GNUNET_free() operation until
606 * #core_read_finished_cb() has been called.
607 */
608 int destroyed;
609
610 /**
611 * #GNUNET_YES if we just rekeyed and must thus possibly
612 * re-decrypt ciphertext.
613 */
614 int rekeyed;
615
616 /**
617 * Monotonic time value for rekey message.
618 */
619 struct GNUNET_TIME_AbsoluteNBO rekey_monotonic_time;
620
621 /**
622 * Monotonic time value for handshake message.
623 */
624 struct GNUNET_TIME_AbsoluteNBO handshake_monotonic_time;
625
626 /**
627 * Monotonic time value for handshake ack message.
628 */
629 struct GNUNET_TIME_AbsoluteNBO handshake_ack_monotonic_time;
630
631 /**
632 * Challenge value used to protect against replay attack, if there is no stored monotonic time value.
633 */
634 struct GNUNET_CRYPTO_ChallengeNonceP challenge;
635
636 /**
637 * Challenge value received. In case of inbound connection we have to remember the value, because we send the challenge back later after we received the GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK.
638 */
639 struct GNUNET_CRYPTO_ChallengeNonceP challenge_received;
640
641 /**
642 * Iteration Context for retrieving the monotonic time send with key for rekeying.
643 */
644 struct GNUNET_PEERSTORE_IterateContext *rekey_monotime_get;
645
646 /**
647 * Iteration Context for retrieving the monotonic time send with the handshake.
648 */
649 struct GNUNET_PEERSTORE_IterateContext *handshake_monotime_get;
650
651 /**
652 * Iteration Context for retrieving the monotonic time send with the handshake ack.
653 */
654 struct GNUNET_PEERSTORE_IterateContext *handshake_ack_monotime_get;
655
656 /**
657 * Store Context for retrieving the monotonic time send with key for rekeying.
658 */
659 struct GNUNET_PEERSTORE_StoreContext *rekey_monotime_sc;
660
661 /**
662 * Store Context for retrieving the monotonic time send with the handshake.
663 */
664 struct GNUNET_PEERSTORE_StoreContext *handshake_monotime_sc;
665
666 /**
667 * Store Context for retrieving the monotonic time send with the handshake ack.
668 */
669 struct GNUNET_PEERSTORE_StoreContext *handshake_ack_monotime_sc;
670};
671
672
673/**
674 * Handle for an incoming connection where we do not yet have enough
675 * information to setup a full queue.
676 */
677struct ProtoQueue
678{
679 /**
680 * Kept in a DLL.
681 */
682 struct ProtoQueue *next;
683
684 /**
685 * Kept in a DLL.
686 */
687 struct ProtoQueue *prev;
688
689 /**
690 * Listen socket.
691 */
692 struct GNUNET_NETWORK_Handle *listen_sock;
693
694 /**
695 * socket that we transmit all data with on this queue
696 */
697 struct GNUNET_NETWORK_Handle *sock;
698
699 /**
700 * ID of write task for this connection.
701 */
702 struct GNUNET_SCHEDULER_Task *write_task;
703
704 /**
705 * buffer for writing struct TCPNATProbeMessage to network.
706 */
707 char write_buf[sizeof (struct TCPNATProbeMessage)];
708
709 /**
710 * Offset of the buffer?
711 */
712 size_t write_off;
713
714 /**
715 * ID of read task for this connection.
716 */
717 struct GNUNET_SCHEDULER_Task *read_task;
718
719 /**
720 * Address of the other peer.
721 */
722 struct sockaddr *address;
723
724 /**
725 * Length of the address.
726 */
727 socklen_t address_len;
728
729 /**
730 * Timeout for this protoqueue.
731 */
732 struct GNUNET_TIME_Absolute timeout;
733
734 /**
735 * Buffer for reading all the information we need to upgrade from
736 * protoqueue to queue.
737 */
738 char ibuf[INITIAL_KX_SIZE];
739
740 /**
741 * Current offset for reading into @e ibuf.
742 */
743 size_t ibuf_off;
744};
745
746/**
747 * In case of port only configuration we like to bind to ipv4 and ipv6 addresses.
748 */
749struct PortOnlyIpv4Ipv6
750{
751 /**
752 * Ipv4 address we like to bind to.
753 */
754 struct sockaddr *addr_ipv4;
755
756 /**
757 * Length of ipv4 address.
758 */
759 socklen_t addr_len_ipv4;
760
761 /**
762 * Ipv6 address we like to bind to.
763 */
764 struct sockaddr *addr_ipv6;
765
766 /**
767 * Length of ipv6 address.
768 */
769 socklen_t addr_len_ipv6;
770
771};
772
773/**
774 * DLL to store the addresses we like to register at NAT service.
775 */
776struct Addresses
777{
778 /**
779 * Kept in a DLL.
780 */
781 struct Addresses *next;
782
783 /**
784 * Kept in a DLL.
785 */
786 struct Addresses *prev;
787
788 /**
789 * Address we like to register at NAT service.
790 */
791 struct sockaddr *addr;
792
793 /**
794 * Length of address we like to register at NAT service.
795 */
796 socklen_t addr_len;
797
798};
799
800
801/**
802 * Maximum queue length before we stop reading towards the transport service.
803 */
804static unsigned long long max_queue_length;
805
806/**
807 * For logging statistics.
808 */
809static struct GNUNET_STATISTICS_Handle *stats;
810
811/**
812 * Our environment.
813 */
814static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
815
816/**
817 * Queues (map from peer identity to `struct Queue`)
818 */
819static struct GNUNET_CONTAINER_MultiPeerMap *queue_map;
820
821/**
822 * ListenTasks (map from socket to `struct ListenTask`)
823 */
824static struct GNUNET_CONTAINER_MultiHashMap *lt_map;
825
826/**
827 * Our public key.
828 */
829static struct GNUNET_PeerIdentity my_identity;
830
831/**
832 * The rekey interval
833 */
834static struct GNUNET_TIME_Relative rekey_interval;
835
836/**
837 * Our private key.
838 */
839static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
840
841/**
842 * Our configuration.
843 */
844static const struct GNUNET_CONFIGURATION_Handle *cfg;
845
846/**
847 * Network scanner to determine network types.
848 */
849static struct GNUNET_NT_InterfaceScanner *is;
850
851/**
852 * Connection to NAT service.
853 */
854static struct GNUNET_NAT_Handle *nat;
855
856/**
857 * Protoqueues DLL head.
858 */
859static struct ProtoQueue *proto_head;
860
861/**
862 * Protoqueues DLL tail.
863 */
864static struct ProtoQueue *proto_tail;
865
866/**
867 * Handle for DNS lookup of bindto address
868 */
869struct GNUNET_RESOLVER_RequestHandle *resolve_request_handle;
870
871/**
872 * Head of DLL with addresses we like to register at NAT servcie.
873 */
874struct Addresses *addrs_head;
875
876/**
877 * Head of DLL with addresses we like to register at NAT servcie.
878 */
879struct Addresses *addrs_tail;
880
881/**
882 * Head of DLL with ListenTasks.
883 */
884struct ListenTask *lts_head;
885
886/**
887 * Head of DLL with ListenTask.
888 */
889struct ListenTask *lts_tail;
890
891/**
892 * Number of addresses in the DLL for register at NAT service.
893 */
894int addrs_lens;
895
896/**
897 * Size of data received without KX challenge played back.
898 */
899// TODO remove?
900size_t unverified_size;
901
902/**
903 * Database for peer's HELLOs.
904 */
905static struct GNUNET_PEERSTORE_Handle *peerstore;
906
907/**
908 * A flag indicating we are already doing a shutdown.
909 */
910int shutdown_running = GNUNET_NO;
911
912/**
913 * The port the communicator should be assigned to.
914 */
915unsigned int bind_port;
916
917/**
918 * Map of pending reversals.
919 */
920struct GNUNET_CONTAINER_MultiHashMap *pending_reversals;
921
922/**
923 * We have been notified that our listen socket has something to
924 * read. Do the read and reschedule this function to be called again
925 * once more is available.
926 *
927 * @param cls NULL
928 */
929static void
930listen_cb (void *cls);
931
932/**
933 * Functions with this signature are called whenever we need
934 * to close a queue due to a disconnect or failure to
935 * establish a connection.
936 *
937 * @param queue queue to close down
938 */
939static void
940queue_destroy (struct Queue *queue)
941{
942 struct ListenTask *lt = NULL;
943 struct GNUNET_HashCode h_sock;
944 int sockfd;
945
946 if (NULL != queue->listen_sock)
947 {
948 sockfd = GNUNET_NETWORK_get_fd (queue->listen_sock);
949 GNUNET_CRYPTO_hash (&sockfd,
950 sizeof(int),
951 &h_sock);
952
953 lt = GNUNET_CONTAINER_multihashmap_get (lt_map, &h_sock);
954 }
955
956 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
957 "Disconnecting queue for peer `%s'\n",
958 GNUNET_i2s (&queue->target));
959 if (NULL != queue->rekey_monotime_sc)
960 {
961 GNUNET_PEERSTORE_store_cancel (queue->rekey_monotime_sc);
962 queue->rekey_monotime_sc = NULL;
963 }
964 if (NULL != queue->handshake_monotime_sc)
965 {
966 GNUNET_PEERSTORE_store_cancel (queue->handshake_monotime_sc);
967 queue->handshake_monotime_sc = NULL;
968 }
969 if (NULL != queue->handshake_ack_monotime_sc)
970 {
971 GNUNET_PEERSTORE_store_cancel (queue->handshake_ack_monotime_sc);
972 queue->handshake_ack_monotime_sc = NULL;
973 }
974 if (NULL != queue->rekey_monotime_get)
975 {
976 GNUNET_PEERSTORE_iterate_cancel (queue->rekey_monotime_get);
977 queue->rekey_monotime_get = NULL;
978 }
979 if (NULL != queue->handshake_monotime_get)
980 {
981 GNUNET_PEERSTORE_iterate_cancel (queue->handshake_monotime_get);
982 queue->handshake_monotime_get = NULL;
983 }
984 if (NULL != queue->handshake_ack_monotime_get)
985 {
986 GNUNET_PEERSTORE_iterate_cancel (queue->handshake_ack_monotime_get);
987 queue->handshake_ack_monotime_get = NULL;
988 }
989 if (NULL != queue->qh)
990 {
991 GNUNET_TRANSPORT_communicator_mq_del (queue->qh);
992 queue->qh = NULL;
993 }
994 GNUNET_assert (
995 GNUNET_YES ==
996 GNUNET_CONTAINER_multipeermap_remove (queue_map, &queue->target, queue));
997 GNUNET_STATISTICS_set (stats,
998 "# queues active",
999 GNUNET_CONTAINER_multipeermap_size (queue_map),
1000 GNUNET_NO);
1001 if (NULL != queue->read_task)
1002 {
1003 GNUNET_SCHEDULER_cancel (queue->read_task);
1004 queue->read_task = NULL;
1005 }
1006 if (NULL != queue->write_task)
1007 {
1008 GNUNET_SCHEDULER_cancel (queue->write_task);
1009 queue->write_task = NULL;
1010 }
1011 if (GNUNET_SYSERR == GNUNET_NETWORK_socket_close (queue->sock))
1012 {
1013 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1014 "closing socket failed\n");
1015 }
1016 gcry_cipher_close (queue->in_cipher);
1017 gcry_cipher_close (queue->out_cipher);
1018 GNUNET_free (queue->address);
1019 if (0 != queue->backpressure)
1020 queue->destroyed = GNUNET_YES;
1021 else
1022 GNUNET_free (queue);
1023
1024 if (NULL == lt)
1025 return;
1026
1027 if ((! shutdown_running) && (NULL == lt->listen_task))
1028 {
1029 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1030 "add read net listen\n");
1031 lt->listen_task = GNUNET_SCHEDULER_add_read_net (
1032 GNUNET_TIME_UNIT_FOREVER_REL,
1033 lt->listen_sock,
1034 &listen_cb,
1035 lt);
1036 }
1037 else
1038 GNUNET_free (lt);
1039}
1040
1041
1042/**
1043 * Compute @a mac over @a buf, and ratched the @a hmac_secret.
1044 *
1045 * @param[in,out] hmac_secret secret for HMAC calculation
1046 * @param buf buffer to MAC
1047 * @param buf_size number of bytes in @a buf
1048 * @param[out] smac where to write the HMAC
1049 */
1050static void
1051calculate_hmac (struct GNUNET_HashCode *hmac_secret,
1052 const void *buf,
1053 size_t buf_size,
1054 struct GNUNET_ShortHashCode *smac)
1055{
1056 struct GNUNET_HashCode mac;
1057
1058 GNUNET_CRYPTO_hmac_raw (hmac_secret,
1059 sizeof(struct GNUNET_HashCode),
1060 buf,
1061 buf_size,
1062 &mac);
1063 /* truncate to `struct GNUNET_ShortHashCode` */
1064 memcpy (smac, &mac, sizeof(struct GNUNET_ShortHashCode));
1065 /* ratchet hmac key */
1066 GNUNET_CRYPTO_hash (hmac_secret,
1067 sizeof(struct GNUNET_HashCode),
1068 hmac_secret);
1069}
1070
1071
1072/**
1073 * Append a 'finish' message to the outgoing transmission. Once the
1074 * finish has been transmitted, destroy the queue.
1075 *
1076 * @param queue queue to shut down nicely
1077 */
1078static void
1079queue_finish (struct Queue *queue)
1080{
1081 struct TCPFinish fin;
1082
1083 memset (&fin, 0, sizeof(fin));
1084 fin.header.size = htons (sizeof(fin));
1085 fin.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH);
1086 calculate_hmac (&queue->out_hmac, &fin, sizeof(fin), &fin.hmac);
1087 /* if there is any message left in pwrite_buf, we
1088 overwrite it (possibly dropping the last message
1089 from CORE hard here) */
1090 memcpy (queue->pwrite_buf, &fin, sizeof(fin));
1091 queue->pwrite_off = sizeof(fin);
1092 /* This flag will ensure that #queue_write() no longer
1093 notifies CORE about the possibility of sending
1094 more data, and that #queue_write() will call
1095 #queue_destroy() once the @c fin was fully written. */
1096 queue->finishing = GNUNET_YES;
1097}
1098
1099
1100/**
1101 * Increment queue timeout due to activity. We do not immediately
1102 * notify the monitor here as that might generate excessive
1103 * signalling.
1104 *
1105 * @param queue queue for which the timeout should be rescheduled
1106 */
1107static void
1108reschedule_queue_timeout (struct Queue *queue)
1109{
1110 queue->timeout =
1111 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1112}
1113
1114
1115/**
1116 * Queue read task. If we hit the timeout, disconnect it
1117 *
1118 * @param cls the `struct Queue *` to disconnect
1119 */
1120static void
1121queue_read (void *cls);
1122
1123
1124/**
1125 * Core tells us it is done processing a message that transport
1126 * received on a queue with status @a success.
1127 *
1128 * @param cls a `struct Queue *` where the message originally came from
1129 * @param success #GNUNET_OK on success
1130 */
1131static void
1132core_read_finished_cb (void *cls, int success)
1133{
1134 struct Queue *queue = cls;
1135 if (GNUNET_OK != success)
1136 GNUNET_STATISTICS_update (stats,
1137 "# messages lost in communicator API towards CORE",
1138 1,
1139 GNUNET_NO);
1140 if (NULL == queue)
1141 return;
1142
1143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1144 "backpressure %u\n",
1145 queue->backpressure);
1146
1147 queue->backpressure--;
1148 /* handle deferred queue destruction */
1149 if ((queue->destroyed) && (0 == queue->backpressure))
1150 {
1151 GNUNET_free (queue);
1152 return;
1153 }
1154 else if (GNUNET_YES != queue->destroyed)
1155 {
1156 reschedule_queue_timeout (queue);
1157 /* possibly unchoke reading, now that CORE made progress */
1158 if (NULL == queue->read_task)
1159 queue->read_task =
1160 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (
1161 queue->timeout),
1162 queue->sock,
1163 &queue_read,
1164 queue);
1165 }
1166}
1167
1168
1169/**
1170 * We received @a plaintext_len bytes of @a plaintext on @a queue.
1171 * Pass it on to CORE. If transmission is actually happening,
1172 * increase backpressure counter.
1173 *
1174 * @param queue the queue that received the plaintext
1175 * @param plaintext the plaintext that was received
1176 * @param plaintext_len number of bytes of plaintext received
1177 */
1178static void
1179pass_plaintext_to_core (struct Queue *queue,
1180 const void *plaintext,
1181 size_t plaintext_len)
1182{
1183 const struct GNUNET_MessageHeader *hdr = plaintext;
1184 int ret;
1185
1186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1187 "pass message from %s to core\n",
1188 GNUNET_i2s (&queue->target));
1189
1190 if (ntohs (hdr->size) != plaintext_len)
1191 {
1192 /* NOTE: If we ever allow multiple CORE messages in one
1193 BOX, this will have to change! */
1194 GNUNET_break (0);
1195 return;
1196 }
1197 ret = GNUNET_TRANSPORT_communicator_receive (ch,
1198 &queue->target,
1199 hdr,
1200 ADDRESS_VALIDITY_PERIOD,
1201 &core_read_finished_cb,
1202 queue);
1203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1204 "passed to core\n");
1205 if (GNUNET_OK == ret)
1206 queue->backpressure++;
1207 GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
1208 if (GNUNET_SYSERR == ret)
1209 GNUNET_STATISTICS_update (stats,
1210 "# bytes lost due to CORE not running",
1211 plaintext_len,
1212 GNUNET_NO);
1213}
1214
1215
1216/**
1217 * Setup @a cipher based on shared secret @a dh and decrypting
1218 * peer @a pid.
1219 *
1220 * @param dh shared secret
1221 * @param pid decrypting peer's identity
1222 * @param[out] cipher cipher to initialize
1223 * @param[out] hmac_key HMAC key to initialize
1224 */
1225static void
1226setup_cipher (const struct GNUNET_HashCode *dh,
1227 const struct GNUNET_PeerIdentity *pid,
1228 gcry_cipher_hd_t *cipher,
1229 struct GNUNET_HashCode *hmac_key)
1230{
1231 char key[256 / 8];
1232 char ctr[128 / 8];
1233
1234 GNUNET_assert (0 == gcry_cipher_open (cipher,
1235 GCRY_CIPHER_AES256 /* low level: go for speed */,
1236 GCRY_CIPHER_MODE_CTR,
1237 0 /* flags */));
1238 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (key,
1239 sizeof(key),
1240 "TCP-key",
1241 strlen ("TCP-key"),
1242 dh,
1243 sizeof(*dh),
1244 pid,
1245 sizeof(*pid),
1246 NULL,
1247 0));
1248 GNUNET_assert (0 == gcry_cipher_setkey (*cipher, key, sizeof(key)));
1249 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (ctr,
1250 sizeof(ctr),
1251 "TCP-ctr",
1252 strlen ("TCP-ctr"),
1253 dh,
1254 sizeof(*dh),
1255 pid,
1256 sizeof(*pid),
1257 NULL,
1258 0));
1259 gcry_cipher_setctr (*cipher, ctr, sizeof(ctr));
1260 GNUNET_assert (GNUNET_YES ==
1261 GNUNET_CRYPTO_kdf (hmac_key,
1262 sizeof(struct GNUNET_HashCode),
1263 "TCP-hmac",
1264 strlen ("TCP-hmac"),
1265 dh,
1266 sizeof(*dh),
1267 pid,
1268 sizeof(*pid),
1269 NULL,
1270 0));
1271}
1272
1273
1274/**
1275 * Callback called when peerstore store operation for rekey monotime value is finished.
1276 * @param cls Queue context the store operation was executed.
1277 * @param success Store operation was successful (GNUNET_OK) or not.
1278 */
1279static void
1280rekey_monotime_store_cb (void *cls, int success)
1281{
1282 struct Queue *queue = cls;
1283 if (GNUNET_OK != success)
1284 {
1285 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1286 "Failed to store rekey monotonic time in PEERSTORE!\n");
1287 }
1288 queue->rekey_monotime_sc = NULL;
1289}
1290
1291
1292/**
1293 * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY
1294 * where found.
1295 * @param cls Queue context the store operation was executed.
1296 * @param record The record found or NULL if there is no record left.
1297 * @param emsg Message from peerstore.
1298 */
1299static void
1300rekey_monotime_cb (void *cls,
1301 const struct GNUNET_PEERSTORE_Record *record,
1302 const char *emsg)
1303{
1304 struct Queue *queue = cls;
1305 struct GNUNET_TIME_AbsoluteNBO *mtbe;
1306 struct GNUNET_TIME_Absolute mt;
1307 const struct GNUNET_PeerIdentity *pid;
1308 struct GNUNET_TIME_AbsoluteNBO *rekey_monotonic_time;
1309
1310 (void) emsg;
1311
1312 rekey_monotonic_time = &queue->rekey_monotonic_time;
1313 pid = &queue->target;
1314 if (NULL == record)
1315 {
1316 queue->rekey_monotime_get = NULL;
1317 return;
1318 }
1319 if (sizeof(*mtbe) != record->value_size)
1320 {
1321 GNUNET_break (0);
1322 return;
1323 }
1324 mtbe = record->value;
1325 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1326 if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
1327 queue->rekey_monotonic_time).abs_value_us)
1328 {
1329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1330 "Queue from %s dropped, rekey monotime in the past\n",
1331 GNUNET_i2s (&queue->target));
1332 GNUNET_break (0);
1333 queue_finish (queue);
1334 return;
1335 }
1336 queue->rekey_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
1337 "transport_tcp_communicator",
1338 pid,
1339 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY,
1340 rekey_monotonic_time,
1341 sizeof(*
1342 rekey_monotonic_time),
1343 GNUNET_TIME_UNIT_FOREVER_ABS,
1344 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
1345 &rekey_monotime_store_cb,
1346 queue);
1347}
1348
1349
1350/**
1351 * Setup cipher of @a queue for decryption.
1352 *
1353 * @param ephemeral ephemeral key we received from the other peer
1354 * @param[in,out] queue queue to initialize decryption cipher for
1355 */
1356static void
1357setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1358 struct Queue *queue)
1359{
1360 struct GNUNET_HashCode dh;
1361
1362 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &dh);
1363 setup_cipher (&dh, &my_identity, &queue->in_cipher, &queue->in_hmac);
1364}
1365
1366
1367/**
1368 * Handle @a rekey message on @a queue. The message was already
1369 * HMAC'ed, but we should additionally still check the signature.
1370 * Then we need to stop the old cipher and start afresh.
1371 *
1372 * @param queue the queue @a rekey was received on
1373 * @param rekey the rekey message
1374 */
1375static void
1376do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
1377{
1378 struct TcpRekeySignature thp;
1379
1380 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY);
1381 thp.purpose.size = htonl (sizeof(thp));
1382 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1383 "do_rekey size %u\n",
1384 thp.purpose.size);
1385 thp.sender = queue->target;
1386 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1387 "sender %s\n",
1388 GNUNET_p2s (&thp.sender.public_key));
1389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1390 "sender %s\n",
1391 GNUNET_p2s (&queue->target.public_key));
1392 thp.receiver = my_identity;
1393 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1394 "receiver %s\n",
1395 GNUNET_p2s (&thp.receiver.public_key));
1396 thp.ephemeral = rekey->ephemeral;
1397 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1398 "ephemeral %s\n",
1399 GNUNET_e2s (&thp.ephemeral));
1400 thp.monotonic_time = rekey->monotonic_time;
1401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1402 "time %s\n",
1403 GNUNET_STRINGS_absolute_time_to_string (
1404 GNUNET_TIME_absolute_ntoh (thp.monotonic_time)));
1405 GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp)));
1406 if (GNUNET_OK !=
1407 GNUNET_CRYPTO_eddsa_verify (
1408 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY,
1409 &thp,
1410 &rekey->sender_sig,
1411 &queue->target.public_key))
1412 {
1413 GNUNET_break (0);
1414 queue_finish (queue);
1415 return;
1416 }
1417 queue->rekey_monotonic_time = rekey->monotonic_time;
1418 queue->rekey_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1419 "transport_tcp_communicator",
1420 &queue->target,
1421 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY,
1422 &rekey_monotime_cb,
1423 queue);
1424 gcry_cipher_close (queue->in_cipher);
1425 queue->rekeyed = GNUNET_YES;
1426 setup_in_cipher (&rekey->ephemeral, queue);
1427}
1428
1429
1430/**
1431 * Callback called when peerstore store operation for handshake ack monotime value is finished.
1432 * @param cls Queue context the store operation was executed.
1433 * @param success Store operation was successful (GNUNET_OK) or not.
1434 */
1435static void
1436handshake_ack_monotime_store_cb (void *cls, int success)
1437{
1438 struct Queue *queue = cls;
1439
1440 if (GNUNET_OK != success)
1441 {
1442 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1443 "Failed to store handshake ack monotonic time in PEERSTORE!\n");
1444 }
1445 queue->handshake_ack_monotime_sc = NULL;
1446}
1447
1448
1449/**
1450 * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK
1451 * where found.
1452 * @param cls Queue context the store operation was executed.
1453 * @param record The record found or NULL if there is no record left.
1454 * @param emsg Message from peerstore.
1455 */
1456static void
1457handshake_ack_monotime_cb (void *cls,
1458 const struct GNUNET_PEERSTORE_Record *record,
1459 const char *emsg)
1460{
1461 struct Queue *queue = cls;
1462 struct GNUNET_TIME_AbsoluteNBO *mtbe;
1463 struct GNUNET_TIME_Absolute mt;
1464 const struct GNUNET_PeerIdentity *pid;
1465 struct GNUNET_TIME_AbsoluteNBO *handshake_ack_monotonic_time;
1466
1467 (void) emsg;
1468
1469 handshake_ack_monotonic_time = &queue->handshake_ack_monotonic_time;
1470 pid = &queue->target;
1471 if (NULL == record)
1472 {
1473 queue->handshake_ack_monotime_get = NULL;
1474 return;
1475 }
1476 if (sizeof(*mtbe) != record->value_size)
1477 {
1478 GNUNET_break (0);
1479 return;
1480 }
1481 mtbe = record->value;
1482 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1483 if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
1484 queue->handshake_ack_monotonic_time).abs_value_us)
1485 {
1486 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1487 "Queue from %s dropped, handshake ack monotime in the past\n",
1488 GNUNET_i2s (&queue->target));
1489 GNUNET_break (0);
1490 queue_finish (queue);
1491 return;
1492 }
1493 queue->handshake_ack_monotime_sc =
1494 GNUNET_PEERSTORE_store (peerstore,
1495 "transport_tcp_communicator",
1496 pid,
1497 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK,
1498 handshake_ack_monotonic_time,
1499 sizeof(*handshake_ack_monotonic_time),
1500 GNUNET_TIME_UNIT_FOREVER_ABS,
1501 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
1502 &
1503 handshake_ack_monotime_store_cb,
1504 queue);
1505}
1506
1507
1508/**
1509 * Sending challenge with TcpConfirmationAck back to sender of ephemeral key.
1510 *
1511 * @param tc The TCPConfirmation originally send.
1512 * @param queue The queue context.
1513 */
1514static void
1515send_challenge (struct GNUNET_CRYPTO_ChallengeNonceP challenge,
1516 struct Queue *queue)
1517{
1518 struct TCPConfirmationAck tca;
1519 struct TcpHandshakeAckSignature thas;
1520
1521 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1522 "sending challenge\n");
1523
1524 tca.header.type = ntohs (
1525 GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK);
1526 tca.header.size = ntohs (sizeof(tca));
1527 tca.challenge = challenge;
1528 tca.sender = my_identity;
1529 tca.monotonic_time =
1530 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1531 thas.purpose.purpose = htonl (
1532 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK);
1533 thas.purpose.size = htonl (sizeof(thas));
1534 thas.sender = my_identity;
1535 thas.receiver = queue->target;
1536 thas.monotonic_time = tca.monotonic_time;
1537 thas.challenge = tca.challenge;
1538 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1539 &thas,
1540 &tca.sender_sig);
1541 GNUNET_assert (0 ==
1542 gcry_cipher_encrypt (queue->out_cipher,
1543 &queue->cwrite_buf[queue->cwrite_off],
1544 sizeof(tca),
1545 &tca,
1546 sizeof(tca)));
1547 queue->cwrite_off += sizeof(tca);
1548 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1549 "sending challenge done\n");
1550}
1551
1552
1553/**
1554 * Setup cipher for outgoing data stream based on target and
1555 * our ephemeral private key.
1556 *
1557 * @param queue queue to setup outgoing (encryption) cipher for
1558 */
1559static void
1560setup_out_cipher (struct Queue *queue)
1561{
1562 struct GNUNET_HashCode dh;
1563
1564 GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral, &queue->target.public_key, &dh);
1565 /* we don't need the private key anymore, drop it! */
1566 memset (&queue->ephemeral, 0, sizeof(queue->ephemeral));
1567 setup_cipher (&dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1568 queue->rekey_time = GNUNET_TIME_relative_to_absolute (rekey_interval);
1569 queue->rekey_left_bytes =
1570 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, REKEY_MAX_BYTES);
1571}
1572
1573
1574/**
1575 * Inject a `struct TCPRekey` message into the queue's plaintext
1576 * buffer.
1577 *
1578 * @param queue queue to perform rekeying on
1579 */
1580static void
1581inject_rekey (struct Queue *queue)
1582{
1583 struct TCPRekey rekey;
1584 struct TcpRekeySignature thp;
1585
1586 GNUNET_assert (0 == queue->pwrite_off);
1587 memset (&rekey, 0, sizeof(rekey));
1588 GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral);
1589 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1590 rekey.header.size = ntohs (sizeof(rekey));
1591 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &rekey.ephemeral);
1592 rekey.monotonic_time =
1593 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1594 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY);
1595 thp.purpose.size = htonl (sizeof(thp));
1596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1597 "inject_rekey size %u\n",
1598 thp.purpose.size);
1599 thp.sender = my_identity;
1600 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1601 "sender %s\n",
1602 GNUNET_p2s (&thp.sender.public_key));
1603 thp.receiver = queue->target;
1604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1605 "receiver %s\n",
1606 GNUNET_p2s (&thp.receiver.public_key));
1607 thp.ephemeral = rekey.ephemeral;
1608 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1609 "ephemeral %s\n",
1610 GNUNET_e2s (&thp.ephemeral));
1611 thp.monotonic_time = rekey.monotonic_time;
1612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1613 "time %s\n",
1614 GNUNET_STRINGS_absolute_time_to_string (
1615 GNUNET_TIME_absolute_ntoh (thp.monotonic_time)));
1616 GNUNET_CRYPTO_eddsa_sign (my_private_key,
1617 &thp,
1618 &rekey.sender_sig);
1619 calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1620 /* Encrypt rekey message with 'old' cipher */
1621 GNUNET_assert (0 ==
1622 gcry_cipher_encrypt (queue->out_cipher,
1623 &queue->cwrite_buf[queue->cwrite_off],
1624 sizeof(rekey),
1625 &rekey,
1626 sizeof(rekey)));
1627 queue->cwrite_off += sizeof(rekey);
1628 /* Setup new cipher for successive messages */
1629 gcry_cipher_close (queue->out_cipher);
1630 setup_out_cipher (queue);
1631}
1632
1633static int
1634pending_reversals_delete_it (void *cls,
1635 const struct GNUNET_HashCode *key,
1636 void *value)
1637{
1638 (void) cls;
1639 struct PendingReversal *pending_reversal = value;
1640
1641 if (NULL != pending_reversal->timeout_task)
1642 {
1643 GNUNET_SCHEDULER_cancel (pending_reversal->timeout_task);
1644 pending_reversal->timeout_task = NULL;
1645 }
1646 GNUNET_CONTAINER_multihashmap_remove (pending_reversals,
1647 key,
1648 pending_reversal);
1649 GNUNET_free (pending_reversal->in);
1650 GNUNET_free (pending_reversal);
1651 return GNUNET_OK;
1652}
1653
1654
1655static void
1656check_and_remove_pending_reversal (struct sockaddr *in, sa_family_t sa_family, struct GNUNET_PeerIdentity *sender)
1657{
1658 if (AF_INET == sa_family)
1659 {
1660 struct PendingReversal *pending_reversal;
1661 struct GNUNET_HashCode key;
1662 struct sockaddr_in *natted_address;
1663
1664 natted_address = GNUNET_memdup (in, sizeof (struct sockaddr));
1665 natted_address->sin_port = 0;
1666 GNUNET_CRYPTO_hash (natted_address,
1667 sizeof(struct sockaddr),
1668 &key);
1669
1670 pending_reversal = GNUNET_CONTAINER_multihashmap_get (pending_reversals,
1671 &key);
1672 if (NULL != pending_reversal && (NULL == sender ||
1673 0 != memcmp (sender, &pending_reversal->target, sizeof(struct GNUNET_PeerIdentity))))
1674 {
1675 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1676 "Removing invalid pending reversal for `%s'at `%s'\n",
1677 GNUNET_i2s (&pending_reversal->target),
1678 GNUNET_a2s (in, sizeof (in)));
1679 pending_reversals_delete_it (NULL, &key, pending_reversal);
1680 }
1681 GNUNET_free (natted_address);
1682 }
1683}
1684
1685
1686/**
1687 * Closes socket and frees memory associated with @a pq.
1688 *
1689 * @param pq proto queue to free
1690 */
1691static void
1692free_proto_queue (struct ProtoQueue *pq)
1693{
1694 if (NULL != pq->listen_sock)
1695 {
1696 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pq->listen_sock));
1697 pq->listen_sock = NULL;
1698 }
1699 if (NULL != pq->read_task)
1700 {
1701 GNUNET_SCHEDULER_cancel (pq->read_task);
1702 pq->read_task = NULL;
1703 }
1704 if (NULL != pq->write_task)
1705 {
1706 GNUNET_SCHEDULER_cancel (pq->write_task);
1707 pq->write_task = NULL;
1708 }
1709 check_and_remove_pending_reversal (pq->address, pq->address->sa_family, NULL);
1710 GNUNET_NETWORK_socket_close (pq->sock);
1711 GNUNET_free (pq->address);
1712 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
1713 GNUNET_free (pq);
1714}
1715
1716
1717/**
1718 * We have been notified that our socket is ready to write.
1719 * Then reschedule this function to be called again once more is available.
1720 *
1721 * @param cls a `struct ProtoQueue`
1722 */
1723static void
1724proto_queue_write (void *cls)
1725{
1726 struct ProtoQueue *pq = cls;
1727 ssize_t sent;
1728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In proto queue write\n");
1729 pq->write_task = NULL;
1730 if (0 != pq->write_off)
1731 {
1732 sent = GNUNET_NETWORK_socket_send (pq->sock,
1733 pq->write_buf,
1734 pq->write_off);
1735 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1736 "Sent %lu bytes to TCP queue\n", sent);
1737 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1738 {
1739 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
1740 free_proto_queue (pq);
1741 return;
1742 }
1743 if (sent > 0)
1744 {
1745 size_t usent = (size_t) sent;
1746 pq->write_off -= usent;
1747 memmove (pq->write_buf,
1748 &pq->write_buf[usent],
1749 pq->write_off);
1750 }
1751 }
1752 /* do we care to write more? */
1753 if ((0 < pq->write_off))
1754 pq->write_task =
1755 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1756 pq->sock,
1757 &proto_queue_write,
1758 pq);
1759}
1760
1761
1762/**
1763 * We have been notified that our socket is ready to write.
1764 * Then reschedule this function to be called again once more is available.
1765 *
1766 * @param cls a `struct Queue`
1767 */
1768static void
1769queue_write (void *cls)
1770{
1771 struct Queue *queue = cls;
1772 ssize_t sent;
1773 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In queue write\n");
1774 queue->write_task = NULL;
1775 if (0 != queue->cwrite_off)
1776 {
1777 sent = GNUNET_NETWORK_socket_send (queue->sock,
1778 queue->cwrite_buf,
1779 queue->cwrite_off);
1780 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1781 "Sent %lu bytes to TCP queue\n", sent);
1782 if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1783 {
1784 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
1785 queue_destroy (queue);
1786 return;
1787 }
1788 if (sent > 0)
1789 {
1790 size_t usent = (size_t) sent;
1791 queue->cwrite_off -= usent;
1792 memmove (queue->cwrite_buf,
1793 &queue->cwrite_buf[usent],
1794 queue->cwrite_off);
1795 reschedule_queue_timeout (queue);
1796 }
1797 }
1798 /* can we encrypt more? (always encrypt full messages, needed
1799 such that #mq_cancel() can work!) */
1800 unsigned int we_do_not_need_to_rekey = (0 < queue->rekey_left_bytes
1801 - (queue->cwrite_off
1802 + queue->pwrite_off
1803 + sizeof (struct TCPRekey)));
1804 if (we_do_not_need_to_rekey &&
1805 (queue->pwrite_off > 0) &&
1806 (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1807 {
1808 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1809 "Encrypting %lu bytes\n", queue->pwrite_off);
1810 GNUNET_assert (0 ==
1811 gcry_cipher_encrypt (queue->out_cipher,
1812 &queue->cwrite_buf[queue->cwrite_off],
1813 queue->pwrite_off,
1814 queue->pwrite_buf,
1815 queue->pwrite_off));
1816 if (queue->rekey_left_bytes > queue->pwrite_off)
1817 queue->rekey_left_bytes -= queue->pwrite_off;
1818 else
1819 queue->rekey_left_bytes = 0;
1820 queue->cwrite_off += queue->pwrite_off;
1821 queue->pwrite_off = 0;
1822 }
1823 // if ((-1 != unverified_size)&& ((0 == queue->pwrite_off) &&
1824 if (((0 == queue->rekey_left_bytes) ||
1825 (0 == GNUNET_TIME_absolute_get_remaining (
1826 queue->rekey_time).rel_value_us)) &&
1827 (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey)&&
1828 (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE)))
1829 {
1830 inject_rekey (queue);
1831 }
1832 if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1833 (GNUNET_YES == queue->mq_awaits_continue))
1834 {
1835 queue->mq_awaits_continue = GNUNET_NO;
1836 GNUNET_MQ_impl_send_continue (queue->mq);
1837 }
1838 /* did we just finish writing 'finish'? */
1839 if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1840 {
1841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1842 "Finishing queue\n");
1843 queue_destroy (queue);
1844 return;
1845 }
1846 /* do we care to write more? */
1847 if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1848 queue->write_task =
1849 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1850 queue->sock,
1851 &queue_write,
1852 queue);
1853}
1854
1855
1856/**
1857 * Test if we have received a full message in plaintext.
1858 * If so, handle it.
1859 *
1860 * @param queue queue to process inbound plaintext for
1861 * @return number of bytes of plaintext handled, 0 for none
1862 */
1863static size_t
1864try_handle_plaintext (struct Queue *queue)
1865{
1866 const struct GNUNET_MessageHeader *hdr =
1867 (const struct GNUNET_MessageHeader *) queue->pread_buf;
1868 const struct TCPConfirmationAck *tca = (const struct
1869 TCPConfirmationAck *) queue->pread_buf;
1870 const struct TCPBox *box = (const struct TCPBox *) queue->pread_buf;
1871 const struct TCPRekey *rekey = (const struct TCPRekey *) queue->pread_buf;
1872 const struct TCPFinish *fin = (const struct TCPFinish *) queue->pread_buf;
1873 struct TCPRekey rekeyz;
1874 struct TCPFinish finz;
1875 struct GNUNET_ShortHashCode tmac;
1876 uint16_t type;
1877 size_t size = 0; /* make compiler happy */
1878 struct TcpHandshakeAckSignature thas;
1879 const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1880
1881 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1882 "try handle plaintext!\n");
1883
1884 if ((sizeof(*hdr) > queue->pread_off))
1885 {
1886 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1887 "Handling plaintext, not even a header!\n");
1888 return 0; /* not even a header */
1889 }
1890
1891 if ((-1 != unverified_size) && (unverified_size > INITIAL_CORE_KX_SIZE))
1892 {
1893 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1894 "Already received data of size %lu bigger than KX size %lu!\n",
1895 unverified_size,
1896 INITIAL_CORE_KX_SIZE);
1897 GNUNET_break_op (0);
1898 queue_finish (queue);
1899 return 0;
1900 }
1901
1902 type = ntohs (hdr->type);
1903 switch (type)
1904 {
1905 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK:
1906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1907 "start processing ack\n");
1908 if (sizeof(*tca) > queue->pread_off)
1909 {
1910 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1911 "Handling plaintext size of tca greater than pread offset.\n");
1912 return 0;
1913 }
1914 if (ntohs (hdr->size) != sizeof(*tca))
1915 {
1916 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1917 "Handling plaintext size does not match message type.\n");
1918 GNUNET_break_op (0);
1919 queue_finish (queue);
1920 return 0;
1921 }
1922
1923 thas.purpose.purpose = htonl (
1924 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK);
1925 thas.purpose.size = htonl (sizeof(thas));
1926 thas.sender = tca->sender;
1927 thas.receiver = my_identity;
1928 thas.monotonic_time = tca->monotonic_time;
1929 thas.challenge = tca->challenge;
1930
1931 if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_verify (
1932 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK,
1933 &thas,
1934 &tca->sender_sig,
1935 &tca->sender.public_key))
1936 {
1937 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1938 "Verification of signature failed!\n");
1939 GNUNET_break (0);
1940 queue_finish (queue);
1941 return 0;
1942 }
1943 if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
1944 {
1945 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1946 "Challenge in TCPConfirmationAck not correct!\n");
1947 GNUNET_break (0);
1948 queue_finish (queue);
1949 return 0;
1950 }
1951
1952 queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1953 "transport_tcp_communicator",
1954 &queue->target,
1955 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK,
1956 &
1957 handshake_ack_monotime_cb,
1958 queue);
1959
1960 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1961 "Handling plaintext, ack processed!\n");
1962
1963 if (GNUNET_TRANSPORT_CS_INBOUND == queue->cs)
1964 {
1965 send_challenge (queue->challenge_received, queue);
1966 queue->write_task =
1967 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
1968 queue->sock,
1969 &queue_write,
1970 queue);
1971 }
1972 else if (GNUNET_TRANSPORT_CS_OUTBOUND == queue->cs)
1973 {
1974 check_and_remove_pending_reversal (queue->address, queue->address->sa_family, NULL);
1975 }
1976
1977 unverified_size = -1;
1978
1979 char *foreign_addr;
1980
1981 switch (queue->address->sa_family)
1982 {
1983 case AF_INET:
1984 GNUNET_asprintf (&foreign_addr,
1985 "%s-%s",
1986 COMMUNICATOR_ADDRESS_PREFIX,
1987 GNUNET_a2s (queue->address, queue->address_len));
1988 break;
1989
1990 case AF_INET6:
1991 GNUNET_asprintf (&foreign_addr,
1992 "%s-%s",
1993 COMMUNICATOR_ADDRESS_PREFIX,
1994 GNUNET_a2s (queue->address, queue->address_len));
1995 break;
1996
1997 default:
1998 GNUNET_assert (0);
1999 }
2000
2001 queue->qh = GNUNET_TRANSPORT_communicator_mq_add (ch,
2002 &queue->target,
2003 foreign_addr,
2004 UINT16_MAX, /* no MTU */
2005 GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED,
2006 0, /* Priority */
2007 queue->nt,
2008 queue->cs,
2009 queue->mq);
2010
2011 GNUNET_free (foreign_addr);
2012
2013 size = ntohs (hdr->size);
2014 break;
2015 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
2016 /* Special case: header size excludes box itself! */
2017 if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
2018 return 0;
2019 calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
2020 if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
2021 {
2022 GNUNET_break_op (0);
2023 queue_finish (queue);
2024 return 0;
2025 }
2026 pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
2027 size = ntohs (hdr->size) + sizeof(*box);
2028 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2029 "Handling plaintext, box processed!\n");
2030 break;
2031
2032 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
2033 if (sizeof(*rekey) > queue->pread_off)
2034 return 0;
2035 if (ntohs (hdr->size) != sizeof(*rekey))
2036 {
2037 GNUNET_break_op (0);
2038 queue_finish (queue);
2039 return 0;
2040 }
2041 rekeyz = *rekey;
2042 memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
2043 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
2044 if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac)))
2045 {
2046 GNUNET_break_op (0);
2047 queue_finish (queue);
2048 return 0;
2049 }
2050 do_rekey (queue, rekey);
2051 size = ntohs (hdr->size);
2052 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2053 "Handling plaintext, rekey processed!\n");
2054 break;
2055
2056 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
2057 if (sizeof(*fin) > queue->pread_off)
2058 return 0;
2059 if (ntohs (hdr->size) != sizeof(*fin))
2060 {
2061 GNUNET_break_op (0);
2062 queue_finish (queue);
2063 return 0;
2064 }
2065 finz = *fin;
2066 memset (&finz.hmac, 0, sizeof(finz.hmac));
2067 calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
2068 if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
2069 {
2070 GNUNET_break_op (0);
2071 queue_finish (queue);
2072 return 0;
2073 }
2074 /* handle FINISH by destroying queue */
2075 queue_destroy (queue);
2076 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2077 "Handling plaintext, finish processed!\n");
2078 break;
2079
2080 default:
2081 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2082 "Handling plaintext, nothing processed!\n");
2083 GNUNET_break_op (0);
2084 queue_finish (queue);
2085 return 0;
2086 }
2087 GNUNET_assert (0 != size);
2088 if (-1 != unverified_size)
2089 unverified_size += size;
2090 return size;
2091}
2092
2093
2094/**
2095 * Queue read task. If we hit the timeout, disconnect it
2096 *
2097 * @param cls the `struct Queue *` to disconnect
2098 */
2099static void
2100queue_read (void *cls)
2101{
2102 struct Queue *queue = cls;
2103 struct GNUNET_TIME_Relative left;
2104 ssize_t rcvd;
2105
2106 queue->read_task = NULL;
2107 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2108 &queue->cread_buf[queue->cread_off],
2109 BUF_SIZE - queue->cread_off);
2110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2111 "Received %zd bytes from TCP queue\n", rcvd);
2112 if (-1 == rcvd)
2113 {
2114 if ((EAGAIN != errno) && (EINTR != errno))
2115 {
2116 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2117 queue_finish (queue);
2118 return;
2119 }
2120 /* try again */
2121 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2122 queue->read_task =
2123 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read, queue);
2124 return;
2125 }
2126 if (0 != rcvd)
2127 reschedule_queue_timeout (queue);
2128 queue->cread_off += rcvd;
2129 while ((queue->pread_off < sizeof(queue->pread_buf)) &&
2130 (queue->cread_off > 0))
2131 {
2132 size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
2133 queue->cread_off);
2134 size_t done;
2135 size_t total;
2136 size_t old_pread_off = queue->pread_off;
2137
2138 GNUNET_assert (0 ==
2139 gcry_cipher_decrypt (queue->in_cipher,
2140 &queue->pread_buf[queue->pread_off],
2141 max,
2142 queue->cread_buf,
2143 max));
2144 queue->pread_off += max;
2145 total = 0;
2146 while (0 != (done = try_handle_plaintext (queue)))
2147 {
2148 /* 'done' bytes of plaintext were used, shift buffer */
2149 GNUNET_assert (done <= queue->pread_off);
2150 /* NOTE: this memmove() could possibly sometimes be
2151 avoided if we pass 'total' into try_handle_plaintext()
2152 and use it at an offset into the buffer there! */
2153 memmove (queue->pread_buf,
2154 &queue->pread_buf[done],
2155 queue->pread_off - done);
2156 queue->pread_off -= done;
2157 total += done;
2158 /* The last plaintext was a rekey, abort for now */
2159 if (GNUNET_YES == queue->rekeyed)
2160 break;
2161 }
2162 /* when we encounter a rekey message, the decryption above uses the
2163 wrong key for everything after the rekey; in that case, we have
2164 to re-do the decryption at 'total' instead of at 'max'.
2165 However, we have to take into account that the plaintext buffer may have
2166 already contained data and not jumped too far ahead in the ciphertext.
2167 If there is no rekey and the last message is incomplete (max > total),
2168 it is safe to keep the decryption so we shift by 'max' */
2169 if (GNUNET_YES == queue->rekeyed)
2170 {
2171 max = total - old_pread_off;
2172 queue->rekeyed = GNUNET_NO;
2173 queue->pread_off = 0;
2174 }
2175 memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
2176 queue->cread_off -= max;
2177 }
2178 if (BUF_SIZE == queue->cread_off)
2179 return; /* buffer full, suspend reading */
2180 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2181 if (0 != left.rel_value_us)
2182 {
2183 if (max_queue_length > queue->backpressure)
2184 {
2185 /* continue reading */
2186 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2187 queue->read_task =
2188 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read, queue);
2189 }
2190 return;
2191 }
2192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2193 "Queue %p was idle for %s, disconnecting\n",
2194 queue,
2195 GNUNET_STRINGS_relative_time_to_string (
2196 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2197 GNUNET_YES));
2198 queue_finish (queue);
2199}
2200
2201
2202/**
2203 * Convert a `struct sockaddr_in6 to a `struct sockaddr *`
2204 *
2205 * @param[out] sock_len set to the length of the address.
2206 * @param v6 The sockaddr_in6 to be converted.
2207 * @return The struct sockaddr *.
2208 */
2209static struct sockaddr *
2210tcp_address_to_sockaddr_numeric_v6 (socklen_t *sock_len,
2211 struct sockaddr_in6 v6,
2212 unsigned int port)
2213{
2214 struct sockaddr *in;
2215
2216 v6.sin6_family = AF_INET6;
2217 v6.sin6_port = htons ((uint16_t) port);
2218#if HAVE_SOCKADDR_IN_SIN_LEN
2219 v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
2220#endif
2221 v6.sin6_flowinfo = 0;
2222 v6.sin6_scope_id = 0;
2223 in = GNUNET_memdup (&v6, sizeof(v6));
2224 *sock_len = sizeof(struct sockaddr_in6);
2225
2226 return in;
2227}
2228
2229
2230/**
2231 * Convert a `struct sockaddr_in4 to a `struct sockaddr *`
2232 *
2233 * @param[out] sock_len set to the length of the address.
2234 * @param v4 The sockaddr_in4 to be converted.
2235 * @return The struct sockaddr *.
2236 */
2237static struct sockaddr *
2238tcp_address_to_sockaddr_numeric_v4 (socklen_t *sock_len,
2239 struct sockaddr_in v4,
2240 unsigned int port)
2241{
2242 struct sockaddr *in;
2243
2244 v4.sin_family = AF_INET;
2245 v4.sin_port = htons ((uint16_t) port);
2246#if HAVE_SOCKADDR_IN_SIN_LEN
2247 v4.sin_len = sizeof(struct sockaddr_in);
2248#endif
2249 in = GNUNET_memdup (&v4, sizeof(v4));
2250 *sock_len = sizeof(struct sockaddr_in);
2251 return in;
2252}
2253
2254
2255/**
2256 * Convert TCP bind specification to a `struct PortOnlyIpv4Ipv6 *`
2257 *
2258 * @param bindto bind specification to convert.
2259 * @return The converted bindto specification.
2260 */
2261static struct PortOnlyIpv4Ipv6 *
2262tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
2263{
2264 struct PortOnlyIpv4Ipv6 *po;
2265 struct sockaddr_in *i4;
2266 struct sockaddr_in6 *i6;
2267 socklen_t sock_len_ipv4;
2268 socklen_t sock_len_ipv6;
2269
2270 /* interpreting value as just a PORT number */
2271 if (*port > UINT16_MAX)
2272 {
2273 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2274 "BINDTO specification `%s' invalid: value too large for port\n",
2275 bindto);
2276 return NULL;
2277 }
2278
2279 po = GNUNET_new (struct PortOnlyIpv4Ipv6);
2280
2281 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
2282 (GNUNET_YES ==
2283 GNUNET_CONFIGURATION_get_value_yesno (cfg,
2284 COMMUNICATOR_CONFIG_SECTION,
2285 "DISABLE_V6")))
2286 {
2287 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2288 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2289 *port);
2290 po->addr_len_ipv4 = sock_len_ipv4;
2291 }
2292 else
2293 {
2294
2295 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2296 po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2297 *port);
2298 po->addr_len_ipv4 = sock_len_ipv4;
2299
2300 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2301 po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
2302 *port);
2303
2304 po->addr_len_ipv6 = sock_len_ipv6;
2305
2306 GNUNET_free (i6);
2307 }
2308
2309 GNUNET_free (i4);
2310
2311 return po;
2312}
2313
2314
2315/**
2316 * This Method extracts the address part of the BINDTO string.
2317 *
2318 * @param bindto String we extract the address part from.
2319 * @return The extracted address string.
2320 */
2321static char *
2322extract_address (const char *bindto)
2323{
2324 char *addr;
2325 char *start;
2326 char *token;
2327 char *cp;
2328 char *rest = NULL;
2329 char *res;
2330
2331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2332 "extract address with bindto %s\n",
2333 bindto);
2334
2335 if (NULL == bindto)
2336 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2337 "bindto is NULL\n");
2338
2339 cp = GNUNET_strdup (bindto);
2340
2341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2342 "extract address 2\n");
2343
2344 start = cp;
2345 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2346 {
2347 start++; /* skip over '['*/
2348 cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
2349 addr = GNUNET_strdup (start);
2350 }
2351 else
2352 {
2353 token = strtok_r (cp, "]", &rest);
2354 if (strlen (bindto) == strlen (token))
2355 {
2356 token = strtok_r (cp, ":", &rest);
2357 addr = GNUNET_strdup (token);
2358 }
2359 else
2360 {
2361 token++;
2362 res = GNUNET_strdup (token);
2363 addr = GNUNET_strdup (res);
2364 }
2365 }
2366
2367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2368 "tcp address: %s\n",
2369 addr);
2370 GNUNET_free (cp);
2371 return addr;
2372}
2373
2374
2375/**
2376 * This Method extracts the port part of the BINDTO string.
2377 *
2378 * @param addr_and_port String we extract the port from.
2379 * @return The extracted port as unsigned int.
2380 */
2381static unsigned int
2382extract_port (const char *addr_and_port)
2383{
2384 unsigned int port;
2385 char dummy[2];
2386 char *token;
2387 char *addr;
2388 char *colon;
2389 char *cp;
2390 char *rest = NULL;
2391
2392 if (NULL != addr_and_port)
2393 {
2394 cp = GNUNET_strdup (addr_and_port);
2395 token = strtok_r (cp, "]", &rest);
2396 if (strlen (addr_and_port) == strlen (token))
2397 {
2398 colon = strrchr (cp, ':');
2399 if (NULL == colon)
2400 {
2401 GNUNET_free (cp);
2402 return 0;
2403 }
2404 addr = colon;
2405 addr++;
2406 }
2407 else
2408 {
2409 token = strtok_r (NULL, "]", &rest);
2410 if (NULL == token)
2411 {
2412 GNUNET_free (cp);
2413 return 0;
2414 }
2415 else
2416 {
2417 addr = token;
2418 addr++;
2419 }
2420 }
2421
2422
2423 if (1 == sscanf (addr, "%u%1s", &port, dummy))
2424 {
2425 /* interpreting value as just a PORT number */
2426 if (port > UINT16_MAX)
2427 {
2428 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2429 "Port `%u' invalid: value too large for port\n",
2430 port);
2431 GNUNET_free (cp);
2432 return 0;
2433 }
2434 }
2435 else
2436 {
2437 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2438 "BINDTO specification invalid: last ':' not followed by number\n");
2439 GNUNET_free (cp);
2440 return 0;
2441 }
2442 GNUNET_free (cp);
2443 }
2444 else
2445 {
2446 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2447 "return 0\n");
2448 /* interpret missing port as 0, aka pick any free one */
2449 port = 0;
2450 }
2451
2452 return port;
2453}
2454
2455
2456/**
2457 * Convert TCP bind specification to a `struct sockaddr *`
2458 *
2459 * @param bindto bind specification to convert
2460 * @param[out] sock_len set to the length of the address
2461 * @return converted bindto specification
2462 */
2463static struct sockaddr *
2464tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2465{
2466 struct sockaddr *in;
2467 unsigned int port;
2468 struct sockaddr_in v4;
2469 struct sockaddr_in6 v6;
2470 char *start;
2471
2472 memset (&v4, 0, sizeof(v4));
2473 start = extract_address (bindto);
2474 GNUNET_assert (NULL != start);
2475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2476 "start %s\n",
2477 start);
2478
2479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2480 "!bindto %s\n",
2481 bindto);
2482
2483
2484 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
2485 {
2486 // colon = strrchr (cp, ':');
2487 port = extract_port (bindto);
2488
2489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2490 "port %u\n",
2491 port);
2492
2493 in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
2494 }
2495 else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2496 {
2497 // colon = strrchr (cp, ':');
2498 port = extract_port (bindto);
2499 in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
2500 }
2501 else
2502 {
2503 GNUNET_assert (0);
2504 }
2505
2506 GNUNET_free (start);
2507 return in;
2508}
2509
2510
2511/**
2512 * Signature of functions implementing the sending functionality of a
2513 * message queue.
2514 *
2515 * @param mq the message queue
2516 * @param msg the message to send
2517 * @param impl_state our `struct Queue`
2518 */
2519static void
2520mq_send (struct GNUNET_MQ_Handle *mq,
2521 const struct GNUNET_MessageHeader *msg,
2522 void *impl_state)
2523{
2524 struct Queue *queue = impl_state;
2525 uint16_t msize = ntohs (msg->size);
2526 struct TCPBox box;
2527 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2528 "In MQ send. Queue finishing: %s; write task running: %s\n",
2529 (GNUNET_YES == queue->finishing) ? "yes" : "no",
2530 (NULL == queue->write_task) ? "yes" : "no");
2531 GNUNET_assert (mq == queue->mq);
2532 queue->mq_awaits_continue = GNUNET_YES;
2533 if (GNUNET_YES == queue->finishing)
2534 return; /* this queue is dying, drop msg */
2535 GNUNET_assert (0 == queue->pwrite_off);
2536 box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
2537 box.header.size = htons (msize);
2538 calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
2539 memcpy (&queue->pwrite_buf[queue->pwrite_off], &box, sizeof(box));
2540 queue->pwrite_off += sizeof(box);
2541 memcpy (&queue->pwrite_buf[queue->pwrite_off], msg, msize);
2542 queue->pwrite_off += msize;
2543 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2544 "%lu bytes of plaintext to send\n", queue->pwrite_off);
2545 GNUNET_assert (NULL != queue->sock);
2546 if (NULL == queue->write_task)
2547 queue->write_task =
2548 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2549 queue->sock,
2550 &queue_write,
2551 queue);
2552}
2553
2554
2555/**
2556 * Signature of functions implementing the destruction of a message
2557 * queue. Implementations must not free @a mq, but should take care
2558 * of @a impl_state.
2559 *
2560 * @param mq the message queue to destroy
2561 * @param impl_state our `struct Queue`
2562 */
2563static void
2564mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
2565{
2566 struct Queue *queue = impl_state;
2567
2568 if (mq == queue->mq)
2569 {
2570 queue->mq = NULL;
2571 queue_finish (queue);
2572 }
2573}
2574
2575
2576/**
2577 * Implementation function that cancels the currently sent message.
2578 *
2579 * @param mq message queue
2580 * @param impl_state our `struct Queue`
2581 */
2582static void
2583mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2584{
2585 struct Queue *queue = impl_state;
2586
2587 GNUNET_assert (0 != queue->pwrite_off);
2588 queue->pwrite_off = 0;
2589}
2590
2591
2592/**
2593 * Generic error handler, called with the appropriate
2594 * error code and the same closure specified at the creation of
2595 * the message queue.
2596 * Not every message queue implementation supports an error handler.
2597 *
2598 * @param cls our `struct Queue`
2599 * @param error error code
2600 */
2601static void
2602mq_error (void *cls, enum GNUNET_MQ_Error error)
2603{
2604 struct Queue *queue = cls;
2605
2606 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2607 "MQ error in queue to %s: %d\n",
2608 GNUNET_i2s (&queue->target),
2609 (int) error);
2610 queue_finish (queue);
2611}
2612
2613
2614/**
2615 * Add the given @a queue to our internal data structure. Setup the
2616 * MQ processing and inform transport that the queue is ready. Must
2617 * be called after the KX for outgoing messages has been bootstrapped.
2618 *
2619 * @param queue queue to boot
2620 */
2621static void
2622boot_queue (struct Queue *queue)
2623{
2624 queue->nt =
2625 GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
2626 (void) GNUNET_CONTAINER_multipeermap_put (
2627 queue_map,
2628 &queue->target,
2629 queue,
2630 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2631 GNUNET_STATISTICS_set (stats,
2632 "# queues active",
2633 GNUNET_CONTAINER_multipeermap_size (queue_map),
2634 GNUNET_NO);
2635 queue->timeout =
2636 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2637 queue->mq = GNUNET_MQ_queue_for_callbacks (&mq_send,
2638 &mq_destroy,
2639 &mq_cancel,
2640 queue,
2641 NULL,
2642 &mq_error,
2643 queue);
2644}
2645
2646
2647/**
2648 * Generate and transmit our ephemeral key and the signature for
2649 * the initial KX with the other peer. Must be called first, before
2650 * any other bytes are ever written to the output buffer. Note that
2651 * our cipher must already be initialized when calling this function.
2652 * Helper function for #start_initial_kx_out().
2653 *
2654 * @param queue queue to do KX for
2655 * @param epub our public key for the KX
2656 */
2657static void
2658transmit_kx (struct Queue *queue,
2659 const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
2660{
2661 struct TcpHandshakeSignature ths;
2662 struct TCPConfirmation tc;
2663
2664 memcpy (queue->cwrite_buf, epub, sizeof(*epub));
2665 queue->cwrite_off = sizeof(*epub);
2666 /* compute 'tc' and append in encrypted format to cwrite_buf */
2667 tc.sender = my_identity;
2668 tc.monotonic_time =
2669 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
2670 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
2671 &tc.challenge,
2672 sizeof(tc.challenge));
2673 ths.purpose.purpose = htonl (
2674 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE);
2675 ths.purpose.size = htonl (sizeof(ths));
2676 ths.sender = my_identity;
2677 ths.receiver = queue->target;
2678 ths.ephemeral = *epub;
2679 ths.monotonic_time = tc.monotonic_time;
2680 ths.challenge = tc.challenge;
2681 GNUNET_CRYPTO_eddsa_sign (my_private_key,
2682 &ths,
2683 &tc.sender_sig);
2684 GNUNET_assert (0 ==
2685 gcry_cipher_encrypt (queue->out_cipher,
2686 &queue->cwrite_buf[queue->cwrite_off],
2687 sizeof(tc),
2688 &tc,
2689 sizeof(tc)));
2690 queue->challenge = tc.challenge;
2691 queue->cwrite_off += sizeof(tc);
2692
2693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2694 "handshake written\n");
2695}
2696
2697
2698/**
2699 * Initialize our key material for outgoing transmissions and
2700 * inform the other peer about it. Must be called first before
2701 * any data is sent.
2702 *
2703 * @param queue the queue to setup
2704 */
2705static void
2706start_initial_kx_out (struct Queue *queue)
2707{
2708 struct GNUNET_CRYPTO_EcdhePublicKey epub;
2709
2710 GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral);
2711 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &epub);
2712 setup_out_cipher (queue);
2713 transmit_kx (queue, &epub);
2714}
2715
2716
2717/**
2718 * Callback called when peerstore store operation for handshake monotime is finished.
2719 * @param cls Queue context the store operation was executed.
2720 * @param success Store operation was successful (GNUNET_OK) or not.
2721 */
2722static void
2723handshake_monotime_store_cb (void *cls, int success)
2724{
2725 struct Queue *queue = cls;
2726 if (GNUNET_OK != success)
2727 {
2728 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2729 "Failed to store handshake monotonic time in PEERSTORE!\n");
2730 }
2731 queue->handshake_monotime_sc = NULL;
2732}
2733
2734
2735/**
2736 * Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE
2737 * where found.
2738 * @param cls Queue context the store operation was executed.
2739 * @param record The record found or NULL if there is no record left.
2740 * @param emsg Message from peerstore.
2741 */
2742static void
2743handshake_monotime_cb (void *cls,
2744 const struct GNUNET_PEERSTORE_Record *record,
2745 const char *emsg)
2746{
2747 struct Queue *queue = cls;
2748 struct GNUNET_TIME_AbsoluteNBO *mtbe;
2749 struct GNUNET_TIME_Absolute mt;
2750 const struct GNUNET_PeerIdentity *pid;
2751 struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
2752
2753 (void) emsg;
2754
2755 handshake_monotonic_time = &queue->handshake_monotonic_time;
2756 pid = &queue->target;
2757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2758 "tcp handshake with us %s\n",
2759 GNUNET_i2s (&my_identity));
2760 if (NULL == record)
2761 {
2762 queue->handshake_monotime_get = NULL;
2763 return;
2764 }
2765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2766 "tcp handshake from peer %s\n",
2767 GNUNET_i2s (pid));
2768 if (sizeof(*mtbe) != record->value_size)
2769 {
2770 GNUNET_break (0);
2771 return;
2772 }
2773 mtbe = record->value;
2774 mt = GNUNET_TIME_absolute_ntoh (*mtbe);
2775 if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
2776 queue->handshake_monotonic_time).abs_value_us)
2777 {
2778 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2779 "Queue from %s dropped, handshake monotime in the past\n",
2780 GNUNET_i2s (&queue->target));
2781 GNUNET_break (0);
2782 queue_finish (queue);
2783 return;
2784 }
2785 queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
2786 "transport_tcp_communicator",
2787 pid,
2788 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE,
2789 handshake_monotonic_time,
2790 sizeof(*
2791 handshake_monotonic_time),
2792 GNUNET_TIME_UNIT_FOREVER_ABS,
2793 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
2794 &
2795 handshake_monotime_store_cb,
2796 queue);
2797}
2798
2799
2800/**
2801 * We have received the first bytes from the other side on a @a queue.
2802 * Decrypt the @a tc contained in @a ibuf and check the signature.
2803 * Note that #setup_in_cipher() must have already been called.
2804 *
2805 * @param queue queue to decrypt initial bytes from other peer for
2806 * @param[out] tc where to store the result
2807 * @param ibuf incoming data, of size
2808 * `INITIAL_KX_SIZE`
2809 * @return #GNUNET_OK if the signature was OK, #GNUNET_SYSERR if not
2810 */
2811static int
2812decrypt_and_check_tc (struct Queue *queue,
2813 struct TCPConfirmation *tc,
2814 char *ibuf)
2815{
2816 struct TcpHandshakeSignature ths;
2817 enum GNUNET_GenericReturnValue ret;
2818
2819 GNUNET_assert (
2820 0 ==
2821 gcry_cipher_decrypt (queue->in_cipher,
2822 tc,
2823 sizeof(*tc),
2824 &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
2825 sizeof(*tc)));
2826 ths.purpose.purpose = htonl (
2827 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE);
2828 ths.purpose.size = htonl (sizeof(ths));
2829 ths.sender = tc->sender;
2830 ths.receiver = my_identity;
2831 memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
2832 ths.monotonic_time = tc->monotonic_time;
2833 ths.challenge = tc->challenge;
2834 ret = GNUNET_CRYPTO_eddsa_verify (
2835 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE,
2836 &ths,
2837 &tc->sender_sig,
2838 &tc->sender.public_key);
2839 if (GNUNET_YES == ret)
2840 queue->handshake_monotime_get =
2841 GNUNET_PEERSTORE_iterate (peerstore,
2842 "transport_tcp_communicator",
2843 &queue->target,
2844 GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE,
2845 &handshake_monotime_cb,
2846 queue);
2847 return ret;
2848}
2849
2850
2851/**
2852 * Read from the socket of the queue until we have enough data
2853 * to initialize the decryption logic and can switch to regular
2854 * reading.
2855 *
2856 * @param cls a `struct Queue`
2857 */
2858static void
2859queue_read_kx (void *cls)
2860{
2861 struct Queue *queue = cls;
2862 ssize_t rcvd;
2863 struct GNUNET_TIME_Relative left;
2864 struct TCPConfirmation tc;
2865
2866 queue->read_task = NULL;
2867 left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2868 if (0 == left.rel_value_us)
2869 {
2870 queue_destroy (queue);
2871 return;
2872 }
2873 rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2874 &queue->cread_buf[queue->cread_off],
2875 BUF_SIZE - queue->cread_off);
2876 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2877 "Received %lu bytes for KX\n",
2878 rcvd);
2879 if (-1 == rcvd)
2880 {
2881 if ((EAGAIN != errno) && (EINTR != errno))
2882 {
2883 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2884 queue_destroy (queue);
2885 return;
2886 }
2887 queue->read_task =
2888 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue);
2889 return;
2890 }
2891 queue->cread_off += rcvd;
2892 if (queue->cread_off < INITIAL_KX_SIZE)
2893 {
2894 /* read more */
2895 queue->read_task =
2896 GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue);
2897 return;
2898 }
2899 /* we got all the data, let's find out who we are talking to! */
2900 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *)
2901 queue->cread_buf,
2902 queue);
2903 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
2904 {
2905 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2906 "Invalid TCP KX received from %s\n",
2907 GNUNET_a2s (queue->address, queue->address_len));
2908 queue_destroy (queue);
2909 return;
2910 }
2911 if (0 !=
2912 memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
2913 {
2914 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2915 "Invalid sender in TCP KX received from %s\n",
2916 GNUNET_a2s (queue->address, queue->address_len));
2917 queue_destroy (queue);
2918 return;
2919 }
2920 send_challenge (tc.challenge, queue);
2921 queue->write_task =
2922 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
2923 queue->sock,
2924 &queue_write,
2925 queue);
2926
2927 /* update queue timeout */
2928 reschedule_queue_timeout (queue);
2929 /* prepare to continue with regular read task immediately */
2930 memmove (queue->cread_buf,
2931 &queue->cread_buf[INITIAL_KX_SIZE],
2932 queue->cread_off - (INITIAL_KX_SIZE));
2933 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2934 "cread_off is %lu bytes before adjusting\n",
2935 queue->cread_off);
2936 queue->cread_off -= INITIAL_KX_SIZE;
2937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2938 "cread_off set to %lu bytes\n",
2939 queue->cread_off);
2940 queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue);
2941}
2942
2943
2944/**
2945 * Read from the socket of the proto queue until we have enough data
2946 * to upgrade to full queue.
2947 *
2948 * @param cls a `struct ProtoQueue`
2949 */
2950static void
2951proto_read_kx (void *cls)
2952{
2953 struct ProtoQueue *pq = cls;
2954 ssize_t rcvd;
2955 struct GNUNET_TIME_Relative left;
2956 struct Queue *queue;
2957 struct TCPConfirmation tc;
2958 GNUNET_SCHEDULER_TaskCallback read_task;
2959
2960 pq->read_task = NULL;
2961 left = GNUNET_TIME_absolute_get_remaining (pq->timeout);
2962 if (0 == left.rel_value_us)
2963 {
2964 free_proto_queue (pq);
2965 return;
2966 }
2967 rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
2968 &pq->ibuf[pq->ibuf_off],
2969 sizeof(pq->ibuf) - pq->ibuf_off);
2970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2971 "Proto received %lu bytes for KX\n", rcvd);
2972 if (-1 == rcvd)
2973 {
2974 if ((EAGAIN != errno) && (EINTR != errno))
2975 {
2976 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2977 free_proto_queue (pq);
2978 return;
2979 }
2980 /* try again */
2981 pq->read_task =
2982 GNUNET_SCHEDULER_add_read_net (left, pq->sock, &proto_read_kx, pq);
2983 return;
2984 }
2985 pq->ibuf_off += rcvd;
2986 if (sizeof (struct TCPNATProbeMessage) == pq->ibuf_off)
2987 {
2988 struct TCPNATProbeMessage *pm = (struct TCPNATProbeMessage *) pq->ibuf;
2989
2990 check_and_remove_pending_reversal (pq->address, pq->address->sa_family, &pm->clientIdentity);
2991
2992 queue = GNUNET_new (struct Queue);
2993 queue->target = pm->clientIdentity;
2994 queue->cs = GNUNET_TRANSPORT_CS_OUTBOUND;
2995 read_task = &queue_read_kx;
2996 }
2997 else if (pq->ibuf_off > sizeof(pq->ibuf))
2998 {
2999 /* read more */
3000 pq->read_task =
3001 GNUNET_SCHEDULER_add_read_net (left, pq->sock, &proto_read_kx, pq);
3002 return;
3003 }
3004 else
3005 {
3006 /* we got all the data, let's find out who we are talking to! */
3007 queue = GNUNET_new (struct Queue);
3008 setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
3009 queue);
3010 if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
3011 {
3012 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3013 "Invalid TCP KX received from %s\n",
3014 GNUNET_a2s (pq->address, pq->address_len));
3015 gcry_cipher_close (queue->in_cipher);
3016 GNUNET_free (queue);
3017 free_proto_queue (pq);
3018 return;
3019 }
3020 queue->target = tc.sender;
3021 queue->cs = GNUNET_TRANSPORT_CS_INBOUND;
3022 read_task = &queue_read;
3023 }
3024 queue->address = pq->address; /* steals reference */
3025 queue->address_len = pq->address_len;
3026 queue->listen_sock = pq->listen_sock;
3027 queue->sock = pq->sock;
3028
3029 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3030 "created queue with target %s\n",
3031 GNUNET_i2s (&queue->target));
3032
3033 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3034 "start kx proto\n");
3035
3036 start_initial_kx_out (queue);
3037 boot_queue (queue);
3038 queue->read_task =
3039 GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3040 queue->sock,
3041 read_task,
3042 queue);
3043 queue->write_task =
3044 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
3045 queue->sock,
3046 &queue_write,
3047 queue);
3048 // TODO To early! Move it somewhere else.
3049 // send_challenge (tc.challenge, queue);
3050 queue->challenge_received = tc.challenge;
3051
3052 GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
3053 GNUNET_free (pq);
3054}
3055
3056static struct ProtoQueue *
3057create_proto_queue (struct GNUNET_NETWORK_Handle *sock,
3058 struct sockaddr *in,
3059 socklen_t addrlen)
3060{
3061 struct ProtoQueue *pq = GNUNET_new (struct ProtoQueue);
3062
3063 if (NULL == sock)
3064 {
3065 //sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, addr, addrlen);
3066 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, 0);
3067 if (NULL == sock)
3068 {
3069 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3070 "socket(%d) failed: %s",
3071 in->sa_family,
3072 strerror (errno));
3073 GNUNET_free (in);
3074 return NULL;
3075 }
3076 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, addrlen)) &&
3077 (errno != EINPROGRESS))
3078 {
3079 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3080 "connect to `%s' failed: %s",
3081 GNUNET_a2s (in, addrlen),
3082 strerror (errno));
3083 GNUNET_NETWORK_socket_close (sock);
3084 GNUNET_free (in);
3085 return NULL;
3086 }
3087 }
3088 pq->address_len = addrlen;
3089 pq->address = in;
3090 pq->timeout = GNUNET_TIME_relative_to_absolute (PROTO_QUEUE_TIMEOUT);
3091 pq->sock = sock;
3092 pq->read_task = GNUNET_SCHEDULER_add_read_net (PROTO_QUEUE_TIMEOUT,
3093 pq->sock,
3094 &proto_read_kx,
3095 pq);
3096 GNUNET_CONTAINER_DLL_insert (proto_head, proto_tail, pq);
3097
3098 return pq;
3099}
3100
3101
3102/**
3103 * We have been notified that our listen socket has something to
3104 * read. Do the read and reschedule this function to be called again
3105 * once more is available.
3106 *
3107 * @param cls ListenTask with listening socket and task
3108 */
3109static void
3110listen_cb (void *cls)
3111{
3112 struct sockaddr_storage in;
3113 socklen_t addrlen;
3114 struct GNUNET_NETWORK_Handle *sock;
3115 struct ProtoQueue *pq;
3116 struct ListenTask *lt;
3117 struct sockaddr *in_addr;
3118
3119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3120 "listen_cb\n");
3121
3122 lt = cls;
3123
3124 lt->listen_task = NULL;
3125 GNUNET_assert (NULL != lt->listen_sock);
3126 addrlen = sizeof(in);
3127 memset (&in, 0, sizeof(in));
3128 sock = GNUNET_NETWORK_socket_accept (lt->listen_sock,
3129 (struct sockaddr*) &in,
3130 &addrlen);
3131 if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
3132 return; /* system limit reached, wait until connection goes down */
3133 lt->listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3134 lt->listen_sock,
3135 &listen_cb,
3136 lt);
3137 if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
3138 return;
3139 if (NULL == sock)
3140 {
3141 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
3142 return;
3143 }
3144 in_addr = GNUNET_memdup (&in, addrlen);
3145 create_proto_queue (sock, in_addr, addrlen);
3146}
3147
3148
3149static void
3150try_connection_reversal (void *cls,
3151 const struct sockaddr *addr,
3152 socklen_t addrlen)
3153{
3154 (void) cls;
3155 struct TCPNATProbeMessage pm;
3156 struct ProtoQueue *pq;
3157 struct sockaddr *in_addr;
3158
3159 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3160 "addr->sa_family %d\n",
3161 addr->sa_family);
3162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3163 "Try to connect back\n");
3164 in_addr = GNUNET_memdup (addr, addrlen);
3165 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3166 "in_addr->sa_family %d\n",
3167 in_addr->sa_family);
3168 pq = create_proto_queue (NULL, in_addr, addrlen);
3169 if (NULL != pq)
3170 {
3171 pm.header.size = htons (sizeof(struct TCPNATProbeMessage));
3172 pm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE);
3173 pm.clientIdentity = my_identity;
3174 memcpy (pq->write_buf, &pm, sizeof(struct TCPNATProbeMessage));
3175 pq->write_off = sizeof(struct TCPNATProbeMessage);
3176 pq->write_task = GNUNET_SCHEDULER_add_write_net (PROTO_QUEUE_TIMEOUT,
3177 pq->sock,
3178 &proto_queue_write,
3179 pq);
3180 }
3181 else
3182 {
3183 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3184 "Couldn't create ProtoQueue for sending TCPNATProbeMessage\n");
3185 }
3186}
3187
3188
3189static void
3190pending_reversal_timeout (void *cls)
3191{
3192 struct sockaddr *in = cls;
3193 struct PendingReversal *pending_reversal;
3194 struct GNUNET_HashCode key;
3195
3196 GNUNET_CRYPTO_hash (in,
3197 sizeof(struct sockaddr),
3198 &key);
3199 pending_reversal = GNUNET_CONTAINER_multihashmap_get (pending_reversals,
3200 &key);
3201
3202 GNUNET_assert (NULL != pending_reversal);
3203
3204 GNUNET_CONTAINER_multihashmap_remove (pending_reversals,
3205 &key,
3206 pending_reversal);
3207 GNUNET_free (pending_reversal->in);
3208 GNUNET_free (pending_reversal);
3209}
3210
3211
3212/**
3213 * Function called by the transport service to initialize a
3214 * message queue given address information about another peer.
3215 * If and when the communication channel is established, the
3216 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
3217 * to notify the service that the channel is now up. It is
3218 * the responsibility of the communicator to manage sane
3219 * retries and timeouts for any @a peer/@a address combination
3220 * provided by the transport service. Timeouts and retries
3221 * do not need to be signalled to the transport service.
3222 *
3223 * @param cls closure
3224 * @param peer identity of the other peer
3225 * @param address where to send the message, human-readable
3226 * communicator-specific format, 0-terminated, UTF-8
3227 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is
3228 * invalid
3229 */
3230static int
3231mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3232{
3233 struct sockaddr *in;
3234 socklen_t in_len = 0;
3235 const char *path;
3236 struct sockaddr_in *v4;
3237 struct sockaddr_in6 *v6;
3238 unsigned int is_natd = GNUNET_NO;
3239 struct GNUNET_HashCode key;
3240
3241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3242 "Connecting to %s at %s\n",
3243 GNUNET_i2s (peer),
3244 address);
3245 if (0 != strncmp (address,
3246 COMMUNICATOR_ADDRESS_PREFIX "-",
3247 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
3248 {
3249 GNUNET_break_op (0);
3250 return GNUNET_SYSERR;
3251 }
3252 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
3253 in = tcp_address_to_sockaddr (path, &in_len);
3254
3255 if (NULL == in)
3256 {
3257 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3258 "Failed to setup TCP socket address\n");
3259 return GNUNET_SYSERR;
3260 }
3261
3262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3263 "in %s\n",
3264 GNUNET_a2s (in, in_len));
3265
3266 switch (in->sa_family)
3267 {
3268 case AF_INET:
3269 v4 = (struct sockaddr_in *) in;
3270 if (0 == v4->sin_port){
3271 is_natd = GNUNET_YES;
3272 GNUNET_CRYPTO_hash (in,
3273 sizeof(struct sockaddr),
3274 &key);
3275 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (pending_reversals,
3276 &key))
3277 {
3278 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3279 "There is already a request reversal for `%s'at `%s'\n",
3280 GNUNET_i2s (peer),
3281 address);
3282 GNUNET_free (in);
3283 return GNUNET_SYSERR;
3284 }
3285 }
3286 break;
3287
3288 case AF_INET6:
3289 v6 = (struct sockaddr_in6 *) in;
3290 if (0 == v6->sin6_port)
3291 {
3292 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3293 "Request reversal for `%s' at `%s' not possible for an IPv6 address\n",
3294 GNUNET_i2s (peer),
3295 address);
3296 GNUNET_free (in);
3297 return GNUNET_SYSERR;
3298 }
3299 break;
3300
3301 default:
3302 GNUNET_assert (0);
3303 }
3304
3305 if (GNUNET_YES == is_natd)
3306 {
3307 struct sockaddr_in local_sa;
3308 struct PendingReversal *pending_reversal;
3309
3310 memset (&local_sa, 0, sizeof(local_sa));
3311 local_sa.sin_family = AF_INET;
3312 local_sa.sin_port = htons (bind_port);
3313 /* We leave sin_address at 0, let the kernel figure it out,
3314 even if our bind() is more specific. (May want to reconsider
3315 later.) */
3316 if (GNUNET_OK != GNUNET_NAT_request_reversal (nat, &local_sa, v4))
3317 {
3318 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3319 "request reversal for `%s' at `%s' failed\n",
3320 GNUNET_i2s (peer),
3321 address);
3322 GNUNET_free (in);
3323 return GNUNET_SYSERR;
3324 }
3325 pending_reversal = GNUNET_new (struct PendingReversal);
3326 pending_reversal->in = in;
3327 GNUNET_assert (GNUNET_OK ==
3328 GNUNET_CONTAINER_multihashmap_put (pending_reversals,
3329 &key,
3330 pending_reversal,
3331 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3332 pending_reversal->target = *peer;
3333 pending_reversal->timeout_task = GNUNET_SCHEDULER_add_delayed (NAT_TIMEOUT, &pending_reversal_timeout, in);
3334 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3335 "Created NAT WAIT connection to `%s' at `%s'\n",
3336 GNUNET_i2s (peer),
3337 GNUNET_a2s (in, sizeof (struct sockaddr)));
3338 }
3339 else
3340 {
3341 struct GNUNET_NETWORK_Handle *sock;
3342 struct Queue *queue;
3343
3344 sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP);
3345 if (NULL == sock)
3346 {
3347 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3348 "socket(%d) failed: %s",
3349 in->sa_family,
3350 strerror (errno));
3351 GNUNET_free (in);
3352 return GNUNET_SYSERR;
3353 }
3354 if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) &&
3355 (errno != EINPROGRESS))
3356 {
3357 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3358 "connect to `%s' failed: %s",
3359 address,
3360 strerror (errno));
3361 GNUNET_NETWORK_socket_close (sock);
3362 GNUNET_free (in);
3363 return GNUNET_SYSERR;
3364 }
3365
3366 queue = GNUNET_new (struct Queue);
3367 queue->target = *peer;
3368 queue->address = in;
3369 queue->address_len = in_len;
3370 queue->sock = sock;
3371 queue->cs = GNUNET_TRANSPORT_CS_OUTBOUND;
3372 boot_queue (queue);
3373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3374 "booted queue with target %s\n",
3375 GNUNET_i2s (&queue->target));
3376 // queue->mq_awaits_continue = GNUNET_YES;
3377 queue->read_task =
3378 GNUNET_SCHEDULER_add_read_net (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3379 queue->sock,
3380 &queue_read_kx,
3381 queue);
3382
3383
3384 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3385 "start kx mq_init\n");
3386
3387 start_initial_kx_out (queue);
3388 queue->write_task =
3389 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
3390 queue->sock,
3391 &queue_write,
3392 queue);
3393 }
3394
3395 return GNUNET_OK;
3396}
3397
3398
3399/**
3400 * Iterator over all ListenTasks to clean up.
3401 *
3402 * @param cls NULL
3403 * @param key unused
3404 * @param value the ListenTask to cancel.
3405 * @return #GNUNET_OK to continue to iterate
3406 */
3407static int
3408get_lt_delete_it (void *cls,
3409 const struct GNUNET_HashCode *key,
3410 void *value)
3411{
3412 struct ListenTask *lt = value;
3413
3414 (void) cls;
3415 (void) key;
3416 if (NULL != lt->listen_task)
3417 {
3418 GNUNET_SCHEDULER_cancel (lt->listen_task);
3419 lt->listen_task = NULL;
3420 }
3421 if (NULL != lt->listen_sock)
3422 {
3423 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (lt->listen_sock));
3424 lt->listen_sock = NULL;
3425 }
3426 GNUNET_free (lt);
3427 return GNUNET_OK;
3428}
3429
3430
3431/**
3432 * Iterator over all message queues to clean up.
3433 *
3434 * @param cls NULL
3435 * @param target unused
3436 * @param value the queue to destroy
3437 * @return #GNUNET_OK to continue to iterate
3438 */
3439static int
3440get_queue_delete_it (void *cls,
3441 const struct GNUNET_PeerIdentity *target,
3442 void *value)
3443{
3444 struct Queue *queue = value;
3445
3446 (void) cls;
3447 (void) target;
3448 queue_destroy (queue);
3449 return GNUNET_OK;
3450}
3451
3452
3453/**
3454 * Shutdown the UNIX communicator.
3455 *
3456 * @param cls NULL (always)
3457 */
3458static void
3459do_shutdown (void *cls)
3460{
3461 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3462 "Shutdown %s!\n",
3463 shutdown_running ? "running" : "not running");
3464
3465 if (GNUNET_YES == shutdown_running)
3466 return;
3467 else
3468 shutdown_running = GNUNET_YES;
3469
3470 while (NULL != proto_head)
3471 free_proto_queue (proto_head);
3472 if (NULL != nat)
3473 {
3474 GNUNET_NAT_unregister (nat);
3475 nat = NULL;
3476 }
3477 GNUNET_CONTAINER_multihashmap_iterate (pending_reversals, &pending_reversals_delete_it, NULL);
3478 GNUNET_CONTAINER_multihashmap_destroy (pending_reversals);
3479 GNUNET_CONTAINER_multihashmap_iterate (lt_map, &get_lt_delete_it, NULL);
3480 GNUNET_CONTAINER_multihashmap_destroy (lt_map);
3481 GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL);
3482 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
3483 if (NULL != ch)
3484 {
3485 GNUNET_TRANSPORT_communicator_address_remove_all (ch);
3486 GNUNET_TRANSPORT_communicator_disconnect (ch);
3487 ch = NULL;
3488 }
3489 if (NULL != stats)
3490 {
3491 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
3492 stats = NULL;
3493 }
3494 if (NULL != my_private_key)
3495 {
3496 GNUNET_free (my_private_key);
3497 my_private_key = NULL;
3498 }
3499 if (NULL != is)
3500 {
3501 GNUNET_NT_scanner_done (is);
3502 is = NULL;
3503 }
3504 if (NULL != peerstore)
3505 {
3506 GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_NO);
3507 peerstore = NULL;
3508 }
3509 if (NULL != resolve_request_handle)
3510 {
3511 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3512 resolve_request_handle = NULL;
3513 }
3514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3515 "Shutdown done!\n");
3516}
3517
3518
3519/**
3520 * Function called when the transport service has received an
3521 * acknowledgement for this communicator (!) via a different return
3522 * path.
3523 *
3524 * Not applicable for TCP.
3525 *
3526 * @param cls closure
3527 * @param sender which peer sent the notification
3528 * @param msg payload
3529 */
3530static void
3531enc_notify_cb (void *cls,
3532 const struct GNUNET_PeerIdentity *sender,
3533 const struct GNUNET_MessageHeader *msg)
3534{
3535 (void) cls;
3536 (void) sender;
3537 (void) msg;
3538 GNUNET_break_op (0);
3539}
3540
3541
3542/**
3543 * Signature of the callback passed to #GNUNET_NAT_register() for
3544 * a function to call whenever our set of 'valid' addresses changes.
3545 *
3546 * @param cls closure
3547 * @param[in,out] app_ctx location where the app can store stuff
3548 * on add and retrieve it on remove
3549 * @param add_remove #GNUNET_YES to add a new public IP address,
3550 * #GNUNET_NO to remove a previous (now invalid) one
3551 * @param ac address class the address belongs to
3552 * @param addr either the previous or the new public IP address
3553 * @param addrlen actual length of the @a addr
3554 */
3555static void
3556nat_address_cb (void *cls,
3557 void **app_ctx,
3558 int add_remove,
3559 enum GNUNET_NAT_AddressClass ac,
3560 const struct sockaddr *addr,
3561 socklen_t addrlen)
3562{
3563 char *my_addr;
3564 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
3565
3566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3567 "nat address cb %s %s\n",
3568 add_remove ? "add" : "remove",
3569 GNUNET_a2s (addr, addrlen));
3570
3571 if (GNUNET_YES == add_remove)
3572 {
3573 enum GNUNET_NetworkType nt;
3574
3575 GNUNET_asprintf (&my_addr,
3576 "%s-%s",
3577 COMMUNICATOR_ADDRESS_PREFIX,
3578 GNUNET_a2s (addr, addrlen));
3579 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3580 ai =
3581 GNUNET_TRANSPORT_communicator_address_add (ch,
3582 my_addr,
3583 nt,
3584 GNUNET_TIME_UNIT_FOREVER_REL);
3585 GNUNET_free (my_addr);
3586 *app_ctx = ai;
3587 }
3588 else
3589 {
3590 ai = *app_ctx;
3591 GNUNET_TRANSPORT_communicator_address_remove (ai);
3592 *app_ctx = NULL;
3593 }
3594}
3595
3596
3597/**
3598 * This method adds addresses to the DLL, that are later register at the NAT service.
3599 */
3600static void
3601add_addr (struct sockaddr *in, socklen_t in_len)
3602{
3603
3604 struct Addresses *saddrs;
3605
3606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3607 "add address %s\n",
3608 GNUNET_a2s (in, in_len));
3609
3610 saddrs = GNUNET_new (struct Addresses);
3611 saddrs->addr = in;
3612 saddrs->addr_len = in_len;
3613 GNUNET_CONTAINER_DLL_insert (addrs_head, addrs_tail, saddrs);
3614
3615 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3616 "after add address %s\n",
3617 GNUNET_a2s (in, in_len));
3618
3619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3620 "add address %s\n",
3621 GNUNET_a2s (saddrs->addr, saddrs->addr_len));
3622
3623 addrs_lens++;
3624}
3625
3626
3627/**
3628 * This method launch network interactions for each address we like to bind to.
3629 *
3630 * @param addr The address we will listen to.
3631 * @param in_len The length of the address we will listen to.
3632 * @return GNUNET_SYSERR in case of error. GNUNET_OK in case we are successfully listen to the address.
3633 */
3634static int
3635init_socket (struct sockaddr *addr,
3636 socklen_t in_len)
3637{
3638 struct sockaddr_storage in_sto;
3639 socklen_t sto_len;
3640 struct GNUNET_NETWORK_Handle *listen_sock;
3641 struct ListenTask *lt;
3642 int sockfd;
3643 struct GNUNET_HashCode h_sock;
3644
3645 if (NULL == addr)
3646 {
3647 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3648 "Address is NULL.\n");
3649 return GNUNET_SYSERR;
3650 }
3651
3652 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3653 "address %s\n",
3654 GNUNET_a2s (addr, in_len));
3655
3656 listen_sock =
3657 GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
3658 if (NULL == listen_sock)
3659 {
3660 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
3661 return GNUNET_SYSERR;
3662 }
3663
3664 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
3665 {
3666 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
3667 GNUNET_NETWORK_socket_close (listen_sock);
3668 listen_sock = NULL;
3669 return GNUNET_SYSERR;
3670 }
3671
3672 if (GNUNET_OK !=
3673 GNUNET_NETWORK_socket_listen (listen_sock,
3674 5))
3675 {
3676 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3677 "listen");
3678 GNUNET_NETWORK_socket_close (listen_sock);
3679 listen_sock = NULL;
3680 return GNUNET_SYSERR;
3681 }
3682
3683 /* We might have bound to port 0, allowing the OS to figure it out;
3684 thus, get the real IN-address from the socket */
3685 sto_len = sizeof(in_sto);
3686
3687 if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
3688 (struct sockaddr *) &in_sto,
3689 &sto_len))
3690 {
3691 memcpy (&in_sto, addr, in_len);
3692 sto_len = in_len;
3693 }
3694
3695 // addr = (struct sockaddr *) &in_sto;
3696 in_len = sto_len;
3697 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3698 "Bound to `%s'\n",
3699 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
3700 stats = GNUNET_STATISTICS_create ("C-TCP", cfg);
3701
3702 if (NULL == is)
3703 is = GNUNET_NT_scanner_init ();
3704
3705 if (NULL == my_private_key)
3706 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
3707 if (NULL == my_private_key)
3708 {
3709 GNUNET_log (
3710 GNUNET_ERROR_TYPE_ERROR,
3711 _ (
3712 "Transport service is lacking key configuration settings. Exiting.\n"));
3713 if (NULL != resolve_request_handle)
3714 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3715 GNUNET_SCHEDULER_shutdown ();
3716 return GNUNET_SYSERR;
3717 }
3718 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key);
3719 /* start listening */
3720
3721 lt = GNUNET_new (struct ListenTask);
3722 lt->listen_sock = listen_sock;
3723
3724 lt->listen_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3725 listen_sock,
3726 &listen_cb,
3727 lt);
3728
3729 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3730 "creating hash\n");
3731 sockfd = GNUNET_NETWORK_get_fd (lt->listen_sock);
3732 GNUNET_CRYPTO_hash (&sockfd,
3733 sizeof(int),
3734 &h_sock);
3735
3736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3737 "creating map\n");
3738 if (NULL == lt_map)
3739 lt_map = GNUNET_CONTAINER_multihashmap_create (2, GNUNET_NO);
3740
3741 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3742 "creating map entry\n");
3743 GNUNET_assert (GNUNET_OK ==
3744 GNUNET_CONTAINER_multihashmap_put (lt_map,
3745 &h_sock,
3746 lt,
3747 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3748
3749 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3750 "map entry created\n");
3751
3752 if (NULL == queue_map)
3753 queue_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
3754
3755 if (NULL == ch)
3756 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
3757 COMMUNICATOR_CONFIG_SECTION,
3758 COMMUNICATOR_ADDRESS_PREFIX,
3759 GNUNET_TRANSPORT_CC_RELIABLE,
3760 &mq_init,
3761 NULL,
3762 &enc_notify_cb,
3763 NULL);
3764
3765 if (NULL == ch)
3766 {
3767 GNUNET_break (0);
3768 if (NULL != resolve_request_handle)
3769 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3770 GNUNET_SCHEDULER_shutdown ();
3771 return GNUNET_SYSERR;
3772 }
3773
3774 add_addr (addr, in_len);
3775 return GNUNET_OK;
3776
3777}
3778
3779
3780/**
3781 * This method reads from the DLL addrs_head to register them at the NAT service.
3782 */
3783static void
3784nat_register ()
3785{
3786 struct sockaddr **saddrs;
3787 socklen_t *saddr_lens;
3788 int i;
3789 size_t len;
3790
3791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3792 "starting nat register!\n");
3793 len = 0;
3794 i = 0;
3795 saddrs = GNUNET_malloc ((addrs_lens) * sizeof(struct sockaddr *));
3796 saddr_lens = GNUNET_malloc ((addrs_lens) * sizeof(socklen_t));
3797 for (struct Addresses *pos = addrs_head; NULL != pos; pos = pos->next)
3798 {
3799 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3800 "registering address %s\n",
3801 GNUNET_a2s (addrs_head->addr, addrs_head->addr_len));
3802
3803 saddr_lens[i] = addrs_head->addr_len;
3804 len += saddr_lens[i];
3805 saddrs[i] = GNUNET_memdup (addrs_head->addr, saddr_lens[i]);
3806 i++;
3807 }
3808
3809 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3810 "registering addresses %lu %lu %lu %lu\n",
3811 (addrs_lens) * sizeof(struct sockaddr *),
3812 (addrs_lens) * sizeof(socklen_t),
3813 len,
3814 sizeof(COMMUNICATOR_CONFIG_SECTION));
3815 nat = GNUNET_NAT_register (cfg,
3816 COMMUNICATOR_CONFIG_SECTION,
3817 IPPROTO_TCP,
3818 addrs_lens,
3819 (const struct sockaddr **) saddrs,
3820 saddr_lens,
3821 &nat_address_cb,
3822 try_connection_reversal,
3823 NULL /* closure */);
3824 for (i = addrs_lens - 1; i >= 0; i--)
3825 GNUNET_free (saddrs[i]);
3826 GNUNET_free (saddrs);
3827 GNUNET_free (saddr_lens);
3828
3829 if (NULL == nat)
3830 {
3831 GNUNET_break (0);
3832 if (NULL != resolve_request_handle)
3833 GNUNET_RESOLVER_request_cancel (resolve_request_handle);
3834 GNUNET_SCHEDULER_shutdown ();
3835 }
3836}
3837
3838
3839/**
3840 * This method is the callback called by the resolver API, and wraps method init_socket.
3841 *
3842 * @param cls The port we will bind to.
3843 * @param addr The address we will bind to.
3844 * @param in_len The length of the address we will bind to.
3845 */
3846static void
3847init_socket_resolv (void *cls,
3848 const struct sockaddr *addr,
3849 socklen_t in_len)
3850{
3851 struct sockaddr_in *v4;
3852 struct sockaddr_in6 *v6;
3853 struct sockaddr *in;
3854
3855 (void) cls;
3856 if (NULL != addr)
3857 {
3858 if (AF_INET == addr->sa_family)
3859 {
3860 v4 = (struct sockaddr_in *) addr;
3861 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, *v4, bind_port);// _global);
3862 }
3863 else if (AF_INET6 == addr->sa_family)
3864 {
3865 v6 = (struct sockaddr_in6 *) addr;
3866 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, *v6, bind_port);// _global);
3867 }
3868 else
3869 {
3870 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3871 "Address family %u not suitable (not AF_INET %u nor AF_INET6 %u \n",
3872 addr->sa_family,
3873 AF_INET,
3874 AF_INET6);
3875 return;
3876 }
3877 init_socket (in, in_len);
3878 }
3879 else
3880 {
3881 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3882 "Address is NULL. This might be an error or the resolver finished resolving.\n");
3883 if (NULL == addrs_head)
3884 {
3885 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3886 "Resolver finished resolving, but we do not listen to an address!.\n");
3887 return;
3888 }
3889 nat_register ();
3890 }
3891}
3892
3893
3894/**
3895 * Setup communicator and launch network interactions.
3896 *
3897 * @param cls NULL (always)
3898 * @param args remaining command-line arguments
3899 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
3900 * @param c configuration
3901 */
3902static void
3903run (void *cls,
3904 char *const *args,
3905 const char *cfgfile,
3906 const struct GNUNET_CONFIGURATION_Handle *c)
3907{
3908 char *bindto;
3909 struct sockaddr *in;
3910 socklen_t in_len;
3911 struct sockaddr_in v4;
3912 struct sockaddr_in6 v6;
3913 char *start;
3914 unsigned int port;
3915 char dummy[2];
3916 char *rest = NULL;
3917 struct PortOnlyIpv4Ipv6 *po;
3918 socklen_t addr_len_ipv4;
3919 socklen_t addr_len_ipv6;
3920
3921 (void) cls;
3922
3923 pending_reversals = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO);
3924 memset (&v4,0,sizeof(struct sockaddr_in));
3925 memset (&v6,0,sizeof(struct sockaddr_in6));
3926 cfg = c;
3927 if (GNUNET_OK !=
3928 GNUNET_CONFIGURATION_get_value_string (cfg,
3929 COMMUNICATOR_CONFIG_SECTION,
3930 "BINDTO",
3931 &bindto))
3932 {
3933 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
3934 COMMUNICATOR_CONFIG_SECTION,
3935 "BINDTO");
3936 return;
3937 }
3938 if (GNUNET_OK !=
3939 GNUNET_CONFIGURATION_get_value_number (cfg,
3940 COMMUNICATOR_CONFIG_SECTION,
3941 "MAX_QUEUE_LENGTH",
3942 &max_queue_length))
3943 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
3944 if (GNUNET_OK !=
3945 GNUNET_CONFIGURATION_get_value_time (cfg,
3946 COMMUNICATOR_CONFIG_SECTION,
3947 "REKEY_INTERVAL",
3948 &rekey_interval))
3949 rekey_interval = DEFAULT_REKEY_INTERVAL;
3950
3951 peerstore = GNUNET_PEERSTORE_connect (cfg);
3952 if (NULL == peerstore)
3953 {
3954 GNUNET_free (bindto);
3955 GNUNET_break (0);
3956 GNUNET_SCHEDULER_shutdown ();
3957 return;
3958 }
3959
3960 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
3961
3962 if (1 == sscanf (bindto, "%u%1s", &bind_port, dummy))
3963 {
3964 po = tcp_address_to_sockaddr_port_only (bindto, &bind_port);
3965 addr_len_ipv4 = po->addr_len_ipv4;
3966 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3967 "address po %s\n",
3968 GNUNET_a2s (po->addr_ipv4, addr_len_ipv4));
3969 if (NULL != po->addr_ipv4)
3970 {
3971 init_socket (po->addr_ipv4, addr_len_ipv4);
3972 }
3973 if (NULL != po->addr_ipv6)
3974 {
3975 addr_len_ipv6 = po->addr_len_ipv6;
3976 init_socket (po->addr_ipv6, addr_len_ipv6);
3977 }
3978 GNUNET_free (po);
3979 nat_register ();
3980 GNUNET_free (bindto);
3981 return;
3982 }
3983
3984 start = extract_address (bindto);
3985 // FIXME: check for NULL == start...
3986 if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
3987 {
3988 bind_port = extract_port (bindto);
3989
3990 in = tcp_address_to_sockaddr_numeric_v4 (&in_len, v4, bind_port);
3991 init_socket (in, in_len);
3992 nat_register ();
3993 GNUNET_free (start);
3994 GNUNET_free (bindto);
3995 return;
3996 }
3997
3998 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
3999 {
4000 bind_port = extract_port (bindto);
4001 in = tcp_address_to_sockaddr_numeric_v6 (&in_len, v6, bind_port);
4002 init_socket (in, in_len);
4003 nat_register ();
4004 GNUNET_free (start);
4005 GNUNET_free (bindto);
4006 return;
4007 }
4008
4009 bind_port = extract_port (bindto);
4010 resolve_request_handle = GNUNET_RESOLVER_ip_get (strtok_r (bindto,
4011 ":",
4012 &rest),
4013 AF_UNSPEC,
4014 GNUNET_TIME_UNIT_MINUTES,
4015 &init_socket_resolv,
4016 &port);
4017
4018 GNUNET_free (bindto);
4019 GNUNET_free (start);
4020}
4021
4022
4023/**
4024 * The main function for the UNIX communicator.
4025 *
4026 * @param argc number of arguments from the command line
4027 * @param argv command line arguments
4028 * @return 0 ok, 1 on error
4029 */
4030int
4031main (int argc, char *const *argv)
4032{
4033 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4034 GNUNET_GETOPT_OPTION_END
4035 };
4036 int ret;
4037
4038 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4039 "Starting tcp communicator\n");
4040 if (GNUNET_OK !=
4041 GNUNET_STRINGS_get_utf8_args (argc, argv,
4042 &argc, &argv))
4043 return 2;
4044
4045 ret = (GNUNET_OK ==
4046 GNUNET_PROGRAM_run (argc,
4047 argv,
4048 "gnunet-communicator-tcp",
4049 _ ("GNUnet TCP communicator"),
4050 options,
4051 &run,
4052 NULL))
4053 ? 0
4054 : 1;
4055 GNUNET_free_nz ((void *) argv);
4056 return ret;
4057}
4058
4059
4060/* end of gnunet-communicator-tcp.c */